[2/6] wpp: Remove the assumption ppy_error calls exit()
Matteo Bruni
matteo.mystral at gmail.com
Thu Sep 10 10:40:33 CDT 2009
Currently wpp simply calls exit() on error situations (being it a
syntax error, a memory allocation failure, ...). While this is ok for
the tools using wpp (wrc, widl) it is not good for a Win application
to be terminated because of this.
These patches allow to redefine wpp behavior on error, allowing it to
continue in spite of errors.
-------------- next part --------------
From da8e3244f766ed1c792f330ebe0997d10ba94698 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Sat, 29 Aug 2009 16:46:26 +0200
Subject: wpp: Remove the assumption ppy_error calls exit()
This is in preparation for the ability to override ppy_error behavior.
---
libs/wpp/ppl.l | 36 +++++++++++++++++++++++++++---------
libs/wpp/ppy.y | 33 +++++++++++++++++++++------------
libs/wpp/preproc.c | 7 +++++++
libs/wpp/wpp.c | 15 +++++++++------
libs/wpp/wpp_private.h | 4 +++-
5 files changed, 67 insertions(+), 28 deletions(-)
diff --git a/libs/wpp/ppl.l b/libs/wpp/ppl.l
index 6091d3f..52f0f04 100644
--- a/libs/wpp/ppl.l
+++ b/libs/wpp/ppl.l
@@ -686,17 +686,20 @@ void writestring( const char *format, ... )
if(yy_current_state() == pp_inc)
ppy_error("Expected include filename");
- if(yy_current_state() == pp_if)
+ else
{
- ppy_lval.cptr = pp_xstrdup(ppy_text);
- return tIDENT;
- }
- else {
- if((yy_current_state()==INITIAL) && (strcasecmp(ppy_text,"RCINCLUDE")==0)){
- yy_push_state(RCINCL);
- return tRCINCLUDE;
+ if(yy_current_state() == pp_if)
+ {
+ ppy_lval.cptr = pp_xstrdup(ppy_text);
+ return tIDENT;
+ }
+ else {
+ if((yy_current_state()==INITIAL) && (strcasecmp(ppy_text,"RCINCLUDE")==0)){
+ yy_push_state(RCINCL);
+ return tRCINCLUDE;
+ }
+ else put_buffer(ppy_text, ppy_leng);
}
- else put_buffer(ppy_text, ppy_leng);
}
}
else if(!ppp->expanding)
@@ -855,7 +858,10 @@ static int make_number(int radix, YYSTYPE *val, const char *str, int len)
ext[0] = len > 2 ? toupper(str[len-3]) : ' ';
if(!strcmp(ext, "LUL"))
+ {
ppy_error("Invalid constant suffix");
+ return 0;
+ }
else if(!strcmp(ext, "LLU") || !strcmp(ext, "ULL"))
{
is_ll++;
@@ -1132,7 +1138,10 @@ static void expand_macro(macexpstackentry_t *mep)
assert(ppp->expanding == 0);
if((ppp->nargs >= 0 && nargs != ppp->nargs) || (ppp->nargs < 0 && nargs < -ppp->nargs))
+ {
ppy_error("Too %s macro arguments (%d)", nargs < abs(ppp->nargs) ? "few" : "many", nargs);
+ return;
+ }
for(n = 0; n < nargs; n++)
nnl += mep->nnls[n];
@@ -1372,7 +1381,10 @@ static bufferstackentry_t *pop_buffer(void)
static void push_macro(pp_entry_t *ppp)
{
if(macexpstackidx >= MAXMACEXPSTACK)
+ {
ppy_error("Too many nested macros");
+ return;
+ }
macexpstack[macexpstackidx] = pp_xmalloc(sizeof(macexpstack[0][0]));
memset( macexpstack[macexpstackidx], 0, sizeof(macexpstack[0][0]));
@@ -1522,13 +1534,19 @@ void pp_do_include(char *fname, int type)
n = strlen(fname);
if(n <= 2)
+ {
ppy_error("Empty include filename");
+ return;
+ }
/* Undo the effect of the quotation */
fname[n-1] = '\0';
if((fp = pp_open_include(fname+1, type ? pp_status.input : NULL, &newpath)) == NULL)
+ {
ppy_error("Unable to open include file %s", fname+1);
+ return;
+ }
fname[n-1] = *fname; /* Redo the quotes */
push_buffer(NULL, newpath, fname, 0);
diff --git a/libs/wpp/ppy.y b/libs/wpp/ppy.y
index c5723ef..505987a 100644
--- a/libs/wpp/ppy.y
+++ b/libs/wpp/ppy.y
@@ -224,6 +224,9 @@ preprocessor
case if_elsetrue:
case if_elsefalse:
ppy_error("#elif cannot follow #else");
+ break;
+ case if_error:
+ break;
default:
pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #elif directive", s);
}
@@ -247,24 +250,29 @@ preprocessor
case if_elsetrue:
case if_elsefalse:
ppy_error("#else clause already defined");
+ break;
+ case if_error:
+ break;
default:
pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #else directive", s);
}
}
| tENDIF tNL {
- pp_pop_if();
- if(pp_incl_state.ifdepth == pp_get_if_depth() && pp_incl_state.state == 1)
- {
- pp_incl_state.state = 2;
- pp_incl_state.seen_junk = 0;
- }
- else if(pp_incl_state.state != 1)
+ if(pp_pop_if() != if_error)
{
- pp_incl_state.state = -1;
+ if(pp_incl_state.ifdepth == pp_get_if_depth() && pp_incl_state.state == 1)
+ {
+ pp_incl_state.state = 2;
+ pp_incl_state.seen_junk = 0;
+ }
+ else if(pp_incl_state.state != 1)
+ {
+ pp_incl_state.state = -1;
+ }
+ if(pp_status.debug)
+ fprintf(stderr, "tENDIF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
+ pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
}
- if(pp_status.debug)
- fprintf(stderr, "tENDIF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
- pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
}
| tUNDEF tIDENT tNL { pp_del_define($2); free($2); }
| tDEFINE opt_text tNL { pp_add_define($1, $2); }
@@ -346,7 +354,8 @@ mtext : tLITERAL { $$ = new_mtext($1, 0, exp_text); }
int mat = marg_index($2);
if(mat < 0)
ppy_error("Stringification identifier must be an argument parameter");
- $$ = new_mtext(NULL, mat, exp_stringize);
+ else
+ $$ = new_mtext(NULL, mat, exp_stringize);
}
| tIDENT {
int mat = marg_index($1);
diff --git a/libs/wpp/preproc.c b/libs/wpp/preproc.c
index c3e5ff0..ff34668 100644
--- a/libs/wpp/preproc.c
+++ b/libs/wpp/preproc.c
@@ -552,13 +552,18 @@ void pp_push_if(pp_if_state_t s)
case if_ignore:
pp_push_ignore_state();
break;
+ default:
+ pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d)", (int)pp_if_state());
}
}
pp_if_state_t pp_pop_if(void)
{
if(if_stack_idx <= 0)
+ {
ppy_error("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)");
+ return if_error;
+ }
switch(pp_if_state())
{
@@ -571,6 +576,8 @@ pp_if_state_t pp_pop_if(void)
case if_ignore:
pp_pop_ignore_state();
break;
+ default:
+ pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d)", (int)pp_if_state());
}
if(pp_flex_debug)
diff --git a/libs/wpp/wpp.c b/libs/wpp/wpp.c
index 0a16a02..1e9d4ba 100644
--- a/libs/wpp/wpp.c
+++ b/libs/wpp/wpp.c
@@ -144,6 +144,7 @@ int wpp_parse( const char *input, FILE *output )
int ret;
pp_status.input = NULL;
+ pp_status.state = 0;
pp_push_define_state();
add_cmdline_defines();
@@ -152,8 +153,8 @@ int wpp_parse( const char *input, FILE *output )
if (!input) currentfile = stdin;
else if (!(currentfile = io_callback->open(input, 1)))
{
- fprintf(stderr,"Could not open %s\n", input);
- exit(2);
+ ppy_error("Could not open %s\n", input);
+ return 2;
}
pp_status.input = input;
@@ -162,6 +163,8 @@ int wpp_parse( const char *input, FILE *output )
writestring("# 1 \"%s\" 1\n", input ? input : "");
ret = ppy_parse();
+ /* If there were errors during processing, return an error code */
+ if(!ret && pp_status.state) ret = pp_status.state;
if (input) io_callback->close(currentfile);
pp_pop_define_state();
@@ -184,14 +187,14 @@ int wpp_parse_temp( const char *input, const char *output_base, char **output_na
if((fd = mkstemps( temp_name, 0 )) == -1)
{
- fprintf(stderr, "Could not generate a temp name from %s\n", temp_name);
- exit(2);
+ ppy_error("Could not generate a temp name from %s\n", temp_name);
+ return 2;
}
if (!(output = fdopen(fd, "wt")))
{
- fprintf(stderr,"Could not open fd %s for writing\n", temp_name);
- exit(2);
+ ppy_error("Could not open fd %s for writing\n", temp_name);
+ return 2;
}
*output_name = temp_name;
diff --git a/libs/wpp/wpp_private.h b/libs/wpp/wpp_private.h
index d04fab8..b064fc8 100644
--- a/libs/wpp/wpp_private.h
+++ b/libs/wpp/wpp_private.h
@@ -113,7 +113,8 @@ typedef enum {
if_elif,
if_elsefalse,
if_elsetrue,
- if_ignore
+ if_ignore,
+ if_error
} pp_if_state_t;
@@ -231,6 +232,7 @@ struct pp_status
const char *input; /* current input file name */
int line_number; /* current line number */
int char_number; /* current char number in line */
+ int state; /* current error state */
int pedantic; /* pedantic option */
int debug; /* debug messages flag */
};
--
1.6.3.3
More information about the wine-patches
mailing list