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