From ea218bb6e9193993c9a9d7da6cb26bbaffe7e813 Mon Sep 17 00:00:00 2001 From: mycroft Date: Thu, 1 Jun 2000 04:16:39 +0000 Subject: [PATCH] Create a `for' context, and substitute iteration variable from it using the normal Var_Parse() path. This allows :R, etc. to work on iteration variables. --- usr.bin/make/for.c | 23 ++++++------- usr.bin/make/make.h | 3 +- usr.bin/make/var.c | 84 +++++++++------------------------------------ 3 files changed, 29 insertions(+), 81 deletions(-) diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c index 8ac9ee5d2e8c..f7f2b2338632 100644 --- a/usr.bin/make/for.c +++ b/usr.bin/make/for.c @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.8 2000/04/18 03:46:41 simonb Exp $ */ +/* $NetBSD: for.c,v 1.9 2000/06/01 04:16:39 mycroft Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -34,14 +34,14 @@ */ #ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: for.c,v 1.8 2000/04/18 03:46:41 simonb Exp $"; +static char rcsid[] = "$NetBSD: for.c,v 1.9 2000/06/01 04:16:39 mycroft Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: for.c,v 1.8 2000/04/18 03:46:41 simonb Exp $"); +__RCSID("$NetBSD: for.c,v 1.9 2000/06/01 04:16:39 mycroft Exp $"); #endif #endif /* not lint */ #endif @@ -310,7 +310,8 @@ For_Run() LstNode ln; char **values; int i, done = 0, len; - char *guy, *orig_guy, *old_guy; + char *guy; + Boolean oldOldVars = oldVars; if (accumFor.buf == NULL || accumFor.vars == NULL || accumFor.lst == NULL) return; @@ -324,6 +325,7 @@ For_Run() return; values = emalloc(arg.nvars * sizeof(char *)); + oldVars = FALSE; while (!done) { /* @@ -347,7 +349,7 @@ For_Run() break; for (i = 0; i < arg.nvars; i++) { - Var_Set(arg.vars[i], values[i], VAR_GLOBAL); + Var_Set(arg.vars[i], values[i], VAR_FOR); if (DEBUG(FOR)) (void) fprintf(stderr, "--- %s = %s\n", arg.vars[i], values[i]); @@ -363,19 +365,14 @@ For_Run() */ guy = (char *) Buf_GetAll(arg.buf, &len); - orig_guy = guy; - for (i = 0; i < arg.nvars; i++) { - old_guy = guy; - guy = Var_Subst(arg.vars[i], guy, VAR_GLOBAL, FALSE); - if (old_guy != orig_guy) - free(old_guy); - } + guy = Var_Subst(NULL, guy, VAR_FOR, FALSE); Parse_FromString(guy); for (i = 0; i < arg.nvars; i++) - Var_Delete(arg.vars[i], VAR_GLOBAL); + Var_Delete(arg.vars[i], VAR_FOR); } + oldVars = oldOldVars; free(values); Lst_Close(arg.lst); diff --git a/usr.bin/make/make.h b/usr.bin/make/make.h index 35f5d37d7271..00e5731742de 100644 --- a/usr.bin/make/make.h +++ b/usr.bin/make/make.h @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.25 2000/05/04 18:27:53 drochner Exp $ */ +/* $NetBSD: make.h,v 1.26 2000/06/01 04:16:39 mycroft Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -342,6 +342,7 @@ extern GNode *DEFAULT; /* .DEFAULT rule */ extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g * in the Makefile itself */ extern GNode *VAR_CMD; /* Variables defined on the command line */ +extern GNode *VAR_FOR; /* Iteration variables */ extern char var_Error[]; /* Value returned by Var_Parse when an error * is encountered. It actually points to * an empty string, so naive callers needn't diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index 6710a843336d..fe394b38d0d3 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.45 2000/06/01 02:29:21 sjg Exp $ */ +/* $NetBSD: var.c,v 1.46 2000/06/01 04:16:39 mycroft Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -39,14 +39,14 @@ */ #ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: var.c,v 1.45 2000/06/01 02:29:21 sjg Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.46 2000/06/01 04:16:39 mycroft Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: var.c,v 1.45 2000/06/01 02:29:21 sjg Exp $"); +__RCSID("$NetBSD: var.c,v 1.46 2000/06/01 04:16:39 mycroft Exp $"); #endif #endif /* not lint */ #endif @@ -134,6 +134,7 @@ static char varNoError[] = ""; */ GNode *VAR_GLOBAL; /* variables from the makefile */ GNode *VAR_CMD; /* variables defined on the command-line */ +GNode *VAR_FOR; /* iteration variables */ #define FIND_CMD 0x1 /* look in VAR_CMD when searching */ #define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */ @@ -1582,11 +1583,12 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr) name[0] = str[1]; name[1] = '\0'; - v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); + v = VarFind (name, ctxt, + ctxt == VAR_FOR ? 0 : FIND_ENV | FIND_GLOBAL | FIND_CMD); if (v == (Var *)NIL) { *lengthPtr = 2; - if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { + if ((ctxt == VAR_FOR) || (ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { /* * If substituting a local variable in a non-local context, * assume it's for dynamic source stuff. We have to handle @@ -1665,8 +1667,10 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr) str = Buf_GetAll(buf, (int *) NULL); vlen = strlen(str); - v = VarFind (str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); - if ((v == (Var *)NIL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) && + v = VarFind (str, ctxt, + ctxt == VAR_FOR ? 0 : FIND_ENV | FIND_GLOBAL | FIND_CMD); + if ((v == (Var *)NIL) && + (ctxt != VAR_FOR) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) && (vlen == 2) && (str[1] == 'F' || str[1] == 'D')) { /* @@ -1723,7 +1727,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr) if (((vlen == 1) || (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) && - ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) + ((ctxt == VAR_FOR) || (ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) { /* * If substituting a local variable in a non-local context, @@ -1744,7 +1748,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr) } } else if ((vlen > 2) && (*str == '.') && isupper((unsigned char) str[1]) && - ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) + ((ctxt == VAR_FOR) || (ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) { int len; @@ -2554,8 +2558,8 @@ cleanup: *----------------------------------------------------------------------- */ char * -Var_Subst (var, str, ctxt, undefErr) - char *var; /* Named variable || NULL for all */ +Var_Subst (junk, str, ctxt, undefErr) + char *junk; /* __DEAD__ */ char *str; /* the string in which to substitute */ GNode *ctxt; /* the context wherein to find variables */ Boolean undefErr; /* TRUE if undefineds are an error */ @@ -2572,7 +2576,7 @@ Var_Subst (var, str, ctxt, undefErr) errorReported = FALSE; while (*str) { - if (var == NULL && (*str == '$') && (str[1] == '$')) { + if (ctxt != VAR_FOR && (*str == '$') && (str[1] == '$')) { /* * A dollar sign may be escaped either with another dollar sign. * In such a case, we skip over the escape character and store the @@ -2592,61 +2596,6 @@ Var_Subst (var, str, ctxt, undefErr) continue; Buf_AddBytes(buf, str - cp, (Byte *)cp); } else { - if (var != NULL) { - int expand; - for (;;) { - if (str[1] != '(' && str[1] != '{') { - if (str[1] != *var || strlen(var) > 1) { - Buf_AddBytes(buf, 2, (Byte *) str); - str += 2; - expand = FALSE; - } - else - expand = TRUE; - break; - } - else { - char *p; - - /* - * Scan up to the end of the variable name. - */ - for (p = &str[2]; *p && - *p != ':' && *p != ')' && *p != '}'; p++) - if (*p == '$') - break; - /* - * A variable inside the variable. We cannot expand - * the external variable yet, so we try again with - * the nested one - */ - if (*p == '$') { - Buf_AddBytes(buf, p - str, (Byte *) str); - str = p; - continue; - } - - if (strncmp(var, str + 2, p - str - 2) != 0 || - var[p - str - 2] != '\0') { - /* - * Not the variable we want to expand, scan - * until the next variable - */ - for (;*p != '$' && *p != '\0'; p++) - continue; - Buf_AddBytes(buf, p - str, (Byte *) str); - str = p; - expand = FALSE; - } - else - expand = TRUE; - break; - } - } - if (!expand) - continue; - } - val = Var_Parse (str, ctxt, undefErr, &length, &doFree); /* @@ -2765,6 +2714,7 @@ Var_Init () { VAR_GLOBAL = Targ_NewGN ("Global"); VAR_CMD = Targ_NewGN ("Command"); + VAR_FOR = Targ_NewGN ("For"); }