ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/eplus_idf.c
Revision: 2.5
Committed: Sun Feb 9 22:19:30 2014 UTC (10 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +3 -1 lines
Log Message:
Partial implementation of eplus_adduvf

File Contents

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