Create VAR_ENV context, and fill it with everything in the environment.
authorMax Okumoto <okumoto@dragonflybsd.org>
Fri, 15 Apr 2005 21:06:35 +0000 (21:06 +0000)
committerMax Okumoto <okumoto@dragonflybsd.org>
Fri, 15 Apr 2005 21:06:35 +0000 (21:06 +0000)
usr.bin/make/main.c
usr.bin/make/var.c
usr.bin/make/var.h

index 8d6e1a2..c79da5b 100644 (file)
@@ -38,7 +38,7 @@
  * @(#) Copyright (c) 1988, 1989, 1990, 1993 The Regents of the University of California.  All rights reserved.
  * @(#)main.c  8.3 (Berkeley) 3/19/94
  * $FreeBSD: src/usr.bin/make/main.c,v 1.118 2005/02/13 13:33:56 harti Exp $
- * $DragonFly: src/usr.bin/make/main.c,v 1.72 2005/04/15 21:05:52 okumoto Exp $
+ * $DragonFly: src/usr.bin/make/main.c,v 1.73 2005/04/15 21:06:34 okumoto Exp $
  */
 
 /*
@@ -93,6 +93,8 @@
 
 #define        MAKEFLAGS       ".MAKEFLAGS"
 
+extern char **environ; /* XXX what header declares this variable? */
+
 /* Targets to be made */
 Lst create = Lst_Initializer(create);
 
@@ -607,7 +609,7 @@ main(int argc, char **argv)
         */
        Dir_Init();             /* Initialize directory structures so -I flags
                                 * can be processed correctly */
-       Var_Init();             /* As well as the lists of variables for
+       Var_Init(environ);      /* As well as the lists of variables for
                                 * parsing arguments */
         str_init();
 
index 2be503c..a1c33c7 100644 (file)
@@ -37,7 +37,7 @@
  *
  * @(#)var.c   8.3 (Berkeley) 3/19/94
  * $FreeBSD: src/usr.bin/make/var.c,v 1.83 2005/02/11 10:49:01 harti Exp $
- * $DragonFly: src/usr.bin/make/var.c,v 1.184 2005/04/15 20:45:48 okumoto Exp $
+ * $DragonFly: src/usr.bin/make/var.c,v 1.185 2005/04/15 21:06:34 okumoto Exp $
  */
 
 /*-
@@ -140,6 +140,7 @@ static char varNoError[] = "";
  * The four contexts are searched in the reverse order from which they are
  * listed.
  */
+GNode  *VAR_ENV;       /* variables from the environment */
 GNode  *VAR_GLOBAL;    /* variables from the makefile */
 GNode  *VAR_CMD;       /* variables defined on the command-line */
 
@@ -278,19 +279,14 @@ static Var *
 VarFindEnv(const char name[], GNode *ctxt)
 {
        Var     *var;
-       char    *env;
 
        name = VarLocal(name);
 
-       /* First look for the variable in the given context. */
        if ((var = VarLookup(&ctxt->context, name)) != NULL)
                return (var);
 
-       /* Look for the variable in the environment. */
-       if ((env = getenv(name)) != NULL) {
-               /* craft this variable from the environment value */
-               return (VarCreate(name, env, VAR_FROM_ENV));
-       }
+       if ((var = VarLookup(&VAR_ENV->context, name)) != NULL)
+               return (var);
 
        return (NULL);
 }
@@ -314,7 +310,6 @@ VarFindAny(const char name[], GNode *ctxt)
        Boolean localCheckEnvFirst;
        LstNode *ln;
        Var     *var;
-       char    *env;
 
        name = VarLocal(name);
 
@@ -350,11 +345,8 @@ VarFindAny(const char name[], GNode *ctxt)
                        return (var);
        }
 
-       /* look in the environment */
-       if ((env = getenv(name)) != NULL) {
-               /* craft this variable from the environment value */
-               return (VarCreate(name, env, VAR_FROM_ENV));
-       }
+       if ((var = VarLookup(&VAR_ENV->context, name)) != NULL)
+               return (var);
 
        /* deferred check for the environment (in case of -e/-E) */
        if ((ctxt != VAR_GLOBAL) && (checkEnvFirst || localCheckEnvFirst)) {
@@ -365,10 +357,8 @@ VarFindAny(const char name[], GNode *ctxt)
        return (NULL);
 }
 
-/*-
- *-----------------------------------------------------------------------
- * VarAdd  --
- *     Add a new variable of name name and value val to the given context.
+/**
+ * Add a new variable of name name and value val to the given context.
  *
  * Results:
  *     None
@@ -377,7 +367,6 @@ VarFindAny(const char name[], GNode *ctxt)
  *     The new variable is placed at the front of the given context
  *     The name and val arguments are duplicated so they may
  *     safely be freed.
- *-----------------------------------------------------------------------
  */
 static void
 VarAdd(const char *name, const char *val, GNode *ctxt)
@@ -451,19 +440,30 @@ Var_Set(const char *name, const char *val, GNode *ctxt)
        v = VarFindOnly(n, ctxt);
        if (v == NULL) {
                VarAdd(n, val, ctxt);
+               if (ctxt == VAR_CMD) {
+                       /*
+                        * Any variables given on the command line
+                        * are automatically exported to the
+                        * environment (as per POSIX standard)
+                        */
+                       setenv(n, val, 1);
+               }
        } else {
                Buf_Clear(v->val);
                Buf_Append(v->val, val);
 
-               DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n, val));
-       }
-       /*
-        * Any variables given on the command line are automatically exported
-        * to the environment (as per POSIX standard)
-        */
-       if (ctxt == VAR_CMD || (v != NULL && (v->flags & VAR_TO_ENV))) {
-               setenv(n, val, 1);
+               if (ctxt == VAR_CMD || (v->flags & VAR_TO_ENV)) {
+                       /*
+                        * Any variables given on the command line
+                        * are automatically exported to the
+                        * environment (as per POSIX standard)
+                        */
+                       setenv(n, val, 1);
+               }
+
        }
