X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/dfd82dce045a7576488fffade8d9c94785d4eae1..11c40ce9ae842585926cc1abd029f9f5a6702827:/src/cpplib.c diff --git a/src/cpplib.c b/src/cpplib.c index b12e4f7..5aff1e9 100644 --- a/src/cpplib.c +++ b/src/cpplib.c @@ -1,41 +1,6 @@ /* -See -http://src.openresources.com/debian/src/devel/HTML/S/altgcc_2.7.2.2.orig%20altgcc-2.7.2.2.orig%20protoize.c.html -static char * -abspath (cwd, rel_filename) - -*/ - -/*!!!! -*** cpplib.c.old Tue Nov 28 2000 09:04:09 AM ---- cpplib.c Tue Nov 28 2000 08:55:18 AM -*************** -*** 5715,5722 **** - c2 = cppReader_peekC (pfile) - if (c2 != '\n' - goto randomchar -! token = CPP_HSPACE -! goto op2any ---- 5714,5723 ---- - case '\\' - c2 = cppReader_peekC (pfile) - if (c2 != '\n' - goto randomchar -! cppReader_forward (pfile, 1) -! pfile->lineno++ -! return CPP_HSPACE - - - case '\n' - cppReader_putChar (pfile, c) - - -Carl J. Appellof ( mailto:cappello@legato.com ) -*/ /*@i8@*/ - -/* -** LCLint - annotation-assisted static program checker -** Copyright (C) 1994-2001 University of Virginia, +** Splint - annotation-assisted static program checker +** Copyright (C) 1994-2003 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -52,9 +17,9 @@ Carl J. Appellof ( mailto:cappello@legato.com ) ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ** MA 02111-1307, USA. ** -** For information on lclint: lclint-request@cs.virginia.edu -** To report a bug: lclint-bug@cs.virginia.edu -** For more information: http://lclint.cs.virginia.edu +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org +** For more information: http://www.splint.org */ /* ** cpplib.c @@ -97,22 +62,26 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # endif # include - # if !(defined (WIN32) || defined (OS2) && defined (__IBMC__)) # include # endif - # include # include # include - # if defined (WIN32) || defined (OS2) && defined (__IBMC__) # include +/* SMF */ +# ifndef BCC32 # include /* for __DATE__ and __TIME__ */ +# endif + # include # else # ifndef VMS -# ifndef USG +/* +** evans 2002-07-03: exception for WATCOM 10.6 compiler suggest by Adam Clarke +*/ +# if !defined (USG) && !defined (__WATCOMC__) # include /* Reported by Paul Smith */ # include # include @@ -127,15 +96,14 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /* This defines "errno" properly for VMS, and gives us EACCES. */ # include -# include "lclintMacros.nf" -# include "llbasic.h" +# include "splintMacros.nf" +# include "basic.h" # include "lcllib.h" # include "cpplib.h" # include "cpperror.h" # include "cpphash.h" # include "cppexp.h" # include "version.h" -# include "portab.h" # include "osd.h" /* @@ -145,6 +113,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /*@+boolint@*/ /*@+charint@*/ +/* Warnings for using sprintf - suppress them all for now... */ +/*@-bufferoverflowhigh@*/ +/*@-bounds@*/ + #define NO_SHORTNAMES # ifdef open @@ -183,9 +155,11 @@ static void cpp_setLocation (cppReader *p_pfile) static enum cpp_token cpp_handleComment (cppReader *p_pfile, struct parse_marker *p_smark) - /*@modifies p_pfile, p_smark@*/; + /*@modifies p_pfile, p_smark@*/; + +static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@modifies p_p@*/ ; -static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@*/ ; +static size_t cppReader_checkMacroNameLoc (fileloc p_loc, char *p_symname, cstring p_usage) ; static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ; @@ -194,7 +168,7 @@ static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ; #endif /* Symbols to predefine. */ - + #ifdef CPP_PREDEFINES static /*@observer@*/ char *predefs = CPP_PREDEFINES; #else @@ -227,7 +201,7 @@ static /*@observer@*/ char *predefs = ""; /*@constant observer char *WCHAR_TYPE@*/ #define WCHAR_TYPE "int" #endif - + /* The string value for __USER_LABEL_PREFIX__ */ #ifndef USER_LABEL_PREFIX @@ -250,7 +224,7 @@ static bool is_idstart[256]; static bool is_hor_space[256]; /* table to tell if c is horizontal or vertical space. */ static bool is_space[256]; - + static /*@exposed@*/ /*@null@*/ cppBuffer * cppReader_getBuffer (/*@special@*/ cppReader *p_pfile) /*@uses p_pfile->buffer@*/ @@ -268,23 +242,33 @@ static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ; # define cppBuffer_get(BUFFER) \ ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF) +/*@function static int cppBuffer_reachedEOF (sef cppBuffer *p_b) modifies nothing; @*/ +# define cppBuffer_reachedEOF(b) \ + ((b)->cur < (b)->rlimit ? FALSE : TRUE) + /* Append string STR (of length N) to PFILE's output buffer. Make space. */ /*@function static void cppReader_puts (sef cppReader *p_file, char *p_str, sef size_t p_n) modifies *p_file; @*/ # define cppReader_puts(PFILE, STR, N) \ - cppReader_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N) - + cpplib_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N) + /* Append character CH to PFILE's output buffer. Assume sufficient space. */ /*@function static void cppReader_putCharQ (cppReader *p_file, char p_ch) modifies *p_file; @*/ # define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH)) - +/* +static void cppReader_putCharQ (cppReader *p_file, char p_ch) +{ + fprintf (stderr, "put char: %c\n", p_ch); + (*(p_file)->limit++ = (p_ch)); +} +*/ /* Append character CH to PFILE's output buffer. Make space if need be. */ /*@function static void cppReader_putChar (sef cppReader *p_file, char p_ch) modifies *p_file; @*/ -#define cppReader_putChar(PFILE, CH) (cppReader_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH)) +#define cppReader_putChar(PFILE, CH) (cpplib_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH)) /* Make sure PFILE->limit is followed by '\0'. */ /*@function static void cppReader_nullTerminateQ (cppReader *p_file) @@ -295,7 +279,7 @@ static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ; /*@function static void cppReader_nullTerminate (sef cppReader *p_file) modifies *p_file; @*/ # define cppReader_nullTerminate(PFILE) \ - (cppReader_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0) + (cpplib_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0) /*@function static void cppReader_adjustWritten (cppReader *p_file, size_t) modifies *p_file; @*/ @@ -319,8 +303,11 @@ static void cppBuffer_forward (cppBuffer *p_buf, int p_n) /*@modifies *p_buf@*/ /*@function static int cppReader_getC (cppReader *p_pfile) modifies *p_pfile; @*/ # define cppReader_getC(pfile) (cppBuffer_get (cppReader_getBufferSafe (pfile))) +/*@function static int cppReader_reachedEOF (sef cppReader *p_pfile) modifies *p_pfile; @*/ +# define cppReader_reachedEOF(pfile) (cppBuffer_reachedEOF (cppReader_getBufferSafe (pfile))) + /*@function static int cppReader_peekC (cppReader *) modifies nothing;@*/ -# define cppReader_peekC(pfile) (cppBufPeek (cppReader_getBufferSafe (pfile))) +# define cppReader_peekC(pfile) (cpplib_bufPeek (cppReader_getBufferSafe (pfile))) /* Move all backslash-newline pairs out of embarrassing places. Exchange all such pairs following BP @@ -373,6 +360,8 @@ static void cppReader_scanBuffer (cppReader *p_pfile); # if defined (WIN32) || defined (OS2) && defined (__IBMC__) +/* SMF */ +# ifndef BCC32 /* ** WIN32 (at least the VC++ include files) does not define mode_t. */ @@ -380,6 +369,7 @@ static void cppReader_scanBuffer (cppReader *p_pfile); /*@-incondefs@*/ /*@-czechtypes@*/ typedef unsigned int mode_t; /*@=incondefs@*/ /*@=czechtypes@*/ +# endif # endif @@ -409,7 +399,7 @@ static int /*@alt void@*/ finclude (cppReader *p_pfile, int p_f, /*@dependent@*/ /*@null@*/ struct file_name_list *p_dirptr); static void validate_else (cppReader *p_pfile, cstring p_directive); - + static void conditional_skip (cppReader *p_pfile, int p_skip, enum node_type p_type, /*@dependent@*/ /*@null@*/ char *p_control_macro); @@ -465,9 +455,9 @@ struct directive { pointers to functions returning void. */ static int do_define (cppReader *, /*@null@*/ struct directive *, - char *, char *); + /*@exposed@*/ char *, char *); static int do_defineAux (cppReader *, /*@null@*/ struct directive *, - char *, char *, bool); + /*@exposed@*/ char *, char *, bool); static int do_line (cppReader *, /*@null@*/ struct directive *); static int do_include (cppReader *, struct directive *, char *, char *); @@ -493,7 +483,7 @@ static int do_warning (cppReader *, struct directive *, char *, char *); /* -I directories are added to the end, then the defaults are added. */ /*@access cstring@*/ - + static struct default_include { /*@dependent@*/ /*@observer@*/ cstring fname; /* The name of the directory. */ int cplusplus; /* Only look here if we're compiling C++. */ @@ -532,7 +522,7 @@ static struct directive directive_table[] = { { 4, do_line, "line", T_LINE, TRUE, FALSE, FALSE }, { 5, do_ident, "ident", T_IDENT, TRUE, FALSE, TRUE }, /* { 8, do_unassert, "unassert", T_UNASSERT, TRUE, FALSE, FALSE }, */ - { -1, 0, "", T_UNUSED, FALSE, FALSE, FALSE }, + { -1, NULL, "", T_UNUSED, FALSE, FALSE, FALSE }, }; /*@noaccess cstring@*/ @@ -612,7 +602,7 @@ static void quote_string (cppReader *pfile, char *src) { char c; - + cppReader_putCharQ (pfile, '\"'); for (;;) { @@ -623,7 +613,7 @@ quote_string (cppReader *pfile, char *src) cppReader_putCharQ (pfile, c); else { - sprintf (cppReader_getPWritten (pfile), "\\%03o", + sprintf (cpplib_getPWritten (pfile), "\\%03o", (unsigned int) c); cppReader_adjustWritten (pfile, (size_t) 4); } @@ -648,7 +638,7 @@ quote_string (cppReader *pfile, char *src) void cppReader_growBuffer (cppReader *pfile, size_t n) { - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); pfile->token_buffer_size = n + 2 * pfile->token_buffer_size; pfile->token_buffer = (char *) drealloc (pfile->token_buffer, pfile->token_buffer_size); @@ -753,7 +743,7 @@ cppReader_define (cppReader *pfile, char *str) (void) do_define (pfile, NULL, buf, buf + strlen (buf)); sfree (buf); } - + /* Append a chain of `struct file_name_list's to the end of the main include chain. FIRST is gthe beginning of the chain to append, and LAST is the end. */ @@ -786,11 +776,17 @@ cppReader_appendIncludeChain (cppReader *pfile, opts->first_bracket_include = first; for (dir = first; ; dir = dir->next) { - int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE; + size_t len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE; + if (len > pfile->max_include_len) - pfile->max_include_len = len; + { + pfile->max_include_len = len; + } + if (dir == last) - break; + { + break; + } } } @@ -798,7 +794,7 @@ cppReader_appendIncludeChain (cppReader *pfile, /* last->next = NULL; */ opts->last_include = last; } - + # if 0 static /*@unused@*/ void cppReader_showIncludeChain (cppReader *pfile) @@ -821,7 +817,7 @@ cppReader_showIncludeChain (cppReader *pfile) } } # endif - + cstring cppReader_getIncludePath () { @@ -846,11 +842,11 @@ cppReader_getIncludePath () } void -cppReader_addIncludeChain (cppReader *pfile, struct file_name_list *dir) +cppReader_addIncludeChain (cppReader *pfile, /*@only@*/ struct file_name_list *dir) { struct cppOptions *opts = CPPOPTIONS (pfile); - if (dir == 0) + if (dir == NULL) { return; } @@ -867,8 +863,9 @@ cppReader_addIncludeChain (cppReader *pfile, struct file_name_list *dir) if (opts->first_bracket_include == 0) { - int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE; + size_t len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE; opts->first_bracket_include = dir; + if (len > pfile->max_include_len) { pfile->max_include_len = len; @@ -887,7 +884,7 @@ static void path_include (cppReader *pfile, char *path) { char *p; - + #ifdef __CYGWIN32__ char *win32temp; @@ -943,7 +940,7 @@ path_include (cppReader *pfile, char *path) p++; } } - + void cppOptions_init (cppOptions *opts) { @@ -973,6 +970,9 @@ cppOptions_init (cppOptions *opts) opts->warn_comments = 0; opts->warnings_are_errors = 0; + /* Added 2003-07-10: */ + opts->traditional = FALSE; + opts->c89 = TRUE; initialize_char_syntax (opts); } @@ -984,7 +984,7 @@ cppReader_nullUnderflow (/*@unused@*/ cppReader *pfile) void cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf, - /*@unused@*/ cppReader *pfile) + /*@unused@*/ cppReader *pfile) { ; } @@ -1078,6 +1078,13 @@ skip_comment (cppReader *pfile, /*@null@*/ long *linep) else if (cppReader_peekC (pfile) == '/' && CPPOPTIONS (pfile)->cplusplus_comments) { + + (void) cppoptgenerror + (FLG_SLASHSLASHCOMMENT, + message ("C++ style // comment" + ), + pfile); + cppReader_forward (pfile, 1); for (;;) @@ -1193,17 +1200,34 @@ copy_rest_of_line (cppReader *pfile) llassert (pfile->buffer != NULL); c = cppReader_getC (pfile); + switch (c) { case EOF: goto end_directive; case '\\': - if (cppReader_peekC (pfile) == '\n') + /* + ** Patch from Brian St. Pierre for handling MS-DOS files. + */ + + DPRINTF (("Reading directive: %d", (int) c)); + + if (cppReader_peekC (pfile) == '\n' + || cppReader_peekC (pfile) == '\r') { + DPRINTF (("Reading directive...")); + if (cppReader_peekC (pfile) == '\r') + { + DPRINTF (("Reading directive...")); + cppReader_forward (pfile, 1); + } + + DPRINTF (("Reading directive...")); cppReader_forward (pfile, 1); continue; } + DPRINTF (("Falling...")); /*@fallthrough@*/ case '\'': case '\"': goto scan_directive_token; @@ -1236,7 +1260,7 @@ copy_rest_of_line (cppReader *pfile) goto end_directive; scan_directive_token: cppReader_forward (pfile, -1); - (void) cppGetToken (pfile); + (void) cpplib_getToken (pfile); continue; } cppReader_putChar (pfile, c); @@ -1248,7 +1272,7 @@ end_directive: ; void cppReader_skipRestOfLine (cppReader *pfile) { - size_t old = cppReader_getWritten (pfile); + size_t old = cpplib_getWritten (pfile); copy_rest_of_line (pfile); cppReader_setWritten (pfile, old); } @@ -1265,7 +1289,7 @@ cppReader_handleDirective (cppReader *pfile) size_t after_ident = 0; char *ident = NULL; char *line_end = NULL; - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); int nspaces = cppSkipHspace (pfile); c = cppReader_peekC (pfile); @@ -1294,7 +1318,7 @@ cppReader_handleDirective (cppReader *pfile) llassert (pfile->token_buffer != NULL); ident = pfile->token_buffer + old_written + 1; - ident_length = cppReader_getPWritten (pfile) - ident; + ident_length = cpplib_getPWritten (pfile) - ident; if (ident_length == 0 && cppReader_peekC (pfile) == '\n') { @@ -1327,7 +1351,7 @@ cppReader_handleDirective (cppReader *pfile) bool comments = 1; /*cppReader_isTraditional (pfile) && kt->traditional_comments; */ int save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments; CPPOPTIONS (pfile)->put_out_comments = comments; - after_ident = cppReader_getWritten (pfile); + after_ident = cpplib_getWritten (pfile); copy_rest_of_line (pfile); CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments; } @@ -1342,7 +1366,7 @@ cppReader_handleDirective (cppReader *pfile) so these parameters are invalid as soon as something gets appended to the token_buffer. */ - line_end = cppReader_getPWritten (pfile); + line_end = cpplib_getPWritten (pfile); if (!kt->pass_thru && kt->type != T_DEFINE) @@ -1455,7 +1479,7 @@ pass_thru_directive (char *buf, char *limit, { int keyword_length = keyword->length; - cppReader_reserve (pfile, + cpplib_reserve (pfile, size_fromInt (2 + keyword_length + (limit - buf))); cppReader_putCharQ (pfile, '#'); /*@-observertrans@*/ @@ -1549,7 +1573,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, p = buf; /* Add one initial space escape-marker to prevent accidental - token-pasting (often removed by macroexpand). */ + token-pasting (often removed by cpplib_macroExpand). */ *exp_p++ = '@'; *exp_p++ = ' '; @@ -1635,7 +1659,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, exp_p--; SKIP_WHITE_SPACE (p); if (p == limit || ! is_idstart[(int) *p] - || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '"'))) + || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '\"'))) cppReader_errorLit (pfile, cstring_makeLiteralTemp ("`#' operator is not followed by a macro argument name")); else @@ -1691,7 +1715,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, /* Handle the start of a symbol. */ if (is_idchar[(int) c] && nargs > 0) { char *id_beg = p - 1; - int id_len; + size_t id_len; --exp_p; while (p != limit && is_idchar[(int) *p]) @@ -1699,10 +1723,10 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, p++; } - id_len = p - id_beg; + id_len = size_fromInt (p - id_beg); if (is_idstart[(int) c] - && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) { + && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) { register struct arglist *arg; for (arg = arglist; arg != NULL; arg = arg->next) { @@ -1710,7 +1734,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, if (arg->name[0] == c && arg->length == id_len - && strncmp (arg->name, id_beg, size_fromInt (id_len)) == 0) { + && strncmp (arg->name, id_beg, id_len) == 0) { char *p1; if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) { @@ -1806,146 +1830,497 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded.")); } - return defn; + /*@i1@*/ return defn; /* Spurious warning here */ } /* - * special extension string that can be added to the last macro argument to - * allow it to absorb the "rest" of the arguments when expanded. Ex: - * #define wow(a, b...) process (b, a, b) - * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); } - * { wow (one, two); } -> { process (two, one, two); } - * if this "rest_arg" is used with the concat token '##' and if it is not - * supplied then the token attached to with ## will not be outputted. Ex: - * #define wow (a, b...) process (b ## , a, ## b) - * { wow (1, 2); } -> { process (2, 1, 2); } - * { wow (one); } -> { process (one); { - */ +** evans 2001-12-31 +** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...) +*/ -/*@-readonlytrans@*/ -static char rest_extension[] = "..."; -/*:=readonlytrans@*/ +static DEFINITION * +collect_expansionLoc (fileloc loc, char *buf, char *limit, + int nargs, /*@null@*/ struct arglist *arglist) +{ + DEFINITION *defn; + char *p, *lastp, *exp_p; + struct reflist *endpat = NULL; + /* Pointer to first nonspace after last ## seen. */ + char *concat = 0; + /* Pointer to first nonspace after last single-# seen. */ + char *stringify = 0; + size_t maxsize; + char expected_delimiter = '\0'; -/*@notfunction@*/ -#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) -/* Create a DEFINITION node from a #define directive. Arguments are - as for do_define. */ + /* Scan thru the replacement list, ignoring comments and quoted + strings, picking up on the macro calls. It does a linear search + thru the arg list on every potential symbol. Profiling might say + that something smarter should happen. */ -static /*@null@*/ MACRODEF -create_definition (char *buf, char *limit, - cppReader *pfile, bool predefinition, - bool noExpand) -{ - char *bp; /* temp ptr into input buffer */ - char *symname; /* remember where symbol name starts */ - int sym_length; /* and how long it is */ - int rest_args = 0; /* really int! */ - int line; - int col; - cstring file = (CPPBUFFER (pfile) != NULL) - ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp (""); - DEFINITION *defn; - int arglengths = 0; /* Accumulate lengths of arg names - plus number of args. */ - MACRODEF mdef; + if (limit < buf) + { + llfatalbug (message ("%q: Limit is less than initial buffer pointer", + fileloc_unparse (loc))); + } - cppBuffer_lineAndColumn (CPPBUFFER (pfile), &line, &col); + /* Find the beginning of the trailing whitespace. */ + p = buf; - bp = buf; + while (p < limit && is_space[(int) limit[-1]]) + { + limit--; + } - while (is_hor_space[(int) *bp]) + /* Allocate space for the text in the macro definition. + Leading and trailing whitespace chars need 2 bytes each. + Each other input char may or may not need 1 byte, + so this is an upper bound. The extra 5 are for invented + leading and trailing newline-marker and final null. */ + maxsize = (sizeof (*defn) + (limit - p) + 5); + + /* Occurrences of '@' get doubled, so allocate extra space for them. */ + while (p < limit) { - bp++; + if (*p++ == '@') + { + maxsize++; + } } - symname = bp; /* remember where it starts */ + defn = (DEFINITION *) dmalloc (maxsize); + defn->noExpand = FALSE; + defn->file = NULL; + defn->pattern = NULL; + defn->nargs = nargs; + defn->predefined = NULL; + exp_p = defn->expansion = (char *) defn + sizeof (*defn); - sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro")); + defn->line = 0; + defn->rest_args = NULL; + defn->args.argnames = NULL; - bp += sym_length; + lastp = exp_p; - /* Lossage will occur if identifiers or control keywords are broken - across lines using backslash. This is not the right place to take - care of that. */ + p = buf; - if (*bp == '(') { - struct arglist *arg_ptrs = NULL; - int argno = 0; + /* Add one initial space escape-marker to prevent accidental + token-pasting (often removed by cpplib_macroExpand). */ + *exp_p++ = '@'; + *exp_p++ = ' '; - bp++; /* skip '(' */ - SKIP_WHITE_SPACE (bp); + if (limit - p >= 2 && p[0] == '#' && p[1] == '#') { + voptgenerror (FLG_PREPROC, + cstring_makeLiteral ("Paste marker ## at start of macro definition"), + loc); + p += 2; + } - /* Loop over macro argument names. */ - while (*bp != ')') - { - struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp)); - temp->name = bp; - temp->next = arg_ptrs; - temp->argno = argno++; - temp->rest_args = 0; + /* Process the main body of the definition. */ + while (p < limit) { + int skipped_arg = 0; + register char c = *p++; - arg_ptrs = temp; + *exp_p++ = c; - if (rest_args != 0) + if (TRUE) { /* !cppReader_isTraditional (pfile)) { */ + switch (c) { + case '\'': + case '\"': + if (expected_delimiter != '\0') { - cppReader_pedwarn (pfile, - message ("another parameter follows `%s'", - cstring_fromChars (rest_extension))); + if (c == expected_delimiter) + expected_delimiter = '\0'; } - - if (!is_idstart[(int) *bp]) + else { - cppReader_pedwarnLit (pfile, - cstring_makeLiteralTemp ("invalid character in macro parameter name")); + expected_delimiter = c; } + /*@switchbreak@*/ break; - /* Find the end of the arg name. */ - while (is_idchar[(int) *bp]) + case '\\': + if (p < limit && (expected_delimiter != '\0')) { - bp++; - /* do we have a "special" rest-args extension here? */ - if (limit - bp > size_toInt (REST_EXTENSION_LENGTH) - && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) - { - rest_args = 1; - temp->rest_args = 1; - /*@innerbreak@*/ break; - } + /* In a string, backslash goes through + and makes next char ordinary. */ + *exp_p++ = *p++; } + /*@switchbreak@*/ break; - temp->length = bp - temp->name; - - if (rest_args != 0) + case '@': + /* An '@' in a string or character constant stands for itself, + and does not need to be escaped. */ + if (expected_delimiter == '\0') { - bp += REST_EXTENSION_LENGTH; + *exp_p++ = c; } - arglengths += temp->length + 2; - SKIP_WHITE_SPACE (bp); + /*@switchbreak@*/ break; - if (temp->length == 0 || (*bp != ',' && *bp != ')')) { - cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("Parameter list for #define is not parseable")); - goto nope; - } + case '#': + /* # is ordinary inside a string. */ + if (expected_delimiter != '\0') + { + /*@switchbreak@*/ break; + } - if (*bp == ',') { - bp++; - SKIP_WHITE_SPACE (bp); - } - if (bp >= limit) { - cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("unterminated parameter list in `#define'")); - goto nope; - } - { - struct arglist *otemp; + if (p < limit && *p == '#') { + /* ##: concatenate preceding and following tokens. */ + /* Take out the first #, discard preceding whitespace. */ + exp_p--; - for (otemp = temp->next; otemp != NULL; otemp = otemp->next) + /*@-usedef@*/ + while (exp_p > lastp && is_hor_space[(int) exp_p[-1]]) + { + --exp_p; + } + /*@=usedef@*/ + + /* Skip the second #. */ + p++; + /* Discard following whitespace. */ + SKIP_WHITE_SPACE (p); + concat = p; + if (p == limit) + { + voptgenerror (FLG_PREPROC, + cstring_makeLiteral ("`##' at end of macro definition"), + loc); + } + } else if (nargs >= 0) { + /* Single #: stringify following argument ref. + Don't leave the # in the expansion. */ + exp_p--; + SKIP_WHITE_SPACE (p); + if (p == limit || ! is_idstart[(int) *p] + || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '\"'))) + { + voptgenerror + (FLG_PREPROC, + cstring_makeLiteral ("`#' operator is not followed by a macro argument name"), + loc); + } + else + stringify = p; + } else { + ; /* BADBRANCH; */ + } + + /*@switchbreak@*/ break; + } + } else { + /* In -traditional mode, recognize arguments inside strings and + and character constants, and ignore special properties of #. + Arguments inside strings are considered "stringified", but no + extra quote marks are supplied. */ + switch (c) { + case '\'': + case '\"': + if (expected_delimiter != '\0') { + if (c == expected_delimiter) + expected_delimiter = '\0'; + } else + expected_delimiter = c; + /*@switchbreak@*/ break; + + case '\\': + /* Backslash quotes delimiters and itself, but not macro args. */ + if (expected_delimiter != '\0' && p < limit + && (*p == expected_delimiter || *p == '\\')) { + *exp_p++ = *p++; + continue; + } + /*@switchbreak@*/ break; + + case '/': + if (expected_delimiter != '\0') /* No comments inside strings. */ + /*@switchbreak@*/ break; + if (*p == '*') { + /* If we find a comment that wasn't removed by cppReader_handleDirective, + this must be -traditional. So replace the comment with + nothing at all. */ + exp_p--; + p += 1; + while (p < limit && !(p[-2] == '*' && p[-1] == '/')) + { + p++; + } + } + /*@switchbreak@*/ break; + } + } + + /* Handle the start of a symbol. */ + if (is_idchar[(int) c] && nargs > 0) { + char *id_beg = p - 1; + size_t id_len; + + --exp_p; + while (p != limit && is_idchar[(int) *p]) + { + p++; + } + + id_len = size_fromInt (p - id_beg); + + if (is_idstart[(int) c] + && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) { + register struct arglist *arg; + + for (arg = arglist; arg != NULL; arg = arg->next) { + struct reflist *tpat; + + if (arg->name[0] == c + && arg->length == id_len + && strncmp (arg->name, id_beg, id_len) == 0) { + char *p1; + + if (expected_delimiter) { /* && CPPOPTIONS (pfile)->warn_stringify) { */ + if (FALSE) { /* cppReader_isTraditional (pfile)) { */ + voptgenerror (FLG_PREPROC, + message ("macro argument `%x' is stringified.", + cstring_prefix (cstring_fromChars (arg->name), id_len)), + loc); + + } else { + voptgenerror (FLG_PREPROC, + message ("Macro arg `%x' would be stringified with -traditional.", + cstring_prefix (cstring_fromChars (arg->name), id_len)), + loc); + + } + } + /* If ANSI, don't actually substitute inside a string. */ + if (TRUE /* !cppReader_isTraditional (pfile) */ && expected_delimiter) + /*@innerbreak@*/ break; + /* make a pat node for this arg and append it to the end of + the pat list */ + tpat = (struct reflist *) dmalloc (sizeof (*tpat)); + tpat->next = NULL; + tpat->raw_before = (concat == id_beg); + tpat->raw_after = 0; + tpat->rest_args = arg->rest_args; + tpat->stringify = (FALSE /* cppReader_isTraditional (pfile) */ + ? expected_delimiter != '\0' + : stringify == id_beg); + + if (endpat == NULL) + { + defn->pattern = tpat; + } + else + { + endpat->next = tpat; + /*@-branchstate@*/ + } /*@=branchstate@*/ /* evs 2000 was =branchstate */ + + endpat = tpat; + + tpat->argno = arg->argno; + tpat->nchars = exp_p - lastp; + + p1 = p; + + SKIP_WHITE_SPACE (p1); + + if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#') + { + tpat->raw_after = 1; + } + + lastp = exp_p; /* place to start copying from next time */ + skipped_arg = 1; + + /*@innerbreak@*/ break; + } + } + } + + /* If this was not a macro arg, copy it into the expansion. */ + if (skipped_arg == 0) { + register char *lim1 = p; + p = id_beg; + + while (p != lim1) + { + *exp_p++ = *p++; + } + + if (stringify == id_beg) + { + voptgenerror + (FLG_PREPROC, + cstring_makeLiteral ("# operator should be followed by a macro argument name"), + loc); + } + } + } + } + + if (/*!cppReader_isTraditional (pfile) && */ expected_delimiter == '\0') + { + /* If ANSI, put in a "@ " marker to prevent token pasting. + But not if "inside a string" (which in ANSI mode + happens only for -D option). */ + *exp_p++ = '@'; + *exp_p++ = ' '; + } + + *exp_p = '\0'; + + defn->length = size_fromInt (exp_p - defn->expansion); + + /* Crash now if we overrun the allocated size. */ + if (defn->length + 1 > maxsize) + { + llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded.")); + } + + /*@i1@*/ return defn; /* Spurious warning here */ +} + +/* + * special extension string that can be added to the last macro argument to + * allow it to absorb the "rest" of the arguments when expanded. Ex: + * #define wow(a, b...) process (b, a, b) + * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); } + * { wow (one, two); } -> { process (two, one, two); } + * if this "rest_arg" is used with the concat token '##' and if it is not + * supplied then the token attached to with ## will not be outputted. Ex: + * #define wow (a, b...) process (b ## , a, ## b) + * { wow (1, 2); } -> { process (2, 1, 2); } + * { wow (one); } -> { process (one); { + */ + +/*@-readonlytrans@*/ +static char rest_extension[] = "..."; +/*:=readonlytrans@*/ + +/*@notfunction@*/ +#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) + +/* Create a DEFINITION node from a #define directive. Arguments are + as for do_define. */ + + +static /*@null@*/ macroDef +create_definition (/*@exposed@*/ char *buf, char *limit, + cppReader *pfile, bool predefinition, + bool noExpand) +{ + char *bp; /* temp ptr into input buffer */ + char *symname; /* remember where symbol name starts */ + size_t sym_length; /* and how long it is */ + int rest_args = 0; /* really int! */ + int line; + int col; + cstring file = (CPPBUFFER (pfile) != NULL) + ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp (""); + DEFINITION *defn; + int arglengths = 0; /* Accumulate lengths of arg names + plus number of args. */ + macroDef mdef; + char save = *limit; + *limit = '\0'; + DPRINTF (("Create definition: %s", buf)); + *limit = save; + + cppBuffer_getLineAndColumn (CPPBUFFER (pfile), &line, &col); + + bp = buf; + + while (is_hor_space[(int) *bp]) + { + bp++; + } + + symname = bp; /* remember where it starts */ + + sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro")); + + bp += sym_length; + + /* Lossage will occur if identifiers or control keywords are broken + across lines using backslash. This is not the right place to take + care of that. */ + + if (*bp == '(') { + struct arglist *arg_ptrs = NULL; + int argno = 0; + + bp++; /* skip '(' */ + SKIP_WHITE_SPACE (bp); + + /* Loop over macro argument names. */ + while (*bp != ')') + { + struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp)); + temp->name = bp; + temp->next = arg_ptrs; + temp->argno = argno++; + temp->rest_args = 0; + + arg_ptrs = temp; + + if (rest_args != 0) + { + cppReader_pedwarn (pfile, + message ("another parameter follows `%s'", + cstring_fromChars (rest_extension))); + } + + if (!is_idstart[(int) *bp]) + { + cppReader_pedwarnLit (pfile, + cstring_makeLiteralTemp ("Invalid character in macro parameter name")); + } + + /* Find the end of the arg name. */ + while (is_idchar[(int) *bp]) + { + bp++; + /* do we have a "special" rest-args extension here? */ + if (limit - bp > size_toInt (REST_EXTENSION_LENGTH) + && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) + { + rest_args = 1; + temp->rest_args = 1; + /*@innerbreak@*/ break; + } + } + + temp->length = size_fromInt (bp - temp->name); + + if (rest_args != 0) + { + bp += REST_EXTENSION_LENGTH; + } + + arglengths += temp->length + 2; + SKIP_WHITE_SPACE (bp); + + if (temp->length == 0 || (*bp != ',' && *bp != ')')) { + cppReader_errorLit (pfile, + cstring_makeLiteralTemp ("Parameter list for #define is not parseable")); + goto nope; + } + + if (*bp == ',') { + bp++; + SKIP_WHITE_SPACE (bp); + } + if (bp >= limit) { + cppReader_errorLit (pfile, + cstring_makeLiteralTemp ("unterminated parameter list in `#define'")); + goto nope; + } + { + struct arglist *otemp; + + for (otemp = temp->next; otemp != NULL; otemp = otemp->next) { if (temp->length == otemp->length && - strncmp (temp->name, otemp->name, size_fromInt (temp->length)) == 0) { + strncmp (temp->name, otemp->name, temp->length) == 0) { cstring name = cstring_copyLength (temp->name, temp->length); cppReader_error (pfile, message ("duplicate argument name `%x' in `#define'", name)); @@ -1954,7 +2329,7 @@ create_definition (char *buf, char *limit, } } } - + ++bp; /* skip paren */ SKIP_WHITE_SPACE (bp); /* now everything from bp before limit is the definition. */ @@ -1965,19 +2340,21 @@ create_definition (char *buf, char *limit, the argument names in reverse order with comma-space between them. */ defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1)); - + { struct arglist *temp; int i = 0; - for (temp = arg_ptrs; temp != NULL; temp = temp->next) { - memcpy (&defn->args.argnames[i], temp->name, size_fromInt (temp->length)); - i += temp->length; - if (temp->next != 0) { - defn->args.argnames[i++] = ','; - defn->args.argnames[i++] = ' '; + for (temp = arg_ptrs; temp != NULL; temp = temp->next) + { + memcpy (&defn->args.argnames[i], temp->name, temp->length); + i += temp->length; + if (temp->next != 0) + { + defn->args.argnames[i++] = ','; + defn->args.argnames[i++] = ' '; + } } - } - + defn->args.argnames[i] = '\0'; } @@ -1992,7 +2369,7 @@ create_definition (char *buf, char *limit, SKIP_WHITE_SPACE (bp); } else { switch (*bp) { - case '!': case '"': case '#': case '%': case '&': case '\'': + case '!': case '\"': case '#': case '%': case '&': case '\'': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case ':': case ';': case '<': case '=': case '>': case '?': case '[': case '\\': case ']': case '^': case '{': @@ -2033,52 +2410,319 @@ create_definition (char *buf, char *limit, return mdef; -nope: - mdef.defn = NULL; - mdef.symnam = NULL; - return mdef; +nope: + mdef.defn = NULL; + mdef.symnam = NULL; + return mdef; +} + +/*@null@*/ macroDef +cpplib_createDefinition (cstring def, + fileloc loc, + bool predefinition, + bool noExpand) +{ + char *buf = cstring_toCharsSafe (def); + char *limit = buf + cstring_length (def); + char *bp; /* temp ptr into input buffer */ + char *symname; /* remember where symbol name starts */ + size_t sym_length; /* and how long it is */ + int rest_args = 0; /* really int! */ + int line = fileloc_lineno (loc); + cstring file = fileloc_filename (loc); + DEFINITION *defn; + int arglengths = 0; /* Accumulate lengths of arg names + plus number of args. */ + macroDef mdef; + + bp = buf; + + DPRINTF (("Creating definition: %s", buf)); + + while (is_hor_space[(int) *bp]) + { + bp++; + } + + symname = bp; /* remember where it starts */ + + sym_length = cppReader_checkMacroNameLoc (loc, symname, cstring_makeLiteralTemp ("macro")); + + DPRINTF (("length: %d", sym_length)); + + bp += sym_length; + + DPRINTF (("Here: %s", bp)); + + /* Lossage will occur if identifiers or control keywords are broken + across lines using backslash. This is not the right place to take + care of that. */ + + if (*bp == '(') { + struct arglist *arg_ptrs = NULL; + int argno = 0; + + bp++; /* skip '(' */ + SKIP_WHITE_SPACE (bp); + + /* Loop over macro argument names. */ + while (*bp != ')') + { + struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp)); + temp->name = bp; + temp->next = arg_ptrs; + temp->argno = argno++; + temp->rest_args = 0; + + arg_ptrs = temp; + + if (rest_args != 0) + { + voptgenerror (FLG_PREPROC, + message ("Another parameter follows %s", + cstring_fromChars (rest_extension)), + loc); + } + + if (!is_idstart[(int) *bp]) + { + voptgenerror (FLG_PREPROC, + message ("Invalid character in macro parameter name: %c", *bp), + loc); + } + + /* Find the end of the arg name. */ + while (is_idchar[(int) *bp]) + { + bp++; + /* do we have a "special" rest-args extension here? */ + if (limit - bp > size_toInt (REST_EXTENSION_LENGTH) + && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) + { + rest_args = 1; + temp->rest_args = 1; + /*@innerbreak@*/ break; + } + } + + temp->length = size_fromInt (bp - temp->name); + + if (rest_args != 0) + { + bp += REST_EXTENSION_LENGTH; + } + + arglengths += temp->length + 2; + SKIP_WHITE_SPACE (bp); + + if (temp->length == 0 || (*bp != ',' && *bp != ')')) { + voptgenerror (FLG_PREPROC, + cstring_makeLiteral ("Parameter list for #define is not parseable"), + loc); + goto nope; + } + + if (*bp == ',') { + bp++; + SKIP_WHITE_SPACE (bp); + } + if (bp >= limit) { + voptgenerror (FLG_PREPROC, + cstring_makeLiteral ("Unterminated parameter list in #define'"), + loc); + goto nope; + } + { + struct arglist *otemp; + + for (otemp = temp->next; otemp != NULL; otemp = otemp->next) + { + if (temp->length == otemp->length && + strncmp (temp->name, otemp->name, temp->length) == 0) { + cstring name = cstring_copyLength (temp->name, temp->length); + + voptgenerror (FLG_PREPROC, + message ("Duplicate argument name in #define: %s", name), + loc); + goto nope; + } + } + } + } + + ++bp; /* skip paren */ + SKIP_WHITE_SPACE (bp); + /* now everything from bp before limit is the definition. */ + defn = collect_expansionLoc (loc, bp, limit, argno, arg_ptrs); + defn->rest_args = rest_args; + + /* Now set defn->args.argnames to the result of concatenating + the argument names in reverse order + with comma-space between them. */ + defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1)); + + { + struct arglist *temp; + int i = 0; + for (temp = arg_ptrs; temp != NULL; temp = temp->next) { + memcpy (&defn->args.argnames[i], temp->name, temp->length); + i += temp->length; + if (temp->next != 0) { + defn->args.argnames[i++] = ','; + defn->args.argnames[i++] = ' '; + } + } + + defn->args.argnames[i] = '\0'; + } + + sfree (arg_ptrs); + } else { + /* Simple expansion or empty definition. */ + + if (bp < limit) + { + if (is_hor_space[(int) *bp]) { + bp++; + SKIP_WHITE_SPACE (bp); + } else { + switch (*bp) { + case '!': case '\"': case '#': case '%': case '&': case '\'': + case ')': case '*': case '+': case ',': case '-': case '.': + case '/': case ':': case ';': case '<': case '=': case '>': + case '?': case '[': case '\\': case ']': case '^': case '{': + case '|': case '}': case '~': + voptgenerror (FLG_PREPROC, + message ("Missing white space after #define %x", + cstring_prefix (cstring_fromChars (symname), + sym_length)), + loc); + break; + + default: + voptgenerror (FLG_PREPROC, + message ("Missing white space after #define %x", + cstring_prefix (cstring_fromChars (symname), + sym_length)), + loc); + break; + } + } + } + + /* now everything from bp before limit is the definition. */ + llassert (limit > bp); + defn = collect_expansionLoc (loc, bp, limit, -1, NULL); + defn->args.argnames = mstring_createEmpty (); + } + + defn->noExpand = noExpand; + DPRINTF (("No expand: %d", noExpand)); + + defn->line = line; + + /* not: llassert (cstring_isUndefined (defn->file)); */ + defn->file = file; + + /* OP is null if this is a predefinition */ + defn->predefined = predefinition; + + mdef.defn = defn; + mdef.symnam = symname; + mdef.symlen = sym_length; + + return mdef; + +nope: + mdef.defn = NULL; + mdef.symnam = NULL; + return mdef; +} + +/* Check a purported macro name SYMNAME, and yield its length. + USAGE is the kind of name this is intended for. */ + +size_t cppReader_checkMacroName (cppReader *pfile, char *symname, cstring usage) +{ + char *p; + size_t sym_length; + + for (p = symname; is_idchar[(int) *p]; p++) + { + ; + } + + sym_length = size_fromInt (p - symname); + + if (sym_length == 0 + || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '\"'))) + { + cppReader_error (pfile, message ("invalid %s name", usage)); + } + else if (!is_idstart[(int) *symname]) + { + char *msg = (char *) dmalloc (sym_length + 1); + memcpy (msg, symname, sym_length); + msg[sym_length] = '\0'; + cppReader_error (pfile, message ("invalid %s name `%s'", usage, + cstring_fromChars (msg))); + sfree (msg); + } + else + { + if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7) + { + cppReader_error (pfile, message ("invalid %s name `defined'", usage)); + } + } + + return sym_length; } + +/* +** evans 2001-12-31 +** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...) +*/ -/* Check a purported macro name SYMNAME, and yield its length. - USAGE is the kind of name this is intended for. */ - -int cppReader_checkMacroName (cppReader *pfile, - char *symname, - cstring usage) +size_t cppReader_checkMacroNameLoc (fileloc loc, char *symname, cstring usage) { char *p; size_t sym_length; - + for (p = symname; is_idchar[(int) *p]; p++) { ; } - + sym_length = size_fromInt (p - symname); - + if (sym_length == 0 - || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"'))) - cppReader_error (pfile, message ("invalid %s name", usage)); + || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '\"'))) + { + voptgenerror (FLG_PREPROC, message ("Invalid %s name: %s", usage, + cstring_fromChars (symname)), loc); + } else if (!is_idstart[(int) *symname]) { char *msg = (char *) dmalloc (sym_length + 1); memcpy (msg, symname, sym_length); msg[sym_length] = '\0'; - cppReader_error (pfile, message ("invalid %s name `%s'", usage, - cstring_fromChars (msg))); + voptgenerror (FLG_PREPROC, message ("Invalid %s name: %s", usage, + cstring_fromChars (msg)), + loc); sfree (msg); } else { if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7) { - cppReader_error (pfile, message ("invalid %s name `defined'", usage)); + voptgenerror (FLG_PREPROC, message ("Invalid %s name: defined", usage), loc); } } - return size_toInt (sym_length); + return sym_length; } - + /* Return zero if two DEFINITIONs are isomorphic. */ static bool @@ -2120,21 +2764,23 @@ compare_defs (DEFINITION *d1, DEFINITION *d2) if (a1 != a2) return TRUE; - if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion), - p2, d2->length - (p2 - d2->expansion), 1)) + if (comp_def_part (first, p1, size_toInt (d1->length - (p1 - d1->expansion)), + p2, size_toInt (d2->length - (p2 - d2->expansion)), 1)) return TRUE; return FALSE; } -/* Return TRUE if two parts of two macro definitions are effectively different. - One of the parts starts at BEG1 and has LEN1 chars; - the other has LEN2 chars at BEG2. - Any sequence of whitespace matches any other sequence of whitespace. - FIRST means these parts are the first of a macro definition; - so ignore leading whitespace entirely. - LAST means these parts are the last of a macro definition; - so ignore trailing whitespace entirely. */ +/* +** Return TRUE if two parts of two macro definitions are effectively different. +** One of the parts starts at BEG1 and has LEN1 chars; +** the other has LEN2 chars at BEG2. +** Any sequence of whitespace matches any other sequence of whitespace. +** FIRST means these parts are the first of a macro definition; +** so ignore leading whitespace entirely. +** LAST means these parts are the last of a macro definition; +** so ignore trailing whitespace entirely. +*/ static bool comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last) @@ -2161,34 +2807,30 @@ comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last return (beg1 != end1) || (beg2 != end2); } -/* Process a #define command. - BUF points to the contents of the #define command, as a contiguous string. - LIMIT points to the first character past the end of the definition. - KEYWORD is the keyword-table entry for #define, - or NULL for a "predefined" macro. */ +/* +** Process a #define command. +** BUF points to the contents of the #define command, as a contiguous string. +** LIMIT points to the first character past the end of the definition. +** KEYWORD is the keyword-table entry for #define, +** or NULL for a "predefined" macro. +*/ static int do_defineAux (cppReader *pfile, struct directive *keyword, - char *buf, char *limit, bool noExpand) + /*@exposed@*/ char *buf, char *limit, bool noExpand) { int hashcode; - MACRODEF mdef; + macroDef mdef; hashNode hp; - - DPRINTF (("Define aux: %d", noExpand)); mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand); if (mdef.defn == 0) goto nope; - hashcode = hashf (mdef.symnam, mdef.symlen, CPP_HASHSIZE); - - DPRINTF (("Macro: %s / %s", - cstring_copyLength (mdef.symnam, mdef.symlen), - bool_unparse (noExpand))); + hashcode = cpphash_hashCode (mdef.symnam, mdef.symlen, CPP_HASHSIZE); - if ((hp = cppReader_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) + if ((hp = cpphash_lookup (mdef.symnam, size_toInt (mdef.symlen), hashcode)) != NULL) { bool ok = FALSE; @@ -2202,7 +2844,7 @@ do_defineAux (cppReader *pfile, struct directive *keyword, else if (hp->type == T_CONST) ok = !CPPOPTIONS (pfile)->done_initializing; else { - BADBRANCH; + ok = FALSE; /* Redefining anything else is bad. */ } /* Print the warning if it's not ok. */ @@ -2245,7 +2887,6 @@ do_defineAux (cppReader *pfile, struct directive *keyword, message ("Macro %q already defined", cstring_copyLength (mdef.symnam, mdef.symlen))); - } } @@ -2270,34 +2911,35 @@ do_defineAux (cppReader *pfile, struct directive *keyword, DPRINTF (("Define macro: %s / %d", mdef.symnam, mdef.defn->noExpand)); - hn = cppReader_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode); + hn = cpphash_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode); /*@-branchstate@*/ } /*@=branchstate@*/ return 0; nope: - return 1; } static int do_define (cppReader *pfile, struct directive *keyword, - char *buf, char *limit) + /*@exposed@*/ char *buf, char *limit) { DPRINTF (("Regular do define")); return do_defineAux (pfile, keyword, buf, limit, FALSE); } -/* This structure represents one parsed argument in a macro call. - `raw' points to the argument text as written (`raw_length' is its length). - `expanded' points to the argument's macro-expansion - (its length is `expand_length'). - `stringified_length' is the length the argument would have - if stringified. - `use_count' is the number of times this macro arg is substituted - into the macro. If the actual use count exceeds 10, - the value stored is 10. */ +/* +** This structure represents one parsed argument in a macro call. +** `raw' points to the argument text as written (`raw_length' is its length). +** `expanded' points to the argument's macro-expansion +** (its length is `expand_length'). +** `stringified_length' is the length the argument would have +** if stringified. +** `use_count' is the number of times this macro arg is substituted +** into the macro. If the actual use count exceeds 10, +** the value stored is 10. +*/ /* raw and expanded are relative to ARG_BASE */ /*@notfunction@*/ @@ -2315,15 +2957,17 @@ struct argdata { int use_count; }; -/* Allocate a new cppBuffer for PFILE, and push it on the input buffer stack. - If BUFFER != NULL, then use the LENGTH characters in BUFFER - as the new input buffer. - Return the new buffer, or NULL on failure. */ +/* +** Allocate a new cppBuffer for PFILE, and push it on the input buffer stack. +** If BUFFER != NULL, then use the LENGTH characters in BUFFER +** as the new input buffer. +** Return the new buffer, or NULL on failure. +*/ /*@null@*/ /*@exposed@*/ cppBuffer * cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length) { - cppBuffer *buf = cppReader_getBuffer (pfile); + cppBuffer *buf = cppReader_getBufferSafe (pfile); if (buf == pfile->buffer_stack) { @@ -2341,6 +2985,7 @@ cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length) buf--; memset ((char *) buf, 0, sizeof (*buf)); + DPRINTF (("Pushing buffer: %s", cstring_copyLength (buffer, length))); CPPBUFFER (pfile) = buf; buf->if_stack = pfile->if_stack; @@ -2372,8 +3017,10 @@ cppReader_popBuffer (cppReader *pfile) return ++CPPBUFFER (pfile); } -/* Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer. - Pop the buffer when done. */ +/* +** Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer. +** Pop the buffer when done. +*/ void cppReader_scanBuffer (cppReader *pfile) @@ -2383,7 +3030,7 @@ cppReader_scanBuffer (cppReader *pfile) { enum cpp_token token; - token = cppGetToken (pfile); + token = cpplib_getToken (pfile); if (token == CPP_EOF) /* Should not happen ... */ { @@ -2404,7 +3051,7 @@ cppReader_scanBuffer (cppReader *pfile) * * The input is copied before it is scanned, so it is safe to pass * it something from the token_buffer that will get overwritten - * (because it follows cppReader_getWritten). This is used by do_include. + * (because it follows cpplib_getWritten). This is used by do_include. */ static void @@ -2414,6 +3061,8 @@ cpp_expand_to_buffer (cppReader *pfile, char *buf, size_t length) char *limit = buf + length; char *buf1, *p1, *p2; + DPRINTF (("Expand to buffer: %s", cstring_copyLength (buf, length))); + /* evans - 2001-08-26 ** length is unsigned - this doesn't make sense if (length < 0) @@ -2487,8 +3136,8 @@ update_position (cppBuffer *pbuf) } void -cppBuffer_lineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep, - /*@null@*/ /*@out@*/ int *colp) +cppBuffer_getLineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep, + /*@null@*/ /*@out@*/ int *colp) { int dummy; @@ -2598,7 +3247,7 @@ output_line_command (cppReader *pfile, bool conditional, if (line > pfile->lineno && line < pfile->lineno + 8) { - cppReader_reserve (pfile, 20); + cpplib_reserve (pfile, 20); while (line > pfile->lineno) { cppReader_putCharQ (pfile, '\n'); @@ -2609,8 +3258,7 @@ output_line_command (cppReader *pfile, bool conditional, } } - cppReader_reserve (pfile, - size_fromInt (4 * cstring_length (ip->nominal_fname) + 50)); + cpplib_reserve (pfile, 4 * cstring_length (ip->nominal_fname) + 50); { #ifdef OUTPUT_LINE_COMMANDS @@ -2621,8 +3269,8 @@ output_line_command (cppReader *pfile, bool conditional, cppReader_putStrN (pfile, sharp_line, sizeof(sharp_line)-1); } - sprintf (cppReader_getPWritten (pfile), "%d ", line); - cppReader_adjustWritten (pfile, strlen (cppReader_getPWritten (pfile))); + sprintf (cpplib_getPWritten (pfile), "%d ", line); + cppReader_adjustWritten (pfile, strlen (cpplib_getPWritten (pfile))); quote_string (pfile, cstring_toCharsSafe (ip->nominal_fname)); @@ -2669,7 +3317,7 @@ macarg (cppReader *pfile, int rest_args) for (;;) { - token = cppGetToken (pfile); + token = cpplib_getToken (pfile); switch (token) { @@ -2824,7 +3472,15 @@ special_symbol (hashNode hp, cppReader *pfile) string = ""; } - cppReader_reserve (pfile, 3 + 4 * strlen (string)); + cpplib_reserve (pfile, 3 + 4 * strlen (string)); + quote_string (pfile, string); + return; + } + case T_FUNC: /* added in ISO C99 */ + { + /* We don't know the actual name of the function, but it doesn't matter */ + char *string = "** function-name **"; + cpplib_reserve (pfile, 3 + 4 * strlen (string)); quote_string (pfile, string); return; } @@ -2846,7 +3502,7 @@ special_symbol (hashNode hp, cppReader *pfile) break; case T_VERSION: - buf = message ("\"%s\"", cstring_makeLiteralTemp (CPP_VERSION)); + buf = cstring_makeLiteral ("\"--- cpp version---\""); break; #ifndef NO_BUILTIN_SIZE_TYPE @@ -2920,7 +3576,7 @@ special_symbol (hashNode hp, cppReader *pfile) case T_SPEC_DEFINED: buf = cstring_makeLiteral (" 0 "); /* Assume symbol is not defined */ ip = cppReader_getBuffer (pfile); - + llassert (ip != NULL); llassert (ip->cur != NULL); SKIP_WHITE_SPACE (ip->cur); @@ -2933,10 +3589,10 @@ special_symbol (hashNode hp, cppReader *pfile) if (!is_idstart[(int) *ip->cur]) goto oops; - if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"')) + if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '\"')) goto oops; - if ((hp = cppReader_lookup (ip->cur, -1, -1)) != 0) + if ((hp = cpphash_lookup (ip->cur, -1, -1)) != 0) { cstring_free (buf); buf = cstring_makeLiteral (" 1 "); @@ -2968,9 +3624,9 @@ special_symbol (hashNode hp, cppReader *pfile) llfatalerror (message ("Pre-processing error: invalid special hash type")); } - len = size_fromInt (cstring_length (buf)); + len = cstring_length (buf); - cppReader_reserve (pfile, len + 1); + cpplib_reserve (pfile, len + 1); cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len); cppReader_nullTerminateQ (pfile); @@ -2987,7 +3643,7 @@ dump_special_to_buffer (cppReader *pfile, char *macro_name) static char define_directive[] = "#define "; size_t macro_name_length = strlen (macro_name); output_line_command (pfile, 0, same_file); - cppReader_reserve (pfile, sizeof(define_directive) + macro_name_length); + cpplib_reserve (pfile, sizeof(define_directive) + macro_name_length); cppReader_putStrN (pfile, define_directive, sizeof(define_directive)-1); cppReader_putStrN (pfile, macro_name, macro_name_length); cppReader_putCharQ (pfile, ' '); @@ -2998,10 +3654,10 @@ dump_special_to_buffer (cppReader *pfile, char *macro_name) /* Initialize the built-in macros. */ static void -cppReader_installBuiltin (/*@observer@*/ char *name, ctype ctyp, - int len, enum node_type type, - int ivalue, /*@null@*/ /*@only@*/ char *value, - int hash) +cpplib_installBuiltin (/*@observer@*/ char *name, ctype ctyp, + int len, enum node_type type, + int ivalue, /*@null@*/ /*@only@*/ char *value, + int hash) { cstring sname = cstring_fromCharsNew (name); @@ -3031,67 +3687,61 @@ cppReader_installBuiltin (/*@observer@*/ char *name, ctype ctyp, ; } - (void) cppReader_install (name, len, type, ivalue, value, hash); + (void) cpphash_install (name, len, type, ivalue, value, hash); cstring_free (sname); } static void -cppReader_installBuiltinType (/*@observer@*/ char *name, ctype ctyp, - int len, enum node_type type, - int ivalue, - /*@only@*/ /*@null@*/ char *value, int hash) +cpplib_installBuiltinType (/*@observer@*/ char *name, ctype ctyp, + int len, enum node_type type, + int ivalue, + /*@only@*/ /*@null@*/ char *value, int hash) { cstring sname = cstring_fromChars (name); - /* evs 2000 07 10 - removed a memory leak, detected by lclint */ + /* evs 2000 07 10 - removed a memory leak, detected by splint */ llassert (usymtab_inGlobalScope ()); if (!usymtab_existsTypeEither (sname)) { uentry ue = uentry_makeDatatype (sname, ctyp, - NO, NO, + NO, qual_createConcrete (), fileloc_createBuiltin ()); llassert (!usymtab_existsEither (sname)); usymtab_addGlobalEntry (ue); } - (void) cppReader_install (name, len, type, ivalue, value, hash); + (void) cpphash_install (name, len, type, ivalue, value, hash); } static void initialize_builtins (cppReader *pfile) { - cppReader_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1); - cppReader_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1); - cppReader_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1); - cppReader_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1); - cppReader_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1); - cppReader_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1); + cpplib_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1); + cpplib_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1); + cpplib_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1); + cpplib_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1); + cpplib_installBuiltin ("__func__", ctype_string, -1, T_FUNC, 0, NULL, -1); + cpplib_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1); + cpplib_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1); #ifndef NO_BUILTIN_SIZE_TYPE - cppReader_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1); + cpplib_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1); #endif #ifndef NO_BUILTIN_PTRDIFF_TYPE - cppReader_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1); + cpplib_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1); #endif - cppReader_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1); - cppReader_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1); - cppReader_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1); - cppReader_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1); - - /* - ** No, don't define __STDC__ - ** + cpplib_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1); + cpplib_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1); + cpplib_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1); + cpplib_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1); if (!cppReader_isTraditional (pfile)) { - cppReader_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1); + cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1); } - ** - */ - # ifdef WIN32 - cppReader_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1); + cpplib_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1); # endif /* @@ -3099,10 +3749,123 @@ initialize_builtins (cppReader *pfile) ** so that it is present only when truly compiling with GNU C. */ - /* cppReader_install ("__GNUC__", -1, T_CONST, 2, 0, -1); */ + /* cpplib_install ("__GNUC__", -1, T_CONST, 2, 0, -1); */ + + cpplib_installBuiltin ("S_SPLINT_S", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1); + + /*drl 1/9/2001/ try to define the right symbol for the architecture + We use autoconf to determine the target cpu + */ + cpplib_installBuiltin ("__" TARGET_CPU, ctype_int, -1, T_CONST, 2, NULL, -1); + + /*drl 1/2/2002 set some flags based on uname + I'd like to be able to do this with autoconf macro instead... + */ - cppReader_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1); + /*Thanks to Nelson Beebe for suggesting possible values for these */ + + if (! strcmp (UNAME, "Linux")) + { +#ifdef __ppc + cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1); +#endif + } + + else if(! strcmp (UNAME, "Darwin")) + { + cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1); + } + else if(! strcmp (UNAME, "HP-UX")) + { + cpplib_installBuiltin ("PWB", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_HIUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_HPUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_PA_RISC1_1", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__PWB", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__PWB__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__STDC_EXT__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hp9000s700", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hp9000s800__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hp9k8__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hppa", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hppa__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hpux", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__hpux__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__unix__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("hppa", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("hpux", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1); + } + else if(! strcmp (UNAME, "IRIX64")) + { + cpplib_installBuiltin ("LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_ABIN32", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_COMPILER_VERSION", ctype_int, -1, T_CONST, 730, NULL, -1); + cpplib_installBuiltin ("_LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_LONGLONG", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_MIPS_FPSET", ctype_int, -1, T_CONST, 32, NULL, -1); + cpplib_installBuiltin ("_MIPS_ISA", ctype_int, -1, T_CONST, 3, NULL, -1); + /*_MIPS_SIM=_ABIN32*/ + cpplib_installBuiltin ("_MIPS_SIM", ctype_int, -1, T_CONST, 2, NULL , -1); + cpplib_installBuiltin ("_MIPS_SZINT", ctype_int, -1, T_CONST, 32, NULL, -1); + cpplib_installBuiltin ("_MIPS_SZLONG", ctype_int, -1, T_CONST, 32, NULL, -1); + cpplib_installBuiltin ("_MIPS_SZPTR", ctype_int, -1, T_CONST, 32, NULL, -1); + cpplib_installBuiltin ("_MODERN_C", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_PIC", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_SGI_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_SIZE_INT", ctype_int, -1, T_CONST, 32, NULL, -1); + cpplib_installBuiltin ("_SIZE_LONG", ctype_int, -1, T_CONST, 32, NULL, -1); + cpplib_installBuiltin ("_SIZE_PTR", ctype_int, -1, T_CONST, 32, NULL, -1); + cpplib_installBuiltin ("_SVR4_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("_SYSTYPE_SVR4", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__DSO__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__EXTENSIONS__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__INLINE_INTRINSICS", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__MATH_HAS_NO_SIDE_EFFECTS", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__host_mips", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__mips", ctype_int, -1, T_CONST, 3, NULL, -1); + cpplib_installBuiltin ("__sgi", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("host_mips", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("mips", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("sgi", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1); + } + else if(! strcmp (UNAME, "OSF1")) + { + cpplib_installBuiltin ("__alpha", ctype_int, -1, T_CONST, 2, NULL, -1); + } + else if (!strcmp (UNAME, "Rhapsody")) + { + cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1); + } + + else if (!strcmp (UNAME, "SunOS")) + { + cpplib_installBuiltin ("__OPEN_MAX", ctype_int, -1, T_CONST, 20, NULL, -1); + cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, 2, NULL, -1); + cpplib_installBuiltin ("__sparc", ctype_int, -1, T_CONST, 2, NULL, -1); + /* This define "-Dfileno(f)=0" should be inserted but we're going to stick to deinfe constants for now...*/ + } + else + { + /* + types which we have not explictedly handled. + AIX, FreeBSD, IRIX, Mach + */ + } + if (CPPOPTIONS (pfile)->debug_output) { dump_special_to_buffer (pfile, "__BASE_FILE__"); @@ -3175,7 +3938,7 @@ unsafe_chars (char c1, char c2) an argument list follows; arguments come from the input stack. */ static void -macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) +cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp) { int nargs; DEFINITION *defn = hp->value.defn; @@ -3183,16 +3946,18 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) char *oxbuf = NULL; int start_line; int start_column; + int end_line; + int end_column; size_t xbuf_len; - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); int rest_args; int rest_zero = 0; int i; struct argdata *args = NULL; pfile->output_escapes++; - - cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column); + cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column); + DPRINTF (("Expand macro: %d:%d", start_line, start_column)); nargs = defn->nargs; @@ -3237,9 +4002,9 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) rest_args = 1; } - args[i].raw = size_toLong (cppReader_getWritten (pfile)); + args[i].raw = size_toLong (cpplib_getWritten (pfile)); token = macarg (pfile, rest_args); - args[i].raw_length = cppReader_getWritten (pfile) - args[i].raw; + args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw); args[i].newlines = FALSE; /* FIXME */ } else @@ -3326,6 +4091,14 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) } } + /* + ** If the agrument list was multiple lines, need to insert new lines to keep line + ** numbers accurate. + */ + + cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &end_line, &end_column); + DPRINTF (("Expand macro: %d:%d", end_line, end_column)); + /* If macro wants zero args, we parsed the arglist for checking only. Read directly from the macro definition. */ @@ -3375,7 +4148,7 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) int need_space = -1; i = 0; - arg->stringified = cppReader_getWritten (pfile); + arg->stringified = cpplib_getWritten (pfile); if (!cppReader_isTraditional (pfile)) cppReader_putChar (pfile, '\"'); /* insert beginning quote */ for (; i < arglen; i++) @@ -3388,8 +4161,8 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) one space except within an string or char token.*/ if (is_space[(int) c]) { - if (cppReader_getWritten (pfile) > arg->stringified - && (cppReader_getPWritten (pfile))[-1] == '@') + if (cpplib_getWritten (pfile) > arg->stringified + && (cpplib_getPWritten (pfile))[-1] == '@') { /* "@ " escape markers are removed */ cppReader_adjustWritten (pfile, -1); @@ -3438,8 +4211,8 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) cppReader_putChar (pfile, c); else { - cppReader_reserve (pfile, 4); - sprintf (cppReader_getPWritten (pfile), "\\%03o", + cpplib_reserve (pfile, 4); + sprintf (cpplib_getPWritten (pfile), "\\%03o", (unsigned int) c); cppReader_adjustWritten (pfile, 4); } @@ -3447,16 +4220,15 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) if (!cppReader_isTraditional (pfile)) cppReader_putChar (pfile, '\"'); /* insert ending quote */ arg->stringified_length - = size_toInt (cppReader_getWritten (pfile) - arg->stringified); + = size_toInt (cpplib_getWritten (pfile) - arg->stringified); } xbuf_len += args[ap->argno].stringified_length; } else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile)) { - /* Add 4 for two newline-space markers to prevent - token concatenation. */ - assertSet (args); /*@i534 shouldn't need this */ + /* Add 4 for two newline-space markers to prevent token concatenation. */ + assertSet (args); /* Splint shouldn't need this */ xbuf_len += args[ap->argno].raw_length + 4; } else @@ -3464,17 +4236,17 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) /* We have an ordinary (expanded) occurrence of the arg. So compute its expansion, if we have not already. */ - assertSet (args); /*@i534 shouldn't need this */ + assertSet (args); /* shouldn't need this */ if (args[ap->argno].expand_length < 0) { - args[ap->argno].expanded = cppReader_getWritten (pfile); + args[ap->argno].expanded = cpplib_getWritten (pfile); cpp_expand_to_buffer (pfile, ARG_BASE + args[ap->argno].raw, size_fromInt (args[ap->argno].raw_length)); args[ap->argno].expand_length - = size_toInt (cppReader_getWritten (pfile) - args[ap->argno].expanded); + = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded); } /* Add 4 for two newline-space markers to prevent @@ -3671,12 +4443,53 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) /* Now put the expansion on the input stack so our caller will commence reading from it. */ + DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len))); + + if (end_line != start_line) + { + /* xbuf must have enough newlines */ + int newlines = end_line - start_line; + int foundnewlines = 0; + char *xbufptr = xbuf; + + while ((xbufptr = strchr (xbufptr, '\n')) != NULL && foundnewlines <= newlines) + { + foundnewlines++; + xbufptr++; + + if (*xbufptr == '\0') + { + break; + } + } + + if (foundnewlines < newlines) + { + cstring newbuf = cstring_copyLength (xbuf, xbuf_len); + + while (foundnewlines < newlines) + { + newbuf = cstring_appendChar (newbuf, '\n'); + foundnewlines++; + } + + sfree (oxbuf); + xbuf = cstring_toCharsSafe (newbuf); + xbuf_len = cstring_length (newbuf); + /*@-branchstate@*/ + } /*@=branchstate@*/ + } + + DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len))); + push_macro_expansion (pfile, xbuf, xbuf_len, hp); - cppReader_getBuffer (pfile)->has_escapes = 1; + DPRINTF (("After pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len))); + cppReader_getBufferSafe (pfile)->has_escapes = 1; /* Pop the space we've used in the token_buffer for argument expansion. */ cppReader_setWritten (pfile, old_written); - + DPRINTF (("Done set written")); + /* Recursive macro use sometimes works traditionally. #define foo(x,y) bar (x (y,0), y) foo (foo, baz) */ @@ -3726,12 +4539,14 @@ push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len, || xbuf[2] == '\"')) { llassert (mbuf->cur != NULL); + DPRINTF (("Eating: %c", xbuf[2])); mbuf->cur += 2; } + } -/* Like cppGetToken, except that it does not read past end-of-line. +/* Like cpplib_getToken, except that it does not read past end-of-line. Also, horizontal space is skipped, and macros are popped. */ static enum cpp_token @@ -3739,7 +4554,7 @@ get_directive_token (cppReader *pfile) { for (;;) { - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); enum cpp_token token; cppSkipHspace (pfile); if (cppReader_peekC (pfile) == '\n') @@ -3747,7 +4562,7 @@ get_directive_token (cppReader *pfile) return CPP_VSPACE; } - token = cppGetToken (pfile); + token = cpplib_getToken (pfile); switch (token) { @@ -3770,7 +4585,7 @@ get_directive_token (cppReader *pfile) This function expects to see "fname" or on the input. The input is normally in part of the output_buffer following - cppReader_getWritten, and will get overwritten by output_line_command. + cpplib_getWritten, and will get overwritten by output_line_command. I.e. in input file specification has been popped by cppReader_handleDirective. This is safe. */ @@ -3787,9 +4602,8 @@ do_include (cppReader *pfile, struct directive *keyword, struct file_name_list *search_start = CPPOPTIONS (pfile)->include; struct file_name_list dsp[1]; /* First in chain, if #include "..." */ struct file_name_list *searchptr = NULL; - size_t old_written = cppReader_getWritten (pfile); - - int flen; + size_t old_written = cpplib_getWritten (pfile); + size_t flen; int f; /* file number */ int angle_brackets = 0; /* 0 for "...", 1 for <...> */ @@ -3803,7 +4617,7 @@ do_include (cppReader *pfile, struct directive *keyword, { /* FIXME - check no trailing garbage */ fbeg = pfile->token_buffer + old_written + 1; - fend = cppReader_getPWritten (pfile) - 1; + fend = cpplib_getPWritten (pfile) - 1; if (fbeg[-1] == '<') { angle_brackets = 1; @@ -3857,8 +4671,8 @@ do_include (cppReader *pfile, struct directive *keyword, /*@=onlytrans@*/ nam[n] = save; - if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len) - pfile->max_include_len = n + INCLUDE_LEN_FUDGE; + if (n + INCLUDE_LEN_FUDGE > size_toInt (pfile->max_include_len)) + pfile->max_include_len = size_fromInt (n + INCLUDE_LEN_FUDGE); } else { @@ -3890,7 +4704,7 @@ do_include (cppReader *pfile, struct directive *keyword, if (CPPOPTIONS (pfile)->first_bracket_include) search_start = CPPOPTIONS (pfile)->first_bracket_include; fbeg = pfile->token_buffer + old_written; - fend = cppReader_getPWritten (pfile); + fend = cpplib_getPWritten (pfile); } #endif else @@ -3952,10 +4766,10 @@ do_include (cppReader *pfile, struct directive *keyword, } } } - + cppReader_setWritten (pfile, old_written); - flen = fend - fbeg; + flen = size_fromInt (fend - fbeg); DPRINTF (("fbeg: %s", fbeg)); @@ -4069,7 +4883,7 @@ do_include (cppReader *pfile, struct directive *keyword, if (f == IMPORT_FOUND) { - return 0; /* Already included this file */ + return 0; /* Already included this file */ } #ifdef EACCES else if (f == IMPORT_NOT_FOUND && errno == EACCES) @@ -4180,7 +4994,7 @@ redundant_include_p (cppReader *pfile, cstring name) { if (cstring_equal (name, l->fname) && (l->control_macro != NULL) - && (cppReader_lookup (l->control_macro, -1, -1) != NULL)) + && (cpphash_lookup (l->control_macro, -1, -1) != NULL)) { return TRUE; } @@ -4209,21 +5023,22 @@ is_system_include (cppReader *pfile, cstring filename) searchptr != NULL; searchptr = searchptr->next) { - if (!cstring_isEmpty (searchptr->fname)) { - cstring sys_dir = searchptr->fname; - int length = cstring_length (sys_dir); - - if (cstring_equalLen (sys_dir, filename, length) - && osd_isConnectChar (cstring_getChar (filename, length))) - { - if (searchptr->c_system_include_path) - return 2; - else - return 1; - } - } + if (!cstring_isEmpty (searchptr->fname)) + { + cstring sys_dir = searchptr->fname; + size_t length = cstring_length (sys_dir); + + if (cstring_equalLen (sys_dir, filename, length) + && osd_isConnectChar (cstring_getChar (filename, length))) + { + if (searchptr->c_system_include_path) + return 2; + else + return 1; + } + } } - + return 0; } @@ -4290,10 +5105,11 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword) { cppBuffer *ip = cppReader_getBuffer (pfile); int new_lineno; - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); enum file_change_code file_change = same_file; enum cpp_token token; + llassert (ip != NULL); token = get_directive_token (pfile); if (token != CPP_NUMBER @@ -4326,11 +5142,11 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword) hashNode *hash_bucket; char *p; size_t num_start; - int fname_length; + size_t fname_length; /* Turn the file name, which is a character string literal, into a null-terminated string. Do this in place. */ - end_name = convert_string (pfile, fname, fname, cppReader_getPWritten (pfile), 1); + end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1); if (end_name == NULL) { cppReader_errorLit (pfile, @@ -4338,8 +5154,8 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword) goto bad_line_directive; } - fname_length = end_name - fname; - num_start = cppReader_getWritten (pfile); + fname_length = size_fromInt (end_name - fname); + num_start = cpplib_getWritten (pfile); token = get_directive_token (pfile); if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) { @@ -4379,16 +5195,22 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword) } hash_bucket = - &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)]; + &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)]; + for (hp = *hash_bucket; hp != NULL; hp = hp->next) { - if (hp->length == fname_length && - strncmp (hp->value.cpval, fname, size_fromInt (fname_length)) == 0) { - ip->nominal_fname = cstring_fromChars (hp->value.cpval); - break; - } + if (hp->length == fname_length) + { + llassert (hp->value.cpval != NULL); + + if (strncmp (hp->value.cpval, fname, fname_length) == 0) + { + ip->nominal_fname = cstring_fromChars (hp->value.cpval); + break; + } + } } - + if (hp == 0) { /* Didn't find it; cons up a new one. */ hp = (hashNode) dmalloc (sizeof (*hp)); @@ -4403,7 +5225,7 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword) hp->length = fname_length; hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1)); - memcpy (hp->value.cpval, fname, size_fromInt (fname_length)); + memcpy (hp->value.cpval, fname, fname_length); hp->value.cpval[fname_length] = '\0'; ip->nominal_fname = cstring_fromChars (hp->value.cpval); } @@ -4437,7 +5259,7 @@ static int do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit) { - int sym_length; + size_t sym_length; hashNode hp; char *orig_buf = buf; @@ -4445,7 +5267,7 @@ do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit) sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro")); - while ((hp = cppReader_lookup (buf, sym_length, -1)) != NULL) + while ((hp = cpphash_lookup (buf, size_toInt (sym_length), -1)) != NULL) { /* If we are generating additional info for debugging (with -g) we need to pass through all effective #undef commands. */ @@ -4488,7 +5310,7 @@ static int do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword, char *buf, char *limit) { - int length = limit - buf; + size_t length = size_fromInt (limit - buf); cstring copy = cstring_copyLength (buf, length); cstring adv = cstring_advanceWhiteSpace (copy); @@ -4507,7 +5329,7 @@ static int do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword, char *buf, char *limit) { - int length = limit - buf; + size_t length = size_fromInt (limit - buf); cstring copy = cstring_copyLength (buf, length); cstring adv = cstring_advanceWhiteSpace (copy); cppReader_warning (pfile, message ("#warning %s", adv)); @@ -4523,11 +5345,12 @@ do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword, /*@unused@*/ char *buf, /*@unused@*/ char *limit) { /* Allow #ident in system headers, since that's not user's fault. */ - if (cppReader_isPedantic (pfile) && !cppReader_getBuffer (pfile)->system_header_p) + if (cppReader_isPedantic (pfile) + && !cppReader_getBufferSafe (pfile)->system_header_p) cppReader_pedwarnLit (pfile, cstring_makeLiteralTemp ("ANSI C does not allow `#ident'")); - /* Leave rest of line to be read by later calls to cppGetToken. */ + /* Leave rest of line to be read by later calls to cpplib_getToken. */ return 0; } @@ -4549,14 +5372,14 @@ do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword, been included yet. */ struct file_name_list *ptr; char *p = buf + 14, *fname, *inc_fname; - int fname_len; + size_t fname_len; SKIP_WHITE_SPACE (p); if (*p == '\n' || *p != '\"') return 0; fname = p + 1; p = (char *) strchr (fname, '\"'); - fname_len = p != NULL ? p - fname : mstring_length (fname); + fname_len = p != NULL ? size_fromInt (p - fname) : mstring_length (fname); for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next) { @@ -4565,7 +5388,7 @@ do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword, ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname); if ((inc_fname != NULL) - && (strncmp (inc_fname, fname, size_fromInt (fname_len)) == 0)) + && (strncmp (inc_fname, fname, fname_len) == 0)) { cpp_setLocation (pfile); @@ -4596,7 +5419,9 @@ static int do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword, char *buf, char *limit) { - HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf); + HOST_WIDE_INT value; + DPRINTF (("Do if: %s", buf)); + value = eval_if_expression (pfile, buf, limit - buf); conditional_skip (pfile, value == 0, T_IF, NULL); return 0; } @@ -4609,7 +5434,7 @@ do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword, static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword, char *buf, char *limit) { - if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) + if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) { cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional")); @@ -4625,9 +5450,9 @@ static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword, cstring_makeLiteralTemp ("`#elif' after `#else'")); if (pfile->if_stack->fname != NULL - && cppReader_getBuffer (pfile)->fname != NULL + && cppReader_getBufferSafe (pfile)->fname != NULL && !cstring_equal (pfile->if_stack->fname, - cppReader_getBuffer (pfile)->nominal_fname)) + cppReader_getBufferSafe (pfile)->nominal_fname)) fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname)); fprintf (stderr, ")\n"); } @@ -4665,17 +5490,18 @@ eval_if_expression (cppReader *pfile, { hashNode save_defined; HOST_WIDE_INT value; - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); - save_defined = cppReader_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1); + DPRINTF (("Saving defined...")); + save_defined = cpphash_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1); pfile->pcp_inside_if = 1; value = cppReader_parseExpression (pfile); pfile->pcp_inside_if = 0; /* Clean up special symbol */ + DPRINTF (("Removing defined...")); cppReader_deleteMacro (save_defined); - cppReader_setWritten (pfile, old_written); /* Pop */ return value; @@ -4692,13 +5518,13 @@ do_xifdef (cppReader *pfile, struct directive *keyword, /*@unused@*/ char *unused1, /*@unused@*/ char *unused2) { int skip; - cppBuffer *ip = cppReader_getBuffer (pfile); + cppBuffer *ip = cppReader_getBufferSafe (pfile); char *ident; - int ident_length; + size_t ident_length; enum cpp_token token; int start_of_file = 0; char *control_macro = 0; - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); DPRINTF (("do xifdef: %d", keyword->type == T_IFNDEF)); @@ -4714,7 +5540,9 @@ do_xifdef (cppReader *pfile, struct directive *keyword, pfile->no_macro_expand--; ident = pfile->token_buffer + old_written; - ident_length = size_toInt (cppReader_getWritten (pfile) - old_written); + DPRINTF (("Ident: %s", ident)); + + ident_length = cpplib_getWritten (pfile) - old_written; cppReader_setWritten (pfile, old_written); /* Pop */ if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF) @@ -4723,25 +5551,22 @@ do_xifdef (cppReader *pfile, struct directive *keyword, if (! cppReader_isTraditional (pfile)) { cppReader_pedwarn (pfile, - message ("`#%s' with no argument", keyword->name)); + message ("`#%s' with no argument", keyword->name)); } } else if (token == CPP_NAME) { - hashNode hp = cppReader_lookup (ident, ident_length, -1); - skip = (keyword->type == T_IFDEF) - ? (hp == NULL) : (hp != NULL); + hashNode hp = cpphash_lookup (ident, size_toInt (ident_length), -1); - DPRINTF (("hp null: %d / %d / %d", - (hp == NULL), - (keyword->type == T_IFNDEF), - skip)); - + skip = (keyword->type == T_IFDEF) ? (hp == NULL) : (hp != NULL); + + DPRINTF (("hp null: %d / %d / %d", hp == NULL, keyword->type == T_IFNDEF, skip)); + if (start_of_file && !skip) { DPRINTF (("Not skipping!")); - control_macro = (char *) dmalloc (size_fromInt (ident_length + 1)); - memcpy (control_macro, ident, size_fromInt (ident_length + 1)); + control_macro = (char *) dmalloc (ident_length + 1); + memcpy (control_macro, ident, ident_length + 1); } } else @@ -4785,7 +5610,7 @@ conditional_skip (cppReader *pfile, int skip, { cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp)); - temp->fname = cppReader_getBuffer (pfile)->nominal_fname; + temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname; temp->next = pfile->if_stack; temp->control_macro = control_macro; temp->lineno = 0; @@ -4834,7 +5659,7 @@ skip_if_group (cppReader *pfile, int any) beg_of_line: if (CPPOPTIONS (pfile)->output_conditionals) { - cppBuffer *pbuf = cppReader_getBuffer (pfile); + cppBuffer *pbuf = cppReader_getBufferSafe (pfile); char *start_line; llassert (pbuf->buf != NULL); @@ -4853,11 +5678,11 @@ beg_of_line: c = cppReader_getC (pfile); if (c == '#') { - size_t old_written = cppReader_getWritten (pfile); + size_t old_written = cpplib_getWritten (pfile); cppSkipHspace (pfile); parse_name (pfile, cppReader_getC (pfile)); - ident_length = size_toInt (cppReader_getWritten (pfile) - old_written); + ident_length = size_toInt (cpplib_getWritten (pfile) - old_written); ident = pfile->token_buffer + old_written; pfile->limit = ident; @@ -4880,7 +5705,7 @@ beg_of_line: case T_IFNDEF: temp = (cppIfStackFrame *) dmalloc (sizeof (*temp)); temp->next = pfile->if_stack; - temp->fname = cppReader_getBuffer (pfile)->nominal_fname; + temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname; temp->type = kt->type; temp->lineno = 0; temp->if_succeeded = 0; @@ -4895,7 +5720,7 @@ beg_of_line: cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif")); /*@fallthrough@*/ case T_ELIF: - if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) + if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) { cppReader_error (pfile, message ("Preprocessor command #%s is not within a conditional", kt->name)); @@ -4931,6 +5756,11 @@ beg_of_line: /*@switchbreak@*/ break; default: ; /*@-branchstate@*/ +#if defined (OS2) && defined (__IBMC__) + /* Dummy code to eleminate optimization problems with icc */ + c = 0; +# endif + } /*@=branchstate@*/ break; @@ -4964,8 +5794,8 @@ beg_of_line: case '\"': case '\'': cppReader_forward (pfile, -1); - old = cppReader_getWritten (pfile); - (void) cppGetToken (pfile); + old = cpplib_getWritten (pfile); + (void) cpplib_getToken (pfile); cppReader_setWritten (pfile, old); /*@switchbreak@*/ break; case '\\': @@ -5011,7 +5841,7 @@ do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword, cppReader_skipRestOfLine (pfile); - if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) { + if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) { cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional")); return 0; @@ -5061,7 +5891,7 @@ do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword, cppReader_skipRestOfLine (pfile); - if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) + if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) { cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif")); } @@ -5106,7 +5936,7 @@ do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword, for ( ; ifile != NULL; ifile = ifile->next) { - if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname)) + if (cstring_equal (ifile->fname, cppReader_getBufferSafe (pfile)->fname)) { ifile->control_macro = temp->control_macro; break; @@ -5144,22 +5974,35 @@ validate_else (cppReader *pfile, cstring directive) */ enum cpp_token -cppGetToken (cppReader *pfile) +cpplib_getToken (cppReader *pfile) +{ + return cpplib_getTokenAux (pfile, FALSE); +} + +enum cpp_token +cpplib_getTokenForceExpand (cppReader *pfile) +{ + return cpplib_getTokenAux (pfile, TRUE); +} + +enum cpp_token +cpplib_getTokenAux (cppReader *pfile, bool forceExpand) { int c, c2, c3; size_t old_written = 0; int start_line, start_column; enum cpp_token token; struct cppOptions *opts = CPPOPTIONS (pfile); - cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur; + cppReader_getBufferSafe (pfile)->prev = cppReader_getBufferSafe (pfile)->cur; get_next: c = cppReader_getC (pfile); + DPRINTF (("Get next token: %c", c)); if (c == EOF) { handle_eof: - if (cppReader_getBuffer (pfile)->seen_eof) + if (cppReader_getBufferSafe (pfile)->seen_eof) { cppBuffer *buf = cppReader_popBuffer (pfile); @@ -5174,10 +6017,10 @@ get_next: } else { - cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile)); - cppReader_getBuffer (pfile)->seen_eof = 1; + cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile)); + cppReader_getBufferSafe (pfile)->seen_eof = 1; - if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname) + if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname) && next_buf != cppReader_nullBuffer (pfile)) { /* We're about to return from an #include file. @@ -5211,10 +6054,10 @@ get_next: } newlines = 0; - cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), + cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column); c = skip_comment (pfile, &newlines); - + DPRINTF (("c = %c", c)); if (opts->put_out_comments && (c == '/' || c == EOF)) { assertSet (&start_mark); @@ -5249,7 +6092,7 @@ get_next: } else { - cppReader_reserve(pfile, 1); + cpplib_reserve(pfile, 1); cppReader_putCharQ (pfile, ' '); return CPP_HSPACE; } @@ -5272,16 +6115,22 @@ get_next: case '\'': /* A single quoted string is treated like a double -- some programs (e.g., troff) are perverse this way */ - cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), - &start_line, &start_column); - old_written = cppReader_getWritten (pfile); + cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), + &start_line, &start_column); + old_written = cpplib_getWritten (pfile); string: + DPRINTF (("Reading string: %c", c)); cppReader_putChar (pfile, c); while (TRUE) { - int cc = cppReader_getC (pfile); - if (cc == EOF) + /* evans-2003-06-07 + ** Because of ISO8859-1 characters in string literals, we need a special test here. + */ + + if (cppReader_reachedEOF (pfile)) { + + DPRINTF (("Matches EOF!")); if (cppBuffer_isMacro (CPPBUFFER (pfile))) { /* try harder: this string crosses a macro expansion @@ -5289,19 +6138,20 @@ get_next: Otherwise, only -D can make a macro with an unmatched quote. */ cppBuffer *next_buf - = cppBuffer_prevBuffer (cppReader_getBuffer (pfile)); - (*cppReader_getBuffer (pfile)->cleanup) - (cppReader_getBuffer (pfile), pfile); + = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile)); + (*cppReader_getBufferSafe (pfile)->cleanup) + (cppReader_getBufferSafe (pfile), pfile); CPPBUFFER (pfile) = next_buf; continue; } + if (!cppReader_isTraditional (pfile)) { cpp_setLocation (pfile); setLine (long_toInt (start_line)); setColumn (long_toInt (start_column)); - + if (pfile->multiline_string_line != long_toInt (start_line) && pfile->multiline_string_line != 0) { @@ -5321,63 +6171,69 @@ get_next: message ("Unterminated string or character constant")); } } - /*@loopbreak@*/ break; - } - cppReader_putChar (pfile, cc); - switch (cc) + /*@loopbreak@*/ break; + } + else { - case '\n': - /* Traditionally, end of line ends a string constant with - no error. So exit the loop and record the new line. */ - if (cppReader_isTraditional (pfile)) - goto while2end; - if (c == '\'') - { - goto while2end; - } - if (cppReader_isPedantic (pfile) - && pfile->multiline_string_line == 0) - { - cppReader_pedwarnWithLine - (pfile, long_toInt (start_line), - long_toInt (start_column), - cstring_makeLiteral ("String constant runs past end of line")); - } - if (pfile->multiline_string_line == 0) - { - pfile->multiline_string_line = start_line; - } - - /*@switchbreak@*/ break; - - case '\\': - cc = cppReader_getC (pfile); - if (cc == '\n') + int cc = cppReader_getC (pfile); + DPRINTF (("cc: %c [%d] [%d]", cc, cc, EOF)); + DPRINTF (("putting char: %c", cc)); + cppReader_putChar (pfile, cc); + switch (cc) { - /* Backslash newline is replaced by nothing at all. */ - cppReader_adjustWritten (pfile, -1); - pfile->lineno++; - } - else - { - /* ANSI stupidly requires that in \\ the second \ - is *not* prevented from combining with a newline. */ - NEWLINE_FIX1(cc); - if (cc != EOF) - cppReader_putChar (pfile, cc); + case '\n': + /* Traditionally, end of line ends a string constant with + no error. So exit the loop and record the new line. */ + if (cppReader_isTraditional (pfile)) + goto while2end; + if (c == '\'') + { + goto while2end; + } + if (cppReader_isPedantic (pfile) + && pfile->multiline_string_line == 0) + { + cppReader_pedwarnWithLine + (pfile, long_toInt (start_line), + long_toInt (start_column), + cstring_makeLiteral ("String constant runs past end of line")); + } + if (pfile->multiline_string_line == 0) + { + pfile->multiline_string_line = start_line; + } + + /*@switchbreak@*/ break; + + case '\\': + cc = cppReader_getC (pfile); + if (cc == '\n') + { + /* Backslash newline is replaced by nothing at all. */ + cppReader_adjustWritten (pfile, -1); + pfile->lineno++; + } + else + { + /* ANSI stupidly requires that in \\ the second \ + is *not* prevented from combining with a newline. */ + NEWLINE_FIX1(cc); + if (cc != EOF) + cppReader_putChar (pfile, cc); + } + /*@switchbreak@*/ break; + + case '\"': + case '\'': + if (cc == c) + goto while2end; + /*@switchbreak@*/ break; } - /*@switchbreak@*/ break; - - case '\"': - case '\'': - if (cc == c) - goto while2end; - /*@switchbreak@*/ break; } } while2end: pfile->lineno += count_newlines (pfile->token_buffer + old_written, - cppReader_getPWritten (pfile)); + cpplib_getPWritten (pfile)); pfile->only_seen_white = 0; return c == '\'' ? CPP_CHAR : CPP_STRING; @@ -5470,7 +6326,7 @@ get_next: if (c2 != c) goto randomchar; cppReader_forward (pfile, 1); - cppReader_reserve (pfile, 4); + cpplib_reserve (pfile, 4); cppReader_putChar (pfile, c); cppReader_putChar (pfile, c2); NEWLINE_FIX; @@ -5482,9 +6338,11 @@ get_next: return CPP_OTHER; case '@': - if (cppReader_getBuffer (pfile)->has_escapes) + DPRINTF (("Macro @!")); + if (cppReader_getBufferSafe (pfile)->has_escapes) { c = cppReader_getC (pfile); + DPRINTF (("got c: %c", c)); if (c == '-') { if (pfile->output_escapes) @@ -5494,7 +6352,7 @@ get_next: } else if (is_space [c]) { - cppReader_reserve (pfile, 2); + cpplib_reserve (pfile, 2); if (pfile->output_escapes) cppReader_putCharQ (pfile, '@'); cppReader_putCharQ (pfile, c); @@ -5516,7 +6374,7 @@ get_next: c2 = cppReader_peekC (pfile); if (isdigit(c2)) { - cppReader_reserve(pfile, 2); + cpplib_reserve(pfile, 2); cppReader_putCharQ (pfile, '.'); c = cppReader_getC (pfile); goto number; @@ -5525,7 +6383,7 @@ get_next: /* FIXME - misses the case "..\\\n." */ if (c2 == '.' && cpp_peekN (pfile, 1) == '.') { - cppReader_reserve(pfile, 4); + cpplib_reserve(pfile, 4); cppReader_putCharQ (pfile, '.'); cppReader_putCharQ (pfile, '.'); cppReader_putCharQ (pfile, '.'); @@ -5538,10 +6396,20 @@ get_next: op2: token = CPP_OTHER; pfile->only_seen_white = 0; - op2any: - cppReader_reserve(pfile, 3); + op2any: /* jumped to for \ continuations */ + cpplib_reserve(pfile, 3); cppReader_putCharQ (pfile, c); - cppReader_putCharQ (pfile, cppReader_getC (pfile)); + + /* evans 2003-08-24: This is a hack to fix line output for \ + continuations. Someday I really should get a decent pre-processor! + */ + + if (c == '\\') { + (void) cppReader_getC (pfile); /* skip the newline to avoid extra lines */ + } else { + cppReader_putCharQ (pfile, cppReader_getC (pfile)); + } + cppReader_nullTerminateQ (pfile); return token; @@ -5562,7 +6430,7 @@ get_next: c2 = '.'; for (;;) { - cppReader_reserve (pfile, 2); + cpplib_reserve (pfile, 2); cppReader_putCharQ (pfile, c); NEWLINE_FIX; c = cppReader_peekC (pfile); @@ -5586,7 +6454,7 @@ get_next: if (opts->chill && cppReader_peekC (pfile) == '\'') { pfile->only_seen_white = 0; - cppReader_reserve (pfile, 2); + cpplib_reserve (pfile, 2); cppReader_putCharQ (pfile, c); cppReader_putCharQ (pfile, '\''); cppReader_forward (pfile, 1); @@ -5608,7 +6476,7 @@ get_next: } if (c == '\'') { - cppReader_reserve (pfile, 2); + cpplib_reserve (pfile, 2); cppReader_putCharQ (pfile, c); cppReader_nullTerminateQ (pfile); return CPP_STRING; @@ -5636,35 +6504,42 @@ get_next: { hashNode hp; char *ident; - size_t before_name_written = cppReader_getWritten (pfile); - int ident_len; + size_t before_name_written = cpplib_getWritten (pfile); + size_t ident_len; parse_name (pfile, c); pfile->only_seen_white = 0; + if (pfile->no_macro_expand) { + DPRINTF (("Not expanding: %s", pfile->token_buffer)); return CPP_NAME; } ident = pfile->token_buffer + before_name_written; - ident_len = (cppReader_getPWritten (pfile)) - ident; + DPRINTF (("Ident: %s", ident)); + + ident_len = size_fromInt ((cpplib_getPWritten (pfile)) - ident); - hp = cppReader_lookupExpand (ident, ident_len, -1); + hp = cpphash_lookupExpand (ident, size_toInt (ident_len), -1, forceExpand); if (hp == NULL) { + DPRINTF (("No expand: %s %d", ident, ident_len)); return CPP_NAME; } if (hp->type == T_DISABLED) { + DPRINTF (("Disabled!")); + if (pfile->output_escapes) { /* Return "@-IDENT", followed by '\0'. */ int i; - cppReader_reserve (pfile, 3); + cpplib_reserve (pfile, 3); ident = pfile->token_buffer + before_name_written; cppReader_adjustWritten (pfile, 2); - for (i = ident_len; i >= 0; i--) + for (i = size_toInt (ident_len); i >= 0; i--) { ident[i+2] = ident[i]; } @@ -5675,36 +6550,50 @@ get_next: return CPP_NAME; } - /* If macro wants an arglist, verify that a '(' follows. - first skip all whitespace, copying it to the output - after the macro name. Then, if there is no '(', - decide this is not a macro call and leave things that way. */ - + /* + ** If macro wants an arglist, verify that a '(' follows. + ** first skip all whitespace, copying it to the output + ** after the macro name. Then, if there is no '(', + ** decide this is not a macro call and leave things that way. + */ + if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) { struct parse_marker macro_mark; int is_macro_call; + DPRINTF (("Arglist macro!")); + + /* + ** evans 2002-07-03: Moved this here (from below). + ** This bug caused necessary whitespace to be lost + ** when parsing parameterized macros without parameters. + */ + + parseSetMark (¯o_mark, pfile); + while (cppBuffer_isMacro (CPPBUFFER (pfile))) { cppBuffer *next_buf; cppSkipHspace (pfile); if (cppReader_peekC (pfile) != EOF) { + DPRINTF (("Peeking!")); /*@loopbreak@*/ break; } - next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile)); - (*cppReader_getBuffer (pfile)->cleanup) (cppReader_getBuffer (pfile), pfile); + next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile)); + (*cppReader_getBufferSafe (pfile)->cleanup) (cppReader_getBufferSafe (pfile), pfile); CPPBUFFER (pfile) = next_buf; } - parseSetMark (¯o_mark, pfile); + /* parseSetMark (¯o_mark, pfile); */ for (;;) { cppSkipHspace (pfile); c = cppReader_peekC (pfile); + DPRINTF (("c: %c", c)); is_macro_call = c == '('; if (c != '\n') /*@loopbreak@*/ break; @@ -5720,9 +6609,11 @@ get_next: if (!is_macro_call) { + DPRINTF (("not macro call!")); return CPP_NAME; } } + /* This is now known to be a macro call. */ /* it might not actually be a macro. */ @@ -5733,17 +6624,20 @@ get_next: cppReader_setWritten (pfile, before_name_written); special_symbol (hp, pfile); - xbuf_len = cppReader_getWritten (pfile) - before_name_written; + xbuf_len = cpplib_getWritten (pfile) - before_name_written; xbuf = (char *) dmalloc (xbuf_len + 1); cppReader_setWritten (pfile, before_name_written); - memcpy (xbuf, cppReader_getPWritten (pfile), xbuf_len + 1); + memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1); push_macro_expansion (pfile, xbuf, xbuf_len, hp); } else { - /* Expand the macro, reading arguments as needed, - and push the expansion on the input stack. */ - macroexpand (pfile, hp); + /* + ** Expand the macro, reading arguments as needed, + ** and push the expansion on the input stack. + */ + + cpplib_macroExpand (pfile, hp); cppReader_setWritten (pfile, before_name_written); } @@ -5759,7 +6653,7 @@ get_next: && pfile->buffer->rlimit[-1] == ' ') { int c1 = pfile->buffer->rlimit[-3]; - int cl2 = cppBufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile))); + int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile))); if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2)) pfile->buffer->rlimit -= 2; @@ -5781,6 +6675,8 @@ get_next: case '\\': c2 = cppReader_peekC (pfile); + /* allow other stuff here if a flag is set? */ + DPRINTF (("Got continuation!")); if (c2 != '\n') goto randomchar; token = CPP_HSPACE; @@ -5840,7 +6736,7 @@ parse_name (cppReader *pfile, int c) cstring_makeLiteralTemp ("`$' in identifier")); } - cppReader_reserve(pfile, 2); /* One more for final NUL. */ + cpplib_reserve(pfile, 2); /* One more for final NUL. */ cppReader_putCharQ (pfile, c); c = cppReader_getC (pfile); @@ -5905,9 +6801,9 @@ static cstring read_filename_string (int ch, /*:open:*/ FILE *f) struct file_name_map_list { - struct file_name_map_list *map_list_next; - cstring map_list_name; - struct file_name_map *map_list_map; + /*@only@*/ struct file_name_map_list *map_list_next; + /*@only@*/ cstring map_list_name; + /*@null@*/ struct file_name_map *map_list_map; }; /* Read the file name map file for DIRNAME. */ @@ -5942,7 +6838,7 @@ read_name_map (cppReader *pfile, cstring dirname) name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE)); - f = fileTable_openFile (context_fileTable (), name, "r"); + f = fileTable_openReadFile (context_fileTable (), name); cstring_free (name); if (f == NULL) @@ -6095,7 +6991,7 @@ open_include_file (cppReader *pfile, if ((searchptr != NULL) && (cstring_isDefined (searchptr->fname)) - && (cstring_length (searchptr->fname) == p - filename) + && (size_toInt (cstring_length (searchptr->fname)) == p - filename) && !strncmp (cstring_toCharsSafe (searchptr->fname), filename, size_fromInt (p - filename))) @@ -6189,7 +7085,7 @@ finclude (cppReader *pfile, int f, /*@=mustfree@*/ } - fp = cppReader_getBuffer (pfile); + fp = cppReader_getBufferSafe (pfile); /*@-temptrans@*/ /* fname shouldn't really be temp */ fp->nominal_fname = fp->fname = fname; @@ -6217,7 +7113,7 @@ finclude (cppReader *pfile, int f, else if (S_ISDIR (st_mode)) { cppReader_error (pfile, - message ("Directory specified in #include: %s", fname)); + message ("Directory specified where file is expected: %s", fname)); check (close (f) == 0); return 0; } @@ -6283,11 +7179,11 @@ finclude (cppReader *pfile, int f, } void -cppReader_init (cppReader *pfile) +cpplib_init (cppReader *pfile) { memset ((char *) pfile, 0, sizeof (*pfile)); - pfile->get_token = cppGetToken; + pfile->get_token = cpplib_getToken; pfile->token_buffer_size = 200; pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size); pfile->all_include_files = NULL; @@ -6314,8 +7210,12 @@ cppReader_finish (/*@unused@*/ cppReader *pfile) This is the cppReader 'finalizer' or 'destructor' (in C++ terminology). */ void -cppCleanup (cppReader *pfile) +cppCleanup (/*@special@*/ cppReader *pfile) + /*@uses pfile@*/ + /*@releases pfile@*/ { + DPRINTF (("cppCleanup!")); + while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile)) { (void) cppReader_popBuffer (pfile); @@ -6344,6 +7244,25 @@ cppCleanup (cppReader *pfile) sfree (temp); } + /* evans 2002-07-12 */ + while (pfile->opts->map_list != NULL) + { + struct file_name_map_list *temp = pfile->opts->map_list; + pfile->opts->map_list = pfile->opts->map_list->map_list_next; + cstring_free (temp->map_list_name); + sfree (temp); + } + + while (pfile->opts->include != NULL) + { + struct file_name_list *temp = pfile->opts->include; + pfile->opts->include = pfile->opts->include->next; + /* cstring_free (temp->fname); */ + sfree (temp); + } + + sfree (pfile->opts); + pfile->opts = NULL; cppReader_hashCleanup (); } @@ -6358,6 +7277,8 @@ file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer) struct stat sbuf; if (fstat (fd, &sbuf) < 0) { + *mode_pointer = 0; + *size_pointer = 0; return (-1); } @@ -6418,7 +7339,7 @@ static int safe_read (int desc, char *ptr, int len) void parseSetMark (struct parse_marker *pmark, cppReader *pfile) { - cppBuffer *pbuf = cppReader_getBuffer (pfile); + cppBuffer *pbuf = cppReader_getBufferSafe (pfile); pmark->next = pbuf->marks; /*@-temptrans@*/ @@ -6427,6 +7348,7 @@ parseSetMark (struct parse_marker *pmark, cppReader *pfile) pmark->buf = pbuf; pmark->position = pbuf->cur - pbuf->buf; + DPRINTF (("set mark: %d / %s", pmark->position, pbuf->cur)); } /* Cleanup PMARK - we no longer need it. */ @@ -6449,7 +7371,7 @@ void parseClearMark (struct parse_marker *pmark) void parseGotoMark (struct parse_marker *pmark, cppReader *pfile) { - cppBuffer *pbuf = cppReader_getBuffer (pfile); + cppBuffer *pbuf = cppReader_getBufferSafe (pfile); if (pbuf != pmark->buf) { @@ -6459,6 +7381,7 @@ parseGotoMark (struct parse_marker *pmark, cppReader *pfile) llassert (pbuf->buf != NULL); pbuf->cur = pbuf->buf + pmark->position; + DPRINTF (("goto mark: %d / %s", pmark->position, pbuf->cur)); } /* Reset PMARK to point to the current position of PFILE. (Same @@ -6467,7 +7390,7 @@ parseGotoMark (struct parse_marker *pmark, cppReader *pfile) void parseMoveMark (struct parse_marker *pmark, cppReader *pfile) { - cppBuffer *pbuf = cppReader_getBuffer (pfile); + cppBuffer *pbuf = cppReader_getBufferSafe (pfile); if (pbuf != pmark->buf) { @@ -6476,9 +7399,10 @@ parseMoveMark (struct parse_marker *pmark, cppReader *pfile) } pmark->position = pbuf->cur - pbuf->buf; + DPRINTF (("move mark: %s", pmark->position)); } -void cppReader_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */ +void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */ { struct cppOptions *opts = CPPOPTIONS (pfile); cstring xp; @@ -6658,24 +7582,26 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library cppReader_appendIncludeChain (pfile, opts->before_system, opts->last_before_system); + opts->first_system_include = opts->before_system; /* Unless -fnostdinc, tack on the standard include file dirs to the specified list */ + if (!opts->no_standard_includes) { struct default_include *p = include_defaults; char *specd_prefix = opts->include_prefix; char *default_prefix = mstring_copy (GCC_INCLUDE_DIR); - int default_len = 0; - - /* Remove the `include' from /usr/local/lib/gcc.../include. */ - if (default_prefix != NULL) { - if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) { - default_len = strlen (default_prefix) - 7; - default_prefix[default_len] = 0; + size_t default_len = 0; + + /* Remove the `include' from /usr/local/lib/gcc.../include. */ + if (default_prefix != NULL) { + if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) { + default_len = strlen (default_prefix) - 7; + default_prefix[default_len] = 0; + } } - } - + /* Search "translated" versions of GNU directories. These have /usr/local/lib/gcc... replaced by specd_prefix. */ if (specd_prefix != 0 && default_len != 0) @@ -6684,8 +7610,9 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library if (!p->cplusplus || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) { /* Does this dir start with the prefix? */ - if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, - size_fromInt (default_len))) + llassert (default_prefix != NULL); + + if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len)) { /* Yes; change prefix and add to search list. */ struct file_name_list *nlist @@ -6701,15 +7628,16 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library nlist->c_system_include_path = !p->cxx_aware; nlist->got_name_map = 0; - cppReader_addIncludeChain (pfile, nlist); if (opts->first_system_include == 0) { opts->first_system_include = nlist; } + + cppReader_addIncludeChain (pfile, nlist); } } } - + /* Search ordinary names for GNU include directories. */ for (p = include_defaults; p->fname != NULL; p++) @@ -6726,12 +7654,14 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library nlist->got_name_map = 0; nlist->next = NULL; - cppReader_addIncludeChain (pfile, nlist); - - if (opts->first_system_include == 0) + /* Spurious warning reported for opts->first_system_include */ + /*@-usereleased@*/ if (opts->first_system_include == NULL) { opts->first_system_include = nlist; } + /*@=usereleased@*/ + + cppReader_addIncludeChain (pfile, nlist); } } sfree (default_prefix); @@ -6741,11 +7671,14 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library cppReader_appendIncludeChain (pfile, opts->after_include, opts->last_after_include); - if (opts->first_system_include == 0) + /* Spurious warnings for opts->first_system_include */ + /*@-usereleased@*/ + if (opts->first_system_include == NULL) { opts->first_system_include = opts->after_include; } - + /*@=usereleased@*/ + /* With -v, print the list of dirs to search. */ if (opts->verbose) { struct file_name_list *p; @@ -6829,7 +7762,7 @@ static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile return (buf->buf + buf->line_base); } -int cppBufPeek (cppBuffer *buf) +int cpplib_bufPeek (cppBuffer *buf) { if (buf->cur == NULL || buf->rlimit == NULL) { return EOF; @@ -6872,9 +7805,9 @@ static void cpp_setLocation (cppReader *pfile) if (pfile->buffer != NULL) { - if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)) + if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname)) { - cstring fname = cppReader_getBuffer (pfile)->nominal_fname; + cstring fname = cppReader_getBufferSafe (pfile)->nominal_fname; DPRINTF (("Looking up: %s", fname)); @@ -6887,16 +7820,16 @@ static void cpp_setLocation (cppReader *pfile) DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname)); fid = fileTable_lookup (context_fileTable (), - cppReader_getBuffer (pfile)->fname); + cppReader_getBufferSafe (pfile)->fname); } } else { fid = fileTable_lookup (context_fileTable (), - cppReader_getBuffer (pfile)->fname); + cppReader_getBufferSafe (pfile)->fname); } - line = cppReader_getBuffer (pfile)->lineno; + line = cppReader_getBufferSafe (pfile)->lineno; fileloc_free (g_currentloc); if (fileId_isValid (fid)) @@ -6915,7 +7848,7 @@ static void cpp_setLocation (cppReader *pfile) } } -static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/ +static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@modifies p*/ { bool checkmacro = FALSE; bool hasParams = FALSE; @@ -6984,7 +7917,6 @@ static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/ hasParams = (c == '('); *p = '\0'; - if (notparseable) { notparseable = FALSE; @@ -7143,8 +8075,7 @@ static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/ { fileloc loc = fileloc_makePreproc (g_currentloc); DPRINTF (("Make constant: %s", sname)); - le = uentry_makeConstant (sname, - ctype_unknown, loc); + le = uentry_makeMacroConstant (sname, ctype_unknown, loc); (void) usymtab_addEntry (le); } @@ -7196,9 +8127,10 @@ static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/ static enum cpp_token cpp_handleComment (cppReader *pfile, struct parse_marker *smark) { - cppBuffer *pbuf = cppReader_getBuffer (pfile); + cppBuffer *pbuf = cppReader_getBufferSafe (pfile); char *start; int len; + fileloc loc; bool eliminateComment = FALSE; llassert (pbuf->buf != NULL); @@ -7215,6 +8147,9 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) char c = ' '; char *scomment = start + 2; char savec = start[len]; + + cpp_setLocation (pfile); + loc = fileloc_copy (g_currentloc); start[0] = BEFORE_COMMENT_MARKER[0]; start[1] = BEFORE_COMMENT_MARKER[1]; @@ -7225,7 +8160,7 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) llassert (start[len - 1] == '/'); start[len - 1] = AFTER_COMMENT_MARKER[1]; - cppReader_reserve(pfile, size_fromInt (1 + len)); + cpplib_reserve(pfile, size_fromInt (1 + len)); cppReader_putCharQ (pfile, c); cpp_setLocation (pfile); @@ -7247,14 +8182,14 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) { if (!context_getFlag (FLG_NOCOMMENTS)) { - context_enterSuppressRegion (); + context_enterSuppressRegion (loc); } } else if (mstring_equalPrefix (scomment, "end")) { if (!context_getFlag (FLG_NOCOMMENTS)) { - context_exitSuppressRegion (); + context_exitSuppressRegion (loc); } } else if (mstring_equalPrefix (scomment, "notparseable")) @@ -7334,27 +8269,32 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) { /* fix from Mike Miller */ context_fileSetFlag (FLG_NESTCOMMENT, - ynm_fromCodeChar (sChar)); + ynm_fromCodeChar (sChar), + loc); } else if (mstring_equalPrefix (rest, "namechecks")) { context_fileSetFlag (FLG_NAMECHECKS, - ynm_fromCodeChar (sChar)); + ynm_fromCodeChar (sChar), + loc); } else if (mstring_equalPrefix (rest, "macroredef")) { context_fileSetFlag (FLG_MACROREDEF, - ynm_fromCodeChar (sChar)); + ynm_fromCodeChar (sChar), + loc); } else if (mstring_equalPrefix (rest, "usevarargs")) { context_fileSetFlag (FLG_USEVARARGS, - ynm_fromCodeChar (sChar)); + ynm_fromCodeChar (sChar), + loc); } else if (mstring_equalPrefix (rest, "nextlinemacros")) { context_fileSetFlag (FLG_MACRONEXTLINE, - ynm_fromCodeChar (sChar)); + ynm_fromCodeChar (sChar), + loc); } else if (mstring_equalPrefix (rest, "allmacros") || mstring_equalPrefix (rest, "fcnmacros") @@ -7376,8 +8316,7 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) fl = FLG_CONSTMACROS; } - - context_fileSetFlag (fl, ynm_fromCodeChar (sChar)); + context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc); notfunction = FALSE; } else @@ -7463,11 +8402,11 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) c = BEFORE_COMMENT_MARKER[0]; start[0] = BEFORE_COMMENT_MARKER[1]; - llassert (cstring_length (lintcomment) == len - 3); + llassert (size_toLong (cstring_length (lintcomment)) == len - 3); for (i = 1; i < len - 2; i++) { - start[i] = cstring_getChar (lintcomment, i); + start[i] = cstring_getChar (lintcomment, size_fromInt (i)); } start[len - 2] = AFTER_COMMENT_MARKER[0]; @@ -7481,9 +8420,10 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) if (start[i] == '/' && i < len - 1 && start[i + 1] == '*') { - (void) cppoptgenerror (FLG_NESTCOMMENT, - message ("Comment starts inside comment"), - pfile); + (void) cppoptgenerror + (FLG_NESTCOMMENT, + message ("Comment starts inside comment"), + pfile); } if (start[i] != '\n') @@ -7493,7 +8433,7 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) } } - cppReader_reserve (pfile, size_fromInt (1 + len)); + cpplib_reserve (pfile, size_fromInt (1 + len)); cppReader_putCharQ (pfile, c); cppReader_putStrN (pfile, start, size_fromInt (len)); parseClearMark (smark); @@ -7512,8 +8452,20 @@ static int cpp_openIncludeFile (char *filename) if (!fileTable_exists (context_fileTable (), cstring_fromChars (filename))) { - (void) fileTable_addHeaderFile (context_fileTable (), + if (fileloc_isXHFile (g_currentloc)) + { + /* + ** Files includes by XH files are also XH files + */ + + (void) fileTable_addXHFile (context_fileTable (), cstring_fromChars (filename)); + } + else + { + (void) fileTable_addHeaderFile (context_fileTable (), + cstring_fromChars (filename)); + } } else { @@ -7538,8 +8490,27 @@ static bool cpp_skipIncludeFile (cstring fname) if (context_getFlag (FLG_SKIPSYSHEADERS)) { - DPRINTF (("Skip include TRUE: %s", fname)); - return TRUE; + /* + ** 2003-04-18: Patch from Randal Parsons + */ + + /* + ** Don't skip include file unless the file actually exists. + ** It may be in a different directory. + */ + + int f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666); + + if (f >= 0) + { + check (close (f) == 0); + DPRINTF (("Skip include TRUE: %s", fname)); + return TRUE; + } + else + { + /* Keep looking... */ + } } } @@ -7548,7 +8519,7 @@ static bool cpp_skipIncludeFile (cstring fname) fname = removePreDirs (fname); # if defined (WIN32) || defined (OS2) - cstring_replaceAll (fname, '/', '\\'); + cstring_replaceAll (fname, '\\', '/'); # endif if (fileTable_exists (context_fileTable (), fname)) @@ -7564,7 +8535,7 @@ static bool cpp_skipIncludeFile (cstring fname) static int cpp_peekN (cppReader *pfile, int n) { - cppBuffer *buf = cppReader_getBuffer (pfile); + cppBuffer *buf = cppReader_getBufferSafe (pfile); llassert (buf->cur != NULL); @@ -7583,3 +8554,6 @@ void cppBuffer_forward (cppBuffer *buf, int n) llassert (buf->cur != NULL); buf->cur += n; } + +/*@=bufferoverflowhigh@*/ +/*@=bounds@*/