[BACK]Return to var.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/var.c between version 1.23 and 1.24

version 1.23, 1999/12/16 17:02:45 version 1.24, 1999/12/16 17:27:18
Line 1672 
Line 1672 
      */       */
     str = VarValue(v);      str = VarValue(v);
     if (strchr (str, '$') != (char *)NULL) {      if (strchr (str, '$') != (char *)NULL) {
         str = Var_Subst(NULL, str, ctxt, err);          str = Var_Subst(str, ctxt, err);
         *freePtr = TRUE;          *freePtr = TRUE;
     }      }
   
Line 2091 
Line 2091 
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * Var_Subst  --   * Var_Subst  --
  *      Substitute for all variables in the given string in the given context   *      Substitute for all variables in a string in a context
  *      If undefErr is TRUE, Parse_Error will be called when an undefined   *      If undefErr is TRUE, Parse_Error will be called when an undefined
  *      variable is encountered.   *      variable is encountered.
  *   *
Line 2103 
Line 2103 
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
 char *  char *
 Var_Subst (var, str, ctxt, undefErr)  Var_Subst(str, ctxt, undefErr)
     char          *var;             /* Named variable || NULL for all */  
     char          *str;             /* the string in which to substitute */      char          *str;             /* the string in which to substitute */
     GNode         *ctxt;            /* the context wherein to find variables */      GNode         *ctxt;            /* the context wherein to find variables */
     Boolean       undefErr;         /* TRUE if undefineds are an error */      Boolean       undefErr;         /* TRUE if undefineds are an error */
 {  {
     BUFFER        buf;              /* Buffer for forming things */      BUFFER        buf;              /* Buffer for forming things */
     char          *val;             /* Value to substitute for a variable */  
     int           length;           /* Length of the variable invocation */  
     Boolean       doFree;           /* Set true if val should be freed */  
     static Boolean errorReported;   /* Set true if an error has already      static Boolean errorReported;   /* Set true if an error has already
                                      * been reported to prevent a plethora                                       * been reported to prevent a plethora
                                      * of messages when recursing */                                       * of messages when recursing */
Line 2120 
Line 2116 
     Buf_Init(&buf, MAKE_BSIZE);      Buf_Init(&buf, MAKE_BSIZE);
     errorReported = FALSE;      errorReported = FALSE;
   
     while (*str) {      for (;;) {
         if (var == NULL && (*str == '$') && (str[1] == '$')) {          char            *val;           /* Value to substitute for a variable */
             /*          size_t          length;         /* Length of the variable invocation */
              * A dollar sign may be escaped either with another dollar sign.          Boolean         doFree;         /* Set true if val should be freed */
              * In such a case, we skip over the escape character and store the          const char *cp;
              * dollar sign into the buffer directly.  
              */  
             str++;  
             Buf_AddChar(&buf, *str);  
             str++;  
         } else if (*str != '$') {  
             /*  
              * Skip as many characters as possible -- either to the end of  
              * the string or to the next dollar sign (variable invocation).  
              */  
             char  *cp;  
   
             for (cp = str++; *str != '$' && *str != '\0'; str++)          /* copy uninteresting stuff */
                 continue;          for (cp = str; *str != '\0' && *str != '$'; str++)
             Buf_AddInterval(&buf, cp, str);              ;
           Buf_AddInterval(&buf, cp, str);
           if (*str == '\0')
               break;
           if (str[1] == '$') {
               /* A dollar sign may be escaped with another dollar sign.  */
               Buf_AddChar(&buf, '$');
               str += 2;
               continue;
           }
           val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
           /* When we come down here, val should either point to the
            * value of this variable, suitably modified, or be NULL.
            * Length should be the total length of the potential
            * variable invocation (from $ to end character...) */
           if (val == var_Error || val == varNoError) {
               /* If performing old-time variable substitution, skip over
                * the variable and continue with the substitution. Otherwise,
                * store the dollar sign and advance str so we continue with
                * the string...  */
               if (oldVars) {
                   str += length;
               } else if (undefErr) {
                   /* If variable is undefined, complain and skip the
                    * variable. The complaint will stop us from doing anything
                    * when the file is parsed.  */
                   if (!errorReported) {
                       Parse_Error(PARSE_FATAL,
                                    "Undefined variable \"%.*s\"",length,str);
                   }
                   str += length;
                   errorReported = TRUE;
               } else {
                   Buf_AddChar(&buf, *str);
                   str += 1;
               }
         } else {          } else {
             if (var != NULL) {              /* We've now got a variable structure to store in. But first,
                 int expand;               * advance the string pointer.  */
                 for (;;) {              str += length;
                     if (str[1] != '(' && str[1] != '{') {  
                         if (str[1] != *var || var[1] != '\0') {  
                             Buf_AddChars(&buf, 2, str);  
                             str += 2;  
                             expand = FALSE;  
                         }  
                         else  
                             expand = TRUE;  
                         break;  
                     }  
                     else {  
                         char *p;  
   
                         /*              /* Copy all the characters from the variable value straight
                          * Scan up to the end of the variable name.               * into the new string.  */
                          */              Buf_AddString(&buf, val);
                         for (p = &str[2]; *p &&              if (doFree)
                              *p != ':' && *p != ')' && *p != '}'; p++)                  free(val);
                             if (*p == '$')          }
                                 break;      }
                         /*      return  Buf_Retrieve(&buf);
                          * A variable inside the variable. We cannot expand  }
                          * the external variable yet, so we try again with  
                          * the nested one  
                          */  
                         if (*p == '$') {  
                             Buf_AddInterval(&buf, str, p);  
                             str = p;  
                             continue;  
                         }  
   
                         if (strncmp(var, str + 2, p - str - 2) != 0 ||  /*-
                             var[p - str - 2] != '\0') {   *-----------------------------------------------------------------------
                             /*   * Var_SubstVar  --
                              * Not the variable we want to expand, scan   *      Substitute for one variable in the given string in the given context
                              * until the next variable   *      If undefErr is TRUE, Parse_Error will be called when an undefined
                              */   *      variable is encountered.
                             for (;*p != '$' && *p != '\0'; p++)   *
                                 continue;   * Side Effects:
                             Buf_AddInterval(&buf, str, p);   *      Append the result to the buffer
                             str = p;   *-----------------------------------------------------------------------
                             expand = FALSE;   */
                         }  void
                         else  Var_SubstVar(buf, str, var, ctxt)
                             expand = TRUE;      Buffer      buf;            /* Where to store the result */
                         break;      char        *str;           /* The string in which to substitute */
                     }      const char  *var;           /* Named variable */
                 }      GNode       *ctxt;          /* The context wherein to find variables */
                 if (!expand)  {
                     continue;      char        *val;           /* Value substituted for a variable */
       size_t      length;         /* Length of the variable invocation */
       Boolean     doFree;         /* Set true if val should be freed */
   
       for (;;) {
           const char *cp;
           /* copy uninteresting stuff */
           for (cp = str; *str != '\0' && *str != '$'; str++)
               ;
           Buf_AddInterval(buf, cp, str);
           if (*str == '\0')
               break;
           if (str[1] == '$') {
               Buf_AddString(buf, "$$");
               str += 2;
               continue;
           }
           if (str[1] != '(' && str[1] != '{') {
               if (str[1] != *var || var[1] != '\0') {
                   Buf_AddChars(buf, 2, str);
                   str += 2;
                   continue;
             }              }
           } else {
               char *p;
               char endc;
   
             val = Var_Parse (str, ctxt, undefErr, &length, &doFree);              if (str[1] == '(')
                   endc = ')';
               else if (str[1] == '{')
                   endc = '}';
   
             /*              /* Find the end of the variable specification.  */
              * When we come down here, val should either point to the              p = str+2;
              * value of this variable, suitably modified, or be NULL.              while (*p != '\0' && *p != ':' && *p != endc && *p != '$')
              * Length should be the total length of the potential                  p++;
              * variable invocation (from $ to end character...)              /* A variable inside the variable.  We don't know how to
              */               * expand the external variable at this point, so we try
             if (val == var_Error || val == varNoError) {               * again with the nested variable.  */
                 /*              if (*p == '$') {
                  * If performing old-time variable substitution, skip over                  Buf_AddInterval(buf, str, p);
                  * the variable and continue with the substitution. Otherwise,                  str = p;
                  * store the dollar sign and advance str so we continue with                  continue;
                  * the string...  
                  */  
                 if (oldVars) {  
                     str += length;  
                 } else if (undefErr) {  
                     /*  
                      * If variable is undefined, complain and skip the  
                      * variable. The complaint will stop us from doing anything  
                      * when the file is parsed.  
                      */  
                     if (!errorReported) {  
                         Parse_Error (PARSE_FATAL,  
                                      "Undefined variable \"%.*s\"",length,str);  
                     }  
                     str += length;  
                     errorReported = TRUE;  
                 } else {  
                     Buf_AddChar(&buf, *str);  
                     str += 1;  
                 }  
             } else {  
                 /*  
                  * We've now got a variable structure to store in. But first,  
                  * advance the string pointer.  
                  */  
                 str += length;  
   
                 /*  
                  * Copy all the characters from the variable value straight  
                  * into the new string.  
                  */  
                 Buf_AddString(&buf, val);  
                 if (doFree)  
                     free(val);  
             }              }
   
               if (strncmp(var, str + 2, p - str - 2) != 0 ||
                   var[p - str - 2] != '\0') {
                   /* Not the variable we want to expand.  */
                   Buf_AddInterval(buf, str, p);
                   str = p;
                   continue;
               }
         }          }
     }          /* okay, so we've found the variable we want to expand.  */
           val = Var_Parse(str, ctxt, FALSE, &length, &doFree);
           /* We've now got a variable structure to store in. But first,
            * advance the string pointer.  */
           str += length;
   
     return Buf_Retrieve(&buf);          /* Copy all the characters from the variable value straight
            * into the new string.  */
           Buf_AddString(buf, val);
           if (doFree)
               free(val);
       }
 }  }
   
 /*-  /*-

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.24