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>
This commit is contained in:
parent
9d4a4d9654
commit
0b6943c93f
@ -133,8 +133,10 @@ static Token condPushBack=None; /* Single push-back token used in
|
|||||||
#define MAXIF 30 /* greatest depth of #if'ing */
|
#define MAXIF 30 /* greatest depth of #if'ing */
|
||||||
|
|
||||||
static Boolean condStack[MAXIF]; /* Stack of conditionals's values */
|
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 condTop = MAXIF; /* Top-most conditional */
|
||||||
static int skipIfLevel=0; /* Depth of skipped conditionals */
|
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
|
static Boolean skipLine = FALSE; /* Whether the parse module is skipping
|
||||||
* lines */
|
* lines */
|
||||||
|
|
||||||
@ -1047,8 +1049,10 @@ Cond_Eval (char *line)
|
|||||||
Boolean isElse;
|
Boolean isElse;
|
||||||
Boolean value = FALSE;
|
Boolean value = FALSE;
|
||||||
int level; /* Level at which to report errors. */
|
int level; /* Level at which to report errors. */
|
||||||
|
int lineno;
|
||||||
|
|
||||||
level = PARSE_FATAL;
|
level = PARSE_FATAL;
|
||||||
|
lineno = curFile.lineno;
|
||||||
|
|
||||||
for (line++; *line == ' ' || *line == '\t'; line++) {
|
for (line++; *line == ' ' || *line == '\t'; line++) {
|
||||||
continue;
|
continue;
|
||||||
@ -1109,6 +1113,7 @@ Cond_Eval (char *line)
|
|||||||
return (COND_INVALID);
|
return (COND_INVALID);
|
||||||
} else if (skipIfLevel == 0) {
|
} else if (skipIfLevel == 0) {
|
||||||
value = !condStack[condTop];
|
value = !condStack[condTop];
|
||||||
|
lineno = condLineno[condTop];
|
||||||
} else {
|
} else {
|
||||||
return (COND_SKIP);
|
return (COND_SKIP);
|
||||||
}
|
}
|
||||||
@ -1130,6 +1135,7 @@ Cond_Eval (char *line)
|
|||||||
* undefined, for which there's an enclosing ifdef that
|
* undefined, for which there's an enclosing ifdef that
|
||||||
* we're skipping...
|
* we're skipping...
|
||||||
*/
|
*/
|
||||||
|
skipIfLineno[skipIfLevel - 1] = lineno;
|
||||||
return(COND_SKIP);
|
return(COND_SKIP);
|
||||||
}
|
}
|
||||||
} else if (skipLine) {
|
} 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
|
* Don't even try to evaluate a conditional that's not an else if
|
||||||
* we're skipping things...
|
* we're skipping things...
|
||||||
*/
|
*/
|
||||||
|
skipIfLineno[skipIfLevel] = lineno;
|
||||||
skipIfLevel += 1;
|
skipIfLevel += 1;
|
||||||
return(COND_SKIP);
|
return(COND_SKIP);
|
||||||
}
|
}
|
||||||
@ -1202,6 +1209,7 @@ Cond_Eval (char *line)
|
|||||||
return (COND_INVALID);
|
return (COND_INVALID);
|
||||||
} else {
|
} else {
|
||||||
condStack[condTop] = value;
|
condStack[condTop] = value;
|
||||||
|
condLineno[condTop] = lineno;
|
||||||
skipLine = !value;
|
skipLine = !value;
|
||||||
return (value ? COND_PARSE : COND_SKIP);
|
return (value ? COND_PARSE : COND_SKIP);
|
||||||
}
|
}
|
||||||
@ -1223,9 +1231,20 @@ Cond_Eval (char *line)
|
|||||||
void
|
void
|
||||||
Cond_End(void)
|
Cond_End(void)
|
||||||
{
|
{
|
||||||
|
int level;
|
||||||
|
|
||||||
if (condTop != MAXIF) {
|
if (condTop != MAXIF) {
|
||||||
Parse_Error(PARSE_FATAL, "%d open conditional%s", MAXIF-condTop,
|
Parse_Error(PARSE_FATAL, "%d open conditional%s:",
|
||||||
MAXIF-condTop == 1 ? "" : "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;
|
condTop = MAXIF;
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,21 @@ typedef struct GNode {
|
|||||||
* but the Suff module) */
|
* but the Suff module) */
|
||||||
} GNode;
|
} 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
|
* 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
|
* 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 */
|
* make(...) statements */
|
||||||
extern Lst dirSearchPath; /* The list of directories to search when
|
extern Lst dirSearchPath; /* The list of directories to search when
|
||||||
* looking for targets */
|
* looking for targets */
|
||||||
|
extern IFile curFile; /* current makefile */
|
||||||
extern Lst parseIncPath; /* The list of directories to search when
|
extern Lst parseIncPath; /* The list of directories to search when
|
||||||
* looking for includes */
|
* looking for includes */
|
||||||
|
|
||||||
|
@ -105,27 +105,13 @@ static Lst targets; /* targets we're working on */
|
|||||||
static Lst targCmds; /* command lines for targets */
|
static Lst targCmds; /* command lines for targets */
|
||||||
static Boolean inLine; /* true if currently in a dependency
|
static Boolean inLine; /* true if currently in a dependency
|
||||||
* line or its commands */
|
* line or its commands */
|
||||||
typedef struct {
|
|
||||||
char *str;
|
|
||||||
char *ptr;
|
|
||||||
} PTR;
|
|
||||||
|
|
||||||
static int fatals = 0;
|
static int fatals = 0;
|
||||||
|
|
||||||
static GNode *mainNode; /* The main target to create. This is the
|
static GNode *mainNode; /* The main target to create. This is the
|
||||||
* first target on the first dependency
|
* first target on the first dependency
|
||||||
* line in the first makefile */
|
* 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
|
static Lst includes; /* stack of IFiles generated by
|
||||||
* #includes */
|
* #includes */
|
||||||
|
Loading…
Reference in New Issue
Block a user