ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/eplus_idf.c
Revision: 2.3
Committed: Sun Feb 9 02:18:16 2014 UTC (10 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +21 -10 lines
Log Message:
Fixed bug in comment reader and added idf_getfield() call

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.3 static const char RCSid[] = "$Id: eplus_idf.c,v 2.2 2014/02/01 02:13:24 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     pptr != NULL; plast = pptr, pptr = pptr->dnext)
138     if (pptr == param)
139     break;
140     if (pptr == NULL)
141     return(0);
142     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     /* Get a named parameter list */
159     IDF_PARAMETER *
160     idf_getparam(IDF_LOADED *idf, const char *pname)
161     {
162     if ((idf == NULL) | (pname == NULL))
163     return(NULL);
164    
165     return((IDF_PARAMETER *)lu_find(&idf->ptab,pname)->data);
166     }
167    
168     /* Read an argument including terminating ',' or ';' -- return which */
169     static int
170     idf_read_argument(char *buf, FILE *fp, int trim)
171     {
172     int skipwhite = trim;
173     char *cp = buf;
174     int c;
175    
176     while ((c = getc(fp)) != EOF && (c != ',') & (c != ';')) {
177     if (skipwhite && isspace(c))
178     continue;
179     skipwhite = 0;
180 greg 2.2 if (cp-buf < IDF_MAXARGL-1)
181 greg 2.1 *cp++ = c;
182     }
183     if (trim)
184     while (cp > buf && isspace(cp[-1]))
185     --cp;
186     *cp = '\0';
187     return(c);
188     }
189    
190     /* Read a comment, including all white space up to next alpha character */
191     static void
192     idf_read_comment(char *buf, int len, FILE *fp)
193     {
194     int incomm = 0;
195     char *cp = buf;
196     char dummyc;
197     int c;
198    
199     if ((buf == NULL) | (len <= 0)) {
200     buf = &dummyc;
201     len = 1;
202     }
203 greg 2.3 while ((c = getc(fp)) != EOF &&
204     (isspace(c) || (incomm += (c == '!')))) {
205     if (c == '\n')
206 greg 2.1 incomm = 0;
207     if (cp-buf < len-1)
208     *cp++ = c;
209     }
210     *cp = '\0';
211     if (c != EOF)
212     ungetc(c, fp);
213     }
214    
215     /* Read a parameter and fields from an open file and add to end of list */
216     IDF_PARAMETER *
217     idf_readparam(IDF_LOADED *idf, FILE *fp)
218     {
219 greg 2.2 char abuf[IDF_MAXARGL], cbuf[IDF_MAXLINE];
220 greg 2.1 int delim;
221     IDF_PARAMETER *pnew;
222    
223     if ((delim = idf_read_argument(abuf, fp, 1)) == EOF)
224     return(NULL);
225     idf_read_comment(cbuf, IDF_MAXLINE, fp);
226     pnew = idf_newparam(idf, abuf, cbuf, NULL);
227     while (delim == ',')
228     if ((delim = idf_read_argument(abuf, fp, 1)) != EOF) {
229     idf_read_comment(cbuf, IDF_MAXLINE, fp);
230     idf_addfield(pnew, abuf, cbuf);
231     }
232     if (delim != ';')
233 greg 2.3 fputs("Expected ';' at end of parameter list!\n", stderr);
234 greg 2.1 return(pnew);
235     }
236    
237 greg 2.2 /* Upper-case string hashing function */
238     static unsigned long
239     strcasehash(const char *s)
240     {
241     char strup[IDF_MAXARGL];
242     char *cdst = strup;
243    
244     while ((*cdst++ = toupper(*s++)))
245     if (cdst >= strup+(sizeof(strup)-1)) {
246     *cdst = '\0';
247     break;
248     }
249     return(lu_shash(strup));
250     }
251    
252 greg 2.1 /* Initialize an IDF struct */
253     IDF_LOADED *
254     idf_create(const char *hdrcomm)
255     {
256     IDF_LOADED *idf = (IDF_LOADED *)calloc(1, sizeof(IDF_LOADED));
257    
258     if (idf == NULL)
259     return(NULL);
260 greg 2.2 idf->ptab.hashf = &strcasehash;
261     idf->ptab.keycmp = &strcasecmp;
262 greg 2.1 idf->ptab.freek = &free;
263     lu_init(&idf->ptab, 200);
264     if (hdrcomm != NULL && *hdrcomm) {
265     idf->hrem = (char *)malloc(strlen(hdrcomm)+1);
266     if (idf->hrem != NULL)
267     strcpy(idf->hrem, hdrcomm);
268     }
269     return(idf);
270     }
271    
272     /* Load an Input Data File */
273     IDF_LOADED *
274     idf_load(const char *fname)
275     {
276 greg 2.3 char hdrcomm[300*IF_MAXLINE];
277 greg 2.1 FILE *fp;
278     IDF_LOADED *idf;
279    
280     if (fname == NULL)
281     fp = stdin; /* open file if not stdin */
282     else if ((fp = fopen(fname, "r")) == NULL)
283     return(NULL);
284     /* read header comments */
285 greg 2.3 idf_read_comment(hdrcomm, sizeof(hdrcomm), fp);
286 greg 2.1 idf = idf_create(hdrcomm); /* create IDF struct */
287     if (idf == NULL)
288     return(NULL);
289     /* read each parameter */
290     while (idf_readparam(idf, fp) != NULL)
291     ;
292     if (fp != stdin) /* close file if not stdin */
293     fclose(fp);
294     return(idf); /* success! */
295     }
296    
297     /* Write a parameter and fields to an open file */
298     int
299     idf_writeparam(IDF_PARAMETER *param, FILE *fp)
300     {
301     IDF_FIELD *fptr;
302    
303     if ((param == NULL) | (fp == NULL))
304     return(0);
305     fputs(param->pname, fp);
306     fputc(',', fp);
307     fputs(param->rem, fp);
308     for (fptr = param->flist; fptr != NULL; fptr = fptr->next) {
309     fputs(fptr->arg, fp);
310     fputc((fptr->next==NULL ? ';' : ','), fp);
311     fputs(fptr->rem, fp);
312     }
313     return(!ferror(fp));
314     }
315    
316     /* Write out an Input Data File */
317     int
318     idf_write(IDF_LOADED *idf, const char *fname)
319     {
320     FILE *fp;
321     IDF_PARAMETER *pptr;
322    
323     if (idf == NULL)
324     return(0);
325     if (fname == NULL)
326     fp = stdout; /* open file if not stdout */
327     else if ((fp = fopen(fname, "w")) == NULL)
328     return(0);
329     fputs(idf->hrem, fp); /* write header then parameters */
330     for (pptr = idf->pfirst; pptr != NULL; pptr = pptr->dnext)
331     if (!idf_writeparam(pptr, fp)) {
332     fclose(fp);
333     return(0);
334     }
335     if (fp == stdout) /* flush/close file & check status */
336     return(fflush(fp) == 0);
337     return(fclose(fp) == 0);
338     }
339    
340     /* Free a loaded IDF */
341     void
342     idf_free(IDF_LOADED *idf)
343     {
344     if (idf == NULL)
345     return;
346     if (idf->hrem != NULL)
347     free(idf->hrem);
348     while (idf->pfirst != NULL)
349     idf_delparam(idf, idf->pfirst);
350     lu_done(&idf->ptab);
351     }