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.
This commit is contained in:
mycroft 2000-06-01 04:16:39 +00:00
parent 7067d99bb7
commit ea218bb6e9
3 changed files with 29 additions and 81 deletions

View File

@ -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 <sys/cdefs.h>
#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);

View File

@ -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

View File

@ -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 <sys/cdefs.h>
#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");
}