| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: var.c,v 1.792 2021/02/03 08:08:18 rillig Exp $ */ | | 1 | /* $NetBSD: var.c,v 1.793 2021/02/03 08:40:47 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | | 4 | * Copyright (c) 1988, 1989, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -121,27 +121,27 @@ | | | @@ -121,27 +121,27 @@ |
121 | #include <regex.h> | | 121 | #include <regex.h> |
122 | #endif | | 122 | #endif |
123 | #include <errno.h> | | 123 | #include <errno.h> |
124 | #include <inttypes.h> | | 124 | #include <inttypes.h> |
125 | #include <limits.h> | | 125 | #include <limits.h> |
126 | #include <time.h> | | 126 | #include <time.h> |
127 | | | 127 | |
128 | #include "make.h" | | 128 | #include "make.h" |
129 | #include "dir.h" | | 129 | #include "dir.h" |
130 | #include "job.h" | | 130 | #include "job.h" |
131 | #include "metachar.h" | | 131 | #include "metachar.h" |
132 | | | 132 | |
133 | /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ | | 133 | /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ |
134 | MAKE_RCSID("$NetBSD: var.c,v 1.792 2021/02/03 08:08:18 rillig Exp $"); | | 134 | MAKE_RCSID("$NetBSD: var.c,v 1.793 2021/02/03 08:40:47 rillig Exp $"); |
135 | | | 135 | |
136 | typedef enum VarFlags { | | 136 | typedef enum VarFlags { |
137 | VAR_NONE = 0, | | 137 | VAR_NONE = 0, |
138 | | | 138 | |
139 | /* | | 139 | /* |
140 | * The variable's value is currently being used by Var_Parse or | | 140 | * The variable's value is currently being used by Var_Parse or |
141 | * Var_Subst. This marker is used to avoid endless recursion. | | 141 | * Var_Subst. This marker is used to avoid endless recursion. |
142 | */ | | 142 | */ |
143 | VAR_IN_USE = 0x01, | | 143 | VAR_IN_USE = 0x01, |
144 | | | 144 | |
145 | /* | | 145 | /* |
146 | * The variable comes from the environment. | | 146 | * The variable comes from the environment. |
147 | * These variables are not registered in any GNode, therefore they | | 147 | * These variables are not registered in any GNode, therefore they |
| @@ -906,26 +906,32 @@ Var_UnExport(Boolean isEnv, const char * | | | @@ -906,26 +906,32 @@ Var_UnExport(Boolean isEnv, const char * |
906 | FStr varnames; | | 906 | FStr varnames; |
907 | | | 907 | |
908 | GetVarnamesToUnexport(isEnv, arg, &varnames, &what); | | 908 | GetVarnamesToUnexport(isEnv, arg, &varnames, &what); |
909 | UnexportVars(&varnames, what); | | 909 | UnexportVars(&varnames, what); |
910 | FStr_Done(&varnames); | | 910 | FStr_Done(&varnames); |
911 | } | | 911 | } |
912 | | | 912 | |
913 | /* Set the variable to the value; the name is not expanded. */ | | 913 | /* Set the variable to the value; the name is not expanded. */ |
914 | static void | | 914 | static void |
915 | SetVar(const char *name, const char *val, GNode *ctxt, VarSetFlags flags) | | 915 | SetVar(const char *name, const char *val, GNode *ctxt, VarSetFlags flags) |
916 | { | | 916 | { |
917 | Var *v; | | 917 | Var *v; |
918 | | | 918 | |
| | | 919 | assert(val != NULL); |
| | | 920 | if (name[0] == '\0') { |
| | | 921 | DEBUG0(VAR, "SetVar: variable name is empty - ignored\n"); |
| | | 922 | return; |
| | | 923 | } |
| | | 924 | |
919 | if (ctxt == VAR_GLOBAL) { | | 925 | if (ctxt == VAR_GLOBAL) { |
920 | v = VarFind(name, VAR_CMDLINE, FALSE); | | 926 | v = VarFind(name, VAR_CMDLINE, FALSE); |
921 | if (v != NULL) { | | 927 | if (v != NULL) { |
922 | if (v->flags & VAR_FROM_CMD) { | | 928 | if (v->flags & VAR_FROM_CMD) { |
923 | DEBUG3(VAR, "%s:%s = %s ignored!\n", | | 929 | DEBUG3(VAR, "%s:%s = %s ignored!\n", |
924 | ctxt->name, name, val); | | 930 | ctxt->name, name, val); |
925 | return; | | 931 | return; |
926 | } | | 932 | } |
927 | VarFreeEnv(v, TRUE); | | 933 | VarFreeEnv(v, TRUE); |
928 | } | | 934 | } |
929 | } | | 935 | } |
930 | | | 936 | |
931 | /* | | 937 | /* |
| @@ -1024,32 +1030,27 @@ Var_SetWithFlags(const char *name, const | | | @@ -1024,32 +1030,27 @@ Var_SetWithFlags(const char *name, const |
1024 | * name name of the variable to set, is expanded once | | 1030 | * name name of the variable to set, is expanded once |
1025 | * val value to give to the variable | | 1031 | * val value to give to the variable |
1026 | * ctxt context in which to set it | | 1032 | * ctxt context in which to set it |
1027 | */ | | 1033 | */ |
1028 | void | | 1034 | void |
1029 | Var_Set(const char *name, const char *val, GNode *ctxt) | | 1035 | Var_Set(const char *name, const char *val, GNode *ctxt) |
1030 | { | | 1036 | { |
1031 | Var_SetWithFlags(name, val, ctxt, VAR_SET_NONE); | | 1037 | Var_SetWithFlags(name, val, ctxt, VAR_SET_NONE); |
1032 | } | | 1038 | } |
1033 | | | 1039 | |
1034 | void | | 1040 | void |
1035 | Global_Set(const char *name, const char *value) | | 1041 | Global_Set(const char *name, const char *value) |
1036 | { | | 1042 | { |
1037 | assert(value != NULL); | | 1043 | SetVar(name, value, VAR_GLOBAL, VAR_SET_NONE); |
1038 | | | | |
1039 | if (name[0] == '\0') | | | |
1040 | DEBUG0(VAR, "Variable name empty - ignored\n"); | | | |
1041 | else | | | |
1042 | SetVar(name, value, VAR_GLOBAL, VAR_SET_NONE); | | | |
1043 | } | | 1044 | } |
1044 | | | 1045 | |
1045 | void | | 1046 | void |
1046 | Global_SetExpand(const char *name, const char *value) | | 1047 | Global_SetExpand(const char *name, const char *value) |
1047 | { | | 1048 | { |
1048 | Var_Set(name, value, VAR_GLOBAL); | | 1049 | Var_Set(name, value, VAR_GLOBAL); |
1049 | } | | 1050 | } |
1050 | | | 1051 | |
1051 | /* | | 1052 | /* |
1052 | * The variable of the given name has the given value appended to it in the | | 1053 | * The variable of the given name has the given value appended to it in the |
1053 | * given context. | | 1054 | * given context. |
1054 | * | | 1055 | * |
1055 | * If the variable doesn't exist, it is created. Otherwise the strings are | | 1056 | * If the variable doesn't exist, it is created. Otherwise the strings are |
| @@ -1083,28 +1084,27 @@ Var_Append(const char *name, const char | | | @@ -1083,28 +1084,27 @@ Var_Append(const char *name, const char |
1083 | name = name_freeIt; | | 1084 | name = name_freeIt; |
1084 | if (name[0] == '\0') { | | 1085 | if (name[0] == '\0') { |
1085 | DEBUG2(VAR, "Var_Append(\"%s\", \"%s\", ...) " | | 1086 | DEBUG2(VAR, "Var_Append(\"%s\", \"%s\", ...) " |
1086 | "name expands to empty string - ignored\n", | | 1087 | "name expands to empty string - ignored\n", |
1087 | unexpanded_name, val); | | 1088 | unexpanded_name, val); |
1088 | free(name_freeIt); | | 1089 | free(name_freeIt); |
1089 | return; | | 1090 | return; |
1090 | } | | 1091 | } |
1091 | } | | 1092 | } |
1092 | | | 1093 | |
1093 | v = VarFind(name, ctxt, ctxt == VAR_GLOBAL); | | 1094 | v = VarFind(name, ctxt, ctxt == VAR_GLOBAL); |
1094 | | | 1095 | |
1095 | if (v == NULL) { | | 1096 | if (v == NULL) { |
1096 | /* XXX: name is expanded for the second time */ | | 1097 | SetVar(name, val, ctxt, VAR_SET_NONE); |
1097 | Var_Set(name, val, ctxt); | | | |
1098 | } else if (v->flags & VAR_READONLY) { | | 1098 | } else if (v->flags & VAR_READONLY) { |
1099 | DEBUG1(VAR, "Ignoring append to %s since it is read-only\n", | | 1099 | DEBUG1(VAR, "Ignoring append to %s since it is read-only\n", |
1100 | name); | | 1100 | name); |
1101 | } else if (ctxt == VAR_CMDLINE || !(v->flags & VAR_FROM_CMD)) { | | 1101 | } else if (ctxt == VAR_CMDLINE || !(v->flags & VAR_FROM_CMD)) { |
1102 | Buf_AddByte(&v->val, ' '); | | 1102 | Buf_AddByte(&v->val, ' '); |
1103 | Buf_AddStr(&v->val, val); | | 1103 | Buf_AddStr(&v->val, val); |
1104 | | | 1104 | |
1105 | DEBUG3(VAR, "%s:%s = %s\n", ctxt->name, name, v->val.data); | | 1105 | DEBUG3(VAR, "%s:%s = %s\n", ctxt->name, name, v->val.data); |
1106 | | | 1106 | |
1107 | if (v->flags & VAR_FROM_ENV) { | | 1107 | if (v->flags & VAR_FROM_ENV) { |
1108 | /* | | 1108 | /* |
1109 | * If the original variable came from the environment, | | 1109 | * If the original variable came from the environment, |
1110 | * we have to install it in the global context (we | | 1110 | * we have to install it in the global context (we |