ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/loadvars.c
Revision: 2.19
Committed: Fri Jun 9 22:52:47 2023 UTC (11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.18: +12 -5 lines
Log Message:
fix: Preserve spaces in quoted strings

File Contents

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