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.22 by schorsch, Sun Mar 28 20:33:12 2004 UTC vs.
Revision 2.38 by greg, Fri Feb 23 03:47:57 2024 UTC

# Line 27 | Line 27 | static const char      RCSid[] = "$Id$";
27  
28   #include "copyright.h"
29  
30 #include  <stdio.h>
31 #include  <string.h>
30   #include  <ctype.h>
31  
32   #include  "rterror.h"
# Line 60 | Line 58 | static VARDEF  *htpos;                 /* ...dfirst() and */
58   static EPNODE  *ochpos;                 /* ...dnext */
59   static EPNODE  *outchan;
60  
61 + static int  optimized = 0;              /* are we optimized? */
62 +
63   EPNODE  *curfunc = NULL;
64 #define  dname(ep)      ((ep)->v.kid->type == SYM ? \
65                        (ep)->v.kid->v.name : \
66                        (ep)->v.kid->v.kid->v.name)
64  
65  
66   void
# Line 80 | Line 77 | fcompile(                      /* get definitions from a file */
77          eputs(": cannot open\n");
78          quit(1);
79      }
80 <    initfile(fp, fname, 0);
80 > #ifdef getc_unlocked                    /* avoid stupid semaphores */
81 >    flockfile(fp);
82 > #endif
83 >   initfile(fp, fname, 0);
84      while (nextc != EOF)
85          getstatement();
86      if (fname != NULL)
87          fclose(fp);
88 + #ifdef getc_unlocked
89 +    else
90 +        funlockfile(fp);
91 + #endif
92   }
93  
94  
# Line 115 | Line 119 | evariable(                     /* evaluate a variable */
119          EPNODE  *ep
120   )
121   {
122 <    register VARDEF  *dp = ep->v.ln;
122 >    VARDEF  *dp = ep->v.ln;
123  
124      return(dvalue(dp->name, dp->def));
125   }
# Line 129 | Line 133 | varset(                /* set a variable's value */
133   )
134   {
135      char  *qname;
136 <    register EPNODE  *ep1, *ep2;
136 >    EPNODE  *ep1, *ep2;
137                                          /* get qualified name */
138      qname = qualname(vname, 0);
139                                          /* check for quick set */
140 <    if ((ep1 = dlookup(qname)) != NULL && ep1->v.kid->type == SYM) {
140 >    if ((ep1 = dlookup(qname)) != NULL && ep1->v.kid->type == SYM &&
141 >                (ep1->type == ':') <= (assign == ':')) {
142          ep2 = ep1->v.kid->sibling;
143          if (ep2->type == NUM) {
144              ep2->v.num = val;
# Line 141 | Line 146 | varset(                /* set a variable's value */
146              return;
147          }
148      }
149 +    if (ep1 != NULL && esupport&E_REDEFW) {
150 +        wputs(qname);
151 +        if (ep1->type == ':')
152 +            wputs(": reset constant expression\n");
153 +        else
154 +            wputs(": reset expression\n");
155 +    }
156                                          /* hand build definition */
157      ep1 = newnode();
158      ep1->type = assign;
# Line 152 | Line 164 | varset(                /* set a variable's value */
164      ep2->type = NUM;
165      ep2->v.num = val;
166      addekid(ep1, ep2);
167 <    dremove(qname);
167 >    if (assign == ':')
168 >        dremove(qname);
169 >    else
170 >        dclear(qname);
171      dpush(qname, ep1);
172   }
173  
# Line 162 | Line 177 | dclear(                        /* delete variable definitions of name */
177          char  *name
178   )
179   {
180 <    register EPNODE  *ep;
180 >    VARDEF  *vp;
181 >    EPNODE  *dp;
182  
183 <    while ((ep = dpop(name)) != NULL) {
184 <        if (ep->type == ':') {
185 <            dpush(name, ep);            /* don't clear constants */
186 <            return;
187 <        }
172 <        epfree(ep);
183 >    while ((vp = varlookup(name)) != NULL &&
184 >                (dp = vp->def) != NULL && dp->type == '=') {
185 >        vp->def = dp->sibling;
186 >        epfree(dp,1);
187 >        varfree(vp);
188      }
189   }
190  
# Line 179 | Line 194 | dremove(                       /* delete all definitions of name */
194          char  *name
195   )
196   {
197 <    register EPNODE  *ep;
197 >    EPNODE  *ep;
198  
199      while ((ep = dpop(name)) != NULL)
200 <        epfree(ep);
200 >        epfree(ep,1);
201   }
202  
203  
204   int
205 < vardefined(     /* return non-zero if variable defined */
205 > vardefined(     /* return '=' or ':' if variable/constant defined */
206          char  *name
207   )
208   {
209 <    register EPNODE  *dp;
209 >    EPNODE  *dp = dlookup(name);
210  
211 <    return((dp = dlookup(name)) != NULL && dp->v.kid->type == SYM);
211 >    if (dp == NULL || dp->v.kid->type != SYM)
212 >        return(0);
213 >
214 >    return(dp->type);
215   }
216  
217  
218   char *
219 < setcontext(                     /* set a new context path */
220 <        register char  *ctx
219 > calcontext(                     /* set a new context path */
220 >        char  *ctx
221   )
222   {
223 <    register char  *cpp;
223 >    char  *cpp;
224  
225      if (ctx == NULL)
226          return(context);                /* just asking */
# Line 236 | Line 254 | pushcontext(           /* push on another context */
254   )
255   {
256      char  oldcontext[MAXCNTX+1];
257 <    register int  n;
257 >    int  n;
258  
259      strcpy(oldcontext, context);        /* save old context */
260 <    setcontext(ctx);                    /* set new context */
260 >    calcontext(ctx);                    /* set new context */
261      n = strlen(context);                /* tack on old */
262      if (n+strlen(oldcontext) > MAXCNTX) {
263          strncpy(context+n, oldcontext, MAXCNTX-n);
# Line 253 | Line 271 | pushcontext(           /* push on another context */
271   char *
272   popcontext(void)                        /* pop off top context */
273   {
274 <    register char  *cp1, *cp2;
274 >    char  *cp1, *cp2;
275  
276      if (!context[0])                    /* nothing left to pop */
277          return(context);
# Line 269 | Line 287 | popcontext(void)                       /* pop off top context */
287  
288   char *
289   qualname(               /* get qualified name */
290 <        register char  *nam,
290 >        char  *nam,
291          int  lvl
292   )
293   {
294      static char  nambuf[RMAXWORD+1];
295 <    register char  *cp = nambuf, *cpp;
295 >    char  *cp = nambuf, *cpp;
296                                  /* check for explicit local */
297 <    if (*nam == CNTXMARK)
297 >    if (*nam == CNTXMARK) {
298          if (lvl > 0)            /* only action is to refuse search */
299              return(NULL);
300 <        else
301 <            nam++;
284 <    else if (nam == nambuf)     /* check for repeat call */
300 >        nam++;
301 >    } else if (nam == nambuf)   /* check for repeat call */
302          return(lvl > 0 ? NULL : nam);
303                                  /* copy name to static buffer */
304      while (*nam) {
# Line 303 | Line 320 | qualname(              /* get qualified name */
320          while (*++cpp && *cpp != CNTXMARK)
321              ;
322      }
323 <    while (*cpp) {              /* copy context to static buffer */
323 >    while (*cpp) {              /* add remaining context to name */
324          if (cp >= nambuf+RMAXWORD)
325              goto toolong;
326          *cp++ = *cpp++;
# Line 316 | Line 333 | toolong:
333  
334   int
335   incontext(                      /* is qualified name in current context? */
336 <        register char  *qn
336 >        char  *qn
337   )
338   {
339      if (!context[0])                    /* global context accepts all */
# Line 332 | Line 349 | chanout(                       /* set output channels */
349          void  (*cs)(int n, double v)
350   )
351   {
352 <    register EPNODE  *ep;
352 >    EPNODE  *ep;
353  
354      for (ep = outchan; ep != NULL; ep = ep->sibling)
355          (*cs)(ep->v.kid->v.chan, evalue(ep->v.kid->sibling));
# Line 341 | Line 358 | chanout(                       /* set output channels */
358  
359  
360   void
361 + doptimize(int activate)         /* optimize current and future definitions? */
362 + {
363 +    EPNODE      *ep;
364 +
365 +    if (activate && optimized)
366 +        return;                 /* already going */
367 +
368 +    if (!(optimized = activate))
369 +        return;                 /* switching off */
370 +
371 +    for (ep = dfirst(); ep != NULL; ep = dnext())
372 +        epoptimize(ep);
373 + }
374 +
375 +
376 + void
377   dcleanup(               /* clear definitions (0->vars,1->output,2->consts) */
378          int  lvl
379   )
380   {
381 <    register int  i;
382 <    register VARDEF  *vp;
383 <    register EPNODE  *ep;
381 >    int  i;
382 >    VARDEF  *vp;
383 >    EPNODE  *ep;
384                                  /* if context is global, clear all */
385      for (i = 0; i < NHASH; i++)
386          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
# Line 357 | Line 390 | dcleanup(              /* clear definitions (0->vars,1->output,2->
390                  else
391                      dclear(vp->name);
392              }
393 <    if (lvl >= 1) {
394 <        for (ep = outchan; ep != NULL; ep = ep->sibling)
395 <            epfree(ep);
396 <        outchan = NULL;
397 <    }
393 >    if (lvl >= 1)
394 >        while (outchan != NULL) {
395 >            ep = outchan;
396 >            outchan = ep->sibling;
397 >            epfree(ep,1);
398 >        }
399   }
400  
401  
# Line 370 | Line 404 | dlookup(                       /* look up a definition */
404          char  *name
405   )
406   {
407 <    register VARDEF  *vp;
407 >    VARDEF  *vp;
408      
409      if ((vp = varlookup(name)) == NULL)
410          return(NULL);
# Line 384 | Line 418 | varlookup(                     /* look up a variable */
418   )
419   {
420      int  lvl = 0;
421 <    register char  *qname;
422 <    register VARDEF  *vp;
421 >    char  *qname;
422 >    VARDEF  *vp;
423                                  /* find most qualified match */
424      while ((qname = qualname(name, lvl++)) != NULL)
425          for (vp = hashtbl[hash(qname)]; vp != NULL; vp = vp->next)
# Line 400 | Line 434 | varinsert(                     /* get a link to a variable */
434          char  *name
435   )
436   {
437 <    register VARDEF  *vp;
437 >    VARDEF  *vp;
438      int  hv;
439      
440      if ((vp = varlookup(name)) != NULL) {
# Line 426 | Line 460 | libupdate(                     /* update library links */
460          char  *fn
461   )
462   {
463 <    register int  i;
464 <    register VARDEF  *vp;
463 >    int  i;
464 >    VARDEF  *vp;
465                                          /* if fn is NULL then relink all */
466      for (i = 0; i < NHASH; i++)
467          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
468 <            if (vp->lib != NULL || fn == NULL || !strcmp(fn, vp->name))
468 >            if ((vp->lib != NULL) | (fn == NULL) || !strcmp(fn, vp->name))
469                  vp->lib = liblookup(vp->name);
470   }
471  
472  
473   void
474   varfree(                                /* release link to variable */
475 <        register VARDEF  *ln
475 >        VARDEF   *ln
476   )
477   {
478 <    register VARDEF  *vp;
478 >    VARDEF  *vp;
479      int  hv;
480  
481      if (--ln->nlinks > 0)
# Line 457 | Line 491 | varfree(                               /* release link to variable */
491          vp->next = ln->next;
492      }
493      freestr(ln->name);
494 <    efree((char *)ln);
494 >    efree(ln);
495   }
496  
497  
# Line 474 | Line 508 | dfirst(void)                   /* return pointer to first definition *
508   EPNODE *
509   dnext(void)                             /* return pointer to next definition */
510   {
511 <    register EPNODE  *ep;
512 <    register char  *nm;
511 >    EPNODE  *ep;
512 >    char  *nm;
513  
514      while (htndx < NHASH) {
515          if (htpos == NULL)
# Line 499 | Line 533 | dpop(                  /* pop a definition */
533          char  *name
534   )
535   {
536 <    register VARDEF  *vp;
537 <    register EPNODE  *dp;
536 >    VARDEF  *vp;
537 >    EPNODE  *dp;
538      
539      if ((vp = varlookup(name)) == NULL || vp->def == NULL)
540          return(NULL);
# Line 514 | Line 548 | dpop(                  /* pop a definition */
548   void
549   dpush(                  /* push on a definition */
550          char  *nm,
551 <        register EPNODE  *ep
551 >        EPNODE   *ep
552   )
553   {
554 <    register VARDEF  *vp;
554 >    VARDEF  *vp;
555  
556      vp = varinsert(nm);
557      ep->sibling = vp->def;
# Line 531 | Line 565 | addchan(                       /* add an output channel assignment */
565   )
566   {
567      int  ch = sp->v.kid->v.chan;
568 <    register EPNODE  *ep, *epl;
568 >    EPNODE  *ep, *epl;
569  
570      for (epl = NULL, ep = outchan; ep != NULL; epl = ep, ep = ep->sibling)
571          if (ep->v.kid->v.chan >= ch) {
# Line 543 | Line 577 | addchan(                       /* add an output channel assignment */
577                  sp->sibling = ep;
578              else {
579                  sp->sibling = ep->sibling;
580 <                epfree(ep);
580 >                epfree(ep,1);
581              }
582              return;
583          }
# Line 559 | Line 593 | addchan(                       /* add an output channel assignment */
593   void
594   getstatement(void)                      /* get next statement */
595   {
596 <    register EPNODE  *ep;
596 >    EPNODE  *ep;
597      char  *qname;
598 <    register VARDEF  *vdef;
598 >    VARDEF  *vdef;
599  
600      if (nextc == ';') {         /* empty statement */
601          scan();
# Line 573 | Line 607 | getstatement(void)                     /* get next statement */
607          addchan(ep);
608      } else {                            /* ordinary definition */
609          ep = getdefn();
610 <        qname = qualname(dname(ep), 0);
610 >        qname = qualname(dfn_name(ep), 0);
611          if (esupport&E_REDEFW && (vdef = varlookup(qname)) != NULL) {
612              if (vdef->def != NULL && epcmp(ep, vdef->def)) {
613                  wputs(qname);
# Line 597 | Line 631 | getstatement(void)                     /* get next statement */
631              syntax("';' expected");
632          scan();
633      }
634 +    if (optimized)
635 +        epoptimize(ep);                 /* optimize new statement */
636   }
637  
638  
# Line 607 | Line 643 | getdefn(void)
643          /*      FUNC(SYM,..) = E1 */
644          /*      FUNC(SYM,..) : E1 */
645   {
646 <    register EPNODE  *ep1, *ep2;
646 >    EPNODE  *ep1, *ep2;
647  
648 <    if (!isalpha(nextc) && nextc != CNTXMARK)
648 >    if (!isalpha(nextc) & (nextc != CNTXMARK))
649          syntax("illegal variable name");
650  
651      ep1 = newnode();
# Line 624 | Line 660 | getdefn(void)
660          do {
661              scan();
662              if (!isalpha(nextc))
663 <                syntax("illegal variable name");
663 >                syntax("illegal parameter name");
664              ep2 = newnode();
665              ep2->type = SYM;
666              ep2->v.name = savestr(getname());
667 +            if (strchr(ep2->v.name, CNTXMARK) != NULL)
668 +                syntax("illegal parameter name");
669              addekid(ep1, ep2);
670          } while (nextc == ',');
671          if (nextc != ')')
# Line 636 | Line 674 | getdefn(void)
674          curfunc = ep1;
675      }
676  
677 <    if (nextc != '=' && nextc != ':')
677 >    if ((nextc != '=') & (nextc != ':'))
678          syntax("'=' or ':' expected");
679  
680      ep2 = newnode();
# Line 647 | Line 685 | getdefn(void)
685  
686      if (ep1->type == SYM && ep1->sibling->type != NUM) {
687          ep1 = newnode();
688 <        ep1->type = TICK;
688 >        ep1->type = CLKT;
689          ep1->v.tick = 0;
690          addekid(ep2, ep1);
691          ep1 = newnode();
# Line 663 | Line 701 | getdefn(void)
701   EPNODE *
702   getchan(void)                   /* A -> $N = E1 */
703   {
704 <    register EPNODE  *ep1, *ep2;
704 >    EPNODE  *ep1, *ep2;
705  
706      if (nextc != '$')
707          syntax("missing '$'");
# Line 693 | Line 731 | getchan(void)                  /* A -> $N = E1 */
731  
732  
733   static double                   /* evaluate a variable */
734 < dvalue(char  *name, EPNODE      *d)
734 > dvalue(char *name, EPNODE *d)
735   {
736 <    register EPNODE  *ep1, *ep2;
736 >    EPNODE  *ep1, *ep2;
737      
738      if (d == NULL || d->v.kid->type != SYM) {
739          eputs(name);
# Line 705 | Line 743 | dvalue(char  *name, EPNODE     *d)
743      ep1 = d->v.kid->sibling;                    /* get expression */
744      if (ep1->type == NUM)
745          return(ep1->v.num);                     /* return if number */
746 +    if (esupport&E_RCONST && d->type == ':') {
747 +        wputs(name);
748 +        wputs(": assigned non-constant value\n");
749 +    }
750      ep2 = ep1->sibling;                         /* check time */
751      if (eclock >= MAXCLOCK)
752          eclock = 1;                             /* wrap clock counter */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines