ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/mgvars.c
Revision: 1.1
Committed: Sat Feb 22 02:07:26 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
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
14 #include <stdlib.h>
15
16 #include <math.h>
17
18 #include <ctype.h>
19
20 #include "mgvars.h"
21
22 #define MAXLINE 512
23
24 #define isid(c) (isalnum(c) || (c) == '_' || (c) == '.')
25
26 #define isnum(c) (isdigit(c)||(c)=='-'||(c)=='+'||(c)=='.'||(c)=='e'||(c)=='E')
27
28 char *findfile(), *emalloc(), *ecalloc(), *erealloc(), *savestr(), *strcpy();
29 FILE *fopen(), *popen();
30 extern char *progname, *libpath[];
31
32 #ifdef DCL_ATOF
33 double atof();
34 #endif
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 mgclearall() /* clear all variable settings */
146 {
147 int j;
148 register IVAR *iv;
149 register int i;
150
151 for (iv = ivhead; iv != NULL; iv = iv->next) {
152 dremove(iv->name);
153 freestr(iv->name);
154 freestr(iv->dfn);
155 efree((char *)iv);
156 }
157 ivhead = NULL;
158
159 for (i = 0; i < NVARS; i++)
160 if (gparam[i].flags & DEFINED)
161 undefine(&gparam[i]);
162
163 for (j = 0; j < MAXCUR; j++)
164 for (i = 0; i < NCVARS; i++)
165 if (cparam[j][i].flags & DEFINED)
166 undefine(&cparam[j][i]);
167 }
168
169
170 mgload(file) /* load a file */
171 char *file;
172 {
173 FILE *fp;
174 char sbuf[MAXLINE], *fgets();
175 int inquote;
176 register char *cp, *cp2;
177
178 if (file == NULL) {
179 fp = stdin;
180 file = "<stdin>";
181 } else if ((fp = fopen(file, "r")) == NULL) {
182 fprintf(stderr, "%s: Cannot open: %s\n", progname, file);
183 quit(1);
184 }
185 while (fgets(sbuf+1, sizeof(sbuf)-1, fp) != NULL) {
186 inquote = 0;
187 cp2 = sbuf;
188 for (cp = sbuf+1; *cp; cp++) /* condition the input line */
189 switch (*cp) {
190 case '#':
191 if (!inquote) {
192 cp[0] = '\n';
193 cp[1] = '\0';
194 break;
195 }
196 *cp2++ = *cp;
197 break;
198 case '"':
199 inquote = !inquote;
200 break;
201 case '\\':
202 if (!cp[1])
203 break;
204 if (cp[1] == '\n') {
205 cp[0] = '\0';
206 fgets(cp, sizeof(sbuf)-(cp-sbuf), fp);
207 cp--;
208 break;
209 }
210 *cp2++ = *++cp;
211 break;
212 case ' ':
213 case '\t':
214 case '\n':
215 if (!inquote)
216 break;
217 *cp2++ = *cp;
218 break;
219 default:
220 *cp2++ = *cp;
221 break;
222 }
223 *cp2 = '\0';
224 if (inquote) {
225 fputs(sbuf, stderr);
226 fprintf(stderr, "%s: %s: Missing quote\n",
227 progname, file);
228 quit(1);
229 }
230 if (sbuf[0])
231 setmgvar(file, fp, sbuf);
232 }
233 if (fp != stdin)
234 fclose(fp);
235 }
236
237
238 mgsave(file) /* save our variables */
239 char *file;
240 {
241 FILE *fp;
242 int j;
243 register IVAR *iv;
244 register int i;
245
246 if (file == NULL)
247 fp = stdout;
248 else if ((fp = fopen(file, "w")) == NULL) {
249 fprintf(stderr, "%s: Cannot write: %s\n", progname, file);
250 quit(1);
251 }
252 for (iv = ivhead; iv != NULL; iv = iv->next)
253 fprintf(fp, "%s\n", iv->dfn);
254
255 for (i = 0; i < NVARS; i++)
256 if (gparam[i].flags & DEFINED)
257 mgprint(&gparam[i], fp);
258
259 for (j = 0; j < MAXCUR; j++)
260 for (i = 0; i < NCVARS; i++)
261 if (cparam[j][i].flags & DEFINED)
262 mgprint(&cparam[j][i], fp);
263
264 if (fp != stdout)
265 fclose(fp);
266 }
267
268
269 setmgvar(fname, fp, string) /* set a variable */
270 char *fname;
271 FILE *fp;
272 char *string;
273 {
274 char name[128];
275 FILE *fp2;
276 register int i;
277 register char *s;
278 register VARIABLE *vp;
279
280 if (!strncmp(string, "include=", 8)) { /* include file */
281 if ((s = findfile(string+8, libpath)) == NULL) {
282 fprintf(stderr, "%s\n", string);
283 fprintf(stderr, "%s: %s: File not found: %s\n",
284 progname, fname, string+8);
285 quit(1);
286 }
287 strcpy(name, s);
288 mgload(name);
289 return;
290 }
291 s = string;
292 i = 0;
293 while (i < sizeof(name)-1 && isid(*s))
294 name[i++] = *s++;
295 name[i] = '\0';
296 vp = vlookup(name);
297 if (vp != NULL) {
298 undefine(vp);
299 switch (vp->type) {
300 case REAL:
301 case FUNCTION:
302 if ((*s == '(') != (vp->type == FUNCTION)) {
303 fprintf(stderr, "%s\n", string);
304 fprintf(stderr,
305 "%s: %s: Bad %s declaration: %s\n",
306 progname, fname,
307 vp->type == FUNCTION ?
308 "function" : "variable",
309 name);
310 quit(1);
311 }
312 scompile(string, fname, 0);
313 vp->v.dfn = savestr(string);
314 break;
315 case STRING:
316 if (*s++ != '=') {
317 fprintf(stderr, "%s\n", string);
318 fprintf(stderr, "%s: %s: Missing '='\n",
319 progname, fname);
320 quit(1);
321 }
322 vp->v.s = savestr(s);
323 break;
324 case DATA:
325 if (*s++ != '=') {
326 fprintf(stderr, "%s\n", string);
327 fprintf(stderr, "%s: %s: Missing '='\n",
328 progname, fname);
329 quit(1);
330 }
331 if (!*s) {
332 loaddata(fname, fp, &vp->v.d);
333 #ifdef UNIX
334 } else if (*s == '!') {
335 if ((fp2 = popen(s+1, "r")) == NULL) {
336 fprintf(stderr, "%s\n", string);
337 fprintf(stderr,
338 "%s: %s: Cannot execute: %s\n",
339 progname, fname, s+1);
340 quit(1);
341 }
342 loaddata(s, fp2, &vp->v.d);
343 pclose(fp2);
344 #endif
345 } else {
346 if ((fp2 = fopen(s, "r")) == NULL) {
347 fprintf(stderr, "%s\n", string);
348 fprintf(stderr,
349 "%s: %s: Data file not found: %s\n",
350 progname, fname, s);
351 quit(1);
352 }
353 loaddata(s, fp2, &vp->v.d);
354 fclose(fp2);
355 }
356 break;
357 }
358 vp->flags |= DEFINED;
359 } else
360 setivar(name, fname, string); /* intermediate */
361 }
362
363
364 setivar(vname, fname, definition) /* set an intermediate variable */
365 char *vname;
366 char *fname;
367 char *definition;
368 {
369 IVAR ivbeg;
370 register IVAR *iv;
371
372 scompile(definition, fname, 0); /* compile the string */
373
374 ivbeg.next = ivhead;
375 for (iv = &ivbeg; iv->next != NULL; iv = iv->next)
376 if (!strcmp(vname, iv->next->name)) {
377 iv = iv->next;
378 freestr(iv->dfn);
379 iv->dfn = savestr(definition);
380 return;
381 }
382
383 iv->next = (IVAR *)emalloc(sizeof(IVAR));
384 iv = iv->next;
385 iv->name = savestr(vname);
386 iv->dfn = savestr(definition);
387 iv->next = NULL;
388 ivhead = ivbeg.next;
389 }
390
391
392 mgtoa(s, vp) /* get a variable's value in ascii form */
393 register char *s;
394 VARIABLE *vp;
395 {
396 register char *sv;
397
398 if (!(vp->flags & DEFINED)) {
399 strcpy(s, "UNDEFINED");
400 return;
401 }
402 switch (vp->type) {
403 case REAL:
404 case FUNCTION:
405 sv = vp->v.dfn;
406 while (*sv != '=' && *sv != ':')
407 sv++;
408 while (*++sv && *sv != ';')
409 *s++ = *sv;
410 *s = '\0';
411 break;
412 case STRING:
413 strcpy(s, vp->v.s);
414 break;
415 case DATA:
416 strcpy(s, "DATA");
417 break;
418 }
419 }
420
421
422 mgprint(vp, fp) /* print a variable definition */
423 register VARIABLE *vp;
424 FILE *fp;
425 {
426 register int i;
427
428 switch (vp->type) {
429 case REAL:
430 case FUNCTION:
431 fprintf(fp, "%s\n", vp->v.dfn);
432 break;
433 case STRING:
434 fprintf(fp, "%s=\"", vp->name);
435 for (i = 0; vp->v.s[i]; i++)
436 switch (vp->v.s[i]) {
437 case '"':
438 case '\\':
439 putc('\\', fp);
440 /* fall through */
441 default:
442 putc(vp->v.s[i], fp);
443 break;
444 }
445 fprintf(fp, "\"\n");
446 break;
447 case DATA:
448 fprintf(fp, "%s=", vp->name);
449 for (i = 0; i < vp->v.d.size; i++) {
450 if (i % 4 == 0)
451 fprintf(fp, "\n");
452 fprintf(fp, "\t%10e", vp->v.d.data[i]);
453 }
454 fprintf(fp, "\n;\n");
455 break;
456 }
457 }
458
459
460 undefine(vp) /* undefine a variable */
461 register VARIABLE *vp;
462 {
463 if (vp == NULL || !(vp->flags & DEFINED))
464 return;
465
466 switch (vp->type) {
467 case REAL:
468 case FUNCTION:
469 dremove(vp->name);
470 freestr(vp->v.dfn);
471 break;
472 case STRING:
473 freestr(vp->v.s);
474 break;
475 case DATA:
476 efree((char *)vp->v.d.data);
477 break;
478 }
479 vp->flags &= ~DEFINED;
480 }
481
482
483 VARIABLE *
484 vlookup(vname) /* look up a variable by its name */
485 char *vname;
486 {
487 register int i;
488 register VARIABLE *vp;
489
490 i = vname[0] - 'A';
491 if (i >= 0 && i < MAXCUR) /* curve variables */
492 for (vp = cparam[i], i = 0; i < NCVARS; vp++, i++)
493 if (!strcmp(vp->name, vname))
494 return(vp);
495 /* standard variables */
496 for (vp = gparam; vp < &gparam[NVARS]; vp++)
497 if (!strcmp(vp->name, vname))
498 return(vp);
499 return(NULL); /* not found */
500 }
501
502
503 loaddata(fname, fp, dp) /* load data from a stream */
504 char *fname;
505 FILE *fp;
506 register DARRAY *dp;
507 {
508 char sbuf[MAXLINE], *fgets();
509 register char *cp;
510
511 dp->size = 0;
512 dp->data = NULL;
513 while (fgets(sbuf, sizeof(sbuf), fp) != NULL) {
514 cp = sbuf;
515 while (*cp) {
516 while (isspace(*cp) || *cp == ',')
517 cp++;
518 if (isnum(*cp)) {
519 dp->data = (float *)erealloc((char *)dp->data,
520 (dp->size+1)*sizeof(float));
521 dp->data[dp->size++] = atof(cp);
522 do
523 cp++;
524 while (isnum(*cp));
525 } else if (*cp == ';') {
526 return;
527 } else if (*cp) {
528 fputs(sbuf, stderr);
529 fprintf(stderr, "%s: %s: Bad data\n",
530 progname, fname);
531 quit(1);
532 }
533 }
534 }
535 }
536
537
538 char *
539 findfile(fname, pathlist) /* find the file fname, return full path */
540 char *fname;
541 register char **pathlist;
542 {
543 static char ffname[128];
544 char *strcpy(), *strcat();
545 register int fd;
546
547 if (fname[0] == '/')
548 return(fname);
549
550 while (*pathlist != NULL) {
551 strcpy(ffname, *pathlist);
552 strcat(ffname, fname);
553 if ((fd = open(ffname, 0)) != -1) {
554 close(fd);
555 return(ffname);
556 }
557 pathlist++;
558 }
559 return(NULL);
560 }
561
562
563 int
564 mgcurve(c, f) /* get a curve's (unmapped) values */
565 int c;
566 int (*f)();
567 {
568 int nargs;
569 double x[2], step;
570 register VARIABLE *cv;
571 register float *p;
572 register int npts;
573
574 if (c < 0 || c >= MAXCUR)
575 return(-1);
576 cv = cparam[c];
577
578 if (cv[C].flags & DEFINED) { /* function or map */
579
580 nargs = fundefined(cv[C].name);
581 if (nargs < 1 || nargs > 2) {
582 fprintf(stderr, "%s: bad # of arguments for '%c'\n",
583 progname, c+'A');
584 quit(1);
585 }
586
587 if (cv[CDATA].flags & DEFINED) { /* map */
588 npts = cv[CDATA].v.d.size / nargs;
589 p = cv[CDATA].v.d.data;
590 while (npts--) {
591 x[0] = *p++;
592 if (nargs == 2)
593 x[1] = *p++;
594 (*f)(c, x[0],
595 funvalue(cv[C].name, nargs, x));
596 }
597 npts = cv[CDATA].v.d.size / nargs;
598 } else if ( nargs == 1 && /* function */
599 gparam[XMIN].flags & DEFINED &&
600 gparam[XMAX].flags & DEFINED &&
601 cv[CNPOINTS].flags & DEFINED ) {
602 npts = varvalue(cv[CNPOINTS].name);
603 if (npts > 1)
604 step = (varvalue(gparam[XMAX].name) -
605 varvalue(gparam[XMIN].name)) /
606 (npts - 1);
607 else
608 step = 0.0;
609 for (x[0] = varvalue(gparam[XMIN].name);
610 npts--; x[0] += step)
611 (*f)(c, x[0],
612 funvalue(cv[C].name, 1, x));
613 npts = varvalue(cv[CNPOINTS].name);
614 } else {
615 fprintf(stderr,
616 "%s: function '%c' needs %cdata or xmin, xmax, %cnpoints\n",
617 progname, c+'A', c+'A', c+'A');
618 quit(1);
619 }
620
621 } else if (cv[CDATA].flags & DEFINED) { /* data */
622
623 npts = cv[CDATA].v.d.size / 2;
624 p = cv[CDATA].v.d.data;
625 while (npts--) {
626 (*f)(c, p[0], p[1]);
627 p += 2;
628 }
629 npts = cv[CDATA].v.d.size / 2;
630
631 } else
632
633 npts = 0;
634
635 return(npts);
636 }