[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.58 and 1.59

version 1.58, 2009/01/30 22:35:10 version 1.59, 2009/01/30 23:07:17
Line 124  __RCSID("$NetBSD$");
Line 124  __RCSID("$NetBSD$");
  * is applied.   * is applied.
  *   *
  * Tokens are scanned from the 'condExpr' string. The scanner (CondToken)   * Tokens are scanned from the 'condExpr' string. The scanner (CondToken)
  * will return And for '&' and '&&', Or for '|' and '||', Not for '!',   * will return TOK_AND for '&' and '&&', TOK_OR for '|' and '||', TOK_NOT for '!',
  * LParen for '(', RParen for ')' and will evaluate the other terminal   * TOK_LPAREN for '(', TOK_RPAREN for ')' and will evaluate the other terminal
  * symbols, using either the default function or the function given in the   * symbols, using either the default function or the function given in the
  * terminal, and return the result as either True or False.   * terminal, and return the result as either TOK_TRUE or TOK_FALSE.
  *   *
  * All Non-Terminal functions (CondE, CondF and CondT) return Err on error.   * All Non-Terminal functions (CondE, CondF and CondT) return TOK_ERROR on error.
  */   */
 typedef enum {  typedef enum {
     And, Or, Not, True, False, LParen, RParen, EndOfFile, None, Err      TOK_AND, TOK_OR, TOK_NOT, TOK_TRUE, TOK_FALSE, TOK_LPAREN, TOK_RPAREN,
       TOK_EOF, TOK_NONE, TOK_ERROR
 } Token;  } Token;
   
 /*-  /*-
Line 170  static const struct If {
Line 171  static const struct If {
   
 static const struct If *if_info;        /* Info for current statement */  static const struct If *if_info;        /* Info for current statement */
 static char       *condExpr;            /* The expression to parse */  static char       *condExpr;            /* The expression to parse */
 static Token      condPushBack=None;    /* Single push-back token used in  static Token      condPushBack=TOK_NONE;        /* Single push-back token used in
                                          * parsing */                                           * parsing */
   
 static unsigned int     cond_depth = 0;         /* current .if nesting level */  static unsigned int     cond_depth = 0;         /* current .if nesting level */
Line 617  CondGetString(Boolean doEval, Boolean *q
Line 618  CondGetString(Boolean doEval, Boolean *q
  *      A Token for the next lexical token in the stream.   *      A Token for the next lexical token in the stream.
  *   *
  * Side Effects:   * Side Effects:
  *      condPushback will be set back to None if it is used.   *      condPushback will be set back to TOK_NONE if it is used.
  *   *
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
Line 634  compare_expression(Boolean doEval)
Line 635  compare_expression(Boolean doEval)
     Boolean rhsQuoted;      Boolean rhsQuoted;
     double      left, right;      double      left, right;
   
     t = Err;      t = TOK_ERROR;
     rhs = NULL;      rhs = NULL;
     lhsFree = rhsFree = FALSE;      lhsFree = rhsFree = FALSE;
     lhsQuoted = rhsQuoted = FALSE;      lhsQuoted = rhsQuoted = FALSE;
Line 672  compare_expression(Boolean doEval)
Line 673  compare_expression(Boolean doEval)
             break;              break;
         default:          default:
             if (!doEval) {              if (!doEval) {
                 t = False;                  t = TOK_FALSE;
                 goto done;                  goto done;
             }              }
             /* For .ifxxx "..." check for non-empty string. */              /* For .ifxxx "..." check for non-empty string. */
             if (lhsQuoted) {              if (lhsQuoted) {
                 t = lhs[0] != 0 ? True : False;                  t = lhs[0] != 0 ? TOK_TRUE : TOK_FALSE;
                 goto done;                  goto done;
             }              }
             /* For .ifxxx <number> compare against zero */              /* For .ifxxx <number> compare against zero */
             if (CondCvtArg(lhs, &left)) {              if (CondCvtArg(lhs, &left)) {
                 t = left != 0.0 ? True : False;                  t = left != 0.0 ? TOK_TRUE : TOK_FALSE;
                 goto done;                  goto done;
             }              }
             /* For .if ${...} check for non-empty string (defProc is ifdef). */              /* For .if ${...} check for non-empty string (defProc is ifdef). */
             if (if_info->form[0] == 0) {              if (if_info->form[0] == 0) {
                 t = lhs[0] != 0 ? True : False;                  t = lhs[0] != 0 ? TOK_TRUE : TOK_FALSE;
                 goto done;                  goto done;
             }              }
             /* Otherwise action default test ... */              /* Otherwise action default test ... */
             t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot ? True : False;              t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot ? TOK_TRUE : TOK_FALSE;
             goto done;              goto done;
     }      }
   
Line 725  do_string_compare:
Line 726  do_string_compare:
          * t is set to the result.           * t is set to the result.
          */           */
         if (*op == '=') {          if (*op == '=') {
             t = strcmp(lhs, rhs) ? False : True;              t = strcmp(lhs, rhs) ? TOK_FALSE : TOK_TRUE;
         } else {          } else {
             t = strcmp(lhs, rhs) ? True : False;              t = strcmp(lhs, rhs) ? TOK_TRUE : TOK_FALSE;
         }          }
     } else {      } else {
         /*          /*
Line 749  do_string_compare:
Line 750  do_string_compare:
                             "Unknown operator");                              "Unknown operator");
                 goto done;                  goto done;
             }              }
             t = (left != right ? True : False);              t = (left != right ? TOK_TRUE : TOK_FALSE);
             break;              break;
         case '=':          case '=':
             if (op[1] != '=') {              if (op[1] != '=') {
Line 757  do_string_compare:
Line 758  do_string_compare:
                             "Unknown operator");                              "Unknown operator");
                 goto done;                  goto done;
             }              }
             t = (left == right ? True : False);              t = (left == right ? TOK_TRUE : TOK_FALSE);
             break;              break;
         case '<':          case '<':
             if (op[1] == '=') {              if (op[1] == '=') {
                 t = (left <= right ? True : False);                  t = (left <= right ? TOK_TRUE : TOK_FALSE);
             } else {              } else {
                 t = (left < right ? True : False);                  t = (left < right ? TOK_TRUE : TOK_FALSE);
             }              }
             break;              break;
         case '>':          case '>':
             if (op[1] == '=') {              if (op[1] == '=') {
                 t = (left >= right ? True : False);                  t = (left >= right ? TOK_TRUE : TOK_FALSE);
             } else {              } else {
                 t = (left > right ? True : False);                  t = (left > right ? TOK_TRUE : TOK_FALSE);
             }              }
             break;              break;
         }          }
Line 789  get_mpt_arg(char **linePtr, char **argPt
Line 790  get_mpt_arg(char **linePtr, char **argPt
 {  {
     /*      /*
      * Use Var_Parse to parse the spec in parens and return       * Use Var_Parse to parse the spec in parens and return
      * True if the resulting string is empty.       * TOK_TRUE if the resulting string is empty.
      */       */
     int     length;      int     length;
     void    *freeIt;      void    *freeIt;
Line 868  compare_function(Boolean doEval)
Line 869  compare_function(Boolean doEval)
         arglen = fn_def->fn_getarg(&cp, &arg, fn_def->fn_name);          arglen = fn_def->fn_getarg(&cp, &arg, fn_def->fn_name);
         if (arglen <= 0) {          if (arglen <= 0) {
             condExpr = cp;              condExpr = cp;
             return arglen < 0 ? Err : False;              return arglen < 0 ? TOK_ERROR : TOK_FALSE;
         }          }
         /* Evaluate the argument using the required function. */          /* Evaluate the argument using the required function. */
         t = !doEval || fn_def->fn_proc(arglen, arg) ? True : False;          t = !doEval || fn_def->fn_proc(arglen, arg) ? TOK_TRUE : TOK_FALSE;
         if (arg)          if (arg)
             free(arg);              free(arg);
         condExpr = cp;          condExpr = cp;
Line 904  compare_function(Boolean doEval)
Line 905  compare_function(Boolean doEval)
      * after .if must have been taken literally, so the argument cannot       * after .if must have been taken literally, so the argument cannot
      * be empty - even if it contained a variable expansion.       * be empty - even if it contained a variable expansion.
      */       */
     t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot ? True : False;      t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot ? TOK_TRUE : TOK_FALSE;
     if (arg)      if (arg)
         free(arg);          free(arg);
     return t;      return t;
Line 916  CondToken(Boolean doEval)
Line 917  CondToken(Boolean doEval)
     Token t;      Token t;
   
     t = condPushBack;      t = condPushBack;
     if (t != None) {      if (t != TOK_NONE) {
         condPushBack = None;          condPushBack = TOK_NONE;
         return t;          return t;
     }      }
   
Line 929  CondToken(Boolean doEval)
Line 930  CondToken(Boolean doEval)
   
     case '(':      case '(':
         condExpr++;          condExpr++;
         return LParen;          return TOK_LPAREN;
   
     case ')':      case ')':
         condExpr++;          condExpr++;
         return RParen;          return TOK_RPAREN;
   
     case '|':      case '|':
         if (condExpr[1] == '|') {          if (condExpr[1] == '|') {
             condExpr++;              condExpr++;
         }          }
         condExpr++;          condExpr++;
         return Or;          return TOK_OR;
   
     case '&':      case '&':
         if (condExpr[1] == '&') {          if (condExpr[1] == '&') {
             condExpr++;              condExpr++;
         }          }
         condExpr++;          condExpr++;
         return And;          return TOK_AND;
   
     case '!':      case '!':
         condExpr++;          condExpr++;
         return Not;          return TOK_NOT;
   
     case '#':      case '#':
     case '\n':      case '\n':
     case '\0':      case '\0':
         return EndOfFile;          return TOK_EOF;
   
     case '"':      case '"':
     case '$':      case '$':
Line 971  CondToken(Boolean doEval)
Line 972  CondToken(Boolean doEval)
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * CondT --   * CondT --
  *      Parse a single term in the expression. This consists of a terminal   *      Parse a single term in the expression. This consists of a terminal
  *      symbol or Not and a terminal symbol (not including the binary   *      symbol or TOK_NOT and a terminal symbol (not including the binary
  *      operators):   *      operators):
  *          T -> defined(variable) | make(target) | exists(file) | symbol   *          T -> defined(variable) | make(target) | exists(file) | symbol
  *          T -> ! T | ( E )   *          T -> ! T | ( E )
  *   *
  * Results:   * Results:
  *      True, False or Err.   *      TOK_TRUE, TOK_FALSE or TOK_ERROR.
  *   *
  * Side Effects:   * Side Effects:
  *      Tokens are consumed.   *      Tokens are consumed.
Line 991  CondT(Boolean doEval)
Line 992  CondT(Boolean doEval)
   
     t = CondToken(doEval);      t = CondToken(doEval);
   
     if (t == EndOfFile) {      if (t == TOK_EOF) {
         /*          /*
          * If we reached the end of the expression, the expression           * If we reached the end of the expression, the expression
          * is malformed...           * is malformed...
          */           */
         t = Err;          t = TOK_ERROR;
     } else if (t == LParen) {      } else if (t == TOK_LPAREN) {
         /*          /*
          * T -> ( E )           * T -> ( E )
          */           */
         t = CondE(doEval);          t = CondE(doEval);
         if (t != Err) {          if (t != TOK_ERROR) {
             if (CondToken(doEval) != RParen) {              if (CondToken(doEval) != TOK_RPAREN) {
                 t = Err;                  t = TOK_ERROR;
             }              }
         }          }
     } else if (t == Not) {      } else if (t == TOK_NOT) {
         t = CondT(doEval);          t = CondT(doEval);
         if (t == True) {          if (t == TOK_TRUE) {
             t = False;              t = TOK_FALSE;
         } else if (t == False) {          } else if (t == TOK_FALSE) {
             t = True;              t = TOK_TRUE;
         }          }
     }      }
     return (t);      return (t);
Line 1025  CondT(Boolean doEval)
Line 1026  CondT(Boolean doEval)
  *          F -> T && F | T   *          F -> T && F | T
  *   *
  * Results:   * Results:
  *      True, False or Err   *      TOK_TRUE, TOK_FALSE or TOK_ERROR
  *   *
  * Side Effects:   * Side Effects:
  *      Tokens are consumed.   *      Tokens are consumed.
Line 1038  CondF(Boolean doEval)
Line 1039  CondF(Boolean doEval)
     Token   l, o;      Token   l, o;
   
     l = CondT(doEval);      l = CondT(doEval);
     if (l != Err) {      if (l != TOK_ERROR) {
         o = CondToken(doEval);          o = CondToken(doEval);
   
         if (o == And) {          if (o == TOK_AND) {
             /*              /*
              * F -> T && F               * F -> T && F
              *               *
              * If T is False, the whole thing will be False, but we have to               * If T is TOK_FALSE, the whole thing will be TOK_FALSE, but we have to
              * parse the r.h.s. anyway (to throw it away).               * parse the r.h.s. anyway (to throw it away).
              * If T is True, the result is the r.h.s., be it an Err or no.               * If T is TOK_TRUE, the result is the r.h.s., be it an TOK_ERROR or no.
              */               */
             if (l == True) {              if (l == TOK_TRUE) {
                 l = CondF(doEval);                  l = CondF(doEval);
             } else {              } else {
                 (void)CondF(FALSE);                  (void)CondF(FALSE);
Line 1071  CondF(Boolean doEval)
Line 1072  CondF(Boolean doEval)
  *          E -> F || E | F   *          E -> F || E | F
  *   *
  * Results:   * Results:
  *      True, False or Err.   *      TOK_TRUE, TOK_FALSE or TOK_ERROR.
  *   *
  * Side Effects:   * Side Effects:
  *      Tokens are, of course, consumed.   *      Tokens are, of course, consumed.
Line 1084  CondE(Boolean doEval)
Line 1085  CondE(Boolean doEval)
     Token   l, o;      Token   l, o;
   
     l = CondF(doEval);      l = CondF(doEval);
     if (l != Err) {      if (l != TOK_ERROR) {
         o = CondToken(doEval);          o = CondToken(doEval);
   
         if (o == Or) {          if (o == TOK_OR) {
             /*              /*
              * E -> F || E               * E -> F || E
              *               *
              * A similar thing occurs for ||, except that here we make sure               * A similar thing occurs for ||, except that here we make sure
              * the l.h.s. is False before we bother to evaluate the r.h.s.               * the l.h.s. is TOK_FALSE before we bother to evaluate the r.h.s.
              * Once again, if l is False, the result is the r.h.s. and once               * Once again, if l is TOK_FALSE, the result is the r.h.s. and once
              * again if l is True, we parse the r.h.s. to throw it away.               * again if l is TOK_TRUE, we parse the r.h.s. to throw it away.
              */               */
             if (l == False) {              if (l == TOK_FALSE) {
                 l = CondE(doEval);                  l = CondE(doEval);
             } else {              } else {
                 (void)CondE(FALSE);                  (void)CondE(FALSE);
Line 1151  Cond_EvalExpression(const struct If *inf
Line 1152  Cond_EvalExpression(const struct If *inf
   
     if_info = info != NULL ? info : ifs + 4;      if_info = info != NULL ? info : ifs + 4;
     condExpr = line;      condExpr = line;
     condPushBack = None;      condPushBack = TOK_NONE;
   
     rval = do_Cond_EvalExpression(value);      rval = do_Cond_EvalExpression(value);
   
Line 1170  do_Cond_EvalExpression(Boolean *value)
Line 1171  do_Cond_EvalExpression(Boolean *value)
 {  {
   
     switch (CondE(TRUE)) {      switch (CondE(TRUE)) {
     case True:      case TOK_TRUE:
         if (CondToken(TRUE) == EndOfFile) {          if (CondToken(TRUE) == TOK_EOF) {
             *value = TRUE;              *value = TRUE;
             return COND_PARSE;              return COND_PARSE;
         }          }
         break;          break;
     case False:      case TOK_FALSE:
         if (CondToken(TRUE) == EndOfFile) {          if (CondToken(TRUE) == TOK_EOF) {
             *value = FALSE;              *value = FALSE;
             return COND_PARSE;              return COND_PARSE;
         }          }
         break;          break;
     default:      default:
     case Err:      case TOK_ERROR:
         break;          break;
     }      }
   

Legend:
Removed from v.1.58  
changed lines
  Added in v.1.59

CVSweb <webmaster@jp.NetBSD.org>