[BACK]Return to cond.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / make

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/usr.bin/make/cond.c between version 1.26 and 1.37

version 1.26, 2005/03/01 04:34:55 version 1.37, 2007/02/04 19:23:49
Line 152  static Token CondT(Boolean);
Line 152  static Token CondT(Boolean);
 static Token CondF(Boolean);  static Token CondF(Boolean);
 static Token CondE(Boolean);  static Token CondE(Boolean);
   
 static struct If {  static const struct If {
     const char  *form;        /* Form of if */      const char  *form;        /* Form of if */
     int         formlen;      /* Length of form */      int         formlen;      /* Length of form */
     Boolean     doNot;        /* TRUE if default function should be negated */      Boolean     doNot;        /* TRUE if default function should be negated */
     Boolean     (*defProc)(int, char *); /* Default function to apply */      Boolean     (*defProc)(int, char *); /* Default function to apply */
 } ifs[] = {  } ifs[] = {
     { "ifdef",    5,      FALSE,  CondDoDefined },      { "def",      3,      FALSE,  CondDoDefined },
     { "ifndef",   6,      TRUE,   CondDoDefined },      { "ndef",     4,      TRUE,   CondDoDefined },
     { "ifmake",   6,      FALSE,  CondDoMake },      { "make",     4,      FALSE,  CondDoMake },
     { "ifnmake",  7,      TRUE,   CondDoMake },      { "nmake",    5,      TRUE,   CondDoMake },
     { "if",       2,      FALSE,  CondDoDefined },      { "",         0,      FALSE,  CondDoDefined },
     { NULL,       0,      FALSE,  NULL }      { NULL,       0,      FALSE,  NULL }
 };  };
   
Line 172  static char    *condExpr;      /* The ex
Line 172  static char    *condExpr;      /* The ex
 static Token      condPushBack=None;    /* Single push-back token used in  static Token      condPushBack=None;    /* Single push-back token used in
                                          * parsing */                                           * parsing */
   
 #define MAXIF           64        /* greatest depth of #if'ing */  static unsigned int     cond_depth = 0;         /* current .if nesting level */
   static unsigned int     cond_min_depth = 0;     /* depth at makefile open */
 static Boolean    finalElse[MAXIF+1][MAXIF+1]; /* Seen final else (stack) */  
 static Boolean    condStack[MAXIF];     /* Stack of conditionals's values */  
 static int        condTop = MAXIF;      /* Top-most conditional */  
 static int        skipIfLevel=0;        /* Depth of skipped conditionals */  
 static Boolean    skipLine = FALSE;     /* Whether the parse module is skipping  
                                          * lines */  
   
 static int  static int
 istoken(const char *str, const char *tok, size_t len)  istoken(const char *str, const char *tok, size_t len)
Line 251  CondGetArg(char **linePtr, char **argPtr
Line 245  CondGetArg(char **linePtr, char **argPtr
          * than hitting the user with a warning message every time s/he uses           * than hitting the user with a warning message every time s/he uses
          * the word 'make' or 'defined' at the beginning of a symbol...           * the word 'make' or 'defined' at the beginning of a symbol...
          */           */
         *argPtr = cp;          *argPtr = NULL;
         return (0);          return (0);
     }      }
   
