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.
This commit is contained in:
dsl 2008-11-29 17:50:11 +00:00
parent 094b7fe7c7
commit 6cb9ef7eef
3 changed files with 124 additions and 116 deletions

View File

@ -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,16 +147,11 @@ 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";
forLevel = 0;
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
continue;
/*
@ -164,8 +159,13 @@ For_Eval(char *line)
* a for.
*/
if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
!isspace((unsigned char) ptr[3]))
return FALSE;
!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;
/*
@ -184,8 +184,8 @@ For_Eval(char *line)
break;
}
if (*in == '\0') {
Parse_Error(level, "missing `in' in for");
return 0;
Parse_Error(PARSE_FATAL, "missing `in' in for");
return -1;
}
/*
@ -203,8 +203,8 @@ For_Eval(char *line)
}
if (accumFor.nvars == 0) {
Parse_Error(level, "no iteration variables in for");
return 0;
Parse_Error(PARSE_FATAL, "no iteration variables in for");
return -1;
}
/* At this point we should be pointing right at the "in" */
@ -230,7 +230,7 @@ For_Eval(char *line)
Buf_AddByte(buf, (Byte)'\0'); \
Lst_AtFront(accumFor.lst, Buf_GetAll(buf, &varlen)); \
Buf_Destroy(buf, FALSE); \
} while (0)
} while (0)
for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++)
continue;
@ -257,9 +257,14 @@ For_Eval(char *line)
free(sub);
accumFor.buf = Buf_Init(0);
forLevel++;
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;
}

View File

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

View File

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