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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.4 static const char RCSid[] = "$Id: mgvars.c,v 1.3 2003/10/27 10:28:59 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.4 #include "rterror.h"
20 schorsch 1.3 #include "rtio.h"
21 schorsch 1.4 #include "calcomp.h"
22 greg 1.1 #include "mgvars.h"
23    
24     #define MAXLINE 512
25    
26     #define isnum(c) (isdigit(c)||(c)=='-'||(c)=='+'||(c)=='.'||(c)=='e'||(c)=='E')
27    
28 schorsch 1.4 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 greg 1.1
34 schorsch 1.4 extern char *progname, *libpath[];
35 greg 1.1
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 schorsch 1.4 void
146     mgclearall(void) /* clear all variable settings */
147 greg 1.1 {
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 schorsch 1.4 void
172     mgload( /* load a file */
173     char *file
174     )
175 greg 1.1 {
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 schorsch 1.4 void
242     mgsave( /* save our variables */
243     char *file
244     )
245 greg 1.1 {
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 schorsch 1.4 void
275     setmgvar( /* set a variable */
276     char *fname,
277     FILE *fp,
278     char *string
279     )
280 greg 1.1 {
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 schorsch 1.4 static void
370     setivar( /* set an intermediate variable */
371     char *vname,
372     char *fname,
373     char *definition
374     )
375 greg 1.1 {
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 schorsch 1.4 void
400     mgtoa( /* get a variable's value in ascii form */
401     register char *s,
402     VARIABLE *vp
403     )
404 greg 1.1 {
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 schorsch 1.4 static void
432     mgprint( /* print a variable definition */
433     register VARIABLE *vp,
434     FILE *fp
435     )
436 greg 1.1 {
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 schorsch 1.4 static void
472     undefine( /* undefine a variable */
473     register VARIABLE *vp
474     )
475 greg 1.1 {
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 schorsch 1.4 static void
517     loaddata( /* load data from a stream */
518     char *fname,
519     FILE *fp,
520     register DARRAY *dp
521     )
522 greg 1.1 {
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 schorsch 1.4 static char *
554     findfile( /* find the file fname, return full path */
555     char *fname,
556     register char **pathlist
557     )
558 greg 1.1 {
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 schorsch 1.4 mgcurve( /* get a curve's (unmapped) values */
580     int c,
581     int (*f)()
582     )
583 greg 1.1 {
584     int nargs;
585     double x[2], step;
586     register VARIABLE *cv;
587     register float *p;
588 schorsch 1.4 register int npts = 0;
589 greg 1.1
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     }