X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/d5047b9135351b2240dbe50c224bd95cf3fe5d64..11c40ce9ae842585926cc1abd029f9f5a6702827:/src/cpplib.c diff --git a/src/cpplib.c b/src/cpplib.c index 58dc81d..5aff1e9 100644 --- a/src/cpplib.c +++ b/src/cpplib.c @@ -1,6 +1,6 @@ /* ** Splint - annotation-assisted static program checker -** Copyright (C) 1994-2002 University of Virginia, +** Copyright (C) 1994-2003 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -70,11 +70,18 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # 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 @@ -90,14 +97,13 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # include # include "splintMacros.nf" -# include "llbasic.h" +# 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" /* @@ -107,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 @@ -232,6 +242,10 @@ 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; @*/ @@ -243,7 +257,13 @@ static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ; /*@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) @@ -283,6 +303,9 @@ 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) (cpplib_bufPeek (cppReader_getBufferSafe (pfile))) @@ -337,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. */ @@ -344,6 +369,7 @@ static void cppReader_scanBuffer (cppReader *p_pfile); /*@-incondefs@*/ /*@-czechtypes@*/ typedef unsigned int mode_t; /*@=incondefs@*/ /*@=czechtypes@*/ +# endif # endif @@ -750,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; + } } } @@ -810,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; } @@ -831,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; @@ -937,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); } @@ -948,7 +984,7 @@ cppReader_nullUnderflow (/*@unused@*/ cppReader *pfile) void cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf, - /*@unused@*/ cppReader *pfile) + /*@unused@*/ cppReader *pfile) { ; } @@ -1164,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; @@ -1777,7 +1830,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit, llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded.")); } - return defn; + /*@i1@*/ return defn; /* Spurious warning here */ } /* @@ -1841,7 +1894,6 @@ collect_expansionLoc (fileloc loc, char *buf, char *limit, defn->pattern = NULL; defn->nargs = nargs; defn->predefined = NULL; - exp_p = defn->expansion = (char *) defn + sizeof (*defn); defn->line = 0; @@ -2124,7 +2176,7 @@ collect_expansionLoc (fileloc loc, char *buf, char *limit, llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded.")); } - return defn; + /*@i1@*/ return defn; /* Spurious warning here */ } /* @@ -2220,7 +2272,7 @@ create_definition (/*@exposed@*/ char *buf, char *limit, if (!is_idstart[(int) *bp]) { cppReader_pedwarnLit (pfile, - cstring_makeLiteralTemp ("invalid character in macro parameter name")); + cstring_makeLiteralTemp ("Invalid character in macro parameter name")); } /* Find the end of the arg name. */ @@ -2712,22 +2764,24 @@ 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. */ - /*@i2@*/ +/* +** 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) { @@ -2753,12 +2807,14 @@ 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. */ - /*@i2@*/ +/* +** 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, /*@exposed@*/ char *buf, char *limit, bool noExpand) @@ -2766,20 +2822,14 @@ do_defineAux (cppReader *pfile, struct directive *keyword, int hashcode; macroDef mdef; hashNode hp; - /*@i2@*/ - DPRINTF (("Define aux: %d", noExpand)); - /*@i2@*/ + mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand); if (mdef.defn == 0) goto nope; - /*@i2@*/ + hashcode = cpphash_hashCode (mdef.symnam, mdef.symlen, CPP_HASHSIZE); - /*@i2@*/ - DPRINTF (("Macro: %s / %s", - cstring_copyLength (mdef.symnam, mdef.symlen), - bool_unparse (noExpand))); - /*@i2@*/ + if ((hp = cpphash_lookup (mdef.symnam, size_toInt (mdef.symlen), hashcode)) != NULL) { bool ok = FALSE; @@ -2794,9 +2844,9 @@ 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. */ } - /*@i2@*/ + /* Print the warning if it's not ok. */ if (!ok) { @@ -2812,7 +2862,7 @@ do_defineAux (cppReader *pfile, struct directive *keyword, } cpp_setLocation (pfile); - /*@i2@*/ + if (hp->type == T_MACRO) { if (hp->value.defn->noExpand) @@ -2837,7 +2887,6 @@ do_defineAux (cppReader *pfile, struct directive *keyword, message ("Macro %q already defined", cstring_copyLength (mdef.symnam, mdef.symlen))); - /*@i2@*/ } } @@ -2853,7 +2902,7 @@ do_defineAux (cppReader *pfile, struct directive *keyword, */ hashNode hn; - /*@i2@*/ + if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL)) { pass_thru_directive (buf, limit, pfile, keyword); @@ -2867,9 +2916,8 @@ do_defineAux (cppReader *pfile, struct directive *keyword, } /*@=branchstate@*/ return 0; - /*@i2@*/ + nope: - /*@i2@*/ return 1; } @@ -2880,21 +2928,23 @@ do_define (cppReader *pfile, struct directive *keyword, DPRINTF (("Regular do define")); return do_defineAux (pfile, keyword, buf, limit, FALSE); } - /*@i2@*/ -/* 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. */ - /*@i2@*/ + +/* +** 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@*/ #define ARG_BASE ((pfile)->token_buffer) - /*@i2@*/ + struct argdata { /* Strings relative to pfile->token_buffer */ long raw; @@ -2907,11 +2957,13 @@ 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. */ - /*@i2@*/ +/* +** 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) { @@ -2933,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; @@ -2952,7 +3005,7 @@ cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length) return buf; } - /*@i2@*/ + cppBuffer * cppReader_popBuffer (cppReader *pfile) { @@ -2964,9 +3017,11 @@ cppReader_popBuffer (cppReader *pfile) return ++CPPBUFFER (pfile); } -/* Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer. - Pop the buffer when done. */ - /*@i2@*/ +/* +** Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer. +** Pop the buffer when done. +*/ + void cppReader_scanBuffer (cppReader *pfile) { @@ -2989,7 +3044,6 @@ cppReader_scanBuffer (cppReader *pfile) } } } - /*@i2@*/ /* * Rescan a string (which may have escape marks) into pfile's buffer. @@ -3007,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) @@ -3081,7 +3137,7 @@ update_position (cppBuffer *pbuf) void cppBuffer_getLineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep, - /*@null@*/ /*@out@*/ int *colp) + /*@null@*/ /*@out@*/ int *colp) { int dummy; @@ -3202,8 +3258,7 @@ output_line_command (cppReader *pfile, bool conditional, } } - cpplib_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 @@ -3421,6 +3476,14 @@ special_symbol (hashNode hp, cppReader *pfile) 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; + } case T_INCLUDE_LEVEL: true_indepth = 0; @@ -3642,7 +3705,7 @@ cpplib_installBuiltinType (/*@observer@*/ char *name, ctype ctyp, if (!usymtab_existsTypeEither (sname)) { uentry ue = uentry_makeDatatype (sname, ctyp, - NO, NO, + NO, qual_createConcrete (), fileloc_createBuiltin ()); llassert (!usymtab_existsEither (sname)); usymtab_addGlobalEntry (ue); @@ -3658,6 +3721,7 @@ initialize_builtins (cppReader *pfile) 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 @@ -3671,18 +3735,11 @@ initialize_builtins (cppReader *pfile) 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__ - ** - if (!cppReader_isTraditional (pfile)) { cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1); } - ** - */ - # ifdef WIN32 cpplib_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1); # endif @@ -3947,7 +4004,7 @@ cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp) args[i].raw = size_toLong (cpplib_getWritten (pfile)); token = macarg (pfile, rest_args); - args[i].raw_length = cpplib_getWritten (pfile) - args[i].raw; + args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw); args[i].newlines = FALSE; /* FIXME */ } else @@ -4041,7 +4098,7 @@ cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp) 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. */ @@ -4170,9 +4227,8 @@ cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp) } 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 @@ -4180,7 +4236,7 @@ cpplib_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) { @@ -4388,7 +4444,7 @@ cpplib_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 */ @@ -4427,11 +4483,13 @@ cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp) DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len))); push_macro_expansion (pfile, xbuf, xbuf_len, hp); + 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) */ @@ -4481,8 +4539,10 @@ 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; } + } @@ -4611,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 { @@ -4823,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) @@ -5505,8 +5565,8 @@ do_xifdef (cppReader *pfile, struct directive *keyword, 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 @@ -5997,7 +6057,7 @@ get_next: 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); @@ -6059,12 +6119,18 @@ get_next: &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 @@ -6078,13 +6144,14 @@ get_next: 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) { @@ -6104,58 +6171,64 @@ 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') - { - /* Backslash newline is replaced by nothing at all. */ - cppReader_adjustWritten (pfile, -1); - pfile->lineno++; - } - else + int cc = cppReader_getC (pfile); + DPRINTF (("cc: %c [%d] [%d]", cc, cc, EOF)); + DPRINTF (("putting char: %c", cc)); + cppReader_putChar (pfile, cc); + switch (cc) { - /* 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: @@ -6265,9 +6338,11 @@ get_next: return CPP_OTHER; case '@': + DPRINTF (("Macro @!")); if (cppReader_getBufferSafe (pfile)->has_escapes) { c = cppReader_getC (pfile); + DPRINTF (("got c: %c", c)); if (c == '-') { if (pfile->output_escapes) @@ -6321,10 +6396,20 @@ get_next: op2: token = CPP_OTHER; pfile->only_seen_white = 0; - op2any: + 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; @@ -6477,12 +6562,23 @@ get_next: 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; } @@ -6491,12 +6587,13 @@ get_next: 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; @@ -6512,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. */ @@ -6576,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; @@ -6700,8 +6801,8 @@ 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; + /*@only@*/ struct file_name_map_list *map_list_next; + /*@only@*/ cstring map_list_name; /*@null@*/ struct file_name_map *map_list_map; }; @@ -7012,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; } @@ -7109,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); @@ -7139,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 (); } @@ -7224,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. */ @@ -7256,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 @@ -7273,6 +7399,7 @@ parseMoveMark (struct parse_marker *pmark, cppReader *pfile) } pmark->position = pbuf->cur - pbuf->buf; + DPRINTF (("move mark: %s", pmark->position)); } void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */ @@ -7455,6 +7582,7 @@ void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is cppReader_appendIncludeChain (pfile, opts->before_system, opts->last_before_system); + opts->first_system_include = opts->before_system; /* Unless -fnostdinc, @@ -7464,7 +7592,7 @@ void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is struct default_include *p = include_defaults; char *specd_prefix = opts->include_prefix; char *default_prefix = mstring_copy (GCC_INCLUDE_DIR); - int default_len = 0; + size_t default_len = 0; /* Remove the `include' from /usr/local/lib/gcc.../include. */ if (default_prefix != NULL) { @@ -7484,8 +7612,7 @@ void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is /* Does this dir start with the prefix? */ llassert (default_prefix != NULL); - if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, - size_fromInt (default_len))) + if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len)) { /* Yes; change prefix and add to search list. */ struct file_name_list *nlist @@ -7501,15 +7628,16 @@ void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is 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++) @@ -7526,12 +7654,14 @@ void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is 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); @@ -7541,11 +7671,14 @@ void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is 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; @@ -8357,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... */ + } } } @@ -8402,3 +8554,6 @@ void cppBuffer_forward (cppBuffer *buf, int n) llassert (buf->cur != NULL); buf->cur += n; } + +/*@=bufferoverflowhigh@*/ +/*@=bounds@*/