Line 265  CondGetArg(char **linePtr, char **argPtr
Line 259  CondGetArg(char **linePtr, char **argPtr
      */       */
     buf = Buf_Init(16);      buf = Buf_Init(16);
   
     while ((strchr(" \t)&|", *cp) == (char *)NULL) && (*cp != '\0')) {      while ((strchr(" \t)&|", *cp) == NULL) && (*cp != '\0')) {
         if (*cp == '$') {          if (*cp == '$') {
             /*              /*
              * Parse the variable spec and install it as part of the argument               * Parse the variable spec and install it as part of the argument
Line 275  CondGetArg(char **linePtr, char **argPtr
Line 269  CondGetArg(char **linePtr, char **argPtr
              */               */
             char        *cp2;              char        *cp2;
             int         len;              int         len;
             Boolean     doFree;              void        *freeIt;
   
             cp2 = Var_Parse(cp, VAR_CMD, TRUE, &len, &doFree);  
   
               cp2 = Var_Parse(cp, VAR_CMD, TRUE, &len, &freeIt);
             Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);              Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
             if (doFree) {              if (freeIt)
                 free(cp2);                  free(freeIt);
             }  
             cp += len;              cp += len;
         } else {          } else {
             Buf_AddByte(buf, (Byte)*cp);              Buf_AddByte(buf, (Byte)*cp);
Line 333  CondDoDefined(int argLen, char *arg)
Line 325  CondDoDefined(int argLen, char *arg)
     Boolean result;      Boolean result;
   
     arg[argLen] = '\0';      arg[argLen] = '\0';
     if (Var_Value(arg, VAR_CMD, &p1) != (char *)NULL) {      if (Var_Value(arg, VAR_CMD, &p1) != NULL) {
         result = TRUE;          result = TRUE;
     } else {      } else {
         result = FALSE;          result = FALSE;
Line 361  CondDoDefined(int argLen, char *arg)
Line 353  CondDoDefined(int argLen, char *arg)
 static int  static int
 CondStrMatch(ClientData string, ClientData pattern)  CondStrMatch(ClientData string, ClientData pattern)
 {  {
     return(!Str_Match((char *) string,(char *) pattern));      return(!Str_Match((char *)string,(char *)pattern));
 }  }
   
 /*-  /*-
Line 384  CondDoMake(int argLen, char *arg)
Line 376  CondDoMake(int argLen, char *arg)
     Boolean result;      Boolean result;
   
     arg[argLen] = '\0';      arg[argLen] = '\0';
     if (Lst_Find(create, (ClientData)arg, CondStrMatch) == NILLNODE) {      if (Lst_Find(create, arg, CondStrMatch) == NILLNODE) {
         result = FALSE;          result = FALSE;
     } else {      } else {
         result = TRUE;          result = TRUE;
Line 415  CondDoExists(int argLen, char *arg)
Line 407  CondDoExists(int argLen, char *arg)
   
     arg[argLen] = '\0';      arg[argLen] = '\0';
     path = Dir_FindFile(arg, dirSearchPath);      path = Dir_FindFile(arg, dirSearchPath);
     if (path != (char *)NULL) {      if (path != NULL) {
         result = TRUE;          result = TRUE;
         free(path);          free(path);
     } else {      } else {
         result = FALSE;          result = FALSE;
     }      }
     arg[argLen] = savec;      arg[argLen] = savec;
       if (DEBUG(COND)) {
           fprintf(debug_file, "exists(%s) result is \"%s\"\n",
                  arg, path ? path : "");
       }
     return (result);      return (result);
 }  }
   
Line 540  CondCvtArg(char *str, double *value)
Line 536  CondCvtArg(char *str, double *value)
  *      string.  This is called for the lhs and rhs of string compares.   *      string.  This is called for the lhs and rhs of string compares.
  *   *
  * Results:   * Results:
  *      Sets doFree if needed,   *      Sets freeIt if needed,
  *      Sets quoted if string was quoted,   *      Sets quoted if string was quoted,
  *      Returns NULL on error,   *      Returns NULL on error,
  *      else returns string - absent any quotes.   *      else returns string - absent any quotes.
Line 551  CondCvtArg(char *str, double *value)
Line 547  CondCvtArg(char *str, double *value)
  *   *
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
   /* coverity:[+alloc : arg-*2] */
 static char *  static char *
 CondGetString(Boolean doEval, Boolean *quoted, Boolean *doFree)  CondGetString(Boolean doEval, Boolean *quoted, void **freeIt)
 {  {
     Buffer buf;      Buffer buf;
     char *cp;      char *cp;
Line 563  CondGetString(Boolean doEval, Boolean *q
Line 560  CondGetString(Boolean doEval, Boolean *q
   
     buf = Buf_Init(0);      buf = Buf_Init(0);
     str = NULL;      str = NULL;
       *freeIt = NULL;
     *quoted = qt = *condExpr == '"' ? 1 : 0;      *quoted = qt = *condExpr == '"' ? 1 : 0;
     if (qt)      if (qt)
         condExpr++;          condExpr++;
Line 596  CondGetString(Boolean doEval, Boolean *q
Line 594  CondGetString(Boolean doEval, Boolean *q
         case '$':          case '$':
             /* if we are in quotes, then an undefined variable is ok */              /* if we are in quotes, then an undefined variable is ok */
             str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval),              str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval),
                             &len, doFree);                              &len, freeIt);
             if (str == var_Error) {              if (str == var_Error) {
                   if (*freeIt) {
                       free(*freeIt);
                       *freeIt = NULL;
                   }
                 /*                  /*
                  * Even if !doEval, we still report syntax errors, which                   * Even if !doEval, we still report syntax errors, which
                  * is what getting var_Error back with !doEval means.                   * is what getting var_Error back with !doEval means.
Line 623  CondGetString(Boolean doEval, Boolean *q
Line 625  CondGetString(Boolean doEval, Boolean *q
             for (cp = str; *cp; cp++) {              for (cp = str; *cp; cp++) {
                 Buf_AddByte(buf, (Byte)*cp);                  Buf_AddByte(buf, (Byte)*cp);
             }              }
             if (*doFree)              if (*freeIt) {
                 free(str);                  free(*freeIt);
             *doFree = FALSE;                  *freeIt = NULL;
               }
             str = NULL;                 /* not finished yet */              str = NULL;                 /* not finished yet */
             condExpr--;                 /* don't skip over next char */              condExpr--;                 /* don't skip over next char */
             break;              break;
Line 637  CondGetString(Boolean doEval, Boolean *q
Line 640  CondGetString(Boolean doEval, Boolean *q
  got_str:   got_str:
     Buf_AddByte(buf, (Byte)'\0');      Buf_AddByte(buf, (Byte)'\0');
     str = (char *)Buf_GetAll(buf, NULL);      str = (char *)Buf_GetAll(buf, NULL);
     *doFree = TRUE;      *freeIt = str;
  cleanup:   cleanup:
     Buf_Destroy(buf, FALSE);      Buf_Destroy(buf, FALSE);
     return str;      return str;
Line 702  CondToken(Boolean doEval)
Line 705  CondToken(Boolean doEval)
                 char    *lhs;                  char    *lhs;
                 char    *rhs;                  char    *rhs;
                 char    *op;                  char    *op;
                 Boolean lhsFree;                  void    *lhsFree;
                 Boolean rhsFree;                  void    *rhsFree;
                 Boolean lhsQuoted;                  Boolean lhsQuoted;
                 Boolean rhsQuoted;                  Boolean rhsQuoted;
   
                   rhs = NULL;
                 lhsFree = rhsFree = FALSE;                  lhsFree = rhsFree = FALSE;
                 lhsQuoted = rhsQuoted = FALSE;                  lhsQuoted = rhsQuoted = FALSE;
   
Line 716  CondToken(Boolean doEval)
Line 720  CondToken(Boolean doEval)
                  */                   */
                 t = Err;                  t = Err;
                 lhs = CondGetString(doEval, &lhsQuoted, &lhsFree);                  lhs = CondGetString(doEval, &lhsQuoted, &lhsFree);
                 if (!lhs)                  if (!lhs) {
                       if (lhsFree)
                           free(lhsFree);
                     return Err;                      return Err;
                   }
                 /*                  /*
                  * Skip whitespace to get to the operator                   * Skip whitespace to get to the operator
                  */                   */
Line 759  CondToken(Boolean doEval)
Line 766  CondToken(Boolean doEval)
                     goto error;                      goto error;
                 }                  }
                 rhs = CondGetString(doEval, &rhsQuoted, &rhsFree);                  rhs = CondGetString(doEval, &rhsQuoted, &rhsFree);
                 if (!rhs)                  if (!rhs) {
                       if (lhsFree)
                           free(lhsFree);
                       if (rhsFree)
                           free(rhsFree);
                     return Err;                      return Err;
                   }
 do_compare:  do_compare:
                 if (rhsQuoted || lhsQuoted) {                  if (rhsQuoted || lhsQuoted) {
 do_string_compare:  do_string_compare:
Line 771  do_string_compare:
Line 783  do_string_compare:
                     }                      }
   
                     if (DEBUG(COND)) {                      if (DEBUG(COND)) {
                         printf("lhs = \"%s\", rhs = \"%s\", op = %.2s\n",                          fprintf(debug_file, "lhs = \"%s\", rhs = \"%s\", op = %.2s\n",
                                lhs, rhs, op);                                 lhs, rhs, op);
                     }                      }
                     /*                      /*
Line 798  do_string_compare:
Line 810  do_string_compare:
                         goto do_string_compare;                          goto do_string_compare;
   
                     if (DEBUG(COND)) {                      if (DEBUG(COND)) {
                         printf("left = %f, right = %f, op = %.2s\n", left,                          fprintf(debug_file, "left = %f, right = %f, op = %.2s\n", left,
                                right, op);                                 right, op);
                     }                      }
                     switch(op[0]) {                      switch(op[0]) {
Line 836  do_string_compare:
Line 848  do_string_compare:
                 }                  }
 error:  error:
                 if (lhsFree)                  if (lhsFree)
                     free(lhs);                      free(lhsFree);
                 if (rhsFree)                  if (rhsFree)
                     free(rhs);                      free(rhsFree);
                 break;                  break;
             }              }
             default: {              default: {
                 Boolean (*evalProc)(int, char *);                  Boolean (*evalProc)(int, char *);
                 Boolean invert = FALSE;                  Boolean invert = FALSE;
                 char    *arg;                  char    *arg = NULL;
                 int     arglen;                  int     arglen = 0;
   
                 if (istoken(condExpr, "defined", 7)) {                  if (istoken(condExpr, "defined", 7)) {
                     /*                      /*
Line 892  error:
Line 904  error:
                      * True if the resulting string is empty.                       * True if the resulting string is empty.
                      */                       */
                     int     length;                      int     length;
                     Boolean doFree;                      void    *freeIt;
                     char    *val;                      char    *val;
   
                     condExpr += 5;                      condExpr += 5;
Line 904  error:
Line 916  error:
   
                     if (condExpr[arglen] != '\0') {                      if (condExpr[arglen] != '\0') {
                         val = Var_Parse(&condExpr[arglen - 1], VAR_CMD,                          val = Var_Parse(&condExpr[arglen - 1], VAR_CMD,
                                         FALSE, &length, &doFree);                                          FALSE, &length, &freeIt);
                         if (val == var_Error) {                          if (val == var_Error) {
                             t = Err;                              t = Err;
                         } else {                          } else {
Line 917  error:
Line 929  error:
                                 continue;                                  continue;
                             t = (*p == '\0') ? True : False;                              t = (*p == '\0') ? True : False;
                         }                          }
                         if (doFree) {                          if (freeIt) {
                             free(val);                              free(freeIt);
                         }                          }
                         /*                          /*
                          * Advance condExpr to beyond the closing ). Note that                           * Advance condExpr to beyond the closing ). Note that
Line 978  error:
Line 990  error:
                 t = (!doEval || (* evalProc) (arglen, arg) ?                  t = (!doEval || (* evalProc) (arglen, arg) ?
                      (invert ? False : True) :                       (invert ? False : True) :
                      (invert ? True : False));                       (invert ? True : False));
                 free(arg);                  if (arg)
                       free(arg);
                 break;                  break;
             }              }
         }          }
Line 1074  CondF(Boolean doEval)
Line 1087  CondF(Boolean doEval)
             if (l == True) {              if (l == True) {
                 l = CondF(doEval);                  l = CondF(doEval);
             } else {              } else {
                 (void) CondF(FALSE);                  (void)CondF(FALSE);
             }              }
         } else {          } else {
             /*              /*
Line 1121  CondE(Boolean doEval)
Line 1134  CondE(Boolean doEval)
             if (l == False) {              if (l == False) {
                 l = CondE(doEval);                  l = CondE(doEval);
             } else {              } else {
                 (void) CondE(FALSE);                  (void)CondE(FALSE);
             }              }
         } else {          } else {
             /*              /*
Line 1198  err:
Line 1211  err:
  * Cond_Eval --   * Cond_Eval --
  *      Evaluate the conditional in the passed line. The line   *      Evaluate the conditional in the passed line. The line
  *      looks like this:   *      looks like this:
  *          #<cond-type> <expr>   *          .<cond-type> <expr>
  *      where <cond-type> is any of if, ifmake, ifnmake, ifdef,   *      where <cond-type> is any of if, ifmake, ifnmake, ifdef,
  *      ifndef, elif, elifmake, elifnmake, elifdef, elifndef   *      ifndef, elif, elifmake, elifnmake, elifdef, elifndef
  *      and <expr> consists of &&, ||, !, make(target), defined(variable)   *      and <expr> consists of &&, ||, !, make(target), defined(variable)
Line 1215  err:
Line 1228  err:
  * Side Effects:   * Side Effects:
  *      None.   *      None.
  *   *
    * Note that the states IF_ACTIVE and ELSE_ACTIVE are only different in order
    * to detect splurious .else lines (as are SKIP_TO_ELSE and SKIP_TO_ENDIF)
    * otherwise .else could be treated as '.elif 1'.
    *
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
 int  int
 Cond_Eval(char *line)  Cond_Eval(char *line)
 {  {
     struct If       *ifp;      #define         MAXIF       64      /* maximum depth of .if'ing */
     Boolean         isElse;      enum if_states {
     Boolean         value = FALSE;          IF_ACTIVE,              /* .if or .elif part active */
           ELSE_ACTIVE,            /* .else part active */
           SEARCH_FOR_ELIF,        /* searching for .elif/else to execute */
           SKIP_TO_ELSE,           /* has been true, but not seen '.else' */
           SKIP_TO_ENDIF           /* nothing else to execute */
       };
       static enum if_states cond_state[MAXIF + 1] = { IF_ACTIVE };
   
       const struct If *ifp;
       Boolean         isElif;
       Boolean         value;
     int             level;      /* Level at which to report errors. */      int             level;      /* Level at which to report errors. */
       enum if_states  state;
   
     level = PARSE_FATAL;      level = PARSE_FATAL;
   
     for (line++; *line == ' ' || *line == '\t'; line++) {      /* skip leading character (the '.') and any whitespace */
       for (line++; *line == ' ' || *line == '\t'; line++)
         continue;          continue;
     }  
   
     /*      /* Find what type of if we're dealing with.  */
      * Find what type of if we're dealing with. The result is left      if (line[0] == 'e') {
      * in ifp and isElse is set TRUE if it's an elif line.          if (line[1] != 'l') {
      */              if (!istoken(line + 1, "ndif", 4))
     if (line[0] == 'e' && line[1] == 'l') {                  return COND_INVALID;
         line += 2;              /* End of conditional section */
         isElse = TRUE;              if (cond_depth == cond_min_depth) {
     } else if (istoken(line, "endif", 5)) {  
         /*  
          * End of a conditional section. If skipIfLevel is non-zero, that  
          * conditional was skipped, so lines following it should also be  
          * skipped. Hence, we return COND_SKIP. Otherwise, the conditional  
          * was read so succeeding lines should be parsed (think about it...)  
          * so we return COND_PARSE, unless this endif isn't paired with  
          * a decent if.  
          */  
         finalElse[condTop][skipIfLevel] = FALSE;  
         if (skipIfLevel != 0) {  
             skipIfLevel -= 1;  
             return (COND_SKIP);  
         } else {  
             if (condTop == MAXIF) {  
                 Parse_Error(level, "if-less endif");                  Parse_Error(level, "if-less endif");
                 return (COND_INVALID);                  return COND_PARSE;
             } else {  
                 skipLine = FALSE;  
                 condTop += 1;  
                 return (COND_PARSE);  
             }              }
               /* Return state for previous conditional */
               cond_depth--;
               return cond_state[cond_depth] <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
         }          }
     } else {  
         isElse = FALSE;          /* Quite likely this is 'else' or 'elif' */
     }          line += 2;
           if (istoken(line, "se", 2)) {
               /* It is else... */
               if (cond_depth == cond_min_depth) {
                   Parse_Error(level, "if-less else");
                   return COND_INVALID;
               }
   
               state = cond_state[cond_depth];
               switch (state) {
               case SEARCH_FOR_ELIF:
                   state = ELSE_ACTIVE;
                   break;
               case ELSE_ACTIVE:
               case SKIP_TO_ENDIF:
                   Parse_Error(PARSE_WARNING, "extra else");
                   /* FALLTHROUGH */
               default:
               case IF_ACTIVE:
               case SKIP_TO_ELSE:
                   state = SKIP_TO_ENDIF;
                   break;
               }
               cond_state[cond_depth] = state;
               return state <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
           }
           /* Assume for now it is an elif */
           isElif = TRUE;
       } else
           isElif = FALSE;
   
       if (line[0] != 'i' || line[1] != 'f')
           /* Not an ifxxx or elifxxx line */
           return COND_INVALID;
   
     /*      /*
      * Figure out what sort of conditional it is -- what its default       * Figure out what sort of conditional it is -- what its default
      * function is, etc. -- by looking in the table of valid "ifs"       * function is, etc. -- by looking in the table of valid "ifs"
      */       */
     for (ifp = ifs; ifp->form != (char *)0; ifp++) {      line += 2;
       for (ifp = ifs; ; ifp++) {
           if (ifp->form == NULL)
               return COND_INVALID;
         if (istoken(ifp->form, line, ifp->formlen)) {          if (istoken(ifp->form, line, ifp->formlen)) {
               line += ifp->formlen;
             break;              break;
         }          }
     }      }
   
     if (ifp->form == (char *) 0) {      /* Now we know what sort of 'if' it is... */
         /*      state = cond_state[cond_depth];
          * Nothing fit. If the first word on the line is actually  
          * "else", it's a valid conditional whose value is the inverse      if (isElif) {
          * of the previous if we parsed.          if (cond_depth == cond_min_depth) {
          */              Parse_Error(level, "if-less elif");
         if (isElse && istoken(line, "se", 2)) {              return COND_INVALID;
             if (finalElse[condTop][skipIfLevel]) {          }
                 Parse_Error(PARSE_WARNING, "extra else");          if (state == SKIP_TO_ENDIF || state == ELSE_ACTIVE)
             } else {              Parse_Error(PARSE_WARNING, "extra elif");
                 finalElse[condTop][skipIfLevel] = TRUE;          if (state != SEARCH_FOR_ELIF) {
             }              /* Either just finished the 'true' block, or already SKIP_TO_ELSE */
             if (condTop == MAXIF) {              cond_state[cond_depth] = SKIP_TO_ELSE;
                 Parse_Error(level, "if-less else");              return COND_SKIP;
                 return (COND_INVALID);  
             } else if (skipIfLevel == 0) {  
                 value = !condStack[condTop];  
             } else {  
                 return (COND_SKIP);  
             }  
         } else {  
             /*  
              * Not a valid conditional type. No error...  
              */  
             return (COND_INVALID);  
         }          }
     } else {      } else {
         if (isElse) {          if (cond_depth >= MAXIF) {
             if (condTop == MAXIF) {              Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF);
                 Parse_Error(level, "if-less elif");              return COND_INVALID;
                 return (COND_INVALID);          }
             } else if (skipIfLevel != 0) {          cond_depth++;
                 /*          if (state > ELSE_ACTIVE) {
                  * If skipping this conditional, just ignore the whole thing.              /* If we aren't parsing the data, treat as always false */
                  * If we don't, the user might be employing a variable that's              cond_state[cond_depth] = SKIP_TO_ELSE;
                  * undefined, for which there's an enclosing ifdef that              return COND_SKIP;
                  * we're skipping...  
                  */  
                 return(COND_SKIP);  
             }  
         } else if (skipLine) {  
             /*  
              * Don't even try to evaluate a conditional that's not an else if  
              * we're skipping things...  
              */  
             skipIfLevel += 1;  
             if (skipIfLevel >= MAXIF) {  
                 Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF);  
                 return (COND_INVALID);  
             }  
             finalElse[condTop][skipIfLevel] = FALSE;  
             return(COND_SKIP);  
         }          }
   
         /*  
          * Initialize file-global variables for parsing  
          */  
         condDefProc = ifp->defProc;  
         condInvert = ifp->doNot;  
   
         line += ifp->formlen;  
         if (Cond_EvalExpression(0, line, &value, 1) == COND_INVALID)  
                 return COND_INVALID;  
     }  
     if (!isElse) {  
         condTop -= 1;  
         finalElse[condTop][skipIfLevel] = FALSE;  
     } else if ((skipIfLevel != 0) || condStack[condTop]) {  
         /*  
          * If this is an else-type conditional, it should only take effect  
          * if its corresponding if was evaluated and FALSE. If its if was  
          * TRUE or skipped, we return COND_SKIP (and start skipping in case  
          * we weren't already), leaving the stack unmolested so later elif's  
          * don't screw up...  
          */  
         skipLine = TRUE;  
         return (COND_SKIP);  
     }      }
   
     if (condTop < 0) {      /* Initialize file-global variables for parsing the expression */
         /*      condDefProc = ifp->defProc;
          * This is the one case where we can definitely proclaim a fatal      condInvert = ifp->doNot;
          * error. If we don't, we're hosed.  
          */      /* And evaluate the conditional expresssion */
         Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF);      if (Cond_EvalExpression(0, line, &value, 1) == COND_INVALID) {
         return (COND_INVALID);          /* Although we get make to reprocess the line, set a state */
     } else {          cond_state[cond_depth] = SEARCH_FOR_ELIF;
         condStack[condTop] = value;          return COND_INVALID;
         skipLine = !value;      }
         return (value ? COND_PARSE : COND_SKIP);  
       if (!value) {
           cond_state[cond_depth] = SEARCH_FOR_ELIF;
           return COND_SKIP;
     }      }
       cond_state[cond_depth] = IF_ACTIVE;
       return COND_PARSE;
 }  }
   
   
Line 1384  Cond_Eval(char *line)
Line 1387  Cond_Eval(char *line)
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
 void  void
 Cond_End(void)  Cond_restore_depth(unsigned int saved_depth)
 {  {
     if (condTop != MAXIF) {      int open_conds = cond_depth - cond_min_depth;
         Parse_Error(PARSE_FATAL, "%d open conditional%s", MAXIF-condTop,  
                     MAXIF-condTop == 1 ? "" : "s");      if (open_conds != 0 || saved_depth > cond_depth) {
           Parse_Error(PARSE_FATAL, "%d open conditional%s", open_conds,
                       open_conds == 1 ? "" : "s");
           cond_depth = cond_min_depth;
     }      }
     condTop = MAXIF;  
       cond_min_depth = saved_depth;
   }
   
   unsigned int
   Cond_save_depth(void)
   {
       int depth = cond_min_depth;
   
       cond_min_depth = cond_depth;
       return depth;
 }  }

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.37

CVSweb <webmaster@jp.NetBSD.org>