diff options
author | harti <harti@FreeBSD.org> | 2004-07-20 07:42:06 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2004-07-20 07:42:06 +0000 |
commit | ee1888d8962780e7914e938802e838cd4ad5ef1f (patch) | |
tree | 46c63222fe2a3c5eb5a6550c60789b5b6f507421 | |
parent | da5b50a882531f96547526696b70bb1f967b00a0 (diff) | |
download | FreeBSD-src-ee1888d8962780e7914e938802e838cd4ad5ef1f.zip FreeBSD-src-ee1888d8962780e7914e938802e838cd4ad5ef1f.tar.gz |
Improve make's diagnostic of mistmatched .if-.endif. This patch is
slightly different from the patch in the PR. The problem is, that
make handles .if clauses inside false .if clauses simply by
counting them - it doesn't put them onto the conditional stack, nor even
parses them so we need an extra line number stack for these ifs.
PR: bin/61257
Submitted by: Mikhail Teterin <mi@aldan.algebra.com>
-rw-r--r-- | usr.bin/make/cond.c | 23 | ||||
-rw-r--r-- | usr.bin/make/make.h | 16 | ||||
-rw-r--r-- | usr.bin/make/parse.c | 18 |
3 files changed, 39 insertions, 18 deletions
diff --git a/usr.bin/make/cond.c b/usr.bin/make/cond.c index 6566766..194a057 100644 --- a/usr.bin/make/cond.c +++ b/usr.bin/make/cond.c @@ -133,8 +133,10 @@ static Token condPushBack=None; /* Single push-back token used in #define MAXIF 30 /* greatest depth of #if'ing */ static Boolean condStack[MAXIF]; /* Stack of conditionals's values */ +static int condLineno[MAXIF]; /* Line numbers of the opening .if */ static int condTop = MAXIF; /* Top-most conditional */ static int skipIfLevel=0; /* Depth of skipped conditionals */ +static int skipIfLineno[MAXIF]; /* Line numbers of skipped .ifs */ static Boolean skipLine = FALSE; /* Whether the parse module is skipping * lines */ @@ -1047,8 +1049,10 @@ Cond_Eval (char *line) Boolean isElse; Boolean value = FALSE; int level; /* Level at which to report errors. */ + int lineno; level = PARSE_FATAL; + lineno = curFile.lineno; for (line++; *line == ' ' || *line == '\t'; line++) { continue; @@ -1109,6 +1113,7 @@ Cond_Eval (char *line) return (COND_INVALID); } else if (skipIfLevel == 0) { value = !condStack[condTop]; + lineno = condLineno[condTop]; } else { return (COND_SKIP); } @@ -1130,6 +1135,7 @@ Cond_Eval (char *line) * undefined, for which there's an enclosing ifdef that * we're skipping... */ + skipIfLineno[skipIfLevel - 1] = lineno; return(COND_SKIP); } } else if (skipLine) { @@ -1137,6 +1143,7 @@ Cond_Eval (char *line) * Don't even try to evaluate a conditional that's not an else if * we're skipping things... */ + skipIfLineno[skipIfLevel] = lineno; skipIfLevel += 1; return(COND_SKIP); } @@ -1202,6 +1209,7 @@ Cond_Eval (char *line) return (COND_INVALID); } else { condStack[condTop] = value; + condLineno[condTop] = lineno; skipLine = !value; return (value ? COND_PARSE : COND_SKIP); } @@ -1223,9 +1231,20 @@ Cond_Eval (char *line) void Cond_End(void) { + int level; + if (condTop != MAXIF) { - Parse_Error(PARSE_FATAL, "%d open conditional%s", MAXIF-condTop, - MAXIF-condTop == 1 ? "" : "s"); + Parse_Error(PARSE_FATAL, "%d open conditional%s:", + MAXIF - condTop + skipIfLevel, + MAXIF - condTop + skipIfLevel== 1 ? "" : "s"); + + for (level = skipIfLevel; level > 0; level--) + Parse_Error(PARSE_FATAL, "\t%*sat line %d (skipped)", + MAXIF - condTop + level + 1, "", skipIfLineno[level - 1]); + for (level = condTop; level < MAXIF; level++) + Parse_Error(PARSE_FATAL, "\t%*sat line %d " + "(evaluated to %s)", MAXIF - level + skipIfLevel, "", + condLineno[level], condStack[level] ? "true" : "false"); } condTop = MAXIF; } diff --git a/usr.bin/make/make.h b/usr.bin/make/make.h index 74949ae..77205aa 100644 --- a/usr.bin/make/make.h +++ b/usr.bin/make/make.h @@ -141,6 +141,21 @@ typedef struct GNode { * but the Suff module) */ } GNode; + +/* + * Definitions for handling #include specifications + */ +typedef struct { + char *str; + char *ptr; +} PTR; +typedef struct IFile { + char *fname; /* name of previous file */ + int lineno; /* saved line number */ + FILE *F; /* the open stream */ + PTR *p; /* the char pointer */ +} IFile; + /* * The OP_ constants are used when parsing a dependency line as a way of * communicating to other parts of the program the way in which a target @@ -273,6 +288,7 @@ extern Lst create; /* The list of target names specified on the * make(...) statements */ extern Lst dirSearchPath; /* The list of directories to search when * looking for targets */ +extern IFile curFile; /* current makefile */ extern Lst parseIncPath; /* The list of directories to search when * looking for includes */ diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index 65fcf05..e8a9935 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -105,27 +105,13 @@ static Lst targets; /* targets we're working on */ static Lst targCmds; /* command lines for targets */ static Boolean inLine; /* true if currently in a dependency * line or its commands */ -typedef struct { - char *str; - char *ptr; -} PTR; - static int fatals = 0; static GNode *mainNode; /* The main target to create. This is the * first target on the first dependency * line in the first makefile */ -/* - * Definitions for handling #include specifications - */ -typedef struct IFile { - char *fname; /* name of previous file */ - int lineno; /* saved line number */ - FILE * F; /* the open stream */ - PTR * p; /* the char pointer */ -} IFile; - -static IFile curFile; + +IFile curFile; /* current makefile */ static Lst includes; /* stack of IFiles generated by * #includes */ |