ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/loadvars.c
Revision: 2.24
Committed: Sat Jun 7 05:09:45 2025 UTC (15 hours, 58 minutes ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.23: +2 -3 lines
Log Message:
refactor: Put some declarations into "paths.h" and included in "platform.h"

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.24 static const char RCSid[] = "$Id: loadvars.c,v 2.23 2025/02/06 21:45:00 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Routines for loading and checking variables from file.
6     */
7    
8 greg 2.10 #include "copyright.h"
9 greg 2.9
10 greg 2.1 #include <ctype.h>
11 schorsch 2.12
12     #include "standard.h"
13 greg 2.24 #include "paths.h"
14 greg 2.1 #include "vars.h"
15    
16     #define NOCHAR 127 /* constant for character to delete */
17    
18 greg 2.4 extern char *fgetline();
19    
20 greg 2.1
21 greg 2.9 void
22 greg 2.15 loadvars( /* load variables into vv from file */
23 greg 2.17 const char *rfname
24 greg 2.15 )
25 greg 2.1 {
26     FILE *fp;
27     char buf[512];
28 greg 2.15 char *cp;
29 greg 2.1
30     if (rfname == NULL)
31     fp = stdin;
32     else if ((fp = fopen(rfname, "r")) == NULL) {
33     perror(rfname);
34 greg 2.5 quit(1);
35 greg 2.1 }
36     while (fgetline(buf, sizeof(buf), fp) != NULL) {
37     for (cp = buf; *cp; cp++) {
38     switch (*cp) {
39     case '\\':
40     *cp++ = NOCHAR;
41     continue;
42     case '#':
43     *cp = '\0';
44     break;
45     default:
46     continue;
47     }
48     break;
49     }
50 greg 2.6 if (setvariable(buf, matchvar) < 0) {
51     fprintf(stderr, "%s: unknown variable: %s\n",
52     rfname, buf);
53     quit(1);
54     }
55 greg 2.1 }
56 greg 2.16 if (fp != stdin)
57     fclose(fp);
58 greg 2.1 }
59    
60    
61 greg 2.6 int
62 greg 2.15 setvariable( /* assign variable according to string */
63 greg 2.17 const char *ass,
64 greg 2.18 VARIABLE *(*mv)(const char*)
65 greg 2.15 )
66 greg 2.1 {
67 greg 2.19 int quote = '\0';
68 greg 2.1 char varname[32];
69     int n;
70 greg 2.15 char *cp;
71     VARIABLE *vp;
72     int i;
73 greg 2.1
74     while (isspace(*ass)) /* skip leading space */
75     ass++;
76     cp = varname; /* extract name */
77     while (cp < varname+sizeof(varname)-1
78     && *ass && !isspace(*ass) && *ass != '=')
79     *cp++ = *ass++;
80     *cp = '\0';
81     if (!varname[0])
82 greg 2.6 return(0); /* no variable name! */
83 greg 2.1 /* trim value */
84     while (isspace(*ass) || *ass == '=')
85     ass++;
86     for (n = strlen(ass); n > 0; n--)
87     if (!isspace(ass[n-1]))
88     break;
89 greg 2.6 if (!n)
90     return(0); /* no assignment */
91 greg 2.1 /* match variable from list */
92 greg 2.6 vp = (*mv)(varname);
93     if (vp == NULL)
94     return(-1);
95 greg 2.1 /* assign new value */
96 schorsch 2.13 if ( (i = vp->nass) ) {
97 greg 2.1 cp = vp->value;
98     while (i--)
99     while (*cp++)
100     ;
101     i = cp - vp->value;
102 greg 2.11 vp->value = (char *)realloc((void *)vp->value, i+n+1);
103 greg 2.1 } else
104 greg 2.9 vp->value = (char *)malloc(n+1);
105 greg 2.1 if (vp->value == NULL) {
106     perror(progname);
107 greg 2.5 quit(1);
108 greg 2.1 }
109 greg 2.19 cp = vp->value+i; /* copy value */
110 greg 2.1 *cp = *ass;
111     for (i = 1; i <= n; i++) {
112     if (ass[i] == NOCHAR)
113     continue;
114 greg 2.19 if (quote) { /* don't change quoted parts */
115     quote *= (ass[i] != quote);
116     } else { /* otherwise, squeeze spaces */
117     if (isspace(*cp))
118 greg 2.21 while (isspace(ass[i])|(ass[i]==NOCHAR))
119 greg 2.19 i++;
120     if ((ass[i] == '"') | (ass[i] == '\''))
121     quote = ass[i];
122     }
123 greg 2.1 *++cp = ass[i];
124     }
125     if (isspace(*cp)) /* remove trailing space */
126     *cp = '\0';
127 greg 2.6 return(++vp->nass);
128 greg 2.1 }
129    
130    
131     VARIABLE *
132 greg 2.15 matchvar( /* match a variable by its name */
133 greg 2.17 const char *nam
134 greg 2.15 )
135 greg 2.1 {
136     int n = strlen(nam);
137 greg 2.15 int i;
138 greg 2.1
139     for (i = 0; i < NVARS; i++)
140     if (n >= vv[i].nick && !strncmp(nam, vv[i].name, n))
141     return(vv+i);
142     return(NULL);
143     }
144    
145    
146     char *
147 greg 2.15 nvalue( /* return nth variable value */
148     int vn,
149     int n
150     )
151 greg 2.1 {
152 greg 2.15 char *cp;
153 greg 2.1
154 schorsch 2.13 if ((vval(vn) == NULL) | (n < 0) | (n >= vdef(vn)))
155 greg 2.1 return(NULL);
156 greg 2.2 cp = vval(vn);
157 greg 2.1 while (n--)
158     while (*cp++)
159     ;
160     return(cp);
161     }
162    
163    
164 greg 2.9 void
165 greg 2.15 checkvalues(void) /* check assignments */
166 greg 2.1 {
167 greg 2.15 int i;
168 greg 2.1
169     for (i = 0; i < NVARS; i++)
170     if (vv[i].fixval != NULL)
171     (*vv[i].fixval)(vv+i);
172     }
173    
174    
175 greg 2.9 void
176 greg 2.15 onevalue( /* only one assignment for this variable */
177     VARIABLE *vp
178     )
179 greg 2.1 {
180     if (vp->nass < 2)
181     return;
182     if (!nowarn)
183     fprintf(stderr,
184     "%s: warning - multiple assignment of variable '%s'\n",
185     progname, vp->name);
186     do
187     vp->value += strlen(vp->value)+1;
188     while (--vp->nass > 1);
189     }
190    
191    
192 greg 2.9 void
193 greg 2.15 catvalues( /* concatenate variable values */
194     VARIABLE *vp
195     )
196 greg 2.1 {
197 greg 2.15 char *cp;
198 greg 2.1
199     if (vp->nass < 2)
200     return;
201     for (cp = vp->value; vp->nass > 1; vp->nass--) {
202     while (*cp)
203     cp++;
204     *cp++ = ' ';
205     }
206     }
207    
208    
209     int
210 greg 2.15 badmatch( /* case insensitive truncated comparison */
211     char *tv,
212     char *cv
213     )
214 greg 2.1 {
215     if (!*tv) return(1); /* null string cannot match */
216     do
217     if (UPPER(*tv) != *cv++)
218     return(1);
219     while (*++tv);
220     return(0); /* OK */
221     }
222    
223    
224 greg 2.9 void
225 greg 2.15 boolvalue( /* check boolean for legal values */
226     VARIABLE *vp
227     )
228 greg 2.1 {
229     if (!vp->nass) return;
230     onevalue(vp);
231     switch (UPPER(vp->value[0])) {
232     case 'T':
233     if (badmatch(vp->value, "TRUE")) break;
234     return;
235     case 'F':
236     if (badmatch(vp->value, "FALSE")) break;
237     return;
238     }
239     fprintf(stderr, "%s: illegal value for boolean variable '%s'\n",
240     progname, vp->name);
241 greg 2.5 quit(1);
242 greg 2.1 }
243    
244    
245 greg 2.9 void
246 greg 2.15 qualvalue( /* check qualitative var. for legal values */
247     VARIABLE *vp
248     )
249 greg 2.1 {
250     if (!vp->nass) return;
251     onevalue(vp);
252     switch (UPPER(vp->value[0])) {
253     case 'L':
254     if (badmatch(vp->value, "LOW")) break;
255     return;
256     case 'M':
257     if (badmatch(vp->value, "MEDIUM")) break;
258     return;
259     case 'H':
260     if (badmatch(vp->value, "HIGH")) break;
261     return;
262     }
263     fprintf(stderr, "%s: illegal value for qualitative variable '%s'\n",
264     progname, vp->name);
265 greg 2.5 quit(1);
266 greg 2.1 }
267    
268 greg 2.20 void
269     strvalue( /* check for single (quoted) string value */
270     VARIABLE *vp
271     )
272     {
273     if (!vp->nass) return;
274     onevalue(vp);
275     if ((vp->value[0] == '"') | (vp->value[0] == '\'')) {
276     char *cp = vp->value + strlen(vp->value+1);
277     if ((cp != vp->value) & (*cp == vp->value[0])) {
278     vp->value++; /* elide quotation marks */
279     *cp = '\0';
280     }
281     }
282     }
283    
284 greg 2.1
285 greg 2.9 void
286 greg 2.15 intvalue( /* check integer variable for legal values */
287     VARIABLE *vp
288     )
289 greg 2.1 {
290     if (!vp->nass) return;
291     onevalue(vp);
292     if (isint(vp->value)) return;
293     fprintf(stderr, "%s: illegal value for integer variable '%s'\n",
294     progname, vp->name);
295 greg 2.5 quit(1);
296 greg 2.1 }
297    
298    
299 greg 2.9 void
300 greg 2.15 fltvalue( /* check float variable for legal values */
301     VARIABLE *vp
302     )
303 greg 2.1 {
304     if (!vp->nass) return;
305     onevalue(vp);
306     if (isflt(vp->value)) return;
307     fprintf(stderr, "%s: illegal value for real variable '%s'\n",
308     progname, vp->name);
309 greg 2.5 quit(1);
310 greg 2.1 }
311    
312    
313 greg 2.23 int
314     singlevar( /* assigned single value? */
315     VARIABLE *vp
316     )
317     {
318     if (vp->fixval == catvalues)
319     return(0);
320    
321     return((vp->fixval == strvalue) |
322     (vp->fixval == fltvalue) |
323     (vp->fixval == intvalue) |
324     (vp->fixval == qualvalue) |
325     (vp->fixval == boolvalue));
326     }
327    
328 greg 2.9 void
329 greg 2.15 printvars( /* print variable values */
330     FILE *fp
331     )
332 greg 2.1 {
333     int i, j, k, clipline;
334 greg 2.15 char *cp;
335 greg 2.1
336     for (i = 0; i < NVARS; i++) /* print each variable */
337     for (j = 0; j < vdef(i); j++) { /* print each assignment */
338     fputs(vnam(i), fp);
339 greg 2.22 fputc('=', fp);
340 greg 2.23 if (!singlevar(&vv[i]))
341     fputc(' ', fp);
342 gwlarson 2.8 k = clipline = ( vv[i].fixval == catvalues ? 64 : 236 )
343 greg 2.1 - strlen(vnam(i)) ;
344 greg 2.2 cp = nvalue(i, j);
345 greg 2.1 while (*cp) {
346     putc(*cp++, fp);
347     if (--k <= 0) { /* line too long */
348     while (*cp && !isspace(*cp))
349 gwlarson 2.7 fputc(*cp++, fp); /* finish this word */
350 greg 2.1 if (*cp) { /* start new line */
351 gwlarson 2.7 if (vv[i].fixval == catvalues) {
352     fputc('\n', fp);
353     fputs(vnam(i), fp);
354     fputc('=', fp);
355     } else
356     fputs(" \\\n", fp);
357 greg 2.1 k = clipline;
358     }
359     }
360     }
361 gwlarson 2.7 fputc('\n', fp);
362 greg 2.1 }
363     fflush(fp);
364     }