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.18 by greg, Sat Feb 22 02:07:21 2003 UTC vs.
Revision 2.30 by greg, Tue May 17 17:51:51 2005 UTC

# Line 17 | Line 17 | static const char      RCSid[] = "$Id$";
17   *  2/19/03     Eliminated conditional compiles in favor of esupport extern.
18   */
19  
20 < /* ====================================================================
21 < * The Radiance Software License, Version 1.0
22 < *
23 < * Copyright (c) 1990 - 2002 The Regents of the University of California,
24 < * through Lawrence Berkeley National Laboratory.   All rights reserved.
25 < *
26 < * Redistribution and use in source and binary forms, with or without
27 < * modification, are permitted provided that the following conditions
28 < * are met:
29 < *
30 < * 1. Redistributions of source code must retain the above copyright
31 < *         notice, this list of conditions and the following disclaimer.
32 < *
33 < * 2. Redistributions in binary form must reproduce the above copyright
34 < *       notice, this list of conditions and the following disclaimer in
35 < *       the documentation and/or other materials provided with the
36 < *       distribution.
37 < *
38 < * 3. The end-user documentation included with the redistribution,
39 < *           if any, must include the following acknowledgment:
40 < *             "This product includes Radiance software
41 < *                 (http://radsite.lbl.gov/)
42 < *                 developed by the Lawrence Berkeley National Laboratory
43 < *               (http://www.lbl.gov/)."
44 < *       Alternately, this acknowledgment may appear in the software itself,
45 < *       if and wherever such third-party acknowledgments normally appear.
46 < *
47 < * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
48 < *       and "The Regents of the University of California" must
49 < *       not be used to endorse or promote products derived from this
50 < *       software without prior written permission. For written
51 < *       permission, please contact [email protected].
52 < *
53 < * 5. Products derived from this software may not be called "Radiance",
54 < *       nor may "Radiance" appear in their name, without prior written
55 < *       permission of Lawrence Berkeley National Laboratory.
56 < *
57 < * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
58 < * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
59 < * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60 < * DISCLAIMED.   IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
61 < * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
62 < * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
63 < * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
64 < * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65 < * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
66 < * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
67 < * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 < * SUCH DAMAGE.
69 < * ====================================================================
70 < *
71 < * This software consists of voluntary contributions made by many
72 < * individuals on behalf of Lawrence Berkeley National Laboratory.   For more
73 < * information on Lawrence Berkeley National Laboratory, please see
74 < * <http://www.lbl.gov/>.
75 < */
20 > #include "copyright.h"
21  
22   #include  <stdio.h>
23 <
23 > #include  <string.h>
24   #include  <ctype.h>
80
25   #include  <errno.h>
82
26   #include  <math.h>
84
27   #include  <stdlib.h>
28  
29 + #include  "rtmisc.h"
30 + #include  "rtio.h"
31 + #include  "rterror.h"
32   #include  "calcomp.h"
33  
34   #define  MAXLINE        256             /* maximum line length */
# Line 92 | Line 37 | static const char      RCSid[] = "$Id$";
37  
38   #define  isdecimal(c)   (isdigit(c) || (c) == '.')
39  
40 < static double  euminus(), eargument(), enumber();
41 < static double  echannel();
42 < static double  eadd(), esubtr(), emult(), edivi(), epow();
43 < static double  ebotch();
40 > static double  euminus(EPNODE *), eargument(EPNODE *), enumber(EPNODE *);
41 > static double  echannel(EPNODE *);
42 > static double  eadd(EPNODE *), esubtr(EPNODE *),
43 >               emult(EPNODE *), edivi(EPNODE *),
44 >               epow(EPNODE *);
45 > static double  ebotch(EPNODE *);
46  
47   unsigned int  esupport =                /* what to support */
48 <                E_VARIABLE | E_FUNCTION | E_REDEFW;
48 >                E_VARIABLE | E_FUNCTION ;
49  
50 + int  eofc = 0;                          /* optional end-of-file character */
51   int  nextc;                             /* lookahead character */
52  
53 < double  (*eoper[])() = {                /* expression operations */
53 > double  (*eoper[])(EPNODE *) = {        /* expression operations */
54          ebotch,
55          evariable,
56          enumber,
# Line 137 | Line 85 | static int  linepos;                   /* position in buffer */
85  
86  
87   EPNODE *
88 < eparse(expr)                    /* parse an expression string */
89 < char  *expr;
88 > eparse(                 /* parse an expression string */
89 >    char  *expr
90 > )
91   {
92      EPNODE  *ep;
93  
# Line 152 | Line 101 | char  *expr;
101  
102  
103   double
104 < eval(expr)                      /* evaluate an expression string */
105 < char  *expr;
104 > eval(                   /* evaluate an expression string */
105 >    char  *expr
106 > )
107   {
108      register EPNODE  *ep;
109      double  rval;
# Line 166 | Line 116 | char  *expr;
116  
117  
118   int
119 < epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
120 < register EPNODE  *ep1, *ep2;
119 > epcmp(                  /* compare two expressions for equivalence */
120 >    register EPNODE  *ep1,
121 >    register EPNODE  *ep2
122 > )
123   {
124          double  d;
125  
# Line 183 | Line 135 | register EPNODE  *ep1, *ep2;
135                  if (ep2->v.num == 0)
136                          return(ep1->v.num != 0);
137                  d = ep1->v.num / ep2->v.num;
138 <                return(d > 1.000000000001 | d < 0.999999999999);
138 >                return((d > 1.000000000001) | (d < 0.999999999999));
139  
140          case CHAN:
141          case ARG:
# Line 214 | Line 166 | register EPNODE  *ep1, *ep2;
166  
167  
168   void
169 < epfree(epar)                    /* free a parse tree */
170 < register EPNODE  *epar;
169 > epfree(                 /* free a parse tree */
170 >    register EPNODE      *epar
171 > )
172   {
173      register EPNODE  *ep;
174  
# Line 249 | Line 202 | register EPNODE         *epar;
202  
203                                  /* the following used to be a switch */
204   static double
205 < eargument(ep)
206 < EPNODE  *ep;
205 > eargument(
206 >    EPNODE      *ep
207 > )
208   {
209      return(argument(ep->v.chan));
210   }
211  
212   static double
213 < enumber(ep)
214 < EPNODE  *ep;
213 > enumber(
214 >    EPNODE      *ep
215 > )
216   {
217      return(ep->v.num);
218   }
219  
220   static double
221 < euminus(ep)
222 < EPNODE  *ep;
221 > euminus(
222 >    EPNODE      *ep
223 > )
224   {
225      register EPNODE  *ep1 = ep->v.kid;
226  
# Line 272 | Line 228 | EPNODE *ep;
228   }
229  
230   static double
231 < echannel(ep)
232 < EPNODE  *ep;
231 > echannel(
232 >    EPNODE      *ep
233 > )
234   {
235      return(chanvalue(ep->v.chan));
236   }
237  
238   static double
239 < eadd(ep)
240 < EPNODE  *ep;
239 > eadd(
240 >    EPNODE      *ep
241 > )
242   {
243      register EPNODE  *ep1 = ep->v.kid;
244  
# Line 288 | Line 246 | EPNODE *ep;
246   }
247  
248   static double
249 < esubtr(ep)
250 < EPNODE  *ep;
249 > esubtr(
250 >    EPNODE      *ep
251 > )
252   {
253      register EPNODE  *ep1 = ep->v.kid;
254  
# Line 297 | Line 256 | EPNODE *ep;
256   }
257  
258   static double
259 < emult(ep)
260 < EPNODE  *ep;
259 > emult(
260 >    EPNODE      *ep
261 > )
262   {
263      register EPNODE  *ep1 = ep->v.kid;
264  
# Line 306 | Line 266 | EPNODE *ep;
266   }
267  
268   static double
269 < edivi(ep)
270 < EPNODE  *ep;
269 > edivi(
270 >    EPNODE      *ep
271 > )
272   {
273      register EPNODE  *ep1 = ep->v.kid;
274      double  d;
# Line 322 | Line 283 | EPNODE *ep;
283   }
284  
285   static double
286 < epow(ep)
287 < EPNODE  *ep;
286 > epow(
287 >    EPNODE      *ep
288 > )
289   {
290      register EPNODE  *ep1 = ep->v.kid;
291      double  d;
# Line 336 | Line 298 | EPNODE *ep;
298      if (!finite(d))
299          errno = EDOM;
300   #endif
301 <    if (errno) {
301 >    if (errno == EDOM || errno == ERANGE) {
302          wputs("Illegal power\n");
303          return(0.0);
304      }
# Line 345 | Line 307 | EPNODE *ep;
307   }
308  
309   static double
310 < ebotch(ep)
311 < EPNODE  *ep;
310 > ebotch(
311 >    EPNODE      *ep
312 > )
313   {
314      eputs("Bad expression!\n");
315      quit(1);
316 +        return 0.0; /* pro forma return */
317   }
318  
319  
320   EPNODE *
321 < ekid(ep, n)                     /* return pointer to a node's nth kid */
322 < register EPNODE  *ep;
323 < register int  n;
321 > ekid(                   /* return pointer to a node's nth kid */
322 >    register EPNODE      *ep,
323 >    register int  n
324 > )
325   {
326  
327      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
# Line 368 | Line 333 | register int  n;
333  
334  
335   int
336 < nekids(ep)                      /* return # of kids for node ep */
337 < register EPNODE  *ep;
336 > nekids(                 /* return # of kids for node ep */
337 >    register EPNODE      *ep
338 > )
339   {
340      register int  n = 0;
341  
# Line 381 | Line 347 | register EPNODE         *ep;
347  
348  
349   void
350 < initfile(fp, fn, ln)            /* prepare input file */
351 < FILE  *fp;
352 < char  *fn;
353 < int  ln;
350 > initfile(               /* prepare input file */
351 >    FILE  *fp,
352 >    char  *fn,
353 >    int  ln
354 > )
355   {
356      static char  inpbuf[MAXLINE];
357  
# Line 399 | Line 366 | int  ln;
366  
367  
368   void
369 < initstr(s, fn, ln)              /* prepare input string */
370 < char  *s;
371 < char  *fn;
372 < int  ln;
369 > initstr(                /* prepare input string */
370 >    char  *s,
371 >    char  *fn,
372 >    int  ln
373 > )
374   {
375      infp = NULL;
376      infile = fn;
# Line 414 | Line 382 | int  ln;
382  
383  
384   void
385 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
386 < char  **fnp;
387 < int  *lnp;
388 < char  **spp;
389 < FILE  **fpp;
385 > getscanpos(     /* return current scan position */
386 >    char  **fnp,
387 >    int  *lnp,
388 >    char  **spp,
389 >    FILE  **fpp
390 > )
391   {
392      if (fnp != NULL) *fnp = infile;
393      if (lnp != NULL) *lnp = lineno;
# Line 428 | Line 397 | FILE  **fpp;
397  
398  
399   int
400 < scan()                          /* scan next character, return literal next */
400 > scan(void)              /* scan next character, return literal next */
401   {
402      register int  lnext = 0;
403  
# Line 445 | Line 414 | scan()                         /* scan next character, return literal next
414              nextc = linbuf[linepos++];
415          if (!lnext)
416                  lnext = nextc;
417 +        if (nextc == eofc) {
418 +                nextc = EOF;
419 +                break;
420 +        }
421          if (nextc == '{') {
422              scan();
423              while (nextc != '}')
# Line 460 | Line 433 | scan()                         /* scan next character, return literal next
433  
434  
435   char *
436 < long2ascii(l)                         /* convert long to ascii */
437 < long  l;
436 > long2ascii(                           /* convert long to ascii */
437 >    long  l
438 > )
439   {
440      static char  buf[16];
441      register char  *cp;
# Line 486 | Line 460 | long  l;
460  
461  
462   void
463 < syntax(err)                     /* report syntax error and quit */
464 < char  *err;
463 > syntax(                 /* report syntax error and quit */
464 >    char  *err
465 > )
466   {
467      register int  i;
468  
# Line 512 | Line 487 | char  *err;
487  
488  
489   void
490 < addekid(ep, ekid)                       /* add a child to ep */
491 < register EPNODE  *ep;
492 < EPNODE  *ekid;
490 > addekid(                        /* add a child to ep */
491 >    register EPNODE      *ep,
492 >    EPNODE      *ekid
493 > )
494   {
495      if (ep->v.kid == NULL)
496          ep->v.kid = ekid;
# Line 528 | Line 504 | EPNODE *ekid;
504  
505  
506   char *
507 < getname()                       /* scan an identifier */
507 > getname(void)                   /* scan an identifier */
508   {
509 <    static char  str[MAXWORD+1];
509 >    static char  str[RMAXWORD+1];
510      register int  i, lnext;
511  
512      lnext = nextc;
513 <    for (i = 0; i < MAXWORD && isid(lnext); i++, lnext = scan())
513 >    for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
514          str[i] = lnext;
515      str[i] = '\0';
516      while (isid(lnext))         /* skip rest of name */
# Line 545 | Line 521 | getname()                      /* scan an identifier */
521  
522  
523   int
524 < getinum()                       /* scan a positive integer */
524 > getinum(void)                   /* scan a positive integer */
525   {
526      register int  n, lnext;
527  
# Line 560 | Line 536 | getinum()                      /* scan a positive integer */
536  
537  
538   double
539 < getnum()                        /* scan a positive float */
539 > getnum(void)                    /* scan a positive float */
540   {
541      register int  i, lnext;
542 <    char  str[MAXWORD+1];
542 >    char  str[RMAXWORD+1];
543  
544      i = 0;
545      lnext = nextc;
546 <    while (isdigit(lnext) && i < MAXWORD) {
546 >    while (isdigit(lnext) && i < RMAXWORD) {
547          str[i++] = lnext;
548          lnext = scan();
549      }
550 <    if (lnext == '.' && i < MAXWORD) {
550 >    if (lnext == '.' && i < RMAXWORD) {
551          str[i++] = lnext;
552          lnext = scan();
553          if (i == 1 && !isdigit(lnext))
554              syntax("badly formed number");
555 <        while (isdigit(lnext) && i < MAXWORD) {
555 >        while (isdigit(lnext) && i < RMAXWORD) {
556              str[i++] = lnext;
557              lnext = scan();
558          }
559      }
560 <    if ((lnext == 'e' | lnext == 'E') && i < MAXWORD) {
560 >    if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
561          str[i++] = lnext;
562          lnext = scan();
563 <        if ((lnext == '-' | lnext == '+') && i < MAXWORD) {
563 >        if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
564              str[i++] = lnext;
565              lnext = scan();
566          }
567          if (!isdigit(lnext))
568              syntax("missing exponent");
569 <        while (isdigit(lnext) && i < MAXWORD) {
569 >        while (isdigit(lnext) && i < RMAXWORD) {
570              str[i++] = lnext;
571              lnext = scan();
572          }
# Line 602 | Line 578 | getnum()                       /* scan a positive float */
578  
579  
580   EPNODE *
581 < getE1()                         /* E1 -> E1 ADDOP E2 */
581 > getE1(void)                             /* E1 -> E1 ADDOP E2 */
582                                  /*       E2 */
583   {
584      register EPNODE  *ep1, *ep2;
# Line 624 | Line 600 | getE1()                                /* E1 -> E1 ADDOP E2 */
600  
601  
602   EPNODE *
603 < getE2()                         /* E2 -> E2 MULOP E3 */
603 > getE2(void)                             /* E2 -> E2 MULOP E3 */
604                                  /*       E3 */
605   {
606      register EPNODE  *ep1, *ep2;
# Line 646 | Line 622 | getE2()                                /* E2 -> E2 MULOP E3 */
622  
623  
624   EPNODE *
625 < getE3()                         /* E3 -> E4 ^ E3 */
625 > getE3(void)                             /* E3 -> E4 ^ E3 */
626                                  /*       E4 */
627   {
628      register EPNODE  *ep1, *ep2;
# Line 668 | Line 644 | getE3()                                /* E3 -> E4 ^ E3 */
644  
645  
646   EPNODE *
647 < getE4()                         /* E4 -> ADDOP E5 */
647 > getE4(void)                             /* E4 -> ADDOP E5 */
648                                  /*       E5 */
649   {
650      register EPNODE  *ep1, *ep2;
# Line 696 | Line 672 | getE4()                                /* E4 -> ADDOP E5 */
672  
673  
674   EPNODE *
675 < getE5()                         /* E5 -> (E1) */
675 > getE5(void)                     /* E5 -> (E1) */
676                                  /*       VAR */
677                                  /*       NUM */
678                                  /*       $N */
679                                  /*       FUNC(E1,..) */
680                                  /*       ARG */
681   {
682 <    int  i;
683 <    char  *nam;
684 <    register EPNODE  *ep1, *ep2;
682 >        int      i;
683 >        char  *nam;
684 >        register EPNODE  *ep1, *ep2;
685  
686 <    if (nextc == '(') {
687 <        scan();
688 <        ep1 = getE1();
689 <        if (nextc != ')')
690 <            syntax("')' expected");
691 <        scan();
692 <        return(ep1);
693 <    }
686 >        if (nextc == '(') {
687 >                scan();
688 >                ep1 = getE1();
689 >                if (nextc != ')')
690 >                        syntax("')' expected");
691 >                scan();
692 >                return(ep1);
693 >        }
694  
695 <    if (esupport&E_INCHAN && nextc == '$') {
696 <        scan();
697 <        ep1 = newnode();
698 <        ep1->type = CHAN;
699 <        ep1->v.chan = getinum();
700 <        return(ep1);
701 <    }
695 >        if (esupport&E_INCHAN && nextc == '$') {
696 >                scan();
697 >                ep1 = newnode();
698 >                ep1->type = CHAN;
699 >                ep1->v.chan = getinum();
700 >                return(ep1);
701 >        }
702  
703 <  if (esupport&(E_VARIABLE|E_FUNCTION) &&
704 <                (isalpha(nextc) || nextc == CNTXMARK)) {
705 <      nam = getname();
706 <      ep1 = NULL;
707 <      if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
708 <                        && curfunc != NULL)
709 <            for (i = 1, ep2 = curfunc->v.kid->sibling;
710 <                                ep2 != NULL; i++, ep2 = ep2->sibling)
711 <                if (!strcmp(ep2->v.name, nam)) {
712 <                    ep1 = newnode();
713 <                    ep1->type = ARG;
714 <                    ep1->v.chan = i;
715 <                    break;
703 >        if (esupport&(E_VARIABLE|E_FUNCTION) &&
704 >                        (isalpha(nextc) || nextc == CNTXMARK)) {
705 >                nam = getname();
706 >                ep1 = NULL;
707 >                if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
708 >                                && curfunc != NULL)
709 >                        for (i = 1, ep2 = curfunc->v.kid->sibling;
710 >                                        ep2 != NULL; i++, ep2 = ep2->sibling)
711 >                                if (!strcmp(ep2->v.name, nam)) {
712 >                                        ep1 = newnode();
713 >                                        ep1->type = ARG;
714 >                                        ep1->v.chan = i;
715 >                                        break;
716 >                                }
717 >                if (ep1 == NULL) {
718 >                        ep1 = newnode();
719 >                        ep1->type = VAR;
720 >                        ep1->v.ln = varinsert(nam);
721                  }
722 <        if (ep1 == NULL) {
723 <            ep1 = newnode();
724 <            ep1->type = VAR;
725 <            ep1->v.ln = varinsert(nam);
722 >                if (esupport&E_FUNCTION && nextc == '(') {
723 >                        ep2 = newnode();
724 >                        ep2->type = FUNC;
725 >                        addekid(ep2, ep1);
726 >                        ep1 = ep2;
727 >                        do {
728 >                                scan();
729 >                                addekid(ep1, getE1());
730 >                        } while (nextc == ',');
731 >                        if (nextc != ')')
732 >                                syntax("')' expected");
733 >                        scan();
734 >                } else if (!(esupport&E_VARIABLE))
735 >                        syntax("'(' expected");
736 >                if (esupport&E_RCONST && isconstvar(ep1))
737 >                        ep1 = rconst(ep1);
738 >                return(ep1);
739          }
746        if (esupport&E_FUNCTION && nextc == '(') {
747            ep2 = newnode();
748            ep2->type = FUNC;
749            addekid(ep2, ep1);
750            ep1 = ep2;
751            do {
752                scan();
753                addekid(ep1, getE1());
754            } while (nextc == ',');
755            if (nextc != ')')
756                syntax("')' expected");
757            scan();
758        } else if (!(esupport&E_VARIABLE))
759            syntax("'(' expected");
760        if (esupport&E_RCONST && isconstvar(ep1))
761            ep1 = rconst(ep1);
762        return(ep1);
763    }
740  
741 <    if (isdecimal(nextc)) {
742 <        ep1 = newnode();
743 <        ep1->type = NUM;
744 <        ep1->v.num = getnum();
745 <        return(ep1);
746 <    }
747 <    syntax("unexpected character");
741 >        if (isdecimal(nextc)) {
742 >                ep1 = newnode();
743 >                ep1->type = NUM;
744 >                ep1->v.num = getnum();
745 >                return(ep1);
746 >        }
747 >        syntax("unexpected character");
748 >        return NULL; /* pro forma return */
749   }
750  
751  
752   EPNODE *
753 < rconst(epar)                    /* reduce a constant expression */
754 < register EPNODE  *epar;
753 > rconst(                 /* reduce a constant expression */
754 >    register EPNODE      *epar
755 > )
756   {
757      register EPNODE  *ep;
758  
# Line 782 | Line 760 | register EPNODE         *epar;
760      ep->type = NUM;
761      errno = 0;
762      ep->v.num = evalue(epar);
763 <    if (errno)
763 >    if (errno == EDOM || errno == ERANGE)
764          syntax("bad constant expression");
765      epfree(epar);
766  
# Line 791 | Line 769 | register EPNODE         *epar;
769  
770  
771   int
772 < isconstvar(ep)                  /* is ep linked to a constant expression? */
773 < register EPNODE  *ep;
772 > isconstvar(                     /* is ep linked to a constant expression? */
773 >    register EPNODE      *ep
774 > )
775   {
776      register EPNODE  *ep1;
777  
# Line 816 | Line 795 | register EPNODE         *ep;
795  
796  
797   int
798 < isconstfun(ep)                  /* is ep linked to a constant function? */
799 < register EPNODE  *ep;
798 > isconstfun(                     /* is ep linked to a constant function? */
799 >    register EPNODE      *ep
800 > )
801   {
802      register EPNODE  *dp;
803      register LIBR  *lp;
804  
805      if (ep->type != VAR)
806          return(0);
807 <    if ((dp = ep->v.ln->def) != NULL)
807 >    if ((dp = ep->v.ln->def) != NULL) {
808          if (dp->v.kid->type == FUNC)
809              return(dp->type == ':');
810          else
811              return(0);          /* don't identify masked library functions */
812 +    }
813      if ((lp = ep->v.ln->lib) != NULL)
814          return(lp->atyp == ':');
815      return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines