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.3 by greg, Mon Aug 10 16:20:43 1992 UTC vs.
Revision 2.11 by greg, Wed Feb 12 17:38:03 1997 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1991 Regents of the University of California */
1 > /* Copyright (c) 1997 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 30 | Line 30 | static char SCCSid[] = "$SunId$ LBL";
30  
31   #include  "calcomp.h"
32  
33 < #ifndef  NHASH
34 < #define  NHASH          521             /* hash size (a prime!) */
33 > #ifndef  NHASH
34 > #define  NHASH          521             /* hash size (a prime!) */
35   #endif
36  
37 < #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
37 > #define  hash(s)        (shash(s)%NHASH)
38  
39 < extern char  *ecalloc(), *savestr(), *strcpy();
39 > #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
40  
41 < static int  hash();
41 > extern char  *ecalloc(), *emalloc(), *savestr(), *strcpy();
42  
43   static double  dvalue();
44  
45 < long  eclock = -1;                      /* value storage timer */
45 > unsigned long  eclock = 0;              /* value storage timer */
46  
47 < static char  context[MAXWORD+1];        /* current context path */
47 > #define  MAXCNTX        1023            /* maximum context length */
48  
49 + static char  context[MAXCNTX+1];        /* current context path */
50 +
51   static VARDEF  *hashtbl[NHASH];         /* definition list */
52   static int  htndx;                      /* index for */        
53   static VARDEF  *htpos;                  /* ...dfirst() and */
54 < #ifdef  OUTCHAN
54 > #ifdef  OUTCHAN
55   static EPNODE  *ochpos;                 /* ...dnext */
56   static EPNODE  *outchan;
57   #endif
58  
59 < #ifdef  FUNCTION
60 < EPNODE  *curfunc;
61 < #define  dname(ep)      ((ep)->v.kid->type == SYM ? \
59 > #ifdef  FUNCTION
60 > EPNODE  *curfunc = NULL;
61 > #define  dname(ep)      ((ep)->v.kid->type == SYM ? \
62                          (ep)->v.kid->v.name : \
63                          (ep)->v.kid->v.kid->v.name)
64   #else
65 < #define  dname(ep)      ((ep)->v.kid->v.name)
65 > #define  dname(ep)      ((ep)->v.kid->v.name)
66   #endif
67  
68  
# Line 105 | Line 107 | char  *vname;
107  
108   double
109   evariable(ep)                   /* evaluate a variable */
110 < EPNODE  *ep;
110 > EPNODE  *ep;
111   {
112      register VARDEF  *dp = ep->v.ln;
113  
# Line 116 | Line 118 | EPNODE  *ep;
118   varset(vname, assign, val)      /* set a variable's value */
119   char  *vname;
120   int  assign;
121 < double  val;
121 > double  val;
122   {
123      char  *qname;
124      register EPNODE  *ep1, *ep2;
# Line 189 | Line 191 | register char  *ctx;
191  
192      if (ctx == NULL)
193          return(context);                /* just asking */
194 +    while (*ctx == CNTXMARK)
195 +        ctx++;                          /* skip past marks */
196      if (!*ctx) {
197 <        context[0] = '\0';              /* clear context */
197 >        context[0] = '\0';              /* empty means clear context */
198          return(context);
199      }
200 <    cpp = context;                      /* else copy it (carefully!) */
201 <    if (*ctx != CNTXMARK)
202 <        *cpp++ = CNTXMARK;              /* make sure there's a mark */
203 <    do {
200 <        if (cpp >= context+MAXWORD)
200 >    cpp = context;                      /* start context with mark */
201 >    *cpp++ = CNTXMARK;
202 >    do {                                /* carefully copy new context */
203 >        if (cpp >= context+MAXCNTX)
204              break;                      /* just copy what we can */
205          if (isid(*ctx))
206              *cpp++ = *ctx++;
# Line 205 | Line 208 | register char  *ctx;
208              *cpp++ = '_'; ctx++;
209          }
210      } while (*ctx);
211 +    while (cpp[-1] == CNTXMARK)         /* cannot end in context mark */
212 +        cpp--;
213      *cpp = '\0';
214      return(context);
215   }
216  
217  
218   char *
219 + pushcontext(ctx)                /* push on another context */
220 + char  *ctx;
221 + {
222 +    extern char  *strncpy(), *strcpy();
223 +    char  oldcontext[MAXCNTX+1];
224 +    register int  n;
225 +
226 +    strcpy(oldcontext, context);        /* save old context */
227 +    setcontext(ctx);                    /* set new context */
228 +    n = strlen(context);                /* tack on old */
229 +    if (n+strlen(oldcontext) > MAXCNTX) {
230 +        strncpy(context+n, oldcontext, MAXCNTX-n);
231 +        context[MAXCNTX] = '\0';
232 +    } else
233 +        strcpy(context+n, oldcontext);
234 +    return(context);
235 + }
236 +
237 +
238 + char *
239 + popcontext()                    /* pop off top context */
240 + {
241 +    register char  *cp1, *cp2;
242 +
243 +    if (!context[0])                    /* nothing left to pop */
244 +        return(context);
245 +    cp2 = context;                      /* find mark */
246 +    while (*++cp2 && *cp2 != CNTXMARK)
247 +        ;
248 +    cp1 = context;                      /* copy tail to front */
249 +    while (*cp1++ = *cp2++)
250 +        ;
251 +    return(context);
252 + }
253 +
254 +
255 + char *
256   qualname(nam, lvl)              /* get qualified name */
257   register char  *nam;
258   int  lvl;
259   {
260 <    static char  nambuf[MAXWORD+1];
260 >    static char  nambuf[MAXWORD+1];
261      register char  *cp = nambuf, *cpp;
262                                  /* check for explicit local */
263      if (*nam == CNTXMARK)
# Line 259 | Line 301 | toolong:
301   incontext(qn)                   /* is qualified name in current context? */
302   register char  *qn;
303   {
304 +    if (!context[0])                    /* global context accepts all */
305 +        return(1);
306      while (*qn && *qn != CNTXMARK)      /* find context mark */
307          qn++;
308      return(!strcmp(qn, context));
309   }
310  
311  
312 < #ifdef  OUTCHAN
312 > #ifdef  OUTCHAN
313   chanout(cs)                     /* set output channels */
314   int  (*cs)();
315   {
# Line 287 | Line 331 | int  lvl;
331                                  /* if context is global, clear all */
332      for (i = 0; i < NHASH; i++)
333          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
334 <            if (!context[0] || incontext(vp->name))
334 >            if (incontext(vp->name))
335                  if (lvl >= 2)
336                      dremove(vp->name);
337                  else
338                      dclear(vp->name);
339 < #ifdef  OUTCHAN
339 > #ifdef  OUTCHAN
340      if (lvl >= 1) {
341          for (ep = outchan; ep != NULL; ep = ep->sibling)
342              epfree(ep);
# Line 309 | Line 353 | char  *name;
353      register VARDEF  *vp;
354      
355      if ((vp = varlookup(name)) == NULL)
356 <        return(NULL);
356 >        return(NULL);
357      return(vp->def);
358   }
359  
# Line 318 | Line 362 | VARDEF *
362   varlookup(name)                 /* look up a variable */
363   char  *name;
364   {
365 <    int  lvl = 0;
365 >    int  lvl = 0;
366      register char  *qname;
367      register VARDEF  *vp;
368 <                                /* find most qualified match */
368 >                                /* find most qualified match */
369      while ((qname = qualname(name, lvl++)) != NULL)
370          for (vp = hashtbl[hash(qname)]; vp != NULL; vp = vp->next)
371              if (!strcmp(vp->name, qname))
# Line 335 | Line 379 | varinsert(name)                        /* get a link to a variable */
379   char  *name;
380   {
381      register VARDEF  *vp;
382 <    int  hv;
382 >    int  hv;
383      
384      if ((vp = varlookup(name)) != NULL) {
385          vp->nlinks++;
386          return(vp);
387      }
388      vp = (VARDEF *)emalloc(sizeof(VARDEF));
389 < #ifdef  FUNCTION
389 > #ifdef  FUNCTION
390      vp->lib = liblookup(name);
391   #else
392      vp->lib = NULL;
# Line 359 | Line 403 | char  *name;
403   }
404  
405  
406 < #ifdef  FUNCTION
406 > #ifdef  FUNCTION
407   libupdate(fn)                   /* update library links */
408   char  *fn;
409   {
# Line 375 | Line 419 | char  *fn;
419  
420  
421   varfree(ln)                             /* release link to variable */
422 < register VARDEF  *ln;
422 > register VARDEF  *ln;
423   {
424      register VARDEF  *vp;
425 <    int  hv;
425 >    int  hv;
426  
427      if (--ln->nlinks > 0)
428 <        return;                         /* still active */
428 >        return;                         /* still active */
429  
430      hv = hash(ln->name);
431      vp = hashtbl[hv];
432      if (vp == ln)
433 <        hashtbl[hv] = vp->next;
433 >        hashtbl[hv] = vp->next;
434      else {
435 <        while (vp->next != ln)          /* must be in list */
436 <                vp = vp->next;
437 <        vp->next = ln->next;
435 >        while (vp->next != ln)          /* must be in list */
436 >                vp = vp->next;
437 >        vp->next = ln->next;
438      }
439      freestr(ln->name);
440      efree((char *)ln);
# Line 402 | Line 446 | dfirst()                       /* return pointer to first definition */
446   {
447      htndx = 0;
448      htpos = NULL;
449 < #ifdef  OUTCHAN
449 > #ifdef  OUTCHAN
450      ochpos = outchan;
451   #endif
452      return(dnext());
# Line 416 | Line 460 | dnext()                                /* return pointer to next definition */
460      register char  *nm;
461  
462      while (htndx < NHASH) {
463 <        if (htpos == NULL)
464 <                htpos = hashtbl[htndx++];
465 <        while (htpos != NULL) {
466 <            ep = htpos->def;
463 >        if (htpos == NULL)
464 >                htpos = hashtbl[htndx++];
465 >        while (htpos != NULL) {
466 >            ep = htpos->def;
467              nm = htpos->name;
468 <            htpos = htpos->next;
469 <            if (ep != NULL && incontext(nm))
470 <                return(ep);
471 <        }
468 >            htpos = htpos->next;
469 >            if (ep != NULL && incontext(nm))
470 >                return(ep);
471 >        }
472      }
473 < #ifdef  OUTCHAN
473 > #ifdef  OUTCHAN
474      if ((ep = ochpos) != NULL)
475 <        ochpos = ep->sibling;
475 >        ochpos = ep->sibling;
476      return(ep);
477   #else
478      return(NULL);
# Line 444 | Line 488 | char  *name;
488      register EPNODE  *dp;
489      
490      if ((vp = varlookup(name)) == NULL || vp->def == NULL)
491 <        return(NULL);
491 >        return(NULL);
492      dp = vp->def;
493      vp->def = dp->sibling;
494      varfree(vp);
# Line 454 | Line 498 | char  *name;
498  
499   dpush(nm, ep)                   /* push on a definition */
500   char  *nm;
501 < register EPNODE  *ep;
501 > register EPNODE  *ep;
502   {
503      register VARDEF  *vp;
504  
# Line 464 | Line 508 | register EPNODE  *ep;
508   }
509  
510  
511 < #ifdef  OUTCHAN
511 > #ifdef  OUTCHAN
512   addchan(sp)                     /* add an output channel assignment */
513 < EPNODE  *sp;
513 > EPNODE  *sp;
514   {
515 <    int  ch = sp->v.kid->v.chan;
515 >    int  ch = sp->v.kid->v.chan;
516      register EPNODE  *ep, *epl;
517  
518      for (epl = NULL, ep = outchan; ep != NULL; epl = ep, ep = ep->sibling)
# Line 505 | Line 549 | getstatement()                 /* get next statement */
549          scan();
550          return;
551      }
552 < #ifdef  OUTCHAN
552 > #ifdef  OUTCHAN
553      if (nextc == '$') {         /* channel assignment */
554          ep = getchan();
555          addchan(ep);
# Line 514 | Line 558 | getstatement()                 /* get next statement */
558      {                           /* ordinary definition */
559          ep = getdefn();
560          qname = qualname(dname(ep), 0);
561 < #ifdef  REDEFW
561 > #ifdef  REDEFW
562          if ((vdef = varlookup(qname)) != NULL)
563 <            if (vdef->def != NULL) {
563 >            if (vdef->def != NULL && epcmp(ep, vdef->def)) {
564                  wputs(qname);
565                  if (vdef->def->type == ':')
566                      wputs(": redefined constant expression\n");
567                  else
568                      wputs(": redefined\n");
569              }
570 < #ifdef  FUNCTION
570 > #ifdef  FUNCTION
571              else if (ep->v.kid->type == FUNC && vdef->lib != NULL) {
572                  wputs(qname);
573                  wputs(": definition hides library function\n");
# Line 547 | Line 591 | getstatement()                 /* get next statement */
591   EPNODE *
592   getdefn()                       /* A -> SYM = E1 */
593                                  /*      SYM : E1 */
594 <                                /*      FUNC(SYM,..) = E1 */
594 >                                /*      FUNC(SYM,..) = E1 */
595                                  /*      FUNC(SYM,..) : E1 */
596   {
597      register EPNODE  *ep1, *ep2;
# Line 559 | Line 603 | getdefn()                      /* A -> SYM = E1 */
603      ep1->type = SYM;
604      ep1->v.name = savestr(getname());
605  
606 < #ifdef  FUNCTION
606 > #ifdef  FUNCTION
607      if (nextc == '(') {
608          ep2 = newnode();
609          ep2->type = FUNC;
# Line 578 | Line 622 | getdefn()                      /* A -> SYM = E1 */
622              syntax("')' expected");
623          scan();
624          curfunc = ep1;
625 <    } else
582 <        curfunc = NULL;
625 >    }
626   #endif
627  
628      if (nextc != '=' && nextc != ':')
# Line 592 | Line 635 | getdefn()                      /* A -> SYM = E1 */
635      addekid(ep2, getE1());
636  
637      if (
638 < #ifdef  FUNCTION
639 <            ep1->type == SYM &&
638 > #ifdef  FUNCTION
639 >            ep1->type == SYM &&
640   #endif
641              ep1->sibling->type != NUM) {
642          ep1 = newnode();
643          ep1->type = TICK;
644 <        ep1->v.tick = -1;
644 >        ep1->v.tick = 0;
645          addekid(ep2, ep1);
646          ep1 = newnode();
647          ep1->type = NUM;
648          addekid(ep2, ep1);
649      }
650  
651 + #ifdef  FUNCTION
652 +    curfunc = NULL;
653 + #endif
654 +
655      return(ep2);
656   }
657  
658  
659 < #ifdef  OUTCHAN
659 > #ifdef  OUTCHAN
660   EPNODE *
661   getchan()                       /* A -> $N = E1 */
662   {
# Line 646 | Line 693 | getchan()                      /* A -> $N = E1 */
693   static double
694   dvalue(name, d)                 /* evaluate a variable */
695   char  *name;
696 < EPNODE  *d;
696 > EPNODE  *d;
697   {
698      register EPNODE  *ep1, *ep2;
699      
# Line 659 | Line 706 | EPNODE  *d;
706      if (ep1->type == NUM)
707          return(ep1->v.num);                     /* return if number */
708      ep2 = ep1->sibling;                         /* check time */
709 <    if (ep2->v.tick < 0 || ep2->v.tick < eclock) {
710 <        ep2->v.tick = d->type == ':' ? 1L<<30 : eclock;
709 >    if (ep2->v.tick == 0 || ep2->v.tick < eclock) {
710 >        ep2->v.tick = d->type == ':' ? ~0L : eclock;
711          ep2 = ep2->sibling;
712          ep2->v.num = evalue(ep1);               /* needs new value */
713      } else
714          ep2 = ep2->sibling;                     /* else reuse old value */
715  
716      return(ep2->v.num);
670 }
671
672
673 static int
674 hash(s)                         /* hash a string */
675 register char  *s;
676 {
677    register int  rval = 0;
678
679    while (*s)
680        rval += *s++;
681    
682    return(rval % NHASH);
717   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines