ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/eplus_idf.c
Revision: 2.4
Committed: Sun Feb 9 05:49:21 2014 UTC (10 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.3: +77 -13 lines
Log Message:
Unfinished implementation of EnergyPlus User View Factors calculation

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.4 static const char RCSid[] = "$Id: eplus_idf.c,v 2.3 2014/02/09 02:18:16 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * eplus_idf.c
6     *
7     * EnergyPlus Input Data File i/o routines
8     *
9     * Created by Greg Ward on 1/31/14.
10     */
11    
12     #include <stdio.h>
13     #include <string.h>
14     #include <ctype.h>
15     #include <stdlib.h>
16     #include "eplus_idf.h"
17    
18     #ifdef getc_unlocked /* avoid horrendous overhead of flockfile */
19     #undef getc
20     #define getc getc_unlocked
21     #endif
22    
23     /* Create a new parameter with empty field list (comment optional) */
24     IDF_PARAMETER *
25     idf_newparam(IDF_LOADED *idf, const char *pname, const char *comm,
26     IDF_PARAMETER *prev)
27     {
28     LUENT *pent;
29     IDF_PARAMETER *pnew;
30    
31     if ((idf == NULL) | (pname == NULL))
32     return(NULL);
33     if (comm == NULL) comm = "";
34     pent = lu_find(&idf->ptab, pname);
35     if (pent == NULL)
36     return(NULL);
37     if (pent->key == NULL) { /* new parameter name/type? */
38     pent->key = (char *)malloc(strlen(pname)+1);
39     if (pent->key == NULL)
40     return(NULL);
41     strcpy(pent->key, pname);
42     }
43     pnew = (IDF_PARAMETER *)malloc(sizeof(IDF_PARAMETER)+strlen(comm));
44     if (pnew == NULL)
45     return(NULL);
46     strcpy(pnew->rem, comm);
47     pnew->flist = NULL;
48     pnew->pname = pent->key; /* add to table */
49     pnew->pnext = (IDF_PARAMETER *)pent->data;
50     pent->data = (char *)pnew;
51     pnew->dnext = NULL; /* add to file list */
52     if (prev != NULL || (prev = idf->plast) != NULL) {
53     pnew->dnext = prev->dnext;
54     if (prev == idf->plast)
55     idf->plast = pnew;
56     }
57     if (idf->pfirst == NULL)
58     idf->pfirst = idf->plast = pnew;
59     else
60     prev->dnext = pnew;
61     return(pnew);
62     }
63    
64     /* Add a field to the given parameter and follow with the given text */
65     int
66     idf_addfield(IDF_PARAMETER *param, const char *fval, const char *comm)
67     {
68     int fnum = 1; /* returned argument number */
69     IDF_FIELD *fnew, *flast;
70     char *cp;
71    
72     if ((param == NULL) | (fval == NULL))
73     return(0);
74     if (comm == NULL) comm = "";
75     fnew = (IDF_FIELD *)malloc(sizeof(IDF_FIELD)+strlen(fval)+strlen(comm));
76     if (fnew == NULL)
77     return(0);
78     fnew->next = NULL;
79     cp = fnew->arg; /* copy argument and comments */
80     while ((*cp++ = *fval++))
81     ;
82     fnew->rem = cp;
83     while ((*cp++ = *comm++))
84     ;
85     /* add to parameter's field list */
86     if ((flast = param->flist) != NULL) {
87     ++fnum;
88     while (flast->next != NULL) {
89     flast = flast->next;
90     ++fnum;
91     }
92     }
93     if (flast == NULL)
94     param->flist = fnew;
95     else
96     flast->next = fnew;
97     return(fnum);
98     }
99    
100 greg 2.3 /* Retrieve the indexed field from parameter (first field index is 1) */
101     IDF_FIELD *
102     idf_getfield(IDF_PARAMETER *param, int fn)
103     {
104     IDF_FIELD *fld;
105    
106     if ((param == NULL) | (fn <= 0))
107     return(NULL);
108     fld = param->flist;
109     while ((--fn > 0) & (fld != NULL))
110     fld = fld->next;
111     return(fld);
112     }
113    
114 greg 2.1 /* Delete the specified parameter from loaded IDF */
115     int
116     idf_delparam(IDF_LOADED *idf, IDF_PARAMETER *param)
117     {
118     LUENT *pent;
119     IDF_PARAMETER *pptr, *plast;
120    
121     if ((idf == NULL) | (param == NULL))
122     return(0);
123     /* remove from parameter table */
124     pent = lu_find(&idf->ptab, param->pname);
125     for (plast = NULL, pptr = (IDF_PARAMETER *)pent->data;
126     pptr != NULL; plast = pptr, pptr = pptr->pnext)
127     if (pptr == param)
128     break;
129     if (pptr == NULL)
130     return(0);
131     if (plast == NULL)
132     pent->data = (char *)param->pnext;
133     else
134     plast->pnext = param->pnext;
135     /* remove from global list */
136     for (plast = NULL, pptr = idf->pfirst;
137 greg 2.4 pptr != param; plast = pptr, pptr = pptr->dnext)
138     if (pptr == NULL)
139     return(0);
140 greg 2.1 if (plast == NULL)
141     idf->pfirst = param->dnext;
142     else
143     plast->dnext = param->dnext;
144     if (idf->plast == param)
145     idf->plast = plast;
146     /* free field list */
147     while (param->flist != NULL) {
148     IDF_FIELD *fdel = param->flist;
149     param->flist = fdel->next;
150     free(fdel);
151     }
152     free(param); /* free parameter struct */
153     return(1);
154     }
155    
156 greg 2.4 /* Move the specified parameter to the given position in the IDF */
157     int
158     idf_movparam(IDF_LOADED *idf, IDF_PARAMETER *param, IDF_PARAMETER *prev)
159     {
160     IDF_PARAMETER *pptr, *plast;
161    
162     if ((idf == NULL) | (param == NULL))
163     return(0);
164     /* find in IDF list, first*/
165     for (plast = NULL, pptr = idf->pfirst;
166     pptr != param; plast = pptr, pptr = pptr->dnext)
167     if (pptr == NULL)
168     return(0);
169     if (plast == NULL) {
170     if (prev == NULL)
171     return(1); /* already in place */
172     idf->pfirst = param->dnext;
173     } else {
174     if (prev == plast)
175     return(1); /* already in place */
176     plast->dnext = param->dnext;
177     }
178     if (idf->plast == param)
179     idf->plast = plast;
180     if (prev == NULL) { /* means they want it at beginning */
181     param->dnext = idf->pfirst;
182     idf->pfirst = param;
183     } else {
184     param->dnext = prev->dnext;
185     prev->dnext = param;
186     }
187     return(1);
188     }
189    
190 greg 2.1 /* Get a named parameter list */
191     IDF_PARAMETER *
192     idf_getparam(IDF_LOADED *idf, const char *pname)
193     {
194     if ((idf == NULL) | (pname == NULL))
195     return(NULL);
196    
197     return((IDF_PARAMETER *)lu_find(&idf->ptab,pname)->data);
198     }
199    
200     /* Read an argument including terminating ',' or ';' -- return which */
201     static int
202     idf_read_argument(char *buf, FILE *fp, int trim)
203     {
204     int skipwhite = trim;
205     char *cp = buf;
206     int c;
207    
208     while ((c = getc(fp)) != EOF && (c != ',') & (c != ';')) {
209     if (skipwhite && isspace(c))
210     continue;
211     skipwhite = 0;
212 greg 2.2 if (cp-buf < IDF_MAXARGL-1)
213 greg 2.1 *cp++ = c;
214     }
215     if (trim)
216     while (cp > buf && isspace(cp[-1]))
217     --cp;
218     *cp = '\0';
219     return(c);
220     }
221    
222     /* Read a comment, including all white space up to next alpha character */
223     static void
224     idf_read_comment(char *buf, int len, FILE *fp)
225     {
226     int incomm = 0;
227     char *cp = buf;
228     char dummyc;
229     int c;
230    
231     if ((buf == NULL) | (len <= 0)) {
232     buf = &dummyc;
233     len = 1;
234     }
235 greg 2.3 while ((c = getc(fp)) != EOF &&
236     (isspace(c) || (incomm += (c == '!')))) {
237     if (c == '\n')
238 greg 2.1 incomm = 0;
239     if (cp-buf < len-1)
240     *cp++ = c;
241     }
242     *cp = '\0';
243     if (c != EOF)
244     ungetc(c, fp);
245     }
246    
247     /* Read a parameter and fields from an open file and add to end of list */
248     IDF_PARAMETER *
249     idf_readparam(IDF_LOADED *idf, FILE *fp)
250     {
251 greg 2.2 char abuf[IDF_MAXARGL], cbuf[IDF_MAXLINE];
252 greg 2.1 int delim;
253     IDF_PARAMETER *pnew;
254    
255     if ((delim = idf_read_argument(abuf, fp, 1)) == EOF)
256     return(NULL);
257     idf_read_comment(cbuf, IDF_MAXLINE, fp);
258     pnew = idf_newparam(idf, abuf, cbuf, NULL);
259     while (delim == ',')
260     if ((delim = idf_read_argument(abuf, fp, 1)) != EOF) {
261     idf_read_comment(cbuf, IDF_MAXLINE, fp);
262     idf_addfield(pnew, abuf, cbuf);
263     }
264     if (delim != ';')
265 greg 2.3 fputs("Expected ';' at end of parameter list!\n", stderr);
266 greg 2.1 return(pnew);
267     }
268    
269 greg 2.2 /* Upper-case string hashing function */
270     static unsigned long
271     strcasehash(const char *s)
272     {
273     char strup[IDF_MAXARGL];
274     char *cdst = strup;
275    
276     while ((*cdst++ = toupper(*s++)))
277     if (cdst >= strup+(sizeof(strup)-1)) {
278     *cdst = '\0';
279     break;
280     }
281     return(lu_shash(strup));
282     }
283    
284 greg 2.1 /* Initialize an IDF struct */
285     IDF_LOADED *
286     idf_create(const char *hdrcomm)
287     {
288     IDF_LOADED *idf = (IDF_LOADED *)calloc(1, sizeof(IDF_LOADED));
289    
290     if (idf == NULL)
291     return(NULL);
292 greg 2.2 idf->ptab.hashf = &strcasehash;
293     idf->ptab.keycmp = &strcasecmp;
294 greg 2.1 idf->ptab.freek = &free;
295     lu_init(&idf->ptab, 200);
296     if (hdrcomm != NULL && *hdrcomm) {
297     idf->hrem = (char *)malloc(strlen(hdrcomm)+1);
298     if (idf->hrem != NULL)
299     strcpy(idf->hrem, hdrcomm);
300     }
301     return(idf);
302     }
303    
304 greg 2.4 /* Add comment(s) to header */
305     int
306     idf_add2hdr(IDF_LOADED *idf, const char *hdrcomm)
307     {
308     int olen, len;
309    
310     if ((idf == NULL) | (hdrcomm == NULL))
311     return(0);
312     len = strlen(hdrcomm);
313     if (!len)
314     return(0);
315     if (idf->hrem == NULL)
316     olen = 0;
317     else
318     olen = strlen(idf->hrem);
319     if (olen)
320     idf->hrem = (char *)realloc(idf->hrem, olen+len+1);
321     else
322     idf->hrem = (char *)malloc(len+1);
323     if (idf->hrem == NULL)
324     return(0);
325     strcpy(idf->hrem+olen, hdrcomm);
326     return(1);
327     }
328    
329 greg 2.1 /* Load an Input Data File */
330     IDF_LOADED *
331     idf_load(const char *fname)
332     {
333 greg 2.4 char hdrcomm[256*IDF_MAXLINE];
334 greg 2.1 FILE *fp;
335     IDF_LOADED *idf;
336    
337     if (fname == NULL)
338     fp = stdin; /* open file if not stdin */
339     else if ((fp = fopen(fname, "r")) == NULL)
340     return(NULL);
341     /* read header comments */
342 greg 2.3 idf_read_comment(hdrcomm, sizeof(hdrcomm), fp);
343 greg 2.1 idf = idf_create(hdrcomm); /* create IDF struct */
344     if (idf == NULL)
345     return(NULL);
346     /* read each parameter */
347     while (idf_readparam(idf, fp) != NULL)
348     ;
349     if (fp != stdin) /* close file if not stdin */
350     fclose(fp);
351     return(idf); /* success! */
352     }
353    
354     /* Write a parameter and fields to an open file */
355     int
356 greg 2.4 idf_writeparam(IDF_PARAMETER *param, FILE *fp, int incl_comm)
357 greg 2.1 {
358     IDF_FIELD *fptr;
359    
360     if ((param == NULL) | (fp == NULL))
361     return(0);
362     fputs(param->pname, fp);
363     fputc(',', fp);
364 greg 2.4 if (incl_comm)
365     fputs(param->rem, fp);
366 greg 2.1 for (fptr = param->flist; fptr != NULL; fptr = fptr->next) {
367 greg 2.4 if (!incl_comm)
368     fputs("\n\t", fp);
369 greg 2.1 fputs(fptr->arg, fp);
370     fputc((fptr->next==NULL ? ';' : ','), fp);
371 greg 2.4 if (incl_comm)
372     fputs(fptr->rem, fp);
373 greg 2.1 }
374 greg 2.4 if (!incl_comm)
375     fputs("\n\n", fp);
376 greg 2.1 return(!ferror(fp));
377     }
378    
379     /* Write out an Input Data File */
380     int
381 greg 2.4 idf_write(IDF_LOADED *idf, const char *fname, int incl_comm)
382 greg 2.1 {
383     FILE *fp;
384     IDF_PARAMETER *pptr;
385    
386     if (idf == NULL)
387     return(0);
388     if (fname == NULL)
389     fp = stdout; /* open file if not stdout */
390     else if ((fp = fopen(fname, "w")) == NULL)
391     return(0);
392 greg 2.4 if (incl_comm)
393     fputs(idf->hrem, fp); /* write header then parameters */
394 greg 2.1 for (pptr = idf->pfirst; pptr != NULL; pptr = pptr->dnext)
395 greg 2.4 if (!idf_writeparam(pptr, fp, incl_comm>0)) {
396 greg 2.1 fclose(fp);
397     return(0);
398     }
399     if (fp == stdout) /* flush/close file & check status */
400     return(fflush(fp) == 0);
401     return(fclose(fp) == 0);
402     }
403    
404     /* Free a loaded IDF */
405     void
406     idf_free(IDF_LOADED *idf)
407     {
408     if (idf == NULL)
409     return;
410     if (idf->hrem != NULL)
411     free(idf->hrem);
412     while (idf->pfirst != NULL)
413     idf_delparam(idf, idf->pfirst);
414     lu_done(&idf->ptab);
415     }