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.9 by greg, Wed Apr 24 08:17:22 1991 UTC vs.
Revision 1.15 by greg, Thu Aug 8 12:28:30 1991 UTC

# Line 19 | Line 19 | static char SCCSid[] = "$SunId$ LBL";
19   *
20   *  5/31/90  Added conditional compile (REDEFW) for redefinition warning.
21   *
22 < *  4/23/91  Added ':' defines for constant expressions (RCONST)
22 > *  4/23/91  Added ':' assignment for constant expressions
23 > *
24 > *  8/7/91  Added optional context path to append to variable names
25   */
26  
27   #include  <stdio.h>
# Line 34 | Line 36 | static char SCCSid[] = "$SunId$ LBL";
36  
37   #define  newnode()      (EPNODE *)ecalloc(1, sizeof(EPNODE))
38  
39 < extern char  *ecalloc(), *savestr();
39 > extern char  *ecalloc(), *savestr(), *strcpy();
40  
41   static double  dvalue();
42  
43   long  eclock = -1;                      /* value storage timer */
44  
45 + static char  context[MAXWORD];          /* current context path */
46 +
47   static VARDEF  *hashtbl[NHASH];         /* definition list */
48   static int  htndx;                      /* index for */        
49   static VARDEF  *htpos;                  /* ...dfirst() and */
# Line 72 | Line 76 | char  *fname;
76      }
77      initfile(fp, fname, 0);
78      while (nextc != EOF)
79 <        loaddefn();
79 >        getstatement();
80      if (fname != NULL)
81          fclose(fp);
82   }
# Line 85 | Line 89 | int  ln;
89   {
90      initstr(str, fn, ln);
91      while (nextc != EOF)
92 <        loaddefn();
92 >        getstatement();
93   }
94  
95  
# Line 112 | Line 116 | char  *vname;
116   int  assign;
117   double  val;
118   {
119 +    char  *qname;
120      register EPNODE  *ep1, *ep2;
121 +                                        /* get qualified name */
122 +    qname = qualname(vname, 0);
123                                          /* check for quick set */
124 <    if ((ep1 = dlookup(vname)) != NULL && ep1->v.kid->type == SYM) {
124 >    if ((ep1 = dlookup(qname)) != NULL && ep1->v.kid->type == SYM) {
125          ep2 = ep1->v.kid->sibling;
126          if (ep2->type == NUM) {
127              ep2->v.num = val;
# Line 133 | Line 140 | double  val;
140      ep2->type = NUM;
141      ep2->v.num = val;
142      addekid(ep1, ep2);
143 <    dremove(vname);
144 <    dpush(ep1);
143 >    dremove(qname);
144 >    dpush(qname, ep1);
145   }
146  
147  
# Line 145 | Line 152 | char  *name;
152  
153      while ((ep = dpop(name)) != NULL) {
154          if (ep->type == ':') {
155 <            dpush(ep);          /* don't clear constants */
155 >            dpush(name, ep);            /* don't clear constants */
156              return;
157          }
158          epfree(ep);
# Line 172 | Line 179 | char  *name;
179   }
180  
181  
182 + char *
183 + setcontext(ctx)                 /* set a new context path */
184 + register char  *ctx;
185 + {
186 +    register char  *cpp;
187 +
188 +    if (ctx == NULL)
189 +        return(context);                /* just asking */
190 +    if (!*ctx) {
191 +        context[0] = '\0';              /* clear context */
192 +        return(context);
193 +    }
194 +    cpp = context;                      /* else copy it (carefully!) */
195 +    if (*ctx != CNTXMARK)
196 +        *cpp++ = CNTXMARK;              /* make sure there's a mark */
197 +    do {
198 +        if (cpp >= context+MAXWORD-1) {
199 +            *cpp = '\0';
200 +            wputs(context);
201 +            wputs(": context path too long\n");
202 +            return(NULL);
203 +        }
204 +        if (isid(*ctx))
205 +            *cpp++ = *ctx++;
206 +        else {
207 +            *cpp++ = '_'; ctx++;
208 +        }
209 +    } while (*ctx);
210 +    *cpp = '\0';
211 +    return(context);
212 + }
213 +
214 +
215 + char *
216 + qualname(nam, lvl)              /* get qualified name */
217 + register char  *nam;
218 + int  lvl;
219 + {
220 +    static char  nambuf[MAXWORD];
221 +    register char  *cp = nambuf, *cpp = context;
222 +                                /* check for explicit global */
223 +    if (*nam == CNTXMARK)
224 +        return(lvl > 0 ? NULL : nam+1);
225 +                                /* check for repeat call */
226 +    if (nam == nambuf)
227 +        return(lvl > 0 ? NULL : nambuf);
228 +                                /* copy name to static buffer */
229 +    while (*nam) {
230 +        if (cp >= nambuf+MAXWORD-1)
231 +                goto toolong;
232 +        if ((*cp++ = *nam++) == CNTXMARK)
233 +            cpp = NULL;         /* flag a qualified name */
234 +    }
235 +    if (cpp == NULL) {
236 +        if (lvl > 0)
237 +            return(NULL);               /* no higher level */
238 +        if (cp[-1] == CNTXMARK) {
239 +            cp--; cpp = context;        /* current context explicitly */
240 +        } else
241 +            cpp = "";                   /* else fully qualified */
242 +    } else                      /* else skip the requested levels */
243 +        while (lvl-- > 0) {
244 +            if (!*cpp)
245 +                return(NULL);   /* return NULL if past global level */
246 +            while (*++cpp && *cpp != CNTXMARK)
247 +                ;
248 +        }
249 +    while (*cpp) {              /* copy context to static buffer */
250 +        if (cp >= nambuf+MAXWORD-1)
251 +            goto toolong;
252 +        *cp++ = *cpp++;
253 +    }
254 +    *cp = '\0';
255 +    return(nambuf);             /* return qualified name */
256 + toolong:
257 +    *cp = '\0';
258 +    eputs(nambuf);
259 +    eputs(": name too long\n");
260 +    quit(1);
261 + }
262 +
263 +
264 + incontext(qn)                   /* is qualified name in current context? */
265 + register char  *qn;
266 + {
267 +    while (*qn && *qn != CNTXMARK)      /* find context mark */
268 +        ;
269 +    return(!strcmp(qn, context));
270 + }
271 +
272 +
273   #ifdef  OUTCHAN
274   chanout(cs)                     /* set output channels */
275   int  (*cs)();
# Line 185 | Line 283 | int  (*cs)();
283   #endif
284  
285  
286 < dcleanup(cons, ochans)          /* clear definitions */
287 < int  cons, ochans;
286 > dcleanup(lvl)           /* clear definitions (0->vars,1->output,2->consts) */
287 > int  lvl;
288   {
289      register int  i;
290      register VARDEF  *vp;
291      register EPNODE  *ep;
292 <
292 >                                /* if context is global, clear all */
293      for (i = 0; i < NHASH; i++)
294          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
295 <            if (cons)
296 <                dremove(vp->name);
297 <            else
298 <                dclear(vp->name);
295 >            if (!context[0] || incontext(vp->name))
296 >                if (lvl >= 2)
297 >                    dremove(vp->name);
298 >                else
299 >                    dclear(vp->name);
300   #ifdef  OUTCHAN
301 <    if (ochans) {
301 >    if (lvl >= 1) {
302          for (ep = outchan; ep != NULL; ep = ep->sibling)
303              epfree(ep);
304          outchan = NULL;
# Line 224 | Line 323 | VARDEF *
323   varlookup(name)                 /* look up a variable */
324   char  *name;
325   {
326 +    int  lvl = 0;
327 +    register char  *qname;
328      register VARDEF  *vp;
329 <    
330 <    for (vp = hashtbl[hash(name)]; vp != NULL; vp = vp->next)
331 <        if (!strcmp(vp->name, name))
332 <            return(vp);
329 >                                /* find most qualified match */
330 >    while ((qname = qualname(name, lvl++)) != NULL)
331 >        for (vp = hashtbl[hash(qname)]; vp != NULL; vp = vp->next)
332 >            if (!strcmp(vp->name, qname))
333 >                return(vp);
334      return(NULL);
335   }
336  
# Line 240 | Line 342 | char  *name;
342      register VARDEF  *vp;
343      int  hv;
344      
345 +    if ((vp = varlookup(name)) != NULL) {
346 +        vp->nlinks++;
347 +        return(vp);
348 +    }
349 +    name = qualname(name, 0);           /* use fully qualified name */
350      hv = hash(name);
244    for (vp = hashtbl[hv]; vp != NULL; vp = vp->next)
245        if (!strcmp(vp->name, name)) {
246            vp->nlinks++;
247            return(vp);
248        }
351      vp = (VARDEF *)emalloc(sizeof(VARDEF));
352      vp->name = savestr(name);
353      vp->nlinks = 1;
# Line 333 | Line 435 | char  *name;
435   }
436  
437  
438 < dpush(ep)                       /* push on a definition */
438 > dpush(nm, ep)                   /* push on a definition */
439 > char  *nm;
440   register EPNODE  *ep;
441   {
442      register VARDEF  *vp;
443  
444 <    vp = varinsert(dname(ep));
444 >    vp = varinsert(nm);
445      ep->sibling = vp->def;
446      vp->def = ep;
447   }
# Line 375 | Line 478 | EPNODE  *sp;
478   #endif
479  
480  
481 < loaddefn()                      /* load next definition */
481 > getstatement()                  /* get next statement */
482   {
483      register EPNODE  *ep;
484 +    char  *qname;
485 +    EPNODE  *lastdef;
486  
487      if (nextc == ';') {         /* empty statement */
488          scan();
# Line 391 | Line 496 | loaddefn()                     /* load next definition */
496   #endif
497      {                           /* ordinary definition */
498          ep = getdefn();
499 +        qname = qualname(dname(ep), 0);
500   #ifdef  REDEFW
501 <        if (dlookup(dname(ep)) != NULL) {
502 <            dclear(dname(ep));
503 <            wputs(dname(ep));
398 <            if (dlookup(dname(ep)) == NULL)
399 <                wputs(": redefined\n");
400 <            else
501 >        if ((lastdef = dlookup(qname)) != NULL) {
502 >            wputs(qname);
503 >            if (lastdef->type == ':')
504                  wputs(": redefined constant expression\n");
505 +            else
506 +                wputs(": redefined\n");
507          }
508   #ifdef  FUNCTION
509 <        else if (ep->v.kid->type == FUNC &&
510 <                        liblookup(ep->v.kid->v.kid->v.name) != NULL) {
511 <            wputs(ep->v.kid->v.kid->v.name);
407 <            wputs(": redefined library function\n");
509 >        else if (ep->v.kid->type == FUNC && liblookup(qname) != NULL) {
510 >            wputs(qname);
511 >            wputs(": definition hides library function\n");
512          }
513   #endif
410 #else
411        dclear(dname(ep));
514   #endif
515 <        dpush(ep);
515 >        if (ep->type == ':')
516 >            dremove(qname);
517 >        else
518 >            dclear(qname);
519 >        dpush(qname, ep);
520      }
521      if (nextc != EOF) {
522          if (nextc != ';')
# Line 465 | Line 571 | getdefn()                      /* A -> SYM = E1 */
571      ep2->type = nextc;
572      scan();
573      addekid(ep2, ep1);
468 #ifdef  RCONST
469    if (
470 #ifdef  FUNCTION
471            ep1->type == SYM &&
472 #endif
473            ep2->type == ':')
474        addekid(ep2, rconst(getE1()));
475    else
476 #endif
574      addekid(ep2, getE1());
575  
576      if (

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines