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.26 by greg, Thu Jul 24 15:41:13 2014 UTC vs.
Revision 2.41 by greg, Wed Jan 1 19:02:08 2025 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 < 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)
61 > static int  optimized = 0;              /* are we optimized? */
62  
63 + EPNODE  *ecurfunc = NULL;
64  
65 +
66   void
67   fcompile(                       /* get definitions from a file */
68          char  *fname
# 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();
85 >        egetstatement();
86      if (fname != NULL)
87          fclose(fp);
88 + #ifdef getc_unlocked
89 +    else
90 +        funlockfile(fp);
91 + #endif
92   }
93  
94  
# Line 97 | Line 101 | scompile(              /* get definitions from a string */
101   {
102      initstr(str, fn, ln);
103      while (nextc != EOF)
104 <        getstatement();
104 >        egetstatement();
105   }
106  
107  
# Line 173 | Line 177 | dclear(                        /* delete variable definitions of name */
177          char  *name
178   )
179   {
180 <    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 <        }
183 <        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 193 | Line 197 | dremove(                       /* delete all definitions of name */
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 <    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 */
219 > calcontext(                     /* set a new context path */
220          char  *ctx
221   )
222   {
# Line 250 | Line 257 | pushcontext(           /* push on another context */
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 284 | Line 291 | qualname(              /* get qualified name */
291          int  lvl
292   )
293   {
294 <    static char  nambuf[RMAXWORD+1];
294 >    static char  nambuf[MAXCNTX+RMAXWORD+1];
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++;
295 <    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) {
305 <        if (cp >= nambuf+RMAXWORD)
305 >        if (cp >= nambuf+(MAXCNTX+RMAXWORD))
306                  goto toolong;
307          *cp++ = *nam++;
308      }
# Line 314 | Line 320 | qualname(              /* get qualified name */
320          while (*++cpp && *cpp != CNTXMARK)
321              ;
322      }
323 <    while (*cpp) {              /* copy context to static buffer */
324 <        if (cp >= nambuf+RMAXWORD)
323 >    while (*cpp) {              /* add remaining context to name */
324 >        if (cp >= nambuf+(MAXCNTX+RMAXWORD))
325              goto toolong;
326          *cp++ = *cpp++;
327      }
# Line 352 | 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   )
# Line 368 | 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 419 | Line 442 | varinsert(                     /* get a link to a variable */
442          return(vp);
443      }
444      vp = (VARDEF *)emalloc(sizeof(VARDEF));
445 <    vp->lib = liblookup(name);
445 >    vp->lib = eliblookup(name);
446      if (vp->lib == NULL)                /* if name not in library */
447          name = qualname(name, 0);       /* use fully qualified version */
448      hv = hash(name);
# Line 433 | Line 456 | varinsert(                     /* get a link to a variable */
456  
457  
458   void
459 < libupdate(                      /* update library links */
459 > elibupdate(                     /* update library links */
460          char  *fn
461   )
462   {
# Line 442 | Line 465 | libupdate(                     /* update library links */
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))
469 <                vp->lib = liblookup(vp->name);
468 >            if ((vp->lib != NULL) | (fn == NULL) || !strcmp(fn, vp->name))
469 >                vp->lib = eliblookup(vp->name);
470   }
471  
472  
# Line 468 | 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 537 | Line 560 | dpush(                 /* push on a definition */
560  
561  
562   void
563 < addchan(                        /* add an output channel assignment */
563 > eaddchan(                       /* add an output channel assignment */
564          EPNODE  *sp
565   )
566   {
# Line 554 | 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 568 | Line 591 | addchan(                       /* add an output channel assignment */
591  
592  
593   void
594 < getstatement(void)                      /* get next statement */
594 > egetstatement(void)                     /* get next statement */
595   {
596      EPNODE  *ep;
597      char  *qname;
598      VARDEF  *vdef;
599  
600      if (nextc == ';') {         /* empty statement */
601 <        scan();
601 >        escan();
602          return;
603      }
604      if (esupport&E_OUTCHAN &&
605                  nextc == '$') {         /* channel assignment */
606 <        ep = getchan();
607 <        addchan(ep);
606 >        ep = egetchan();
607 >        if (optimized)
608 >            epoptimize(ep);             /* optimize new chan expr */
609 >        eaddchan(ep);
610      } else {                            /* ordinary definition */
611 <        ep = getdefn();
612 <        qname = qualname(dname(ep), 0);
611 >        ep = egetdefn();
612 >        if (optimized)
613 >            epoptimize(ep);             /* optimize new statement */
614 >        qname = qualname(dfn_name(ep), 0);
615          if (esupport&E_REDEFW && (vdef = varlookup(qname)) != NULL) {
616              if (vdef->def != NULL && epcmp(ep, vdef->def)) {
617                  wputs(qname);
# Line 605 | Line 632 | getstatement(void)                     /* get next statement */
632      }
633      if (nextc != EOF) {
634          if (nextc != ';')
635 <            syntax("';' expected");
636 <        scan();
635 >            esyntax("';' expected");
636 >        escan();
637      }
638   }
639  
640  
641   EPNODE *
642 < getdefn(void)
642 > egetdefn(void)
643          /* A -> SYM = E1 */
644          /*      SYM : E1 */
645          /*      FUNC(SYM,..) = E1 */
# Line 620 | Line 647 | getdefn(void)
647   {
648      EPNODE  *ep1, *ep2;
649  
650 <    if (!isalpha(nextc) && nextc != CNTXMARK)
651 <        syntax("illegal variable name");
650 >    if (!isalpha(nextc) & (nextc != CNTXMARK))
651 >        esyntax("illegal variable name");
652  
653      ep1 = newnode();
654      ep1->type = SYM;
# Line 633 | Line 660 | getdefn(void)
660          addekid(ep2, ep1);
661          ep1 = ep2;
662          do {
663 <            scan();
663 >            escan();
664              if (!isalpha(nextc))
665 <                syntax("illegal parameter name");
665 >                esyntax("illegal parameter name");
666              ep2 = newnode();
667              ep2->type = SYM;
668              ep2->v.name = savestr(getname());
669 +            if (strchr(ep2->v.name, CNTXMARK) != NULL)
670 +                esyntax("illegal parameter name");
671              addekid(ep1, ep2);
672          } while (nextc == ',');
673          if (nextc != ')')
674 <            syntax("')' expected");
675 <        scan();
676 <        curfunc = ep1;
674 >            esyntax("')' expected");
675 >        escan();
676 >        ecurfunc = ep1;
677      }
678  
679 <    if (nextc != '=' && nextc != ':')
680 <        syntax("'=' or ':' expected");
679 >    if ((nextc != '=') & (nextc != ':'))
680 >        esyntax("'=' or ':' expected");
681  
682      ep2 = newnode();
683      ep2->type = nextc;
684 <    scan();
684 >    escan();
685      addekid(ep2, ep1);
686      addekid(ep2, getE1());
687  
# Line 665 | Line 694 | getdefn(void)
694          ep1->type = NUM;
695          addekid(ep2, ep1);
696      }
697 <    curfunc = NULL;
697 >    ecurfunc = NULL;
698  
699      return(ep2);
700   }
701  
702  
703   EPNODE *
704 < getchan(void)                   /* A -> $N = E1 */
704 > egetchan(void)                  /* A -> $N = E1 */
705   {
706      EPNODE  *ep1, *ep2;
707  
708      if (nextc != '$')
709 <        syntax("missing '$'");
710 <    scan();
709 >        esyntax("missing '$'");
710 >    escan();
711  
712      ep1 = newnode();
713      ep1->type = CHAN;
714      ep1->v.chan = getinum();
715  
716      if (nextc != '=')
717 <        syntax("'=' expected");
718 <    scan();
717 >        esyntax("'=' expected");
718 >    escan();
719  
720      ep2 = newnode();
721      ep2->type = '=';
# Line 704 | Line 733 | getchan(void)                  /* A -> $N = E1 */
733  
734  
735   static double                   /* evaluate a variable */
736 < dvalue(char  *name, EPNODE      *d)
736 > dvalue(char *name, EPNODE *d)
737   {
738      EPNODE  *ep1, *ep2;
739      
# Line 716 | Line 745 | dvalue(char  *name, EPNODE     *d)
745      ep1 = d->v.kid->sibling;                    /* get expression */
746      if (ep1->type == NUM)
747          return(ep1->v.num);                     /* return if number */
748 +    if (esupport&E_RCONST && d->type == ':') {
749 +        wputs(name);
750 +        wputs(": assigned non-constant value\n");
751 +    }
752      ep2 = ep1->sibling;                         /* check time */
753      if (eclock >= MAXCLOCK)
754          eclock = 1;                             /* wrap clock counter */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines