summaryrefslogtreecommitdiff
path: root/usr.bin/make
diff options
context:
space:
mode:
authordsl <dsl@NetBSD.org>2008-11-29 17:50:11 +0000
committerdsl <dsl@NetBSD.org>2008-11-29 17:50:11 +0000
commit6cb9ef7eefd4ee230d54d20233c5a2ec08cec906 (patch)
tree88fcdac4d1307a94e55be7be6140130dd4ec842e /usr.bin/make
parent094b7fe7c7ef2ae9b13041b4cb790760e3e61bcb (diff)
Split For_Eval() into two functions.
For_Eval() is now only called for the first line of a .for. For_Accum() is called for the subsequent lines. Stops any problems with forLevel being left invalid after an error. Use a return value of -1 from For_Eval() to mean 'skip input line' to stop a .for line with a syntax error being reparsed by make.
Diffstat (limited to 'usr.bin/make')
-rw-r--r--usr.bin/make/for.c223
-rw-r--r--usr.bin/make/nonints.h3
-rw-r--r--usr.bin/make/parse.c20
3 files changed, 127 insertions, 119 deletions
diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c
index 3112a6247bf..4942156bb48 100644
--- a/usr.bin/make/for.c
+++ b/usr.bin/make/for.c
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.31 2008/11/22 17:34:56 dsl Exp $ */
+/* $NetBSD: for.c,v 1.32 2008/11/29 17:50:11 dsl Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -30,14 +30,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: for.c,v 1.31 2008/11/22 17:34:56 dsl Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.32 2008/11/29 17:50:11 dsl 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.31 2008/11/22 17:34:56 dsl Exp $");
+__RCSID("$NetBSD: for.c,v 1.32 2008/11/29 17:50:11 dsl Exp $");
#endif
#endif /* not lint */
#endif
@@ -147,119 +147,124 @@ int
For_Eval(char *line)
{
char *ptr = line, *sub, *in, *wrd;
- int level; /* Level at which to report errors. */
-
- level = PARSE_FATAL;
-
-
- if (forLevel == 0) {
- Buffer buf;
- int varlen;
- static const char instr[] = "in";
+ Buffer buf;
+ int varlen;
+ static const char instr[] = "in";
+
+ forLevel = 0;
+ for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
+ continue;
+ /*
+ * If we are not in a for loop quickly determine if the statement is
+ * a for.
+ */
+ if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
+ !isspace((unsigned char) ptr[3])) {
+ if (ptr[0] == 'e' && strncmp(ptr+1, "ndfor", 5) == 0) {
+ Parse_Error(PARSE_FATAL, "for-less endfor");
+ return -1;
+ }
+ return 0;
+ }
+ ptr += 3;
+
+ /*
+ * we found a for loop, and now we are going to parse it.
+ */
+ while (*ptr && isspace((unsigned char) *ptr))
+ ptr++;
+
+ /*
+ * Find the "in".
+ */
+ 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(PARSE_FATAL, "missing `in' in for");
+ return -1;
+ }
- for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
- continue;
- /*
- * If we are not in a for loop quickly determine if the statement is
- * a for.
- */
- if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
- !isspace((unsigned char) ptr[3]))
- return FALSE;
- ptr += 3;
+ /*
+ * Grab the variables.
+ */
+ accumFor.vars = NULL;
- /*
- * we found a for loop, and now we are going to parse it.
- */
+ while (ptr < in) {
+ wrd = ptr;
+ while (*ptr && !isspace((unsigned char) *ptr))
+ ptr++;
+ ForAddVar(wrd, ptr - wrd);
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
+ }
- /*
- * Find the "in".
- */
- 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;
- }
-
- /*
- * Grab the variables.
- */
- 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;
- }
+ if (accumFor.nvars == 0) {
+ Parse_Error(PARSE_FATAL, "no iteration variables in for");
+ return -1;
+ }
- /* At this point we should be pointing right at the "in" */
- /*
- * compensate for hp/ux's brain damaged assert macro that
- * does not handle double quotes nicely.
- */
- assert(!memcmp(ptr, instr, 2));
- ptr += 2;
+ /* At this point we should be pointing right at the "in" */
+ /*
+ * compensate for hp/ux's brain damaged assert macro that
+ * does not handle double quotes nicely.
+ */
+ assert(!memcmp(ptr, instr, 2));
+ ptr += 2;
- while (*ptr && isspace((unsigned char) *ptr))
- ptr++;
+ while (*ptr && isspace((unsigned char) *ptr))
+ ptr++;
- /*
- * Make a list with the remaining words
- */
- accumFor.lst = Lst_Init(FALSE);
- buf = Buf_Init(0);
- sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
+ /*
+ * Make a list with the remaining words
+ */
+ accumFor.lst = Lst_Init(FALSE);
+ buf = Buf_Init(0);
+ sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
#define ADDWORD() do { \
- Buf_AddBytes(buf, ptr - wrd, (Byte *)wrd); \
- Buf_AddByte(buf, (Byte)'\0'); \
- Lst_AtFront(accumFor.lst, Buf_GetAll(buf, &varlen)); \
- Buf_Destroy(buf, FALSE); \
- } while (0)
+ Buf_AddBytes(buf, ptr - wrd, (Byte *)wrd); \
+ Buf_AddByte(buf, (Byte)'\0'); \
+ Lst_AtFront(accumFor.lst, Buf_GetAll(buf, &varlen)); \
+ Buf_Destroy(buf, FALSE); \
+} while (0)
- for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++)
- continue;
+ for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++)
+ continue;
- for (wrd = ptr; *ptr; ptr++)
- if (isspace((unsigned char) *ptr)) {
- ADDWORD();
- buf = Buf_Init(0);
- while (*ptr && isspace((unsigned char) *ptr))
- ptr++;
- wrd = ptr--;
- }
- if (DEBUG(FOR)) {
- int i;
- for (i = 0; i < accumFor.nvars; i++) {
- (void)fprintf(debug_file, "For: variable %s\n", accumFor.vars[i]);
- }
- (void)fprintf(debug_file, "For: list %s\n", sub);
- }
- if (ptr - wrd > 0)
+ for (wrd = ptr; *ptr; ptr++)
+ if (isspace((unsigned char) *ptr)) {
ADDWORD();
- else
- Buf_Destroy(buf, TRUE);
- free(sub);
-
- accumFor.buf = Buf_Init(0);
- forLevel++;
- return 1;
+ buf = Buf_Init(0);
+ while (*ptr && isspace((unsigned char) *ptr))
+ ptr++;
+ wrd = ptr--;
+ }
+ if (DEBUG(FOR)) {
+ int i;
+ for (i = 0; i < accumFor.nvars; i++) {
+ (void)fprintf(debug_file, "For: variable %s\n", accumFor.vars[i]);
+ }
+ (void)fprintf(debug_file, "For: list %s\n", sub);
}
+ if (ptr - wrd > 0)
+ ADDWORD();
+ else
+ Buf_Destroy(buf, TRUE);
+ free(sub);
+
+ accumFor.buf = Buf_Init(0);
+ forLevel = 1;
+ return 1;
+}
+
+int
+For_Accum(char *line)
+{
+ char *ptr = line;
if (*ptr == '.') {
@@ -270,10 +275,8 @@ For_Eval(char *line)
(isspace((unsigned char) ptr[6]) || !ptr[6])) {
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: end for %d\n", forLevel);
- if (--forLevel < 0) {
- Parse_Error(level, "for-less endfor");
+ if (--forLevel <= 0)
return 0;
- }
} else if (strncmp(ptr, "for", 3) == 0 &&
isspace((unsigned char) ptr[3])) {
forLevel++;
@@ -282,13 +285,9 @@ For_Eval(char *line)
}
}
- if (forLevel != 0 && accumFor.buf) {
- Buf_AddBytes(accumFor.buf, strlen(line), (Byte *)line);
- Buf_AddByte(accumFor.buf, (Byte)'\n');
- return 1;
- }
-
- return 0;
+ Buf_AddBytes(accumFor.buf, strlen(line), (Byte *)line);
+ Buf_AddByte(accumFor.buf, (Byte)'\n');
+ return 1;
}
diff --git a/usr.bin/make/nonints.h b/usr.bin/make/nonints.h
index bacb771bda2..8d4fd884e3f 100644
--- a/usr.bin/make/nonints.h
+++ b/usr.bin/make/nonints.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nonints.h,v 1.49 2008/10/06 22:09:21 joerg Exp $ */
+/* $NetBSD: nonints.h,v 1.50 2008/11/29 17:50:11 dsl Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -102,6 +102,7 @@ unsigned int Cond_save_depth(void);
/* for.c */
int For_Eval(char *);
+int For_Accum(char *);
void For_Run(int);
/* main.c */
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c
index 61e1cf1a094..aaf6c1323ab 100644
--- a/usr.bin/make/parse.c
+++ b/usr.bin/make/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.150 2008/11/12 15:56:57 apb Exp $ */
+/* $NetBSD: parse.c,v 1.151 2008/11/29 17:50:11 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.150 2008/11/12 15:56:57 apb Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.151 2008/11/29 17:50:11 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: parse.c,v 1.150 2008/11/12 15:56:57 apb Exp $");
+__RCSID("$NetBSD: parse.c,v 1.151 2008/11/29 17:50:11 dsl Exp $");
#endif
#endif /* not lint */
#endif
@@ -2369,6 +2369,7 @@ ParseReadLine(void)
char *line; /* Result */
int lineLength; /* Length of result */
int lineno; /* Saved line # */
+ int rval;
for (;;) {
line = ParseGetLine(0, &lineLength);
@@ -2394,10 +2395,17 @@ ParseReadLine(void)
case COND_PARSE:
continue;
case COND_INVALID: /* Not a conditional line */
- if (!For_Eval(line))
+ /* Check for .for loops */
+ rval = For_Eval(line);
+ if (rval == 0)
+ /* Not a .for line */
break;
+ if (rval < 0)
+ /* Syntax error - error printed, ignore line */
+ continue;
+ /* Start of a .for loop */
lineno = curFile->lineno;
- /* Skip after the matching end */
+ /* Accumulate loop lines until matching .endfor */
do {
line = ParseGetLine(PARSE_RAW, &lineLength);
if (line == NULL) {
@@ -2405,7 +2413,7 @@ ParseReadLine(void)
"Unexpected end of file in for loop.\n");
break;
}
- } while (For_Eval(line));
+ } while (For_Accum(line));
/* Stash each iteration as a new 'input file' */
For_Run(lineno);
/* Read next line from for-loop buffer */