X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/15b3d2b27a3dce7a3b65e88fb0d1732e235117f4..9882c7226e384d7f791c274288708f0f47783bfe:/src/cpplib.c diff --git a/src/cpplib.c b/src/cpplib.c index 86fc538..b8837a6 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-2002 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 @@ -127,7 +92,7 @@ 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 "splintMacros.nf" # include "llbasic.h" # include "lcllib.h" # include "cpplib.h" @@ -185,7 +150,11 @@ static enum cpp_token cpp_handleComment (cppReader *p_pfile, struct parse_marker *p_smark) /*@modifies p_pfile, p_smark@*/; -static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@*/ ; +static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@modifies p_p@*/ ; + +static int cppReader_checkMacroNameLoc (fileloc p_loc, + char *p_symname, + cstring p_usage) ; static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ; @@ -272,7 +241,7 @@ static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ; /*@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. */ @@ -284,7 +253,7 @@ static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ; /*@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 +264,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; @*/ @@ -320,7 +289,7 @@ static void cppBuffer_forward (cppBuffer *p_buf, int p_n) /*@modifies *p_buf@*/ # define cppReader_getC(pfile) (cppBuffer_get (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 @@ -465,9 +434,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 *); @@ -532,7 +501,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@*/ @@ -623,7 +592,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 +617,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); @@ -799,6 +768,7 @@ cppReader_appendIncludeChain (cppReader *pfile, opts->last_include = last; } +# if 0 static /*@unused@*/ void cppReader_showIncludeChain (cppReader *pfile) { @@ -819,6 +789,7 @@ cppReader_showIncludeChain (cppReader *pfile) fprintf (stderr, "No includes\n"); } } +# endif cstring cppReader_getIncludePath () @@ -1076,6 +1047,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 (;;) @@ -1234,7 +1212,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); @@ -1246,7 +1224,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); } @@ -1261,8 +1239,9 @@ cppReader_handleDirective (cppReader *pfile) struct directive *kt = NULL; int ident_length; size_t after_ident = 0; - char *ident, *line_end = NULL; - size_t old_written = cppReader_getWritten (pfile); + char *ident = NULL; + char *line_end = NULL; + size_t old_written = cpplib_getWritten (pfile); int nspaces = cppSkipHspace (pfile); c = cppReader_peekC (pfile); @@ -1291,7 +1270,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') { @@ -1307,7 +1286,7 @@ cppReader_handleDirective (cppReader *pfile) } if (kt->length == ident_length - && (cstring_equalPrefix (kt->name, ident))) + && (cstring_equalPrefix (kt->name, cstring_fromChars (ident)))) { break; } @@ -1324,7 +1303,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; } @@ -1339,7 +1318,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) @@ -1452,7 +1431,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@*/ @@ -1546,7 +1525,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++ = ' '; @@ -1632,7 +1611,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 @@ -1699,7 +1678,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, id_len = 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) { @@ -1767,101 +1746,665 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, } } - /* 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) - cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("`#' operator should be followed by a macro argument name")); - } + /* 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) + cppReader_errorLit (pfile, + cstring_makeLiteralTemp ("`#' operator should be followed by a macro argument name")); + } + } + } + + 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.")); + } + + return defn; +} + +/* +** evans 2001-12-31 +** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...) +*/ + +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'; + + + /* 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. */ + + if (limit < buf) + { + llfatalbug (message ("%q: Limit is less than initial buffer pointer", + fileloc_unparse (loc))); + } + + /* Find the beginning of the trailing whitespace. */ + p = buf; + + while (p < limit && is_space[(int) limit[-1]]) + { + limit--; + } + + /* 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) + { + if (*p++ == '@') + { + maxsize++; + } + } + + 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); + + defn->line = 0; + defn->rest_args = NULL; + defn->args.argnames = NULL; + + lastp = exp_p; + + p = buf; + + /* Add one initial space escape-marker to prevent accidental + token-pasting (often removed by cpplib_macroExpand). */ + *exp_p++ = '@'; + *exp_p++ = ' '; + + if (limit - p >= 2 && p[0] == '#' && p[1] == '#') { + voptgenerror (FLG_PREPROC, + cstring_makeLiteral ("Paste marker ## at start of macro definition"), + loc); + p += 2; + } + + /* Process the main body of the definition. */ + while (p < limit) { + int skipped_arg = 0; + register char c = *p++; + + *exp_p++ = c; + + if (TRUE) { /* !cppReader_isTraditional (pfile)) { */ + switch (c) { + case '\'': + case '\"': + if (expected_delimiter != '\0') + { + if (c == expected_delimiter) + expected_delimiter = '\0'; + } + else + { + expected_delimiter = c; + } + /*@switchbreak@*/ break; + + case '\\': + if (p < limit && (expected_delimiter != '\0')) + { + /* In a string, backslash goes through + and makes next char ordinary. */ + *exp_p++ = *p++; + } + /*@switchbreak@*/ break; + + case '@': + /* An '@' in a string or character constant stands for itself, + and does not need to be escaped. */ + if (expected_delimiter == '\0') + { + *exp_p++ = c; + } + + /*@switchbreak@*/ break; + + case '#': + /* # is ordinary inside a string. */ + if (expected_delimiter != '\0') + { + /*@switchbreak@*/ break; + } + + if (p < limit && *p == '#') { + /* ##: concatenate preceding and following tokens. */ + /* Take out the first #, discard preceding whitespace. */ + exp_p--; + + /*@-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; + int id_len; + + --exp_p; + while (p != limit && is_idchar[(int) *p]) + { + p++; + } + + id_len = 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, size_fromInt (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.")); + } + + return defn; +} + +/* + * 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 */ + 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; + char save = *limit; + *limit = '\0'; + DPRINTF (("Create definition: %s", buf)); + *limit = save; + + cppBuffer_lineAndColumn (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 = 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) { + cstring name = cstring_copyLength (temp->name, temp->length); + cppReader_error (pfile, + message ("duplicate argument name `%x' in `#define'", name)); + goto nope; + } + } + } + } + + ++bp; /* skip paren */ + SKIP_WHITE_SPACE (bp); + /* now everything from bp before limit is the definition. */ + defn = collect_expansion (pfile, 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, size_fromInt (temp->length)); + i += temp->length; + if (temp->next != 0) { + defn->args.argnames[i++] = ','; + defn->args.argnames[i++] = ' '; + } + } + + defn->args.argnames[i] = '\0'; } - } - 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++ = ' '; - } + sfree (arg_ptrs); + } else { + /* Simple expansion or empty definition. */ - *exp_p = '\0'; + 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 '~': + cppReader_warning (pfile, + message ("Missing white space after #define %x", + cstring_prefix (cstring_fromChars (symname), + sym_length))); + break; - defn->length = size_fromInt (exp_p - defn->expansion); + default: + cppReader_pedwarn (pfile, + message ("Missing white space after #define %x", + cstring_prefix (cstring_fromChars (symname), + sym_length))); + break; + } + } + } + /* now everything from bp before limit is the definition. */ + defn = collect_expansion (pfile, bp, limit, -1, NULL); + defn->args.argnames = mstring_createEmpty (); + } - /* Crash now if we overrun the allocated size. */ - if (defn->length + 1 > maxsize) - { - llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded.")); - } + defn->noExpand = noExpand; + DPRINTF (("No expand: %d", noExpand)); - return defn; -} + defn->line = line; -/* - * 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); { - */ + /* not: llassert (cstring_isUndefined (defn->file)); */ + defn->file = file; -/*@-readonlytrans@*/ -static char rest_extension[] = "..."; -/*:=readonlytrans@*/ + /* OP is null if this is a predefinition */ + defn->predefined = predefinition; + mdef.defn = defn; + mdef.symnam = symname; + mdef.symlen = sym_length; -/*@notfunction@*/ -#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) + return mdef; -/* Create a DEFINITION node from a #define directive. Arguments are - as for do_define. */ +nope: + mdef.defn = NULL; + mdef.symnam = NULL; + return mdef; +} -static /*@null@*/ MACRODEF -create_definition (char *buf, char *limit, - cppReader *pfile, bool predefinition, - bool noExpand) +/*@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 */ 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 (""); + 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; - - cppBuffer_lineAndColumn (CPPBUFFER (pfile), &line, &col); + macroDef mdef; bp = buf; + DPRINTF (("Creating definition: %s", buf)); + while (is_hor_space[(int) *bp]) { bp++; } - symname = bp; /* remember where it starts */ + symname = bp; /* remember where it starts */ - sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro")); + 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. */ @@ -1886,15 +2429,17 @@ create_definition (char *buf, char *limit, if (rest_args != 0) { - cppReader_pedwarn (pfile, - message ("another parameter follows `%s'", - cstring_fromChars (rest_extension))); + voptgenerror (FLG_PREPROC, + message ("Another parameter follows %s", + cstring_fromChars (rest_extension)), + loc); } if (!is_idstart[(int) *bp]) { - cppReader_pedwarnLit (pfile, - cstring_makeLiteralTemp ("invalid character in macro parameter name")); + voptgenerror (FLG_PREPROC, + message ("Invalid character in macro parameter name: %c", *bp), + loc); } /* Find the end of the arg name. */ @@ -1912,7 +2457,7 @@ create_definition (char *buf, char *limit, } temp->length = bp - temp->name; - + if (rest_args != 0) { bp += REST_EXTENSION_LENGTH; @@ -1920,10 +2465,11 @@ create_definition (char *buf, char *limit, 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")); + voptgenerror (FLG_PREPROC, + cstring_makeLiteral ("Parameter list for #define is not parseable"), + loc); goto nope; } @@ -1932,8 +2478,9 @@ create_definition (char *buf, char *limit, SKIP_WHITE_SPACE (bp); } if (bp >= limit) { - cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("unterminated parameter list in `#define'")); + voptgenerror (FLG_PREPROC, + cstring_makeLiteral ("Unterminated parameter list in #define'"), + loc); goto nope; } { @@ -1944,18 +2491,20 @@ create_definition (char *buf, char *limit, if (temp->length == otemp->length && strncmp (temp->name, otemp->name, size_fromInt (temp->length)) == 0) { cstring name = cstring_copyLength (temp->name, temp->length); - cppReader_error (pfile, - message ("duplicate argument name `%x' in `#define'", name)); + + 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_expansion (pfile, bp, limit, argno, arg_ptrs); + defn = collect_expansionLoc (loc, bp, limit, argno, arg_ptrs); defn->rest_args = rest_args; /* Now set defn->args.argnames to the result of concatenating @@ -1989,28 +2538,32 @@ 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 '{': case '|': case '}': case '~': - cppReader_warning (pfile, - message ("Missing white space after #define %x", - cstring_prefix (cstring_fromChars (symname), - sym_length))); + voptgenerror (FLG_PREPROC, + message ("Missing white space after #define %x", + cstring_prefix (cstring_fromChars (symname), + sym_length)), + loc); break; default: - cppReader_pedwarn (pfile, - message ("Missing white space after #define %x", - cstring_prefix (cstring_fromChars (symname), - sym_length))); + 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. */ - defn = collect_expansion (pfile, bp, limit, -1, NULL); + llassert (limit > bp); + defn = collect_expansionLoc (loc, bp, limit, -1, NULL); defn->args.argnames = mstring_createEmpty (); } @@ -2024,6 +2577,7 @@ create_definition (char *buf, char *limit, /* OP is null if this is a predefinition */ defn->predefined = predefinition; + mdef.defn = defn; mdef.symnam = symname; mdef.symlen = sym_length; @@ -2040,22 +2594,24 @@ nope: USAGE is the kind of name this is intended for. */ int cppReader_checkMacroName (cppReader *pfile, - char *symname, - cstring usage) + 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 == '\"'))) + { + cppReader_error (pfile, message ("invalid %s name", usage)); + } else if (!is_idstart[(int) *symname]) { char *msg = (char *) dmalloc (sym_length + 1); @@ -2076,6 +2632,52 @@ int cppReader_checkMacroName (cppReader *pfile, return size_toInt (sym_length); } +/* +** evans 2001-12-31 +** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...) +*/ + +int 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 == '\"'))) + { + 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'; + 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) + { + voptgenerror (FLG_PREPROC, message ("Invalid %s name: defined", usage), loc); + } + } + + return size_toInt (sym_length); +} + /* Return zero if two DEFINITIONs are isomorphic. */ static bool @@ -2166,10 +2768,10 @@ comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last 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)); @@ -2179,13 +2781,13 @@ do_defineAux (cppReader *pfile, struct directive *keyword, if (mdef.defn == 0) goto nope; - hashcode = hashf (mdef.symnam, mdef.symlen, CPP_HASHSIZE); + hashcode = cpphash_hashCode (mdef.symnam, mdef.symlen, CPP_HASHSIZE); DPRINTF (("Macro: %s / %s", cstring_copyLength (mdef.symnam, mdef.symlen), bool_unparse (noExpand))); - if ((hp = cppReader_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) + if ((hp = cpphash_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) { bool ok = FALSE; @@ -2267,7 +2869,7 @@ 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@*/ @@ -2280,7 +2882,7 @@ nope: 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); @@ -2380,7 +2982,7 @@ cppReader_scanBuffer (cppReader *pfile) { enum cpp_token token; - token = cppGetToken (pfile); + token = cpplib_getToken (pfile); if (token == CPP_EOF) /* Should not happen ... */ { @@ -2401,7 +3003,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 @@ -2411,8 +3013,12 @@ cpp_expand_to_buffer (cppReader *pfile, char *buf, size_t length) char *limit = buf + length; char *buf1, *p1, *p2; + /* evans - 2001-08-26 + ** length is unsigned - this doesn't make sense if (length < 0) abort (); + ** + */ /* Set up the input on the input stack. */ @@ -2591,7 +3197,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'); @@ -2602,7 +3208,7 @@ output_line_command (cppReader *pfile, bool conditional, } } - cppReader_reserve (pfile, + cpplib_reserve (pfile, size_fromInt (4 * cstring_length (ip->nominal_fname) + 50)); { @@ -2614,8 +3220,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)); @@ -2662,7 +3268,7 @@ macarg (cppReader *pfile, int rest_args) for (;;) { - token = cppGetToken (pfile); + token = cpplib_getToken (pfile); switch (token) { @@ -2817,7 +3423,7 @@ 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; } @@ -2839,7 +3445,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 @@ -2926,10 +3532,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 "); @@ -2963,7 +3569,7 @@ special_symbol (hashNode hp, cppReader *pfile) len = size_fromInt (cstring_length (buf)); - cppReader_reserve (pfile, len + 1); + cpplib_reserve (pfile, len + 1); cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len); cppReader_nullTerminateQ (pfile); @@ -2980,7 +3586,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, ' '); @@ -2991,10 +3597,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); @@ -3024,18 +3630,18 @@ 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 ()); @@ -3048,28 +3654,28 @@ cppReader_installBuiltinType (/*@observer@*/ char *name, ctype ctyp, 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 ("__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); + 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); /* ** No, don't define __STDC__ @@ -3077,14 +3683,14 @@ initialize_builtins (cppReader *pfile) 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 /* @@ -3092,10 +3698,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); - cppReader_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... + */ + + /*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__"); @@ -3168,7 +3887,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; @@ -3177,7 +3896,7 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) int start_line; int start_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; @@ -3230,9 +3949,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 = cpplib_getWritten (pfile) - args[i].raw; args[i].newlines = FALSE; /* FIXME */ } else @@ -3368,7 +4087,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++) @@ -3381,8 +4100,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); @@ -3431,8 +4150,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); } @@ -3440,7 +4159,7 @@ 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; @@ -3461,13 +4180,13 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp) 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 @@ -3724,7 +4443,7 @@ push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len, } -/* 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 @@ -3732,7 +4451,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') @@ -3740,7 +4459,7 @@ get_directive_token (cppReader *pfile) return CPP_VSPACE; } - token = cppGetToken (pfile); + token = cpplib_getToken (pfile); switch (token) { @@ -3763,24 +4482,10 @@ 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. */ -# ifdef WIN32 -static void replace_unixdir_with_windir(char *filename) -{ - int i=0; - - while(filename[i] != '\0') - { - if(filename[i] == '/') - filename[i] = '\\'; - i++; - } -} -# endif - static int do_include (cppReader *pfile, struct directive *keyword, /*@unused@*/ char *unused1, /*@unused@*/ char *unused2) @@ -3794,7 +4499,7 @@ 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); + size_t old_written = cpplib_getWritten (pfile); int flen; @@ -3810,7 +4515,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; @@ -3897,7 +4602,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 @@ -4036,11 +4741,11 @@ do_include (cppReader *pfile, struct directive *keyword, DPRINTF (("fname: %s", fname)); /* Win32 directory fix from Kay Buschner. */ -#ifdef WIN32 +#if defined (WIN32) || defined (OS2) /* Fix all unixdir slashes to win dir slashes */ if (searchptr->fname && (searchptr->fname[0] != 0)) { - replace_unixdir_with_windir(fname); + cstring_replaceAll (fname, '/', '\\'); } #endif /* WIN32 */ @@ -4187,7 +4892,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; } @@ -4297,7 +5002,7 @@ 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; @@ -4337,7 +5042,7 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword) /* 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, @@ -4346,7 +5051,7 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword) } fname_length = end_name - fname; - num_start = cppReader_getWritten (pfile); + num_start = cpplib_getWritten (pfile); token = get_directive_token (pfile); if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) { @@ -4386,7 +5091,7 @@ 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 && @@ -4452,7 +5157,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, sym_length, -1)) != NULL) { /* If we are generating additional info for debugging (with -g) we need to pass through all effective #undef commands. */ @@ -4534,7 +5239,7 @@ do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword, 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; } @@ -4603,7 +5308,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; } @@ -4672,17 +5379,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; @@ -4705,7 +5413,7 @@ do_xifdef (cppReader *pfile, struct directive *keyword, 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)); @@ -4721,7 +5429,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 = size_toInt (cpplib_getWritten (pfile) - old_written); cppReader_setWritten (pfile, old_written); /* Pop */ if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF) @@ -4730,20 +5440,23 @@ 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); + hashNode hp = cpphash_lookup (ident, ident_length, -1); + + DPRINTF (("Lookup: %s %d", ident, ident_length)); + 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!")); @@ -4860,11 +5573,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; @@ -4872,7 +5585,7 @@ beg_of_line: { cppIfStackFrame *temp; if (ident_length == kt->length - && cstring_equalPrefix (kt->name, ident)) + && cstring_equalPrefix (kt->name, cstring_fromChars (ident))) { /* If we are asked to return on next directive, do so now. */ if (any) @@ -4938,6 +5651,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; @@ -4971,8 +5689,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 '\\': @@ -5151,7 +5869,19 @@ 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; @@ -5162,6 +5892,7 @@ cppGetToken (cppReader *pfile) get_next: c = cppReader_getC (pfile); + DPRINTF (("Get next token: %c", c)); if (c == EOF) { @@ -5256,7 +5987,7 @@ get_next: } else { - cppReader_reserve(pfile, 1); + cpplib_reserve(pfile, 1); cppReader_putCharQ (pfile, ' '); return CPP_HSPACE; } @@ -5281,7 +6012,7 @@ get_next: programs (e.g., troff) are perverse this way */ cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column); - old_written = cppReader_getWritten (pfile); + old_written = cpplib_getWritten (pfile); string: cppReader_putChar (pfile, c); while (TRUE) @@ -5384,7 +6115,7 @@ get_next: } 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; @@ -5477,7 +6208,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; @@ -5501,7 +6232,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); @@ -5523,7 +6254,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; @@ -5532,7 +6263,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, '.'); @@ -5546,7 +6277,7 @@ get_next: token = CPP_OTHER; pfile->only_seen_white = 0; op2any: - cppReader_reserve(pfile, 3); + cpplib_reserve(pfile, 3); cppReader_putCharQ (pfile, c); cppReader_putCharQ (pfile, cppReader_getC (pfile)); cppReader_nullTerminateQ (pfile); @@ -5569,7 +6300,7 @@ get_next: c2 = '.'; for (;;) { - cppReader_reserve (pfile, 2); + cpplib_reserve (pfile, 2); cppReader_putCharQ (pfile, c); NEWLINE_FIX; c = cppReader_peekC (pfile); @@ -5593,7 +6324,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); @@ -5615,7 +6346,7 @@ get_next: } if (c == '\'') { - cppReader_reserve (pfile, 2); + cpplib_reserve (pfile, 2); cppReader_putCharQ (pfile, c); cppReader_nullTerminateQ (pfile); return CPP_STRING; @@ -5643,31 +6374,38 @@ get_next: { hashNode hp; char *ident; - size_t before_name_written = cppReader_getWritten (pfile); + size_t before_name_written = cpplib_getWritten (pfile); int 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)); - hp = cppReader_lookupExpand (ident, ident_len, -1); + ident_len = (cpplib_getPWritten (pfile)) - ident; + + hp = cpphash_lookupExpand (ident, 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); @@ -5682,11 +6420,13 @@ 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; @@ -5740,17 +6480,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); } @@ -5766,7 +6509,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; @@ -5847,7 +6590,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); @@ -5949,7 +6692,7 @@ read_name_map (cppReader *pfile, cstring dirname) name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE)); - f = fopen (cstring_toCharsSafe (name), "r"); + f = fileTable_openFile (context_fileTable (), name, "r"); cstring_free (name); if (f == NULL) @@ -6007,7 +6750,7 @@ read_name_map (cppReader *pfile, cstring dirname) } assertSet (map_list_ptr->map_list_map); - check (fclose (f) == 0); + check (fileTable_closeFile (context_fileTable (),f) == 0); } map_list_ptr->map_list_next = pfile->opts->map_list; @@ -6290,11 +7033,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; @@ -6365,6 +7108,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); } @@ -6485,7 +7230,7 @@ parseMoveMark (struct parse_marker *pmark, cppReader *pfile) pmark->position = pbuf->cur - pbuf->buf; } -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; @@ -6496,7 +7241,7 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library struct default_include *include_defaults = include_defaults_array; - /* Add dirs from CPATH after dirs from -I. */ + /* Add dirs from INCLUDEPATH_VAR after dirs from -I. */ /* There seems to be confusion about what CPATH should do, so for the moment it is not documented. */ /* Some people say that CPATH should replace the standard include dirs, @@ -6836,7 +7581,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; @@ -6922,7 +7667,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; @@ -6991,7 +7736,6 @@ static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/ hasParams = (c == '('); *p = '\0'; - if (notparseable) { notparseable = FALSE; @@ -7150,8 +7894,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); } @@ -7221,6 +7964,7 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark) int i; char c = ' '; char *scomment = start + 2; + char savec = start[len]; start[0] = BEFORE_COMMENT_MARKER[0]; start[1] = BEFORE_COMMENT_MARKER[1]; @@ -7231,11 +7975,24 @@ 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); + start[len] = '\0'; + + if (mstring_containsString (scomment, "/*")) + { + (void) cppoptgenerror + (FLG_NESTCOMMENT, + message ("Comment starts inside syntactic comment: %s", + cstring_fromChars (scomment)), + pfile); + } + + start[len] = savec; + if (mstring_equalPrefix (scomment, "ignore")) { if (!context_getFlag (FLG_NOCOMMENTS)) @@ -7486,7 +8243,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); @@ -7499,20 +8256,32 @@ static int cpp_openIncludeFile (char *filename) { int res = open (filename, O_RDONLY, 0666); - if (res) + /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */ + if (res >= 0) { 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 { DPRINTF (("File already exists: %s", filename)); } } - return res; }