Detect missing endif markers.

This commit is contained in:
steve 2003-09-26 02:08:31 +00:00
parent 39b2928ad8
commit 2ed433b8c1
2 changed files with 88 additions and 35 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.41 2003/08/26 16:26:02 steve Exp $"
#ident "$Id: lexor.lex,v 1.42 2003/09/26 02:08:31 steve Exp $"
#endif
# include "config.h"
@ -73,6 +73,54 @@ static struct include_stack_t*file_queue = 0;
static struct include_stack_t*istack = 0;
static struct include_stack_t*standby = 0;
/*
* Keep a stack of active ifdef, so that I can report errors
* when there are missing endifs.
*/
struct ifdef_stack_t {
char*path;
unsigned lineno;
struct ifdef_stack_t*next;
};
static struct ifdef_stack_t *ifdef_stack = 0;
static void ifdef_enter(void)
{
struct ifdef_stack_t*cur;
cur = calloc(1, sizeof(struct ifdef_stack_t));
cur->path = strdup(istack->path);
cur->lineno = istack->lineno;
cur->next = ifdef_stack;
ifdef_stack = cur;
}
static void ifdef_leave(void)
{
struct ifdef_stack_t*cur;
assert(ifdef_stack);
cur = ifdef_stack;
ifdef_stack = cur->next;
if (strcmp(istack->path,cur->path) != 0) {
fprintf(stderr, "%s:%u: warning: "
"This `endif matches an ifdef in another file.\n",
istack->path, istack->lineno);
fprintf(stderr, "%s:%u: : "
"This is the odd matched `ifdef.\n",
cur->path, cur->lineno);
}
free(cur->path);
free(cur);
}
#define YY_INPUT(buf,result,max_size) do { \
if (istack->file) { \
size_t rc = fread(buf, 1, max_size, istack->file); \
@ -123,6 +171,7 @@ W [ \t\b\f]+
directives contained within are ignored. Contains macros are
expanded, however. */
"(*"{W}?")" { ECHO; }
"(*" { comment_enter = YY_START; BEGIN(PCOMENT); ECHO; }
<PCOMENT>[^\r\n] { ECHO; }
<PCOMENT>\n\r { istack->lineno += 1; fputc('\n', yyout); }
@ -225,6 +274,8 @@ W [ \t\b\f]+
name += 6;
name += strspn(name, " \t\b\f");
ifdef_enter();
if (is_defined(name)) {
yy_push_state(IFDEF_TRUE);
} else {
@ -238,6 +289,8 @@ W [ \t\b\f]+
name += 7;
name += strspn(name, " \t\b\f");
ifdef_enter();
if (!is_defined(name)) {
yy_push_state(IFDEF_TRUE);
} else {
@ -245,8 +298,14 @@ W [ \t\b\f]+
}
}
<IFDEF_FALSE,IFDEF_SUPR>`ifdef{W} { yy_push_state(IFDEF_SUPR); }
<IFDEF_FALSE,IFDEF_SUPR>`ifndef{W} { yy_push_state(IFDEF_SUPR); }
<IFDEF_FALSE,IFDEF_SUPR>`ifdef{W} {
ifdef_enter();
yy_push_state(IFDEF_SUPR);
}
<IFDEF_FALSE,IFDEF_SUPR>`ifndef{W} {
ifdef_enter();
yy_push_state(IFDEF_SUPR);
}
<IFDEF_TRUE>`else { BEGIN(IFDEF_FALSE); }
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
@ -259,9 +318,7 @@ W [ \t\b\f]+
<IFDEF_FALSE,IFDEF_SUPR>\n { istack->lineno += 1; fputc('\n', yyout); }
<IFDEF_FALSE,IFDEF_SUPR>\r { istack->lineno += 1; fputc('\n', yyout); }
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif {
yy_pop_state();
}
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif { ifdef_leave(); yy_pop_state(); }
/* This pattern notices macros and arranges for them to be replaced. */
`[a-zA-Z][a-zA-Z0-9_$]* { def_match(); }
@ -692,6 +749,21 @@ static void emit_pathline(struct include_stack_t*isp)
isp->path, isp->lineno+1);
}
static void lexor_done()
{
while (ifdef_stack) {
struct ifdef_stack_t*cur = ifdef_stack;
ifdef_stack = cur->next;
fprintf(stderr, "%s:%u: error: This `ifdef lacks an `endif.\n",
cur->path, cur->lineno);
free(cur->path);
free(cur);
error_count += 1;
}
}
/*
* The lexical analyzer calls this function when the current file
* ends. Here I pop the include stack and resume the previous file. If
@ -721,13 +793,15 @@ static int yywrap()
}
free(isp);
/* If I am out if include stack, the main input is
/* If I am out of include stack, the main input is
done. Look for another file to process in the input
queue. If none are there, give up. Otherwise, open the file
and continue parsing. */
if (istack == 0) {
if (file_queue == 0)
if (file_queue == 0) {
lexor_done();
return 1;
}
istack = file_queue;
file_queue = file_queue->next;
@ -737,7 +811,8 @@ static int yywrap()
istack->file = fopen(istack->path, "r");
if (istack->file == 0) {
perror(istack->path);
exit(1);
error_count += 1;
return 1;
}
if (line_direct_flag)

View File

@ -17,7 +17,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.c,v 1.16 2002/08/12 01:35:02 steve Exp $"
#ident "$Id: main.c,v 1.17 2003/09/26 02:08:31 steve Exp $"
#endif
# include "config.h"
@ -288,6 +288,9 @@ int main(int argc, char*argv[])
/*
* $Log: main.c,v $
* Revision 1.17 2003/09/26 02:08:31 steve
* Detect missing endif markers.
*
* Revision 1.16 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
@ -312,30 +315,5 @@ int main(int argc, char*argv[])
*
* Revision 1.9 2001/05/20 18:08:07 steve
* local declares if the header is missing.
*
* Revision 1.8 2000/12/06 05:15:21 steve
* fix portfaults pass values.
*
* Revision 1.7 2000/09/13 22:33:13 steve
* undefined macros are null (with warnings.)
*
* Revision 1.6 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.5 2000/06/30 15:49:44 steve
* Handle errors from parser slightly differently.
*
* Revision 1.4 1999/11/29 17:02:21 steve
* include getopt if present.
*
* Revision 1.3 1999/09/05 22:33:18 steve
* Take multiple source files on the command line.
*
* Revision 1.2 1999/07/03 20:03:47 steve
* Add include path and line directives.
*
* Revision 1.1 1999/07/03 17:24:11 steve
* Add a preprocessor.
*
*/