1a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Internals of variables for GNU Make. 2a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerCopyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software 4a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation, Inc. 5a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerThis file is part of GNU Make. 6a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 7a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make is free software; you can redistribute it and/or modify it under the 8a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerterms of the GNU General Public License as published by the Free Software 9a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation; either version 2, or (at your option) any later version. 10a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 11a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make is distributed in the hope that it will be useful, but WITHOUT ANY 12a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 13a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerA PARTICULAR PURPOSE. See the GNU General Public License for more details. 14a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 15a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerYou should have received a copy of the GNU General Public License along with 16a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make; see the file COPYING. If not, write to the Free Software 17a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ 18a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 19a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "make.h" 20a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 21a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <assert.h> 22a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 23a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "dep.h" 24a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "filedef.h" 25a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "job.h" 26a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "commands.h" 27a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "variable.h" 28a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "rule.h" 29a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 30a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "pathstuff.h" 31a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 32a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "hash.h" 33a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 34a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Chain of all pattern-specific variables. */ 35a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 36a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct pattern_var *pattern_vars; 37a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 38a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Pointer to last struct in the chain, so we can add onto the end. */ 39a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 40a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct pattern_var *last_pattern_var; 41a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 42a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Create a new pattern-specific variable struct. */ 43a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 44a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct pattern_var * 45a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnercreate_pattern_var (char *target, char *suffix) 46a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 47a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct pattern_var *p 48a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner = (struct pattern_var *) xmalloc (sizeof (struct pattern_var)); 49a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 50a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (last_pattern_var != 0) 51a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner last_pattern_var->next = p; 52a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 53a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pattern_vars = p; 54a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner last_pattern_var = p; 55a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->next = 0; 56a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 57a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->target = target; 58a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->len = strlen (target); 59a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->suffix = suffix + 1; 60a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 61a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return p; 62a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 63a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 64a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Look up a target in the pattern-specific variable list. */ 65a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 66a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct pattern_var * 67a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerlookup_pattern_var (struct pattern_var *start, char *target) 68a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 69a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct pattern_var *p; 70a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned int targlen = strlen(target); 71a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 72a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (p = start ? start->next : pattern_vars; p != 0; p = p->next) 73a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 74a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *stem; 75a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned int stemlen; 76a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 77a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p->len > targlen) 78a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* It can't possibly match. */ 79a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 80a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 81a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* From the lengths of the filename and the pattern parts, 82a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner find the stem: the part of the filename that matches the %. */ 83a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner stem = target + (p->suffix - p->target - 1); 84a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner stemlen = targlen - p->len + 1; 85a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 86a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Compare the text in the pattern before the stem, if any. */ 87a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (stem > target && !strneq (p->target, target, stem - target)) 88a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 89a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 90a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Compare the text in the pattern after the stem, if any. 91a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner We could test simply using streq, but this way we compare the 92a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner first two characters immediately. This saves time in the very 93a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner common case where the first character matches because it is a 94a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner period. */ 95a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p->suffix == stem[stemlen] 96a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && (*p->suffix == '\0' || streq (&p->suffix[1], &stem[stemlen+1]))) 97a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 98a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 99a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 100a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return p; 101a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 102a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 103a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Hash table of all global variable definitions. */ 104a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 105a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 106a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervariable_hash_1 (const void *keyv) 107a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 108a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable const *key = (struct variable const *) keyv; 109a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_STRING_N_HASH_1 (key->name, key->length); 110a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 111a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 112a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 113a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervariable_hash_2 (const void *keyv) 114a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 115a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable const *key = (struct variable const *) keyv; 116a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_STRING_N_HASH_2 (key->name, key->length); 117a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 118a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 119a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 120a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervariable_hash_cmp (const void *xv, const void *yv) 121a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 122a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable const *x = (struct variable const *) xv; 123a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable const *y = (struct variable const *) yv; 124a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int result = x->length - y->length; 125a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 126a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 127a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_STRING_N_COMPARE (x->name, y->name, x->length); 128a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 129a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 130a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef VARIABLE_BUCKETS 131a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define VARIABLE_BUCKETS 523 132a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 133a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef PERFILE_VARIABLE_BUCKETS 134a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define PERFILE_VARIABLE_BUCKETS 23 135a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 136a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef SMALL_SCOPE_VARIABLE_BUCKETS 137a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define SMALL_SCOPE_VARIABLE_BUCKETS 13 138a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 139a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 140a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct variable_set global_variable_set; 141a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct variable_set_list global_setlist 142a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner = { 0, &global_variable_set }; 143a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable_set_list *current_variable_set_list = &global_setlist; 144a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 145a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Implement variables. */ 146a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 147a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 148a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerinit_hash_global_variable_set (void) 149a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 150a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&global_variable_set.table, VARIABLE_BUCKETS, 151a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable_hash_1, variable_hash_2, variable_hash_cmp); 152a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 153a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 154a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Define variable named NAME with value VALUE in SET. VALUE is copied. 155a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner LENGTH is the length of NAME, which does not need to be null-terminated. 156a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ORIGIN specifies the origin of the variable (makefile, command line 157a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner or environment). 158a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner If RECURSIVE is nonzero a flag is set in the variable saying 159a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner that it should be recursively re-expanded. */ 160a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 161a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable * 162a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdefine_variable_in_set (const char *name, unsigned int length, 163a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *value, enum variable_origin origin, 164a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int recursive, struct variable_set *set, 165a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const struct floc *flocp) 166a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 167a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v; 168a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **var_slot; 169a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable var_key; 170a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 171a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (set == NULL) 172a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set = &global_variable_set; 173a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 174a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var_key.name = (char *) name; 175a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var_key.length = length; 176a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var_slot = (struct variable **) hash_find_slot (&set->table, &var_key); 177a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 178a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (env_overrides && origin == o_env) 179a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = o_env_override; 180a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 181a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = *var_slot; 182a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! HASH_VACANT (v)) 183a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 184a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (env_overrides && v->origin == o_env) 185a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* V came from in the environment. Since it was defined 186a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner before the switches were parsed, it wasn't affected by -e. */ 187a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->origin = o_env_override; 188a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 189a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* A variable of this name is already defined. 190a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner If the old definition is from a stronger source 191a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner than this one, don't redefine it. */ 192a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if ((int) origin >= (int) v->origin) 193a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 194a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->value != 0) 195a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (v->value); 196a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->value = xstrdup (value); 197a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (flocp != 0) 198a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->fileinfo = *flocp; 199a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 200a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->fileinfo.filenm = 0; 201a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->origin = origin; 202a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->recursive = recursive; 203a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 204a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return v; 205a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 206a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 207a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Create a new variable definition and add it to the hash table. */ 208a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 209a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = (struct variable *) xmalloc (sizeof (struct variable)); 210a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->name = savestring (name, length); 211a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->length = length; 212a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_insert_at (&set->table, v, var_slot); 213a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->value = xstrdup (value); 214a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (flocp != 0) 215a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->fileinfo = *flocp; 216a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 217a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->fileinfo.filenm = 0; 218a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->origin = origin; 219a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->recursive = recursive; 220a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->special = 0; 221a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->expanding = 0; 222a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->exp_count = 0; 223a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->per_target = 0; 224a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->append = 0; 225a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->export = v_default; 226a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 227a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->exportable = 1; 228a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*name != '_' && (*name < 'A' || *name > 'Z') 229a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && (*name < 'a' || *name > 'z')) 230a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->exportable = 0; 231a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 232a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 233a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (++name; *name != '\0'; ++name) 234a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*name != '_' && (*name < 'a' || *name > 'z') 235a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && (*name < 'A' || *name > 'Z') && !ISDIGIT(*name)) 236a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 237a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 238a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*name != '\0') 239a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->exportable = 0; 240a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 241a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 242a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return v; 243a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 244a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 245a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* If the variable passed in is "special", handle its special nature. 246a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Currently there are two such variables, both used for introspection: 247a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner .VARIABLES expands to a list of all the variables defined in this instance 248a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner of make. 249a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner .TARGETS expands to a list of all the targets defined in this 250a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner instance of make. 251a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Returns the variable reference passed in. */ 252a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 253a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define EXPANSION_INCREMENT(_l) ((((_l) / 500) + 1) * 500) 254a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 255a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct variable * 256a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerhandle_special_var (struct variable *var) 257a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 258a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static unsigned long last_var_count = 0; 259a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 260a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 261a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* This one actually turns out to be very hard, due to the way the parser 262a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner records targets. The way it works is that target information is collected 263a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner internally until make knows the target is completely specified. It unitl 264a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner it sees that some new construct (a new target or variable) is defined that 265a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner it knows the previous one is done. In short, this means that if you do 266a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner this: 267a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 268a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner all: 269a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 270a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner TARGS := $(.TARGETS) 271a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 272a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner then $(TARGS) won't contain "all", because it's not until after the 273a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable is created that the previous target is completed. 274a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 275a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Changing this would be a major pain. I think a less complex way to do it 276a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner would be to pre-define the target files as soon as the first line is 277a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner parsed, then come back and do the rest of the definition as now. That 278a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner would allow $(.TARGETS) to be correct without a major change to the way 279a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner the parser works. 280a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 281a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (streq (var->name, ".TARGETS")) 282a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var->value = build_target_list (var->value); 283a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 284a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 285a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 286a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (streq (var->name, ".VARIABLES") 287a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && global_variable_set.table.ht_fill != last_var_count) 288a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 289a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long max = EXPANSION_INCREMENT (strlen (var->value)); 290a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long len; 291a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *p; 292a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **vp = (struct variable **) global_variable_set.table.ht_vec; 293a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **end = &vp[global_variable_set.table.ht_size]; 294a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 295a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Make sure we have at least MAX bytes in the allocated buffer. */ 296a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var->value = xrealloc (var->value, max); 297a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 298a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Walk through the hash of variables, constructing a list of names. */ 299a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = var->value; 300a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner len = 0; 301a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (; vp < end; ++vp) 302a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!HASH_VACANT (*vp)) 303a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 304a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v = *vp; 305a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int l = v->length; 306a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 307a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner len += l + 1; 308a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (len > max) 309a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 310a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long off = p - var->value; 311a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 312a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner max += EXPANSION_INCREMENT (l + 1); 313a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var->value = xrealloc (var->value, max); 314a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = &var->value[off]; 315a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 316a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 317a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bcopy (v->name, p, l); 318a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p += l; 319a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *(p++) = ' '; 320a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 321a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *(p-1) = '\0'; 322a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 323a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Remember how many variables are in our current count. Since we never 324a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner remove variables from the list, this is a reliable way to know whether 325a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner the list is up to date or needs to be recomputed. */ 326a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 327a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner last_var_count = global_variable_set.table.ht_fill; 328a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 329a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 330a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return var; 331a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 332a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 333a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 334a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Lookup a variable whose name is a string starting at NAME 335a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner and with LENGTH chars. NAME need not be null-terminated. 336a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Returns address of the `struct variable' containing all info 337a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner on the variable, or nil if no such variable is defined. */ 338a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 339a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable * 340a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerlookup_variable (const char *name, unsigned int length) 341a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 342a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const struct variable_set_list *setlist; 343a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable var_key; 344a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 345a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var_key.name = (char *) name; 346a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var_key.length = length; 347a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 348a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (setlist = current_variable_set_list; 349a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist != 0; setlist = setlist->next) 350a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 351a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const struct variable_set *set = setlist->set; 352a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v; 353a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 354a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key); 355a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v) 356a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return v->special ? handle_special_var (v) : v; 357a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 358a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 359a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 360a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* since we don't read envp[] on startup, try to get the 361a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable via getenv() here. */ 362a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 363a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *vname = alloca (length + 1); 364a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *value; 365a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner strncpy (vname, name, length); 366a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner vname[length] = 0; 367a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner value = getenv (vname); 368a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (value != 0) 369a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 370a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *sptr; 371a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int scnt; 372a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 373a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sptr = value; 374a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner scnt = 0; 375a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 376a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while ((sptr = strchr (sptr, '$'))) 377a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 378a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner scnt++; 379a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sptr++; 380a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 381a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 382a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (scnt > 0) 383a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 384a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *nvalue; 385a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *nptr; 386a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 387a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner nvalue = alloca (strlen (value) + scnt + 1); 388a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sptr = value; 389a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner nptr = nvalue; 390a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 391a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (*sptr) 392a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 393a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*sptr == '$') 394a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 395a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *nptr++ = '$'; 396a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *nptr++ = '$'; 397a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 398a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 399a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 400a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *nptr++ = *sptr; 401a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 402a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sptr++; 403a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 404a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 405a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *nptr = '\0'; 406a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return define_variable (vname, length, nvalue, o_env, 1); 407a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 408a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 409a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 410a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return define_variable (vname, length, value, o_env, 1); 411a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 412a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 413a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* VMS */ 414a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 415a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 416a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 417a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 418a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Lookup a variable whose name is a string starting at NAME 419a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner and with LENGTH chars in set SET. NAME need not be null-terminated. 420a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Returns address of the `struct variable' containing all info 421a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner on the variable, or nil if no such variable is defined. */ 422a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 423a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable * 424a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerlookup_variable_in_set (const char *name, unsigned int length, 425a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const struct variable_set *set) 426a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 427a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable var_key; 428a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 429a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var_key.name = (char *) name; 430a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner var_key.length = length; 431a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 432a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key); 433a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 434a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 435a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Initialize FILE's variable set list. If FILE already has a variable set 436a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner list, the topmost variable set is left intact, but the the rest of the 437a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner chain is replaced with FILE->parent's setlist. If FILE is a double-colon 438a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner rule, then we will use the "root" double-colon target's variable set as the 439a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner parent of FILE's variable set. 440a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 441a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner If we're READing a makefile, don't do the pattern variable search now, 442a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner since the pattern variable might not have been defined yet. */ 443a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 444a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 445a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerinitialize_file_variables (struct file *file, int reading) 446a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 447a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *l = file->variables; 448a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 449a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (l == 0) 450a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 451a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner l = (struct variable_set_list *) 452a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner xmalloc (sizeof (struct variable_set_list)); 453a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner l->set = (struct variable_set *) xmalloc (sizeof (struct variable_set)); 454a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&l->set->table, PERFILE_VARIABLE_BUCKETS, 455a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable_hash_1, variable_hash_2, variable_hash_cmp); 456a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner file->variables = l; 457a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 458a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 459a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If this is a double-colon, then our "parent" is the "root" target for 460a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner this double-colon rule. Since that rule has the same name, parent, 461a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner etc. we can just use its variables as the "next" for ours. */ 462a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 463a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (file->double_colon && file->double_colon != file) 464a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 465a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner initialize_file_variables (file->double_colon, reading); 466a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner l->next = file->double_colon->variables; 467a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 468a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 469a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 470a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (file->parent == 0) 471a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner l->next = &global_setlist; 472a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 473a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 474a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner initialize_file_variables (file->parent, reading); 475a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner l->next = file->parent->variables; 476a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 477a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 478a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If we're not reading makefiles and we haven't looked yet, see if 479a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner we can find pattern variables for this target. */ 480a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 481a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!reading && !file->pat_searched) 482a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 483a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct pattern_var *p; 484a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 485a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = lookup_pattern_var (0, file->name); 486a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p != 0) 487a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 488a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *global = current_variable_set_list; 489a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 490a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* We found at least one. Set up a new variable set to accumulate 491a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner all the pattern variables that match this target. */ 492a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 493a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner file->pat_variables = create_new_variable_set (); 494a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list = file->pat_variables; 495a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 496a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner do 497a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 498a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* We found one, so insert it into the set. */ 499a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 500a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v; 501a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 502a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p->variable.flavor == f_simple) 503a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 504a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = define_variable_loc ( 505a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->variable.name, strlen (p->variable.name), 506a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->variable.value, p->variable.origin, 507a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 0, &p->variable.fileinfo); 508a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 509a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->flavor = f_simple; 510a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 511a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 512a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 513a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = do_variable_definition ( 514a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &p->variable.fileinfo, p->variable.name, 515a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->variable.value, p->variable.origin, 516a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p->variable.flavor, 1); 517a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 518a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 519a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Also mark it as a per-target and copy export status. */ 520a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->per_target = p->variable.per_target; 521a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->export = p->variable.export; 522a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 523a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while ((p = lookup_pattern_var (p, file->name)) != 0); 524a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 525a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list = global; 526a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 527a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner file->pat_searched = 1; 528a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 529a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 530a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If we have a pattern variable match, set it up. */ 531a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 532a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (file->pat_variables != 0) 533a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 534a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner file->pat_variables->next = l->next; 535a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner l->next = file->pat_variables; 536a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 537a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 538a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 539a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Pop the top set off the current variable set list, 540a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner and free all its storage. */ 541a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 542a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable_set_list * 543a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnercreate_new_variable_set (void) 544a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 545a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct variable_set_list *setlist; 546a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct variable_set *set; 547a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 548a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set = (struct variable_set *) xmalloc (sizeof (struct variable_set)); 549a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&set->table, SMALL_SCOPE_VARIABLE_BUCKETS, 550a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable_hash_1, variable_hash_2, variable_hash_cmp); 551a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 552a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist = (struct variable_set_list *) 553a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner xmalloc (sizeof (struct variable_set_list)); 554a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist->set = set; 555a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist->next = current_variable_set_list; 556a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 557a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return setlist; 558a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 559a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 560a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 561a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerfree_variable_name_and_value (const void *item) 562a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 563a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v = (struct variable *) item; 564a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (v->name); 565a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (v->value); 566a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 567a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 568a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 569a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerfree_variable_set (struct variable_set_list *list) 570a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 571a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_map (&list->set->table, free_variable_name_and_value); 572a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_free (&list->set->table, 1); 573a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free ((char *) list->set); 574a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free ((char *) list); 575a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 576a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 577a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Create a new variable set and push it on the current setlist. 578a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner If we're pushing a global scope (that is, the current scope is the global 579a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner scope) then we need to "push" it the other way: file variable sets point 580a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner directly to the global_setlist so we need to replace that with the new one. 581a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 582a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 583a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable_set_list * 584a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerpush_new_variable_scope (void) 585a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 586a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list = create_new_variable_set(); 587a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (current_variable_set_list->next == &global_setlist) 588a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 589a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* It was the global, so instead of new -> &global we want to replace 590a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &global with the new one and have &global -> new, with current still 591a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pointing to &global */ 592a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set *set = current_variable_set_list->set; 593a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list->set = global_setlist.set; 594a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner global_setlist.set = set; 595a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list->next = global_setlist.next; 596a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner global_setlist.next = current_variable_set_list; 597a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list = &global_setlist; 598a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 599a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return (current_variable_set_list); 600a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 601a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 602a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 603a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerpop_variable_scope (void) 604a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 605a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *setlist; 606a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set *set; 607a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 608a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Can't call this if there's no scope to pop! */ 609a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner assert(current_variable_set_list->next != NULL); 610a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 611a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (current_variable_set_list != &global_setlist) 612a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 613a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* We're not pointing to the global setlist, so pop this one. */ 614a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist = current_variable_set_list; 615a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set = setlist->set; 616a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list = setlist->next; 617a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 618a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 619a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 620a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* This set is the one in the global_setlist, but there is another global 621a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set beyond that. We want to copy that set to global_setlist, then 622a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner delete what used to be in global_setlist. */ 623a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist = global_setlist.next; 624a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set = global_setlist.set; 625a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner global_setlist.set = setlist->set; 626a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner global_setlist.next = setlist->next; 627a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 628a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 629a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Free the one we no longer need. */ 630a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free ((char *) setlist); 631a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_map (&set->table, free_variable_name_and_value); 632a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_free (&set->table, 1); 633a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free ((char *) set); 634a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 635a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 636a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Merge FROM_SET into TO_SET, freeing unused storage in FROM_SET. */ 637a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 638a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 639a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnermerge_variable_sets (struct variable_set *to_set, 640a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set *from_set) 641a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 642a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **from_var_slot = (struct variable **) from_set->table.ht_vec; 643a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **from_var_end = from_var_slot + from_set->table.ht_size; 644a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 645a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for ( ; from_var_slot < from_var_end; from_var_slot++) 646a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! HASH_VACANT (*from_var_slot)) 647a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 648a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *from_var = *from_var_slot; 649a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **to_var_slot 650a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner = (struct variable **) hash_find_slot (&to_set->table, *from_var_slot); 651a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (HASH_VACANT (*to_var_slot)) 652a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_insert_at (&to_set->table, from_var, to_var_slot); 653a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 654a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 655a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* GKM FIXME: delete in from_set->table */ 656a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (from_var->value); 657a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (from_var); 658a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 659a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 660a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 661a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 662a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Merge SETLIST1 into SETLIST0, freeing unused storage in SETLIST1. */ 663a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 664a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 665a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnermerge_variable_set_lists (struct variable_set_list **setlist0, 666a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *setlist1) 667a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 668a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *to = *setlist0; 669a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *last0 = 0; 670a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 671a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If there's nothing to merge, stop now. */ 672a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!setlist1) 673a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 674a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 675a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* This loop relies on the fact that all setlists terminate with the global 676a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist (before NULL). If that's not true, arguably we SHOULD die. */ 677a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (to) 678a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (setlist1 != &global_setlist && to != &global_setlist) 679a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 680a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *from = setlist1; 681a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setlist1 = setlist1->next; 682a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 683a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner merge_variable_sets (to->set, from->set); 684a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 685a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner last0 = to; 686a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner to = to->next; 687a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 688a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 689a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (setlist1 != &global_setlist) 690a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 691a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (last0 == 0) 692a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *setlist0 = setlist1; 693a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 694a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner last0->next = setlist1; 695a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 696a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 697a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 698a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Define the automatic variables, and record the addresses 699a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner of their structures so we can change their values quickly. */ 700a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 701a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 702a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdefine_automatic_variables (void) 703a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 704a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#if defined(WINDOWS32) || defined(__EMX__) 705a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner extern char* default_shell; 706a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 707a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner extern char default_shell[]; 708a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 709a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct variable *v; 710a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char buf[200]; 711a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 712a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sprintf (buf, "%u", makelevel); 713a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) define_variable (MAKELEVEL_NAME, MAKELEVEL_LENGTH, buf, o_env, 0); 714a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 715a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sprintf (buf, "%s%s%s", 716a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner version_string, 717a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (remote_description == 0 || remote_description[0] == '\0') 718a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ? "" : "-", 719a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (remote_description == 0 || remote_description[0] == '\0') 720a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ? "" : remote_description); 721a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) define_variable ("MAKE_VERSION", 12, buf, o_default, 0); 722a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 723a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef __MSDOS__ 724a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Allow to specify a special shell just for Make, 725a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner and use $COMSPEC as the default $SHELL when appropriate. */ 726a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 727a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static char shell_str[] = "SHELL"; 728a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const int shlen = sizeof (shell_str) - 1; 729a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *mshp = lookup_variable ("MAKESHELL", 9); 730a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *comp = lookup_variable ("COMSPEC", 7); 731a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 732a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Make $MAKESHELL override $SHELL even if -e is in effect. */ 733a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (mshp) 734a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) define_variable (shell_str, shlen, 735a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner mshp->value, o_env_override, 0); 736a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (comp) 737a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 738a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* $COMSPEC shouldn't override $SHELL. */ 739a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *shp = lookup_variable (shell_str, shlen); 740a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 741a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!shp) 742a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) define_variable (shell_str, shlen, comp->value, o_env, 0); 743a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 744a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 745a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#elif defined(__EMX__) 746a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 747a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static char shell_str[] = "SHELL"; 748a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const int shlen = sizeof (shell_str) - 1; 749a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *shell = lookup_variable (shell_str, shlen); 750a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *replace = lookup_variable ("MAKESHELL", 9); 751a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 752a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* if $MAKESHELL is defined in the environment assume o_env_override */ 753a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (replace && *replace->value && replace->origin == o_env) 754a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner replace->origin = o_env_override; 755a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 756a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* if $MAKESHELL is not defined use $SHELL but only if the variable 757a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner did not come from the environment */ 758a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!replace || !*replace->value) 759a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (shell && *shell->value && (shell->origin == o_env 760a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner || shell->origin == o_env_override)) 761a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 762a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* overwrite whatever we got from the environment */ 763a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free(shell->value); 764a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shell->value = xstrdup (default_shell); 765a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shell->origin = o_default; 766a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 767a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 768a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Some people do not like cmd to be used as the default 769a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if $SHELL is not defined in the Makefile. 770a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner With -DNO_CMD_DEFAULT you can turn off this behaviour */ 771a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifndef NO_CMD_DEFAULT 772a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* otherwise use $COMSPEC */ 773a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!replace || !*replace->value) 774a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner replace = lookup_variable ("COMSPEC", 7); 775a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 776a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* otherwise use $OS2_SHELL */ 777a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!replace || !*replace->value) 778a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner replace = lookup_variable ("OS2_SHELL", 9); 779a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# else 780a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# warning NO_CMD_DEFAULT: GNU make will not use CMD.EXE as default shell 781a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 782a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 783a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (replace && *replace->value) 784a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* overwrite $SHELL */ 785a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) define_variable (shell_str, shlen, replace->value, 786a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner replace->origin, 0); 787a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 788a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* provide a definition if there is none */ 789a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) define_variable (shell_str, shlen, default_shell, 790a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner o_default, 0); 791a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 792a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 793a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 794a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 795a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* This won't override any definition, but it will provide one if there 796a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner isn't one there. */ 797a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = define_variable ("SHELL", 5, default_shell, o_default, 0); 798a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 799a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* On MSDOS we do use SHELL from environment, since it isn't a standard 800a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner environment variable on MSDOS, so whoever sets it, does that on purpose. 801a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner On OS/2 we do not use SHELL from environment but we have already handled 802a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner that problem above. */ 803a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#if !defined(__MSDOS__) && !defined(__EMX__) 804a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Don't let SHELL come from the environment. */ 805a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override) 806a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 807a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (v->value); 808a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->origin = o_file; 809a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->value = xstrdup (default_shell); 810a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 811a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 812a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 813a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Make sure MAKEFILES gets exported if it is set. */ 814a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = define_variable ("MAKEFILES", 9, "", o_default, 0); 815a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->export = v_ifset; 816a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 817a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Define the magic D and F variables in terms of 818a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner the automatic variables they are variations of. */ 819a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 820a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 821a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("@D", 2, "$(dir $@)", o_automatic, 1); 822a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("%D", 2, "$(dir $%)", o_automatic, 1); 823a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("*D", 2, "$(dir $*)", o_automatic, 1); 824a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("<D", 2, "$(dir $<)", o_automatic, 1); 825a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("?D", 2, "$(dir $?)", o_automatic, 1); 826a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("^D", 2, "$(dir $^)", o_automatic, 1); 827a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("+D", 2, "$(dir $+)", o_automatic, 1); 828a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 829a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("@D", 2, "$(patsubst %/,%,$(dir $@))", o_automatic, 1); 830a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("%D", 2, "$(patsubst %/,%,$(dir $%))", o_automatic, 1); 831a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("*D", 2, "$(patsubst %/,%,$(dir $*))", o_automatic, 1); 832a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("<D", 2, "$(patsubst %/,%,$(dir $<))", o_automatic, 1); 833a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("?D", 2, "$(patsubst %/,%,$(dir $?))", o_automatic, 1); 834a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("^D", 2, "$(patsubst %/,%,$(dir $^))", o_automatic, 1); 835a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("+D", 2, "$(patsubst %/,%,$(dir $+))", o_automatic, 1); 836a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 837a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("@F", 2, "$(notdir $@)", o_automatic, 1); 838a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("%F", 2, "$(notdir $%)", o_automatic, 1); 839a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("*F", 2, "$(notdir $*)", o_automatic, 1); 840a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("<F", 2, "$(notdir $<)", o_automatic, 1); 841a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("?F", 2, "$(notdir $?)", o_automatic, 1); 842a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("^F", 2, "$(notdir $^)", o_automatic, 1); 843a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner define_variable ("+F", 2, "$(notdir $+)", o_automatic, 1); 844a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 845a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 846a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerint export_all_variables; 847a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 848a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Create a new environment for FILE's commands. 849a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner If FILE is nil, this is for the `shell' function. 850a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner The child's MAKELEVEL variable is incremented. */ 851a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 852a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerchar ** 853a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnertarget_environment (struct file *file) 854a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 855a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set_list *set_list; 856a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct variable_set_list *s; 857a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct hash_table table; 858a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **v_slot; 859a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **v_end; 860a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable makelevel_key; 861a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char **result_0; 862a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char **result; 863a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 864a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (file == 0) 865a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set_list = current_variable_set_list; 866a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 867a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set_list = file->variables; 868a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 869a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&table, VARIABLE_BUCKETS, 870a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable_hash_1, variable_hash_2, variable_hash_cmp); 871a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 872a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Run through all the variable sets in the list, 873a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner accumulating variables in TABLE. */ 874a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (s = set_list; s != 0; s = s->next) 875a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 876a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable_set *set = s->set; 877a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v_slot = (struct variable **) set->table.ht_vec; 878a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v_end = v_slot + set->table.ht_size; 879a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for ( ; v_slot < v_end; v_slot++) 880a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! HASH_VACANT (*v_slot)) 881a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 882a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable **new_slot; 883a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v = *v_slot; 884a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 885a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If this is a per-target variable and it hasn't been touched 886a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner already then look up the global version and take its export 887a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner value. */ 888a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->per_target && v->export == v_default) 889a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 890a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *gv; 891a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 892a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner gv = lookup_variable_in_set (v->name, strlen(v->name), 893a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &global_variable_set); 894a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (gv) 895a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->export = gv->export; 896a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 897a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 898a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (v->export) 899a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 900a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case v_default: 901a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->origin == o_default || v->origin == o_automatic) 902a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Only export default variables by explicit request. */ 903a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 904a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 905a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The variable doesn't have a name that can be exported. */ 906a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! v->exportable) 907a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 908a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 909a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! export_all_variables 910a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && v->origin != o_command 911a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && v->origin != o_env && v->origin != o_env_override) 912a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 913a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 914a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 915a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case v_export: 916a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 917a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 918a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case v_noexport: 919a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If this is the SHELL variable and it's not exported, then 920a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner add the value from our original environment. */ 921a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (streq (v->name, "SHELL")) 922a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 923a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner extern struct variable shell_var; 924a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = &shell_var; 925a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 926a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 927a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 928a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 929a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case v_ifset: 930a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->origin == o_default) 931a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 932a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 933a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 934a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 935a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new_slot = (struct variable **) hash_find_slot (&table, v); 936a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (HASH_VACANT (*new_slot)) 937a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_insert_at (&table, v, new_slot); 938a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 939a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 940a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 941a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner makelevel_key.name = MAKELEVEL_NAME; 942a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner makelevel_key.length = MAKELEVEL_LENGTH; 943a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_delete (&table, &makelevel_key); 944a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 945a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner result = result_0 = (char **) xmalloc ((table.ht_fill + 2) * sizeof (char *)); 946a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 947a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v_slot = (struct variable **) table.ht_vec; 948a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v_end = v_slot + table.ht_size; 949a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for ( ; v_slot < v_end; v_slot++) 950a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! HASH_VACANT (*v_slot)) 951a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 952a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v = *v_slot; 953a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 954a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If V is recursively expanded and didn't come from the environment, 955a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner expand its value. If it came from the environment, it should 956a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner go back into the environment unchanged. */ 957a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->recursive 958a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && v->origin != o_env && v->origin != o_env_override) 959a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 960a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *value = recursively_expand_for_file (v, file); 961a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 962a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strcmp(v->name, "Path") == 0 || 963a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner strcmp(v->name, "PATH") == 0) 964a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner convert_Path_to_windows32(value, ';'); 965a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 966a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *result++ = concat (v->name, "=", value); 967a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (value); 968a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 969a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 970a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 971a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 972a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strcmp(v->name, "Path") == 0 || 973a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner strcmp(v->name, "PATH") == 0) 974a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner convert_Path_to_windows32(v->value, ';'); 975a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 976a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *result++ = concat (v->name, "=", v->value); 977a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 978a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 979a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 980a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *result = (char *) xmalloc (100); 981a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) sprintf (*result, "%s=%u", MAKELEVEL_NAME, makelevel + 1); 982a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *++result = 0; 983a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 984a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_free (&table, 0); 985a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 986a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result_0; 987a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 988a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 989a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Given a variable, a value, and a flavor, define the variable. 990a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner See the try_variable_definition() function for details on the parameters. */ 991a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 992a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable * 993a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdo_variable_definition (const struct floc *flocp, const char *varname, 994a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *value, enum variable_origin origin, 995a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner enum variable_flavor flavor, int target_var) 996a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 997a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *p, *alloc_value = NULL; 998a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *v; 999a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int append = 0; 1000a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int conditional = 0; 1001a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1002a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Calculate the variable's new value in VALUE. */ 1003a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1004a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (flavor) 1005a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1006a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner default: 1007a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case f_bogus: 1008a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Should not be possible. */ 1009a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner abort (); 1010a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case f_simple: 1011a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* A simple variable definition "var := value". Expand the value. 1012a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner We have to allocate memory since otherwise it'll clobber the 1013a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable buffer, and we may still need that if we're looking at a 1014a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner target-specific variable. */ 1015a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = alloc_value = allocated_variable_expand (value); 1016a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1017a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case f_conditional: 1018a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* A conditional variable definition "var ?= value". 1019a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner The value is set IFF the variable is not defined yet. */ 1020a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = lookup_variable (varname, strlen (varname)); 1021a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v) 1022a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return v; 1023a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1024a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner conditional = 1; 1025a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor = f_recursive; 1026a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* FALLTHROUGH */ 1027a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case f_recursive: 1028a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* A recursive variable definition "var = value". 1029a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner The value is used verbatim. */ 1030a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = value; 1031a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1032a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case f_append: 1033a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1034a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If we have += but we're in a target variable context, we want to 1035a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner append only with other variables in the context of this target. */ 1036a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (target_var) 1037a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1038a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner append = 1; 1039a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = lookup_variable_in_set (varname, strlen (varname), 1040a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner current_variable_set_list->set); 1041a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1042a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Don't append from the global set if a previous non-appending 1043a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner target-specific variable definition exists. */ 1044a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v && !v->append) 1045a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner append = 0; 1046a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1047a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1048a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = lookup_variable (varname, strlen (varname)); 1049a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1050a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v == 0) 1051a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1052a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* There was no old value. 1053a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner This becomes a normal recursive definition. */ 1054a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = value; 1055a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor = f_recursive; 1056a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1057a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1058a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1059a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Paste the old and new values together in VALUE. */ 1060a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1061a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned int oldlen, vallen; 1062a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *val; 1063a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1064a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner val = value; 1065a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->recursive) 1066a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The previous definition of the variable was recursive. 1067a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner The new value is the unexpanded old and new values. */ 1068a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor = f_recursive; 1069a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1070a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The previous definition of the variable was simple. 1071a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner The new value comes from the old value, which was expanded 1072a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner when it was set; and from the expanded new value. Allocate 1073a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner memory for the expansion as we may still need the rest of the 1074a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner buffer if we're looking at a target-specific variable. */ 1075a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner val = alloc_value = allocated_variable_expand (val); 1076a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1077a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner oldlen = strlen (v->value); 1078a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner vallen = strlen (val); 1079a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = (char *) alloca (oldlen + 1 + vallen + 1); 1080a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bcopy (v->value, p, oldlen); 1081a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p[oldlen] = ' '; 1082a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bcopy (val, &p[oldlen + 1], vallen + 1); 1083a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1084a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1085a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1086a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1087a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef __MSDOS__ 1088a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Many Unix Makefiles include a line saying "SHELL=/bin/sh", but 1089a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner non-Unix systems don't conform to this default configuration (in 1090a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fact, most of them don't even have `/bin'). On the other hand, 1091a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner $SHELL in the environment, if set, points to the real pathname of 1092a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner the shell. 1093a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Therefore, we generally won't let lines like "SHELL=/bin/sh" from 1094a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner the Makefile override $SHELL from the environment. But first, we 1095a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner look for the basename of the shell in the directory where SHELL= 1096a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner points, and along the $PATH; if it is found in any of these places, 1097a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner we define $SHELL to be the actual pathname of the shell. Thus, if 1098a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner you have bash.exe installed as d:/unix/bash.exe, and d:/unix is on 1099a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner your $PATH, then SHELL=/usr/local/bin/bash will have the effect of 1100a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner defining SHELL to be "d:/unix/bash.exe". */ 1101a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if ((origin == o_file || origin == o_override) 1102a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && strcmp (varname, "SHELL") == 0) 1103a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1104a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner PATH_VAR (shellpath); 1105a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner extern char * __dosexec_find_on_path (const char *, char *[], char *); 1106a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1107a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* See if we can find "/bin/sh.exe", "/bin/sh.com", etc. */ 1108a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (__dosexec_find_on_path (p, (char **)0, shellpath)) 1109a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1110a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *p; 1111a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1112a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (p = shellpath; *p; p++) 1113a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1114a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '\\') 1115a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *p = '/'; 1116a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1117a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = define_variable_loc (varname, strlen (varname), 1118a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shellpath, origin, flavor == f_recursive, 1119a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flocp); 1120a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1121a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1122a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1123a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *shellbase, *bslash; 1124a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *pathv = lookup_variable ("PATH", 4); 1125a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *path_string; 1126a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *fake_env[2]; 1127a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner size_t pathlen = 0; 1128a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1129a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shellbase = strrchr (p, '/'); 1130a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bslash = strrchr (p, '\\'); 1131a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!shellbase || bslash > shellbase) 1132a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shellbase = bslash; 1133a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!shellbase && p[1] == ':') 1134a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shellbase = p + 1; 1135a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (shellbase) 1136a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shellbase++; 1137a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1138a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shellbase = p; 1139a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1140a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Search for the basename of the shell (with standard 1141a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner executable extensions) along the $PATH. */ 1142a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (pathv) 1143a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner pathlen = strlen (pathv->value); 1144a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner path_string = (char *)xmalloc (5 + pathlen + 2 + 1); 1145a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* On MSDOS, current directory is considered as part of $PATH. */ 1146a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner sprintf (path_string, "PATH=.;%s", pathv ? pathv->value : ""); 1147a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fake_env[0] = path_string; 1148a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fake_env[1] = (char *)0; 1149a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (__dosexec_find_on_path (shellbase, fake_env, shellpath)) 1150a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1151a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *p; 1152a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1153a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (p = shellpath; *p; p++) 1154a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1155a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '\\') 1156a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *p = '/'; 1157a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1158a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = define_variable_loc (varname, strlen (varname), 1159a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner shellpath, origin, 1160a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor == f_recursive, flocp); 1161a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1162a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1163a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = lookup_variable (varname, strlen (varname)); 1164a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1165a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (path_string); 1166a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1167a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1168a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1169a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* __MSDOS__ */ 1170a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 1171a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if ((origin == o_file || origin == o_override || origin == o_command) 1172a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner && streq (varname, "SHELL")) 1173a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1174a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner extern char *default_shell; 1175a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1176a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Call shell locator function. If it returns TRUE, then 1177a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set no_default_sh_exe to indicate sh was found and 1178a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner set new value for SHELL variable. */ 1179a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1180a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (find_and_set_default_shell (p)) 1181a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1182a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = define_variable_in_set (varname, strlen (varname), default_shell, 1183a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin, flavor == f_recursive, 1184a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (target_var 1185a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ? current_variable_set_list->set 1186a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner : NULL), 1187a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flocp); 1188a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner no_default_sh_exe = 0; 1189a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1190a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1191a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = lookup_variable (varname, strlen (varname)); 1192a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1193a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1194a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1195a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1196a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If we are defining variables inside an $(eval ...), we might have a 1197a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner different variable context pushed, not the global context (maybe we're 1198a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner inside a $(call ...) or something. Since this function is only ever 1199a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner invoked in places where we want to define globally visible variables, 1200a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner make sure we define this variable in the global set. */ 1201a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1202a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v = define_variable_in_set (varname, strlen (varname), p, 1203a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin, flavor == f_recursive, 1204a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (target_var 1205a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ? current_variable_set_list->set : NULL), 1206a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flocp); 1207a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->append = append; 1208a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->conditional = conditional; 1209a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1210a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (alloc_value) 1211a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (alloc_value); 1212a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1213a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return v; 1214a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1215a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1216a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Try to interpret LINE (a null-terminated string) as a variable definition. 1217a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1218a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ORIGIN may be o_file, o_override, o_env, o_env_override, 1219a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner or o_command specifying that the variable definition comes 1220a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner from a makefile, an override directive, the environment with 1221a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner or without the -e switch, or the command line. 1222a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1223a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner See the comments for parse_variable_definition(). 1224a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1225a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner If LINE was recognized as a variable definition, a pointer to its `struct 1226a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable' is returned. If LINE is not a variable definition, NULL is 1227a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner returned. */ 1228a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1229a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable * 1230a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerparse_variable_definition (struct variable *v, char *line) 1231a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1232a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register int c; 1233a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register char *p = line; 1234a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register char *beg; 1235a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register char *end; 1236a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner enum variable_flavor flavor = f_bogus; 1237a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *name; 1238a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1239a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (1) 1240a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1241a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner c = *p++; 1242a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (c == '\0' || c == '#') 1243a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 1244a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (c == '=') 1245a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1246a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner end = p - 1; 1247a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor = f_recursive; 1248a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1249a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1250a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (c == ':') 1251a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '=') 1252a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1253a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner end = p++ - 1; 1254a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor = f_simple; 1255a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1256a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1257a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1258a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* A colon other than := is a rule line, not a variable defn. */ 1259a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 1260a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (c == '+' && *p == '=') 1261a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1262a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner end = p++ - 1; 1263a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor = f_append; 1264a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1265a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1266a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (c == '?' && *p == '=') 1267a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1268a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner end = p++ - 1; 1269a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner flavor = f_conditional; 1270a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1271a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1272a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (c == '$') 1273a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1274a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* This might begin a variable expansion reference. Make sure we 1275a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner don't misrecognize chars inside the reference as =, := or +=. */ 1276a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char closeparen; 1277a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int count; 1278a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner c = *p++; 1279a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (c == '(') 1280a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner closeparen = ')'; 1281a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (c == '{') 1282a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner closeparen = '}'; 1283a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1284a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; /* Nope. */ 1285a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1286a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* P now points past the opening paren or brace. 1287a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Count parens or braces until it is matched. */ 1288a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner count = 0; 1289a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (; *p != '\0'; ++p) 1290a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1291a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == c) 1292a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++count; 1293a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (*p == closeparen && --count < 0) 1294a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1295a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++p; 1296a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1297a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1298a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1299a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1300a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1301a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->flavor = flavor; 1302a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1303a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner beg = next_token (line); 1304a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (end > beg && isblank ((unsigned char)end[-1])) 1305a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner --end; 1306a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = next_token (p); 1307a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->value = p; 1308a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1309a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Expand the name, so "$(foo)bar = baz" works. */ 1310a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner name = (char *) alloca (end - beg + 1); 1311a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bcopy (beg, name, end - beg); 1312a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner name[end - beg] = '\0'; 1313a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->name = allocated_variable_expand (name); 1314a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1315a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->name[0] == '\0') 1316a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fatal (&v->fileinfo, _("empty variable name")); 1317a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1318a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return v; 1319a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1320a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1321a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Try to interpret LINE (a null-terminated string) as a variable definition. 1322a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1323a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ORIGIN may be o_file, o_override, o_env, o_env_override, 1324a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner or o_command specifying that the variable definition comes 1325a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner from a makefile, an override directive, the environment with 1326a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner or without the -e switch, or the command line. 1327a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1328a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner See the comments for parse_variable_definition(). 1329a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1330a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner If LINE was recognized as a variable definition, a pointer to its `struct 1331a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner variable' is returned. If LINE is not a variable definition, NULL is 1332a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner returned. */ 1333a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1334a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct variable * 1335a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnertry_variable_definition (const struct floc *flocp, char *line, 1336a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner enum variable_origin origin, int target_var) 1337a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1338a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable v; 1339a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct variable *vp; 1340a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1341a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (flocp != 0) 1342a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v.fileinfo = *flocp; 1343a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1344a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v.fileinfo.filenm = 0; 1345a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1346a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!parse_variable_definition (&v, line)) 1347a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 1348a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1349a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner vp = do_variable_definition (flocp, v.name, v.value, 1350a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin, v.flavor, target_var); 1351a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1352a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (v.name); 1353a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1354a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return vp; 1355a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1356a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1357a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Print information for variable V, prefixing it with PREFIX. */ 1358a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1359a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 1360a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerprint_variable (const void *item, void *arg) 1361a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1362a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const struct variable *v = (struct variable *) item; 1363a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const char *prefix = (char *) arg; 1364a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner const char *origin; 1365a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1366a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner switch (v->origin) 1367a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1368a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_default: 1369a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = _("default"); 1370a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1371a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_env: 1372a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = _("environment"); 1373a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1374a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_file: 1375a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = _("makefile"); 1376a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1377a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_env_override: 1378a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = _("environment under -e"); 1379a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1380a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_command: 1381a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = _("command line"); 1382a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1383a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_override: 1384a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = _("`override' directive"); 1385a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1386a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_automatic: 1387a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner origin = _("automatic"); 1388a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 1389a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner case o_invalid: 1390a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner default: 1391a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner abort (); 1392a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1393a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs ("# ", stdout); 1394a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (origin, stdout); 1395a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->fileinfo.filenm) 1396a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_(" (from `%s', line %lu)"), 1397a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner v->fileinfo.filenm, v->fileinfo.lineno); 1398a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner putchar ('\n'); 1399a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (prefix, stdout); 1400a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1401a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Is this a `define'? */ 1402a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (v->recursive && strchr (v->value, '\n') != 0) 1403a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("define %s\n%s\nendef\n", v->name, v->value); 1404a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1405a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1406a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register char *p; 1407a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1408a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("%s %s= ", v->name, v->recursive ? v->append ? "+" : "" : ":"); 1409a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1410a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Check if the value is just whitespace. */ 1411a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = next_token (v->value); 1412a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p != v->value && *p == '\0') 1413a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* All whitespace. */ 1414a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("$(subst ,,%s)", v->value); 1415a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (v->recursive) 1416a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (v->value, stdout); 1417a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1418a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Double up dollar signs. */ 1419a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (p = v->value; *p != '\0'; ++p) 1420a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1421a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*p == '$') 1422a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner putchar ('$'); 1423a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner putchar (*p); 1424a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1425a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner putchar ('\n'); 1426a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1427a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1428a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1429a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1430a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Print all the variables in SET. PREFIX is printed before 1431a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner the actual variable definitions (everything else is comments). */ 1432a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1433a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 1434a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerprint_variable_set (struct variable_set *set, char *prefix) 1435a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1436a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_map_arg (&set->table, print_variable, prefix); 1437a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1438a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_("# variable set hash-table stats:\n"), stdout); 1439a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs ("# ", stdout); 1440a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_print_stats (&set->table, stdout); 1441a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner putc ('\n', stdout); 1442a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1443a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1444a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Print the data base of variables. */ 1445a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1446a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 1447a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerprint_variable_data_base (void) 1448a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1449a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner puts (_("\n# Variables\n")); 1450a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1451a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner print_variable_set (&global_variable_set, ""); 1452a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1453a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner puts (_("\n# Pattern-specific Variable Values")); 1454a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1455a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1456a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct pattern_var *p; 1457a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int rules = 0; 1458a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1459a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (p = pattern_vars; p != 0; p = p->next) 1460a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1461a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++rules; 1462a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("\n%s :\n", p->target); 1463a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner print_variable (&p->variable, "# "); 1464a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1465a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1466a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (rules == 0) 1467a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner puts (_("\n# No pattern-specific variable values.")); 1468a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1469a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("\n# %u pattern-specific variable values"), rules); 1470a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1471a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1472a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1473a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1474a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Print all the local variables of FILE. */ 1475a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1476a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 1477a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerprint_file_variables (struct file *file) 1478a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1479a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (file->variables != 0) 1480a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner print_variable_set (file->variables->set, "# "); 1481a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1482a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1483a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 1484a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 1485a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnersync_Path_environment (void) 1486a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1487a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *path = allocated_variable_expand ("$(PATH)"); 1488a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static char *environ_path = NULL; 1489a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1490a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!path) 1491a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return; 1492a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1493a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* 1494a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * If done this before, don't leak memory unnecessarily. 1495a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * Free the previous entry before allocating new one. 1496a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 1497a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (environ_path) 1498a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (environ_path); 1499a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1500a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* 1501a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * Create something WINDOWS32 world can grok 1502a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 1503a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner convert_Path_to_windows32 (path, ';'); 1504a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner environ_path = concat ("PATH", "=", path); 1505a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner putenv (environ_path); 1506a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (path); 1507a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1508a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1509