[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.37 and 1.38

version 1.37, 2000/06/23 16:23:26 version 1.38, 2000/06/23 16:27:29
Line 125 
Line 125 
 #include    <stddef.h>  #include    <stddef.h>
 #include    "make.h"  #include    "make.h"
 #include    "buf.h"  #include    "buf.h"
   #include    "ohash.h"
   #include    "hashconsts.h"
   
 static SymTable *CTXT_GLOBAL, *CTXT_CMD, *CTXT_ENV;  static SymTable *CTXT_GLOBAL, *CTXT_CMD, *CTXT_ENV;
   
 /* `Quick' index variants.  */  
 static char *varnames[] = {  static char *varnames[] = {
     TARGET,      TARGET,
     OODATE,      OODATE,
Line 177 
Line 178 
 #define FIND_ENV        0x4   /* look in the environment also */  #define FIND_ENV        0x4   /* look in the environment also */
   
 typedef struct Var_ {  typedef struct Var_ {
     char          *name;        /* the variable's name */  
     BUFFER        val;          /* its value */      BUFFER        val;          /* its value */
     int           flags;        /* miscellaneous status flags */      int           flags;        /* miscellaneous status flags */
 #define VAR_IN_USE      1           /* Variable's value currently being used.  #define VAR_IN_USE      1           /* Variable's value currently being used.
Line 186 
Line 186 
                                      * should be destroyed when done with                                       * should be destroyed when done with
                                      * it. Used by Var_Parse for undefined,                                       * it. Used by Var_Parse for undefined,
                                      * modified variables */                                       * modified variables */
       char          name[1];      /* the variable's name */
 }  Var;  }  Var;
   
 /* Var*Pattern flags */  /* Var*Pattern flags */
Line 213 
Line 214 
 } VarREPattern;  } VarREPattern;
 #endif  #endif
   
   static struct hash_info var_info = {
           offsetof(Var, name),
       NULL, hash_alloc, hash_free, element_alloc };
   static int quick_lookup __P((const char *, const char **, u_int32_t *));
 #define VarValue(v)     Buf_Retrieve(&((v)->val))  #define VarValue(v)     Buf_Retrieve(&((v)->val))
 static int VarCmp __P((void *, void *));  static int VarCmp __P((void *, void *));
 static Var *VarFind __P((char *, SymTable *, int));  static Var *VarFind __P((char *, SymTable *, int));
Line 239 
Line 244 
 static void VarPrintVar __P((void *));  static void VarPrintVar __P((void *));
 static Boolean VarUppercase __P((char *, Boolean, Buffer, void *));  static Boolean VarUppercase __P((char *, Boolean, Buffer, void *));
 static Boolean VarLowercase __P((char *, Boolean, Buffer, void *));  static Boolean VarLowercase __P((char *, Boolean, Buffer, void *));
 static char *context_name __P((GSymT *));  static const char *context_name __P((GSymT *));
 static Var *new_var __P((char *, char *));  static Var *new_var __P((char *, char *));
 static Var *getvar __P((Lst, char *));  static Var *getvar __P((GSymT *, char *, const char *, u_int32_t));
   
 void  void
 SymTable_Init(ctxt)  SymTable_Init(ctxt)
Line 262 
Line 267 
             VarDelete(ctxt->locals[i]);              VarDelete(ctxt->locals[i]);
 }  }
   
   static int
   quick_lookup(name, end, pk)
       const char *name;
       const char **end;
       u_int32_t *pk;
   {
       size_t len;
   
       *pk = hash_interval(name, end);
       len = *end - name;
           /* substitute short version for long local name */
       switch (*pk % MAGICSLOTS) {             /* MAGICSLOTS should be the    */
       case K_LONGALLSRC % MAGICSLOTS:         /* smallest constant yielding  */
                                               /* distinct case values        */
           if (*pk == K_LONGALLSRC && strncmp(name, LONGALLSRC, len) == 0 &&
               len == strlen(LONGALLSRC))
               return ALLSRC_INDEX;
           break;
       case K_LONGARCHIVE % MAGICSLOTS:
           if (*pk == K_LONGARCHIVE && strncmp(name, LONGARCHIVE, len) == 0 &&
               len == strlen(LONGARCHIVE))
               return ARCHIVE_INDEX;
           break;
       case K_LONGIMPSRC % MAGICSLOTS:
           if (*pk == K_LONGIMPSRC && strncmp(name, LONGIMPSRC, len) == 0 &&
               len == strlen(LONGIMPSRC))
               return IMPSRC_INDEX;
           break;
       case K_LONGMEMBER % MAGICSLOTS:
           if (*pk == K_LONGMEMBER && strncmp(name, LONGMEMBER, len) == 0 &&
               len == strlen(LONGMEMBER))
               return MEMBER_INDEX;
           break;
       case K_LONGOODATE % MAGICSLOTS:
           if (*pk == K_LONGOODATE && strncmp(name, LONGOODATE, len) == 0 &&
               len == strlen(LONGOODATE))
               return OODATE_INDEX;
           break;
       case K_LONGPREFIX % MAGICSLOTS:
           if (*pk == K_LONGPREFIX && strncmp(name, LONGPREFIX, len) == 0 &&
               len == strlen(LONGPREFIX))
               return PREFIX_INDEX;
           break;
       case K_LONGTARGET % MAGICSLOTS:
           if (*pk == K_LONGTARGET && strncmp(name, LONGTARGET, len) == 0 &&
               len == strlen(LONGTARGET))
               return TARGET_INDEX;
           break;
       case K_TARGET % MAGICSLOTS:
           if (name[0] == TARGET[0] && len == 1)
               return TARGET_INDEX;
           break;
       case K_OODATE % MAGICSLOTS:
           if (name[0] == OODATE[0] && len == 1)
               return OODATE_INDEX;
           break;
       case K_ALLSRC % MAGICSLOTS:
           if (name[0] == ALLSRC[0] && len == 1)
               return ALLSRC_INDEX;
           break;
       case K_IMPSRC % MAGICSLOTS:
           if (name[0] == IMPSRC[0] && len == 1)
               return IMPSRC_INDEX;
           break;
       case K_PREFIX % MAGICSLOTS:
           if (name[0] == PREFIX[0] && len == 1)
               return PREFIX_INDEX;
           break;
       case K_ARCHIVE % MAGICSLOTS:
           if (name[0] == ARCHIVE[0] && len == 1)
               return ARCHIVE_INDEX;
           break;
       case K_MEMBER % MAGICSLOTS:
           if (name[0] == MEMBER[0] && len == 1)
               return MEMBER_INDEX;
           break;
       default:
           break;
       }
       return -1;
   }
   
 void  void
 Varq_Set(idx, val, gn)  Varq_Set(idx, val, gn)
     int         idx;      int         idx;
     char        *val;      char        *val;
     GNode       *gn;      GNode       *gn;
 {  {
       /* We only look for a variable in the given context since anything set
        * here will override anything in a lower context, so there's not much
        * point in searching them all just to save a bit of memory...  */
     Var *v = gn->context.locals[idx];      Var *v = gn->context.locals[idx];
   
     if (v == NULL) {      if (v == NULL) {
Line 326 
Line 415 
 }  }
   
   
 static char *  static const char *
 context_name(ctxt)  context_name(ctxt)
     GSymT *ctxt;      GSymT *ctxt;
 {  {
Line 345 
Line 434 
     char *val;      char *val;
 {  {
     Var *v;      Var *v;
       const char *end = NULL;
   
     v = (Var *)emalloc(sizeof(Var));      v = hash_create_entry(&var_info, name, &end);
   
     v->name = estrdup(name);  
   
     if (val != NULL) {      if (val != NULL) {
         size_t len = strlen(val);          size_t len = strlen(val);
         Buf_Init(&(v->val), len+1);          Buf_Init(&(v->val), len+1);
Line 360 
Line 448 
     return v;      return v;
 }  }
   
 /*-  
  *-----------------------------------------------------------------------  
  * VarCmp  --  
  *      See if the given variable matches the named one. Used by getvar.  
  *-----------------------------------------------------------------------  
  */  
 static int  
 VarCmp(v, name)  
     void *v;            /* VAR structure to compare */  
     void *name;         /* name to look for */  
 {  
     return strcmp((char *)name, ((Var *)v)->name);  
 }  
   
 static Var *  static Var *
 getvar(l, n)  getvar(ctxt, name, end, k)
     Lst         l;      GSymT       *ctxt;
     char        *n;      char        *name;
       const char  *end;
       u_int32_t   k;
 {  {
     LstNode ln;      return hash_find(ctxt, hash_lookup_interval(ctxt, name, end, k));
   
     ln = Lst_Find(l, VarCmp, n);  
     if (ln != NULL)  
         return (Var *)Lst_Datum(ln);  
     else  
         return NULL;  
 }  }
   
 /*-  /*-
Line 414 
Line 484 
                                  * environment/VAR_ENV context.  */                                   * environment/VAR_ENV context.  */
 {  {
     Var                 *v;      Var                 *v;
       const char          *end = NULL;
       int                 idx;
       u_int32_t           k;
   
         /*      idx = quick_lookup(name, &end, &k);
          * If the variable name begins with a '.', it could very well be one of  
          * the local ones.  We check the name against all the local variables  
          * and substitute the short version in for 'name' if it matches one of  
          * them.  
          */  
         if (*name == '.' && isupper((unsigned char) name[1]))  
                 switch (name[1]) {  
                 case 'A':  
                         if (!strcmp(name, ".ALLSRC"))  
                                 name = ALLSRC;  
                         if (!strcmp(name, ".ARCHIVE"))  
                                 name = ARCHIVE;  
                         break;  
                 case 'I':  
                         if (!strcmp(name, ".IMPSRC"))  
                                 name = IMPSRC;  
                         break;  
                 case 'M':  
                         if (!strcmp(name, ".MEMBER"))  
                                 name = MEMBER;  
                         break;  
                 case 'O':  
                         if (!strcmp(name, ".OODATE"))  
                                 name = OODATE;  
                         break;  
                 case 'P':  
                         if (!strcmp(name, ".PREFIX"))  
                                 name = PREFIX;  
                         break;  
                 case 'T':  
                         if (!strcmp(name, ".TARGET"))  
                                 name = TARGET;  
                         break;  
                 }  
     /*      /*
      * First look for the variable in the given context. If it's not there,       * First look for the variable in the given context. If it's not there,
      * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,       * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
Line 458 
Line 498 
     if (ctxt == NULL)      if (ctxt == NULL)
         v = NULL;          v = NULL;
     else if (ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD || ctxt == CTXT_ENV)      else if (ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD || ctxt == CTXT_ENV)
         v = getvar((Lst)ctxt, name);          v = getvar((GSymT *)ctxt, name, end, k);
     else {      else {
         v = NULL;          if (idx == -1)
         if (name[1] == '\0')              v = NULL;
             switch(name[0]) {          else
                 case '@':              v = ctxt->locals[idx];
                     v = ctxt->locals[TARGET_INDEX];  
                     break;  
                 case '?':  
                     v = ctxt->locals[OODATE_INDEX];  
                     break;  
                 case '>':  
                     v = ctxt->locals[ALLSRC_INDEX];  
                     break;  
                 case '<':  
                     v = ctxt->locals[IMPSRC_INDEX];  
                     break;  
                 case '*':  
                     v = ctxt->locals[PREFIX_INDEX];  
                     break;  
                 case '!':  
                     v = ctxt->locals[ARCHIVE_INDEX];  
                     break;  
                 case '%':  
                     v = ctxt->locals[MEMBER_INDEX];  
                     break;  
                 default:  
                     break;  
                 }  
     }      }
     if (v != NULL)      if (v != NULL)
         return v;          return v;
   
     if ((flags & FIND_CMD) && ctxt != CTXT_CMD)      if ((flags & FIND_CMD) && ctxt != CTXT_CMD)
         v = getvar(VAR_CMD, name);          v = getvar(VAR_CMD, name, end, k);
     if (v != NULL)      if (v != NULL)
         return v;          return v;
   
     if (!checkEnvFirst && (flags & FIND_GLOBAL) && ctxt != CTXT_GLOBAL)      if (!checkEnvFirst && (flags & FIND_GLOBAL) && ctxt != CTXT_GLOBAL)
         v = getvar(VAR_GLOBAL, name);          v = getvar(VAR_GLOBAL, name, end, k);
     if (v != NULL)      if (v != NULL)
         return v;          return v;
   
     if ((flags & FIND_ENV)) {      if ((flags & FIND_ENV)) {
         char *env;          char *env;
   
         v = getvar(VAR_ENV, name);          v = getvar(VAR_ENV, name, end, k);
         if (v != NULL)          if (v != NULL)
             return v;              return v;
   
Line 513 
Line 530 
     }      }
   
     if (checkEnvFirst && (flags & FIND_GLOBAL) && ctxt != CTXT_GLOBAL)      if (checkEnvFirst && (flags & FIND_GLOBAL) && ctxt != CTXT_GLOBAL)
         v = getvar(VAR_GLOBAL, name);          v = getvar(VAR_GLOBAL, name, end, k);
     return v;      return v;
 }  }
   
Line 537 
Line 554 
     char        *val;   /* value to set it to */      char        *val;   /* value to set it to */
     GSymT       *ctxt;  /* context in which to set it */      GSymT       *ctxt;  /* context in which to set it */
 {  {
     Var   *v;      Var         *v;
       const char  *end = NULL;
       int         idx;
       u_int32_t   k;
   
     v = new_var(name, val);      v = new_var(name, val);
   
     v->flags = 0;      v->flags = 0;
   
     Lst_AtFront(ctxt, v);      idx = quick_lookup(name, &end, &k);
   
       if (idx != -1) {
           Parse_Error(PARSE_FATAL, "Trying to set dynamic variable %s",
               v->name);
       } else
           hash_insert(ctxt, hash_lookup_interval(ctxt, name, end, k), v);
     return v;      return v;
 }  }
   
Line 565 
Line 591 
     void *vp;      void *vp;
 {  {
     Var *v = (Var *) vp;      Var *v = (Var *) vp;
     free(v->name);  
     Buf_Destroy(&(v->val));      Buf_Destroy(&(v->val));
     free(v);      free(v);
 }  }
Line 590 
Line 615 
     char          *name;      char          *name;
     GSymT         *ctxt;      GSymT         *ctxt;
 {  {
     LstNode       ln;      Var *v;
       u_int32_t k;
       const char *end = NULL;
   
     if (DEBUG(VAR))      if (DEBUG(VAR))
         printf("%s:delete %s\n", context_name(ctxt), name);          printf("%s:delete %s\n", context_name(ctxt), name);
       (void)quick_lookup(name, &end, &k);
       v = hash_remove(ctxt, hash_lookup_interval(ctxt, name, end, k));
   
     ln = Lst_Find(ctxt, VarCmp, name);      if (v != NULL)
     if (ln != NULL) {  
         register Var      *v;  
   
         v = (Var *)Lst_Datum(ln);  
         Lst_Remove(ctxt, ln);  
         VarDelete(v);          VarDelete(v);
     }  
 }  }
   
 /*-  /*-
Line 640 
Line 663 
      * point in searching them all just to save a bit of memory...       * point in searching them all just to save a bit of memory...
      */       */
     v = VarFind(name, (SymTable *)ctxt, 0);      v = VarFind(name, (SymTable *)ctxt, 0);
     if (v == NULL) {      if (v == NULL)
         (void)VarAdd(name, val, ctxt);          (void)VarAdd(name, val, ctxt);
     } else {      else {
         Buf_Reset(&(v->val));          Buf_Reset(&(v->val));
         Buf_AddString(&(v->val), val);          Buf_AddString(&(v->val), val);
   
Line 2471 
Line 2494 
     VAR_GLOBAL = &global_vars;      VAR_GLOBAL = &global_vars;
     VAR_CMD = &cmd_vars;      VAR_CMD = &cmd_vars;
     VAR_ENV = &env_vars;      VAR_ENV = &env_vars;
     Lst_Init(VAR_GLOBAL);      hash_init(VAR_GLOBAL, 10, &var_info);
     Lst_Init(VAR_CMD);      hash_init(VAR_CMD, 5, &var_info);
     Lst_Init(VAR_ENV);      hash_init(VAR_ENV, 5, &var_info);
     CTXT_GLOBAL = (SymTable *)VAR_GLOBAL;      CTXT_GLOBAL = (SymTable *)VAR_GLOBAL;
     CTXT_CMD = (SymTable *)VAR_CMD;      CTXT_CMD = (SymTable *)VAR_CMD;
     CTXT_ENV = (SymTable *)VAR_ENV;      CTXT_ENV = (SymTable *)VAR_ENV;
Line 2484 
Line 2507 
 Var_End()  Var_End()
 {  {
 #ifdef CLEANUP  #ifdef CLEANUP
     Lst_Destroy(VAR_GLOBAL, VarDelete);      Var *v;
     Lst_Destroy(VAR_CMD, VarDelete);      unsigned int i;
     Lst_Destroy(VAR_END, VarDelete);  
       for (v = hash_first(VAR_GLOBAL, &i); v != NULL;
           v = hash_next(VAR_GLOBAL, &i))
               VarDelete(v);
       for (v = hash_first(VAR_CMD, &i); v != NULL;
           v = hash_next(VAR_CMD, &i))
               VarDelete(v);
       for (v = hash_first(VAR_ENV, &i); v != NULL;
           v = hash_next(VAR_ENV, &i))
               VarDelete(v);
 #endif  #endif
 }  }
   
Line 2511 
Line 2543 
 Var_Dump(ctxt)  Var_Dump(ctxt)
    GSymT        *ctxt;     GSymT        *ctxt;
 {  {
     Lst_Every(ctxt, VarPrintVar);          Var *v;
           unsigned int i;
   
           for (v = hash_first(ctxt, &i); v != NULL;
               v = hash_next(ctxt, &i))
                   VarPrintVar(v);
 }  }
   

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