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.20 by greg, Mon Oct 28 09:47:19 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 int  hash();
42 +
43   static double  dvalue();
44  
45   long  eclock = -1;                      /* value storage timer */
46  
47 + static char  context[MAXWORD+1];        /* current context path */
48 +
49   static VARDEF  *hashtbl[NHASH];         /* definition list */
50   static int  htndx;                      /* index for */        
51   static VARDEF  *htpos;                  /* ...dfirst() and */
# Line 72 | Line 78 | char  *fname;
78      }
79      initfile(fp, fname, 0);
80      while (nextc != EOF)
81 <        loaddefn();
81 >        getstatement();
82      if (fname != NULL)
83          fclose(fp);
84   }
# Line 85 | Line 91 | int  ln;
91   {
92      initstr(str, fn, ln);
93      while (nextc != EOF)
94 <        loaddefn();
94 >        getstatement();
95   }
96  
97  
# Line 112 | Line 118 | char  *vname;
118   int  assign;
119   double  val;
120   {
121 +    char  *qname;
122      register EPNODE  *ep1, *ep2;
123 +                                        /* get qualified name */
124 +    qname = qualname(vname, 0);
125                                          /* check for quick set */
126 <    if ((ep1 = dlookup(vname)) != NULL && ep1->v.kid->type == SYM) {
126 >    if ((ep1 = dlookup(qname)) != NULL && ep1->v.kid->type == SYM) {
127          ep2 = ep1->v.kid->sibling;
128          if (ep2->type == NUM) {
129              ep2->v.num = val;
# Line 133 | Line 142 | double  val;
142      ep2->type = NUM;
143      ep2->v.num = val;
144      addekid(ep1, ep2);
145 <    dremove(vname);
146 <    dpush(ep1);
145 >    dremove(qname);
146 >    dpush(qname, ep1);
147   }
148  
149  
# Line 145 | Line 154 | char  *name;
154  
155      while ((ep = dpop(name)) != NULL) {
156          if (ep->type == ':') {
157 <            dpush(ep);          /* don't clear constants */
157 >            dpush(name, ep);            /* don't clear constants */
158              return;
159          }
160          epfree(ep);
# Line 172 | Line 181 | char  *name;
181   }
182  
183  
184 + char *
185 + setcontext(ctx)                 /* set a new context path */
186 + register char  *ctx;
187 + {
188 +    register char  *cpp;
189 +
190 +    if (ctx == NULL)
191 +        return(context);                /* just asking */
192 +    if (!*ctx) {
193 +        context[0] = '\0';              /* clear context */
194 +        return(context);
195 +    }
196 +    cpp = context;                      /* else copy it (carefully!) */
197 +    if (*ctx != CNTXMARK)
198 +        *cpp++ = CNTXMARK;              /* make sure there's a mark */
199 +    do {
200 +        if (cpp >= context+MAXWORD)
201 +            break;                      /* just copy what we can */
202 +        if (isid(*ctx))
203 +            *cpp++ = *ctx++;
204 +        else {
205 +            *cpp++ = '_'; ctx++;
206 +        }
207 +    } while (*ctx);
208 +    *cpp = '\0';
209 +    return(context);
210 + }
211 +
212 +
213 + char *
214 + qualname(nam, lvl)              /* get qualified name */
215 + register char  *nam;
216 + int  lvl;
217 + {
218 +    static char  nambuf[MAXWORD+1];
219 +    register char  *cp = nambuf, *cpp;
220 +                                /* check for explicit local */
221 +    if (*nam == CNTXMARK)
222 +        if (lvl > 0)            /* only action is to refuse search */
223 +            return(NULL);
224 +        else
225 +            nam++;
226 +    else if (nam == nambuf)     /* check for repeat call */
227 +        return(lvl > 0 ? NULL : nam);
228 +                                /* copy name to static buffer */
229 +    while (*nam) {
230 +        if (cp >= nambuf+MAXWORD)
231 +                goto toolong;
232 +        *cp++ = *nam++;
233 +    }
234 +                                /* check for explicit global */
235 +    if (cp > nambuf && cp[-1] == CNTXMARK) {
236 +        if (lvl > 0)
237 +            return(NULL);
238 +        *--cp = '\0';
239 +        return(nambuf);         /* already qualified */
240 +    }
241 +    cpp = context;              /* else skip the requested levels */
242 +    while (lvl-- > 0) {
243 +        if (!*cpp)
244 +            return(NULL);       /* return NULL if past global level */
245 +        while (*++cpp && *cpp != CNTXMARK)
246 +            ;
247 +    }
248 +    while (*cpp) {              /* copy context to static buffer */
249 +        if (cp >= nambuf+MAXWORD)
250 +            goto toolong;
251 +        *cp++ = *cpp++;
252 +    }
253 + toolong:
254 +    *cp = '\0';
255 +    return(nambuf);             /* return qualified name */
256 + }
257 +
258 +
259 + incontext(qn)                   /* is qualified name in current context? */
260 + register char  *qn;
261 + {
262 +    while (*qn && *qn != CNTXMARK)      /* find context mark */
263 +        qn++;
264 +    return(!strcmp(qn, context));
265 + }
266 +
267 +
268   #ifdef  OUTCHAN
269   chanout(cs)                     /* set output channels */
270   int  (*cs)();
# Line 191 | Line 284 | int  lvl;
284      register int  i;
285      register VARDEF  *vp;
286      register EPNODE  *ep;
287 <
287 >                                /* if context is global, clear all */
288      for (i = 0; i < NHASH; i++)
289          for (vp = hashtbl[i]; vp != NULL; vp = vp->next)
290 <            if (lvl >= 2)
291 <                dremove(vp->name);
292 <            else
293 <                dclear(vp->name);
290 >            if (!context[0] || incontext(vp->name))
291 >                if (lvl >= 2)
292 >                    dremove(vp->name);
293 >                else
294 >                    dclear(vp->name);
295   #ifdef  OUTCHAN
296      if (lvl >= 1) {
297          for (ep = outchan; ep != NULL; ep = ep->sibling)
# Line 224 | Line 318 | VARDEF *
318   varlookup(name)                 /* look up a variable */
319   char  *name;
320   {
321 +    int  lvl = 0;
322 +    register char  *qname;
323      register VARDEF  *vp;
324 <    
325 <    for (vp = hashtbl[hash(name)]; vp != NULL; vp = vp->next)
326 <        if (!strcmp(vp->name, name))
327 <            return(vp);
324 >                                /* find most qualified match */
325 >    while ((qname = qualname(name, lvl++)) != NULL)
326 >        for (vp = hashtbl[hash(qname)]; vp != NULL; vp = vp->next)
327 >            if (!strcmp(vp->name, qname))
328 >                return(vp);
329      return(NULL);
330   }
331  
# Line 238 | Line 335 | varinsert(name)                        /* get a link to a variable */
335   char  *name;
336   {
337      register VARDEF  *vp;
338 +    LIBR  *libp;
339      int  hv;
340      
341 +    if ((vp = varlookup(name)) != NULL) {
342 +        vp->nlinks++;
343 +        return(vp);
344 +    }
345 + #ifdef  FUNCTION
346 +    libp = liblookup(name);
347 + #else
348 +    libp = NULL;
349 + #endif
350 +    if (libp == NULL)                   /* if name not in library */
351 +        name = qualname(name, 0);       /* use fully qualified version */
352      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        }
353      vp = (VARDEF *)emalloc(sizeof(VARDEF));
354      vp->name = savestr(name);
355      vp->nlinks = 1;
356      vp->def = NULL;
357 <    vp->lib = NULL;
357 >    vp->lib = libp;
358      vp->next = hashtbl[hv];
359      hashtbl[hv] = vp;
360      return(vp);
# Line 296 | Line 400 | EPNODE *
400   dnext()                         /* return pointer to next definition */
401   {
402      register EPNODE  *ep;
403 +    register char  *nm;
404  
405      while (htndx < NHASH) {
406          if (htpos == NULL)
407                  htpos = hashtbl[htndx++];
408          while (htpos != NULL) {
409              ep = htpos->def;
410 +            nm = htpos->name;
411              htpos = htpos->next;
412 <            if (ep != NULL)
412 >            if (ep != NULL && incontext(nm))
413                  return(ep);
414          }
415      }
# Line 333 | Line 439 | char  *name;
439   }
440  
441  
442 < dpush(ep)                       /* push on a definition */
442 > dpush(nm, ep)                   /* push on a definition */
443 > char  *nm;
444   register EPNODE  *ep;
445   {
446      register VARDEF  *vp;
447  
448 <    vp = varinsert(dname(ep));
448 >    vp = varinsert(nm);
449      ep->sibling = vp->def;
450      vp->def = ep;
451   }
# Line 375 | Line 482 | EPNODE  *sp;
482   #endif
483  
484  
485 < loaddefn()                      /* load next definition */
485 > getstatement()                  /* get next statement */
486   {
487      register EPNODE  *ep;
488 <    EPNODE  *lastdef;
488 >    char  *qname;
489 >    register VARDEF  *vdef;
490  
491      if (nextc == ';') {         /* empty statement */
492          scan();
# Line 392 | Line 500 | loaddefn()                     /* load next definition */
500   #endif
501      {                           /* ordinary definition */
502          ep = getdefn();
503 +        qname = qualname(dname(ep), 0);
504   #ifdef  REDEFW
505 <        if ((lastdef = dlookup(dname(ep))) != NULL) {
506 <            wputs(dname(ep));
507 <            if (lastdef->type == ':')
508 <                wputs(": redefined constant expression\n");
509 <            else
510 <                wputs(": redefined\n");
511 <        }
505 >        if ((vdef = varlookup(qname)) != NULL)
506 >            if (vdef->def != NULL) {
507 >                wputs(qname);
508 >                if (vdef->def->type == ':')
509 >                    wputs(": redefined constant expression\n");
510 >                else
511 >                    wputs(": redefined\n");
512 >            }
513   #ifdef  FUNCTION
514 <        else if (ep->v.kid->type == FUNC &&
515 <                        liblookup(ep->v.kid->v.kid->v.name) != NULL) {
516 <            wputs(ep->v.kid->v.kid->v.name);
517 <            wputs(": definition hides library function\n");
408 <        }
514 >            else if (ep->v.kid->type == FUNC && vdef->lib != NULL) {
515 >                wputs(qname);
516 >                wputs(": definition hides library function\n");
517 >            }
518   #endif
519   #endif
520          if (ep->type == ':')
521 <            dremove(dname(ep));
521 >            dremove(qname);
522          else
523 <            dclear(dname(ep));
524 <        dpush(ep);
523 >            dclear(qname);
524 >        dpush(qname, ep);
525      }
526      if (nextc != EOF) {
527          if (nextc != ';')
# Line 430 | Line 539 | getdefn()                      /* A -> SYM = E1 */
539   {
540      register EPNODE  *ep1, *ep2;
541  
542 <    if (!isalpha(nextc))
542 >    if (!isalpha(nextc) && nextc != CNTXMARK)
543          syntax("illegal variable name");
544  
545      ep1 = newnode();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines