--- ray/src/cv/mgflib/parser.c 1995/04/18 15:53:26 1.16 +++ ray/src/cv/mgflib/parser.c 1996/06/19 22:34:59 1.23 @@ -1,4 +1,4 @@ -/* Copyright (c) 1995 Regents of the University of California */ +/* Copyright (c) 1996 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -27,6 +27,12 @@ char mg_ename[MG_NENTITIES][MG_MAXELEN] = MG_NAMELIST; int (*mg_ehand[MG_NENTITIES])(); + /* Handler routine for unknown entities */ + +int (*mg_uhand)() = mg_defuhand; + +unsigned mg_nunknown; /* count of unknown entities */ + /* error messages */ char *mg_err[MG_NERRS] = MG_ERRLIST; @@ -57,11 +63,12 @@ int mg_nqcdivs = MG_NQCD; /* number of divisions per q static int e_any_toss(), /* discard unneeded entity */ e_ies(), /* IES luminaire file */ - e_include(), /* include file */ - e_sph(), /* sphere */ e_cct(), /* color temperature */ e_cmix(), /* color mixtures */ - e_cspec(), /* color spectra */ + e_cspec(); /* color spectra */ + +int e_include(), /* include file */ + e_sph(), /* sphere */ e_cyl(), /* cylinder */ e_cone(), /* cone */ e_prism(), /* prism */ @@ -89,83 +96,83 @@ mg_init() /* initialize alternate entity handlers */ mg_ehand[MG_E_INCLUDE] = e_include; if (mg_ehand[MG_E_SPH] == NULL) { mg_ehand[MG_E_SPH] = e_sph; - ineed |= 1<prev; /* restore enclosing context */ - if (ctx->fp == stdin) - return; /* don't close standard input */ - fclose(ctx->fp); + if (ctx->fp != stdin) /* close file if it's a file */ + fclose(ctx->fp); } @@ -295,11 +304,11 @@ mg_read() /* read next line from file */ if (fgets(mg_file->inpline+len, MG_MAXLINE-len, mg_file->fp) == NULL) return(len); - mg_file->lineno++; len += strlen(mg_file->inpline+len); - if (len > 1 && mg_file->inpline[len-2] == '\\') - mg_file->inpline[--len-1] = ' '; - } while (mg_file->inpline[len]); + if (len >= MG_MAXLINE-1) + return(len); + mg_file->lineno++; + } while (len > 1 && mg_file->inpline[len-2] == '\\'); return(len); } @@ -311,10 +320,13 @@ mg_parse() /* parse current input line */ char abuf[MG_MAXLINE]; char *argv[MG_MAXARGC]; int en; - register char *cp, **ap; - - strcpy(cp=abuf, mg_file->inpline); - ap = argv; /* break into words */ + register char *cp, *cp2, **ap; + /* copy line, removing escape chars */ + cp = abuf; cp2 = mg_file->inpline; + while ((*cp++ = *cp2++)) + if (cp2[0] == '\n' && cp2[-1] == '\\') + cp--; + cp = abuf; ap = argv; /* break into words */ for ( ; ; ) { while (isspace(*cp)) *cp++ = '\0'; @@ -340,28 +352,48 @@ char *fn; { MG_FCTXT cntxt; int rval; + register int nbr; if ((rval = mg_open(&cntxt, fn)) != MG_OK) { fprintf(stderr, "%s: %s\n", fn, mg_err[rval]); return(rval); } - while (mg_read()) /* parse each line */ + while ((nbr = mg_read()) > 0) { /* parse each line */ + if (nbr >= MG_MAXLINE-1) { + fprintf(stderr, "%s: %d: %s\n", cntxt.fname, + cntxt.lineno, mg_err[rval=MG_ELINE]); + break; + } if ((rval = mg_parse()) != MG_OK) { fprintf(stderr, "%s: %d: %s:\n%s", cntxt.fname, cntxt.lineno, mg_err[rval], cntxt.inpline); break; } + } mg_close(); return(rval); } +int +mg_defuhand(ac, av) /* default handler for unknown entities */ +int ac; +char **av; +{ + if (mg_nunknown++ == 0) /* report first incident */ + fprintf(stderr, "%s: %d: %s: %s\n", mg_file->fname, + mg_file->lineno, mg_err[MG_EUNK], av[0]); + return(MG_OK); +} + + void mg_clear() /* clear parser history */ { c_clearall(); /* clear context tables */ - mg_file = NULL; /* reset our context */ + while (mg_file != NULL) /* reset our file context */ + mg_close(); } @@ -379,7 +411,7 @@ char **av; } -static int +int e_include(ac, av) /* include file */ int ac; char **av; @@ -387,7 +419,7 @@ char **av; char *xfarg[MG_MAXARGC]; MG_FCTXT ictx; XF_SPEC *xf_orig = xf_context; - int rv; + register int rv; if (ac < 2) return(MG_EARGC); @@ -400,11 +432,19 @@ char **av; for (i = 1; i < ac-1; i++) xfarg[i] = av[i+1]; xfarg[ac-1] = NULL; - if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK) + if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK) { + mg_close(); return(rv); + } } do { - while (mg_read()) + while ((rv = mg_read()) > 0) { + if (rv >= MG_MAXLINE-1) { + fprintf(stderr, "%s: %d: %s\n", ictx.fname, + ictx.lineno, mg_err[MG_ELINE]); + mg_close(); + return(MG_EINCL); + } if ((rv = mg_parse()) != MG_OK) { fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname, ictx.lineno, mg_err[rv], @@ -412,9 +452,12 @@ char **av; mg_close(); return(MG_EINCL); } + } if (ac > 2) - if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK) + if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK) { + mg_close(); return(rv); + } } while (xf_context != xf_orig); mg_close(); return(MG_OK); @@ -438,7 +481,7 @@ FVECT u, v, w; } -static int +int e_sph(ac, av) /* expand a sphere into cones */ int ac; char **av; @@ -490,7 +533,7 @@ char **av; } -static int +int e_torus(ac, av) /* expand a torus into cones */ int ac; char **av; @@ -582,7 +625,7 @@ char **av; } -static int +int e_cyl(ac, av) /* replace a cylinder with equivalent cone */ int ac; char **av; @@ -599,7 +642,7 @@ char **av; } -static int +int e_ring(ac, av) /* turn a ring into polygons */ int ac; char **av; @@ -697,7 +740,7 @@ char **av; } -static int +int e_cone(ac, av) /* turn a cone into polygons */ int ac; char **av; @@ -712,6 +755,7 @@ char **av; static char *p4ent[5] = {mg_ename[MG_E_POINT],p4[0],p4[1],p4[2]}; static char *n4ent[5] = {mg_ename[MG_E_NORMAL],n4[0],n4[1],n4[2]}; static char *fent[6] = {mg_ename[MG_E_FACE],"_cv1","_cv2","_cv3","_cv4"}; + char *v1n; register C_VERTEX *cv1, *cv2; register int i, j; FVECT u, v, w; @@ -727,6 +771,7 @@ char **av; if ((cv1 = c_getvert(av[1])) == NULL || (cv2 = c_getvert(av[3])) == NULL) return(MG_EUNDEF); + v1n = av[1]; if (!isflt(av[2]) || !isflt(av[4])) return(MG_ETYPE); rad1 = atof(av[2]); @@ -745,6 +790,7 @@ char **av; cv = cv1; cv1 = cv2; cv2 = cv; + v1n = av[3]; d = rad1; rad1 = rad2; rad2 = d; @@ -778,7 +824,7 @@ char **av; if ((rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK) return(rv); if (rad1 == 0.) { /* triangles */ - v1ent[3] = av[1]; + v1ent[3] = v1n; if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rv); for (j = 0; j < 3; j++) @@ -864,7 +910,7 @@ char **av; } -static int +int e_prism(ac, av) /* turn a prism into polygons */ int ac; char **av; @@ -976,13 +1022,10 @@ put_cxy() /* put out current xy chromaticities */ { static char xbuf[24], ybuf[24]; static char *ccom[4] = {mg_ename[MG_E_CXY], xbuf, ybuf}; - int rv; sprintf(xbuf, "%.4f", c_ccolor->cx); sprintf(ybuf, "%.4f", c_ccolor->cy); - if ((rv = mg_handle(MG_E_CXY, 3, ccom)) != MG_OK) - return(rv); - return(MG_OK); + return(mg_handle(MG_E_CXY, 3, ccom)); }