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

Comparing ray/src/common/caldefn.c (file contents):
Revision 2.16 by schorsch, Sat Jun 7 12:50:20 2003 UTC vs.
Revision 2.29 by greg, Mon Aug 31 15:06:20 2020 UTC

# Line 27 | Line 27 | static const char      RCSid[] = "$Id$";
27  
28   #include "copyright.h"
29  
30 #include  <stdio.h>
31
32 #include  <string.h>
33
30   #include  <ctype.h>
31  
32 + #include  "rterror.h"
33 + #include  "rtio.h"
34 + #include  "rtmisc.h"
35   #include  "calcomp.h"
36  
37   #ifndef  NHASH
# Line 43 | Line 42 | static const char      RCSid[] = "$Id$";
42  
43   #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
44  
45 < static double  dvalue();
45 > static double  dvalue(char  *name, EPNODE *d);
46  
47   #define  MAXCLOCK       (1L<<31)        /* clock wrap value */
48  
# Line 114 | Line 113 | evariable(                     /* evaluate a variable */
113          EPNODE  *ep
114   )
115   {
116 <    register VARDEF  *dp = ep->v.ln;
116 >    VARDEF  *dp = ep->v.ln;
117  
118      return(dvalue(dp->name, dp->def));
119   }
# Line 128 | Line 127 | varset(                /* set a variable's value */
127   )
128   {
129      char  *qname;
130 <    register EPNODE  *ep1, *ep2;
130 >    EPNODE  *ep1, *ep2;
131                                          /* get qualified name */
132      qname = qualname(vname, 0);
133                                          /* check for quick set */
134 <    if ((ep1 = dlookup(qname)) != NULL && ep1->v.kid->type == SYM) {
134 >    if ((ep1 = dlookup(qname)) != NULL && ep1->v.kid->type == SYM &&
135 >                (ep1->type == ':') <= (assign == ':')) {
136          ep2 = ep1->v.kid->sibling;
137          if (ep2->type == NUM) {
138              ep2->v.num = val;
# Line 140 | Line 140 | varset(                /* set a variable's value */
140              return;
141          }
142      }
143 +    if (ep1 != NULL && esupport&E_REDEFW) {
144 +        wputs(qname);
145 +        if (ep1->type == ':')
146 +            wputs(": reset constant expression\n");
147 +        else
148 +            wputs(": reset expression\n");
149 +    }
150                                          /* hand build definition */
151      ep1 = newnode();
152      ep1->type = assign;
# Line 151 | Line 158 | varset(                /* set a variable's value */
158      ep2->type = NUM;
159      ep2->v.num = val;
160      addekid(ep1, ep2);
161 <    dremove(qname);
161 >    if (assign == ':')
162 >        dremove(qname);
163 >    else
164 >        dclear(qname);
165      dpush(qname, ep1);
166   }
167  
# Line 161 | Line 171 | dclear(                        /* delete variable definitions of name */
171          char  *name
172   )
173   {
174 <    register EPNODE  *ep;
174 >    EPNODE  *ep;
175  
176      while ((ep = dpop(name)) != NULL) {
177          if (ep->type == ':') {
# Line 178 | Line 188 | dremove(                       /* delete all definitions of name */
188          char  *name
189   )
190   {
191 <    register EPNODE  *ep;
191 >    EPNODE  *ep;
192  
193      while ((ep = dpop(name)) != NULL)
194          epfree(ep);
# Line 190 | Line 200 | vardefined(    /* return non-zero if variable defined */
200          char  *name
201   )
202   {
203 <    register EPNODE  *dp;
203 >    EPNODE  *dp;
204  
205      return((dp = dlookup(name)) != NULL && dp->v.kid->type == SYM);
206   }
# Line 198 | Line 208 | vardefined(    /* return non-zero if variable defined */
208  
209   char *
210   setcontext(                     /* set a new context path */
211 <        register char  *ctx
211 >        char  *ctx
212   )
213   {
214 <    register char  *cpp;
214 >    char  *cpp;
215  
216      if (ctx == NULL)
217          return(context);                /* just asking */
# Line 235 | Line 245 | pushcontext(           /* push on another context */
245   )
246   {
247      char  oldcontext[MAXCNTX+1];
248 <    register int  n;
248 >    int  n;
249  
250      strcpy(oldcontext, context);        /* save old context */
251      setcontext(ctx);                    /* set new context */
# Line 252 | Line 262 | pushcontext(           /* push on another context */
262   char *
263   popcontext(void)                        /* pop off top context */
264   {
265 <    register char  *cp1, *cp2;
265 >    char  *cp1, *cp2;
266  
267      if (!context[0])                    /* nothing left to pop */
268          return(context);
# Line 260 | Line 270 | popcontext(void)                       /* pop off top context */
270      while (*++cp2 && *cp2 != CNTXMARK)
271          ;
272      cp1 = context;                      /* copy tail to front */
273 <    while (*cp1++ = *cp2++)
273 >    while ( (*cp1++ = *cp2++) )
274          ;
275      return(context);
276   }
# Line 268 | Line 278 | popcontext(void)                       /* pop off top context */
278  
279   char *
280   qualname(               /* get qualified name */
281 <        register char  *nam,
281 >        char  *nam,
282          int  lvl
283   )
284   {
285 <    static char  nambuf[MAXWORD+1];
286 <    register char  *cp = nambuf, *cpp;
285 >    static char  nambuf[RMAXWORD+1];
286 >    char  *cp = nambuf, *cpp;
287                                  /* check for explicit local */
288      if (*nam == CNTXMARK)
289          if (lvl > 0)            /* only action is to refuse search */
# Line 284 | Line 294 | qualname(              /* get qualified name */
294          return(lvl > 0 ? NULL : nam);
295                                  /* copy name to static buffer */
296      while (*nam) {
297 <        if (cp >= nambuf+MAXWORD)
297 >        if (cp >= nambuf+RMAXWORD)
298                  goto toolong;
299          *cp++ = *nam++;
300      }
# Line 303 | Line 313 | qualname(              /* get qualified name */
313              ;
314      }
315      while (*cpp) {              /* copy context to static buffer */
316 <        if (cp >= nambuf+MAXWORD)
316 >        if (cp >= nambuf+RMAXWORD)
317              goto toolong;
318          *cp++ = *cpp++;
319      }
# Line 315 | Line 325 | toolong:
325  
326   int
327   incontext(                      /* is qualified name in current context? */
328 <        register char  *qn
328 >        char  *qn
329   )
330   {
331      if (!context[0])                    /* global context accepts all */
# Line 331 | Line 341 | chanout(                       /* set output channels */
341          void  (*cs)(int n, double v)
342   )
343   {
344 <    register EPNODE  *ep;
344 >    EPNODE  *ep;
345  
346      for (ep = outchan; ep != NULL; ep = ep->sibling)
347          (*cs)(ep->v.kid->v.chan, evalue(ep->v.kid->sibling));
# Line 344 | Line 354 | dcleanup(              /* clear definitions (0->vars,1->output,2->
354          int  lvl
355   )
356   {
357 <    register int  i;
358 <    register VARDEF  *vp;
359 <    register EPNODE  *ep;
357 >    int  i;
358 >    VARDEF  *vp;
359 >    EPNODE  *ep;
360                                  /* if context is global, clear all */
361      for (i = 0; i < NHASH; i++)
362          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
363 <            if (incontext(vp->name))
363 >            if (incontext(vp->name)) {
364                  if (lvl >= 2)
365                      dremove(vp->name);
366                  else
367                      dclear(vp->name);
368 +            }
369      if (lvl >= 1) {
370          for (ep = outchan; ep != NULL; ep = ep->sibling)
371              epfree(ep);
# Line 368 | Line 379 | dlookup(                       /* look up a definition */
379          char  *name
380   )
381   {
382 <    register VARDEF  *vp;
382 >    VARDEF  *vp;
383      
384      if ((vp = varlookup(name)) == NULL)
385          return(NULL);
# Line 382 | Line 393 | varlookup(                     /* look up a variable */
393   )
394   {
395      int  lvl = 0;
396 <    register char  *qname;
397 <    register VARDEF  *vp;
396 >    char  *qname;
397 >    VARDEF  *vp;
398                                  /* find most qualified match */
399      while ((qname = qualname(name, lvl++)) != NULL)
400          for (vp = hashtbl[hash(qname)]; vp != NULL; vp = vp->next)
# Line 398 | Line 409 | varinsert(                     /* get a link to a variable */
409          char  *name
410   )
411   {
412 <    register VARDEF  *vp;
412 >    VARDEF  *vp;
413      int  hv;
414      
415      if ((vp = varlookup(name)) != NULL) {
# Line 424 | Line 435 | libupdate(                     /* update library links */
435          char  *fn
436   )
437   {
438 <    register int  i;
439 <    register VARDEF  *vp;
438 >    int  i;
439 >    VARDEF  *vp;
440                                          /* if fn is NULL then relink all */
441      for (i = 0; i < NHASH; i++)
442          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
# Line 436 | Line 447 | libupdate(                     /* update library links */
447  
448   void
449   varfree(                                /* release link to variable */
450 <        register VARDEF  *ln
450 >        VARDEF   *ln
451   )
452   {
453 <    register VARDEF  *vp;
453 >    VARDEF  *vp;
454      int  hv;
455  
456      if (--ln->nlinks > 0)
# Line 472 | Line 483 | dfirst(void)                   /* return pointer to first definition *
483   EPNODE *
484   dnext(void)                             /* return pointer to next definition */
485   {
486 <    register EPNODE  *ep;
487 <    register char  *nm;
486 >    EPNODE  *ep;
487 >    char  *nm;
488  
489      while (htndx < NHASH) {
490          if (htpos == NULL)
# Line 497 | Line 508 | dpop(                  /* pop a definition */
508          char  *name
509   )
510   {
511 <    register VARDEF  *vp;
512 <    register EPNODE  *dp;
511 >    VARDEF  *vp;
512 >    EPNODE  *dp;
513      
514      if ((vp = varlookup(name)) == NULL || vp->def == NULL)
515          return(NULL);
# Line 512 | Line 523 | dpop(                  /* pop a definition */
523   void
524   dpush(                  /* push on a definition */
525          char  *nm,
526 <        register EPNODE  *ep
526 >        EPNODE   *ep
527   )
528   {
529 <    register VARDEF  *vp;
529 >    VARDEF  *vp;
530  
531      vp = varinsert(nm);
532      ep->sibling = vp->def;
# Line 529 | Line 540 | addchan(                       /* add an output channel assignment */
540   )
541   {
542      int  ch = sp->v.kid->v.chan;
543 <    register EPNODE  *ep, *epl;
543 >    EPNODE  *ep, *epl;
544  
545      for (epl = NULL, ep = outchan; ep != NULL; epl = ep, ep = ep->sibling)
546          if (ep->v.kid->v.chan >= ch) {
# Line 557 | Line 568 | addchan(                       /* add an output channel assignment */
568   void
569   getstatement(void)                      /* get next statement */
570   {
571 <    register EPNODE  *ep;
571 >    EPNODE  *ep;
572      char  *qname;
573 <    register VARDEF  *vdef;
573 >    VARDEF  *vdef;
574  
575      if (nextc == ';') {         /* empty statement */
576          scan();
# Line 572 | Line 583 | getstatement(void)                     /* get next statement */
583      } else {                            /* ordinary definition */
584          ep = getdefn();
585          qname = qualname(dname(ep), 0);
586 <        if (esupport&E_REDEFW && (vdef = varlookup(qname)) != NULL)
586 >        if (esupport&E_REDEFW && (vdef = varlookup(qname)) != NULL) {
587              if (vdef->def != NULL && epcmp(ep, vdef->def)) {
588                  wputs(qname);
589                  if (vdef->def->type == ':')
# Line 583 | Line 594 | getstatement(void)                     /* get next statement */
594                  wputs(qname);
595                  wputs(": definition hides library function\n");
596              }
597 +        }
598          if (ep->type == ':')
599              dremove(qname);
600          else
# Line 604 | Line 616 | getdefn(void)
616          /*      FUNC(SYM,..) = E1 */
617          /*      FUNC(SYM,..) : E1 */
618   {
619 <    register EPNODE  *ep1, *ep2;
619 >    EPNODE  *ep1, *ep2;
620  
621      if (!isalpha(nextc) && nextc != CNTXMARK)
622          syntax("illegal variable name");
# Line 621 | Line 633 | getdefn(void)
633          do {
634              scan();
635              if (!isalpha(nextc))
636 <                syntax("illegal variable name");
636 >                syntax("illegal parameter name");
637              ep2 = newnode();
638              ep2->type = SYM;
639              ep2->v.name = savestr(getname());
640 +            if (strchr(ep2->v.name, CNTXMARK) != NULL)
641 +                syntax("illegal parameter name");
642              addekid(ep1, ep2);
643          } while (nextc == ',');
644          if (nextc != ')')
# Line 644 | Line 658 | getdefn(void)
658  
659      if (ep1->type == SYM && ep1->sibling->type != NUM) {
660          ep1 = newnode();
661 <        ep1->type = TICK;
661 >        ep1->type = CLKT;
662          ep1->v.tick = 0;
663          addekid(ep2, ep1);
664          ep1 = newnode();
# Line 660 | Line 674 | getdefn(void)
674   EPNODE *
675   getchan(void)                   /* A -> $N = E1 */
676   {
677 <    register EPNODE  *ep1, *ep2;
677 >    EPNODE  *ep1, *ep2;
678  
679      if (nextc != '$')
680          syntax("missing '$'");
# Line 689 | Line 703 | getchan(void)                  /* A -> $N = E1 */
703   */
704  
705  
706 < static double
707 < dvalue(                 /* evaluate a variable */
694 < char  *name,
695 < EPNODE  *d
696 < )
706 > static double                   /* evaluate a variable */
707 > dvalue(char *name, EPNODE *d)
708   {
709 <    register EPNODE  *ep1, *ep2;
709 >    EPNODE  *ep1, *ep2;
710      
711      if (d == NULL || d->v.kid->type != SYM) {
712          eputs(name);
# Line 705 | Line 716 | EPNODE *d
716      ep1 = d->v.kid->sibling;                    /* get expression */
717      if (ep1->type == NUM)
718          return(ep1->v.num);                     /* return if number */
719 +    if (esupport&E_RCONST && d->type == ':') {
720 +        wputs(name);
721 +        wputs(": assigned non-constant value\n");
722 +    }
723      ep2 = ep1->sibling;                         /* check time */
724      if (eclock >= MAXCLOCK)
725          eclock = 1;                             /* wrap clock counter */
726      if (ep2->v.tick < MAXCLOCK &&
727 <                ep2->v.tick == 0 | ep2->v.tick != eclock) {
727 >                (ep2->v.tick == 0) | (ep2->v.tick != eclock)) {
728          ep2->v.tick = d->type == ':' ? MAXCLOCK : eclock;
729          ep2 = ep2->sibling;
730          ep2->v.num = evalue(ep1);               /* needs new value */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines