ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/eplus_idf.c
Revision: 2.2
Committed: Sat Feb 1 02:13:24 2014 UTC (10 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +20 -5 lines
Log Message:
Made sure parameter names are case-insensitive in lookups

File Contents

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