ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/mgvars.c
Revision: 1.6
Committed: Sun Mar 28 20:33:13 2004 UTC (20 years, 8 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1, rad5R3, HEAD
Changes since 1.5: +2 -1 lines
Log Message:
Continued ANSIfication, and other fixes and clarifications.

File Contents

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