[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.54 and 1.55

version 1.54, 2001/05/15 13:31:03 version 1.55, 2001/05/23 12:34:51
Line 66 
Line 66 
  * SUCH DAMAGE.   * SUCH DAMAGE.
  */   */
   
 /*-  #include <sys/types.h>
  * var.c --  #include <assert.h>
  *      Variable-handling functions  #include <stddef.h>
  *  #include <stdio.h>
  * Basic interface:  #include <stdlib.h>
  *      Var_Set             Set the value of a variable in the given  #include <string.h>
  *                          context. The variable is created if it doesn't  
  *                          yet exist. The value and variable name need not  
  *                          be preserved.  
  *  
  *      Var_Append          Append more characters to an existing variable  
  *                          in the given context. The variable needn't  
  *                          exist already -- it will be created if it doesn't.  
  *                          A space is placed between the old value and the  
  *                          new one.  
  *  
  *      Var_Value           Return the value of a variable in a context or  
  *                          NULL if the variable is undefined.  
  *  
  *      Var_Delete          Delete a variable in a context.  
  *  
  *      Var_Init            Initialize this module.  
  *  
  * Fast interface:  
  *      Varq_Set, Varq_Append, Varq_Value:  
  *                          Use index form of local variables  
  *  
  * Higher level functions:  
  *      Var_Subst           Substitute variables in a string using  
  *                          the given context as the top-most one. If the  
  *                          third argument is non-zero, Parse_Error is  
  *                          called if any variables are undefined.  
  *  
  *      Var_SubstVar        Substitute a named variable in a string using  
  *                          the given context as the top-most one,  
  *                          accumulating the result into a user-supplied  
  *                          buffer.  
  *  
  *      Var_Parse           Parse a variable expansion from a string and  
  *                          return the result and the number of characters  
  *                          consumed.  
  *  
  * Debugging:  
  *      Var_Dump            Print out all global variables.  
  */  
   
 #include    <assert.h>  #include "config.h"
 #include    <ctype.h>  #include "defines.h"
 #include    <stdlib.h>  #include "buf.h"
 #include    <stddef.h>  #include "stats.h"
 #include    <string.h>  #include "ohash.h"
 #include    "make.h"  #include "varmodifiers.h"
 #include    "buf.h"  #include "var.h"
 #include    "stats.h"  #include "varname.h"
 #include    "ohash.h"  #include "error.h"
 #include    "varmodifiers.h"  #include "str.h"
   #include "var_int.h"
   #include "memory.h"
   #include "symtable.h"
   #include "gnode.h"
   
 #ifndef lint  /* extended indices for System V stuff */
 #if 0  #define FTARGET_INDEX   7
 static char sccsid[] = "@(#)var.c       8.3 (Berkeley) 3/19/94";  #define DTARGET_INDEX   8
 #else  #define FPREFIX_INDEX   9
 UNUSED  #define DPREFIX_INDEX   10
 static char rcsid[] = "$OpenBSD$";  #define FARCHIVE_INDEX  11
 #endif  #define DARCHIVE_INDEX  12
 #endif /* not lint */  #define FMEMBER_INDEX   13
   #define DMEMBER_INDEX   14
   
   #define EXTENDED2SIMPLE(i)      (((i)-LOCAL_SIZE)/2)
   #define IS_EXTENDED_F(i)        ((i)%2 == 1)
   
 /*  /*
  * This is a harmless return value for Var_Parse that can be used by Var_Subst   * This is a harmless return value for Var_Parse that can be used by Var_Subst
Line 210 
Line 178 
 static int quick_lookup(const char *, const char **, u_int32_t *);  static int quick_lookup(const char *, const char **, u_int32_t *);
 #define VarValue(v)     Buf_Retrieve(&((v)->val))  #define VarValue(v)     Buf_Retrieve(&((v)->val))
 static Var *varfind(const char *, const char *, SymTable *, int, int, u_int32_t);  static Var *varfind(const char *, const char *, SymTable *, int, int, u_int32_t);
 static Var *VarFind_interval(const char *, const char *, SymTable *, int);  static Var *VarFindi(const char *, const char *, SymTable *, int);
 static Var *VarAdd(const char *, const char *, u_int32_t, const char *, GSymT *);  static Var *VarAdd(const char *, const char *, u_int32_t, const char *, GSymT *);
 static void VarDelete(void *);  static void VarDelete(void *);
 static void VarPrintVar(Var *);  static void VarPrintVar(Var *);
Line 230 
Line 198 
 /* retrieve the hashed values  for well-known variables.  */  /* retrieve the hashed values  for well-known variables.  */
 #include    "varhashconsts.h"  #include    "varhashconsts.h"
   
 /* Parse a variable name for embedded $, to handle recursive variables */  
 const char *  
 Var_Name_Get(start, name, ctxt, err, cont)  
         const char      *start; /* start of variable spec */  
         struct Name     *name;  /* result, might be a copy or not */  
         SymTable        *ctxt;  /* context in which to expand */  
         Boolean         err;    /* whether to error out for undefined sub */  
         const char *(*cont)(const char *);  
                                 /* hook: find the next interesting character */  
 {  
         const char *p;  
         size_t len;  
   
         p = cont(start);  
         /* If we don't want recursive variables, we skip over '$' */  
         if (!FEATURES(FEATURE_RECVARS)) {  
                 while (*p == '$')  
                     p = cont(p);  
         }  
         if (*p != '$') {  
                 name->s = start;  
                 name->e = p;  
                 name->tofree = FALSE;  
                 return p;  
         } else {  
                 BUFFER buf;  
                 Buf_Init(&buf, MAKE_BSIZE);  
                 for (;;) {  
                         Buf_AddInterval(&buf, start, p);  
                         if (*p != '$') {  
                                 name->s = (const char *)Buf_Retrieve(&buf);  
                                 name->e = name->s + Buf_Size(&buf);  
                                 name->tofree = TRUE;  
                                 return p;  
                         }  
                         start = p;  
                         Var_ParseBuffer(&buf, start, ctxt, err, &len);  
                         start += len;  
                         p = cont(start);  
                 }  
         }  
 }  
   
 void  void
 Var_Name_Free(name)  
         struct Name *name;  
 {  
         if (name->tofree)  
                 free((char *)name->s);  
 }  
   
 void  
 SymTable_Init(ctxt)  SymTable_Init(ctxt)
     SymTable    *ctxt;      SymTable    *ctxt;
 {  {
Line 573 
Line 490 
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * VarFind_interval --   * VarFindi --
  *      Find the given variable in the given context and any other contexts   *      Find the given variable in the given context and any other contexts
  *      indicated.  if end is NULL, name is a string, otherwise, only   *      indicated.  if end is NULL, name is a string, otherwise, only
  *      the interval name - end  is concerned.   *      the interval name - end  is concerned.
Line 584 
Line 501 
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
 static Var *  static Var *
 VarFind_interval(name, end, ctxt, flags)  VarFindi(name, end, ctxt, flags)
     const char          *name;  /* name to find */      const char          *name;  /* name to find */
     const char          *end;   /* end of name */      const char          *end;   /* end of name */
     SymTable            *ctxt;  /* context in which to find it */      SymTable            *ctxt;  /* context in which to find it */
Line 725 
Line 642 
   
   
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_Delete --  
  *      Remove a global variable.  
  *  
  * Side Effects:  
  *      The Var structure is removed and freed.  
  *-----------------------------------------------------------------------  
  */  
 void  void
 Var_Delete(name)  Var_Delete(name)
     const char    *name;      const char    *name;
Line 759 
Line 667 
     }      }
 }  }
   
 /*-  /*      The variable is searched for only in its context before being
  *-----------------------------------------------------------------------  
  * Var_Set --  
  *      Set the variable name to the value val in the given context.  
  *  
  * Side Effects:  
  *      If the variable doesn't yet exist, a new record is created for it.  
  *      Else the old value is freed and the new one stuck in its place  
  *  
  * Notes:  
  *      The variable is searched for only in its context before being  
  *      created in that context. I.e. if the context is CTXT_GLOBAL,   *      created in that context. I.e. if the context is CTXT_GLOBAL,
  *      only CTXT_GLOBAL is searched. Likewise if it is CTXT_CMD, only   *      only CTXT_GLOBAL is searched. Likewise if it is CTXT_CMD, only
  *      CTXT_CMD is searched.   *      CTXT_CMD is searched.
  *-----------------------------------------------------------------------  
  */   */
 void  void
 Var_Set_interval(name, end, val, ctxt)  Var_Seti(name, end, val, ctxt)
     const char  *name;  /* name of variable to set */      const char  *name;  /* name of variable to set */
     const char  *end;      const char  *end;
     const char  *val;   /* value to give to the variable */      const char  *val;   /* value to give to the variable */
