ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/mgvars.c
Revision: 1.4
Committed: Fri Nov 14 00:14:40 2003 UTC (21 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.3: +62 -44 lines
Log Message:
Continued ansification, and got rid of gets().

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mgvars.c,v 1.3 2003/10/27 10:28:59 schorsch Exp $";
3 #endif
4 /*
5 * mgvars.c - routines dealing with graph variables.
6 *
7 * 6/23/86
8 *
9 * Greg Ward Larson
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <math.h>
15 #include <string.h>
16 #include <ctype.h>
17
18 #include "rtprocess.h"
19 #include "rterror.h"
20 #include "rtio.h"
21 #include "calcomp.h"
22 #include "mgvars.h"
23
24 #define MAXLINE 512
25
26 #define isnum(c) (isdigit(c)||(c)=='-'||(c)=='+'||(c)=='.'||(c)=='e'||(c)=='E')
27
28 static void mgprint(register VARIABLE *vp, FILE *fp);
29 static void setivar(char *vname, char *fname, char *definition);
30 static char *findfile(char *fname, register char **pathlist);
31 static void loaddata(char *fname, FILE *fp, register DARRAY *dp);
32 static void undefine(register VARIABLE *vp);
33
34 extern char *progname, *libpath[];
35
36 IVAR *ivhead = NULL; /* intermediate variables */
37
38 VARIABLE gparam[NVARS] = { /* standard variables */
39 { "fthick", REAL, "frame thickness" },
40 { "grid", REAL, "grid on?" },
41 { "legend", STRING, "legend title" },
42 { "othick", REAL, "origin thickness" },
43 { "period", REAL, "period of polar plot" },
44 { "subtitle", STRING },
45 { "symfile", STRING, "symbol file" },
46 { "tstyle", REAL, "tick mark style" },
47 { "title", STRING },
48 { "xlabel", STRING },
49 { "xmap", FUNCTION, "x axis mapping function" },
50 { "xmax", REAL },
51 { "xmin", REAL },
52 { "xstep", REAL },
53 { "ylabel", STRING },
54 { "ymap", FUNCTION, "y axis mapping function" },
55 { "ymax", REAL },
56 { "ymin", REAL },
57 { "ystep", REAL },
58 };
59
60 VARIABLE cparam[MAXCUR][NCVARS] = { /* curve variables */
61 {
62 { "A", FUNCTION, "function for curve A" },
63 { "Acolor", REAL, "color for A" },
64 { "Adata", DATA, "point data for A" },
65 { "Alabel", STRING },
66 { "Alintype", REAL, "line type for A" },
67 { "Anpoints", REAL, "number of points for A" },
68 { "Asymsize", REAL, "symbol size for A" },
69 { "Asymtype", STRING, "symbol type for A" },
70 { "Athick", REAL, "line thickness for A" },
71 }, {
72 { "B", FUNCTION, "function for curve B" },
73 { "Bcolor", REAL, "color for B" },
74 { "Bdata", DATA, "point data for B" },
75 { "Blabel", STRING },
76 { "Blintype", REAL, "line type for B" },
77 { "Bnpoints", REAL, "number of points for B" },
78 { "Bsymsize", REAL, "symbol size for B" },
79 { "Bsymtype", STRING, "symbol type for B" },
80 { "Bthick", REAL, "line thickness for B" },
81 }, {
82 { "C", FUNCTION, "function for curve C" },
83 { "Ccolor", REAL, "color for C" },
84 { "Cdata", DATA, "point data for C" },
85 { "Clabel", STRING },
86 { "Clintype", REAL, "line type for C" },
87 { "Cnpoints", REAL, "number of points for C" },
88 { "Csymsize", REAL, "symbol size for C" },
89 { "Csymtype", STRING, "symbol type for C" },
90 { "Cthick", REAL, "line thickness for C" },
91 }, {
92 { "D", FUNCTION, "function for curve D" },
93 { "Dcolor", REAL, "color for D" },
94 { "Ddata", DATA, "point data for D" },
95 { "Dlabel", STRING },
96 { "Dlintype", REAL, "line type for D" },
97 { "Dnpoints", REAL, "number of points for D" },
98 { "Dsymsize", REAL, "symbol size for D" },
99 { "Dsymtype", STRING, "symbol type for D" },
100 { "Dthick", REAL, "line thickness for D" },
101 }, {
102 { "E", FUNCTION, "function for curve E" },
103 { "Ecolor", REAL, "color for E" },
104 { "Edata", DATA, "point data for E" },
105 { "Elabel", STRING },
106 { "Elintype", REAL, "line type for E" },
107 { "Enpoints", REAL, "number of points for E" },
108 { "Esymsize", REAL, "symbol size for E" },
109 { "Esymtype", STRING, "symbol type for E" },
110 { "Ethick", REAL, "line thickness for E" },
111 }, {
112 { "F", FUNCTION, "function for curve F" },
113 { "Fcolor", REAL, "color for F" },
114 { "Fdata", DATA, "point data for F" },
115 { "Flabel", STRING },
116 { "Flintype", REAL, "line type for F" },
117 { "Fnpoints", REAL, "number of points for F" },
118 { "Fsymsize", REAL, "symbol size for F" },
119 { "Fsymtype", STRING, "symbol type for F" },
120 { "Fthick", REAL, "line thickness for F" },
121 }, {
122 { "G", FUNCTION, "function for curve G" },
123 { "Gcolor", REAL, "color for G" },
124 { "Gdata", DATA, "point data for G" },
125 { "Glabel", STRING },
126 { "Glintype", REAL, "line type for G" },
127 { "Gnpoints", REAL, "number of points for G" },
128 { "Gsymsize", REAL, "symbol size for G" },
129 { "Gsymtype", STRING, "symbol type for G" },
130 { "Gthick", REAL, "line thickness for G" },
131 }, {
132 { "H", FUNCTION, "function for curve H" },
133 { "Hcolor", REAL, "color for H" },
134 { "Hdata", DATA, "point data for H" },
135 { "Hlabel", STRING },
136 { "Hlintype", REAL, "line type for H" },
137 { "Hnpoints", REAL, "number of points for H" },
138 { "Hsymsize", REAL, "symbol size for H" },
139 { "Hsymtype", STRING, "symbol type for H" },
140 { "Hthick", REAL, "line thickness for H" },
141 },
142 };
143
144
145 void
146 mgclearall(void) /* clear all variable settings */
147 {
148 int j;
149 register IVAR *iv;
150 register int i;
151
152 for (iv = ivhead; iv != NULL; iv = iv->next) {
153 dremove(iv->name);
154 freestr(iv->name);
155 freestr(iv->dfn);
156 efree((char *)iv);
157 }
158 ivhead = NULL;
159
160 for (i = 0; i < NVARS; i++)
161 if (gparam[i].flags & DEFINED)
162 undefine(&gparam[i]);
163
164 for (j = 0; j < MAXCUR; j++)
165 for (i = 0; i < NCVARS; i++)
166 if (cparam[j][i].flags & DEFINED)
167 undefine(&cparam[j][i]);
168 }
169
170
171 void
172 mgload( /* load a file */
173 char *file
174 )
175 {
176 FILE *fp;
177 char sbuf[MAXLINE], *fgets();
178 int inquote;
179 register char *cp, *cp2;
180
181 if (file == NULL) {
182 fp = stdin;
183 file = "<stdin>";
184 } else if ((fp = fopen(file, "r")) == NULL) {
185 fprintf(stderr, "%s: Cannot open: %s\n", progname, file);
186 quit(1);
187 }
188 while (fgets(sbuf+1, sizeof(sbuf)-1, fp) != NULL) {
189 inquote = 0;
190 cp2 = sbuf;
191 for (cp = sbuf+1; *cp; cp++) /* condition the input line */
192 switch (*cp) {
193 case '#':
194 if (!inquote) {
195 cp[0] = '\n';
196 cp[1] = '\0';
197 break;
198 }
199 *cp2++ = *cp;
200 break;
201 case '"':
202 inquote = !inquote;
203 break;
204 case '\\':
205 if (!cp[1])
206 break;
207 if (cp[1] == '\n') {
208 cp[0] = '\0';
209 fgets(cp, sizeof(sbuf)-(cp-sbuf), fp);
210 cp--;
211 break;
212 }
213 *cp2++ = *++cp;
214 break;
215 case ' ':
216 case '\t':
217 case '\n':
218 if (!inquote)
219 break;
220 *cp2++ = *cp;
221 break;
222 default:
223 *cp2++ = *cp;
224 break;
225 }
226 *cp2 = '\0';
227 if (inquote) {
228 fputs(sbuf, stderr);
229 fprintf(stderr, "%s: %s: Missing quote\n",
230 progname, file);
231 quit(1);
232 }
233 if (sbuf[0])
234 setmgvar(file, fp, sbuf);
235 }
236 if (fp != stdin)
237 fclose(fp);
238 }
239
240
241 void
242 mgsave( /* save our variables */
243 char *file
244 )
245 {
246 FILE *fp;
247 int j;
248 register IVAR *iv;
249 register int i;
250
251 if (file == NULL)
252 fp = stdout;
253 else if ((fp = fopen(file, "w")) == NULL) {
254 fprintf(stderr, "%s: Cannot write: %s\n", progname, file);
255 quit(1);
256 }
257 for (iv = ivhead; iv != NULL; iv = iv->next)
258 fprintf(fp, "%s\n", iv->dfn);
259
260 for (i = 0; i < NVARS; i++)
261 if (gparam[i].flags & DEFINED)
262 mgprint(&gparam[i], fp);
263
264 for (j = 0; j < MAXCUR; j++)
265 for (i = 0; i < NCVARS; i++)
266 if (cparam[j][i].flags & DEFINED)
267 mgprint(&cparam[j][i], fp);
268
269 if (fp != stdout)
270 fclose(fp);
271 }
272
273
274 void
275 setmgvar( /* set a variable */
276 char *fname,
277 FILE *fp,
278 char *string
279 )
280 {
281 char name[128];
282 FILE *fp2;
283 register int i;
284 register char *s;
285 register VARIABLE *vp;
286
287 if (!strncmp(string, "include=", 8)) { /* include file */
288 if ((s = findfile(string+8, libpath)) == NULL) {
289 fprintf(stderr, "%s\n", string);
290 fprintf(stderr, "%s: %s: File not found: %s\n",
291 progname, fname, string+8);
292 quit(1);
293 }
294 strcpy(name, s);
295 mgload(name);
296 return;
297 }
298 s = string;
299 i = 0;
300 while (i < sizeof(name)-1 && isid(*s))
301 name[i++] = *s++;
302 name[i] = '\0';
303 vp = vlookup(name);
304 if (vp != NULL) {
305 undefine(vp);
306 switch (vp->type) {
307 case REAL:
308 case FUNCTION:
309 if ((*s == '(') != (vp->type == FUNCTION)) {
310 fprintf(stderr, "%s\n", string);
311 fprintf(stderr,
312 "%s: %s: Bad %s declaration: %s\n",
313 progname, fname,
314 vp->type == FUNCTION ?
315 "function" : "variable",
316 name);
317 quit(1);
318 }
319 scompile(string, fname, 0);
320 vp->v.dfn = savestr(string);
321 break;
322 case STRING:
323 if (*s++ != '=') {
324 fprintf(stderr, "%s\n", string);
325 fprintf(stderr, "%s: %s: Missing '='\n",
326 progname, fname);
327 quit(1);
328 }
329 vp->v.s = savestr(s);
330 break;
331 case DATA:
332 if (*s++ != '=') {
333 fprintf(stderr, "%s\n", string);
334 fprintf(stderr, "%s: %s: Missing '='\n",
335 progname, fname);
336 quit(1);
337 }
338 if (!*s) {
339 loaddata(fname, fp, &vp->v.d);
340 } else if (*s == '!') {
341 if ((fp2 = popen(s+1, "r")) == NULL) {
342 fprintf(stderr, "%s\n", string);
343 fprintf(stderr,
344 "%s: %s: Cannot execute: %s\n",
345 progname, fname, s+1);
346 quit(1);
347 }
348 loaddata(s, fp2, &vp->v.d);
349 pclose(fp2);
350 } else {
351 if ((fp2 = fopen(s, "r")) == NULL) {
352 fprintf(stderr, "%s\n", string);
353 fprintf(stderr,
354 "%s: %s: Data file not found: %s\n",
355 progname, fname, s);
356 quit(1);
357 }
358 loaddata(s, fp2, &vp->v.d);
359 fclose(fp2);
360 }
361 break;
362 }
363 vp->flags |= DEFINED;
364 } else
365 setivar(name, fname, string); /* intermediate */
366 }
367
368
369 static void
370 setivar( /* set an intermediate variable */
371 char *vname,
372 char *fname,
373 char *definition
374 )
375 {
376 IVAR ivbeg;
377 register IVAR *iv;
378
379 scompile(definition, fname, 0); /* compile the string */
380
381 ivbeg.next = ivhead;
382 for (iv = &ivbeg; iv->next != NULL; iv = iv->next)
383 if (!strcmp(vname, iv->next->name)) {
384 iv = iv->next;
385 freestr(iv->dfn);
386 iv->dfn = savestr(definition);
387 return;
388 }
389
390 iv->next = (IVAR *)emalloc(sizeof(IVAR));
391 iv = iv->next;
392 iv->name = savestr(vname);
393 iv->dfn = savestr(definition);
394 iv->next = NULL;
395 ivhead = ivbeg.next;
396 }
397
398
399 void
400 mgtoa( /* get a variable's value in ascii form */
401 register char *s,
402 VARIABLE *vp
403 )
404 {
405 register char *sv;
406
407 if (!(vp->flags & DEFINED)) {
408 strcpy(s, "UNDEFINED");
409 return;
410 }
411 switch (vp->type) {
412 case REAL:
413 case FUNCTION:
414 sv = vp->v.dfn;
415 while (*sv != '=' && *sv != ':')
416 sv++;
417 while (*++sv && *sv != ';')
418 *s++ = *sv;
419 *s = '\0';
420 break;
421 case STRING:
422 strcpy(s, vp->v.s);
423 break;
424 case DATA:
425 strcpy(s, "DATA");
426 break;
427 }
428 }
429
430
431 static void
432 mgprint( /* print a variable definition */
433 register VARIABLE *vp,
434 FILE *fp
435 )
436 {
437 register int i;
438
439 switch (vp->type) {
440 case REAL:
441 case FUNCTION:
442 fprintf(fp, "%s\n", vp->v.dfn);
443 break;
444 case STRING:
445 fprintf(fp, "%s=\"", vp->name);
446 for (i = 0; vp->v.s[i]; i++)
447 switch (vp->v.s[i]) {
448 case '"':
449 case '\\':
450 putc('\\', fp);
451 /* fall through */
452 default:
453 putc(vp->v.s[i], fp);
454 break;
455 }
456 fprintf(fp, "\"\n");
457 break;
458 case DATA:
459 fprintf(fp, "%s=", vp->name);
460 for (i = 0; i < vp->v.d.size; i++) {
461 if (i % 4 == 0)
462 fprintf(fp, "\n");
463 fprintf(fp, "\t%10e", vp->v.d.data[i]);
464 }
465 fprintf(fp, "\n;\n");
466 break;
467 }
468 }
469
470
471 static void
472 undefine( /* undefine a variable */
473 register VARIABLE *vp
474 )
475 {
476 if (vp == NULL || !(vp->flags & DEFINED))
477 return;
478
479 switch (vp->type) {
480 case REAL:
481 case FUNCTION:
482 dremove(vp->name);
483 freestr(vp->v.dfn);
484 break;
485 case STRING:
486 freestr(vp->v.s);
487 break;
488 case DATA:
489 efree((char *)vp->v.d.data);
490 break;
491 }
492 vp->flags &= ~DEFINED;
493 }
494
495
496 VARIABLE *
497 vlookup(vname) /* look up a variable by its name */
498 char *vname;
499 {
500 register int i;
501 register VARIABLE *vp;
502
503 i = vname[0] - 'A';
504 if (i >= 0 && i < MAXCUR) /* curve variables */
505 for (vp = cparam[i], i = 0; i < NCVARS; vp++, i++)
506 if (!strcmp(vp->name, vname))
507 return(vp);
508 /* standard variables */
509 for (vp = gparam; vp < &gparam[NVARS]; vp++)
510 if (!strcmp(vp->name, vname))
511 return(vp);
512 return(NULL); /* not found */
513 }
514
515
516 static void
517 loaddata( /* load data from a stream */
518 char *fname,
519 FILE *fp,
520 register DARRAY *dp
521 )
522 {
523 char sbuf[MAXLINE], *fgets();
524 register char *cp;
525
526 dp->size = 0;
527 dp->data = NULL;
528 while (fgets(sbuf, sizeof(sbuf), fp) != NULL) {
529 cp = sbuf;
530 while (*cp) {
531 while (isspace(*cp) || *cp == ',')
532 cp++;
533 if (isnum(*cp)) {
534 dp->data = (float *)erealloc((char *)dp->data,
535 (dp->size+1)*sizeof(float));
536 dp->data[dp->size++] = atof(cp);
537 do
538 cp++;
539 while (isnum(*cp));
540 } else if (*cp == ';') {
541 return;
542 } else if (*cp) {
543 fputs(sbuf, stderr);
544 fprintf(stderr, "%s: %s: Bad data\n",
545 progname, fname);
546 quit(1);
547 }
548 }
549 }
550 }
551
552
553 static char *
554 findfile( /* find the file fname, return full path */
555 char *fname,
556 register char **pathlist
557 )
558 {
559 static char ffname[128];
560 register int fd;
561
562 if (fname[0] == '/')
563 return(fname);
564
565 while (*pathlist != NULL) {
566 strcpy(ffname, *pathlist);
567 strcat(ffname, fname);
568 if ((fd = open(ffname, 0)) != -1) {
569 close(fd);
570 return(ffname);
571 }
572 pathlist++;
573 }
574 return(NULL);
575 }
576
577
578 int
579 mgcurve( /* get a curve's (unmapped) values */
580 int c,
581 int (*f)()
582 )
583 {
584 int nargs;
585 double x[2], step;
586 register VARIABLE *cv;
587 register float *p;
588 register int npts = 0;
589
590 if (c < 0 || c >= MAXCUR)
591 return(-1);
592 cv = cparam[c];
593
594 if (cv[C].flags & DEFINED) { /* function or map */
595
596 nargs = fundefined(cv[C].name);
597 if (nargs < 1 || nargs > 2) {
598 fprintf(stderr, "%s: bad # of arguments for '%c'\n",
599 progname, c+'A');
600 quit(1);
601 }
602
603 if (cv[CDATA].flags & DEFINED) { /* map */
604 npts = cv[CDATA].v.d.size / nargs;
605 p = cv[CDATA].v.d.data;
606 while (npts--) {
607 x[0] = *p++;
608 if (nargs == 2)
609 x[1] = *p++;
610 (*f)(c, x[0],
611 funvalue(cv[C].name, nargs, x));
612 }
613 npts = cv[CDATA].v.d.size / nargs;
614 } else if ( nargs == 1 && /* function */
615 gparam[XMIN].flags & DEFINED &&
616 gparam[XMAX].flags & DEFINED &&
617 cv[CNPOINTS].flags & DEFINED ) {
618 npts = varvalue(cv[CNPOINTS].name);
619 if (npts > 1)
620 step = (varvalue(gparam[XMAX].name) -
621 varvalue(gparam[XMIN].name)) /
622 (npts - 1);
623 else
624 step = 0.0;
625 for (x[0] = varvalue(gparam[XMIN].name);
626 npts--; x[0] += step)
627 (*f)(c, x[0],
628 funvalue(cv[C].name, 1, x));
629 npts = varvalue(cv[CNPOINTS].name);
630 } else {
631 fprintf(stderr,
632 "%s: function '%c' needs %cdata or xmin, xmax, %cnpoints\n",
633 progname, c+'A', c+'A', c+'A');
634 quit(1);
635 }
636
637 } else if (cv[CDATA].flags & DEFINED) { /* data */
638
639 npts = cv[CDATA].v.d.size / 2;
640 p = cv[CDATA].v.d.data;
641 while (npts--) {
642 (*f)(c, p[0], p[1]);
643 p += 2;
644 }
645 npts = cv[CDATA].v.d.size / 2;
646
647 } else
648
649 npts = 0;
650
651 return(npts);
652 }