diff options
| author | dsl <dsl@NetBSD.org> | 2008-11-29 17:50:11 +0000 |
|---|---|---|
| committer | dsl <dsl@NetBSD.org> | 2008-11-29 17:50:11 +0000 |
| commit | 6cb9ef7eefd4ee230d54d20233c5a2ec08cec906 (patch) | |
| tree | 88fcdac4d1307a94e55be7be6140130dd4ec842e /usr.bin/make | |
| parent | 094b7fe7c7ef2ae9b13041b4cb790760e3e61bcb (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.c | 223 | ||||
| -rw-r--r-- | usr.bin/make/nonints.h | 3 | ||||
| -rw-r--r-- | usr.bin/make/parse.c | 20 |
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 */ |
