Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make PR/9899: David A. Holland: multi-variable .for ...
details: https://anonhg.NetBSD.org/src/rev/adcf38ac9e36
branches: trunk
changeset: 485019:adcf38ac9e36
user: christos <christos%NetBSD.org@localhost>
date: Sun Apr 16 22:08:06 2000 +0000
description:
PR/9899: David A. Holland: multi-variable .for constructs in make
diffstat:
usr.bin/make/for.c | 236 ++++++++++++++++++++++++++++++++++-----------------
usr.bin/make/make.1 | 18 ++-
2 files changed, 170 insertions(+), 84 deletions(-)
diffs (truncated from 402 to 300 lines):
diff -r d7691ce7a51b -r adcf38ac9e36 usr.bin/make/for.c
--- a/usr.bin/make/for.c Sun Apr 16 22:07:24 2000 +0000
+++ b/usr.bin/make/for.c Sun Apr 16 22:08:06 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.6 1997/09/28 03:31:03 lukem Exp $ */
+/* $NetBSD: for.c,v 1.7 2000/04/16 22:08:06 christos 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.6 1997/09/28 03:31:03 lukem Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.7 2000/04/16 22:08:06 christos 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.6 1997/09/28 03:31:03 lukem Exp $");
+__RCSID("$NetBSD: for.c,v 1.7 2000/04/16 22:08:06 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -57,6 +57,7 @@
*/
#include <ctype.h>
+#include <assert.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
@@ -74,27 +75,59 @@
* and the .endfor statements, accumulating all the statements between
* the initial .for loop and the matching .endfor;
* then we evaluate the for loop for each variable in the varlist.
+ *
+ * Note that any nested fors are just passed through; they get handled
+ * recursively in For_Eval when we're expanding the enclosing for in
+ * For_Run.
*/
static int forLevel = 0; /* Nesting level */
-static char *forVar; /* Iteration variable */
-static Buffer forBuf; /* Commands in loop */
-static Lst forLst; /* List of items */
/*
* State of a for loop.
*/
typedef struct _For {
- Buffer buf; /* Unexpanded buffer */
- char* var; /* Index name */
- Lst lst; /* List of variables */
+ Buffer buf; /* Body of loop */
+ char **vars; /* Iteration variables */
+ int nvars; /* # of iteration vars */
+ Lst lst; /* List of items */
} For;
-static int ForExec __P((ClientData, ClientData));
+static For accumFor; /* Loop being accumulated */
+static void ForAddVar __P((const char *, size_t));
+
+/*-
+ *-----------------------------------------------------------------------
+ * ForAddVar --
+ * Add an iteration variable to the currently accumulating for.
+ *
+ * Results: none
+ * Side effects: no additional side effects.
+ *-----------------------------------------------------------------------
+ */
+static void
+ForAddVar(data, len)
+ const char *data;
+ size_t len;
+{
+ Buffer buf;
+ size_t varlen;
+
+ buf = Buf_Init(0);
+ Buf_AddBytes(buf, len, (Byte *) data);
+
+ accumFor.nvars++;
+ accumFor.vars = erealloc(accumFor.vars, accumFor.nvars*sizeof(char *));
+
+ accumFor.vars[accumFor.nvars-1] = (char *) Buf_GetAll(buf, &varlen);
+
+ Buf_Destroy(buf, FALSE);
+}
+
/*-
*-----------------------------------------------------------------------
* For_Eval --
@@ -116,7 +149,7 @@
For_Eval (line)
char *line; /* Line to parse */
{
- char *ptr = line, *sub, *wrd;
+ char *ptr = line, *sub, *in, *wrd;
int level; /* Level at which to report errors. */
level = PARSE_FATAL;
@@ -144,33 +177,41 @@
ptr++;
/*
- * Grab the variable
+ * Find the "in".
*/
- buf = Buf_Init(0);
- for (wrd = ptr; *ptr && !isspace((unsigned char) *ptr); ptr++)
- continue;
- Buf_AddBytes(buf, ptr - wrd, (Byte *) wrd);
-
- forVar = (char *) Buf_GetAll(buf, &varlen);
- if (varlen == 0) {
- Parse_Error (level, "missing variable in for");
+ for (in = ptr; *in; in++) {
+ if (isspace((unsigned char) in[0]) && in[1]== 'i' &&
+ in[2] == 'n' &&
+ (in[3] == '\0' || isspace((unsigned char) in[3])))
+ break;
+ }
+ if (*in == '\0') {
+ Parse_Error(level, "missing `in' in for");
return 0;
}
- Buf_Destroy(buf, FALSE);
-
- while (*ptr && isspace((unsigned char) *ptr))
- ptr++;
/*
- * Grab the `in'
+ * Grab the variables.
*/
- if (ptr[0] != 'i' || ptr[1] != 'n' ||
- !isspace((unsigned char) ptr[2])) {
- Parse_Error (level, "missing `in' in for");
- printf("%s\n", ptr);
+ accumFor.vars = NULL;
+
+ while (ptr < in) {
+ wrd = ptr;
+ while (*ptr && !isspace((unsigned char) *ptr))
+ ptr++;
+ ForAddVar(wrd, ptr - wrd);
+ while (*ptr && isspace((unsigned char) *ptr))
+ ptr++;
+ }
+
+ if (accumFor.nvars == 0) {
+ Parse_Error(level, "no iteration variables in for");
return 0;
}
- ptr += 3;
+
+ /* At this point we should be pointing right at the "in" */
+ assert(!memcmp(ptr, "in", 2));
+ ptr += 2;
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
@@ -178,14 +219,14 @@
/*
* Make a list with the remaining words
*/
- forLst = Lst_Init(FALSE);
+ accumFor.lst = Lst_Init(FALSE);
buf = Buf_Init(0);
sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
#define ADDWORD() \
Buf_AddBytes(buf, ptr - wrd, (Byte *) wrd), \
Buf_AddByte(buf, (Byte) '\0'), \
- Lst_AtFront(forLst, (ClientData) Buf_GetAll(buf, &varlen)), \
+ Lst_AtFront(accumFor.lst, (ClientData) Buf_GetAll(buf, &varlen)), \
Buf_Destroy(buf, FALSE)
for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++)
@@ -199,15 +240,20 @@
ptr++;
wrd = ptr--;
}
- if (DEBUG(FOR))
- (void) fprintf(stderr, "For: Iterator %s List %s\n", forVar, sub);
+ if (DEBUG(FOR)) {
+ int i;
+ for (i = 0; i < accumFor.nvars; i++) {
+ (void) fprintf(stderr, "For: variable %s\n", accumFor.vars[i]);
+ }
+ (void) fprintf(stderr, "For: list %s\n", sub);
+ }
if (ptr - wrd > 0)
ADDWORD();
else
Buf_Destroy(buf, TRUE);
free((Address) sub);
- forBuf = Buf_Init(0);
+ accumFor.buf = Buf_Init(0);
forLevel++;
return 1;
}
@@ -234,8 +280,8 @@
}
if (forLevel != 0) {
- Buf_AddBytes(forBuf, strlen(line), (Byte *) line);
- Buf_AddByte(forBuf, (Byte) '\n');
+ Buf_AddBytes(accumFor.buf, strlen(line), (Byte *) line);
+ Buf_AddByte(accumFor.buf, (Byte) '\n');
return 1;
}
else {
@@ -243,42 +289,11 @@
}
}
-/*-
- *-----------------------------------------------------------------------
- * ForExec --
- * Expand the for loop for this index and push it in the Makefile
- *
- * Results:
- * None.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-static int
-ForExec(namep, argp)
- ClientData namep;
- ClientData argp;
-{
- char *name = (char *) namep;
- For *arg = (For *) argp;
- int len;
- Var_Set(arg->var, name, VAR_GLOBAL);
- if (DEBUG(FOR))
- (void) fprintf(stderr, "--- %s = %s\n", arg->var, name);
- Parse_FromString(Var_Subst(arg->var, (char *) Buf_GetAll(arg->buf, &len),
- VAR_GLOBAL, FALSE));
- Var_Delete(arg->var, VAR_GLOBAL);
-
- return 0;
-}
-
/*-
*-----------------------------------------------------------------------
* For_Run --
- * Run the for loop, immitating the actions of an include file
+ * Run the for loop, imitating the actions of an include file
*
* Results:
* None.
@@ -292,19 +307,84 @@
For_Run()
{
For arg;
+ LstNode ln;
+ char **values;
+ int i, done = 0, len;
+ char *guy, *orig_guy, *old_guy;
- if (forVar == NULL || forBuf == NULL || forLst == NULL)
+ if (accumFor.buf == NULL || accumFor.vars == NULL || accumFor.lst == NULL)
+ return;
+ arg = accumFor;
+ accumFor.buf = NULL;
+ accumFor.vars = NULL;
+ accumFor.nvars = 0;
+ accumFor.lst = NULL;
+
+ if (Lst_Open(arg.lst) != SUCCESS)
return;
- arg.var = forVar;
- arg.buf = forBuf;
- arg.lst = forLst;
- forVar = NULL;
- forBuf = NULL;
- forLst = NULL;
+
+ values = emalloc(arg.nvars * sizeof(char *));
+
+ while (!done) {
+ /*
+ * due to the dumb way this is set up, this loop must run
+ * backwards.
Home |
Main Index |
Thread Index |
Old Index