Line 817 
Line 714 
         esetenv(v->name, val);          esetenv(v->name, val);
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_Append --  
  *      The variable of the given name has the given value appended to it in  
  *      the given context.  
  *  
  * Side Effects:  
  *      If the variable doesn't exist, it is created. Else the strings  
  *      are concatenated (with a space in between).  
  *  
  *-----------------------------------------------------------------------  
  */  
 void  void
 Var_Append_interval(name, end, val, ctxt)  Var_Appendi(name, end, val, ctxt)
     const char  *name;  /* Name of variable to modify */      const char  *name;  /* Name of variable to modify */
     const char  *end;      const char  *end;
     const char  *val;   /* String to append to it */      const char  *val;   /* String to append to it */
Line 863 
Line 748 
         printf("%s:%s = %s\n", context_name(ctxt), v->name, VarValue(v));          printf("%s:%s = %s\n", context_name(ctxt), v->name, VarValue(v));
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_Value --  
  *      Return the value of a global named variable  
  *  
  * Results:  
  *      The value if the variable exists, NULL if it doesn't  
  *-----------------------------------------------------------------------  
  */  
 char *  char *
 Var_Value_interval(name, end)  Var_Valuei(name, end)
     const char  *name;  /* name to find */      const char  *name;  /* name to find */
     const char  *end;      const char  *end;
 {  {
     Var            *v;      Var            *v;
   
     v = VarFind_interval(name, end, NULL, FIND_ENV | FIND_MINE);      v = VarFindi(name, end, NULL, FIND_ENV | FIND_MINE);
     if (v != NULL && (v->flags & VAR_DUMMY) == 0)      if (v != NULL && (v->flags & VAR_DUMMY) == 0)
         return VarValue(v);          return VarValue(v);
     else      else
Line 929 
Line 805 
         }          }
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_ParseSkip --  
  *      Do whatever is needed to skip over a var specification.  Since the  
  *      result is not needed at this point, some shortcuts may be taken.  
  *  
  * Return value: the amount to skip  
  *-----------------------------------------------------------------------  
  */  
 size_t  size_t
 Var_ParseSkip(str, ctxt, result)  Var_ParseSkip(str, ctxt, result)
     const char  *str;      const char  *str;
     SymTable    *ctxt;      SymTable    *ctxt;
     ReturnStatus *result;      bool *result;
 {  {
     const char  *tstr;          /* Pointer into str */      const char  *tstr;          /* Pointer into str */
     Var         *v;             /* Variable in invocation */      Var         *v;             /* Variable in invocation */
Line 957 
Line 824 
     str++;      str++;
   
     if (*str != '(' && *str != '{') {      if (*str != '(' && *str != '{') {
         name.tofree = FALSE;          name.tofree = false;
         tstr = str + 1;          tstr = str + 1;
         length = 2;          length = 2;
         endc = '\0';          endc = '\0';
Line 966 
Line 833 
         str++;          str++;
   
         /* Find eventual modifiers in the variable */          /* Find eventual modifiers in the variable */
         tstr = Var_Name_Get(str, &name, ctxt, FALSE, find_pos(endc));          tstr = VarName_Get(str, &name, ctxt, false, find_pos(endc));
         Var_Name_Free(&name);          VarName_Free(&name);
         length = tstr - start;          length = tstr - start;
         /* Terminated correctly */          if (*tstr != 0)
         if (*tstr != '\0')              length++;
                 length++;  
     }      }
   
     if (result != NULL)      if (result != NULL)
         *result = SUCCESS;          *result = true;
     if (*tstr == ':' && endc != '\0')      if (*tstr == ':' && endc != '\0')
          if (VarModifiers_Apply(NULL, NULL, ctxt, TRUE, NULL, tstr, endc,           if (VarModifiers_Apply(NULL, NULL, ctxt, true, NULL, tstr, endc,
             &length) == var_Error)              &length) == var_Error)
                 *result = FAILURE;                  *result = false;
     return length;      return length;
 }  }
   
 /*-  /* As of now, Var_ParseBuffer is just a wrapper around Var_Parse. For
  *-----------------------------------------------------------------------   * speed, it may be better to revisit the implementation to do things
  * Var_ParseBuffer --   * directly. */
  *      Given the start of a variable invocation, extract the variable  bool
  *      name and find its value, then modify it according to the  
  *      specification, and add the result to the buffer.  
  *  
  * Results:  
  *      FAILURE for invalid specifications.  
  *  
  * Side-effects:  
  *      The length of the specification is placed in *lengthPtr  
  *      (for invalid specifications, this is just 2...?).  
  *-----------------------------------------------------------------------  
  */  
 ReturnStatus  
 Var_ParseBuffer(buf, str, ctxt, err, lengthPtr)  Var_ParseBuffer(buf, str, ctxt, err, lengthPtr)
     Buffer      buf;      Buffer      buf;
     const char  *str;      const char  *str;
     SymTable    *ctxt;      SymTable    *ctxt;
     Boolean     err;      bool        err;
     size_t      *lengthPtr;      size_t      *lengthPtr;
 {  {
     char        *result;      char        *result;
     Boolean     freeIt;      bool        freeIt;
   
     result = Var_Parse(str, ctxt, err, lengthPtr, &freeIt);      result = Var_Parse(str, ctxt, err, lengthPtr, &freeIt);
     if (result == var_Error)      if (result == var_Error)
         return FAILURE;          return false;
   
     Buf_AddString(buf, result);      Buf_AddString(buf, result);
     if (freeIt)      if (freeIt)
         free(result);          free(result);
     return SUCCESS;      return true;
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_Parse --  
  *      Given the start of a variable invocation, extract the variable  
  *      name and find its value, then modify it according to the  
  *      specification.  
  *  
  * Results:  
  *      The (possibly-modified) value of the variable or var_Error if the  
  *      specification is invalid. The length of the specification is  
  *      placed in *lengthPtr (for invalid specifications, this is just  
  *      2...?).  
  *      A Boolean in *freePtr telling whether the returned string should  
  *      be freed by the caller.  
  *-----------------------------------------------------------------------  
  */  
 char *  char *
 Var_Parse(str, ctxt, err, lengthPtr, freePtr)  Var_Parse(str, ctxt, err, lengthPtr, freePtr)
     const char  *str;           /* The string to parse */      const char  *str;           /* The string to parse */
     SymTable    *ctxt;          /* The context for the variable */      SymTable    *ctxt;          /* The context for the variable */
     Boolean     err;            /* TRUE if undefined variables are an error */      bool        err;            /* true if undefined variables are an error */
     size_t      *lengthPtr;     /* OUT: The length of the specification */      size_t      *lengthPtr;     /* OUT: The length of the specification */
     Boolean     *freePtr;       /* OUT: TRUE if caller should free result */      bool        *freePtr;       /* OUT: true if caller should free result */
 {  {
     const char  *tstr;          /* Pointer into str */      const char  *tstr;          /* Pointer into str */
     Var         *v;             /* Variable in invocation */      Var         *v;             /* Variable in invocation */
Line 1053 
Line 891 
     u_int32_t   k;      u_int32_t   k;
     int         idx;      int         idx;
   
     *freePtr = FALSE;      *freePtr = false;
     start = str++;      start = str++;
   
     val = NULL;      val = NULL;
Line 1063 
Line 901 
     if (*str != '(' && *str != '{') {      if (*str != '(' && *str != '{') {
         name.s = str;          name.s = str;
         name.e = str+1;          name.e = str+1;
         name.tofree = FALSE;          name.tofree = false;
         tstr = str + 1;          tstr = str + 1;
         *lengthPtr = 2;          *lengthPtr = 2;
         endc = '\0';          endc = '\0';
Line 1072 
Line 910 
         str++;          str++;
   
         /* Find eventual modifiers in the variable */          /* Find eventual modifiers in the variable */
         tstr = Var_Name_Get(str, &name, ctxt, FALSE, find_pos(endc));          tstr = VarName_Get(str, &name, ctxt, false, find_pos(endc));
         *lengthPtr = tstr - start;          *lengthPtr = tstr - start;
         if (*tstr != '\0')          if (*tstr != '\0')
                 (*lengthPtr)++;                  (*lengthPtr)++;
Line 1098 
Line 936 
         if (idx == -1) {          if (idx == -1) {
             if (strchr(val, '$') != NULL) {              if (strchr(val, '$') != NULL) {
                 val = Var_Subst(val, ctxt, err);                  val = Var_Subst(val, ctxt, err);
                 *freePtr = TRUE;                  *freePtr = true;
             }              }
         } else if (idx >= LOCAL_SIZE) {          } else if (idx >= LOCAL_SIZE) {
             if (IS_EXTENDED_F(idx))              if (IS_EXTENDED_F(idx))
                 val = Var_GetTail(val);                  val = Var_GetTail(val);
             else              else
                 val = Var_GetHead(val);                  val = Var_GetHead(val);
             *freePtr = TRUE;              *freePtr = true;
         }          }
         v->flags &= ~VAR_IN_USE;          v->flags &= ~VAR_IN_USE;
     }      }
Line 1118 
Line 956 
         if (idx != -1) {          if (idx != -1) {
             /* can't be expanded for now: copy the var spec instead. */              /* can't be expanded for now: copy the var spec instead. */
             if (ctxt == NULL || ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD) {              if (ctxt == NULL || ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD) {
                 *freePtr = TRUE;                  *freePtr = true;
                 val = interval_dup(start, start+ *lengthPtr);                  val = Str_dupi(start, start+ *lengthPtr);
             } else {              } else {
             /* somehow, this should have been expanded already. */              /* somehow, this should have been expanded already. */
                 GNode *n;                  GNode *n;
Line 1139 
Line 977 
             }              }
         }          }
     }      }
     Var_Name_Free(&name);      VarName_Free(&name);
     return val;      return val;
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_Subst  --  
  *      Substitute for all variables in a string in a context  
  *      If undefErr is TRUE, Parse_Error will be called when an undefined  
  *      variable is encountered.  
  *  
  * Results:  
  *      The resulting string.  
  *  
  * Side Effects:  
  *      The new string must be freed by the caller  
  *-----------------------------------------------------------------------  
  */  
 char *  char *
 Var_Subst(str, ctxt, undefErr)  Var_Subst(str, ctxt, undefErr)
     const char    *str;             /* the string in which to substitute */      const char    *str;             /* the string in which to substitute */
     SymTable      *ctxt;            /* the context wherein to find variables */      SymTable      *ctxt;            /* the context wherein to find variables */
     Boolean       undefErr;         /* TRUE if undefineds are an error */      bool          undefErr;         /* true if undefineds are an error */
 {  {
     BUFFER        buf;              /* Buffer for forming things */      BUFFER        buf;              /* Buffer for forming things */
     static Boolean errorReported;   /* Set true if an error has already      static bool 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 */
   
     Buf_Init(&buf, MAKE_BSIZE);      Buf_Init(&buf, MAKE_BSIZE);
     errorReported = FALSE;      errorReported = false;
   
     for (;;) {      for (;;) {
         char            *val;           /* Value to substitute for a variable */          char            *val;           /* Value to substitute for a variable */
         size_t          length;         /* Length of the variable invocation */          size_t          length;         /* Length of the variable invocation */
         Boolean         doFree;         /* Set true if val should be freed */          bool    doFree;         /* Set true if val should be freed */
         const char *cp;          const char *cp;
   
         /* copy uninteresting stuff */          /* copy uninteresting stuff */
         for (cp = str; *str != '\0' && *str != '$'; str++)          for (cp = str; *str != '\0' && *str != '$'; str++)
             ;              ;
         Buf_AddInterval(&buf, cp, str);          Buf_Addi(&buf, cp, str);
         if (*str == '\0')          if (*str == '\0')
             break;              break;
         if (str[1] == '$') {          if (str[1] == '$') {
Line 1209 
Line 1033 
                     Parse_Error(PARSE_FATAL,                      Parse_Error(PARSE_FATAL,
                                  "Undefined variable \"%.*s\"",length,str);                                   "Undefined variable \"%.*s\"",length,str);
                 str += length;                  str += length;
                 errorReported = TRUE;                  errorReported = true;
             } else {              } else {
                 Buf_AddChar(&buf, *str);                  Buf_AddChar(&buf, *str);
                 str++;                  str++;
Line 1229 
Line 1053 
     return  Buf_Retrieve(&buf);      return  Buf_Retrieve(&buf);
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_SubstVar  --  
  *      Substitute for one variable in the given string in the given context  
  *      If undefErr is TRUE, Parse_Error will be called when an undefined  
  *      variable is encountered. Add the substituted string to buffer.  
  *-----------------------------------------------------------------------  
  */  
 void  void
 Var_SubstVar(buf, str, var, val)  Var_SubstVar(buf, str, var, val)
     Buffer      buf;      Buffer      buf;
Line 1252 
Line 1068 
         /* Copy uninteresting stuff */          /* Copy uninteresting stuff */
         for (start = str; *str != '\0' && *str != '$'; str++)          for (start = str; *str != '\0' && *str != '$'; str++)
             ;              ;
         Buf_AddInterval(buf, start, str);          Buf_Addi(buf, start, str);
   
         start = str;          start = str;
         if (*str++ == '\0')          if (*str++ == '\0')
Line 1260 
Line 1076 
         str++;          str++;
         /* and escaped dollars */          /* and escaped dollars */
         if (start[1] == '$') {          if (start[1] == '$') {
             Buf_AddInterval(buf, start, start+2);              Buf_Addi(buf, start, start+2);
             continue;              continue;
         }          }
         /* Simple variable, if it's not us, copy.  */          /* Simple variable, if it's not us, copy.  */
Line 1286 
Line 1102 
              * expand the external variable at this point, so we try               * expand the external variable at this point, so we try
              * again with the nested variable.  */               * again with the nested variable.  */
             if (*p == '$') {              if (*p == '$') {
                 Buf_AddInterval(buf, start, p);                  Buf_Addi(buf, start, p);
                 str = p;                  str = p;
                 continue;                  continue;
             }              }
Line 1294 
Line 1110 
             if (strncmp(var, str, p - str) != 0 ||              if (strncmp(var, str, p - str) != 0 ||
                 var[p - str] != '\0') {                  var[p - str] != '\0') {
                 /* Not the variable we want to expand.  */                  /* Not the variable we want to expand.  */
                 Buf_AddInterval(buf, start, p);                  Buf_Addi(buf, start, p);
                 str = p;                  str = p;
                 continue;                  continue;
             }              }
             if (*p == ':') {              if (*p == ':') {
                 size_t  length;         /* Length of the variable invocation */                  size_t  length;         /* Length of the variable invocation */
                 Boolean doFree;         /* Set true if val should be freed */                  bool doFree;    /* Set true if val should be freed */
                 char    *newval;        /* Value substituted for a variable */                  char    *newval;        /* Value substituted for a variable */
                 struct Name name;                  struct Name name;
   
                 length = p - str + 1;                  length = p - str + 1;
                 doFree = FALSE;                  doFree = false;
                 name.s = var;                  name.s = var;
                 name.e = var + (p-str);                  name.e = var + (p-str);
   
                 /* val won't be freed since doFree == FALSE, but                  /* val won't be freed since doFree == false, but
                  * VarModifiers_Apply doesn't know that, hence the cast. */                   * VarModifiers_Apply doesn't know that, hence the cast. */
                 newval = VarModifiers_Apply((char *)val, &name, NULL, FALSE,                  newval = VarModifiers_Apply((char *)val, &name, NULL, false,
                     &doFree, p, endc, &length);                      &doFree, p, endc, &length);
                 Buf_AddString(buf, newval);                  Buf_AddString(buf, newval);
                 if (doFree)                  if (doFree)
Line 1350 
Line 1166 
 }  }
   
   
   #ifdef CLEANUP
 void  void
 Var_End()  Var_End()
 {  {
 #ifdef CLEANUP  
     Var *v;      Var *v;
     unsigned int i;      unsigned int i;
   
Line 1363 
Line 1179 
     for (v = ohash_first(VAR_CMD, &i); v != NULL;      for (v = ohash_first(VAR_CMD, &i); v != NULL;
         v = ohash_next(VAR_CMD, &i))          v = ohash_next(VAR_CMD, &i))
             VarDelete(v);              VarDelete(v);
 #endif  
 }  }
   #endif
   
 static const char *interpret(int);  static const char *interpret(int);
   
Line 1387 
Line 1203 
         (v->flags & VAR_DUMMY) == 0 ? VarValue(v) : "(none)");          (v->flags & VAR_DUMMY) == 0 ? VarValue(v) : "(none)");
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * Var_Dump --  
  *      print all variables  
  *-----------------------------------------------------------------------  
  */  
 void  void
 Var_Dump()  Var_Dump()
 {  {

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.55