+
+       DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n, val));
        free(n);
 }
 
@@ -476,9 +476,24 @@ Var_SetEnv(const char *name, GNode *ctxt)
 {
        Var    *v;
 
+       v = VarFindOnly(name, VAR_CMD);
+       if (v != NULL) {
+               /*
+                * Do not allow .EXPORT: to be set on variables
+                * from the comand line or MAKEFLAGS.
+                */
+               Error(
+                   "Warning: Did not set .EXPORT: on %s because it "
+                   "is from the comand line or MAKEFLAGS", name);
+               return;
+       }
+
        v = VarFindAny(name, ctxt);
        if (v == NULL) {
-               Error("Cannot set environment flag on non-existant variable %s", name);
+               Lst_AtFront(&VAR_ENV->context,
+                   VarCreate(name, NULL, VAR_TO_ENV));
+               setenv(name, "", 1);
+               Error("Warning: .EXPORT: set on undefined variable %s", name);
        } else {
                if ((v->flags & VAR_TO_ENV) == 0) {
                        v->flags |= VAR_TO_ENV;
@@ -523,21 +538,6 @@ Var_Append(const char *name, const char *val, GNode *ctxt)
        }
        if (v == NULL) {
                VarAdd(n, val, ctxt);
-
-       } else if (v->flags & VAR_FROM_ENV) {
-               Buf_AddByte(v->val, (Byte)' ');
-               Buf_Append(v->val, val);
-               DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n, Buf_Data(v->val)));
-               /*
-                * If the original variable came from the
-                * environment, we have to install it in the global
-                * context (we could place it in the environment, but
-                * then we should provide a way to export other
-                * variables...)
-                */
-               v->flags &= ~VAR_FROM_ENV;
-               Lst_AtFront(&ctxt->context, v);
-
        } else {
                Buf_AddByte(v->val, (Byte)' ');
                Buf_Append(v->val, val);
@@ -570,10 +570,6 @@ Var_Exists(const char *name, GNode *ctxt)
        if (v == NULL) {
                free(n);
                return (FALSE);
-       } else if (v->flags & VAR_FROM_ENV) {
-               VarDestroy(v, TRUE);
-               free(n);
-               return (TRUE);
        } else {
                free(n);
                return (TRUE);
@@ -604,10 +600,6 @@ Var_Value(const char *name, GNode *ctxt, char **frp)
        if (v == NULL) {
                p = NULL;
                *frp = NULL;
-       } else if (v->flags & VAR_FROM_ENV) {
-               p = Buf_Data(v->val);
-               *frp = p;
-               VarDestroy(v, FALSE);
        } else {
                p = Buf_Data(v->val);
                *frp = NULL;
@@ -1329,10 +1321,6 @@ ParseRestModifier(VarParser *vp, char startc, Buffer *buf, Boolean *freeResult)
        v = VarFindAny(vname, vp->ctxt);
        if (v != NULL) {
                value = ParseModifier(vp, startc, v, freeResult);
-
-               if (v->flags & VAR_FROM_ENV) {
-                       VarDestroy(v, TRUE);
-               }
                return (value);
        }
 
@@ -1439,11 +1427,6 @@ ParseRestEnd(VarParser *vp, Buffer *buf, Boolean *freeResult)
        v = VarFindAny(vname, vp->ctxt);
        if (v != NULL) {
                value = VarExpand(v, vp);
-
-               if (v->flags & VAR_FROM_ENV) {
-                       VarDestroy(v, TRUE);
-               }
-
                *freeResult = TRUE;
                return (value);
        }
@@ -1609,11 +1592,6 @@ VarParseShort(VarParser *vp, Boolean *freeResult)
        v = VarFindAny(vname, vp->ctxt);
        if (v != NULL) {
                value = VarExpand(v, vp);
-
-               if (v->flags & VAR_FROM_ENV) {
-                       VarDestroy(v, TRUE);
-               }
-
                *freeResult = TRUE;
                return (value);
        }
@@ -1959,11 +1937,29 @@ Var_GetHead(char *file)
  *-----------------------------------------------------------------------
  */
 void
-Var_Init(void)
+Var_Init(char **env)
 {
+       char    **ptr;
 
-       VAR_GLOBAL = Targ_NewGN("Global");
        VAR_CMD = Targ_NewGN("Command");
+       VAR_ENV = Targ_NewGN("Environment");
+       VAR_GLOBAL = Targ_NewGN("Global");
+
+       /*
+        * Copy user environment variables into ENV context.
+        */
+       for (ptr = env; *ptr != NULL; ++ptr) {
+               char            *tmp = estrdup(*ptr);
+               const char      *name = tmp;
+               char            *sep = strchr(name, '=');
+               const char      *value = sep + 1;
+
+               if (sep != NULL) {
+                       *sep = '\0';
+                       VarAdd(name, value, VAR_ENV);
+               }
+               free(tmp);
+       }
 }
 
 /*-
index 8ba0be9..9bd59f2 100644 (file)
@@ -37,7 +37,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/usr.bin/make/var.h,v 1.8 2005/02/07 16:27:19 harti Exp $
- * $DragonFly: src/usr.bin/make/var.h,v 1.23 2005/03/22 11:29:49 okumoto Exp $
+ * $DragonFly: src/usr.bin/make/var.h,v 1.24 2005/04/15 21:06:35 okumoto Exp $
  */
 
 #ifndef var_h_9cccafce
@@ -58,8 +58,6 @@ typedef struct Var {
 #define        VAR_IN_USE      1       /* Variable's value currently being used.
                                 * Used to avoid recursion */
 
-#define        VAR_FROM_ENV    2       /* Variable comes from the environment */
-
 #define        VAR_JUNK        4       /* Variable is a junk variable that
                                 * should be destroyed when done with
                                 * it. Used by Var_Parse for undefined,
@@ -98,7 +96,7 @@ void Var_Dump(const struct GNode *);
 Boolean Var_Exists(const char *, struct GNode *);
 char *Var_GetHead(char *);
 char *Var_GetTail(char *);
-void Var_Init(void);
+void Var_Init(char **);
 char *Var_Parse(const char *, struct GNode *, Boolean, size_t *, Boolean *);
 char *Var_Quote(const char *);
 void Var_Set(const char *, const char *, struct GNode *);