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 (10 hours, 35 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: loadvars.c,v 2.23 2025/02/06 21:45:00 greg Exp $";
3 #endif
4 /*
5 * Routines for loading and checking variables from file.
6 */
7
8 #include "copyright.h"
9
10 #include <ctype.h>
11
12 #include "standard.h"
13 #include "paths.h"
14 #include "vars.h"
15
16 #define NOCHAR 127 /* constant for character to delete */
17
18 extern char *fgetline();
19
20
21 void
22 loadvars( /* load variables into vv from file */
23 const char *rfname
24 )
25 {
26 FILE *fp;
27 char buf[512];
28 char *cp;
29
30 if (rfname == NULL)
31 fp = stdin;
32 else if ((fp = fopen(rfname, "r")) == NULL) {
33 perror(rfname);
34 quit(1);
35 }
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 if (setvariable(buf, matchvar) < 0) {
51 fprintf(stderr, "%s: unknown variable: %s\n",
52 rfname, buf);
53 quit(1);
54 }
55 }
56 if (fp != stdin)
57 fclose(fp);
58 }
59
60
61 int
62 setvariable( /* assign variable according to string */
63 const char *ass,
64 VARIABLE *(*mv)(const char*)
65 )
66 {
67 int quote = '\0';
68 char varname[32];
69 int n;
70 char *cp;
71 VARIABLE *vp;
72 int i;
73
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 return(0); /* no variable name! */
83 /* 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 if (!n)
90 return(0); /* no assignment */
91 /* match variable from list */
92 vp = (*mv)(varname);
93 if (vp == NULL)
94 return(-1);
95 /* assign new value */
96 if ( (i = vp->nass) ) {
97 cp = vp->value;
98 while (i--)
99 while (*cp++)
100 ;
101 i = cp - vp->value;
102 vp->value = (char *)realloc((void *)vp->value, i+n+1);
103 } else
104 vp->value = (char *)malloc(n+1);
105 if (vp->value == NULL) {
106 perror(progname);
107 quit(1);
108 }
109 cp = vp->value+i; /* copy value */
110 *cp = *ass;
111 for (i = 1; i <= n; i++) {
112 if (ass[i] == NOCHAR)
113 continue;
114 if (quote) { /* don't change quoted parts */
115 quote *= (ass[i] != quote);
116 } else { /* otherwise, squeeze spaces */
117 if (isspace(*cp))
118 while (isspace(ass[i])|(ass[i]==NOCHAR))
119 i++;
120 if ((ass[i] == '"') | (ass[i] == '\''))
121 quote = ass[i];
122 }
123 *++cp = ass[i];
124 }
125 if (isspace(*cp)) /* remove trailing space */
126 *cp = '\0';
127 return(++vp->nass);
128 }
129
130
131 VARIABLE *
132 matchvar( /* match a variable by its name */
133 const char *nam
134 )
135 {
136 int n = strlen(nam);
137 int i;
138
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 nvalue( /* return nth variable value */
148 int vn,
149 int n
150 )
151 {
152 char *cp;
153
154 if ((vval(vn) == NULL) | (n < 0) | (n >= vdef(vn)))
155 return(NULL);
156 cp = vval(vn);
157 while (n--)
158 while (*cp++)
159 ;
160 return(cp);
161 }
162
163
164 void
165 checkvalues(void) /* check assignments */
166 {
167 int i;
168
169 for (i = 0; i < NVARS; i++)
170 if (vv[i].fixval != NULL)
171 (*vv[i].fixval)(vv+i);
172 }
173
174
175 void
176 onevalue( /* only one assignment for this variable */
177 VARIABLE *vp
178 )
179 {
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 void
193 catvalues( /* concatenate variable values */
194 VARIABLE *vp
195 )
196 {
197 char *cp;
198
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 badmatch( /* case insensitive truncated comparison */
211 char *tv,
212 char *cv
213 )
214 {
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 void
225 boolvalue( /* check boolean for legal values */
226 VARIABLE *vp
227 )
228 {
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 quit(1);
242 }
243
244
245 void
246 qualvalue( /* check qualitative var. for legal values */
247 VARIABLE *vp
248 )
249 {
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 quit(1);
266 }
267
268 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
285 void
286 intvalue( /* check integer variable for legal values */
287 VARIABLE *vp
288 )
289 {
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 quit(1);
296 }
297
298
299 void
300 fltvalue( /* check float variable for legal values */
301 VARIABLE *vp
302 )
303 {
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 quit(1);
310 }
311
312
313 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 void
329 printvars( /* print variable values */
330 FILE *fp
331 )
332 {
333 int i, j, k, clipline;
334 char *cp;
335
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 fputc('=', fp);
340 if (!singlevar(&vv[i]))
341 fputc(' ', fp);
342 k = clipline = ( vv[i].fixval == catvalues ? 64 : 236 )
343 - strlen(vnam(i)) ;
344 cp = nvalue(i, j);
345 while (*cp) {
346 putc(*cp++, fp);
347 if (--k <= 0) { /* line too long */
348 while (*cp && !isspace(*cp))
349 fputc(*cp++, fp); /* finish this word */
350 if (*cp) { /* start new line */
351 if (vv[i].fixval == catvalues) {
352 fputc('\n', fp);
353 fputs(vnam(i), fp);
354 fputc('=', fp);
355 } else
356 fputs(" \\\n", fp);
357 k = clipline;
358 }
359 }
360 }
361 fputc('\n', fp);
362 }
363 fflush(fp);
364 }