ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/parser.c
(Generate patch)

Comparing ray/src/cv/mgflib/parser.c (file contents):
Revision 1.6 by greg, Fri Jun 24 16:28:18 1994 UTC vs.
Revision 1.23 by greg, Wed Jun 19 22:34:59 1996 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1994 Regents of the University of California */
1 > /* Copyright (c) 1996 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 27 | Line 27 | char   mg_ename[MG_NENTITIES][MG_MAXELEN] = MG_NAMELIST;
27  
28   int     (*mg_ehand[MG_NENTITIES])();
29  
30 +                        /* Handler routine for unknown entities */
31 +
32 + int     (*mg_uhand)() = mg_defuhand;
33 +
34 + unsigned        mg_nunknown;    /* count of unknown entities */
35 +
36                          /* error messages */
37  
38   char    *mg_err[MG_NERRS] = MG_ERRLIST;
# Line 57 | Line 63 | int    mg_nqcdivs = MG_NQCD;   /* number of divisions per q
63  
64   static int      e_any_toss(),           /* discard unneeded entity */
65                  e_ies(),                /* IES luminaire file */
66 <                e_include(),            /* include file */
61 <                e_sph(),                /* sphere */
66 >                e_cct(),                /* color temperature */
67                  e_cmix(),               /* color mixtures */
68 <                e_cspec(),              /* color spectra */
68 >                e_cspec();              /* color spectra */
69 >
70 > int             e_include(),            /* include file */
71 >                e_sph(),                /* sphere */
72                  e_cyl(),                /* cylinder */
73                  e_cone(),               /* cone */
74                  e_prism(),              /* prism */
# Line 88 | Line 96 | mg_init()                      /* initialize alternate entity handlers */
96                  mg_ehand[MG_E_INCLUDE] = e_include;
97          if (mg_ehand[MG_E_SPH] == NULL) {
98                  mg_ehand[MG_E_SPH] = e_sph;
99 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
99 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
100          } else
101 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
101 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
102          if (mg_ehand[MG_E_CYL] == NULL) {
103                  mg_ehand[MG_E_CYL] = e_cyl;
104 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
104 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
105          } else
106 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
106 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
107          if (mg_ehand[MG_E_CONE] == NULL) {
108                  mg_ehand[MG_E_CONE] = e_cone;
109 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
109 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
110          } else
111 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
111 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
112          if (mg_ehand[MG_E_RING] == NULL) {
113                  mg_ehand[MG_E_RING] = e_ring;
114 <                ineed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX;
114 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX;
115          } else
116 <                uneed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX|1<<MG_E_XF;
116 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX|1L<<MG_E_XF;
117          if (mg_ehand[MG_E_PRISM] == NULL) {
118                  mg_ehand[MG_E_PRISM] = e_prism;
119 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
119 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
120          } else
121 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
121 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
122          if (mg_ehand[MG_E_TORUS] == NULL) {
123                  mg_ehand[MG_E_TORUS] = e_torus;
124 <                ineed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX;
124 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX;
125          } else
126 <                uneed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX|1<<MG_E_XF;
126 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX|1L<<MG_E_XF;
127          if (mg_ehand[MG_E_COLOR] != NULL) {
128                  if (mg_ehand[MG_E_CMIX] == NULL) {
129                          mg_ehand[MG_E_CMIX] = e_cmix;
130 <                        ineed |= 1<<MG_E_COLOR|1<<MG_E_CXY|1<<MG_E_CSPEC|1<<MG_E_CMIX;
130 >                        ineed |= 1L<<MG_E_COLOR|1L<<MG_E_CXY|1L<<MG_E_CSPEC|1L<<MG_E_CMIX|1L<<MG_E_CCT;
131                  }
132                  if (mg_ehand[MG_E_CSPEC] == NULL) {
133                          mg_ehand[MG_E_CSPEC] = e_cspec;
134 <                        ineed |= 1<<MG_E_COLOR|1<<MG_E_CXY|1<<MG_E_CSPEC|1<<MG_E_CMIX;
134 >                        ineed |= 1L<<MG_E_COLOR|1L<<MG_E_CXY|1L<<MG_E_CSPEC|1L<<MG_E_CMIX|1L<<MG_E_CCT;
135                  }
136 +                if (mg_ehand[MG_E_CCT] == NULL) {
137 +                        mg_ehand[MG_E_CCT] = e_cct;
138 +                        ineed |= 1L<<MG_E_COLOR|1L<<MG_E_CXY|1L<<MG_E_CSPEC|1L<<MG_E_CMIX|1L<<MG_E_CCT;
139 +                }
140          }
141                                          /* check for consistency */
142          if (mg_ehand[MG_E_FACE] != NULL)
143 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
143 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
144          if (mg_ehand[MG_E_CXY] != NULL || mg_ehand[MG_E_CSPEC] != NULL ||
145                          mg_ehand[MG_E_CMIX] != NULL)
146 <                uneed |= 1<<MG_E_COLOR;
146 >                uneed |= 1L<<MG_E_COLOR;
147          if (mg_ehand[MG_E_RD] != NULL || mg_ehand[MG_E_TD] != NULL ||
148 +                        mg_ehand[MG_E_IR] != NULL ||
149                          mg_ehand[MG_E_ED] != NULL ||
150                          mg_ehand[MG_E_RS] != NULL ||
151 <                        mg_ehand[MG_E_TS] != NULL)
152 <                uneed |= 1<<MG_E_MATERIAL;
151 >                        mg_ehand[MG_E_TS] != NULL ||
152 >                        mg_ehand[MG_E_SIDES] != NULL)
153 >                uneed |= 1L<<MG_E_MATERIAL;
154          for (i = 0; i < MG_NENTITIES; i++)
155 <                if (uneed & 1<<i && mg_ehand[i] == NULL) {
155 >                if (uneed & 1L<<i && mg_ehand[i] == NULL) {
156                          fprintf(stderr, "Missing support for \"%s\" entity\n",
157                                          mg_ename[i]);
158                          exit(1);
159                  }
160                                          /* add support as needed */
161 <        if (ineed & 1<<MG_E_VERTEX && mg_ehand[MG_E_VERTEX] != c_hvertex)
161 >        if (ineed & 1L<<MG_E_VERTEX && mg_ehand[MG_E_VERTEX] != c_hvertex)
162                  e_supp[MG_E_VERTEX] = c_hvertex;
163 <        if (ineed & 1<<MG_E_POINT && mg_ehand[MG_E_POINT] != c_hvertex)
163 >        if (ineed & 1L<<MG_E_POINT && mg_ehand[MG_E_POINT] != c_hvertex)
164                  e_supp[MG_E_POINT] = c_hvertex;
165 <        if (ineed & 1<<MG_E_NORMAL && mg_ehand[MG_E_NORMAL] != c_hvertex)
165 >        if (ineed & 1L<<MG_E_NORMAL && mg_ehand[MG_E_NORMAL] != c_hvertex)
166                  e_supp[MG_E_NORMAL] = c_hvertex;
167 <        if (ineed & 1<<MG_E_COLOR && mg_ehand[MG_E_COLOR] != c_hcolor)
167 >        if (ineed & 1L<<MG_E_COLOR && mg_ehand[MG_E_COLOR] != c_hcolor)
168                  e_supp[MG_E_COLOR] = c_hcolor;
169 <        if (ineed & 1<<MG_E_CXY && mg_ehand[MG_E_CXY] != c_hcolor)
169 >        if (ineed & 1L<<MG_E_CXY && mg_ehand[MG_E_CXY] != c_hcolor)
170                  e_supp[MG_E_CXY] = c_hcolor;
171 <        if (ineed & 1<<MG_E_CSPEC && mg_ehand[MG_E_CSPEC] != c_hcolor)
171 >        if (ineed & 1L<<MG_E_CSPEC && mg_ehand[MG_E_CSPEC] != c_hcolor)
172                  e_supp[MG_E_CSPEC] = c_hcolor;
173 <        if (ineed & 1<<MG_E_CMIX && mg_ehand[MG_E_CMIX] != c_hcolor)
173 >        if (ineed & 1L<<MG_E_CMIX && mg_ehand[MG_E_CMIX] != c_hcolor)
174                  e_supp[MG_E_CMIX] = c_hcolor;
175 +        if (ineed & 1L<<MG_E_CCT && mg_ehand[MG_E_CCT] != c_hcolor)
176 +                e_supp[MG_E_CCT] = c_hcolor;
177                                          /* discard remaining entities */
178          for (i = 0; i < MG_NENTITIES; i++)
179                  if (mg_ehand[i] == NULL)
# Line 165 | Line 181 | mg_init()                      /* initialize alternate entity handlers */
181   }
182  
183  
168
184   int
185   mg_entity(name)                 /* get entity number from its name */
186   char    *name;
187   {
188 <        static LUTAB    ent_tab;        /* entity lookup table */
188 >        static LUTAB    ent_tab = LU_SINIT(NULL,NULL);  /* lookup table */
189          register char   *cp;
190  
191          if (!ent_tab.tsiz) {            /* initialize hash table */
# Line 187 | Line 202 | char   *name;
202   }
203  
204  
205 < static int
206 < handle_it(en, ac, av)           /* pass entity to appropriate handler */
205 > int
206 > mg_handle(en, ac, av)           /* pass entity to appropriate handler */
207   register int    en;
208   int     ac;
209   char    **av;
210   {
211          int     rv;
212  
213 <        if (en < 0 && (en = mg_entity(av[0])) < 0)
213 >        if (en < 0 && (en = mg_entity(av[0])) < 0) {    /* unknown entity */
214 >                if (mg_uhand != NULL)
215 >                        return((*mg_uhand)(ac, av));
216                  return(MG_EUNK);
217 <        if (e_supp[en] != NULL) {
217 >        }
218 >        if (e_supp[en] != NULL) {                       /* support handler */
219                  if ((rv = (*e_supp[en])(ac, av)) != MG_OK)
220                          return(rv);
221          }
222 <        return((*mg_ehand[en])(ac, av));
222 >        return((*mg_ehand[en])(ac, av));                /* assigned handler */
223   }
224  
225  
# Line 210 | Line 228 | mg_open(ctx, fn)                       /* open new input file */
228   register MG_FCTXT       *ctx;
229   char    *fn;
230   {
231 <        int     olen;
231 >        static int      nfids;
232          register char   *cp;
233  
234 +        ctx->fid = ++nfids;
235          ctx->lineno = 0;
236          if (fn == NULL) {
237 <                ctx->fname = "<stdin>";
237 >                strcpy(ctx->fname, "<stdin>");
238                  ctx->fp = stdin;
239                  ctx->prev = mg_file;
240                  mg_file = ctx;
241                  return(MG_OK);
242          }
243                                          /* get name relative to this context */
244 <        if (mg_file != NULL &&
226 <                        (cp = strrchr(mg_file->fname, '/')) != NULL)
227 <                olen = cp - mg_file->fname + 1;
228 <        else
229 <                olen = 0;
230 <        ctx->fname = (char *)malloc(olen+strlen(fn)+1);
231 <        if (ctx->fname == NULL)
232 <                return(MG_EMEM);
233 <        if (olen)
244 >        if (mg_file != NULL && (cp = strrchr(mg_file->fname, '/')) != NULL) {
245                  strcpy(ctx->fname, mg_file->fname);
246 <        strcpy(ctx->fname+olen, fn);
246 >                strcpy(ctx->fname+(cp-mg_file->fname+1), fn);
247 >        } else
248 >                strcpy(ctx->fname, fn);
249          ctx->fp = fopen(ctx->fname, "r");
250 <        if (ctx->fp == NULL) {
238 <                free((MEM_PTR)ctx->fname);
250 >        if (ctx->fp == NULL)
251                  return(MG_ENOFILE);
240        }
252          ctx->prev = mg_file;            /* establish new context */
253          mg_file = ctx;
254          return(MG_OK);
# Line 250 | Line 261 | mg_close()                     /* close input file */
261          register MG_FCTXT       *ctx = mg_file;
262  
263          mg_file = ctx->prev;            /* restore enclosing context */
264 <        if (ctx->fp == stdin)
265 <                return;                 /* don't close standard input */
255 <        fclose(ctx->fp);
256 <        free((MEM_PTR)ctx->fname);
264 >        if (ctx->fp != stdin)           /* close file if it's a file */
265 >                fclose(ctx->fp);
266   }
267  
268  
269 + void
270 + mg_fgetpos(pos)                 /* get current position in input file */
271 + register MG_FPOS        *pos;
272 + {
273 +        extern long     ftell();
274 +
275 +        pos->fid = mg_file->fid;
276 +        pos->lineno = mg_file->lineno;
277 +        pos->offset = ftell(mg_file->fp);
278 + }
279 +
280 +
281   int
282 < mg_rewind()                     /* rewind input file */
282 > mg_fgoto(pos)                   /* reposition input file pointer */
283 > register MG_FPOS        *pos;
284   {
285 <        if (mg_file->lineno == 0)
285 >        if (pos->fid != mg_file->fid)
286 >                return(MG_ESEEK);
287 >        if (pos->lineno == mg_file->lineno)
288                  return(MG_OK);
289          if (mg_file->fp == stdin)
290                  return(MG_ESEEK);       /* cannot seek on standard input */
291 <        if (fseek(mg_file->fp, 0L, 0) == EOF)
291 >        if (fseek(mg_file->fp, pos->offset, 0) == EOF)
292                  return(MG_ESEEK);
293 <        mg_file->lineno = 0;
293 >        mg_file->lineno = pos->lineno;
294          return(MG_OK);
295   }
296  
# Line 280 | Line 304 | mg_read()                      /* read next line from file */
304                  if (fgets(mg_file->inpline+len,
305                                  MG_MAXLINE-len, mg_file->fp) == NULL)
306                          return(len);
283                mg_file->lineno++;
307                  len += strlen(mg_file->inpline+len);
308 <                if (len > 1 && mg_file->inpline[len-2] == '\\')
309 <                        mg_file->inpline[--len-1] = ' ';
310 <        } while (mg_file->inpline[len]);
308 >                if (len >= MG_MAXLINE-1)
309 >                        return(len);
310 >                mg_file->lineno++;
311 >        } while (len > 1 && mg_file->inpline[len-2] == '\\');
312  
313          return(len);
314   }
# Line 296 | Line 320 | mg_parse()                     /* parse current input line */
320          char    abuf[MG_MAXLINE];
321          char    *argv[MG_MAXARGC];
322          int     en;
323 <        register char   *cp, **ap;
324 <
325 <        strcpy(cp=abuf, mg_file->inpline);
326 <        ap = argv;                      /* break into words */
323 >        register char   *cp, *cp2, **ap;
324 >                                        /* copy line, removing escape chars */
325 >        cp = abuf; cp2 = mg_file->inpline;
326 >        while ((*cp++ = *cp2++))
327 >                if (cp2[0] == '\n' && cp2[-1] == '\\')
328 >                        cp--;
329 >        cp = abuf; ap = argv;           /* break into words */
330          for ( ; ; ) {
331                  while (isspace(*cp))
332                          *cp++ = '\0';
# Line 315 | Line 342 | mg_parse()                     /* parse current input line */
342                  return(MG_OK);          /* no words in line */
343          *ap = NULL;
344                                          /* else handle it */
345 <        return(handle_it(-1, ap-argv, argv));
345 >        return(mg_handle(-1, ap-argv, argv));
346   }
347  
348  
# Line 325 | Line 352 | char   *fn;
352   {
353          MG_FCTXT        cntxt;
354          int     rval;
355 +        register int    nbr;
356  
357          if ((rval = mg_open(&cntxt, fn)) != MG_OK) {
358                  fprintf(stderr, "%s: %s\n", fn, mg_err[rval]);
359                  return(rval);
360          }
361 <        while (mg_read())               /* parse each line */
361 >        while ((nbr = mg_read()) > 0) { /* parse each line */
362 >                if (nbr >= MG_MAXLINE-1) {
363 >                        fprintf(stderr, "%s: %d: %s\n", cntxt.fname,
364 >                                        cntxt.lineno, mg_err[rval=MG_ELINE]);
365 >                        break;
366 >                }
367                  if ((rval = mg_parse()) != MG_OK) {
368                          fprintf(stderr, "%s: %d: %s:\n%s", cntxt.fname,
369                                          cntxt.lineno, mg_err[rval],
370                                          cntxt.inpline);
371                          break;
372                  }
373 +        }
374          mg_close();
375          return(rval);
376   }
377  
378  
379 < void
380 < mg_clear()                      /* clear parser history */
379 > int
380 > mg_defuhand(ac, av)             /* default handler for unknown entities */
381 > int     ac;
382 > char    **av;
383   {
384 <        c_clearall();                   /* clear context tables */
385 <        mg_file = NULL;                 /* reset our context */
384 >        if (mg_nunknown++ == 0)         /* report first incident */
385 >                fprintf(stderr, "%s: %d: %s: %s\n", mg_file->fname,
386 >                                mg_file->lineno, mg_err[MG_EUNK], av[0]);
387 >        return(MG_OK);
388   }
389  
390  
391 < int
392 < mg_iterate(ac, av, f)           /* iterate on statement */
355 < int     ac;
356 < register char   **av;
357 < int     (*f)();
391 > void
392 > mg_clear()                      /* clear parser history */
393   {
394 <        int     niter, rval;
395 <        register int    i, j;
396 <        char    *argv[MG_MAXARGC];
362 <        char    cntbuf[10];
363 <                                        /* build partial transformation */
364 <        for (i = 0; i < ac; i++) {
365 <                if (av[i][0] == '-' && av[i][1] == 'a' && av[i][2] == '\0')
366 <                        break;
367 <                argv[i+1] = av[i];
368 <        }
369 <        argv[i+1] = NULL;
370 <        if (i) {                        /* handle transformation */
371 <                argv[0] = mg_ename[MG_E_XF];
372 <                if ((rval = handle_it(MG_E_XF, i+1, argv)) != MG_OK)
373 <                        return(rval);
374 <        }
375 <        if (i < ac) {                   /* run array */
376 <                if (i+1 >= ac || !isint(av[i+1]))
377 <                        return(MG_ETYPE);
378 <                niter = atoi(av[i+1]);
379 <                argv[0] = mg_ename[MG_E_OBJECT];
380 <                argv[1] = cntbuf;
381 <                for (j = 2; j+i < ac; j++)
382 <                        argv[j] = av[j+i];
383 <                argv[j] = NULL;
384 <                for (j = 0; j < niter; j++) {
385 <                        sprintf(cntbuf, "%d", j);
386 <                        if ((rval = handle_it(MG_E_OBJECT, 2, argv)) != MG_OK)
387 <                                return(rval);
388 <                        argv[0] = "-i";
389 <                        if ((rval = mg_iterate(ac-i, argv, f)) != MG_OK)
390 <                                return(rval);
391 <                        argv[0] = mg_ename[MG_E_OBJECT];
392 <                        if ((rval = handle_it(MG_E_OBJECT, 1, argv)) != MG_OK)
393 <                                return(rval);
394 <                }
395 <        } else if ((rval = (*f)()) != MG_OK)    /* else do this instance */
396 <                        return(rval);
397 <        if (i) {                        /* reset the transform */
398 <                argv[0] = mg_ename[MG_E_XF];
399 <                argv[1] = NULL;
400 <                (void)handle_it(MG_E_XF, 1, argv);
401 <        }
402 <        return(MG_OK);
394 >        c_clearall();                   /* clear context tables */
395 >        while (mg_file != NULL)         /* reset our file context */
396 >                mg_close();
397   }
398  
399  
# Line 417 | Line 411 | char   **av;
411   }
412  
413  
414 < static int
421 < reload_file()                   /* reload current MGF file */
422 < {
423 <        register int    rval;
424 <
425 <        if ((rval = mg_rewind()) != MG_OK)
426 <                return(rval);
427 <        while (mg_read())
428 <                if ((rval = mg_parse()) != MG_OK)
429 <                        return(rval);
430 <        return(MG_OK);
431 < }
432 <
433 <
434 < static int
414 > int
415   e_include(ac, av)               /* include file */
416   int     ac;
417   char    **av;
418   {
419 +        char    *xfarg[MG_MAXARGC];
420          MG_FCTXT        ictx;
421 <        int     rv;
421 >        XF_SPEC *xf_orig = xf_context;
422 >        register int    rv;
423  
424          if (ac < 2)
425                  return(MG_EARGC);
426          if ((rv = mg_open(&ictx, av[1])) != MG_OK)
427                  return(rv);
428 <        if ((rv = mg_iterate(ac-2, av+2, reload_file)) != MG_OK) {
429 <                fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname,
430 <                                ictx.lineno, mg_err[rv], ictx.inpline);
431 <                mg_close();
432 <                return(MG_EINCL);
428 >        if (ac > 2) {
429 >                register int    i;
430 >
431 >                xfarg[0] = mg_ename[MG_E_XF];
432 >                for (i = 1; i < ac-1; i++)
433 >                        xfarg[i] = av[i+1];
434 >                xfarg[ac-1] = NULL;
435 >                if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK) {
436 >                        mg_close();
437 >                        return(rv);
438 >                }
439          }
440 +        do {
441 +                while ((rv = mg_read()) > 0) {
442 +                        if (rv >= MG_MAXLINE-1) {
443 +                                fprintf(stderr, "%s: %d: %s\n", ictx.fname,
444 +                                                ictx.lineno, mg_err[MG_ELINE]);
445 +                                mg_close();
446 +                                return(MG_EINCL);
447 +                        }
448 +                        if ((rv = mg_parse()) != MG_OK) {
449 +                                fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname,
450 +                                                ictx.lineno, mg_err[rv],
451 +                                                ictx.inpline);
452 +                                mg_close();
453 +                                return(MG_EINCL);
454 +                        }
455 +                }
456 +                if (ac > 2)
457 +                        if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK) {
458 +                                mg_close();
459 +                                return(rv);
460 +                        }
461 +        } while (xf_context != xf_orig);
462          mg_close();
463          return(MG_OK);
464   }
# Line 471 | Line 481 | FVECT  u, v, w;
481   }
482  
483  
484 < static int
484 > int
485   e_sph(ac, av)                   /* expand a sphere into cones */
486   int     ac;
487   char    **av;
# Line 496 | Line 506 | char   **av;
506          rad = atof(av[2]);
507                                          /* initialize */
508          warpconends = 1;
509 <        if ((rval = handle_it(MG_E_VERTEX, 3, v2ent)) != MG_OK)
509 >        if ((rval = mg_handle(MG_E_VERTEX, 3, v2ent)) != MG_OK)
510                  return(rval);
511          sprintf(p2x, FLTFMT, cv->p[0]);
512          sprintf(p2y, FLTFMT, cv->p[1]);
513          sprintf(p2z, FLTFMT, cv->p[2]+rad);
514 <        if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK)
514 >        if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK)
515                  return(rval);
516          r2[0] = '0'; r2[1] = '\0';
517          for (i = 1; i <= 2*mg_nqcdivs; i++) {
518                  theta = i*(PI/2)/mg_nqcdivs;
519 <                if ((rval = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK)
519 >                if ((rval = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
520                          return(rval);
521                  sprintf(p2z, FLTFMT, cv->p[2]+rad*cos(theta));
522 <                if ((rval = handle_it(MG_E_VERTEX, 2, v2ent)) != MG_OK)
522 >                if ((rval = mg_handle(MG_E_VERTEX, 2, v2ent)) != MG_OK)
523                          return(rval);
524 <                if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK)
524 >                if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK)
525                          return(rval);
526                  strcpy(r1, r2);
527                  sprintf(r2, FLTFMT, rad*sin(theta));
528 <                if ((rval = handle_it(MG_E_CONE, 5, conent)) != MG_OK)
528 >                if ((rval = mg_handle(MG_E_CONE, 5, conent)) != MG_OK)
529                          return(rval);
530          }
531          warpconends = 0;
# Line 523 | Line 533 | char   **av;
533   }
534  
535  
536 < static int
536 > int
537   e_torus(ac, av)                 /* expand a torus into cones */
538   int     ac;
539   char    **av;
# Line 570 | Line 580 | char   **av;
580          for (j = 0; j < 3; j++)
581                  sprintf(p2[j], FLTFMT, cv->p[j] +
582                                  .5*sgn*(maxrad-minrad)*cv->n[j]);
583 <        if ((rval = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK)
583 >        if ((rval = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK)
584                  return(rval);
585 <        if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK)
585 >        if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK)
586                  return(rval);
587          sprintf(r2, FLTFMT, avgrad=.5*(minrad+maxrad));
588                                          /* run outer section */
589          for (i = 1; i <= 2*mg_nqcdivs; i++) {
590                  theta = i*(PI/2)/mg_nqcdivs;
591 <                if ((rval = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK)
591 >                if ((rval = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
592                          return(rval);
593                  for (j = 0; j < 3; j++)
594                          sprintf(p2[j], FLTFMT, cv->p[j] +
595                                  .5*sgn*(maxrad-minrad)*cos(theta)*cv->n[j]);
596 <                if ((rval = handle_it(MG_E_VERTEX, 2, v2ent)) != MG_OK)
596 >                if ((rval = mg_handle(MG_E_VERTEX, 2, v2ent)) != MG_OK)
597                          return(rval);
598 <                if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK)
598 >                if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK)
599                          return(rval);
600                  strcpy(r1, r2);
601                  sprintf(r2, FLTFMT, avgrad + .5*(maxrad-minrad)*sin(theta));
602 <                if ((rval = handle_it(MG_E_CONE, 5, conent)) != MG_OK)
602 >                if ((rval = mg_handle(MG_E_CONE, 5, conent)) != MG_OK)
603                          return(rval);
604          }
605                                          /* run inner section */
# Line 599 | Line 609 | char   **av;
609                  for (j = 0; j < 3; j++)
610                          sprintf(p2[j], FLTFMT, cv->p[j] +
611                                  .5*sgn*(maxrad-minrad)*cos(theta)*cv->n[j]);
612 <                if ((rval = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK)
612 >                if ((rval = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
613                          return(rval);
614 <                if ((rval = handle_it(MG_E_VERTEX, 2, v2ent)) != MG_OK)
614 >                if ((rval = mg_handle(MG_E_VERTEX, 2, v2ent)) != MG_OK)
615                          return(rval);
616 <                if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK)
616 >                if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK)
617                          return(rval);
618                  strcpy(r1, r2);
619                  sprintf(r2, FLTFMT, -avgrad - .5*(maxrad-minrad)*sin(theta));
620 <                if ((rval = handle_it(MG_E_CONE, 5, conent)) != MG_OK)
620 >                if ((rval = mg_handle(MG_E_CONE, 5, conent)) != MG_OK)
621                          return(rval);
622          }
623          warpconends = 0;
# Line 615 | Line 625 | char   **av;
625   }
626  
627  
628 < static int
628 > int
629   e_cyl(ac, av)                   /* replace a cylinder with equivalent cone */
630   int     ac;
631   char    **av;
# Line 628 | Line 638 | char   **av;
638          avnew[2] = av[2];
639          avnew[3] = av[3];
640          avnew[4] = av[2];
641 <        return(handle_it(MG_E_CONE, 5, avnew));
641 >        return(mg_handle(MG_E_CONE, 5, avnew));
642   }
643  
644  
645 < static int
645 > int
646   e_ring(ac, av)                  /* turn a ring into polygons */
647   int     ac;
648   char    **av;
# Line 670 | Line 680 | char   **av;
680          make_axes(u, v, cv->n);
681          for (j = 0; j < 3; j++)
682                  sprintf(p3[j], FLTFMT, cv->p[j] + maxrad*u[j]);
683 <        if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK)
683 >        if ((rv = mg_handle(MG_E_VERTEX, 3, v3ent)) != MG_OK)
684                  return(rv);
685 <        if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK)
685 >        if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK)
686                  return(rv);
687          if (minrad == 0.) {             /* closed */
688                  v1ent[3] = av[1];
689 <                if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK)
689 >                if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
690                          return(rv);
691 <                if ((rv = handle_it(MG_E_NORMAL, 4, nzent)) != MG_OK)
691 >                if ((rv = mg_handle(MG_E_NORMAL, 4, nzent)) != MG_OK)
692                          return(rv);
693                  for (i = 1; i <= 4*mg_nqcdivs; i++) {
694                          theta = i*(PI/2)/mg_nqcdivs;
695 <                        if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK)
695 >                        if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK)
696                                  return(rv);
697                          for (j = 0; j < 3; j++)
698                                  sprintf(p3[j], FLTFMT, cv->p[j] +
699                                                  maxrad*u[j]*cos(theta) +
700                                                  maxrad*v[j]*sin(theta));
701 <                        if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK)
701 >                        if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK)
702                                  return(rv);
703 <                        if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK)
703 >                        if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK)
704                                  return(rv);
705 <                        if ((rv = handle_it(MG_E_FACE, 4, fent)) != MG_OK)
705 >                        if ((rv = mg_handle(MG_E_FACE, 4, fent)) != MG_OK)
706                                  return(rv);
707                  }
708          } else {                        /* open */
709 <                if ((rv = handle_it(MG_E_VERTEX, 3, v4ent)) != MG_OK)
709 >                if ((rv = mg_handle(MG_E_VERTEX, 3, v4ent)) != MG_OK)
710                          return(rv);
711                  for (j = 0; j < 3; j++)
712                          sprintf(p4[j], FLTFMT, cv->p[j] + minrad*u[j]);
713 <                if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK)
713 >                if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK)
714                          return(rv);
715                  v1ent[3] = "_rv4";
716                  for (i = 1; i <= 4*mg_nqcdivs; i++) {
717                          theta = i*(PI/2)/mg_nqcdivs;
718 <                        if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK)
718 >                        if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
719                                  return(rv);
720 <                        if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK)
720 >                        if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK)
721                                  return(rv);
722                          for (j = 0; j < 3; j++) {
723                                  d = u[j]*cos(theta) + v[j]*sin(theta);
724                                  sprintf(p3[j], FLTFMT, cv->p[j] + maxrad*d);
725                                  sprintf(p4[j], FLTFMT, cv->p[j] + minrad*d);
726                          }
727 <                        if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK)
727 >                        if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK)
728                                  return(rv);
729 <                        if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK)
729 >                        if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK)
730                                  return(rv);
731 <                        if ((rv = handle_it(MG_E_VERTEX, 2, v4ent)) != MG_OK)
731 >                        if ((rv = mg_handle(MG_E_VERTEX, 2, v4ent)) != MG_OK)
732                                  return(rv);
733 <                        if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK)
733 >                        if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK)
734                                  return(rv);
735 <                        if ((rv = handle_it(MG_E_FACE, 5, fent)) != MG_OK)
735 >                        if ((rv = mg_handle(MG_E_FACE, 5, fent)) != MG_OK)
736                                  return(rv);
737                  }
738          }
# Line 730 | Line 740 | char   **av;
740   }
741  
742  
743 < static int
743 > int
744   e_cone(ac, av)                  /* turn a cone into polygons */
745   int     ac;
746   char    **av;
# Line 745 | Line 755 | char   **av;
755          static char     *p4ent[5] = {mg_ename[MG_E_POINT],p4[0],p4[1],p4[2]};
756          static char     *n4ent[5] = {mg_ename[MG_E_NORMAL],n4[0],n4[1],n4[2]};
757          static char     *fent[6] = {mg_ename[MG_E_FACE],"_cv1","_cv2","_cv3","_cv4"};
758 +        char    *v1n;
759          register C_VERTEX       *cv1, *cv2;
760          register int    i, j;
761          FVECT   u, v, w;
# Line 760 | Line 771 | char   **av;
771          if ((cv1 = c_getvert(av[1])) == NULL ||
772                          (cv2 = c_getvert(av[3])) == NULL)
773                  return(MG_EUNDEF);
774 +        v1n = av[1];
775          if (!isflt(av[2]) || !isflt(av[4]))
776                  return(MG_ETYPE);
777          rad1 = atof(av[2]);
# Line 778 | Line 790 | char   **av;
790                  cv = cv1;
791                  cv1 = cv2;
792                  cv2 = cv;
793 +                v1n = av[3];
794                  d = rad1;
795                  rad1 = rad2;
796                  rad2 = d;
# Line 804 | Line 817 | char   **av;
817                  else
818                          sprintf(n3[j], FLTFMT, u[j] + w[j]*n2off);
819          }
820 <        if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK)
820 >        if ((rv = mg_handle(MG_E_VERTEX, 3, v3ent)) != MG_OK)
821                  return(rv);
822 <        if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK)
822 >        if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK)
823                  return(rv);
824 <        if ((rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK)
824 >        if ((rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK)
825                  return(rv);
826          if (rad1 == 0.) {               /* triangles */
827 <                v1ent[3] = av[1];
828 <                if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK)
827 >                v1ent[3] = v1n;
828 >                if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
829                          return(rv);
830                  for (j = 0; j < 3; j++)
831                          sprintf(n4[j], FLTFMT, w[j]);
832 <                if ((rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK)
832 >                if ((rv = mg_handle(MG_E_NORMAL, 4, n4ent)) != MG_OK)
833                          return(rv);
834                  for (i = 1; i <= 4*mg_nqcdivs; i++) {
835                          theta = sgn*i*(PI/2)/mg_nqcdivs;
836 <                        if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK)
836 >                        if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK)
837                                  return(rv);
838                          for (j = 0; j < 3; j++) {
839                                  d = u[j]*cos(theta) + v[j]*sin(theta);
# Line 828 | Line 841 | char   **av;
841                                  if (n2off > -FHUGE)
842                                          sprintf(n3[j], FLTFMT, d + w[j]*n2off);
843                          }
844 <                        if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK)
844 >                        if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK)
845                                  return(rv);
846 <                        if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK)
846 >                        if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK)
847                                  return(rv);
848                          if (n2off > -FHUGE &&
849 <                        (rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK)
849 >                        (rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK)
850                                  return(rv);
851 <                        if ((rv = handle_it(MG_E_FACE, 4, fent)) != MG_OK)
851 >                        if ((rv = mg_handle(MG_E_FACE, 4, fent)) != MG_OK)
852                                  return(rv);
853                  }
854          } else {                        /* quads */
# Line 854 | Line 867 | char   **av;
867                          else
868                                  sprintf(n4[j], FLTFMT, u[j] + w[j]*n1off);
869                  }
870 <                if ((rv = handle_it(MG_E_VERTEX, 3, v4ent)) != MG_OK)
870 >                if ((rv = mg_handle(MG_E_VERTEX, 3, v4ent)) != MG_OK)
871                          return(rv);
872 <                if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK)
872 >                if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK)
873                          return(rv);
874 <                if ((rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK)
874 >                if ((rv = mg_handle(MG_E_NORMAL, 4, n4ent)) != MG_OK)
875                          return(rv);
876                  for (i = 1; i <= 4*mg_nqcdivs; i++) {
877                          theta = sgn*i*(PI/2)/mg_nqcdivs;
878 <                        if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK)
878 >                        if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
879                                  return(rv);
880 <                        if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK)
880 >                        if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK)
881                                  return(rv);
882                          for (j = 0; j < 3; j++) {
883                                  d = u[j]*cos(theta) + v[j]*sin(theta);
# Line 875 | Line 888 | char   **av;
888                                  if (n1off < FHUGE)
889                                          sprintf(n4[j], FLTFMT, d + w[j]*n1off);
890                          }
891 <                        if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK)
891 >                        if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK)
892                                  return(rv);
893 <                        if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK)
893 >                        if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK)
894                                  return(rv);
895                          if (n2off > -FHUGE &&
896 <                        (rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK)
896 >                        (rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK)
897                                  return(rv);
898 <                        if ((rv = handle_it(MG_E_VERTEX, 2, v4ent)) != MG_OK)
898 >                        if ((rv = mg_handle(MG_E_VERTEX, 2, v4ent)) != MG_OK)
899                                  return(rv);
900 <                        if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK)
900 >                        if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK)
901                                  return(rv);
902                          if (n1off < FHUGE &&
903 <                        (rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK)
903 >                        (rv = mg_handle(MG_E_NORMAL, 4, n4ent)) != MG_OK)
904                                  return(rv);
905 <                        if ((rv = handle_it(MG_E_FACE, 5, fent)) != MG_OK)
905 >                        if ((rv = mg_handle(MG_E_FACE, 5, fent)) != MG_OK)
906                                  return(rv);
907                  }
908          }
# Line 897 | Line 910 | char   **av;
910   }
911  
912  
913 < static int
913 > int
914   e_prism(ac, av)                 /* turn a prism into polygons */
915   int     ac;
916   char    **av;
917   {
918          static char     p[3][24];
919 <        static char     *vent[4] = {mg_ename[MG_E_VERTEX],NULL,"="};
919 >        static char     *vent[5] = {mg_ename[MG_E_VERTEX],NULL,"="};
920          static char     *pent[5] = {mg_ename[MG_E_POINT],p[0],p[1],p[2]};
921 +        static char     *znorm[5] = {mg_ename[MG_E_NORMAL],"0","0","0"};
922          char    *newav[MG_MAXARGC], nvn[MG_MAXARGC-1][8];
923          double  length;
924 +        int     hasnorm;
925          FVECT   v1, v2, v3, norm;
926          register C_VERTEX       *cv;
927          C_VERTEX        *cv0;
928          int     rv;
929          register int    i, j;
930 <
930 >                                                /* check arguments */
931          if (ac < 5)
932                  return(MG_EARGC);
933          if (!isflt(av[ac-1]))
# Line 920 | Line 935 | char   **av;
935          length = atof(av[ac-1]);
936          if (length <= FTINY && length >= -FTINY)
937                  return(MG_EILL);
938 <                                        /* do bottom face */
939 <        newav[0] = mg_ename[MG_E_FACE];
925 <        for (i = 1; i < ac-1; i++)
926 <                newav[i] = av[i];
927 <        newav[i] = NULL;
928 <        if ((rv = handle_it(MG_E_FACE, i, newav)) != MG_OK)
929 <                return(rv);
930 <                                        /* compute face normal */
931 <        if ((cv0 = c_getvert(av[2])) == NULL)
938 >                                                /* compute face normal */
939 >        if ((cv0 = c_getvert(av[1])) == NULL)
940                  return(MG_EUNDEF);
941 +        hasnorm = 0;
942          norm[0] = norm[1] = norm[2] = 0.;
943          v1[0] = v1[1] = v1[2] = 0.;
944          for (i = 2; i < ac-1; i++) {
945                  if ((cv = c_getvert(av[i])) == NULL)
946                          return(MG_EUNDEF);
947 +                hasnorm += !is0vect(cv->n);
948                  v2[0] = cv->p[0] - cv0->p[0];
949                  v2[1] = cv->p[1] - cv0->p[1];
950                  v2[2] = cv->p[2] - cv0->p[2];
# Line 946 | Line 956 | char   **av;
956          }
957          if (normalize(norm) == 0.)
958                  return(MG_EILL);
959 <                                        /* create moved vertices */
959 >                                                /* create moved vertices */
960          for (i = 1; i < ac-1; i++) {
961                  sprintf(nvn[i-1], "_pv%d", i);
962                  vent[1] = nvn[i-1];
963 <                if ((rv = handle_it(MG_E_VERTEX, 3, vent)) != MG_OK)
963 >                vent[3] = av[i];
964 >                if ((rv = mg_handle(MG_E_VERTEX, 4, vent)) != MG_OK)
965                          return(rv);
966                  cv = c_getvert(av[i]);          /* checked above */
967                  for (j = 0; j < 3; j++)
968                          sprintf(p[j], FLTFMT, cv->p[j] - length*norm[j]);
969 <                if ((rv = handle_it(MG_E_POINT, 4, pent)) != MG_OK)
969 >                if ((rv = mg_handle(MG_E_POINT, 4, pent)) != MG_OK)
970                          return(rv);
960                newav[ac-1-i] = nvn[i-1];       /* reverse */
971          }
972 <                                                /* do top face */
973 <        if ((rv = handle_it(MG_E_FACE, ac-1, newav)) != MG_OK)
964 <                return(rv);
972 >                                                /* make faces */
973 >        newav[0] = mg_ename[MG_E_FACE];
974                                                  /* do the side faces */
975          newav[5] = NULL;
976          newav[3] = av[ac-2];
# Line 969 | Line 978 | char   **av;
978          for (i = 1; i < ac-1; i++) {
979                  newav[1] = nvn[i-1];
980                  newav[2] = av[i];
981 <                if ((rv = handle_it(MG_E_FACE, 5, newav)) != MG_OK)
981 >                if ((rv = mg_handle(MG_E_FACE, 5, newav)) != MG_OK)
982                          return(rv);
983                  newav[3] = newav[2];
984                  newav[4] = newav[1];
985          }
986 +                                                /* do top face */
987 +        for (i = 1; i < ac-1; i++) {
988 +                if (hasnorm) {                  /* zero normals */
989 +                        vent[1] = nvn[i-1];
990 +                        if ((rv = mg_handle(MG_E_VERTEX, 2, vent)) != MG_OK)
991 +                                return(rv);
992 +                        if ((rv = mg_handle(MG_E_NORMAL, 4, znorm)) != MG_OK)
993 +                                return(rv);
994 +                }
995 +                newav[ac-1-i] = nvn[i-1];       /* reverse */
996 +        }
997 +        if ((rv = mg_handle(MG_E_FACE, ac-1, newav)) != MG_OK)
998 +                return(rv);
999 +                                                /* do bottom face */
1000 +        if (hasnorm)
1001 +                for (i = 1; i < ac-1; i++) {
1002 +                        vent[1] = nvn[i-1];
1003 +                        vent[3] = av[i];
1004 +                        if ((rv = mg_handle(MG_E_VERTEX, 4, vent)) != MG_OK)
1005 +                                return(rv);
1006 +                        if ((rv = mg_handle(MG_E_NORMAL, 4, znorm)) != MG_OK)
1007 +                                return(rv);
1008 +                        newav[i] = nvn[i-1];
1009 +                }
1010 +        else
1011 +                for (i = 1; i < ac-1; i++)
1012 +                        newav[i] = av[i];
1013 +        newav[i] = NULL;
1014 +        if ((rv = mg_handle(MG_E_FACE, i, newav)) != MG_OK)
1015 +                return(rv);
1016          return(MG_OK);
1017   }
1018  
1019  
1020   static int
1021 < e_cspec(ac, av)                 /* handle spectral color */
983 < int     ac;
984 < char    **av;
1021 > put_cxy()                       /* put out current xy chromaticities */
1022   {
1023          static char     xbuf[24], ybuf[24];
1024          static char     *ccom[4] = {mg_ename[MG_E_CXY], xbuf, ybuf};
988        int     rv;
1025  
1026 +        sprintf(xbuf, "%.4f", c_ccolor->cx);
1027 +        sprintf(ybuf, "%.4f", c_ccolor->cy);
1028 +        return(mg_handle(MG_E_CXY, 3, ccom));
1029 + }
1030 +
1031 +
1032 + static int
1033 + put_cspec()                     /* put out current color spectrum */
1034 + {
1035 +        char    wl[2][6], vbuf[C_CNSS][24];
1036 +        char    *newav[C_CNSS+4];
1037 +        double  sf;
1038 +        register int    i;
1039 +
1040 +        if (mg_ehand[MG_E_CSPEC] != c_hcolor) {
1041 +                sprintf(wl[0], "%d", C_CMINWL);
1042 +                sprintf(wl[1], "%d", C_CMAXWL);
1043 +                newav[0] = mg_ename[MG_E_CSPEC];
1044 +                newav[1] = wl[0];
1045 +                newav[2] = wl[1];
1046 +                sf = (double)C_CNSS / c_ccolor->ssum;
1047 +                for (i = 0; i < C_CNSS; i++) {
1048 +                        sprintf(vbuf[i], "%.4f", sf*c_ccolor->ssamp[i]);
1049 +                        newav[i+3] = vbuf[i];
1050 +                }
1051 +                newav[C_CNSS+3] = NULL;
1052 +                if ((i = mg_handle(MG_E_CSPEC, C_CNSS+3, newav)) != MG_OK)
1053 +                        return(i);
1054 +        }
1055 +        return(MG_OK);
1056 + }
1057 +
1058 +
1059 + static int
1060 + e_cspec(ac, av)                 /* handle spectral color */
1061 + int     ac;
1062 + char    **av;
1063 + {
1064 +                                /* convert to xy chromaticity */
1065          c_ccvt(c_ccolor, C_CSXY);
1066                                  /* if it's really their handler, use it */
1067 <        if (mg_ehand[MG_E_CXY] != c_hcolor) {
1068 <                sprintf(xbuf, "%.4f", c_ccolor->cx);
994 <                sprintf(ybuf, "%.4f", c_ccolor->cy);
995 <                if ((rv = handle_it(MG_E_CXY, 3, ccom)) != MG_OK)
996 <                        return(rv);
997 <        }
1067 >        if (mg_ehand[MG_E_CXY] != c_hcolor)
1068 >                return(put_cxy());
1069          return(MG_OK);
1070   }
1071  
# Line 1004 | Line 1075 | e_cmix(ac, av)                 /* handle mixing of colors */
1075   int     ac;
1076   char    **av;
1077   {
1007        char    wl[2][6], vbuf[C_CNSS][24];
1008        char    *newav[C_CNSS+4];
1009        int     rv;
1010        register int    i;
1078          /*
1079           * Contorted logic works as follows:
1080           *      1. the colors are already mixed in c_hcolor() support function
# Line 1018 | Line 1085 | char   **av;
1085           */
1086          if (mg_ehand[MG_E_CSPEC] == e_cspec)
1087                  c_ccvt(c_ccolor, C_CSXY);
1088 <        else if (c_ccolor->flags & C_CDSPEC) {
1089 <                if (mg_ehand[MG_E_CSPEC] != c_hcolor) {
1090 <                        sprintf(wl[0], "%d", C_CMINWL);
1091 <                        sprintf(wl[1], "%d", C_CMAXWL);
1092 <                        newav[0] = mg_ename[MG_E_CSPEC];
1093 <                        newav[1] = wl[0];
1094 <                        newav[2] = wl[1];
1095 <                        for (i = 0; i < C_CNSS; i++) {
1096 <                                sprintf(vbuf[i], "%.6f",
1097 <                                                (double)c_ccolor->ssamp[i] /
1098 <                                                c_ccolor->ssum);
1099 <                                newav[i+3] = vbuf[i];
1100 <                        }
1101 <                        newav[C_CNSS+3] = NULL;
1102 <                        if ((rv = handle_it(MG_E_CSPEC, C_CNSS+3, newav)) != MG_OK)
1103 <                                return(rv);
1104 <                }
1105 <                return(MG_OK);
1106 <        }
1107 <        if (mg_ehand[MG_E_CXY] != c_hcolor) {
1108 <                sprintf(vbuf[0], "%.4f", c_ccolor->cx);
1109 <                sprintf(vbuf[1], "%.4f", c_ccolor->cy);
1110 <                newav[0] = mg_ename[MG_E_CXY];
1111 <                newav[1] = vbuf[0];
1045 <                newav[2] = vbuf[1];
1046 <                newav[3] = NULL;
1047 <                if ((rv = handle_it(MG_E_CXY, 3, newav)) != MG_OK)
1048 <                        return(rv);
1049 <        }
1088 >        else if (c_ccolor->flags & C_CDSPEC)
1089 >                return(put_cspec());
1090 >        if (mg_ehand[MG_E_CXY] != c_hcolor)
1091 >                return(put_cxy());
1092 >        return(MG_OK);
1093 > }
1094 >
1095 >
1096 > static int
1097 > e_cct(ac, av)                   /* handle color temperature */
1098 > int     ac;
1099 > char    **av;
1100 > {
1101 >        /*
1102 >         * Logic is similar to e_cmix here.  Support handler has already
1103 >         * converted temperature to spectral color.  Put it out as such
1104 >         * if they support it, otherwise convert to xy chromaticity and
1105 >         * put it out if they handle it.
1106 >         */
1107 >        if (mg_ehand[MG_E_CSPEC] != e_cspec)
1108 >                return(put_cspec());
1109 >        c_ccvt(c_ccolor, C_CSXY);
1110 >        if (mg_ehand[MG_E_CXY] != c_hcolor)
1111 >                return(put_cxy());
1112          return(MG_OK);
1113   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines