ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/calexpr.c
(Generate patch)

Comparing ray/src/common/calexpr.c (file contents):
Revision 2.16 by greg, Thu Feb 16 09:49:29 1995 UTC vs.
Revision 2.28 by schorsch, Fri Nov 14 17:22:06 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1992 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   *  Compute data values using expression parser
6   *
# Line 16 | Line 13 | static char SCCSid[] = "$SunId$ LBL";
13   *  1/29/87  Made variables conditional (VARIABLE)
14   *
15   *  5/19/88  Added constant subexpression elimination (RCONST)
16 + *
17 + *  2/19/03     Eliminated conditional compiles in favor of esupport extern.
18   */
19  
20 < #include  <stdio.h>
20 > #include "copyright.h"
21  
22 + #include  <stdio.h>
23 + #include  <string.h>
24   #include  <ctype.h>
24
25   #include  <errno.h>
26
26   #include  <math.h>
27 + #include  <stdlib.h>
28  
29 + #include  "rterror.h"
30   #include  "calcomp.h"
31  
32   #define  MAXLINE        256             /* maximum line length */
# Line 34 | Line 35 | static char SCCSid[] = "$SunId$ LBL";
35  
36   #define  isdecimal(c)   (isdigit(c) || (c) == '.')
37  
38 < extern char  *savestr();
39 < extern char  *emalloc(), *ecalloc();
40 < extern EPNODE  *curfunc;
41 < extern double  efunc(), evariable();
42 < static double  euminus(), eargument(), enumber();
43 < #ifdef  INCHAN
43 < static double  echannel();
44 < #endif
45 < static double  eadd(), esubtr(), emult(), edivi(), epow();
46 < static double  ebotch();
38 > static double  euminus(EPNODE *), eargument(EPNODE *), enumber(EPNODE *);
39 > static double  echannel(EPNODE *);
40 > static double  eadd(EPNODE *), esubtr(EPNODE *),
41 >               emult(EPNODE *), edivi(EPNODE *),
42 >               epow(EPNODE *);
43 > static double  ebotch(EPNODE *);
44  
45 < #ifdef  DCL_ATOF
46 < extern double  atof();
50 < #endif
45 > unsigned int  esupport =                /* what to support */
46 >                E_VARIABLE | E_FUNCTION ;
47  
48   int  nextc;                             /* lookahead character */
49  
50 < double  (*eoper[])() = {                /* expression operations */
50 > double  (*eoper[])(EPNODE *) = {        /* expression operations */
51          ebotch,
56 #ifdef  VARIABLE
52          evariable,
58 #else
59        ebotch,
60 #endif
53          enumber,
54          euminus,
63 #ifdef  INCHAN
55          echannel,
65 #else
66        ebotch,
67 #endif
68 #ifdef  FUNCTION
56          efunc,
57          eargument,
71 #else
58          ebotch,
59          ebotch,
74 #endif
75        ebotch,
76        ebotch,
60          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
61          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62          emult,
# Line 99 | Line 82 | static int  linepos;                   /* position in buffer */
82  
83  
84   EPNODE *
85 < eparse(expr)                    /* parse an expression string */
86 < char  *expr;
85 > eparse(                 /* parse an expression string */
86 >    char  *expr
87 > )
88   {
89      EPNODE  *ep;
90  
91      initstr(expr, NULL, 0);
108 #if  defined(VARIABLE) && defined(FUNCTION)
92      curfunc = NULL;
110 #endif
93      ep = getE1();
94      if (nextc != EOF)
95          syntax("unexpected character");
# Line 116 | Line 98 | char  *expr;
98  
99  
100   double
101 < eval(expr)                      /* evaluate an expression string */
102 < char  *expr;
101 > eval(                   /* evaluate an expression string */
102 >    char  *expr
103 > )
104   {
105      register EPNODE  *ep;
106      double  rval;
# Line 129 | Line 112 | char  *expr;
112   }
113  
114  
115 < epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
116 < register EPNODE  *ep1, *ep2;
115 > int
116 > epcmp(                  /* compare two expressions for equivalence */
117 >    register EPNODE  *ep1,
118 >    register EPNODE  *ep2
119 > )
120   {
121          double  d;
122  
# Line 146 | Line 132 | register EPNODE  *ep1, *ep2;
132                  if (ep2->v.num == 0)
133                          return(ep1->v.num != 0);
134                  d = ep1->v.num / ep2->v.num;
135 <                return(d > 1.000000000001 | d < 0.999999999999);
135 >                return((d > 1.000000000001) | (d < 0.999999999999));
136  
137          case CHAN:
138          case ARG:
# Line 176 | Line 162 | register EPNODE  *ep1, *ep2;
162   }
163  
164  
165 < epfree(epar)                    /* free a parse tree */
166 < register EPNODE  *epar;
165 > void
166 > epfree(                 /* free a parse tree */
167 >    register EPNODE      *epar
168 > )
169   {
170      register EPNODE  *ep;
171  
172      switch (epar->type) {
173  
186 #if  defined(VARIABLE) || defined(FUNCTION)
174          case VAR:
175              varfree(epar->v.ln);
176              break;
# Line 191 | Line 178 | register EPNODE         *epar;
178          case SYM:
179              freestr(epar->v.name);
180              break;
194 #endif
181  
182          case NUM:
183          case CHAN:
# Line 212 | Line 198 | register EPNODE         *epar;
198   }
199  
200                                  /* the following used to be a switch */
215 #ifdef  FUNCTION
201   static double
202 < eargument(ep)
203 < EPNODE  *ep;
202 > eargument(
203 >    EPNODE      *ep
204 > )
205   {
206      return(argument(ep->v.chan));
207   }
222 #endif
208  
209   static double
210 < enumber(ep)
211 < EPNODE  *ep;
210 > enumber(
211 >    EPNODE      *ep
212 > )
213   {
214      return(ep->v.num);
215   }
216  
217   static double
218 < euminus(ep)
219 < EPNODE  *ep;
218 > euminus(
219 >    EPNODE      *ep
220 > )
221   {
222      register EPNODE  *ep1 = ep->v.kid;
223  
224      return(-evalue(ep1));
225   }
226  
240 #ifdef  INCHAN
227   static double
228 < echannel(ep)
229 < EPNODE  *ep;
228 > echannel(
229 >    EPNODE      *ep
230 > )
231   {
232      return(chanvalue(ep->v.chan));
233   }
247 #endif
234  
235   static double
236 < eadd(ep)
237 < EPNODE  *ep;
236 > eadd(
237 >    EPNODE      *ep
238 > )
239   {
240      register EPNODE  *ep1 = ep->v.kid;
241  
# Line 256 | Line 243 | EPNODE *ep;
243   }
244  
245   static double
246 < esubtr(ep)
247 < EPNODE  *ep;
246 > esubtr(
247 >    EPNODE      *ep
248 > )
249   {
250      register EPNODE  *ep1 = ep->v.kid;
251  
# Line 265 | Line 253 | EPNODE *ep;
253   }
254  
255   static double
256 < emult(ep)
257 < EPNODE  *ep;
256 > emult(
257 >    EPNODE      *ep
258 > )
259   {
260      register EPNODE  *ep1 = ep->v.kid;
261  
# Line 274 | Line 263 | EPNODE *ep;
263   }
264  
265   static double
266 < edivi(ep)
267 < EPNODE  *ep;
266 > edivi(
267 >    EPNODE      *ep
268 > )
269   {
270      register EPNODE  *ep1 = ep->v.kid;
271      double  d;
# Line 290 | Line 280 | EPNODE *ep;
280   }
281  
282   static double
283 < epow(ep)
284 < EPNODE  *ep;
283 > epow(
284 >    EPNODE      *ep
285 > )
286   {
287      register EPNODE  *ep1 = ep->v.kid;
288      double  d;
# Line 304 | Line 295 | EPNODE *ep;
295      if (!finite(d))
296          errno = EDOM;
297   #endif
298 <    if (errno) {
298 >    if (errno == EDOM || errno == ERANGE) {
299          wputs("Illegal power\n");
300          return(0.0);
301      }
# Line 313 | Line 304 | EPNODE *ep;
304   }
305  
306   static double
307 < ebotch(ep)
308 < EPNODE  *ep;
307 > ebotch(
308 >    EPNODE      *ep
309 > )
310   {
311      eputs("Bad expression!\n");
312      quit(1);
313 +        return 0.0; /* pro forma return */
314   }
315  
316  
317   EPNODE *
318 < ekid(ep, n)                     /* return pointer to a node's nth kid */
319 < register EPNODE  *ep;
320 < register int  n;
318 > ekid(                   /* return pointer to a node's nth kid */
319 >    register EPNODE      *ep,
320 >    register int  n
321 > )
322   {
323  
324      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
# Line 336 | Line 330 | register int  n;
330  
331  
332   int
333 < nekids(ep)                      /* return # of kids for node ep */
334 < register EPNODE  *ep;
333 > nekids(                 /* return # of kids for node ep */
334 >    register EPNODE      *ep
335 > )
336   {
337      register int  n = 0;
338  
# Line 348 | Line 343 | register EPNODE         *ep;
343   }
344  
345  
346 < initfile(fp, fn, ln)            /* prepare input file */
347 < FILE  *fp;
348 < char  *fn;
349 < int  ln;
346 > void
347 > initfile(               /* prepare input file */
348 >    FILE  *fp,
349 >    char  *fn,
350 >    int  ln
351 > )
352   {
353      static char  inpbuf[MAXLINE];
354  
# Line 365 | Line 362 | int  ln;
362   }
363  
364  
365 < initstr(s, fn, ln)              /* prepare input string */
366 < char  *s;
367 < char  *fn;
368 < int  ln;
365 > void
366 > initstr(                /* prepare input string */
367 >    char  *s,
368 >    char  *fn,
369 >    int  ln
370 > )
371   {
372      infp = NULL;
373      infile = fn;
# Line 379 | Line 378 | int  ln;
378   }
379  
380  
381 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
382 < char  **fnp;
383 < int  *lnp;
384 < char  **spp;
385 < FILE  **fpp;
381 > void
382 > getscanpos(     /* return current scan position */
383 >    char  **fnp,
384 >    int  *lnp,
385 >    char  **spp,
386 >    FILE  **fpp
387 > )
388   {
389      if (fnp != NULL) *fnp = infile;
390      if (lnp != NULL) *lnp = lineno;
# Line 393 | Line 394 | FILE  **fpp;
394  
395  
396   int
397 < scan()                          /* scan next character, return literal next */
397 > scan(void)              /* scan next character, return literal next */
398   {
399      register int  lnext = 0;
400  
# Line 425 | Line 426 | scan()                         /* scan next character, return literal next
426  
427  
428   char *
429 < long2ascii(l)                         /* convert long to ascii */
430 < long  l;
429 > long2ascii(                           /* convert long to ascii */
430 >    long  l
431 > )
432   {
433      static char  buf[16];
434      register char  *cp;
# Line 450 | Line 452 | long  l;
452   }
453  
454  
455 < syntax(err)                     /* report syntax error and quit */
456 < char  *err;
455 > void
456 > syntax(                 /* report syntax error and quit */
457 >    char  *err
458 > )
459   {
460      register int  i;
461  
# Line 475 | Line 479 | char  *err;
479   }
480  
481  
482 < addekid(ep, ekid)                       /* add a child to ep */
483 < register EPNODE  *ep;
484 < EPNODE  *ekid;
482 > void
483 > addekid(                        /* add a child to ep */
484 >    register EPNODE      *ep,
485 >    EPNODE      *ekid
486 > )
487   {
488      if (ep->v.kid == NULL)
489          ep->v.kid = ekid;
# Line 490 | Line 496 | EPNODE *ekid;
496   }
497  
498  
493 #if  defined(VARIABLE) || defined(FUNCTION)
499   char *
500 < getname()                       /* scan an identifier */
500 > getname(void)                   /* scan an identifier */
501   {
502 <    static char  str[MAXWORD+1];
502 >    static char  str[RMAXWORD+1];
503      register int  i, lnext;
504  
505      lnext = nextc;
506 <    for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
506 >    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
507          str[i] = lnext;
508      str[i] = '\0';
509      while (isid(lnext))         /* skip rest of name */
# Line 506 | Line 511 | getname()                      /* scan an identifier */
511  
512      return(str);
513   }
509 #endif
514  
515  
516   int
517 < getinum()                       /* scan a positive integer */
517 > getinum(void)                   /* scan a positive integer */
518   {
519      register int  n, lnext;
520  
# Line 525 | Line 529 | getinum()                      /* scan a positive integer */
529  
530  
531   double
532 < getnum()                        /* scan a positive float */
532 > getnum(void)                    /* scan a positive float */
533   {
534      register int  i, lnext;
535 <    char  str[MAXWORD+1];
535 >    char  str[RMAXWORD+1];
536  
537      i = 0;
538      lnext = nextc;
539 <    while (isdigit(lnext) && i < MAXWORD) {
539 >    while (isdigit(lnext) && i < RMAXWORD) {
540          str[i++] = lnext;
541          lnext = scan();
542      }
543 <    if (lnext == '.' && i < MAXWORD) {
543 >    if (lnext == '.' && i < RMAXWORD) {
544          str[i++] = lnext;
545          lnext = scan();
546 <        while (isdigit(lnext) && i < MAXWORD) {
546 >        if (i == 1 && !isdigit(lnext))
547 >            syntax("badly formed number");
548 >        while (isdigit(lnext) && i < RMAXWORD) {
549              str[i++] = lnext;
550              lnext = scan();
551          }
552      }
553 <    if ((lnext == 'e' || lnext == 'E') && i < MAXWORD) {
553 >    if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
554          str[i++] = lnext;
555          lnext = scan();
556 <        if ((lnext == '-' || lnext == '+') && i < MAXWORD) {
556 >        if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
557              str[i++] = lnext;
558              lnext = scan();
559          }
560 <        while (isdigit(lnext) && i < MAXWORD) {
560 >        if (!isdigit(lnext))
561 >            syntax("missing exponent");
562 >        while (isdigit(lnext) && i < RMAXWORD) {
563              str[i++] = lnext;
564              lnext = scan();
565          }
# Line 563 | Line 571 | getnum()                       /* scan a positive float */
571  
572  
573   EPNODE *
574 < getE1()                         /* E1 -> E1 ADDOP E2 */
574 > getE1(void)                             /* E1 -> E1 ADDOP E2 */
575                                  /*       E2 */
576   {
577      register EPNODE  *ep1, *ep2;
# Line 575 | Line 583 | getE1()                                /* E1 -> E1 ADDOP E2 */
583          scan();
584          addekid(ep2, ep1);
585          addekid(ep2, getE2());
586 < #ifdef  RCONST
587 <        if (ep1->type == NUM && ep1->sibling->type == NUM)
586 >        if (esupport&E_RCONST &&
587 >                        ep1->type == NUM && ep1->sibling->type == NUM)
588                  ep2 = rconst(ep2);
581 #endif
589          ep1 = ep2;
590      }
591      return(ep1);
# Line 586 | Line 593 | getE1()                                /* E1 -> E1 ADDOP E2 */
593  
594  
595   EPNODE *
596 < getE2()                         /* E2 -> E2 MULOP E3 */
596 > getE2(void)                             /* E2 -> E2 MULOP E3 */
597                                  /*       E3 */
598   {
599      register EPNODE  *ep1, *ep2;
# Line 598 | Line 605 | getE2()                                /* E2 -> E2 MULOP E3 */
605          scan();
606          addekid(ep2, ep1);
607          addekid(ep2, getE3());
608 < #ifdef  RCONST
609 <        if (ep1->type == NUM && ep1->sibling->type == NUM)
608 >        if (esupport&E_RCONST &&
609 >                        ep1->type == NUM && ep1->sibling->type == NUM)
610                  ep2 = rconst(ep2);
604 #endif
611          ep1 = ep2;
612      }
613      return(ep1);
# Line 609 | Line 615 | getE2()                                /* E2 -> E2 MULOP E3 */
615  
616  
617   EPNODE *
618 < getE3()                         /* E3 -> E4 ^ E3 */
618 > getE3(void)                             /* E3 -> E4 ^ E3 */
619                                  /*       E4 */
620   {
621      register EPNODE  *ep1, *ep2;
# Line 621 | Line 627 | getE3()                                /* E3 -> E4 ^ E3 */
627          scan();
628          addekid(ep2, ep1);
629          addekid(ep2, getE3());
630 < #ifdef  RCONST
631 <        if (ep1->type == NUM && ep1->sibling->type == NUM)
630 >        if (esupport&E_RCONST &&
631 >                        ep1->type == NUM && ep1->sibling->type == NUM)
632                  ep2 = rconst(ep2);
627 #endif
633          return(ep2);
634      }
635      return(ep1);
# Line 632 | Line 637 | getE3()                                /* E3 -> E4 ^ E3 */
637  
638  
639   EPNODE *
640 < getE4()                         /* E4 -> ADDOP E5 */
640 > getE4(void)                             /* E4 -> ADDOP E5 */
641                                  /*       E5 */
642   {
643      register EPNODE  *ep1, *ep2;
# Line 660 | Line 665 | getE4()                                /* E4 -> ADDOP E5 */
665  
666  
667   EPNODE *
668 < getE5()                         /* E5 -> (E1) */
668 > getE5(void)                     /* E5 -> (E1) */
669                                  /*       VAR */
670                                  /*       NUM */
671                                  /*       $N */
672                                  /*       FUNC(E1,..) */
673                                  /*       ARG */
674   {
675 <    int  i;
676 <    char  *nam;
677 <    register EPNODE  *ep1, *ep2;
675 >        int      i;
676 >        char  *nam;
677 >        register EPNODE  *ep1, *ep2;
678  
679 <    if (nextc == '(') {
680 <        scan();
681 <        ep1 = getE1();
682 <        if (nextc != ')')
683 <            syntax("')' expected");
684 <        scan();
685 <        return(ep1);
686 <    }
679 >        if (nextc == '(') {
680 >                scan();
681 >                ep1 = getE1();
682 >                if (nextc != ')')
683 >                        syntax("')' expected");
684 >                scan();
685 >                return(ep1);
686 >        }
687  
688 < #ifdef  INCHAN
689 <    if (nextc == '$') {
690 <        scan();
691 <        ep1 = newnode();
692 <        ep1->type = CHAN;
693 <        ep1->v.chan = getinum();
694 <        return(ep1);
690 <    }
691 < #endif
688 >        if (esupport&E_INCHAN && nextc == '$') {
689 >                scan();
690 >                ep1 = newnode();
691 >                ep1->type = CHAN;
692 >                ep1->v.chan = getinum();
693 >                return(ep1);
694 >        }
695  
696 < #if  defined(VARIABLE) || defined(FUNCTION)
697 <    if (isalpha(nextc) || nextc == CNTXMARK) {
698 <        nam = getname();
699 < #if  defined(VARIABLE) && defined(FUNCTION)
700 <        ep1 = NULL;
701 <        if (curfunc != NULL)
702 <            for (i = 1, ep2 = curfunc->v.kid->sibling;
703 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
704 <                if (!strcmp(ep2->v.name, nam)) {
705 <                    ep1 = newnode();
706 <                    ep1->type = ARG;
707 <                    ep1->v.chan = i;
708 <                    break;
696 >        if (esupport&(E_VARIABLE|E_FUNCTION) &&
697 >                        (isalpha(nextc) || nextc == CNTXMARK)) {
698 >                nam = getname();
699 >                ep1 = NULL;
700 >                if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
701 >                                && curfunc != NULL)
702 >                        for (i = 1, ep2 = curfunc->v.kid->sibling;
703 >                                        ep2 != NULL; i++, ep2 = ep2->sibling)
704 >                                if (!strcmp(ep2->v.name, nam)) {
705 >                                        ep1 = newnode();
706 >                                        ep1->type = ARG;
707 >                                        ep1->v.chan = i;
708 >                                        break;
709 >                                }
710 >                if (ep1 == NULL) {
711 >                        ep1 = newnode();
712 >                        ep1->type = VAR;
713 >                        ep1->v.ln = varinsert(nam);
714                  }
715 <        if (ep1 == NULL)
716 < #endif
717 <        {
718 <            ep1 = newnode();
719 <            ep1->type = VAR;
720 <            ep1->v.ln = varinsert(nam);
715 >                if (esupport&E_FUNCTION && nextc == '(') {
716 >                        ep2 = newnode();
717 >                        ep2->type = FUNC;
718 >                        addekid(ep2, ep1);
719 >                        ep1 = ep2;
720 >                        do {
721 >                                scan();
722 >                                addekid(ep1, getE1());
723 >                        } while (nextc == ',');
724 >                        if (nextc != ')')
725 >                                syntax("')' expected");
726 >                        scan();
727 >                } else if (!(esupport&E_VARIABLE))
728 >                        syntax("'(' expected");
729 >                if (esupport&E_RCONST && isconstvar(ep1))
730 >                        ep1 = rconst(ep1);
731 >                return(ep1);
732          }
714 #ifdef  FUNCTION
715        if (nextc == '(') {
716            ep2 = newnode();
717            ep2->type = FUNC;
718            addekid(ep2, ep1);
719            ep1 = ep2;
720            do {
721                scan();
722                addekid(ep1, getE1());
723            } while (nextc == ',');
724            if (nextc != ')')
725                syntax("')' expected");
726            scan();
727        }
728 #ifndef  VARIABLE
729        else
730            syntax("'(' expected");
731 #endif
732 #endif
733 #ifdef  RCONST
734        if (isconstvar(ep1))
735            ep1 = rconst(ep1);
736 #endif
737        return(ep1);
738    }
739 #endif
733  
734 <    if (isdecimal(nextc)) {
735 <        ep1 = newnode();
736 <        ep1->type = NUM;
737 <        ep1->v.num = getnum();
738 <        return(ep1);
739 <    }
740 <    syntax("unexpected character");
734 >        if (isdecimal(nextc)) {
735 >                ep1 = newnode();
736 >                ep1->type = NUM;
737 >                ep1->v.num = getnum();
738 >                return(ep1);
739 >        }
740 >        syntax("unexpected character");
741 >        return NULL; /* pro forma return */
742   }
743  
744  
751 #ifdef  RCONST
745   EPNODE *
746 < rconst(epar)                    /* reduce a constant expression */
747 < register EPNODE  *epar;
746 > rconst(                 /* reduce a constant expression */
747 >    register EPNODE      *epar
748 > )
749   {
750      register EPNODE  *ep;
751  
# Line 759 | Line 753 | register EPNODE         *epar;
753      ep->type = NUM;
754      errno = 0;
755      ep->v.num = evalue(epar);
756 <    if (errno)
756 >    if (errno == EDOM || errno == ERANGE)
757          syntax("bad constant expression");
758      epfree(epar);
759  
# Line 767 | Line 761 | register EPNODE         *epar;
761   }
762  
763  
764 < isconstvar(ep)                  /* is ep linked to a constant expression? */
765 < register EPNODE  *ep;
764 > int
765 > isconstvar(                     /* is ep linked to a constant expression? */
766 >    register EPNODE      *ep
767 > )
768   {
773 #ifdef  VARIABLE
769      register EPNODE  *ep1;
775 #ifdef  FUNCTION
770  
771 <    if (ep->type == FUNC) {
771 >    if (esupport&E_FUNCTION && ep->type == FUNC) {
772          if (!isconstfun(ep->v.kid))
773                  return(0);
774          for (ep1 = ep->v.kid->sibling; ep1 != NULL; ep1 = ep1->sibling)
# Line 782 | Line 776 | register EPNODE         *ep;
776                  return(0);
777          return(1);
778      }
785 #endif
779      if (ep->type != VAR)
780          return(0);
781      ep1 = ep->v.ln->def;
782      if (ep1 == NULL || ep1->type != ':')
783          return(0);
784 < #ifdef  FUNCTION
792 <    if (ep1->v.kid->type != SYM)
784 >    if (esupport&E_FUNCTION && ep1->v.kid->type != SYM)
785          return(0);
794 #endif
786      return(1);
796 #else
797    return(ep->type == FUNC);
798 #endif
787   }
788  
789  
790 < #if  defined(FUNCTION) && defined(VARIABLE)
791 < isconstfun(ep)                  /* is ep linked to a constant function? */
792 < register EPNODE  *ep;
790 > int
791 > isconstfun(                     /* is ep linked to a constant function? */
792 >    register EPNODE      *ep
793 > )
794   {
795      register EPNODE  *dp;
796      register LIBR  *lp;
797  
798      if (ep->type != VAR)
799          return(0);
800 <    if ((dp = ep->v.ln->def) != NULL && dp->v.kid->type == FUNC)
801 <        return(dp->type == ':');
800 >    if ((dp = ep->v.ln->def) != NULL) {
801 >        if (dp->v.kid->type == FUNC)
802 >            return(dp->type == ':');
803 >        else
804 >            return(0);          /* don't identify masked library functions */
805 >    }
806      if ((lp = ep->v.ln->lib) != NULL)
807          return(lp->atyp == ':');
808      return(0);
809   }
817 #endif
818 #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines