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 1.7 by greg, Fri Jul 20 08:30:23 1990 UTC vs.
Revision 2.19 by schorsch, Mon Jul 21 22:30:17 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1986 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  Store variable definitions.
6   *
# Line 18 | Line 15 | static char SCCSid[] = "$SunId$ LBL";
15   *  11/16/88  Added VARDEF structure for hard linking.
16   *
17   *  5/31/90  Added conditional compile (REDEFW) for redefinition warning.
18 + *
19 + *  4/23/91  Added ':' assignment for constant expressions
20 + *
21 + *  8/7/91  Added optional context path to append to variable names
22 + *
23 + *  5/17/2001  Fixed clock counter wrapping behavior
24 + *
25 + *  2/19/03     Eliminated conditional compiles in favor of esupport extern.
26   */
27  
28 < #include  <stdio.h>
28 > #include "copyright.h"
29  
30 + #include  <stdio.h>
31 + #include  <string.h>
32   #include  <ctype.h>
33  
34 + #include  "rterror.h"
35   #include  "calcomp.h"
36  
37 < #ifndef  NHASH
38 < #define  NHASH          521             /* hash size (a prime!) */
37 > #ifndef  NHASH
38 > #define  NHASH          521             /* hash size (a prime!) */
39   #endif
40  
41 < #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
41 > #define  hash(s)        (shash(s)%NHASH)
42  
43 < extern char  *ecalloc(), *savestr();
43 > #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
44  
45 < static double  dvalue();
45 > static double  dvalue(char  *name, EPNODE *d);
46  
47 < long  eclock = -1;                      /* value storage timer */
47 > #define  MAXCLOCK       (1L<<31)        /* clock wrap value */
48  
49 + unsigned long  eclock = 0;              /* value storage timer */
50 +
51 + #define  MAXCNTX        1023            /* maximum context length */
52 +
53 + static char  context[MAXCNTX+1];        /* current context path */
54 +
55   static VARDEF  *hashtbl[NHASH];         /* definition list */
56   static int  htndx;                      /* index for */        
57   static VARDEF  *htpos;                  /* ...dfirst() and */
44 #ifdef  OUTCHAN
58   static EPNODE  *ochpos;                 /* ...dnext */
59   static EPNODE  *outchan;
47 #endif
60  
61 < #ifdef  FUNCTION
62 < EPNODE  *curfunc;
51 < #define  dname(ep)      ((ep)->v.kid->type == SYM ? \
61 > EPNODE  *curfunc = NULL;
62 > #define  dname(ep)      ((ep)->v.kid->type == SYM ? \
63                          (ep)->v.kid->v.name : \
64                          (ep)->v.kid->v.kid->v.name)
54 #else
55 #define  dname(ep)      ((ep)->v.kid->v.name)
56 #endif
65  
66  
67 < fcompile(fname)                 /* get definitions from a file */
68 < char  *fname;
67 > void
68 > fcompile(                       /* get definitions from a file */
69 >        char  *fname
70 > )
71   {
72      FILE  *fp;
73  
# Line 70 | Line 80 | char  *fname;
80      }
81      initfile(fp, fname, 0);
82      while (nextc != EOF)
83 <        loaddefn();
83 >        getstatement();
84      if (fname != NULL)
85          fclose(fp);
86   }
87  
88  
89 < scompile(str, fn, ln)           /* get definitions from a string */
90 < char  *str;
91 < char  *fn;
92 < int  ln;
89 > void
90 > scompile(               /* get definitions from a string */
91 >        char  *str,
92 >        char  *fn,
93 >        int  ln
94 > )
95   {
96      initstr(str, fn, ln);
97      while (nextc != EOF)
98 <        loaddefn();
98 >        getstatement();
99   }
100  
101  
102   double
103 < varvalue(vname)                 /* return a variable's value */
104 < char  *vname;
103 > varvalue(                       /* return a variable's value */
104 >        char  *vname
105 > )
106   {
107      return(dvalue(vname, dlookup(vname)));
108   }
109  
110  
111   double
112 < evariable(ep)                   /* evaluate a variable */
113 < EPNODE  *ep;
112 > evariable(                      /* evaluate a variable */
113 >        EPNODE  *ep
114 > )
115   {
116      register VARDEF  *dp = ep->v.ln;
117  
# Line 105 | Line 119 | EPNODE  *ep;
119   }
120  
121  
122 < varset(vname, val)              /* set a variable's value */
123 < char  *vname;
124 < double  val;
122 > void
123 > varset(         /* set a variable's value */
124 >        char  *vname,
125 >        int  assign,
126 >        double  val
127 > )
128   {
129 +    char  *qname;
130      register EPNODE  *ep1, *ep2;
131 +                                        /* get qualified name */
132 +    qname = qualname(vname, 0);
133                                          /* check for quick set */
134 <    if ((ep1 = dlookup(vname)) != NULL && ep1->v.kid->type == SYM) {
134 >    if ((ep1 = dlookup(qname)) != NULL && ep1->v.kid->type == SYM) {
135          ep2 = ep1->v.kid->sibling;
136          if (ep2->type == NUM) {
137              ep2->v.num = val;
138 +            ep1->type = assign;
139              return;
140          }
141      }
142                                          /* hand build definition */
143      ep1 = newnode();
144 <    ep1->type = '=';
144 >    ep1->type = assign;
145      ep2 = newnode();
146      ep2->type = SYM;
147      ep2->v.name = savestr(vname);
# Line 129 | Line 150 | double  val;
150      ep2->type = NUM;
151      ep2->v.num = val;
152      addekid(ep1, ep2);
153 <    dclear(vname);
154 <    dpush(ep1);
153 >    dremove(qname);
154 >    dpush(qname, ep1);
155   }
156  
157  
158 < dclear(name)                    /* delete all definitions of name */
159 < char  *name;
158 > void
159 > dclear(                 /* delete variable definitions of name */
160 >        char  *name
161 > )
162   {
163      register EPNODE  *ep;
164  
165 +    while ((ep = dpop(name)) != NULL) {
166 +        if (ep->type == ':') {
167 +            dpush(name, ep);            /* don't clear constants */
168 +            return;
169 +        }
170 +        epfree(ep);
171 +    }
172 + }
173 +
174 +
175 + void
176 + dremove(                        /* delete all definitions of name */
177 +        char  *name
178 + )
179 + {
180 +    register EPNODE  *ep;
181 +
182      while ((ep = dpop(name)) != NULL)
183          epfree(ep);
184   }
185  
186  
187 < vardefined(name)        /* return non-zero if variable defined */
188 < char  *name;
187 > int
188 > vardefined(     /* return non-zero if variable defined */
189 >        char  *name
190 > )
191   {
192      register EPNODE  *dp;
193  
# Line 153 | Line 195 | char  *name;
195   }
196  
197  
198 < #ifdef  OUTCHAN
199 < chanout(cs)                     /* set output channels */
200 < int  (*cs)();
198 > char *
199 > setcontext(                     /* set a new context path */
200 >        register char  *ctx
201 > )
202   {
203 +    register char  *cpp;
204 +
205 +    if (ctx == NULL)
206 +        return(context);                /* just asking */
207 +    while (*ctx == CNTXMARK)
208 +        ctx++;                          /* skip past marks */
209 +    if (!*ctx) {
210 +        context[0] = '\0';              /* empty means clear context */
211 +        return(context);
212 +    }
213 +    cpp = context;                      /* start context with mark */
214 +    *cpp++ = CNTXMARK;
215 +    do {                                /* carefully copy new context */
216 +        if (cpp >= context+MAXCNTX)
217 +            break;                      /* just copy what we can */
218 +        if (isid(*ctx))
219 +            *cpp++ = *ctx++;
220 +        else {
221 +            *cpp++ = '_'; ctx++;
222 +        }
223 +    } while (*ctx);
224 +    while (cpp[-1] == CNTXMARK)         /* cannot end in context mark */
225 +        cpp--;
226 +    *cpp = '\0';
227 +    return(context);
228 + }
229 +
230 +
231 + char *
232 + pushcontext(            /* push on another context */
233 +        char  *ctx
234 + )
235 + {
236 +    char  oldcontext[MAXCNTX+1];
237 +    register int  n;
238 +
239 +    strcpy(oldcontext, context);        /* save old context */
240 +    setcontext(ctx);                    /* set new context */
241 +    n = strlen(context);                /* tack on old */
242 +    if (n+strlen(oldcontext) > MAXCNTX) {
243 +        strncpy(context+n, oldcontext, MAXCNTX-n);
244 +        context[MAXCNTX] = '\0';
245 +    } else
246 +        strcpy(context+n, oldcontext);
247 +    return(context);
248 + }
249 +
250 +
251 + char *
252 + popcontext(void)                        /* pop off top context */
253 + {
254 +    register char  *cp1, *cp2;
255 +
256 +    if (!context[0])                    /* nothing left to pop */
257 +        return(context);
258 +    cp2 = context;                      /* find mark */
259 +    while (*++cp2 && *cp2 != CNTXMARK)
260 +        ;
261 +    cp1 = context;                      /* copy tail to front */
262 +    while (*cp1++ = *cp2++)
263 +        ;
264 +    return(context);
265 + }
266 +
267 +
268 + char *
269 + qualname(               /* get qualified name */
270 +        register char  *nam,
271 +        int  lvl
272 + )
273 + {
274 +    static char  nambuf[RMAXWORD+1];
275 +    register char  *cp = nambuf, *cpp;
276 +                                /* check for explicit local */
277 +    if (*nam == CNTXMARK)
278 +        if (lvl > 0)            /* only action is to refuse search */
279 +            return(NULL);
280 +        else
281 +            nam++;
282 +    else if (nam == nambuf)     /* check for repeat call */
283 +        return(lvl > 0 ? NULL : nam);
284 +                                /* copy name to static buffer */
285 +    while (*nam) {
286 +        if (cp >= nambuf+RMAXWORD)
287 +                goto toolong;
288 +        *cp++ = *nam++;
289 +    }
290 +                                /* check for explicit global */
291 +    if (cp > nambuf && cp[-1] == CNTXMARK) {
292 +        if (lvl > 0)
293 +            return(NULL);
294 +        *--cp = '\0';
295 +        return(nambuf);         /* already qualified */
296 +    }
297 +    cpp = context;              /* else skip the requested levels */
298 +    while (lvl-- > 0) {
299 +        if (!*cpp)
300 +            return(NULL);       /* return NULL if past global level */
301 +        while (*++cpp && *cpp != CNTXMARK)
302 +            ;
303 +    }
304 +    while (*cpp) {              /* copy context to static buffer */
305 +        if (cp >= nambuf+RMAXWORD)
306 +            goto toolong;
307 +        *cp++ = *cpp++;
308 +    }
309 + toolong:
310 +    *cp = '\0';
311 +    return(nambuf);             /* return qualified name */
312 + }
313 +
314 +
315 + int
316 + incontext(                      /* is qualified name in current context? */
317 +        register char  *qn
318 + )
319 + {
320 +    if (!context[0])                    /* global context accepts all */
321 +        return(1);
322 +    while (*qn && *qn != CNTXMARK)      /* find context mark */
323 +        qn++;
324 +    return(!strcmp(qn, context));
325 + }
326 +
327 +
328 + void
329 + chanout(                        /* set output channels */
330 +        void  (*cs)(int n, double v)
331 + )
332 + {
333      register EPNODE  *ep;
334  
335      for (ep = outchan; ep != NULL; ep = ep->sibling)
336          (*cs)(ep->v.kid->v.chan, evalue(ep->v.kid->sibling));
337  
338   }
166 #endif
339  
340  
341 < dclearall()                     /* clear all definitions */
341 > void
342 > dcleanup(               /* clear definitions (0->vars,1->output,2->consts) */
343 >        int  lvl
344 > )
345   {
346      register int  i;
347      register VARDEF  *vp;
348      register EPNODE  *ep;
349 <
349 >                                /* if context is global, clear all */
350      for (i = 0; i < NHASH; i++)
351          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
352 <            dclear(vp->name);
353 < #ifdef  OUTCHAN
354 <    for (ep = outchan; ep != NULL; ep = ep->sibling)
355 <        epfree(ep);
356 <    outchan = NULL;
357 < #endif
352 >            if (incontext(vp->name)) {
353 >                if (lvl >= 2)
354 >                    dremove(vp->name);
355 >                else
356 >                    dclear(vp->name);
357 >            }
358 >    if (lvl >= 1) {
359 >        for (ep = outchan; ep != NULL; ep = ep->sibling)
360 >            epfree(ep);
361 >        outchan = NULL;
362 >    }
363   }
364  
365  
366   EPNODE *
367 < dlookup(name)                   /* look up a definition */
368 < char  *name;
367 > dlookup(                        /* look up a definition */
368 >        char  *name
369 > )
370   {
371      register VARDEF  *vp;
372      
373      if ((vp = varlookup(name)) == NULL)
374 <        return(NULL);
374 >        return(NULL);
375      return(vp->def);
376   }
377  
378  
379   VARDEF *
380 < varlookup(name)                 /* look up a variable */
381 < char  *name;
380 > varlookup(                      /* look up a variable */
381 >        char  *name
382 > )
383   {
384 +    int  lvl = 0;
385 +    register char  *qname;
386      register VARDEF  *vp;
387 <    
388 <    for (vp = hashtbl[hash(name)]; vp != NULL; vp = vp->next)
389 <        if (!strcmp(vp->name, name))
390 <            return(vp);
387 >                                /* find most qualified match */
388 >    while ((qname = qualname(name, lvl++)) != NULL)
389 >        for (vp = hashtbl[hash(qname)]; vp != NULL; vp = vp->next)
390 >            if (!strcmp(vp->name, qname))
391 >                return(vp);
392      return(NULL);
393   }
394  
395  
396   VARDEF *
397 < varinsert(name)                 /* get a link to a variable */
398 < char  *name;
397 > varinsert(                      /* get a link to a variable */
398 >        char  *name
399 > )
400   {
401      register VARDEF  *vp;
402 <    int  hv;
402 >    int  hv;
403      
404 <    hv = hash(name);
405 <    for (vp = hashtbl[hv]; vp != NULL; vp = vp->next)
406 <        if (!strcmp(vp->name, name)) {
407 <            vp->nlinks++;
222 <            return(vp);
223 <        }
404 >    if ((vp = varlookup(name)) != NULL) {
405 >        vp->nlinks++;
406 >        return(vp);
407 >    }
408      vp = (VARDEF *)emalloc(sizeof(VARDEF));
409 +    vp->lib = liblookup(name);
410 +    if (vp->lib == NULL)                /* if name not in library */
411 +        name = qualname(name, 0);       /* use fully qualified version */
412 +    hv = hash(name);
413      vp->name = savestr(name);
414      vp->nlinks = 1;
415      vp->def = NULL;
228    vp->lib = NULL;
416      vp->next = hashtbl[hv];
417      hashtbl[hv] = vp;
418      return(vp);
419   }
420  
421  
422 < varfree(ln)                             /* release link to variable */
423 < register VARDEF  *ln;
422 > void
423 > libupdate(                      /* update library links */
424 >        char  *fn
425 > )
426   {
427 +    register int  i;
428      register VARDEF  *vp;
429 <    int  hv;
429 >                                        /* if fn is NULL then relink all */
430 >    for (i = 0; i < NHASH; i++)
431 >        for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
432 >            if (vp->lib != NULL || fn == NULL || !strcmp(fn, vp->name))
433 >                vp->lib = liblookup(vp->name);
434 > }
435  
436 +
437 + void
438 + varfree(                                /* release link to variable */
439 +        register VARDEF  *ln
440 + )
441 + {
442 +    register VARDEF  *vp;
443 +    int  hv;
444 +
445      if (--ln->nlinks > 0)
446 <        return;                         /* still active */
446 >        return;                         /* still active */
447  
448      hv = hash(ln->name);
449      vp = hashtbl[hv];
450      if (vp == ln)
451 <        hashtbl[hv] = vp->next;
451 >        hashtbl[hv] = vp->next;
452      else {
453 <        while (vp->next != ln)          /* must be in list */
454 <                vp = vp->next;
455 <        vp->next = ln->next;
453 >        while (vp->next != ln)          /* must be in list */
454 >                vp = vp->next;
455 >        vp->next = ln->next;
456      }
457      freestr(ln->name);
458      efree((char *)ln);
# Line 256 | Line 460 | register VARDEF  *ln;
460  
461  
462   EPNODE *
463 < dfirst()                        /* return pointer to first definition */
463 > dfirst(void)                    /* return pointer to first definition */
464   {
465      htndx = 0;
466      htpos = NULL;
263 #ifdef  OUTCHAN
467      ochpos = outchan;
265 #endif
468      return(dnext());
469   }
470  
471  
472   EPNODE *
473 < dnext()                         /* return pointer to next definition */
473 > dnext(void)                             /* return pointer to next definition */
474   {
475      register EPNODE  *ep;
476 +    register char  *nm;
477  
478      while (htndx < NHASH) {
479 <        if (htpos == NULL)
480 <                htpos = hashtbl[htndx++];
481 <        while (htpos != NULL) {
482 <            ep = htpos->def;
483 <            htpos = htpos->next;
484 <            if (ep != NULL)
485 <                return(ep);
486 <        }
479 >        if (htpos == NULL)
480 >                htpos = hashtbl[htndx++];
481 >        while (htpos != NULL) {
482 >            ep = htpos->def;
483 >            nm = htpos->name;
484 >            htpos = htpos->next;
485 >            if (ep != NULL && incontext(nm))
486 >                return(ep);
487 >        }
488      }
285 #ifdef  OUTCHAN
489      if ((ep = ochpos) != NULL)
490 <        ochpos = ep->sibling;
490 >        ochpos = ep->sibling;
491      return(ep);
289 #else
290    return(NULL);
291 #endif
492   }
493  
494  
495   EPNODE *
496 < dpop(name)                      /* pop a definition */
497 < char  *name;
496 > dpop(                   /* pop a definition */
497 >        char  *name
498 > )
499   {
500      register VARDEF  *vp;
501      register EPNODE  *dp;
502      
503      if ((vp = varlookup(name)) == NULL || vp->def == NULL)
504 <        return(NULL);
504 >        return(NULL);
505      dp = vp->def;
506      vp->def = dp->sibling;
507      varfree(vp);
# Line 308 | Line 509 | char  *name;
509   }
510  
511  
512 < dpush(ep)                       /* push on a definition */
513 < register EPNODE  *ep;
512 > void
513 > dpush(                  /* push on a definition */
514 >        char  *nm,
515 >        register EPNODE  *ep
516 > )
517   {
518      register VARDEF  *vp;
519  
520 <    vp = varinsert(dname(ep));
520 >    vp = varinsert(nm);
521      ep->sibling = vp->def;
522      vp->def = ep;
523   }
524  
525  
526 < #ifdef  OUTCHAN
527 < addchan(sp)                     /* add an output channel assignment */
528 < EPNODE  *sp;
526 > void
527 > addchan(                        /* add an output channel assignment */
528 >        EPNODE  *sp
529 > )
530   {
531 <    int  ch = sp->v.kid->v.chan;
531 >    int  ch = sp->v.kid->v.chan;
532      register EPNODE  *ep, *epl;
533  
534      for (epl = NULL, ep = outchan; ep != NULL; epl = ep, ep = ep->sibling)
# Line 347 | Line 552 | EPNODE  *sp;
552      sp->sibling = NULL;
553  
554   }
350 #endif
555  
556  
557 < loaddefn()                      /* load next definition */
557 > void
558 > getstatement(void)                      /* get next statement */
559   {
560      register EPNODE  *ep;
561 +    char  *qname;
562 +    register VARDEF  *vdef;
563  
564      if (nextc == ';') {         /* empty statement */
565          scan();
566          return;
567      }
568 < #ifdef  OUTCHAN
569 <    if (nextc == '$') {         /* channel assignment */
568 >    if (esupport&E_OUTCHAN &&
569 >                nextc == '$') {         /* channel assignment */
570          ep = getchan();
571          addchan(ep);
572 <    } else
366 < #endif
367 <    {                           /* ordinary definition */
572 >    } else {                            /* ordinary definition */
573          ep = getdefn();
574 < #ifdef  REDEFW
575 <        if (dlookup(dname(ep)) != NULL) {
576 <                dclear(dname(ep));
577 <                wputs(dname(ep));
578 <                wputs(": redefined\n");
574 >        qname = qualname(dname(ep), 0);
575 >        if (esupport&E_REDEFW && (vdef = varlookup(qname)) != NULL) {
576 >            if (vdef->def != NULL && epcmp(ep, vdef->def)) {
577 >                wputs(qname);
578 >                if (vdef->def->type == ':')
579 >                    wputs(": redefined constant expression\n");
580 >                else
581 >                    wputs(": redefined\n");
582 >            } else if (ep->v.kid->type == FUNC && vdef->lib != NULL) {
583 >                wputs(qname);
584 >                wputs(": definition hides library function\n");
585 >            }
586          }
587 < #else
588 <        dclear(dname(ep));
589 < #endif
590 <        dpush(ep);
587 >        if (ep->type == ':')
588 >            dremove(qname);
589 >        else
590 >            dclear(qname);
591 >        dpush(qname, ep);
592      }
593      if (nextc != EOF) {
594          if (nextc != ';')
# Line 386 | Line 599 | loaddefn()                     /* load next definition */
599  
600  
601   EPNODE *
602 < getdefn()                       /* A -> SYM = E1 */
603 <                                /*      FUNC(SYM,..) = E1 */
602 > getdefn(void)
603 >        /* A -> SYM = E1 */
604 >        /*      SYM : E1 */
605 >        /*      FUNC(SYM,..) = E1 */
606 >        /*      FUNC(SYM,..) : E1 */
607   {
608      register EPNODE  *ep1, *ep2;
609  
610 <    if (!isalpha(nextc))
610 >    if (!isalpha(nextc) && nextc != CNTXMARK)
611          syntax("illegal variable name");
612  
613      ep1 = newnode();
614      ep1->type = SYM;
615      ep1->v.name = savestr(getname());
616  
617 < #ifdef  FUNCTION
402 <    if (nextc == '(') {
617 >    if (esupport&E_FUNCTION && nextc == '(') {
618          ep2 = newnode();
619          ep2->type = FUNC;
620          addekid(ep2, ep1);
# Line 417 | Line 632 | getdefn()                      /* A -> SYM = E1 */
632              syntax("')' expected");
633          scan();
634          curfunc = ep1;
635 <    } else
421 <        curfunc = NULL;
422 < #endif
635 >    }
636  
637 <    if (nextc != '=')
638 <        syntax("'=' expected");
426 <    scan();
637 >    if (nextc != '=' && nextc != ':')
638 >        syntax("'=' or ':' expected");
639  
640      ep2 = newnode();
641 <    ep2->type = '=';
641 >    ep2->type = nextc;
642 >    scan();
643      addekid(ep2, ep1);
644      addekid(ep2, getE1());
645  
646 <    if (
434 < #ifdef  FUNCTION
435 <            ep1->type == SYM &&
436 < #endif
437 <            ep1->sibling->type != NUM) {
646 >    if (ep1->type == SYM && ep1->sibling->type != NUM) {
647          ep1 = newnode();
648          ep1->type = TICK;
649 <        ep1->v.tick = -1;
649 >        ep1->v.tick = 0;
650          addekid(ep2, ep1);
651          ep1 = newnode();
652          ep1->type = NUM;
653          addekid(ep2, ep1);
654      }
655 +    curfunc = NULL;
656  
657      return(ep2);
658   }
659  
660  
451 #ifdef  OUTCHAN
661   EPNODE *
662 < getchan()                       /* A -> $N = E1 */
662 > getchan(void)                   /* A -> $N = E1 */
663   {
664      register EPNODE  *ep1, *ep2;
665  
# Line 473 | Line 682 | getchan()                      /* A -> $N = E1 */
682  
683      return(ep2);
684   }
476 #endif
685  
686  
687  
# Line 482 | Line 690 | getchan()                      /* A -> $N = E1 */
690   */
691  
692  
693 < static double
694 < dvalue(name, d)                 /* evaluate a variable */
487 < char  *name;
488 < EPNODE  *d;
693 > static double                   /* evaluate a variable */
694 > dvalue(char  *name, EPNODE      *d)
695   {
696      register EPNODE  *ep1, *ep2;
697      
# Line 498 | Line 704 | EPNODE  *d;
704      if (ep1->type == NUM)
705          return(ep1->v.num);                     /* return if number */
706      ep2 = ep1->sibling;                         /* check time */
707 <    if (ep2->v.tick < 0 || ep2->v.tick < eclock) {
708 <        ep2->v.tick = eclock;
707 >    if (eclock >= MAXCLOCK)
708 >        eclock = 1;                             /* wrap clock counter */
709 >    if (ep2->v.tick < MAXCLOCK &&
710 >                ep2->v.tick == 0 | ep2->v.tick != eclock) {
711 >        ep2->v.tick = d->type == ':' ? MAXCLOCK : eclock;
712          ep2 = ep2->sibling;
713          ep2->v.num = evalue(ep1);               /* needs new value */
714      } else
715          ep2 = ep2->sibling;                     /* else reuse old value */
716  
717      return(ep2->v.num);
509 }
510
511
512 static int
513 hash(s)                         /* hash a string */
514 register char  *s;
515 {
516    register int  rval = 0;
517
518    while (*s)
519        rval += *s++;
520    
521    return(rval % NHASH);
718   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines