Deleted Added
full compact
var.c (133562) var.c (138232)
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.

--- 25 unchanged lines hidden (view full) ---

34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)var.c 8.3 (Berkeley) 3/19/94
39 */
40
41#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.

--- 25 unchanged lines hidden (view full) ---

34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)var.c 8.3 (Berkeley) 3/19/94
39 */
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: head/usr.bin/make/var.c 133562 2004-08-12 11:49:55Z harti $");
42__FBSDID("$FreeBSD: head/usr.bin/make/var.c 138232 2004-11-30 17:46:29Z harti $");
43
44/*-
45 * var.c --
46 * Variable-handling functions
47 *
48 * Interface:
49 * Var_Set Set the value of a variable in the given
50 * context. The variable is created if it doesn't

--- 79 unchanged lines hidden (view full) ---

130#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
131#define FIND_ENV 0x4 /* look in the environment also */
132
133static int VarCmp(void *, void *);
134static void VarPossiblyExpand(char **, GNode *);
135static Var *VarFind(char *, GNode *, int);
136static void VarAdd(char *, char *, GNode *);
137static void VarDelete(void *);
43
44/*-
45 * var.c --
46 * Variable-handling functions
47 *
48 * Interface:
49 * Var_Set Set the value of a variable in the given
50 * context. The variable is created if it doesn't

--- 79 unchanged lines hidden (view full) ---

130#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
131#define FIND_ENV 0x4 /* look in the environment also */
132
133static int VarCmp(void *, void *);
134static void VarPossiblyExpand(char **, GNode *);
135static Var *VarFind(char *, GNode *, int);
136static void VarAdd(char *, char *, GNode *);
137static void VarDelete(void *);
138static char *VarGetPattern(GNode *, int, char **, int, int *, int *,
138static char *VarGetPattern(GNode *, int, char **, int, int *, int *,
139 VarPattern *);
140static char *VarModify(char *,
141 Boolean (*)(const char *, Boolean, Buffer, void *),
142 void *);
143static int VarPrintVar(void *, void *);
144
145/*-
146 *-----------------------------------------------------------------------

--- 4 unchanged lines hidden (view full) ---

151 * Results:
152 * 0 if they match. non-zero otherwise.
153 *
154 * Side Effects:
155 * none
156 *-----------------------------------------------------------------------
157 */
158static int
139 VarPattern *);
140static char *VarModify(char *,
141 Boolean (*)(const char *, Boolean, Buffer, void *),
142 void *);
143static int VarPrintVar(void *, void *);
144
145/*-
146 *-----------------------------------------------------------------------

--- 4 unchanged lines hidden (view full) ---

151 * Results:
152 * 0 if they match. non-zero otherwise.
153 *
154 * Side Effects:
155 * none
156 *-----------------------------------------------------------------------
157 */
158static int
159VarCmp (void *v, void *name)
159VarCmp(void *v, void *name)
160{
160{
161 return (strcmp ((char *) name, ((Var *) v)->name));
161
162 return (strcmp((char *)name, ((Var *)v)->name));
162}
163
164/*-
165 *-----------------------------------------------------------------------
166 * VarPossiblyExpand --
167 * Expand a variable name's embedded variables in the given context.
168 *
169 * Results:
170 * The contents of name, possibly expanded.
171 *
172 * Side Effects:
173 * The caller must free the new contents or old contents of name.
174 *-----------------------------------------------------------------------
175 */
176static void
177VarPossiblyExpand(char **name, GNode *ctxt)
178{
163}
164
165/*-
166 *-----------------------------------------------------------------------
167 * VarPossiblyExpand --
168 * Expand a variable name's embedded variables in the given context.
169 *
170 * Results:
171 * The contents of name, possibly expanded.
172 *
173 * Side Effects:
174 * The caller must free the new contents or old contents of name.
175 *-----------------------------------------------------------------------
176 */
177static void
178VarPossiblyExpand(char **name, GNode *ctxt)
179{
180
179 if (strchr(*name, '$') != NULL)
180 *name = Var_Subst(NULL, *name, ctxt, 0);
181 else
182 *name = estrdup(*name);
183}
184
185/*-
186 *-----------------------------------------------------------------------

--- 10 unchanged lines hidden (view full) ---

197 * A pointer to the structure describing the desired variable or
198 * NULL if the variable does not exist.
199 *
200 * Side Effects:
201 * None
202 *-----------------------------------------------------------------------
203 */
204static Var *
181 if (strchr(*name, '$') != NULL)
182 *name = Var_Subst(NULL, *name, ctxt, 0);
183 else
184 *name = estrdup(*name);
185}
186
187/*-
188 *-----------------------------------------------------------------------

--- 10 unchanged lines hidden (view full) ---

199 * A pointer to the structure describing the desired variable or
200 * NULL if the variable does not exist.
201 *
202 * Side Effects:
203 * None
204 *-----------------------------------------------------------------------
205 */
206static Var *
205VarFind (char *name, GNode *ctxt, int flags)
207VarFind(char *name, GNode *ctxt, int flags)
206{
207 Boolean localCheckEnvFirst;
208 LstNode var;
209 Var *v;
210
211 /*
212 * If the variable name begins with a '.', it could very well be one of
213 * the local ones. We check the name against all the local variables
214 * and substitute the short version in for 'name' if it matches one of
215 * them.
216 */
208{
209 Boolean localCheckEnvFirst;
210 LstNode var;
211 Var *v;
212
213 /*
214 * If the variable name begins with a '.', it could very well be one of
215 * the local ones. We check the name against all the local variables
216 * and substitute the short version in for 'name' if it matches one of
217 * them.
218 */
217 if (*name == '.' && isupper((unsigned char) name[1]))
219 if (*name == '.' && isupper((unsigned char)name[1]))
218 switch (name[1]) {
219 case 'A':
220 if (!strcmp(name, ".ALLSRC"))
221 name = ALLSRC;
222 if (!strcmp(name, ".ARCHIVE"))
223 name = ARCHIVE;
224 break;
225 case 'I':

--- 17 unchanged lines hidden (view full) ---

243 name = TARGET;
244 break;
245 }
246
247 /*
248 * Note whether this is one of the specific variables we were told through
249 * the -E flag to use environment-variable-override for.
250 */
220 switch (name[1]) {
221 case 'A':
222 if (!strcmp(name, ".ALLSRC"))
223 name = ALLSRC;
224 if (!strcmp(name, ".ARCHIVE"))
225 name = ARCHIVE;
226 break;
227 case 'I':

--- 17 unchanged lines hidden (view full) ---

245 name = TARGET;
246 break;
247 }
248
249 /*
250 * Note whether this is one of the specific variables we were told through
251 * the -E flag to use environment-variable-override for.
252 */
251 if (Lst_Find (envFirstVars, (void *)name,
253 if (Lst_Find(envFirstVars, (void *)name,
252 (int (*)(void *, void *)) strcmp) != NULL)
253 {
254 localCheckEnvFirst = TRUE;
255 } else {
256 localCheckEnvFirst = FALSE;
257 }
258
259 /*
260 * First look for the variable in the given context. If it's not there,
261 * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
262 * depending on the FIND_* flags in 'flags'
263 */
254 (int (*)(void *, void *)) strcmp) != NULL)
255 {
256 localCheckEnvFirst = TRUE;
257 } else {
258 localCheckEnvFirst = FALSE;
259 }
260
261 /*
262 * First look for the variable in the given context. If it's not there,
263 * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
264 * depending on the FIND_* flags in 'flags'
265 */
264 var = Lst_Find (ctxt->context, (void *)name, VarCmp);
266 var = Lst_Find(ctxt->context, (void *)name, VarCmp);
265
266 if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
267
268 if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
267 var = Lst_Find (VAR_CMD->context, (void *)name, VarCmp);
269 var = Lst_Find(VAR_CMD->context, (void *)name, VarCmp);
268 }
269 if ((var == NULL) && (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL) &&
270 !checkEnvFirst && !localCheckEnvFirst)
271 {
270 }
271 if ((var == NULL) && (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL) &&
272 !checkEnvFirst && !localCheckEnvFirst)
273 {
272 var = Lst_Find (VAR_GLOBAL->context, (void *)name, VarCmp);
274 var = Lst_Find(VAR_GLOBAL->context, (void *)name, VarCmp);
273 }
274 if ((var == NULL) && (flags & FIND_ENV)) {
275 char *env;
276
275 }
276 if ((var == NULL) && (flags & FIND_ENV)) {
277 char *env;
278
277 if ((env = getenv (name)) != NULL) {
279 if ((env = getenv(name)) != NULL) {
278 int len;
279
280 int len;
281
280 v = (Var *) emalloc(sizeof(Var));
282 v = (Var *)emalloc(sizeof(Var));
281 v->name = estrdup(name);
282
283 len = strlen(env);
284
285 v->val = Buf_Init(len);
286 Buf_AddBytes(v->val, len, (Byte *)env);
287
288 v->flags = VAR_FROM_ENV;
289 return (v);
290 } else if ((checkEnvFirst || localCheckEnvFirst) &&
291 (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL))
292 {
283 v->name = estrdup(name);
284
285 len = strlen(env);
286
287 v->val = Buf_Init(len);
288 Buf_AddBytes(v->val, len, (Byte *)env);
289
290 v->flags = VAR_FROM_ENV;
291 return (v);
292 } else if ((checkEnvFirst || localCheckEnvFirst) &&
293 (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL))
294 {
293 var = Lst_Find (VAR_GLOBAL->context, (void *)name, VarCmp);
295 var = Lst_Find(VAR_GLOBAL->context, (void *)name, VarCmp);
294 if (var == NULL) {
296 if (var == NULL) {
295 return ((Var *) NULL);
297 return ((Var *)NULL);
296 } else {
297 return ((Var *)Lst_Datum(var));
298 }
299 } else {
298 } else {
299 return ((Var *)Lst_Datum(var));
300 }
301 } else {
300 return((Var *)NULL);
302 return ((Var *)NULL);
301 }
302 } else if (var == NULL) {
303 }
304 } else if (var == NULL) {
303 return ((Var *) NULL);
305 return ((Var *)NULL);
304 } else {
306 } else {
305 return ((Var *) Lst_Datum (var));
307 return ((Var *)Lst_Datum(var));
306 }
307}
308
309/*-
310 *-----------------------------------------------------------------------
311 * VarAdd --
312 * Add a new variable of name name and value val to the given context.
313 *
314 * Results:
315 * None
316 *
317 * Side Effects:
318 * The new variable is placed at the front of the given context
319 * The name and val arguments are duplicated so they may
320 * safely be freed.
321 *-----------------------------------------------------------------------
322 */
323static void
308 }
309}
310
311/*-
312 *-----------------------------------------------------------------------
313 * VarAdd --
314 * Add a new variable of name name and value val to the given context.
315 *
316 * Results:
317 * None
318 *
319 * Side Effects:
320 * The new variable is placed at the front of the given context
321 * The name and val arguments are duplicated so they may
322 * safely be freed.
323 *-----------------------------------------------------------------------
324 */
325static void
324VarAdd (char *name, char *val, GNode *ctxt)
326VarAdd(char *name, char *val, GNode *ctxt)
325{
326 Var *v;
327 int len;
328
327{
328 Var *v;
329 int len;
330
329 v = (Var *) emalloc (sizeof (Var));
331 v = (Var *)emalloc(sizeof(Var));
330
332
331 v->name = estrdup (name);
333 v->name = estrdup(name);
332
333 len = val ? strlen(val) : 0;
334 v->val = Buf_Init(len+1);
335 Buf_AddBytes(v->val, len, (Byte *)val);
336
337 v->flags = 0;
338
334
335 len = val ? strlen(val) : 0;
336 v->val = Buf_Init(len+1);
337 Buf_AddBytes(v->val, len, (Byte *)val);
338
339 v->flags = 0;
340
339 (void) Lst_AtFront (ctxt->context, (void *)v);
340 (void) Lst_AtEnd (allVars, (void *) v);
341 Lst_AtFront(ctxt->context, (void *)v);
342 Lst_AtEnd(allVars, (void *)v);
341 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
342}
343
343 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
344}
345
344
345/*-
346 *-----------------------------------------------------------------------
347 * VarDelete --
348 * Delete a variable and all the space associated with it.
349 *
350 * Results:
351 * None
352 *
353 * Side Effects:
354 * None
355 *-----------------------------------------------------------------------
356 */
357static void
358VarDelete(void *vp)
359{
346/*-
347 *-----------------------------------------------------------------------
348 * VarDelete --
349 * Delete a variable and all the space associated with it.
350 *
351 * Results:
352 * None
353 *
354 * Side Effects:
355 * None
356 *-----------------------------------------------------------------------
357 */
358static void
359VarDelete(void *vp)
360{
360 Var *v = (Var *) vp;
361 Var *v = (Var *)vp;
362
361 free(v->name);
362 Buf_Destroy(v->val, TRUE);
363 free(v);
364}
365
363 free(v->name);
364 Buf_Destroy(v->val, TRUE);
365 free(v);
366}
367
366
367
368/*-
369 *-----------------------------------------------------------------------
370 * Var_Delete --
371 * Remove a variable from a context.
372 *
373 * Results:
374 * None.
375 *

--- 11 unchanged lines hidden (view full) ---

387 ln = Lst_Find(ctxt->context, (void *)name, VarCmp);
388 if (ln != NULL) {
389 Var *v;
390
391 v = (Var *)Lst_Datum(ln);
392 Lst_Remove(ctxt->context, ln);
393 ln = Lst_Member(allVars, v);
394 Lst_Remove(allVars, ln);
368/*-
369 *-----------------------------------------------------------------------
370 * Var_Delete --
371 * Remove a variable from a context.
372 *
373 * Results:
374 * None.
375 *

--- 11 unchanged lines hidden (view full) ---

387 ln = Lst_Find(ctxt->context, (void *)name, VarCmp);
388 if (ln != NULL) {
389 Var *v;
390
391 v = (Var *)Lst_Datum(ln);
392 Lst_Remove(ctxt->context, ln);
393 ln = Lst_Member(allVars, v);
394 Lst_Remove(allVars, ln);
395 VarDelete((void *) v);
395 VarDelete((void *)v);
396 }
397}
398
399/*-
400 *-----------------------------------------------------------------------
401 * Var_Set --
402 * Set the variable name to the value val in the given context.
403 *

--- 9 unchanged lines hidden (view full) ---

413 * created in that context. I.e. if the context is VAR_GLOBAL,
414 * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
415 * VAR_CMD->context is searched. This is done to avoid the literally
416 * thousands of unnecessary strcmp's that used to be done to
417 * set, say, $(@) or $(<).
418 *-----------------------------------------------------------------------
419 */
420void
396 }
397}
398
399/*-
400 *-----------------------------------------------------------------------
401 * Var_Set --
402 * Set the variable name to the value val in the given context.
403 *

--- 9 unchanged lines hidden (view full) ---

413 * created in that context. I.e. if the context is VAR_GLOBAL,
414 * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
415 * VAR_CMD->context is searched. This is done to avoid the literally
416 * thousands of unnecessary strcmp's that used to be done to
417 * set, say, $(@) or $(<).
418 *-----------------------------------------------------------------------
419 */
420void
421Var_Set (char *name, char *val, GNode *ctxt)
421Var_Set(char *name, char *val, GNode *ctxt)
422{
423 Var *v;
424
425 /*
426 * We only look for a variable in the given context since anything set
427 * here will override anything in a lower context, so there's not much
428 * point in searching them all just to save a bit of memory...
429 */
430 VarPossiblyExpand(&name, ctxt);
422{
423 Var *v;
424
425 /*
426 * We only look for a variable in the given context since anything set
427 * here will override anything in a lower context, so there's not much
428 * point in searching them all just to save a bit of memory...
429 */
430 VarPossiblyExpand(&name, ctxt);
431 v = VarFind (name, ctxt, 0);
432 if (v == (Var *) NULL) {
433 VarAdd (name, val, ctxt);
431 v = VarFind(name, ctxt, 0);
432 if (v == (Var *)NULL) {
433 VarAdd(name, val, ctxt);
434 } else {
435 Buf_Discard(v->val, Buf_Size(v->val));
436 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
437
438 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
439 }
440 /*
441 * Any variables given on the command line are automatically exported

--- 23 unchanged lines hidden (view full) ---

465 * environment searched.
466 * XXX: Knows its calling circumstances in that if called with ctxt
467 * an actual target, it will only search that context since only
468 * a local variable could be being appended to. This is actually
469 * a big win and must be tolerated.
470 *-----------------------------------------------------------------------
471 */
472void
434 } else {
435 Buf_Discard(v->val, Buf_Size(v->val));
436 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
437
438 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
439 }
440 /*
441 * Any variables given on the command line are automatically exported

--- 23 unchanged lines hidden (view full) ---

465 * environment searched.
466 * XXX: Knows its calling circumstances in that if called with ctxt
467 * an actual target, it will only search that context since only
468 * a local variable could be being appended to. This is actually
469 * a big win and must be tolerated.
470 *-----------------------------------------------------------------------
471 */
472void
473Var_Append (char *name, char *val, GNode *ctxt)
473Var_Append(char *name, char *val, GNode *ctxt)
474{
475 Var *v;
476
477 VarPossiblyExpand(&name, ctxt);
474{
475 Var *v;
476
477 VarPossiblyExpand(&name, ctxt);
478 v = VarFind (name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
478 v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
479
479
480 if (v == (Var *) NULL) {
481 VarAdd (name, val, ctxt);
480 if (v == (Var *)NULL) {
481 VarAdd(name, val, ctxt);
482 } else {
483 Buf_AddByte(v->val, (Byte)' ');
484 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
485
482 } else {
483 Buf_AddByte(v->val, (Byte)' ');
484 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
485
486 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name,
487 (char *) Buf_GetAll(v->val, (int *)NULL)));
486 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name,
487 (char *)Buf_GetAll(v->val, (int *)NULL)));
488
489 if (v->flags & VAR_FROM_ENV) {
490 /*
491 * If the original variable came from the environment, we
492 * have to install it in the global context (we could place
493 * it in the environment, but then we should provide a way to
494 * export other variables...)
495 */

--- 22 unchanged lines hidden (view full) ---

518{
519 Var *v;
520
521 VarPossiblyExpand(&name, ctxt);
522 v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
523 free(name);
524
525 if (v == (Var *)NULL) {
488
489 if (v->flags & VAR_FROM_ENV) {
490 /*
491 * If the original variable came from the environment, we
492 * have to install it in the global context (we could place
493 * it in the environment, but then we should provide a way to
494 * export other variables...)
495 */

--- 22 unchanged lines hidden (view full) ---

518{
519 Var *v;
520
521 VarPossiblyExpand(&name, ctxt);
522 v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
523 free(name);
524
525 if (v == (Var *)NULL) {
526 return(FALSE);
526 return (FALSE);
527 } else if (v->flags & VAR_FROM_ENV) {
528 free(v->name);
529 Buf_Destroy(v->val, TRUE);
530 free((char *)v);
531 }
527 } else if (v->flags & VAR_FROM_ENV) {
528 free(v->name);
529 Buf_Destroy(v->val, TRUE);
530 free((char *)v);
531 }
532 return(TRUE);
532 return (TRUE);
533}
534
535/*-
536 *-----------------------------------------------------------------------
537 * Var_Value --
538 * Return the value of the named variable in the given context
539 *
540 * Results:
541 * The value if the variable exists, NULL if it doesn't
542 *
543 * Side Effects:
544 * None
545 *-----------------------------------------------------------------------
546 */
547char *
533}
534
535/*-
536 *-----------------------------------------------------------------------
537 * Var_Value --
538 * Return the value of the named variable in the given context
539 *
540 * Results:
541 * The value if the variable exists, NULL if it doesn't
542 *
543 * Side Effects:
544 * None
545 *-----------------------------------------------------------------------
546 */
547char *
548Var_Value (char *name, GNode *ctxt, char **frp)
548Var_Value(char *name, GNode *ctxt, char **frp)
549{
550 Var *v;
551
552 VarPossiblyExpand(&name, ctxt);
549{
550 Var *v;
551
552 VarPossiblyExpand(&name, ctxt);
553 v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
553 v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
554 free(name);
555 *frp = NULL;
556 if (v != (Var *) NULL) {
557 char *p = ((char *)Buf_GetAll(v->val, (int *)NULL));
558 if (v->flags & VAR_FROM_ENV) {
559 Buf_Destroy(v->val, FALSE);
560 free(v);
561 *frp = p;
562 }
554 free(name);
555 *frp = NULL;
556 if (v != (Var *) NULL) {
557 char *p = ((char *)Buf_GetAll(v->val, (int *)NULL));
558 if (v->flags & VAR_FROM_ENV) {
559 Buf_Destroy(v->val, FALSE);
560 free(v);
561 *frp = p;
562 }
563 return p;
563 return (p);
564 } else {
564 } else {
565 return ((char *) NULL);
565 return ((char *)NULL);
566 }
567}
568
569/*-
570 *-----------------------------------------------------------------------
571 * VarModify --
572 * Modify each of the words of the passed string using the given
573 * function. Used to implement all modifiers.
574 *
575 * Results:
576 * A string of all the words modified appropriately.
577 *
578 * Side Effects:
579 * None.
580 *
581 *-----------------------------------------------------------------------
582 */
583static char *
566 }
567}
568
569/*-
570 *-----------------------------------------------------------------------
571 * VarModify --
572 * Modify each of the words of the passed string using the given
573 * function. Used to implement all modifiers.
574 *
575 * Results:
576 * A string of all the words modified appropriately.
577 *
578 * Side Effects:
579 * None.
580 *
581 *-----------------------------------------------------------------------
582 */
583static char *
584VarModify (char *str, Boolean (*modProc)(const char *, Boolean, Buffer, void *),
584VarModify(char *str, Boolean (*modProc)(const char *, Boolean, Buffer, void *),
585 void *datum)
586{
587 Buffer buf; /* Buffer for the new string */
588 Boolean addSpace; /* TRUE if need to add a space to the
589 * buffer before adding the trimmed
590 * word */
591 char **av; /* word list [first word does not count] */
592 int ac, i;
593
585 void *datum)
586{
587 Buffer buf; /* Buffer for the new string */
588 Boolean addSpace; /* TRUE if need to add a space to the
589 * buffer before adding the trimmed
590 * word */
591 char **av; /* word list [first word does not count] */
592 int ac, i;
593
594 buf = Buf_Init (0);
594 buf = Buf_Init(0);
595 addSpace = FALSE;
596
597 av = brk_string(str, &ac, FALSE);
598
599 for (i = 1; i < ac; i++)
600 addSpace = (*modProc)(av[i], addSpace, buf, datum);
601
602 Buf_AddByte (buf, '\0');
595 addSpace = FALSE;
596
597 av = brk_string(str, &ac, FALSE);
598
599 for (i = 1; i < ac; i++)
600 addSpace = (*modProc)(av[i], addSpace, buf, datum);
601
602 Buf_AddByte (buf, '\0');
603 str = (char *)Buf_GetAll (buf, (int *)NULL);
604 Buf_Destroy (buf, FALSE);
603 str = (char *)Buf_GetAll(buf, (int *)NULL);
604 Buf_Destroy(buf, FALSE);
605 return (str);
606}
607
608/*-
609 *-----------------------------------------------------------------------
610 * VarSortWords --
611 * Sort the words in the string.
612 *

--- 26 unchanged lines hidden (view full) ---

639 str = (char *)Buf_GetAll(buf, (int *)NULL);
640 Buf_Destroy(buf, FALSE);
641 return (str);
642}
643
644static int
645SortIncreasing(const void *l, const void *r)
646{
605 return (str);
606}
607
608/*-
609 *-----------------------------------------------------------------------
610 * VarSortWords --
611 * Sort the words in the string.
612 *

--- 26 unchanged lines hidden (view full) ---

639 str = (char *)Buf_GetAll(buf, (int *)NULL);
640 Buf_Destroy(buf, FALSE);
641 return (str);
642}
643
644static int
645SortIncreasing(const void *l, const void *r)
646{
647
647 return (strcmp(*(const char* const*)l, *(const char* const*)r));
648}
649
650/*-
651 *-----------------------------------------------------------------------
652 * VarGetPattern --
653 * Pass through the tstr looking for 1) escaped delimiters,
654 * '$'s and backslashes (place the escaped character in

--- 16 unchanged lines hidden (view full) ---

671 */
672static char *
673VarGetPattern(GNode *ctxt, int err, char **tstr, int delim, int *flags,
674 int *length, VarPattern *pattern)
675{
676 char *cp;
677 Buffer buf = Buf_Init(0);
678 int junk;
648 return (strcmp(*(const char* const*)l, *(const char* const*)r));
649}
650
651/*-
652 *-----------------------------------------------------------------------
653 * VarGetPattern --
654 * Pass through the tstr looking for 1) escaped delimiters,
655 * '$'s and backslashes (place the escaped character in

--- 16 unchanged lines hidden (view full) ---

672 */
673static char *
674VarGetPattern(GNode *ctxt, int err, char **tstr, int delim, int *flags,
675 int *length, VarPattern *pattern)
676{
677 char *cp;
678 Buffer buf = Buf_Init(0);
679 int junk;
680
679 if (length == NULL)
680 length = &junk;
681
682#define IS_A_MATCH(cp, delim) \
683 ((cp[0] == '\\') && ((cp[1] == delim) || \
684 (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
685
686 /*
687 * Skim through until the matching delimiter is found;
688 * pick up variable substitutions on the way. Also allow
689 * backslashes to quote the delimiter, $, and \, but don't
690 * touch other backslashes.
691 */
692 for (cp = *tstr; *cp && (*cp != delim); cp++) {
693 if (IS_A_MATCH(cp, delim)) {
681 if (length == NULL)
682 length = &junk;
683
684#define IS_A_MATCH(cp, delim) \
685 ((cp[0] == '\\') && ((cp[1] == delim) || \
686 (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
687
688 /*
689 * Skim through until the matching delimiter is found;
690 * pick up variable substitutions on the way. Also allow
691 * backslashes to quote the delimiter, $, and \, but don't
692 * touch other backslashes.
693 */
694 for (cp = *tstr; *cp && (*cp != delim); cp++) {
695 if (IS_A_MATCH(cp, delim)) {
694 Buf_AddByte(buf, (Byte) cp[1]);
696 Buf_AddByte(buf, (Byte)cp[1]);
695 cp++;
696 } else if (*cp == '$') {
697 if (cp[1] == delim) {
698 if (flags == NULL)
697 cp++;
698 } else if (*cp == '$') {
699 if (cp[1] == delim) {
700 if (flags == NULL)
699 Buf_AddByte(buf, (Byte) *cp);
701 Buf_AddByte(buf, (Byte)*cp);
700 else
701 /*
702 * Unescaped $ at end of pattern => anchor
703 * pattern at end.
704 */
705 *flags |= VAR_MATCH_END;
706 } else {
707 if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
708 char *cp2;
709 int len;
710 Boolean freeIt;
711
712 /*
713 * If unescaped dollar sign not before the
714 * delimiter, assume it's a variable
715 * substitution and recurse.
716 */
717 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
702 else
703 /*
704 * Unescaped $ at end of pattern => anchor
705 * pattern at end.
706 */
707 *flags |= VAR_MATCH_END;
708 } else {
709 if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
710 char *cp2;
711 int len;
712 Boolean freeIt;
713
714 /*
715 * If unescaped dollar sign not before the
716 * delimiter, assume it's a variable
717 * substitution and recurse.
718 */
719 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
718 Buf_AddBytes(buf, strlen(cp2), (Byte *) cp2);
720 Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
719 if (freeIt)
720 free(cp2);
721 cp += len - 1;
722 } else {
723 char *cp2 = &cp[1];
724
725 if (*cp2 == '(' || *cp2 == '{') {
726 /*

--- 11 unchanged lines hidden (view full) ---

738 ++depth;
739 if (*cp2 == want)
740 --depth;
741 }
742 }
743 Buf_AddBytes(buf, cp2 - cp, (Byte *)cp);
744 cp = --cp2;
745 } else
721 if (freeIt)
722 free(cp2);
723 cp += len - 1;
724 } else {
725 char *cp2 = &cp[1];
726
727 if (*cp2 == '(' || *cp2 == '{') {
728 /*

--- 11 unchanged lines hidden (view full) ---

740 ++depth;
741 if (*cp2 == want)
742 --depth;
743 }
744 }
745 Buf_AddBytes(buf, cp2 - cp, (Byte *)cp);
746 cp = --cp2;
747 } else
746 Buf_AddByte(buf, (Byte) *cp);
748 Buf_AddByte(buf, (Byte)*cp);
747 }
748 }
749 }
750 else if (pattern && *cp == '&')
751 Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs);
752 else
749 }
750 }
751 }
752 else if (pattern && *cp == '&')
753 Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs);
754 else
753 Buf_AddByte(buf, (Byte) *cp);
755 Buf_AddByte(buf, (Byte)*cp);
754 }
755
756 }
757
756 Buf_AddByte(buf, (Byte) '\0');
758 Buf_AddByte(buf, (Byte)'\0');
757
758 if (*cp != delim) {
759 *tstr = cp;
760 *length = 0;
759
760 if (*cp != delim) {
761 *tstr = cp;
762 *length = 0;
761 return NULL;
762 }
763 else {
763 return (NULL);
764 } else {
764 *tstr = ++cp;
765 *tstr = ++cp;
765 cp = (char *) Buf_GetAll(buf, length);
766 cp = (char *)Buf_GetAll(buf, length);
766 *length -= 1; /* Don't count the NULL */
767 Buf_Destroy(buf, FALSE);
767 *length -= 1; /* Don't count the NULL */
768 Buf_Destroy(buf, FALSE);
768 return cp;
769 return (cp);
769 }
770}
771
770 }
771}
772
772
773/*-
774 *-----------------------------------------------------------------------
775 * Var_Quote --
776 * Quote shell meta-characters in the string
777 *
778 * Results:
779 * The quoted string
780 *
781 * Side Effects:
782 * None.
783 *
784 *-----------------------------------------------------------------------
785 */
786char *
787Var_Quote(const char *str)
788{
773/*-
774 *-----------------------------------------------------------------------
775 * Var_Quote --
776 * Quote shell meta-characters in the string
777 *
778 * Results:
779 * The quoted string
780 *
781 * Side Effects:
782 * None.
783 *
784 *-----------------------------------------------------------------------
785 */
786char *
787Var_Quote(const char *str)
788{
789
790 Buffer buf;
791 /* This should cover most shells :-( */
792 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
793 char *ret;
794
789 Buffer buf;
790 /* This should cover most shells :-( */
791 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
792 char *ret;
793
795 buf = Buf_Init (MAKE_BSIZE);
794 buf = Buf_Init(MAKE_BSIZE);
796 for (; *str; str++) {
797 if (strchr(meta, *str) != NULL)
798 Buf_AddByte(buf, (Byte)'\\');
799 Buf_AddByte(buf, (Byte)*str);
800 }
795 for (; *str; str++) {
796 if (strchr(meta, *str) != NULL)
797 Buf_AddByte(buf, (Byte)'\\');
798 Buf_AddByte(buf, (Byte)*str);
799 }
801 Buf_AddByte(buf, (Byte) '\0');
802 ret = Buf_GetAll (buf, NULL);
803 Buf_Destroy (buf, FALSE);
804 return ret;
800 Buf_AddByte(buf, (Byte)'\0');
801 ret = Buf_GetAll(buf, NULL);
802 Buf_Destroy(buf, FALSE);
803 return (ret);
805}
806
807/*-
808 *-----------------------------------------------------------------------
809 * VarREError --
810 * Print the error caused by a regcomp or regexec call.
811 *
812 * Results:

--- 71 unchanged lines hidden (view full) ---

884 * We just need to check for the first character and return the
885 * value if it exists.
886 */
887 char name[2];
888
889 name[0] = str[1];
890 name[1] = '\0';
891
804}
805
806/*-
807 *-----------------------------------------------------------------------
808 * VarREError --
809 * Print the error caused by a regcomp or regexec call.
810 *
811 * Results:

--- 71 unchanged lines hidden (view full) ---

883 * We just need to check for the first character and return the
884 * value if it exists.
885 */
886 char name[2];
887
888 name[0] = str[1];
889 name[1] = '\0';
890
892 v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
891 v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
893 if (v == (Var *)NULL) {
894 if (str[1] != '\0')
895 *lengthPtr = 2;
896 else
897 *lengthPtr = 1;
898
899 if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
900 /*
901 * If substituting a local variable in a non-local context,
902 * assume it's for dynamic source stuff. We have to handle
903 * this specially and return the longhand for the variable
904 * with the dollar sign escaped so it makes it back to the
905 * caller. Only four of the local variables are treated
906 * specially as they are the only four that will be set
907 * when dynamic sources are expanded.
908 */
909 /* XXX: It looks like $% and $! are reversed here */
910 switch (str[1]) {
911 case '@':
892 if (v == (Var *)NULL) {
893 if (str[1] != '\0')
894 *lengthPtr = 2;
895 else
896 *lengthPtr = 1;
897
898 if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
899 /*
900 * If substituting a local variable in a non-local context,
901 * assume it's for dynamic source stuff. We have to handle
902 * this specially and return the longhand for the variable
903 * with the dollar sign escaped so it makes it back to the
904 * caller. Only four of the local variables are treated
905 * specially as they are the only four that will be set
906 * when dynamic sources are expanded.
907 */
908 /* XXX: It looks like $% and $! are reversed here */
909 switch (str[1]) {
910 case '@':
912 return("$(.TARGET)");
911 return ("$(.TARGET)");
913 case '%':
912 case '%':
914 return("$(.ARCHIVE)");
913 return ("$(.ARCHIVE)");
915 case '*':
914 case '*':
916 return("$(.PREFIX)");
915 return ("$(.PREFIX)");
917 case '!':
916 case '!':
918 return("$(.MEMBER)");
917 return ("$(.MEMBER)");
919 default:
920 break;
921 }
922 }
923 /*
924 * Error
925 */
926 return (err ? var_Error : varNoError);

--- 13 unchanged lines hidden (view full) ---

940 * Skip to the end character or a colon, whichever comes first,
941 * replacing embedded variables as we go.
942 */
943 for (tstr = str + 2; *tstr != '\0' && *tstr != endc && *tstr != ':'; tstr++)
944 if (*tstr == '$') {
945 int rlen;
946 Boolean rfree;
947 char* rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
918 default:
919 break;
920 }
921 }
922 /*
923 * Error
924 */
925 return (err ? var_Error : varNoError);

--- 13 unchanged lines hidden (view full) ---

939 * Skip to the end character or a colon, whichever comes first,
940 * replacing embedded variables as we go.
941 */
942 for (tstr = str + 2; *tstr != '\0' && *tstr != endc && *tstr != ':'; tstr++)
943 if (*tstr == '$') {
944 int rlen;
945 Boolean rfree;
946 char* rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
948
947
949 if (rval == var_Error) {
950 Fatal("Error expanding embedded variable.");
951 } else if (rval != NULL) {
948 if (rval == var_Error) {
949 Fatal("Error expanding embedded variable.");
950 } else if (rval != NULL) {
952 Buf_AddBytes(buf, strlen(rval), (Byte *) rval);
951 Buf_AddBytes(buf, strlen(rval), (Byte *)rval);
953 if (rfree)
954 free(rval);
955 }
956 tstr += rlen - 1;
957 } else
952 if (rfree)
953 free(rval);
954 }
955 tstr += rlen - 1;
956 } else
958 Buf_AddByte(buf, (Byte) *tstr);
959
957 Buf_AddByte(buf, (Byte)*tstr);
958
960 if (*tstr == '\0') {
961 /*
962 * If we never did find the end character, return NULL
963 * right now, setting the length to be the distance to
964 * the end of the string, since that's what make does.
965 */
966 *lengthPtr = tstr - str;
967 return (var_Error);
968 }
959 if (*tstr == '\0') {
960 /*
961 * If we never did find the end character, return NULL
962 * right now, setting the length to be the distance to
963 * the end of the string, since that's what make does.
964 */
965 *lengthPtr = tstr - str;
966 return (var_Error);
967 }
969
968
970 haveModifier = (*tstr == ':');
971 *tstr = '\0';
972
969 haveModifier = (*tstr == ':');
970 *tstr = '\0';
971
973 Buf_AddByte(buf, (Byte) '\0');
972 Buf_AddByte(buf, (Byte)'\0');
974 str = Buf_GetAll(buf, NULL);
975 vlen = strlen(str);
976
973 str = Buf_GetAll(buf, NULL);
974 vlen = strlen(str);
975
977 v = VarFind (str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
976 v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
978 if ((v == (Var *)NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
979 (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
980 {
981 /*
982 * Check for bogus D and F forms of local variables since we're
983 * in a local context and the name is the right length.
984 */
977 if ((v == (Var *)NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
978 (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
979 {
980 /*
981 * Check for bogus D and F forms of local variables since we're
982 * in a local context and the name is the right length.
983 */
985 switch(str[0]) {
984 switch (str[0]) {
986 case '@':
987 case '%':
988 case '*':
989 case '!':
990 case '>':
991 case '<':
992 {
993 char vname[2];

--- 22 unchanged lines hidden (view full) ---

1016 /*
1017 * Resulting string is dynamically allocated, so
1018 * tell caller to free it.
1019 */
1020 *freePtr = TRUE;
1021 *lengthPtr = tstr-start+1;
1022 *tstr = endc;
1023 Buf_Destroy(buf, TRUE);
985 case '@':
986 case '%':
987 case '*':
988 case '!':
989 case '>':
990 case '<':
991 {
992 char vname[2];

--- 22 unchanged lines hidden (view full) ---

1015 /*
1016 * Resulting string is dynamically allocated, so
1017 * tell caller to free it.
1018 */
1019 *freePtr = TRUE;
1020 *lengthPtr = tstr-start+1;
1021 *tstr = endc;
1022 Buf_Destroy(buf, TRUE);
1024 return(val);
1023 return (val);
1025 }
1026 break;
1027 default:
1028 break;
1029 }
1030 }
1031 }
1032
1033 if (v == (Var *)NULL) {
1034 if (((vlen == 1) ||
1024 }
1025 break;
1026 default:
1027 break;
1028 }
1029 }
1030 }
1031
1032 if (v == (Var *)NULL) {
1033 if (((vlen == 1) ||
1035 (((vlen == 2) && (str[1] == 'F' ||
1036 str[1] == 'D')))) &&
1034 (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
1037 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1038 {
1039 /*
1040 * If substituting a local variable in a non-local context,
1041 * assume it's for dynamic source stuff. We have to handle
1042 * this specially and return the longhand for the variable
1043 * with the dollar sign escaped so it makes it back to the
1044 * caller. Only four of the local variables are treated

--- 6 unchanged lines hidden (view full) ---

1051 case '*':
1052 case '!':
1053 dynamic = TRUE;
1054 break;
1055 default:
1056 break;
1057 }
1058 } else if ((vlen > 2) && (str[0] == '.') &&
1035 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1036 {
1037 /*
1038 * If substituting a local variable in a non-local context,
1039 * assume it's for dynamic source stuff. We have to handle
1040 * this specially and return the longhand for the variable
1041 * with the dollar sign escaped so it makes it back to the
1042 * caller. Only four of the local variables are treated

--- 6 unchanged lines hidden (view full) ---

1049 case '*':
1050 case '!':
1051 dynamic = TRUE;
1052 break;
1053 default:
1054 break;
1055 }
1056 } else if ((vlen > 2) && (str[0] == '.') &&
1059 isupper((unsigned char) str[1]) &&
1057 isupper((unsigned char)str[1]) &&
1060 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1061 {
1062 int len;
1063
1064 len = vlen - 1;
1065 if ((strncmp(str, ".TARGET", len) == 0) ||
1066 (strncmp(str, ".ARCHIVE", len) == 0) ||
1067 (strncmp(str, ".PREFIX", len) == 0) ||

--- 11 unchanged lines hidden (view full) ---

1079 *lengthPtr = tstr - start + 1;
1080 *tstr = endc;
1081 if (dynamic) {
1082 str = emalloc(*lengthPtr + 1);
1083 strncpy(str, start, *lengthPtr);
1084 str[*lengthPtr] = '\0';
1085 *freePtr = TRUE;
1086 Buf_Destroy(buf, TRUE);
1058 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1059 {
1060 int len;
1061
1062 len = vlen - 1;
1063 if ((strncmp(str, ".TARGET", len) == 0) ||
1064 (strncmp(str, ".ARCHIVE", len) == 0) ||
1065 (strncmp(str, ".PREFIX", len) == 0) ||

--- 11 unchanged lines hidden (view full) ---

1077 *lengthPtr = tstr - start + 1;
1078 *tstr = endc;
1079 if (dynamic) {
1080 str = emalloc(*lengthPtr + 1);
1081 strncpy(str, start, *lengthPtr);
1082 str[*lengthPtr] = '\0';
1083 *freePtr = TRUE;
1084 Buf_Destroy(buf, TRUE);
1087 return(str);
1085 return (str);
1088 } else {
1089 Buf_Destroy(buf, TRUE);
1090 return (err ? var_Error : varNoError);
1091 }
1092 } else {
1093 /*
1094 * Still need to get to the end of the variable specification,
1095 * so kludge up a Var structure for the modifications
1096 */
1086 } else {
1087 Buf_Destroy(buf, TRUE);
1088 return (err ? var_Error : varNoError);
1089 }
1090 } else {
1091 /*
1092 * Still need to get to the end of the variable specification,
1093 * so kludge up a Var structure for the modifications
1094 */
1097 v = (Var *) emalloc(sizeof(Var));
1095 v = (Var *)emalloc(sizeof(Var));
1098 v->name = estrdup(str);
1099 v->val = Buf_Init(1);
1100 v->flags = VAR_JUNK;
1101 }
1102 }
1103 Buf_Destroy(buf, TRUE);
1104 }
1105

--- 8 unchanged lines hidden (view full) ---

1114 * has been fully expanded. If it looks like recursion might be
1115 * necessary (there's a dollar sign somewhere in the variable's value)
1116 * we just call Var_Subst to do any other substitutions that are
1117 * necessary. Note that the value returned by Var_Subst will have
1118 * been dynamically-allocated, so it will need freeing when we
1119 * return.
1120 */
1121 str = (char *)Buf_GetAll(v->val, (int *)NULL);
1096 v->name = estrdup(str);
1097 v->val = Buf_Init(1);
1098 v->flags = VAR_JUNK;
1099 }
1100 }
1101 Buf_Destroy(buf, TRUE);
1102 }
1103

--- 8 unchanged lines hidden (view full) ---

1112 * has been fully expanded. If it looks like recursion might be
1113 * necessary (there's a dollar sign somewhere in the variable's value)
1114 * we just call Var_Subst to do any other substitutions that are
1115 * necessary. Note that the value returned by Var_Subst will have
1116 * been dynamically-allocated, so it will need freeing when we
1117 * return.
1118 */
1119 str = (char *)Buf_GetAll(v->val, (int *)NULL);
1122 if (strchr (str, '$') != (char *)NULL) {
1120 if (strchr(str, '$') != (char *)NULL) {
1123 str = Var_Subst(NULL, str, ctxt, err);
1124 *freePtr = TRUE;
1125 }
1126
1127 v->flags &= ~VAR_IN_USE;
1128
1129 /*
1130 * Now we need to apply any modifiers the user wants applied.

--- 34 unchanged lines hidden (view full) ---

1165 char *cp2;
1166 Boolean copy;
1167
1168 copy = FALSE;
1169 for (cp = tstr + 1;
1170 *cp != '\0' && *cp != ':' && *cp != endc;
1171 cp++)
1172 {
1121 str = Var_Subst(NULL, str, ctxt, err);
1122 *freePtr = TRUE;
1123 }
1124
1125 v->flags &= ~VAR_IN_USE;
1126
1127 /*
1128 * Now we need to apply any modifiers the user wants applied.

--- 34 unchanged lines hidden (view full) ---

1163 char *cp2;
1164 Boolean copy;
1165
1166 copy = FALSE;
1167 for (cp = tstr + 1;
1168 *cp != '\0' && *cp != ':' && *cp != endc;
1169 cp++)
1170 {
1173 if (*cp == '\\' && (cp[1] == ':' || cp[1] == endc)){
1171 if (*cp == '\\' && (cp[1] == ':' || cp[1] == endc)) {
1174 copy = TRUE;
1175 cp++;
1176 }
1177 }
1178 termc = *cp;
1179 *cp = '\0';
1180 if (copy) {
1181 /*

--- 16 unchanged lines hidden (view full) ---

1198 }
1199 *cp2 = '\0';
1200 } else {
1201 pattern = &tstr[1];
1202 }
1203 if (*tstr == 'M' || *tstr == 'm') {
1204 newStr = VarModify(str, VarMatch, (void *)pattern);
1205 } else {
1172 copy = TRUE;
1173 cp++;
1174 }
1175 }
1176 termc = *cp;
1177 *cp = '\0';
1178 if (copy) {
1179 /*

--- 16 unchanged lines hidden (view full) ---

1196 }
1197 *cp2 = '\0';
1198 } else {
1199 pattern = &tstr[1];
1200 }
1201 if (*tstr == 'M' || *tstr == 'm') {
1202 newStr = VarModify(str, VarMatch, (void *)pattern);
1203 } else {
1206 newStr = VarModify(str, VarNoMatch,
1207 (void *)pattern);
1204 newStr = VarModify(str, VarNoMatch, (void *)pattern);
1208 }
1209 if (copy) {
1210 free(pattern);
1211 }
1212 break;
1213 }
1214 case 'S':
1215 {

--- 153 unchanged lines hidden (view full) ---

1369 * Note that flags can only contain the 3 bits we're
1370 * interested in so we don't have to mask unrelated
1371 * bits. We can test for equality.
1372 */
1373 if (!pattern.leftLen && pattern.flags == VAR_SUB_GLOBAL)
1374 Fatal("Global substitution of the empty string");
1375
1376 termc = *cp;
1205 }
1206 if (copy) {
1207 free(pattern);
1208 }
1209 break;
1210 }
1211 case 'S':
1212 {

--- 153 unchanged lines hidden (view full) ---

1366 * Note that flags can only contain the 3 bits we're
1367 * interested in so we don't have to mask unrelated
1368 * bits. We can test for equality.
1369 */
1370 if (!pattern.leftLen && pattern.flags == VAR_SUB_GLOBAL)
1371 Fatal("Global substitution of the empty string");
1372
1373 termc = *cp;
1377 newStr = VarModify(str, VarSubstitute,
1378 (void *)&pattern);
1374 newStr = VarModify(str, VarSubstitute, (void *)&pattern);
1379 /*
1380 * Free the two strings.
1381 */
1382 free(pattern.lhs);
1383 free(pattern.rhs);
1384 break;
1385 }
1386 case 'C':

--- 73 unchanged lines hidden (view full) ---

1460 free(pattern.matches);
1461 break;
1462 }
1463 case 'L':
1464 if (tstr[1] == endc || tstr[1] == ':') {
1465 Buffer buf;
1466 buf = Buf_Init(MAKE_BSIZE);
1467 for (cp = str; *cp ; cp++)
1375 /*
1376 * Free the two strings.
1377 */
1378 free(pattern.lhs);
1379 free(pattern.rhs);
1380 break;
1381 }
1382 case 'C':

--- 73 unchanged lines hidden (view full) ---

1456 free(pattern.matches);
1457 break;
1458 }
1459 case 'L':
1460 if (tstr[1] == endc || tstr[1] == ':') {
1461 Buffer buf;
1462 buf = Buf_Init(MAKE_BSIZE);
1463 for (cp = str; *cp ; cp++)
1468 Buf_AddByte(buf, (Byte) tolower(*cp));
1464 Buf_AddByte(buf, (Byte)tolower(*cp));
1469
1465
1470 Buf_AddByte(buf, (Byte) '\0');
1471 newStr = (char *) Buf_GetAll(buf, (int *) NULL);
1466 Buf_AddByte(buf, (Byte)'\0');
1467 newStr = (char *)Buf_GetAll(buf, (int *)NULL);
1472 Buf_Destroy(buf, FALSE);
1473
1474 cp = tstr + 1;
1475 termc = *cp;
1476 break;
1477 }
1478 /* FALLTHROUGH */
1479 case 'O':
1480 if (tstr[1] == endc || tstr[1] == ':') {
1481 newStr = VarSortWords(str, SortIncreasing);
1482 cp = tstr + 1;
1483 termc = *cp;
1484 break;
1485 }
1486 /* FALLTHROUGH */
1487 case 'Q':
1488 if (tstr[1] == endc || tstr[1] == ':') {
1468 Buf_Destroy(buf, FALSE);
1469
1470 cp = tstr + 1;
1471 termc = *cp;
1472 break;
1473 }
1474 /* FALLTHROUGH */
1475 case 'O':
1476 if (tstr[1] == endc || tstr[1] == ':') {
1477 newStr = VarSortWords(str, SortIncreasing);
1478 cp = tstr + 1;
1479 termc = *cp;
1480 break;
1481 }
1482 /* FALLTHROUGH */
1483 case 'Q':
1484 if (tstr[1] == endc || tstr[1] == ':') {
1489 newStr = Var_Quote (str);
1485 newStr = Var_Quote(str);
1490 cp = tstr + 1;
1491 termc = *cp;
1492 break;
1493 }
1494 /*FALLTHRU*/
1495 case 'T':
1496 if (tstr[1] == endc || tstr[1] == ':') {
1486 cp = tstr + 1;
1487 termc = *cp;
1488 break;
1489 }
1490 /*FALLTHRU*/
1491 case 'T':
1492 if (tstr[1] == endc || tstr[1] == ':') {
1497 newStr = VarModify (str, VarTail, (void *)0);
1493 newStr = VarModify(str, VarTail, (void *)0);
1498 cp = tstr + 1;
1499 termc = *cp;
1500 break;
1501 }
1502 /*FALLTHRU*/
1503 case 'U':
1504 if (tstr[1] == endc || tstr[1] == ':') {
1505 Buffer buf;
1506 buf = Buf_Init(MAKE_BSIZE);
1507 for (cp = str; *cp ; cp++)
1494 cp = tstr + 1;
1495 termc = *cp;
1496 break;
1497 }
1498 /*FALLTHRU*/
1499 case 'U':
1500 if (tstr[1] == endc || tstr[1] == ':') {
1501 Buffer buf;
1502 buf = Buf_Init(MAKE_BSIZE);
1503 for (cp = str; *cp ; cp++)
1508 Buf_AddByte(buf, (Byte) toupper(*cp));
1504 Buf_AddByte(buf, (Byte)toupper(*cp));
1509
1505
1510 Buf_AddByte(buf, (Byte) '\0');
1511 newStr = (char *) Buf_GetAll(buf, (int *) NULL);
1506 Buf_AddByte(buf, (Byte)'\0');
1507 newStr = (char *)Buf_GetAll(buf, (int *)NULL);
1512 Buf_Destroy(buf, FALSE);
1513
1514 cp = tstr + 1;
1515 termc = *cp;
1516 break;
1517 }
1518 /* FALLTHROUGH */
1519 case 'H':
1520 if (tstr[1] == endc || tstr[1] == ':') {
1508 Buf_Destroy(buf, FALSE);
1509
1510 cp = tstr + 1;
1511 termc = *cp;
1512 break;
1513 }
1514 /* FALLTHROUGH */
1515 case 'H':
1516 if (tstr[1] == endc || tstr[1] == ':') {
1521 newStr = VarModify (str, VarHead, (void *)0);
1517 newStr = VarModify(str, VarHead, (void *)0);
1522 cp = tstr + 1;
1523 termc = *cp;
1524 break;
1525 }
1526 /*FALLTHRU*/
1527 case 'E':
1528 if (tstr[1] == endc || tstr[1] == ':') {
1518 cp = tstr + 1;
1519 termc = *cp;
1520 break;
1521 }
1522 /*FALLTHRU*/
1523 case 'E':
1524 if (tstr[1] == endc || tstr[1] == ':') {
1529 newStr = VarModify (str, VarSuffix, (void *)0);
1525 newStr = VarModify(str, VarSuffix, (void *)0);
1530 cp = tstr + 1;
1531 termc = *cp;
1532 break;
1533 }
1534 /*FALLTHRU*/
1535 case 'R':
1536 if (tstr[1] == endc || tstr[1] == ':') {
1526 cp = tstr + 1;
1527 termc = *cp;
1528 break;
1529 }
1530 /*FALLTHRU*/
1531 case 'R':
1532 if (tstr[1] == endc || tstr[1] == ':') {
1537 newStr = VarModify (str, VarRoot, (void *)0);
1533 newStr = VarModify(str, VarRoot, (void *)0);
1538 cp = tstr + 1;
1539 termc = *cp;
1540 break;
1541 }
1542 /*FALLTHRU*/
1543#ifdef SUNSHCMD
1544 case 's':
1545 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
1546 char *error;
1534 cp = tstr + 1;
1535 termc = *cp;
1536 break;
1537 }
1538 /*FALLTHRU*/
1539#ifdef SUNSHCMD
1540 case 's':
1541 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
1542 char *error;
1547 newStr = Cmd_Exec (str, &error);
1543 newStr = Cmd_Exec(str, &error);
1548 if (error)
1544 if (error)
1549 Error (error, str);
1545 Error(error, str);
1550 cp = tstr + 2;
1551 termc = *cp;
1552 break;
1553 }
1554 /*FALLTHRU*/
1555#endif
1556 default:
1557 {

--- 63 unchanged lines hidden (view full) ---

1621 }
1622
1623 /*
1624 * SYSV modifications happen through the whole
1625 * string. Note the pattern is anchored at the end.
1626 */
1627 termc = *--cp;
1628 delim = '\0';
1546 cp = tstr + 2;
1547 termc = *cp;
1548 break;
1549 }
1550 /*FALLTHRU*/
1551#endif
1552 default:
1553 {

--- 63 unchanged lines hidden (view full) ---

1617 }
1618
1619 /*
1620 * SYSV modifications happen through the whole
1621 * string. Note the pattern is anchored at the end.
1622 */
1623 termc = *--cp;
1624 delim = '\0';
1629 newStr = VarModify(str, VarSYSVMatch,
1630 (void *)&pattern);
1625 newStr = VarModify(str, VarSYSVMatch, (void *)&pattern);
1631
1632 free(pattern.lhs);
1633 free(pattern.rhs);
1634
1635 termc = endc;
1636 } else
1637#endif
1638 {
1626
1627 free(pattern.lhs);
1628 free(pattern.rhs);
1629
1630 termc = endc;
1631 } else
1632#endif
1633 {
1639 Error ("Unknown modifier '%c'\n", *tstr);
1634 Error("Unknown modifier '%c'\n", *tstr);
1640 for (cp = tstr+1;
1641 *cp != ':' && *cp != endc && *cp != '\0';
1642 cp++)
1643 continue;
1644 termc = *cp;
1645 newStr = var_Error;
1646 }
1647 }
1648 }
1649 DEBUGF(VAR, ("Result is \"%s\"\n", newStr));
1650
1651 if (*freePtr) {
1635 for (cp = tstr+1;
1636 *cp != ':' && *cp != endc && *cp != '\0';
1637 cp++)
1638 continue;
1639 termc = *cp;
1640 newStr = var_Error;
1641 }
1642 }
1643 }
1644 DEBUGF(VAR, ("Result is \"%s\"\n", newStr));
1645
1646 if (*freePtr) {
1652 free (str);
1647 free(str);
1653 }
1654 str = newStr;
1655 if (str != var_Error) {
1656 *freePtr = TRUE;
1657 } else {
1658 *freePtr = FALSE;
1659 }
1660 if (termc == '\0') {

--- 60 unchanged lines hidden (view full) ---

1721 * Results:
1722 * The resulting string.
1723 *
1724 * Side Effects:
1725 * None. The old string must be freed by the caller
1726 *-----------------------------------------------------------------------
1727 */
1728char *
1648 }
1649 str = newStr;
1650 if (str != var_Error) {
1651 *freePtr = TRUE;
1652 } else {
1653 *freePtr = FALSE;
1654 }
1655 if (termc == '\0') {

--- 60 unchanged lines hidden (view full) ---

1716 * Results:
1717 * The resulting string.
1718 *
1719 * Side Effects:
1720 * None. The old string must be freed by the caller
1721 *-----------------------------------------------------------------------
1722 */
1723char *
1729Var_Subst (char *var, char *str, GNode *ctxt, Boolean undefErr)
1724Var_Subst(char *var, char *str, GNode *ctxt, Boolean undefErr)
1730{
1731 Buffer buf; /* Buffer for forming things */
1732 char *val; /* Value to substitute for a variable */
1733 int length; /* Length of the variable invocation */
1734 Boolean doFree; /* Set true if val should be freed */
1735 static Boolean errorReported; /* Set true if an error has already
1736 * been reported to prevent a plethora
1737 * of messages when recursing */
1738
1725{
1726 Buffer buf; /* Buffer for forming things */
1727 char *val; /* Value to substitute for a variable */
1728 int length; /* Length of the variable invocation */
1729 Boolean doFree; /* Set true if val should be freed */
1730 static Boolean errorReported; /* Set true if an error has already
1731 * been reported to prevent a plethora
1732 * of messages when recursing */
1733
1739 buf = Buf_Init (MAKE_BSIZE);
1734 buf = Buf_Init(MAKE_BSIZE);
1740 errorReported = FALSE;
1741
1742 while (*str) {
1743 if (var == NULL && (*str == '$') && (str[1] == '$')) {
1744 /*
1745 * A dollar sign may be escaped either with another dollar sign.
1746 * In such a case, we skip over the escape character and store the
1747 * dollar sign into the buffer directly.

--- 12 unchanged lines hidden (view full) ---

1760 continue;
1761 Buf_AddBytes(buf, str - cp, (Byte *)cp);
1762 } else {
1763 if (var != NULL) {
1764 int expand;
1765 for (;;) {
1766 if (str[1] != '(' && str[1] != '{') {
1767 if (str[1] != *var || var[1] != '\0') {
1735 errorReported = FALSE;
1736
1737 while (*str) {
1738 if (var == NULL && (*str == '$') && (str[1] == '$')) {
1739 /*
1740 * A dollar sign may be escaped either with another dollar sign.
1741 * In such a case, we skip over the escape character and store the
1742 * dollar sign into the buffer directly.

--- 12 unchanged lines hidden (view full) ---

1755 continue;
1756 Buf_AddBytes(buf, str - cp, (Byte *)cp);
1757 } else {
1758 if (var != NULL) {
1759 int expand;
1760 for (;;) {
1761 if (str[1] != '(' && str[1] != '{') {
1762 if (str[1] != *var || var[1] != '\0') {
1768 Buf_AddBytes(buf, 2, (Byte *) str);
1763 Buf_AddBytes(buf, 2, (Byte *)str);
1769 str += 2;
1770 expand = FALSE;
1771 }
1772 else
1773 expand = TRUE;
1774 break;
1775 }
1776 else {

--- 7 unchanged lines hidden (view full) ---

1784 if (*p == '$')
1785 break;
1786 /*
1787 * A variable inside the variable. We cannot expand
1788 * the external variable yet, so we try again with
1789 * the nested one
1790 */
1791 if (*p == '$') {
1764 str += 2;
1765 expand = FALSE;
1766 }
1767 else
1768 expand = TRUE;
1769 break;
1770 }
1771 else {

--- 7 unchanged lines hidden (view full) ---

1779 if (*p == '$')
1780 break;
1781 /*
1782 * A variable inside the variable. We cannot expand
1783 * the external variable yet, so we try again with
1784 * the nested one
1785 */
1786 if (*p == '$') {
1792 Buf_AddBytes(buf, p - str, (Byte *) str);
1787 Buf_AddBytes(buf, p - str, (Byte *)str);
1793 str = p;
1794 continue;
1795 }
1796
1797 if (strncmp(var, str + 2, p - str - 2) != 0 ||
1798 var[p - str - 2] != '\0') {
1799 /*
1800 * Not the variable we want to expand, scan
1801 * until the next variable
1802 */
1803 for (;*p != '$' && *p != '\0'; p++)
1804 continue;
1788 str = p;
1789 continue;
1790 }
1791
1792 if (strncmp(var, str + 2, p - str - 2) != 0 ||
1793 var[p - str - 2] != '\0') {
1794 /*
1795 * Not the variable we want to expand, scan
1796 * until the next variable
1797 */
1798 for (;*p != '$' && *p != '\0'; p++)
1799 continue;
1805 Buf_AddBytes(buf, p - str, (Byte *) str);
1800 Buf_AddBytes(buf, p - str, (Byte *)str);
1806 str = p;
1807 expand = FALSE;
1808 }
1809 else
1810 expand = TRUE;
1811 break;
1812 }
1813 }
1814 if (!expand)
1815 continue;
1816 }
1817
1801 str = p;
1802 expand = FALSE;
1803 }
1804 else
1805 expand = TRUE;
1806 break;
1807 }
1808 }
1809 if (!expand)
1810 continue;
1811 }
1812
1818 val = Var_Parse (str, ctxt, undefErr, &length, &doFree);
1813 val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
1819
1820 /*
1821 * When we come down here, val should either point to the
1822 * value of this variable, suitably modified, or be NULL.
1823 * Length should be the total length of the potential
1824 * variable invocation (from $ to end character...)
1825 */
1826 if (val == var_Error || val == varNoError) {

--- 7 unchanged lines hidden (view full) ---

1834 str += length;
1835 } else if (undefErr) {
1836 /*
1837 * If variable is undefined, complain and skip the
1838 * variable. The complaint will stop us from doing anything
1839 * when the file is parsed.
1840 */
1841 if (!errorReported) {
1814
1815 /*
1816 * When we come down here, val should either point to the
1817 * value of this variable, suitably modified, or be NULL.
1818 * Length should be the total length of the potential
1819 * variable invocation (from $ to end character...)
1820 */
1821 if (val == var_Error || val == varNoError) {

--- 7 unchanged lines hidden (view full) ---

1829 str += length;
1830 } else if (undefErr) {
1831 /*
1832 * If variable is undefined, complain and skip the
1833 * variable. The complaint will stop us from doing anything
1834 * when the file is parsed.
1835 */
1836 if (!errorReported) {
1842 Parse_Error (PARSE_FATAL,
1837 Parse_Error(PARSE_FATAL,
1843 "Undefined variable \"%.*s\"",length,str);
1844 }
1845 str += length;
1846 errorReported = TRUE;
1847 } else {
1848 Buf_AddByte (buf, (Byte)*str);
1849 str += 1;
1850 }
1851 } else {
1852 /*
1853 * We've now got a variable structure to store in. But first,
1854 * advance the string pointer.
1855 */
1856 str += length;
1857
1858 /*
1859 * Copy all the characters from the variable value straight
1860 * into the new string.
1861 */
1838 "Undefined variable \"%.*s\"",length,str);
1839 }
1840 str += length;
1841 errorReported = TRUE;
1842 } else {
1843 Buf_AddByte (buf, (Byte)*str);
1844 str += 1;
1845 }
1846 } else {
1847 /*
1848 * We've now got a variable structure to store in. But first,
1849 * advance the string pointer.
1850 */
1851 str += length;
1852
1853 /*
1854 * Copy all the characters from the variable value straight
1855 * into the new string.
1856 */
1862 Buf_AddBytes (buf, strlen (val), (Byte *)val);
1857 Buf_AddBytes(buf, strlen(val), (Byte *)val);
1863 if (doFree) {
1858 if (doFree) {
1864 free (val);
1859 free(val);
1865 }
1866 }
1867 }
1868 }
1869
1860 }
1861 }
1862 }
1863 }
1864
1870 Buf_AddByte (buf, '\0');
1871 str = (char *)Buf_GetAll (buf, (int *)NULL);
1872 Buf_Destroy (buf, FALSE);
1865 Buf_AddByte(buf, '\0');
1866 str = (char *)Buf_GetAll(buf, (int *)NULL);
1867 Buf_Destroy(buf, FALSE);
1873 return (str);
1874}
1875
1876/*-
1877 *-----------------------------------------------------------------------
1878 * Var_GetTail --
1879 * Return the tail from each of a list of words. Used to set the
1880 * System V local variables.

--- 4 unchanged lines hidden (view full) ---

1885 * Side Effects:
1886 * None.
1887 *
1888 *-----------------------------------------------------------------------
1889 */
1890char *
1891Var_GetTail(char *file)
1892{
1868 return (str);
1869}
1870
1871/*-
1872 *-----------------------------------------------------------------------
1873 * Var_GetTail --
1874 * Return the tail from each of a list of words. Used to set the
1875 * System V local variables.

--- 4 unchanged lines hidden (view full) ---

1880 * Side Effects:
1881 * None.
1882 *
1883 *-----------------------------------------------------------------------
1884 */
1885char *
1886Var_GetTail(char *file)
1887{
1893 return(VarModify(file, VarTail, (void *)0));
1888
1889 return (VarModify(file, VarTail, (void *)0));
1894}
1895
1896/*-
1897 *-----------------------------------------------------------------------
1898 * Var_GetHead --
1899 * Find the leading components of a (list of) filename(s).
1900 * XXX: VarHead does not replace foo by ., as (sun) System V make
1901 * does.

--- 4 unchanged lines hidden (view full) ---

1906 * Side Effects:
1907 * None.
1908 *
1909 *-----------------------------------------------------------------------
1910 */
1911char *
1912Var_GetHead(char *file)
1913{
1890}
1891
1892/*-
1893 *-----------------------------------------------------------------------
1894 * Var_GetHead --
1895 * Find the leading components of a (list of) filename(s).
1896 * XXX: VarHead does not replace foo by ., as (sun) System V make
1897 * does.

--- 4 unchanged lines hidden (view full) ---

1902 * Side Effects:
1903 * None.
1904 *
1905 *-----------------------------------------------------------------------
1906 */
1907char *
1908Var_GetHead(char *file)
1909{
1914 return(VarModify(file, VarHead, (void *)0));
1910
1911 return (VarModify(file, VarHead, (void *)0));
1915}
1916
1917/*-
1918 *-----------------------------------------------------------------------
1919 * Var_Init --
1920 * Initialize the module
1921 *
1922 * Results:
1923 * None
1924 *
1925 * Side Effects:
1926 * The VAR_CMD and VAR_GLOBAL contexts are created
1927 *-----------------------------------------------------------------------
1928 */
1929void
1912}
1913
1914/*-
1915 *-----------------------------------------------------------------------
1916 * Var_Init --
1917 * Initialize the module
1918 *
1919 * Results:
1920 * None
1921 *
1922 * Side Effects:
1923 * The VAR_CMD and VAR_GLOBAL contexts are created
1924 *-----------------------------------------------------------------------
1925 */
1926void
1930Var_Init (void)
1927Var_Init(void)
1931{
1928{
1932 VAR_GLOBAL = Targ_NewGN ("Global");
1933 VAR_CMD = Targ_NewGN ("Command");
1929
1930 VAR_GLOBAL = Targ_NewGN("Global");
1931 VAR_CMD = Targ_NewGN("Command");
1934 allVars = Lst_Init(FALSE);
1935
1936}
1937
1932 allVars = Lst_Init(FALSE);
1933
1934}
1935
1938
1939void
1936void
1940Var_End (void)
1937Var_End(void)
1941{
1938{
1939
1942 Lst_Destroy(allVars, VarDelete);
1943}
1944
1945
1946/****************** PRINT DEBUGGING INFO *****************/
1947static int
1940 Lst_Destroy(allVars, VarDelete);
1941}
1942
1943
1944/****************** PRINT DEBUGGING INFO *****************/
1945static int
1948VarPrintVar (void *vp, void *dummy __unused)
1946VarPrintVar(void *vp, void *dummy __unused)
1949{
1950 Var *v = (Var *) vp;
1947{
1948 Var *v = (Var *) vp;
1951 printf ("%-16s = %s\n", v->name, (char *) Buf_GetAll(v->val, (int *)NULL));
1949
1950 printf("%-16s = %s\n", v->name, (char *)Buf_GetAll(v->val, (int *)NULL));
1952 return (0);
1953}
1954
1955/*-
1956 *-----------------------------------------------------------------------
1957 * Var_Dump --
1958 * print all variables in a context
1959 *-----------------------------------------------------------------------
1960 */
1961void
1951 return (0);
1952}
1953
1954/*-
1955 *-----------------------------------------------------------------------
1956 * Var_Dump --
1957 * print all variables in a context
1958 *-----------------------------------------------------------------------
1959 */
1960void
1962Var_Dump (GNode *ctxt)
1961Var_Dump(GNode *ctxt)
1963{
1962{
1964 Lst_ForEach (ctxt->context, VarPrintVar, (void *) 0);
1963
1964 Lst_ForEach (ctxt->context, VarPrintVar, (void *)0);
1965}
1965}