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.12 by greg, Wed Jul 17 11:12:02 1991 UTC vs.
Revision 1.19 by greg, Wed Aug 14 15:50:38 1991 UTC

# Line 20 | Line 20 | static char SCCSid[] = "$SunId$ LBL";
20   *  5/31/90  Added conditional compile (REDEFW) for redefinition warning.
21   *
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+1];        /* 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)
199 +            break;                      /* just copy what we can */
200 +        if (isid(*ctx))
201 +            *cpp++ = *ctx++;
202 +        else {
203 +            *cpp++ = '_'; ctx++;
204 +        }
205 +    } while (*ctx);
206 +    *cpp = '\0';
207 +    return(context);
208 + }
209 +
210 +
211 + char *
212 + qualname(nam, lvl)              /* get qualified name */
213 + register char  *nam;
214 + int  lvl;
215 + {
216 +    static char  nambuf[MAXWORD+1];
217 +    register char  *cp = nambuf, *cpp;
218 +                                /* check for explicit local */
219 +    if (*nam == CNTXMARK)
220 +        if (lvl > 0)            /* only action is to refuse search */
221 +            return(NULL);
222 +        else
223 +            nam++;
224 +    else if (nam == nambuf)     /* check for repeat call */
225 +        return(lvl > 0 ? NULL : nam);
226 +                                /* copy name to static buffer */
227 +    while (*nam) {
228 +        if (cp >= nambuf+MAXWORD)
229 +                goto toolong;
230 +        *cp++ = *nam++;
231 +    }
232 +                                /* check for explicit global */
233 +    if (cp > nambuf && cp[-1] == CNTXMARK) {
234 +        if (lvl > 0)
235 +            return(NULL);
236 +        *--cp = '\0';
237 +        return(nambuf);         /* already qualified */
238 +    }
239 +    cpp = context;              /* else skip the requested levels */
240 +    while (lvl-- > 0) {
241 +        if (!*cpp)
242 +            return(NULL);       /* return NULL if past global level */
243 +        while (*++cpp && *cpp != CNTXMARK)
244 +            ;
245 +    }
246 +    while (*cpp) {              /* copy context to static buffer */
247 +        if (cp >= nambuf+MAXWORD)
248 +            goto toolong;
249 +        *cp++ = *cpp++;
250 +    }
251 + toolong:
252 +    *cp = '\0';
253 +    return(nambuf);             /* return qualified name */
254 + }
255 +
256 +
257 + incontext(qn)                   /* is qualified name in current context? */
258 + register char  *qn;
259 + {
260 +    while (*qn && *qn != CNTXMARK)      /* find context mark */
261 +        qn++;
262 +    return(!strcmp(qn, context));
263 + }
264 +
265 +
266   #ifdef  OUTCHAN
267   chanout(cs)                     /* set output channels */
268   int  (*cs)();
# Line 191 | Line 282 | int  lvl;
282      register int  i;
283      register VARDEF  *vp;
284      register EPNODE  *ep;
285 <
285 >                                /* if context is global, clear all */
286      for (i = 0; i < NHASH; i++)
287          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
288 <            if (lvl >= 2)
289 <                dremove(vp->name);
290 <            else
291 <                dclear(vp->name);
288 >            if (!context[0] || incontext(vp->name))
289 >                if (lvl >= 2)
290 >                    dremove(vp->name);
291 >                else
292 >                    dclear(vp->name);
293   #ifdef  OUTCHAN
294      if (lvl >= 1) {
295          for (ep = outchan; ep != NULL; ep = ep->sibling)
# Line 224 | Line 316 | VARDEF *
316   varlookup(name)                 /* look up a variable */
317   char  *name;
318   {
319 +    int  lvl = 0;
320 +    register char  *qname;
321      register VARDEF  *vp;
322 <    
323 <    for (vp = hashtbl[hash(name)]; vp != NULL; vp = vp->next)
324 <        if (!strcmp(vp->name, name))
325 <            return(vp);
322 >                                /* find most qualified match */
323 >    while ((qname = qualname(name, lvl++)) != NULL)
324 >        for (vp = hashtbl[hash(qname)]; vp != NULL; vp = vp->next)
325 >            if (!strcmp(vp->name, qname))
326 >                return(vp);
327      return(NULL);
328   }
329  
# Line 238 | Line 333 | varinsert(name)                        /* get a link to a variable */
333   char  *name;
334   {
335      register VARDEF  *vp;
336 +    LIBR  *libp;
337      int  hv;
338      
339 +    if ((vp = varlookup(name)) != NULL) {
340 +        vp->nlinks++;
341 +        return(vp);
342 +    }
343 + #ifdef  FUNCTION
344 +    libp = liblookup(name);
345 + #else
346 +    libp = NULL;
347 + #endif
348 +    if (libp == NULL)                   /* if name not in library */
349 +        name = qualname(name, 0);       /* use fully qualified version */
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;
354      vp->def = NULL;
355 <    vp->lib = NULL;
355 >    vp->lib = libp;
356      vp->next = hashtbl[hv];
357      hashtbl[hv] = vp;
358      return(vp);
# Line 296 | Line 398 | EPNODE *
398   dnext()                         /* return pointer to next definition */
399   {
400      register EPNODE  *ep;
401 +    register char  *nm;
402  
403      while (htndx < NHASH) {
404          if (htpos == NULL)
405                  htpos = hashtbl[htndx++];
406          while (htpos != NULL) {
407              ep = htpos->def;
408 +            nm = htpos->name;
409              htpos = htpos->next;
410 <            if (ep != NULL)
410 >            if (ep != NULL && incontext(nm))
411                  return(ep);
412          }
413      }
# Line 333 | Line 437 | char  *name;
437   }
438  
439  
440 < dpush(ep)                       /* push on a definition */
440 > dpush(nm, ep)                   /* push on a definition */
441 > char  *nm;
442   register EPNODE  *ep;
443   {
444      register VARDEF  *vp;
445  
446 <    vp = varinsert(dname(ep));
446 >    vp = varinsert(nm);
447      ep->sibling = vp->def;
448      vp->def = ep;
449   }
# Line 375 | Line 480 | EPNODE  *sp;
480   #endif
481  
482  
483 < loaddefn()                      /* load next definition */
483 > getstatement()                  /* get next statement */
484   {
485      register EPNODE  *ep;
486 <    EPNODE  *lastdef;
486 >    char  *qname;
487 >    register VARDEF  *vdef;
488  
489      if (nextc == ';') {         /* empty statement */
490          scan();
# Line 392 | Line 498 | loaddefn()                     /* load next definition */
498   #endif
499      {                           /* ordinary definition */
500          ep = getdefn();
501 +        qname = qualname(dname(ep), 0);
502   #ifdef  REDEFW
503 <        if ((lastdef = dlookup(dname(ep))) != NULL) {
504 <            wputs(dname(ep));
505 <            if (lastdef->type == ':')
506 <                wputs(": redefined constant expression\n");
507 <            else
508 <                wputs(": redefined\n");
509 <        }
503 >        if ((vdef = varlookup(qname)) != NULL)
504 >            if (vdef->def != NULL) {
505 >                wputs(qname);
506 >                if (vdef->def->type == ':')
507 >                    wputs(": redefined constant expression\n");
508 >                else
509 >                    wputs(": redefined\n");
510 >            }
511   #ifdef  FUNCTION
512 <        else if (ep->v.kid->type == FUNC &&
513 <                        liblookup(ep->v.kid->v.kid->v.name) != NULL) {
514 <            wputs(ep->v.kid->v.kid->v.name);
515 <            wputs(": definition hides library function\n");
408 <        }
512 >            else if (ep->v.kid->type == FUNC && vdef->lib != NULL) {
513 >                wputs(qname);
514 >                wputs(": definition hides library function\n");
515 >            }
516   #endif
517   #endif
518          if (ep->type == ':')
519 <            dremove(dname(ep));
519 >            dremove(qname);
520          else
521 <            dclear(dname(ep));
522 <        dpush(ep);
521 >            dclear(qname);
522 >        dpush(qname, ep);
523      }
524      if (nextc != EOF) {
525          if (nextc != ';')
# Line 430 | Line 537 | getdefn()                      /* A -> SYM = E1 */
537   {
538      register EPNODE  *ep1, *ep2;
539  
540 <    if (!isalpha(nextc))
540 >    if (!isalpha(nextc) && nextc != CNTXMARK)
541          syntax("illegal variable name");
542  
543      ep1 = newnode();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines