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