From b7d3c79bebd3083b94c909e5250a2e852031fa45 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 16 Jul 2002 02:33:10 +0000 Subject: [PATCH] Split the C preprocessor from wrc into a separate library. Prefixed exported functions by 'pp' to avoid namespace conflicts. --- configure | 3 +- configure.ac | 1 + tools/Makefile.in | 3 + tools/wpp/.cvsignore | 4 + tools/wpp/Makefile.in | 32 ++ tools/{wrc => wpp}/ppl.l | 293 ++++++++--------- tools/{wrc => wpp}/ppy.y | 103 +++--- tools/{wrc => wpp}/preproc.c | 345 +++++++++++++-------- tools/wpp/wpp.c | 131 ++++++++ tools/wpp/wpp.h | 35 +++ tools/{wrc/preproc.h => wpp/wpp_private.h} | 92 ++++-- tools/wrc/.cvsignore | 6 - tools/wrc/Makefile.in | 20 +- tools/wrc/parser.l | 1 - tools/wrc/parser.y | 11 +- tools/wrc/utils.c | 21 -- tools/wrc/utils.h | 2 - tools/wrc/wrc.c | 94 ++---- 18 files changed, 714 insertions(+), 483 deletions(-) create mode 100644 tools/wpp/.cvsignore create mode 100644 tools/wpp/Makefile.in rename tools/{wrc => wpp}/ppl.l (82%) rename tools/{wrc => wpp}/ppy.y (86%) rename tools/{wrc => wpp}/preproc.c (55%) create mode 100644 tools/wpp/wpp.c create mode 100644 tools/wpp/wpp.h rename tools/{wrc/preproc.h => wpp/wpp_private.h} (67%) diff --git a/configure b/configure index a029db0fd32..58b1b152a85 100755 --- a/configure +++ b/configure @@ -13314,7 +13314,7 @@ MAKE_DLL_RULES=dlls/Makedll.rules MAKE_PROG_RULES=programs/Makeprog.rules -ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules programs/Makeprog.rules Makefile debugger/Makefile dlls/Makefile dlls/advapi32/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/comcat/Makefile dlls/comctl32/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/d3d8/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dinput8/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile dlls/gdi/Makefile dlls/glu32/Makefile dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/kernel/Makefile dlls/lzexpand/Makefile dlls/mapi32/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/imaadp32/Makefile dlls/msacm/msadp32/Makefile dlls/msacm/msg711/Makefile dlls/msacm/winemp3/Makefile dlls/msdmo/Makefile dlls/msimg32/Makefile dlls/msisys/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt20/Makefile dlls/msvideo/Makefile dlls/netapi32/Makefile dlls/ntdll/Makefile dlls/odbc32/Makefile dlls/ole32/Makefile dlls/oleaut32/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/psapi/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/rasapi32/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/snmpapi/Makefile dlls/sti/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winealsa/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winspool/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile documentation/Makefile include/Makefile library/Makefile miscemu/Makefile ole/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/expand/Makefile programs/notepad/Makefile programs/osversioncheck/Makefile programs/progman/Makefile programs/regapi/Makefile programs/regedit/Makefile programs/regsvr32/Makefile programs/regtest/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineconsole/Makefile programs/winefile/Makefile programs/winemine/Makefile programs/winepath/Makefile programs/winetest/Makefile programs/winhelp/Makefile programs/winver/Makefile server/Makefile tools/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/wmc/Makefile tools/wrc/Makefile tsx11/Makefile unicode/Makefile" +ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules programs/Makeprog.rules Makefile debugger/Makefile dlls/Makefile dlls/advapi32/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/comcat/Makefile dlls/comctl32/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/d3d8/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dinput8/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile dlls/gdi/Makefile dlls/glu32/Makefile dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/kernel/Makefile dlls/lzexpand/Makefile dlls/mapi32/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/imaadp32/Makefile dlls/msacm/msadp32/Makefile dlls/msacm/msg711/Makefile dlls/msacm/winemp3/Makefile dlls/msdmo/Makefile dlls/msimg32/Makefile dlls/msisys/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt20/Makefile dlls/msvideo/Makefile dlls/netapi32/Makefile dlls/ntdll/Makefile dlls/odbc32/Makefile dlls/ole32/Makefile dlls/oleaut32/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/psapi/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/rasapi32/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/snmpapi/Makefile dlls/sti/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winealsa/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winspool/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile documentation/Makefile include/Makefile library/Makefile miscemu/Makefile ole/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/expand/Makefile programs/notepad/Makefile programs/osversioncheck/Makefile programs/progman/Makefile programs/regapi/Makefile programs/regedit/Makefile programs/regsvr32/Makefile programs/regtest/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineconsole/Makefile programs/winefile/Makefile programs/winemine/Makefile programs/winepath/Makefile programs/winetest/Makefile programs/winhelp/Makefile programs/winver/Makefile server/Makefile tools/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/wmc/Makefile tools/wpp/Makefile tools/wrc/Makefile tsx11/Makefile unicode/Makefile" cat >confcache <<\_ACEOF @@ -13925,6 +13925,7 @@ do "tools/winebuild/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/winebuild/Makefile" ;; "tools/winedump/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/winedump/Makefile" ;; "tools/wmc/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/wmc/Makefile" ;; + "tools/wpp/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/wpp/Makefile" ;; "tools/wrc/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/wrc/Makefile" ;; "tsx11/Makefile" ) CONFIG_FILES="$CONFIG_FILES tsx11/Makefile" ;; "unicode/Makefile" ) CONFIG_FILES="$CONFIG_FILES unicode/Makefile" ;; diff --git a/configure.ac b/configure.ac index f064a98d4e0..926e021df1d 100644 --- a/configure.ac +++ b/configure.ac @@ -1378,6 +1378,7 @@ tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/wmc/Makefile +tools/wpp/Makefile tools/wrc/Makefile tsx11/Makefile unicode/Makefile]) diff --git a/tools/Makefile.in b/tools/Makefile.in index 2fdd45b43b4..7af39fd03e0 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -13,6 +13,7 @@ SUBDIRS = \ winebuild \ winedump \ wmc \ + wpp \ wrc INSTALLSUBDIRS = $(SUBDIRS) @@ -27,6 +28,8 @@ all: $(PROGRAMS) $(SUBDIRS) @MAKE_RULES@ +wrc: wpp + makedep: makedep.o $(CC) $(CFLAGS) -o makedep makedep.o diff --git a/tools/wpp/.cvsignore b/tools/wpp/.cvsignore new file mode 100644 index 00000000000..8e7a16238bc --- /dev/null +++ b/tools/wpp/.cvsignore @@ -0,0 +1,4 @@ +Makefile +lex.yy.c +y.tab.c +y.tab.h diff --git a/tools/wpp/Makefile.in b/tools/wpp/Makefile.in new file mode 100644 index 00000000000..5aca31f5222 --- /dev/null +++ b/tools/wpp/Makefile.in @@ -0,0 +1,32 @@ +DEFS = -D__WINE__ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +LEXOPT = -Cf #-w -b +YACCOPT = #-v +MODULE = none + +C_SRCS = \ + preproc.c \ + wpp.c + +EXTRA_SRCS = ppy.y ppl.l +EXTRA_OBJS = y.tab.o @LEX_OUTPUT_ROOT@.o + +all: libwpp.a + +@MAKE_RULES@ + +libwpp.a: $(OBJS) + $(RM) $@ + $(AR) $@ $(OBJS) + $(RANLIB) $@ + +y.tab.c y.tab.h: ppy.y + $(YACC) $(YACCOPT) -ppp -d -t $(SRCDIR)/ppy.y + +@LEX_OUTPUT_ROOT@.c: ppl.l + $(LEX) $(LEXOPT) -d -Ppp -o$@ -8 $(SRCDIR)/ppl.l + +### Dependencies: diff --git a/tools/wrc/ppl.l b/tools/wpp/ppl.l similarity index 82% rename from tools/wrc/ppl.l rename to tools/wpp/ppl.l index b7d2d06c72c..b8716269f5e 100644 --- a/tools/wrc/ppl.l +++ b/tools/wpp/ppl.l @@ -159,11 +159,8 @@ ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL] #include #include -#include "utils.h" -#include "wrc.h" -#include "preproc.h" - -#include "ppy.tab.h" +#include "wpp_private.h" +#include "y.tab.h" /* * Make sure that we are running an appropriate version of flex. @@ -182,7 +179,7 @@ ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL] /* * Always update the current character position within a line */ -#define YY_USER_ACTION char_number+=ppleng; +#define YY_USER_ACTION pp_status.char_number+=ppleng; /* * Buffer management for includes and expansions @@ -194,16 +191,13 @@ typedef struct bufferstackentry { pp_entry_t *define; /* Points to expanding define or NULL if handling includes */ int line_number; /* Line that we were handling */ int char_number; /* The current position on that line */ - char *filename; /* Filename that we were handling */ + const char *filename; /* Filename that we were handling */ int if_depth; /* How many #if:s deep to check matching #endif:s */ int ncontinuations; /* Remember the continuation state */ int should_pop; /* Set if we must pop the start-state on EOF */ /* Include management */ - int include_state; - char *include_ppp; - char *include_filename; - int include_ifdepth; - int seen_junk; + include_state_t incl; + char *include_filename; int pass_data; } bufferstackentry_t; @@ -280,21 +274,15 @@ static int pass_data=1; /* * Global variables */ -/* - * Trace the include files to prevent double reading. - * This save 20..30% of processing time for most stuff - * that uses complex includes. - * States: - * -1 Don't track or seen junk - * 0 New include, waiting for "#ifndef __xxx_h" - * 1 Seen #ifndef, waiting for "#define __xxx_h ..." - * 2 Seen #endif, waiting for EOF - */ -int include_state = -1; -char *include_ppp = NULL; /* The define to be set from the #ifndef */ -int include_ifdepth = 0; /* The level of ifs at the #ifdef */ -int seen_junk = 0; /* Set when junk is seen */ -includelogicentry_t *includelogiclist = NULL; +include_state_t pp_incl_state = +{ + -1, /* state */ + NULL, /* ppp */ + 0, /* ifdepth */ + 0 /* seen_junk */ +}; + +includelogicentry_t *pp_includelogiclist = NULL; %} @@ -317,7 +305,7 @@ includelogicentry_t *includelogiclist = NULL; /* * Detect the leading # of a preprocessor directive. */ -^{ws}*# seen_junk++; yy_push_state(pp_pp); +^{ws}*# pp_incl_state.seen_junk++; yy_push_state(pp_pp); /* * Scan for the preprocessor directives @@ -330,7 +318,7 @@ includelogicentry_t *includelogiclist = NULL; {ws}*ident{ws}* yy_pp_state(pp_eol); if(yy_top_state() != pp_ignore) return tPPIDENT; {ws}*undef{ws}* if(yy_top_state() != pp_ignore) {yy_pp_state(pp_ifd); return tUNDEF;} else {yy_pp_state(pp_eol);} {ws}*ifdef{ws}* yy_pp_state(pp_ifd); return tIFDEF; -{ws}*ifndef{ws}* seen_junk--; yy_pp_state(pp_ifd); return tIFNDEF; +{ws}*ifndef{ws}* pp_incl_state.seen_junk--; yy_pp_state(pp_ifd); return tIFNDEF; {ws}*if{ws}* yy_pp_state(pp_if); return tIF; {ws}*elif{ws}* yy_pp_state(pp_if); return tELIF; {ws}*else{ws}* return tELSE; @@ -395,7 +383,7 @@ includelogicentry_t *includelogiclist = NULL; * Handle #ifdef, #ifndef and #undef * to get only an untranslated/unexpanded identifier */ -{cident} pplval.cptr = xstrdup(pptext); return tIDENT; +{cident} pplval.cptr = pp_xstrdup(pptext); return tIDENT; {ws}+ ; \n newline(1); yy_pop_state(); return tNL; \\\r?\n newline(0); @@ -406,7 +394,7 @@ includelogicentry_t *includelogiclist = NULL; * This is necessary to get the identifier prior to any * substitutions. */ -{cident} yy_pop_state(); pplval.cptr = xstrdup(pptext); return tIDENT; +{cident} yy_pop_state(); pplval.cptr = pp_xstrdup(pptext); return tIDENT; {ws}+ ; (\()|(\)) return *pptext; \\\r?\n newline(0); @@ -418,17 +406,17 @@ includelogicentry_t *includelogiclist = NULL; * will act appropriately. * Comments are stripped from the literal text. */ -[^/\\\n]+ if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; } -\/[^/\\\n*]* if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; } -(\\\r?)|(\/[^/*]) if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; } +[^/\\\n]+ if(yy_top_state() != pp_ignore) { pplval.cptr = pp_xstrdup(pptext); return tLITERAL; } +\/[^/\\\n*]* if(yy_top_state() != pp_ignore) { pplval.cptr = pp_xstrdup(pptext); return tLITERAL; } +(\\\r?)|(\/[^/*]) if(yy_top_state() != pp_ignore) { pplval.cptr = pp_xstrdup(pptext); return tLITERAL; } \n newline(1); yy_pop_state(); if(yy_current_state() != pp_ignore) { return tNL; } \\\r?\n newline(0); /* * Handle left side of #define */ -{cident}\( pplval.cptr = xstrdup(pptext); pplval.cptr[ppleng-1] = '\0'; yy_pp_state(pp_macro); return tMACRO; -{cident} pplval.cptr = xstrdup(pptext); yy_pp_state(pp_define); return tDEFINE; +{cident}\( pplval.cptr = pp_xstrdup(pptext); pplval.cptr[ppleng-1] = '\0'; yy_pp_state(pp_macro); return tMACRO; +{cident} pplval.cptr = pp_xstrdup(pptext); yy_pp_state(pp_define); return tDEFINE; {ws}+ ; \\\r?\n newline(0); (\\\r?)|(\n)|(.) perror("Identifier expected"); @@ -436,9 +424,9 @@ includelogicentry_t *includelogiclist = NULL; /* * Scan the substitution of a define */ -[^'"/\\\n]+ pplval.cptr = xstrdup(pptext); return tLITERAL; -(\\\r?)|(\/[^/*]) pplval.cptr = xstrdup(pptext); return tLITERAL; -\\\r?\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL; +[^'"/\\\n]+ pplval.cptr = pp_xstrdup(pptext); return tLITERAL; +(\\\r?)|(\/[^/*]) pplval.cptr = pp_xstrdup(pptext); return tLITERAL; +\\\r?\n{ws}+ newline(0); pplval.cptr = pp_xstrdup(" "); return tLITERAL; \\\r?\n newline(0); \n newline(1); yy_pop_state(); return tNL; \' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs); @@ -449,7 +437,7 @@ includelogicentry_t *includelogiclist = NULL; */ \){ws}* yy_pp_state(pp_mbody); return tMACROEND; {ws}+ ; -{cident} pplval.cptr = xstrdup(pptext); return tIDENT; +{cident} pplval.cptr = pp_xstrdup(pptext); return tIDENT; , return ','; "..." return tELIPSIS; (\\\r?)|(\n)|(.)|(\.\.?) pperror("Argument identifier expected"); @@ -458,13 +446,13 @@ includelogicentry_t *includelogiclist = NULL; /* * Scan the substitution of a macro */ -[^a-zA-Z0-9'"#/\\\n]+ pplval.cptr = xstrdup(pptext); return tLITERAL; -{cident} pplval.cptr = xstrdup(pptext); return tIDENT; +[^a-zA-Z0-9'"#/\\\n]+ pplval.cptr = pp_xstrdup(pptext); return tLITERAL; +{cident} pplval.cptr = pp_xstrdup(pptext); return tIDENT; \#\# return tCONCAT; \# return tSTRINGIZE; -[0-9][^'"#/\\\n]* pplval.cptr = xstrdup(pptext); return tLITERAL; -(\\\r?)|(\/[^/*'"#\\\n]*) pplval.cptr = xstrdup(pptext); return tLITERAL; -\\\r?\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL; +[0-9][^'"#/\\\n]* pplval.cptr = pp_xstrdup(pptext); return tLITERAL; +(\\\r?)|(\/[^/*'"#\\\n]*) pplval.cptr = pp_xstrdup(pptext); return tLITERAL; +\\\r?\n{ws}+ newline(0); pplval.cptr = pp_xstrdup(" "); return tLITERAL; \\\r?\n newline(0); \n newline(1); yy_pop_state(); return tNL; \' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs); @@ -519,7 +507,7 @@ includelogicentry_t *includelogiclist = NULL; \" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs); \' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs); "/*" yy_push_state(pp_comment); add_text_to_macro(" ", 1); -\n line_number++; char_number = 1; add_text_to_macro(pptext, ppleng); +\n pp_status.line_number++; pp_status.char_number = 1; add_text_to_macro(pptext, ppleng); ([^/(),\\\n"']+)|(\/[^/*(),\\\n'"]*)|(\\\r?)|(.) add_text_to_macro(pptext, ppleng); \\\r?\n newline(0); @@ -542,8 +530,8 @@ includelogicentry_t *includelogiclist = NULL; /* * Single, double and <> quoted constants */ -\" seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs); -\' seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs); +\" pp_incl_state.seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs); +\' pp_incl_state.seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs); [^"\\\n]+ add_string(pptext, ppleng); \" { add_string(pptext, ppleng); @@ -621,7 +609,7 @@ includelogicentry_t *includelogiclist = NULL; */ {cident} { pp_entry_t *ppp; - seen_junk++; + pp_incl_state.seen_junk++; if(!(ppp = pplookup(pptext))) { if(yy_current_state() == pp_inc) @@ -629,7 +617,7 @@ includelogicentry_t *includelogiclist = NULL; if(yy_current_state() == pp_if) { - pplval.cptr = xstrdup(pptext); + pplval.cptr = pp_xstrdup(pptext); return tIDENT; } else { @@ -655,7 +643,7 @@ includelogicentry_t *includelogiclist = NULL; push_macro(ppp); break; default: - internal_error(__FILE__, __LINE__, "Invalid define type %d\n", ppp->type); + pp_internal_error(__FILE__, __LINE__, "Invalid define type %d\n", ppp->type); } } } @@ -664,11 +652,11 @@ includelogicentry_t *includelogiclist = NULL; * Everything else that needs to be passed and * newline and continuation handling */ -[^a-zA-Z_#'"/\\\n \r\t\f\v]+|(\/|\\)[^a-zA-Z_/*'"\\\n \r\t\v\f]* seen_junk++; put_buffer(pptext, ppleng); +[^a-zA-Z_#'"/\\\n \r\t\f\v]+|(\/|\\)[^a-zA-Z_/*'"\\\n \r\t\v\f]* pp_incl_state.seen_junk++; put_buffer(pptext, ppleng); {ws}+ put_buffer(pptext, ppleng); \n newline(1); \\\r?\n newline(0); -\\\r? seen_junk++; put_buffer(pptext, ppleng); +\\\r? pp_incl_state.seen_junk++; put_buffer(pptext, ppleng); /* * Special catcher for macro argmument expansion to prevent @@ -677,7 +665,7 @@ includelogicentry_t *includelogiclist = NULL; (\n)|(.)|(\\\r?(\n|.)) put_buffer(pptext, ppleng); [A-Za-z0-9_\.\\/]+ { - pplval.cptr=xstrdup(pptext); + pplval.cptr=pp_xstrdup(pptext); yy_pop_state(); return tRCINCLUDEPATH; } @@ -692,13 +680,13 @@ includelogicentry_t *includelogiclist = NULL; * This is a 'catch-all' rule to discover errors in the scanner * in an orderly manner. */ -<*>. seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext & 0xff) ? *pptext : ' ', *pptext); +<*>. pp_incl_state.seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext & 0xff) ? *pptext : ' ', *pptext); <> { YY_BUFFER_STATE b = YY_CURRENT_BUFFER; bufferstackentry_t *bep = pop_buffer(); - if((!bep && get_if_depth()) || (bep && get_if_depth() != bep->if_depth)) + if((!bep && pp_get_if_depth()) || (bep && pp_get_if_depth() != bep->if_depth)) ppwarning("Unmatched #if/#endif at end of file"); if(!bep) @@ -742,8 +730,8 @@ int ppwrap(void) */ static void newline(int dowrite) { - line_number++; - char_number = 1; + pp_status.line_number++; + pp_status.char_number = 1; if(dowrite == -1) return; @@ -819,7 +807,7 @@ static int make_number(int radix, YYSTYPE *val, char *str, int len) } if(is_ll) - internal_error(__FILE__, __LINE__, "long long constants not implemented yet"); + pp_internal_error(__FILE__, __LINE__, "long long constants not implemented yet"); if(is_u && is_l) { @@ -834,24 +822,11 @@ static int make_number(int radix, YYSTYPE *val, char *str, int len) else if(is_u && !is_l) { val->uint = (unsigned int)strtoul(str, NULL, radix); - if(!win32 && val->uint > 65535) - { - pperror("Constant overflow"); - } return tUINT; } /* Else it must be an int... */ val->sint = (int)strtol(str, NULL, radix); - if(!win32 && (val->sint < -32768 || val->sint > 32768)) - { - /* - * Note: test must be > 32768 because unary minus - * is handled as an expression! This can result in - * failure and must be checked in the parser. - */ - pperror("Constant overflow"); - } return tSINT; } @@ -873,35 +848,23 @@ static void expand_special(pp_entry_t *ppp) if(!strcmp(ppp->ident, "__LINE__")) { dbgtext = "def_special(__LINE__)"; - buf = xrealloc(buf, 32); - sprintf(buf, "%d", line_number); + buf = pp_xrealloc(buf, 32); + sprintf(buf, "%d", pp_status.line_number); } else if(!strcmp(ppp->ident, "__FILE__")) { dbgtext = "def_special(__FILE__)"; - buf = xrealloc(buf, strlen(input_name) + 3); - sprintf(buf, "\"%s\"", input_name); - } - else if(!strcmp(ppp->ident, "__DATE__")) - { - dbgtext = "def_special(__DATE__)"; - buf = xrealloc(buf, 32); - strftime(buf, 32, "\"%b %d %Y\"", localtime(&now)); - } - else if(!strcmp(ppp->ident, "__TIME__")) - { - dbgtext = "def_special(__TIME__)"; - buf = xrealloc(buf, 32); - strftime(buf, 32, "\"%H:%M:%S\"", localtime(&now)); + buf = pp_xrealloc(buf, strlen(pp_status.input) + 3); + sprintf(buf, "\"%s\"", pp_status.input); } else - internal_error(__FILE__, __LINE__, "Special macro '%s' not found...\n", ppp->ident); + pp_internal_error(__FILE__, __LINE__, "Special macro '%s' not found...\n", ppp->ident); - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "expand_special(%d): %s:%d: '%s' -> '%s'\n", macexpstackidx, - input_name, - line_number, + pp_status.input, + pp_status.line_number, ppp->ident, buf ? buf : ""); @@ -916,11 +879,11 @@ static void expand_define(pp_entry_t *ppp) { assert(ppp->type == def_define); - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "expand_define(%d): %s:%d: '%s' -> '%s'\n", macexpstackidx, - input_name, - line_number, + pp_status.input, + pp_status.line_number, ppp->ident, ppp->subst.text); if(ppp->subst.text && ppp->subst.text[0]) @@ -941,7 +904,7 @@ static void add_text(char *str, int len) if(curdef_idx >= curdef_alloc || curdef_alloc - curdef_idx < len) { curdef_alloc += (len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1); - curdef_text = xrealloc(curdef_text, curdef_alloc * sizeof(curdef_text[0])); + curdef_text = pp_xrealloc(curdef_text, curdef_alloc * sizeof(curdef_text[0])); if(curdef_alloc > 65536) ppwarning("Reallocating macro-expansion buffer larger than 64kB"); } @@ -962,13 +925,13 @@ static mtext_t *add_expand_text(mtext_t *mtp, macexpstackentry_t *mep, int *nnl) switch(mtp->type) { case exp_text: - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "add_expand_text: exp_text: '%s'\n", mtp->subst.text); add_text(mtp->subst.text, strlen(mtp->subst.text)); break; case exp_stringize: - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "add_expand_text: exp_stringize(%d): '%s'\n", mtp->subst.argidx, mep->args[mtp->subst.argidx]); @@ -985,7 +948,7 @@ static mtext_t *add_expand_text(mtext_t *mtp, macexpstackentry_t *mep, int *nnl) break; case exp_concat: - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "add_expand_text: exp_concat\n"); /* Remove trailing whitespace from current expansion text */ while(curdef_idx) @@ -1036,12 +999,12 @@ static mtext_t *add_expand_text(mtext_t *mtp, macexpstackentry_t *mep, int *nnl) } mep->nnls[mtp->subst.argidx] = 0; } - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "add_expand_text: exp_subst(%d): '%s'\n", mtp->subst.argidx, exp); break; default: - internal_error(__FILE__, __LINE__, "Invalid expansion type (%d) in macro expansion\n", mtp->type); + pp_internal_error(__FILE__, __LINE__, "Invalid expansion type (%d) in macro expansion\n", mtp->type); } return mtp; } @@ -1064,11 +1027,11 @@ static void expand_macro(macexpstackentry_t *mep) for(n = 0; n < nargs; n++) nnl += mep->nnls[n]; - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "expand_macro(%d): %s:%d: '%s'(%d,%d) -> ...\n", macexpstackidx, - input_name, - line_number, + pp_status.input, + pp_status.line_number, ppp->ident, mep->nargs, nnl); @@ -1111,7 +1074,7 @@ static void expand_macro(macexpstackentry_t *mep) if(k - n > 0) { - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "expand_text: '%s'\n", curdef_text + n); push_buffer(ppp, NULL, NULL, 0); /*yy_scan_bytes(curdef_text + n, k - n);*/ @@ -1131,7 +1094,7 @@ static void new_string(void) ppwarning("new_string: strbuf_idx != 0"); #endif strbuf_idx = 0; - str_startline = line_number; + str_startline = pp_status.line_number; } static void add_string(char *str, int len) @@ -1141,7 +1104,7 @@ static void add_string(char *str, int len) if(strbuf_idx >= strbuf_alloc || strbuf_alloc - strbuf_idx < len) { strbuf_alloc += (len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1); - strbuffer = xrealloc(strbuffer, strbuf_alloc * sizeof(strbuffer[0])); + strbuffer = pp_xrealloc(strbuffer, strbuf_alloc * sizeof(strbuffer[0])); if(strbuf_alloc > 65536) ppwarning("Reallocating string buffer larger than 64kB"); } @@ -1151,7 +1114,7 @@ static void add_string(char *str, int len) static char *get_string(void) { - char *str = (char *)xmalloc(strbuf_idx + 1); + char *str = pp_xmalloc(strbuf_idx + 1); memcpy(str, strbuffer, strbuf_idx); str[strbuf_idx] = '\0'; #ifdef DEBUG @@ -1184,22 +1147,19 @@ static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop) if(ppdebug) printf("push_buffer(%d): %p %p %p %d\n", bufferstackidx, ppp, filename, incname, pop); if(bufferstackidx >= MAXBUFFERSTACK) - internal_error(__FILE__, __LINE__, "Buffer stack overflow"); + pp_internal_error(__FILE__, __LINE__, "Buffer stack overflow"); memset(&bufferstack[bufferstackidx], 0, sizeof(bufferstack[0])); bufferstack[bufferstackidx].bufferstate = YY_CURRENT_BUFFER; bufferstack[bufferstackidx].define = ppp; - bufferstack[bufferstackidx].line_number = line_number; - bufferstack[bufferstackidx].char_number = char_number; - bufferstack[bufferstackidx].if_depth = get_if_depth(); + bufferstack[bufferstackidx].line_number = pp_status.line_number; + bufferstack[bufferstackidx].char_number = pp_status.char_number; + bufferstack[bufferstackidx].if_depth = pp_get_if_depth(); bufferstack[bufferstackidx].should_pop = pop; - bufferstack[bufferstackidx].filename = input_name; + bufferstack[bufferstackidx].filename = pp_status.input; bufferstack[bufferstackidx].ncontinuations = ncontinuations; - bufferstack[bufferstackidx].include_state = include_state; - bufferstack[bufferstackidx].include_ppp = include_ppp; + bufferstack[bufferstackidx].incl = pp_incl_state; bufferstack[bufferstackidx].include_filename = incname; - bufferstack[bufferstackidx].include_ifdepth = include_ifdepth; - bufferstack[bufferstackidx].seen_junk = seen_junk; bufferstack[bufferstackidx].pass_data = pass_data; if(ppp) @@ -1207,20 +1167,20 @@ static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop) else if(filename) { /* These will track the pperror to the correct file and line */ - line_number = 1; - char_number = 1; - input_name = filename; + pp_status.line_number = 1; + pp_status.char_number = 1; + pp_status.input = filename; ncontinuations = 0; } else if(!pop) - internal_error(__FILE__, __LINE__, "Pushing buffer without knowing where to go to"); + pp_internal_error(__FILE__, __LINE__, "Pushing buffer without knowing where to go to"); bufferstackidx++; } static bufferstackentry_t *pop_buffer(void) { if(bufferstackidx < 0) - internal_error(__FILE__, __LINE__, "Bufferstack underflow?"); + pp_internal_error(__FILE__, __LINE__, "Bufferstack underflow?"); if(bufferstackidx == 0) return NULL; @@ -1231,41 +1191,39 @@ static bufferstackentry_t *pop_buffer(void) bufferstack[bufferstackidx].define->expanding = 0; else { - line_number = bufferstack[bufferstackidx].line_number; - char_number = bufferstack[bufferstackidx].char_number; - input_name = bufferstack[bufferstackidx].filename; + pp_status.line_number = bufferstack[bufferstackidx].line_number; + pp_status.char_number = bufferstack[bufferstackidx].char_number; + pp_status.input = bufferstack[bufferstackidx].filename; ncontinuations = bufferstack[bufferstackidx].ncontinuations; if(!bufferstack[bufferstackidx].should_pop) { fclose(ppin); - fprintf(ppout, "# %d \"%s\" 2\n", line_number, input_name); + fprintf(ppout, "# %d \"%s\" 2\n", pp_status.line_number, pp_status.input); /* We have EOF, check the include logic */ - if(include_state == 2 && !seen_junk && include_ppp) + if(pp_incl_state.state == 2 && !pp_incl_state.seen_junk && pp_incl_state.ppp) { - pp_entry_t *ppp = pplookup(include_ppp); + pp_entry_t *ppp = pplookup(pp_incl_state.ppp); if(ppp) { - includelogicentry_t *iep = xmalloc(sizeof(includelogicentry_t)); + includelogicentry_t *iep = pp_xmalloc(sizeof(includelogicentry_t)); iep->ppp = ppp; ppp->iep = iep; iep->filename = bufferstack[bufferstackidx].include_filename; - iep->next = includelogiclist; + iep->prev = NULL; + iep->next = pp_includelogiclist; if(iep->next) iep->next->prev = iep; - includelogiclist = iep; - if(debuglevel & DEBUGLEVEL_PPMSG) - fprintf(stderr, "pop_buffer: %s:%d: includelogic added, include_ppp='%s', file='%s'\n", input_name, line_number, include_ppp, iep->filename); + pp_includelogiclist = iep; + if(pp_status.debug) + fprintf(stderr, "pop_buffer: %s:%d: includelogic added, include_ppp='%s', file='%s'\n", pp_status.input, pp_status.line_number, pp_incl_state.ppp, iep->filename); } else if(bufferstack[bufferstackidx].include_filename) free(bufferstack[bufferstackidx].include_filename); } - if(include_ppp) - free(include_ppp); - include_state = bufferstack[bufferstackidx].include_state; - include_ppp = bufferstack[bufferstackidx].include_ppp; - include_ifdepth = bufferstack[bufferstackidx].include_ifdepth; - seen_junk = bufferstack[bufferstackidx].seen_junk; + if(pp_incl_state.ppp) + free(pp_incl_state.ppp); + pp_incl_state = bufferstack[bufferstackidx].incl; pass_data = bufferstack[bufferstackidx].pass_data; } @@ -1289,7 +1247,7 @@ static bufferstackentry_t *pop_buffer(void) if(yy_current_state() == pp_macexp) macro_add_expansion(); else - internal_error(__FILE__, __LINE__, "Pop buffer and state without macro expansion state"); + pp_internal_error(__FILE__, __LINE__, "Pop buffer and state without macro expansion state"); yy_pop_state(); } @@ -1307,8 +1265,8 @@ static void push_macro(pp_entry_t *ppp) if(macexpstackidx >= MAXMACEXPSTACK) pperror("Too many nested macros"); - macexpstack[macexpstackidx] = xmalloc(sizeof(macexpstack[0][0])); - + macexpstack[macexpstackidx] = pp_xmalloc(sizeof(macexpstack[0][0])); + memset( macexpstack[macexpstackidx], 0, sizeof(macexpstack[0][0])); macexpstack[macexpstackidx]->ppp = ppp; macexpstackidx++; } @@ -1321,7 +1279,7 @@ static macexpstackentry_t *top_macro(void) static macexpstackentry_t *pop_macro(void) { if(macexpstackidx <= 0) - internal_error(__FILE__, __LINE__, "Macro expansion stack underflow\n"); + pp_internal_error(__FILE__, __LINE__, "Macro expansion stack underflow\n"); return macexpstack[--macexpstackidx]; } @@ -1348,8 +1306,8 @@ static void add_text_to_macro(char *text, int len) if(mep->curargalloc - mep->curargsize <= len+1) /* +1 for '\0' */ { - mep->curargalloc += max(ALLOCBLOCKSIZE, len+1); - mep->curarg = xrealloc(mep->curarg, mep->curargalloc * sizeof(mep->curarg[0])); + mep->curargalloc += (ALLOCBLOCKSIZE > len+1) ? ALLOCBLOCKSIZE : len+1; + mep->curarg = pp_xrealloc(mep->curarg, mep->curargalloc * sizeof(mep->curarg[0])); } memcpy(mep->curarg + mep->curargsize, text, len); mep->curargsize += len; @@ -1364,10 +1322,10 @@ static void macro_add_arg(int last) assert(mep->ppp->expanding == 0); - mep->args = xrealloc(mep->args, (mep->nargs+1) * sizeof(mep->args[0])); - mep->ppargs = xrealloc(mep->ppargs, (mep->nargs+1) * sizeof(mep->ppargs[0])); - mep->nnls = xrealloc(mep->nnls, (mep->nargs+1) * sizeof(mep->nnls[0])); - mep->args[mep->nargs] = xstrdup(mep->curarg ? mep->curarg : ""); + mep->args = pp_xrealloc(mep->args, (mep->nargs+1) * sizeof(mep->args[0])); + mep->ppargs = pp_xrealloc(mep->ppargs, (mep->nargs+1) * sizeof(mep->ppargs[0])); + mep->nnls = pp_xrealloc(mep->nnls, (mep->nargs+1) * sizeof(mep->nnls[0])); + mep->args[mep->nargs] = pp_xstrdup(mep->curarg ? mep->curarg : ""); cptr = mep->args[mep->nargs]-1; while((cptr = strchr(cptr+1, '\n'))) { @@ -1379,10 +1337,10 @@ static void macro_add_arg(int last) mep->curargalloc = mep->curargsize = 0; mep->curarg = NULL; - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "macro_add_arg: %s:%d: %d -> '%s'\n", - input_name, - line_number, + pp_status.input, + pp_status.line_number, mep->nargs-1, mep->args[mep->nargs-1]); @@ -1402,15 +1360,15 @@ static void macro_add_expansion(void) assert(mep->ppp->expanding == 0); - mep->ppargs[mep->nargs-1] = xstrdup(mep->curarg ? mep->curarg : ""); + mep->ppargs[mep->nargs-1] = pp_xstrdup(mep->curarg ? mep->curarg : ""); free(mep->curarg); mep->curargalloc = mep->curargsize = 0; mep->curarg = NULL; - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "macro_add_expansion: %s:%d: %d -> '%s'\n", - input_name, - line_number, + pp_status.input, + pp_status.line_number, mep->nargs-1, mep->ppargs[mep->nargs-1]); } @@ -1437,7 +1395,7 @@ static void put_buffer(char *s, int len) * Include management *------------------------------------------------------------------------- */ -int is_c_h_include(char *fname) +static int is_c_h_include(char *fname) { int sl=strlen(fname); if (sl < 2) return 0; @@ -1446,13 +1404,13 @@ int is_c_h_include(char *fname) return 1; } -void do_include(char *fname, int type) +void pp_do_include(char *fname, int type) { char *newpath; int n; includelogicentry_t *iep; - for(iep = includelogiclist; iep; iep = iep->next) + for(iep = pp_includelogiclist; iep; iep = iep->next) { if(!strcmp(iep->filename, fname)) { @@ -1473,19 +1431,20 @@ void do_include(char *fname, int type) /* Undo the effect of the quotation */ fname[n-1] = '\0'; - if((ppin = open_include(fname+1, type, &newpath)) == NULL) + if((ppin = pp_open_include(fname+1, type, &newpath)) == NULL) pperror("Unable to open include file %s", fname+1); fname[n-1] = *fname; /* Redo the quotes */ push_buffer(NULL, newpath, fname, 0); - seen_junk = 0; - include_state = 0; - include_ppp = NULL; + pp_incl_state.seen_junk = 0; + pp_incl_state.state = 0; + pp_incl_state.ppp = NULL; if (is_c_h_include(newpath)) pass_data=0; else pass_data=1; - if(debuglevel & DEBUGLEVEL_PPMSG) - fprintf(stderr, "do_include: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d ,pass_data=%d\n", input_name, line_number, include_state, include_ppp, include_ifdepth,pass_data); + if(pp_status.debug) + fprintf(stderr, "pp_do_include: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d ,pass_data=%d\n", + pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth, pass_data); pp_switch_to_buffer(pp_create_buffer(ppin, YY_BUF_SIZE)); fprintf(ppout, "# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3"); @@ -1497,12 +1456,12 @@ void do_include(char *fname, int type) * which are false. *------------------------------------------------------------------------- */ -void push_ignore_state(void) +void pp_push_ignore_state(void) { yy_push_state(pp_ignore); } -void pop_ignore_state(void) +void pp_pop_ignore_state(void) { yy_pop_state(); } diff --git a/tools/wrc/ppy.y b/tools/wpp/ppy.y similarity index 86% rename from tools/wrc/ppy.y rename to tools/wpp/ppy.y index 099a12ba734..8186be5bfb7 100644 --- a/tools/wrc/ppy.y +++ b/tools/wpp/ppy.y @@ -38,10 +38,7 @@ #include #include -#include "utils.h" -#include "newstruc.h" -#include "wrc.h" -#include "preproc.h" +#include "wpp_private.h" #define UNARY_OP(r, v, OP) \ @@ -96,7 +93,7 @@ case SIZE_INT: BIN_OP_INT(r, v1, v2, OP); break; \ case SIZE_LONG: BIN_OP_LONG(r, v1, v2, OP); break; \ case SIZE_LONGLONG: BIN_OP_LONGLONG(r, v1, v2, OP); break; \ - default: internal_error(__FILE__, __LINE__, "Invalid type indicator (0x%04x)", v1.type); \ + default: pp_internal_error(__FILE__, __LINE__, "Invalid type indicator (0x%04x)", v1.type); \ } @@ -186,91 +183,93 @@ pp_file : /* Empty */ ; preprocessor - : tINCLUDE tDQSTRING tNL { do_include($2, 1); } - | tINCLUDE tIQSTRING tNL { do_include($2, 0); } - | tIF pp_expr tNL { next_if_state(boolean(&$2)); } - | tIFDEF tIDENT tNL { next_if_state(pplookup($2) != NULL); free($2); } + : tINCLUDE tDQSTRING tNL { pp_do_include($2, 1); } + | tINCLUDE tIQSTRING tNL { pp_do_include($2, 0); } + | tIF pp_expr tNL { pp_next_if_state(boolean(&$2)); } + | tIFDEF tIDENT tNL { pp_next_if_state(pplookup($2) != NULL); free($2); } | tIFNDEF tIDENT tNL { int t = pplookup($2) == NULL; - if(include_state == 0 && t && !seen_junk) + if(pp_incl_state.state == 0 && t && !pp_incl_state.seen_junk) { - include_state = 1; - include_ppp = $2; - include_ifdepth = get_if_depth(); + pp_incl_state.state = 1; + pp_incl_state.ppp = $2; + pp_incl_state.ifdepth = pp_get_if_depth(); } - else if(include_state != 1) + else if(pp_incl_state.state != 1) { - include_state = -1; + pp_incl_state.state = -1; free($2); } else free($2); - next_if_state(t); - if(debuglevel & DEBUGLEVEL_PPMSG) - fprintf(stderr, "tIFNDEF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n", input_name, line_number, include_state, include_ppp, include_ifdepth); + pp_next_if_state(t); + if(pp_status.debug) + fprintf(stderr, "tIFNDEF: %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); } | tELIF pp_expr tNL { - if_state_t s = pop_if(); + pp_if_state_t s = pp_pop_if(); switch(s) { case if_true: case if_elif: - push_if(if_elif); + pp_push_if(if_elif); break; case if_false: - push_if(boolean(&$2) ? if_true : if_false); + pp_push_if(boolean(&$2) ? if_true : if_false); break; case if_ignore: - push_if(if_ignore); + pp_push_if(if_ignore); break; case if_elsetrue: case if_elsefalse: pperror("#elif cannot follow #else"); default: - internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #elif directive", s); + pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #elif directive", s); } } | tELSE tNL { - if_state_t s = pop_if(); + pp_if_state_t s = pp_pop_if(); switch(s) { case if_true: - push_if(if_elsefalse); + pp_push_if(if_elsefalse); break; case if_elif: - push_if(if_elif); + pp_push_if(if_elif); break; case if_false: - push_if(if_elsetrue); + pp_push_if(if_elsetrue); break; case if_ignore: - push_if(if_ignore); + pp_push_if(if_ignore); break; case if_elsetrue: case if_elsefalse: pperror("#else clause already defined"); default: - internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #else directive", s); + pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #else directive", s); } } | tENDIF tNL { - pop_if(); - if(include_ifdepth == get_if_depth() && include_state == 1) + pp_pop_if(); + if(pp_incl_state.ifdepth == pp_get_if_depth() && pp_incl_state.state == 1) { - include_state = 2; - seen_junk = 0; + pp_incl_state.state = 2; + pp_incl_state.seen_junk = 0; } - else if(include_state != 1) + else if(pp_incl_state.state != 1) { - include_state = -1; + pp_incl_state.state = -1; } - if(debuglevel & DEBUGLEVEL_PPMSG) - fprintf(stderr, "tENDIF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n", input_name, line_number, include_state, include_ppp, include_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 { del_define($2); free($2); } - | tDEFINE opt_text tNL { add_define($1, $2); } + | tUNDEF tIDENT tNL { pp_del_define($2); free($2); } + | tDEFINE opt_text tNL { pp_add_define($1, $2); } | tMACRO res_arg allmargs tMACROEND opt_mtexts tNL { - add_macro($1, macro_args, nmacro_args, $5); + pp_add_macro($1, macro_args, nmacro_args, $5); } | tLINE tSINT tDQSTRING tNL { fprintf(ppout, "# %d %s\n", $2 , $3); free($3); } | tGCCLINE tSINT tDQSTRING tNL { fprintf(ppout, "# %d %s\n", $2 , $3); free($3); } @@ -285,17 +284,17 @@ preprocessor | tGCCLINE tNL /* The null-token */ | tERROR opt_text tNL { pperror("#error directive: '%s'", $2); if($2) free($2); } | tWARNING opt_text tNL { ppwarning("#warning directive: '%s'", $2); if($2) free($2); } - | tPRAGMA opt_text tNL { if(pedantic) ppwarning("#pragma ignored (arg: '%s')", $2); if($2) free($2); } - | tPPIDENT opt_text tNL { if(pedantic) ppwarning("#ident ignored (arg: '%s')", $2); if($2) free($2); } + | tPRAGMA opt_text tNL { if(pp_status.pedantic) ppwarning("#pragma ignored (arg: '%s')", $2); if($2) free($2); } + | tPPIDENT opt_text tNL { if(pp_status.pedantic) ppwarning("#ident ignored (arg: '%s')", $2); if($2) free($2); } | tRCINCLUDE tRCINCLUDEPATH { int nl=strlen($2) +3; - char *fn=xmalloc(nl); - snprintf(fn,nl,"\"%s\"",$2); + char *fn=pp_xmalloc(nl); + sprintf(fn,"\"%s\"",$2); free($2); - do_include(fn,1); + pp_do_include(fn,1); } | tRCINCLUDE tDQSTRING { - do_include($2,1); + pp_do_include($2,1); } /*| tNL*/ ; @@ -537,9 +536,10 @@ static int boolean(cval_t *v) static marg_t *new_marg(char *str, def_arg_t type) { - marg_t *ma = (marg_t *)xmalloc(sizeof(marg_t)); + marg_t *ma = pp_xmalloc(sizeof(marg_t)); ma->arg = str; ma->type = type; + ma->nnl = 0; return ma; } @@ -547,7 +547,7 @@ static marg_t *add_new_marg(char *str, def_arg_t type) { marg_t *ma = new_marg(str, type); nmacro_args++; - macro_args = (marg_t **)xrealloc(macro_args, nmacro_args * sizeof(macro_args[0])); + macro_args = pp_xrealloc(macro_args, nmacro_args * sizeof(macro_args[0])); macro_args[nmacro_args-1] = ma; return ma; } @@ -565,12 +565,13 @@ static int marg_index(char *id) static mtext_t *new_mtext(char *str, int idx, def_exp_t type) { - mtext_t *mt = (mtext_t *)xmalloc(sizeof(mtext_t)); + mtext_t *mt = pp_xmalloc(sizeof(mtext_t)); if(str == NULL) mt->subst.argidx = idx; else mt->subst.text = str; mt->type = type; + mt->next = mt->prev = NULL; return mt; } @@ -584,7 +585,7 @@ static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp) if(tail->type == exp_text && mtp->type == exp_text) { - tail->subst.text = xrealloc(tail->subst.text, strlen(tail->subst.text)+strlen(mtp->subst.text)+1); + tail->subst.text = pp_xrealloc(tail->subst.text, strlen(tail->subst.text)+strlen(mtp->subst.text)+1); strcat(tail->subst.text, mtp->subst.text); free(mtp->subst.text); free(mtp); @@ -650,7 +651,7 @@ static char *merge_text(char *s1, char *s2) { int l1 = strlen(s1); int l2 = strlen(s2); - s1 = xrealloc(s1, l1+l2+1); + s1 = pp_xrealloc(s1, l1+l2+1); memcpy(s1+l1, s2, l2+1); free(s2); return s1; diff --git a/tools/wrc/preproc.c b/tools/wpp/preproc.c similarity index 55% rename from tools/wrc/preproc.c rename to tools/wpp/preproc.c index 8fda4ce8b19..8978c251232 100644 --- a/tools/wrc/preproc.c +++ b/tools/wpp/preproc.c @@ -18,21 +18,23 @@ #include "config.h" +#include +#include #include #include #include -#include +#include +#include -#include "wrc.h" -#include "utils.h" -#include "preproc.h" +#include "wpp_private.h" +struct pp_status pp_status; #define HASHKEY 2039 static pp_entry_t *pp_defines[HASHKEY]; #define MAXIFSTACK 64 -static if_state_t if_stack[MAXIFSTACK]; +static pp_if_state_t if_stack[MAXIFSTACK]; static int if_stack_idx = 0; #if 0 @@ -57,6 +59,43 @@ void pp_status(void) } #endif +void *pp_xmalloc(size_t size) +{ + void *res; + + assert(size > 0); + res = malloc(size); + if(res == NULL) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + exit(2); + } + return res; +} + +void *pp_xrealloc(void *p, size_t size) +{ + void *res; + + assert(size > 0); + res = realloc(p, size); + if(res == NULL) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + exit(2); + } + return res; +} + +char *pp_xstrdup(const char *str) +{ + char *s; + + assert(str != NULL); + s = pp_xmalloc(strlen(str)+1); + return strcpy(s, str); +} + /* Don't comment on the hash, its primitive but functional... */ int pphash(char *str) { @@ -79,27 +118,27 @@ pp_entry_t *pplookup(char *ident) return NULL; } -void del_define(char *name) +void pp_del_define(char *name) { int idx; pp_entry_t *ppp; if((ppp = pplookup(name)) == NULL) { - if(pedantic) - yywarning("%s was not defined", name); + if(pp_status.pedantic) + ppwarning("%s was not defined", name); return; } if(ppp->iep) { - if(debuglevel & DEBUGLEVEL_PPMSG) - fprintf(stderr, "del_define: %s:%d: includelogic removed, include_ppp='%s', file=%s\n", input_name, line_number, name, ppp->iep->filename); - if(ppp->iep == includelogiclist) + if(pp_status.debug) + fprintf(stderr, "pp_del_define: %s:%d: includelogic removed, include_ppp='%s', file=%s\n", pp_status.input, pp_status.line_number, name, ppp->iep->filename); + if(ppp->iep == pp_includelogiclist) { - includelogiclist = ppp->iep->next; - if(includelogiclist) - includelogiclist->prev = NULL; + pp_includelogiclist = ppp->iep->next; + if(pp_includelogiclist) + pp_includelogiclist->prev = NULL; } else { @@ -127,11 +166,11 @@ void del_define(char *name) free(ppp); - if(debuglevel & DEBUGLEVEL_PPMSG) - printf("Deleted (%s, %d) <%s>\n", input_name, line_number, name); + if(pp_status.debug) + printf("Deleted (%s, %d) <%s>\n", pp_status.input, pp_status.line_number, name); } -pp_entry_t *add_define(char *def, char *text) +pp_entry_t *pp_add_define(char *def, char *text) { int len; char *cptr; @@ -140,16 +179,17 @@ pp_entry_t *add_define(char *def, char *text) if((ppp = pplookup(def)) != NULL) { - if(pedantic) - yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber); - del_define(def); + if(pp_status.pedantic) + ppwarning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber); + pp_del_define(def); } - ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t)); + ppp = pp_xmalloc(sizeof(pp_entry_t)); + memset( ppp, 0, sizeof(*ppp) ); ppp->ident = def; ppp->type = def_define; ppp->subst.text = text; - ppp->filename = input_name ? xstrdup(input_name) : ""; - ppp->linenumber = input_name ? line_number : 0; + ppp->filename = pp_status.input ? pp_xstrdup(pp_status.input) : ""; + ppp->linenumber = pp_status.input ? pp_status.line_number : 0; ppp->next = pp_defines[idx]; pp_defines[idx] = ppp; if(ppp->next) @@ -168,55 +208,40 @@ pp_entry_t *add_define(char *def, char *text) if(text != cptr) memmove(text, cptr, strlen(cptr)+1); } - if(debuglevel & DEBUGLEVEL_PPMSG) - printf("Added define (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, text ? text : "(null)"); + if(pp_status.debug) + printf("Added define (%s, %d) <%s> to <%s>\n", pp_status.input, pp_status.line_number, ppp->ident, text ? text : "(null)"); return ppp; } -pp_entry_t *add_cmdline_define(char *set) -{ - char *cpy = xstrdup(set); /* Because gcc passes a R/O string */ - char *cptr = strchr(cpy, '='); - if(cptr) - *cptr = '\0'; - return add_define(cpy, xstrdup(cptr ? cptr+1 : "")); -} - -pp_entry_t *add_special_define(char *id) -{ - pp_entry_t *ppp = add_define(xstrdup(id), xstrdup("")); - ppp->type = def_special; - return ppp; -} - -pp_entry_t *add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp) +pp_entry_t *pp_add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp) { int idx = pphash(id); pp_entry_t *ppp; if((ppp = pplookup(id)) != NULL) { - if(pedantic) - yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber); - del_define(id); + if(pp_status.pedantic) + ppwarning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber); + pp_del_define(id); } - ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t)); + ppp = pp_xmalloc(sizeof(pp_entry_t)); + memset( ppp, 0, sizeof(*ppp) ); ppp->ident = id; ppp->type = def_macro; ppp->margs = args; ppp->nargs = nargs; ppp->subst.mtext= exp; - ppp->filename = input_name ? xstrdup(input_name) : ""; - ppp->linenumber = input_name ? line_number : 0; + ppp->filename = pp_status.input ? pp_xstrdup(pp_status.input) : ""; + ppp->linenumber = pp_status.input ? pp_status.line_number : 0; ppp->next = pp_defines[idx]; pp_defines[idx] = ppp; if(ppp->next) ppp->next->prev = ppp; - if(debuglevel & DEBUGLEVEL_PPMSG) + if(pp_status.debug) { - fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", input_name, line_number, ppp->ident, nargs); + fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", pp_status.input, pp_status.line_number, ppp->ident, nargs); for(; exp; exp = exp->next) { switch(exp->type) @@ -255,10 +280,10 @@ pp_entry_t *add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp) static char **includepath; static int nincludepath = 0; -void add_include_path(char *path) +void wpp_add_include_path(const char *path) { char *tok; - char *cpy = xstrdup(path); + char *cpy = pp_xstrdup(path); tok = strtok(cpy, INCLUDESEPARATOR); while(tok) @@ -267,7 +292,7 @@ void add_include_path(char *path) char *cptr; if(strlen(tok) == 0) continue; - dir = xstrdup(tok); + dir = pp_xstrdup(tok); for(cptr = dir; *cptr; cptr++) { /* Convert to forward slash */ @@ -280,71 +305,78 @@ void add_include_path(char *path) /* Add to list */ nincludepath++; - includepath = (char **)xrealloc(includepath, nincludepath * sizeof(*includepath)); + includepath = pp_xrealloc(includepath, nincludepath * sizeof(*includepath)); includepath[nincludepath-1] = dir; tok = strtok(NULL, INCLUDESEPARATOR); } free(cpy); } -FILE *open_include(const char *name, int search, char **newpath) +char *wpp_find_include(const char *name, int search) { - char *cpy = xstrdup(name); - char *cptr; - FILE *fp; - int i; + char *cpy = pp_xstrdup(name); + char *cptr; + int i, fd; - for(cptr = cpy; *cptr; cptr++) - { - /* kill double backslash */ - if(*cptr == '\\' && *(cptr+1) == '\\') - memmove(cptr, cptr+1, strlen(cptr)); - /* Convert to forward slash */ - if(*cptr == '\\') - *cptr = '/'; - } + for(cptr = cpy; *cptr; cptr++) + { + /* kill double backslash */ + if(*cptr == '\\' && *(cptr+1) == '\\') + memmove(cptr, cptr+1, strlen(cptr)); + /* Convert to forward slash */ + if(*cptr == '\\') + *cptr = '/'; + } - if(search) - { - /* Search current dir and then -I path */ - fp = fopen(cpy, "rt"); - if(fp) - { - if(debuglevel & DEBUGLEVEL_PPMSG) - printf("Going to include <%s>\n", name); - if(newpath) - *newpath = cpy; - else - free(cpy); - return fp; - } - } - /* Search -I path */ - for(i = 0; i < nincludepath; i++) - { - char *path; - path = (char *)xmalloc(strlen(includepath[i]) + strlen(cpy) + 2); - strcpy(path, includepath[i]); - strcat(path, "/"); - strcat(path, cpy); - fp = fopen(path, "rt"); - if(fp && (debuglevel & DEBUGLEVEL_PPMSG)) - printf("Going to include <%s>\n", path); - if(fp) - { - if(newpath) - *newpath = path; - else - free(path); - free(cpy); - return fp; - } - free(path); - } - free(cpy); - if(newpath) - *newpath = NULL; - return NULL; + if(search) + { + /* Search current dir and then -I path */ + fd = open( cpy, O_RDONLY ); + if (fd != -1) + { + close( fd ); + return cpy; + } + } + /* Search -I path */ + for(i = 0; i < nincludepath; i++) + { + char *path; + path = pp_xmalloc(strlen(includepath[i]) + strlen(cpy) + 2); + strcpy(path, includepath[i]); + strcat(path, "/"); + strcat(path, cpy); + fd = open( path, O_RDONLY ); + if (fd != -1) + { + close( fd ); + free( cpy ); + return path; + } + free( path ); + } + free( cpy ); + return NULL; +} + +FILE *pp_open_include(const char *name, int search, char **newpath) +{ + char *path; + FILE *fp; + + if (!(path = wpp_find_include( name, search ))) return NULL; + fp = fopen(path, "rt"); + + if (fp) + { + if (pp_status.debug) + printf("Going to include <%s>\n", path); + if (newpath) *newpath = path; + else free( path ); + return fp; + } + free( path ); + return NULL; } /* @@ -395,7 +427,7 @@ FILE *open_include(const char *name, int search, char **newpath) * *------------------------------------------------------------------------- */ -static char *if_state_str[] = { +static char *pp_if_state_str[] = { "if_false", "if_true", "if_elif", @@ -404,13 +436,13 @@ static char *if_state_str[] = { "if_ignore" }; -void push_if(if_state_t s) +void pp_push_if(pp_if_state_t s) { if(if_stack_idx >= MAXIFSTACK) - internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK); + pp_internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK); - if(debuglevel & DEBUGLEVEL_PPLEX) - fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", input_name, line_number, if_state_str[if_state()], if_stack_idx, if_state_str[s], if_stack_idx+1); + if(pp_flex_debug) + fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", pp_status.input, pp_status.line_number, pp_if_state_str[pp_if_state()], if_stack_idx, pp_if_state_str[s], if_stack_idx+1); if_stack[if_stack_idx++] = s; @@ -423,17 +455,17 @@ void push_if(if_state_t s) case if_elsefalse: case if_elif: case if_ignore: - push_ignore_state(); + pp_push_ignore_state(); break; } } -if_state_t pop_if(void) +pp_if_state_t pp_pop_if(void) { if(if_stack_idx <= 0) - yyerror("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)"); + pperror("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)"); - switch(if_state()) + switch(pp_if_state()) { case if_true: case if_elsetrue: @@ -442,23 +474,23 @@ if_state_t pop_if(void) case if_elsefalse: case if_elif: case if_ignore: - pop_ignore_state(); + pp_pop_ignore_state(); break; } - if(debuglevel & DEBUGLEVEL_PPLEX) + if(pp_flex_debug) fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n", - input_name, - line_number, - if_state_str[if_state()], + pp_status.input, + pp_status.line_number, + pp_if_state_str[pp_if_state()], if_stack_idx, - if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]], + pp_if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]], if_stack_idx-1); return if_stack[--if_stack_idx]; } -if_state_t if_state(void) +pp_if_state_t pp_if_state(void) { if(!if_stack_idx) return if_true; @@ -467,27 +499,78 @@ if_state_t if_state(void) } -void next_if_state(int i) +void pp_next_if_state(int i) { - switch(if_state()) + switch(pp_if_state()) { case if_true: case if_elsetrue: - push_if(i ? if_true : if_false); + pp_push_if(i ? if_true : if_false); break; case if_false: case if_elsefalse: case if_elif: case if_ignore: - push_if(if_ignore); + pp_push_if(if_ignore); break; default: - internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #{if,ifdef,ifndef} directive", (int)if_state()); + pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #{if,ifdef,ifndef} directive", (int)pp_if_state()); } } -int get_if_depth(void) +int pp_get_if_depth(void) { return if_stack_idx; } +/* #define WANT_NEAR_INDICATION */ + +static void generic_msg(const char *s, const char *t, const char *n, va_list ap) +{ + fprintf(stderr, "%s:%d:%d: %s: ", pp_status.input ? pp_status.input : "stdin", + pp_status.line_number, pp_status.char_number, t); + vfprintf(stderr, s, ap); +#ifdef WANT_NEAR_INDICATION + { + char *cpy, *p; + if(n) + { + cpy = pp_xstrdup(n); + for (p = cpy; *p; p++) if(!isprint(*p)) *p = ' '; + fprintf(stderr, " near '%s'", cpy); + free(cpy); + } + } +#endif + fprintf(stderr, "\n"); +} + +int pperror(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + generic_msg(s, "Error", pptext, ap); + va_end(ap); + exit(1); + return 1; +} + +int ppwarning(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + generic_msg(s, "Warning", pptext, ap); + va_end(ap); + return 0; +} + +void pp_internal_error(const char *file, int line, const char *s, ...) +{ + va_list ap; + va_start(ap, s); + fprintf(stderr, "Internal error (please report) %s %d: ", file, line); + vfprintf(stderr, s, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(3); +} diff --git a/tools/wpp/wpp.c b/tools/wpp/wpp.c new file mode 100644 index 00000000000..239734bd2a5 --- /dev/null +++ b/tools/wpp/wpp.c @@ -0,0 +1,131 @@ +/* + * Exported functions of the Wine preprocessor + * + * Copyrignt 1998 Bertho A. Stultiens + * Copyright 2002 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "wpp_private.h" +#include "wpp.h" + +static void add_special_defines(void) +{ + time_t now = time(NULL); + pp_entry_t *ppp; + char buf[32]; + + strftime(buf, sizeof(buf), "\"%b %d %Y\"", localtime(&now)); + pp_add_define( pp_xstrdup("__DATE__"), pp_xstrdup(buf) ); + + strftime(buf, sizeof(buf), "\"%H:%M:%S\"", localtime(&now)); + pp_add_define( pp_xstrdup("__TIME__"), pp_xstrdup(buf) ); + + ppp = pp_add_define( pp_xstrdup("__FILE__"), pp_xstrdup("") ); + ppp->type = def_special; + + ppp = pp_add_define( pp_xstrdup("__LINE__"), pp_xstrdup("") ); + ppp->type = def_special; +} + + +/* add a define to the preprocessor list */ +void wpp_add_define( const char *name, const char *value ) +{ + if (!value) value = ""; + pp_add_define( pp_xstrdup(name), pp_xstrdup(value) ); +} + + +/* add a command-line define of the form NAME=VALUE */ +void wpp_add_cmdline_define( const char *value ) +{ + char *str = pp_xstrdup(value); + char *p = strchr( str, '=' ); + if (p) *p++ = 0; + else p = ""; + pp_add_define( str, pp_xstrdup(p) ); +} + + +/* set the various debug flags */ +void wpp_set_debug( int lex_debug, int parser_debug, int msg_debug ) +{ + pp_flex_debug = lex_debug; + ppdebug = parser_debug; + pp_status.debug = msg_debug; +} + + +/* set the pedantic mode */ +void wpp_set_pedantic( int on ) +{ + pp_status.pedantic = on; +} + + +/* the main preprocessor parsing loop */ +int wpp_parse( const char *input, FILE *output ) +{ + int ret; + + add_special_defines(); + + if (!input) ppin = stdin; + else if (!(ppin = fopen(input, "rt"))) + { + fprintf(stderr,"Could not open %s\n", input); + exit(2); + } + + pp_status.input = input; + + ppout = output; + fprintf(ppout, "# 1 \"%s\" 1\n", input ? input : ""); + + ret = ppparse(); + + if (input) fclose(ppin); + return ret; +} + + +/* parse into a temporary file */ +int wpp_parse_temp( const char *input, char **output_name ) +{ + char *temp_name; + FILE *output; + int ret; + + if(!(temp_name = tmpnam(NULL))) + { + fprintf(stderr, "Could not generate a temp-name\n"); + temp_name = pp_xstrdup(temp_name); + } + + if (!(output = fopen(temp_name, "wt"))) + { + fprintf(stderr,"Could not open %s for writing\n", temp_name); + exit(2); + } + + *output_name = temp_name; + ret = wpp_parse( input, output ); + fclose( output ); + return ret; +} diff --git a/tools/wpp/wpp.h b/tools/wpp/wpp.h new file mode 100644 index 00000000000..1815ad6a467 --- /dev/null +++ b/tools/wpp/wpp.h @@ -0,0 +1,35 @@ +/* + * Exported functions of the Wine preprocessor + * + * Copyright 2002 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __WINE_WPP_H +#define __WINE_WPP_H + +#include + +extern void wpp_add_define( const char *name, const char *value ); +extern void wpp_add_cmdline_define( const char *value ); +extern void wpp_set_debug( int lex_debug, int parser_debug, int msg_debug ); +extern void wpp_set_pedantic( int on ); +extern void wpp_add_include_path( const char *path ); +extern char *wpp_find_include( const char *name, int search ); +extern int wpp_parse( const char *input, FILE *output ); +extern int wpp_parse_temp( const char *input, char **output_name ); + +#endif /* __WINE_WPP_H */ diff --git a/tools/wrc/preproc.h b/tools/wpp/wpp_private.h similarity index 67% rename from tools/wrc/preproc.h rename to tools/wpp/wpp_private.h index 0573e394cf4..19b7e51c262 100644 --- a/tools/wrc/preproc.h +++ b/tools/wpp/wpp_private.h @@ -1,5 +1,6 @@ /* * Copyright 1998 Bertho A. Stultiens (BS) + * Copyright 2002 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,8 +17,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __WRC_PREPROC_H -#define __WRC_PREPROC_H +#ifndef __WINE_WPP_PRIVATE_H +#define __WINE_WPP_PRIVATE_H + +#include +#include struct pp_entry; /* forward */ /* @@ -106,7 +110,27 @@ typedef enum { if_elsefalse, if_elsetrue, if_ignore -} if_state_t; +} pp_if_state_t; + + +/* + * Trace the include files to prevent double reading. + * This save 20..30% of processing time for most stuff + * that uses complex includes. + * States: + * -1 Don't track or seen junk + * 0 New include, waiting for "#ifndef __xxx_h" + * 1 Seen #ifndef, waiting for "#define __xxx_h ..." + * 2 Seen #endif, waiting for EOF + */ +typedef struct +{ + int state; + char *ppp; /* The define to be set from the #ifndef */ + int ifdepth; /* The level of ifs at the #ifdef */ + int seen_junk; /* Set when junk is seen */ +} include_state_t; + /* * I assume that 'long long' exists in the compiler when it has a size @@ -167,19 +191,42 @@ typedef struct cval { +void *pp_xmalloc(size_t); +void *pp_xrealloc(void *, size_t); +char *pp_xstrdup(const char *str); pp_entry_t *pplookup(char *ident); -pp_entry_t *add_define(char *def, char *text); -pp_entry_t *add_cmdline_define(char *set); -pp_entry_t *add_special_define(char *id); -pp_entry_t *add_macro(char *ident, marg_t *args[], int nargs, mtext_t *exp); -void del_define(char *name); -FILE *open_include(const char *name, int search, char **newpath); -void add_include_path(char *path); -void push_if(if_state_t s); -void next_if_state(int); -if_state_t pop_if(void); -if_state_t if_state(void); -int get_if_depth(void); +pp_entry_t *pp_add_define(char *def, char *text); +pp_entry_t *pp_add_macro(char *ident, marg_t *args[], int nargs, mtext_t *exp); +void pp_del_define(char *name); +FILE *pp_open_include(const char *name, int search, char **newpath); +void pp_push_if(pp_if_state_t s); +void pp_next_if_state(int); +pp_if_state_t pp_pop_if(void); +pp_if_state_t pp_if_state(void); +int pp_get_if_depth(void); + +#ifndef __GNUC__ +#define __attribute__(x) /*nothing*/ +#endif + +int pperror(const char *s, ...) __attribute__((format (printf, 1, 2))); +int ppwarning(const char *s, ...) __attribute__((format (printf, 1, 2))); +void pp_internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4))); + +/* current preprocessor state */ +/* everything is in this structure to avoid polluting the global symbol space */ +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 pedantic; /* pedantic option */ + int debug; /* debug messages flag */ +}; + +extern struct pp_status pp_status; +extern include_state_t pp_incl_state; +extern includelogicentry_t *pp_includelogiclist; /* * From ppl.l @@ -190,16 +237,10 @@ extern char *pptext; extern int pp_flex_debug; int pplex(void); -void do_include(char *fname, int type); -void push_ignore_state(void); -void pop_ignore_state(void); +void pp_do_include(char *fname, int type); +void pp_push_ignore_state(void); +void pp_pop_ignore_state(void); -extern int include_state; -extern char *include_ppp; -extern char *include_filename; -extern int include_ifdepth; -extern int seen_junk; -extern includelogicentry_t *includelogiclist; /* * From ppy.y @@ -207,5 +248,4 @@ extern includelogicentry_t *includelogiclist; int ppparse(void); extern int ppdebug; -#endif - +#endif /* __WINE_WPP_PRIVATE_H */ diff --git a/tools/wrc/.cvsignore b/tools/wrc/.cvsignore index 5bb0841ebc7..3604ec717d8 100644 --- a/tools/wrc/.cvsignore +++ b/tools/wrc/.cvsignore @@ -1,13 +1,7 @@ Makefile -lex.ppl.c lex.yy.c -ppy.tab.c -ppy.tab.h wrc y.tab.c y.tab.h -ppy.tab.c -ppy.tab.h y.output -ppy.output lex.backup diff --git a/tools/wrc/Makefile.in b/tools/wrc/Makefile.in index a101e781ac4..8cbd6f6c06b 100644 --- a/tools/wrc/Makefile.in +++ b/tools/wrc/Makefile.in @@ -6,6 +6,8 @@ VPATH = @srcdir@ LEXOPT = -Cf #-w -b YACCOPT = #-v EXEEXT = @EXEEXT@ +EXTRAINCL = -I$(TOPSRCDIR)/tools/wpp +EXTRALIBS = -L$(TOPOBJDIR)/tools/wpp -lwpp PROGRAMS = wrc$(EXEEXT) MODULE = none @@ -14,13 +16,11 @@ C_SRCS = \ dumpres.c \ genres.c \ newstruc.c \ - preproc.c \ readres.c \ utils.c \ wrc.c \ writeres.c -GEN_C_SRCS = ppy.tab.c lex.ppl.c EXTRA_SRCS = parser.y parser.l EXTRA_OBJS = y.tab.o @LEX_OUTPUT_ROOT@.o @@ -28,26 +28,20 @@ all: $(PROGRAMS) @MAKE_RULES@ -wrc: $(OBJS) - $(CC) $(CFLAGS) -o wrc $(OBJS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) $(LDFLAGS) +wrc: $(OBJS) $(TOPOBJDIR)/tools/wpp/libwpp.a + $(CC) $(CFLAGS) -o wrc $(OBJS) $(EXTRALIBS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) $(LDFLAGS) -wrc.exe: $(OBJS) - $(CC) $(CFLAGS) -o wrc.exe $(OBJS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) -liberty $(LDFLAGS) +wrc.exe: $(OBJS) $(TOPOBJDIR)/tools/wpp/libwpp.a + $(CC) $(CFLAGS) -o wrc.exe $(OBJS) $(EXTRALIBS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) -liberty $(LDFLAGS) y.tab.c y.tab.h: parser.y $(YACC) $(YACCOPT) -d -t $(SRCDIR)/parser.y -ppy.tab.c ppy.tab.h: ppy.y - $(YACC) $(YACCOPT) -bppy -ppp -d -t $(SRCDIR)/ppy.y - @LEX_OUTPUT_ROOT@.c: parser.l $(LEX) $(LEXOPT) -d -8 $(SRCDIR)/parser.l -lex.ppl.c: ppl.l - $(LEX) $(LEXOPT) -d -Ppp -8 -olex.ppl.c $(SRCDIR)/ppl.l - clean:: - $(RM) ppy.tab.h ppy.output parser.output parser.tab.h lex.backup y.output + $(RM) parser.output parser.tab.h lex.backup y.output install:: $(PROGRAMS) $(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext) diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l index d2544022f53..0e5329cdb8c 100644 --- a/tools/wrc/parser.l +++ b/tools/wrc/parser.l @@ -102,7 +102,6 @@ cident [a-zA-Z_][0-9a-zA-Z_]* #include "wrc.h" #include "utils.h" -#include "preproc.h" #include "parser.h" #include "newstruc.h" diff --git a/tools/wrc/parser.y b/tools/wrc/parser.y index 4ad3bd71663..7cdcb827bb0 100644 --- a/tools/wrc/parser.y +++ b/tools/wrc/parser.y @@ -136,7 +136,7 @@ #include "utils.h" #include "newstruc.h" #include "dumpres.h" -#include "preproc.h" +#include "wpp.h" #include "parser.h" #include "windef.h" #include "winbase.h" @@ -2278,14 +2278,17 @@ static itemex_opt_t *new_itemex_opt(int id, int type, int state, int helpid) /* Raw data functions */ static raw_data_t *load_file(string_t *name) { - FILE *fp; + FILE *fp = NULL; + char *path; raw_data_t *rd; if(name->type != str_char) yyerror("Filename must be ASCII string"); - fp = open_include(name->str.cstr, 1, NULL); - if(!fp) + if (!(path = wpp_find_include(name->str.cstr, 1))) yyerror("Cannot open file %s", name->str.cstr); + if (!(fp = fopen( path, "rb" ))) + yyerror("Cannot open file %s", name->str.cstr); + free( path ); rd = new_raw_data(); fseek(fp, 0, SEEK_END); rd->size = ftell(fp); diff --git a/tools/wrc/utils.c b/tools/wrc/utils.c index d8db7a6fac6..ab13429a21b 100644 --- a/tools/wrc/utils.c +++ b/tools/wrc/utils.c @@ -33,7 +33,6 @@ #include "wrc.h" #include "utils.h" #include "parser.h" -#include "preproc.h" /* #define WANT_NEAR_INDICATION */ @@ -90,26 +89,6 @@ int yywarning(const char *s, ...) return 0; } -int pperror(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - generic_msg(s, "Error", pptext, ap); - va_end(ap); - exit(1); - return 1; -} - -int ppwarning(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - generic_msg(s, "Warning", pptext, ap); - va_end(ap); - return 0; -} - - void internal_error(const char *file, int line, const char *s, ...) { va_list ap; diff --git a/tools/wrc/utils.h b/tools/wrc/utils.h index 86de9463a39..13242053384 100644 --- a/tools/wrc/utils.h +++ b/tools/wrc/utils.h @@ -31,8 +31,6 @@ void *xmalloc(size_t); void *xrealloc(void *, size_t); char *xstrdup(const char *str); -int pperror(const char *s, ...) __attribute__((format (printf, 1, 2))); -int ppwarning(const char *s, ...) __attribute__((format (printf, 1, 2))); int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2))); int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2))); void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4))); diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c index 89855b7203d..9041c13a39c 100644 --- a/tools/wrc/wrc.c +++ b/tools/wrc/wrc.c @@ -64,8 +64,8 @@ #include "dumpres.h" #include "genres.h" #include "newstruc.h" -#include "preproc.h" #include "parser.h" +#include "wpp.h" static char usage[] = "Usage: wrc [options...] [infile[.rc|.res]]\n" @@ -342,7 +342,7 @@ int main(int argc,char *argv[]) debuglevel = strtol(optarg, NULL, 0); break; case 'D': - add_cmdline_define(optarg); + wpp_add_cmdline_define(optarg); break; case 'e': extensions = 0; @@ -360,7 +360,7 @@ int main(int argc,char *argv[]) create_header = 1; break; case 'I': - add_include_path(optarg); + wpp_add_include_path(optarg); break; case 'l': { @@ -419,6 +419,7 @@ int main(int argc,char *argv[]) break; case 'W': pedantic = 1; + wpp_set_pedantic(1); break; default: lose++; @@ -571,28 +572,25 @@ int main(int argc,char *argv[]) yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; - ppdebug = debuglevel & DEBUGLEVEL_PPTRACE ? 1 : 0; - pp_flex_debug = debuglevel & DEBUGLEVEL_PPLEX ? 1 : 0; + + wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0, + (debuglevel & DEBUGLEVEL_PPTRACE) != 0, + (debuglevel & DEBUGLEVEL_PPMSG) != 0 ); /* Set the default defined stuff */ - add_cmdline_define("__WRC__=" WRC_EXP_STRINGIZE(WRC_MAJOR_VERSION)); - add_cmdline_define("__WRC_MINOR__=" WRC_EXP_STRINGIZE(WRC_MINOR_VERSION)); - add_cmdline_define("__WRC_MICRO__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION)); - add_cmdline_define("__WRC_PATCH__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION)); + wpp_add_cmdline_define("__WRC__=" WRC_EXP_STRINGIZE(WRC_MAJOR_VERSION)); + wpp_add_cmdline_define("__WRC_MINOR__=" WRC_EXP_STRINGIZE(WRC_MINOR_VERSION)); + wpp_add_cmdline_define("__WRC_MICRO__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION)); + wpp_add_cmdline_define("__WRC_PATCH__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION)); - add_cmdline_define("RC_INVOKED=1"); + wpp_add_cmdline_define("RC_INVOKED=1"); if(win32) { - add_cmdline_define("__WIN32__=1"); - add_cmdline_define("__FLAT__=1"); + wpp_add_cmdline_define("__WIN32__=1"); + wpp_add_cmdline_define("__FLAT__=1"); } - add_special_define("__FILE__"); - add_special_define("__LINE__"); - add_special_define("__DATE__"); - add_special_define("__TIME__"); - /* Check if the user set a language, else set default */ if(!currentlanguage) currentlanguage = new_language(0, 0); @@ -624,7 +622,6 @@ int main(int argc,char *argv[]) /* Run the preprocessor on the input */ if(!no_preprocess && !binary) { - char *real_name; /* * Preprocess the input to a temp-file, or stdout if * no output was given. @@ -632,54 +629,32 @@ int main(int argc,char *argv[]) chat("Starting preprocess"); - if(preprocess_only && !output_name) - { - ppout = stdout; - } - else if(preprocess_only && output_name) - { - if(!(ppout = fopen(output_name, "wb"))) - error("Could not open %s for writing\n", output_name); - } - else - { - if(!(temp_name = tmpnam(NULL))) - error("Could nor generate a temp-name\n"); - temp_name = xstrdup(temp_name); - if(!(ppout = fopen(temp_name, "wb"))) - error("Could not create a temp-file\n"); + if (!preprocess_only) + { + atexit(rm_tempfile); + ret = wpp_parse_temp( input_name, &temp_name ); + } + else if (output_name) + { + FILE *output; - atexit(rm_tempfile); - } - - real_name = input_name; /* Because it gets overwritten */ - - if(!input_name) - ppin = stdin; - else - { - if(!(ppin = fopen(input_name, "rb"))) - error("Could not open %s\n", input_name); - } - - fprintf(ppout, "# 1 \"%s\" 1\n", input_name ? input_name : ""); - - ret = ppparse(); - - input_name = real_name; - - if(input_name) - fclose(ppin); - - fclose(ppout); - - input_name = temp_name; + if (!(output = fopen( output_name, "w" ))) + error( "Could not open %s for writing\n", output_name ); + ret = wpp_parse( input_name, output ); + fclose( output ); + } + else + { + ret = wpp_parse( input_name, stdout ); + } if(ret) exit(1); /* Error during preprocess */ if(preprocess_only) exit(0); + + input_name = temp_name; } if(!binary) @@ -761,4 +736,3 @@ static void segvhandler(int sig) fflush(stderr); abort(); } -