=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/make/var.c,v retrieving revision 1.104 retrieving revision 1.105 diff -c -r1.104 -r1.105 *** src/usr.bin/make/var.c 2022/06/09 13:13:14 1.104 --- src/usr.bin/make/var.c 2023/08/10 10:52:43 1.105 *************** *** 1,4 **** ! /* $OpenBSD: var.c,v 1.104 2022/06/09 13:13:14 espie Exp $ */ /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ /* --- 1,4 ---- ! /* $OpenBSD: var.c,v 1.105 2023/08/10 10:52:43 espie Exp $ */ /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ /* *************** *** 104,109 **** --- 104,111 ---- bool errorIsOkay; static bool checkEnvFirst; /* true if environment should be searched for * variables before the global context */ + /* do we need to recompute varname_list */ + static bool varname_list_changed = true; void Var_setCheckEnvFirst(bool yes) *************** *** 222,227 **** --- 224,230 ---- #define VAR_FROM_ENV 8 /* Special source: environment */ #define VAR_SEEN_ENV 16 /* No need to go look up environment again */ #define VAR_IS_SHELL 32 /* Magic behavior */ + #define VAR_IS_NAMES 1024 /* Very expensive, only defined when needed */ /* XXX there are also some flag values which are part of the visible API * and thus defined inside var.h, don't forget to look there if you want * to define some new flags ! *************** *** 231,236 **** --- 234,241 ---- char name[1]; /* the variable's name */ } Var; + /* for GNU make compatibility */ + #define VARNAME_LIST ".VARIABLES" static struct ohash_info var_info = { offsetof(Var, name), *************** *** 245,254 **** static Var *create_var(const char *, const char *); static void var_set_initial_value(Var *, const char *); static void var_set_value(Var *, const char *); ! #define var_get_value(v) ((v)->flags & VAR_EXEC_LATER ? \ ! var_exec_cmd(v) : \ ! Buf_Retrieve(&((v)->val))) ! static char *var_exec_cmd(Var *); static void var_append_value(Var *, const char *); static void poison_check(Var *); static void var_set_append(const char *, const char *, const char *, int, bool); --- 250,260 ---- static Var *create_var(const char *, const char *); static void var_set_initial_value(Var *, const char *); static void var_set_value(Var *, const char *); ! static char *var_get_value(Var *); ! static void var_exec_cmd(Var *); ! static void varname_list_retrieve(Var *); ! ! static void var_append_value(Var *, const char *); static void poison_check(Var *); static void var_set_append(const char *, const char *, const char *, int, bool); *************** *** 423,428 **** --- 429,435 ---- len = strlen(val); Buf_Init(&(v->val), len+1); Buf_AddChars(&(v->val), len, val); + varname_list_changed = true; } /* Normal version of var_set_value(), to be called after variable is fully *************** *** 440,445 **** --- 447,462 ---- } } + static char * + var_get_value(Var *v) + { + if (v->flags & VAR_IS_NAMES) + varname_list_retrieve(v); + else if (v->flags & VAR_EXEC_LATER) + var_exec_cmd(v); + return Buf_Retrieve(&(v->val)); + } + /* Add to a variable, insert a separating space if the variable was already * defined. */ *************** *** 628,633 **** --- 645,651 ---- ohash_remove(&global_variables, slot); delete_var(v); + varname_list_changed = true; } /* Set or add a global variable, either to VAR_CMD or VAR_GLOBAL. *************** *** 687,693 **** var_set_append(name, ename, val, ctxt, true); } ! static char * var_exec_cmd(Var *v) { char *arg = Buf_Retrieve(&(v->val)); --- 705,711 ---- var_set_append(name, ename, val, ctxt, true); } ! static void var_exec_cmd(Var *v) { char *arg = Buf_Retrieve(&(v->val)); *************** *** 699,707 **** var_set_value(v, res1); free(res1); v->flags &= ~VAR_EXEC_LATER; - return Buf_Retrieve(&(v->val)); } /* XXX different semantics for Var_Valuei() and Var_Definedi(): * references to poisoned value variables will error out in Var_Valuei(), * but not in Var_Definedi(), so the following construct works: --- 717,748 ---- var_set_value(v, res1); free(res1); v->flags &= ~VAR_EXEC_LATER; } + static void + varname_list_retrieve(Var *v) + { + unsigned int i; + void *e; + bool first = true; + + if (!varname_list_changed) + return; + for (e = ohash_first(&global_variables, &i); e != NULL; + e = ohash_next(&global_variables, &i)) { + Var *v2 = e; + if (v2->flags & VAR_DUMMY) + continue; + + if (first) + var_set_value(v, v2->name); + else + var_append_value(v, v2->name); + first = false; + } + varname_list_changed = false; + } + /* XXX different semantics for Var_Valuei() and Var_Definedi(): * references to poisoned value variables will error out in Var_Valuei(), * but not in Var_Definedi(), so the following construct works: *************** *** 1339,1344 **** --- 1380,1401 ---- v->flags = VAR_IS_SHELL | VAR_SEEN_ENV; } + static void + set_magic_name_list_variable() + { + const char *name = VARNAME_LIST; + const char *ename = NULL; + uint32_t k; + Var *v; + + k = ohash_interval(name, &ename); + v = find_global_var_without_env(name, ename, k); + /* XXX We need to set a "dummy" value because that variable can't be + * VAR_DUMMY, since we wouldn't hit var_get_value otherwise. + */ + var_set_initial_value(v, ""); + v->flags = VAR_IS_NAMES; + } /* * Var_Init * Initialize the module *************** *** 1348,1358 **** { ohash_init(&global_variables, 10, &var_info); set_magic_shell_variable(); - errorIsOkay = true; Var_setCheckEnvFirst(false); - VarModifiers_Init(); Buf_Init(&subst_buffer, MAKE_BSIZE); } --- 1405,1414 ---- { ohash_init(&global_variables, 10, &var_info); set_magic_shell_variable(); + set_magic_name_list_variable(); errorIsOkay = true; Var_setCheckEnvFirst(false); VarModifiers_Init(); Buf_Init(&subst_buffer, MAKE_BSIZE); }