/*
-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)
-
-*/
-/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
** 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
# endif
# include <string.h>
-
# if !(defined (WIN32) || defined (OS2) && defined (__IBMC__))
# include <unistd.h>
# endif
-
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
-
# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
# include <io.h>
# include <sys/utime.h> /* for __DATE__ and __TIME__ */
# include <time.h>
# 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 <time.h> /* Reported by Paul Smith */
# include <sys/time.h>
# include <sys/resource.h>
/* This defines "errno" properly for VMS, and gives us EACCES. */
# include <errno.h>
-# include "lclintMacros.nf"
-# include "llbasic.h"
+# include "splintMacros.nf"
+# include "basic.h"
# include "lcllib.h"
# include "cpplib.h"
# include "cpperror.h"
# include "cpphash.h"
# include "cppexp.h"
# include "version.h"
-# include "portab.h"
# include "osd.h"
/*
/*@+boolint@*/
/*@+charint@*/
+/* Warnings for using sprintf - suppress them all for now... */
+/*@-bufferoverflowhigh@*/
+/*@-bounds@*/
+
#define NO_SHORTNAMES
# ifdef open
static enum cpp_token cpp_handleComment (cppReader *p_pfile,
struct parse_marker *p_smark)
- /*@modifies p_pfile, p_smark@*/;
-
+ /*@modifies p_pfile, p_smark@*/;
+
static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@modifies p_p@*/ ;
+static size_t cppReader_checkMacroNameLoc (fileloc p_loc, char *p_symname, cstring p_usage) ;
+
static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ;
#ifndef O_RDONLY
#endif
/* Symbols to predefine. */
-
+
#ifdef CPP_PREDEFINES
static /*@observer@*/ char *predefs = CPP_PREDEFINES;
#else
/*@constant observer char *WCHAR_TYPE@*/
#define WCHAR_TYPE "int"
#endif
-
+
/* The string value for __USER_LABEL_PREFIX__ */
#ifndef USER_LABEL_PREFIX
static bool is_hor_space[256];
/* table to tell if c is horizontal or vertical space. */
static bool is_space[256];
-
+
static /*@exposed@*/ /*@null@*/ cppBuffer *
cppReader_getBuffer (/*@special@*/ cppReader *p_pfile)
/*@uses p_pfile->buffer@*/
# define cppBuffer_get(BUFFER) \
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
+/*@function static int cppBuffer_reachedEOF (sef cppBuffer *p_b) modifies nothing; @*/
+# define cppBuffer_reachedEOF(b) \
+ ((b)->cur < (b)->rlimit ? FALSE : TRUE)
+
/* Append string STR (of length N) to PFILE's output buffer. Make space. */
/*@function static void cppReader_puts (sef cppReader *p_file, char *p_str, sef size_t p_n)
modifies *p_file; @*/
# define cppReader_puts(PFILE, STR, N) \
- cppReader_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)
-
+ cpplib_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)
+
/* Append character CH to PFILE's output buffer. Assume sufficient space. */
/*@function static void cppReader_putCharQ (cppReader *p_file, char p_ch)
modifies *p_file; @*/
# define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH))
-
+/*
+static void cppReader_putCharQ (cppReader *p_file, char p_ch)
+{
+ fprintf (stderr, "put char: %c\n", p_ch);
+ (*(p_file)->limit++ = (p_ch));
+}
+*/
/* Append character CH to PFILE's output buffer. Make space if need be. */
/*@function static void cppReader_putChar (sef cppReader *p_file, char p_ch)
modifies *p_file; @*/
-#define cppReader_putChar(PFILE, CH) (cppReader_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))
+#define cppReader_putChar(PFILE, CH) (cpplib_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))
/* Make sure PFILE->limit is followed by '\0'. */
/*@function static void cppReader_nullTerminateQ (cppReader *p_file)
/*@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; @*/
/*@function static int cppReader_getC (cppReader *p_pfile) modifies *p_pfile; @*/
# define cppReader_getC(pfile) (cppBuffer_get (cppReader_getBufferSafe (pfile)))
+/*@function static int cppReader_reachedEOF (sef cppReader *p_pfile) modifies *p_pfile; @*/
+# define cppReader_reachedEOF(pfile) (cppBuffer_reachedEOF (cppReader_getBufferSafe (pfile)))
+
/*@function static int cppReader_peekC (cppReader *) modifies nothing;@*/
-# define cppReader_peekC(pfile) (cppBufPeek (cppReader_getBufferSafe (pfile)))
+# define cppReader_peekC(pfile) (cpplib_bufPeek (cppReader_getBufferSafe (pfile)))
/* Move all backslash-newline pairs out of embarrassing places.
Exchange all such pairs following BP
/*@dependent@*/ /*@null@*/ struct file_name_list *p_dirptr);
static void validate_else (cppReader *p_pfile, cstring p_directive);
-
+
static void conditional_skip (cppReader *p_pfile, int p_skip,
enum node_type p_type,
/*@dependent@*/ /*@null@*/ char *p_control_macro);
/* -I directories are added to the end, then the defaults are added. */
/*@access cstring@*/
-
+
static struct default_include {
/*@dependent@*/ /*@observer@*/ cstring fname; /* The name of the directory. */
int cplusplus; /* Only look here if we're compiling C++. */
{ 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@*/
quote_string (cppReader *pfile, char *src)
{
char c;
-
+
cppReader_putCharQ (pfile, '\"');
for (;;)
{
cppReader_putCharQ (pfile, c);
else
{
- sprintf (cppReader_getPWritten (pfile), "\\%03o",
+ sprintf (cpplib_getPWritten (pfile), "\\%03o",
(unsigned int) c);
cppReader_adjustWritten (pfile, (size_t) 4);
}
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);
(void) do_define (pfile, NULL, buf, buf + strlen (buf));
sfree (buf);
}
-
+
/* Append a chain of `struct file_name_list's
to the end of the main include chain.
FIRST is gthe beginning of the chain to append, and LAST is the end. */
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;
+ }
}
}
/* last->next = NULL; */
opts->last_include = last;
}
-
+
# if 0
static /*@unused@*/ void
cppReader_showIncludeChain (cppReader *pfile)
}
}
# endif
-
+
cstring
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;
}
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;
path_include (cppReader *pfile, char *path)
{
char *p;
-
+
#ifdef __CYGWIN32__
char *win32temp;
p++;
}
}
-
+
void
cppOptions_init (cppOptions *opts)
{
void
cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf,
- /*@unused@*/ cppReader *pfile)
+ /*@unused@*/ cppReader *pfile)
{
;
}
else if (cppReader_peekC (pfile) == '/'
&& CPPOPTIONS (pfile)->cplusplus_comments)
{
+
+ (void) cppoptgenerror
+ (FLG_SLASHSLASHCOMMENT,
+ message ("C++ style // comment"
+ ),
+ pfile);
+
cppReader_forward (pfile, 1);
for (;;)
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;
goto end_directive;
scan_directive_token:
cppReader_forward (pfile, -1);
- (void) cppGetToken (pfile);
+ (void) cpplib_getToken (pfile);
continue;
}
cppReader_putChar (pfile, c);
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);
}
size_t after_ident = 0;
char *ident = NULL;
char *line_end = NULL;
- size_t old_written = cppReader_getWritten (pfile);
+ size_t old_written = cpplib_getWritten (pfile);
int nspaces = cppSkipHspace (pfile);
c = cppReader_peekC (pfile);
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')
{
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;
}
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)
{
int keyword_length = keyword->length;
- cppReader_reserve (pfile,
+ cpplib_reserve (pfile,
size_fromInt (2 + keyword_length + (limit - buf)));
cppReader_putCharQ (pfile, '#');
/*@-observertrans@*/
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++ = ' ';
/* Handle the start of a symbol. */
if (is_idchar[(int) c] && nargs > 0) {
char *id_beg = p - 1;
- int id_len;
+ size_t id_len;
--exp_p;
while (p != limit && is_idchar[(int) *p])
p++;
}
- id_len = p - id_beg;
+ id_len = size_fromInt (p - id_beg);
if (is_idstart[(int) c]
&& ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) {
if (arg->name[0] == c
&& arg->length == id_len
- && strncmp (arg->name, id_beg, size_fromInt (id_len)) == 0) {
+ && strncmp (arg->name, id_beg, id_len) == 0) {
char *p1;
if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) {
}
/*
- * special extension string that can be added to the last macro argument to
- * allow it to absorb the "rest" of the arguments when expanded. Ex:
- * #define wow(a, b...) process (b, a, b)
- * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); }
- * { wow (one, two); } -> { process (two, one, two); }
- * if this "rest_arg" is used with the concat token '##' and if it is not
- * supplied then the token attached to with ## will not be outputted. Ex:
- * #define wow (a, b...) process (b ## , a, ## b)
- * { wow (1, 2); } -> { process (2, 1, 2); }
- * { wow (one); } -> { process (one); {
- */
+** evans 2001-12-31
+** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...)
+*/
-/*@-readonlytrans@*/
-static char rest_extension[] = "...";
-/*:=readonlytrans@*/
+static DEFINITION *
+collect_expansionLoc (fileloc loc, char *buf, char *limit,
+ int nargs, /*@null@*/ struct arglist *arglist)
+{
+ DEFINITION *defn;
+ char *p, *lastp, *exp_p;
+ struct reflist *endpat = NULL;
+ /* Pointer to first nonspace after last ## seen. */
+ char *concat = 0;
+ /* Pointer to first nonspace after last single-# seen. */
+ char *stringify = 0;
+ size_t maxsize;
+ char expected_delimiter = '\0';
-/*@notfunction@*/
-#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
-/* Create a DEFINITION node from a #define directive. Arguments are
- as for do_define. */
+ /* Scan thru the replacement list, ignoring comments and quoted
+ strings, picking up on the macro calls. It does a linear search
+ thru the arg list on every potential symbol. Profiling might say
+ that something smarter should happen. */
-static /*@null@*/ MACRODEF
-create_definition (/*@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;
+ if (limit < buf)
+ {
+ llfatalbug (message ("%q: Limit is less than initial buffer pointer",
+ fileloc_unparse (loc)));
+ }
- cppBuffer_lineAndColumn (CPPBUFFER (pfile), &line, &col);
+ /* Find the beginning of the trailing whitespace. */
+ p = buf;
- bp = buf;
+ while (p < limit && is_space[(int) limit[-1]])
+ {
+ limit--;
+ }
- while (is_hor_space[(int) *bp])
+ /* Allocate space for the text in the macro definition.
+ Leading and trailing whitespace chars need 2 bytes each.
+ Each other input char may or may not need 1 byte,
+ so this is an upper bound. The extra 5 are for invented
+ leading and trailing newline-marker and final null. */
+ maxsize = (sizeof (*defn) + (limit - p) + 5);
+
+ /* Occurrences of '@' get doubled, so allocate extra space for them. */
+ while (p < limit)
{
- bp++;
+ if (*p++ == '@')
+ {
+ maxsize++;
+ }
}
- symname = bp; /* remember where it starts */
+ defn = (DEFINITION *) dmalloc (maxsize);
+ defn->noExpand = FALSE;
+ defn->file = NULL;
+ defn->pattern = NULL;
+ defn->nargs = nargs;
+ defn->predefined = NULL;
- sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));
+ exp_p = defn->expansion = (char *) defn + sizeof (*defn);
- bp += sym_length;
+ defn->line = 0;
+ defn->rest_args = NULL;
+ defn->args.argnames = NULL;
- /* 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. */
+ lastp = exp_p;
- if (*bp == '(') {
- struct arglist *arg_ptrs = NULL;
- int argno = 0;
+ p = buf;
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
+ /* Add one initial space escape-marker to prevent accidental
+ token-pasting (often removed by cpplib_macroExpand). */
+ *exp_p++ = '@';
+ *exp_p++ = ' ';
- /* 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;
+ if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
+ voptgenerror (FLG_PREPROC,
+ cstring_makeLiteral ("Paste marker ## at start of macro definition"),
+ loc);
+ p += 2;
+ }
- arg_ptrs = temp;
+ /* Process the main body of the definition. */
+ while (p < limit) {
+ int skipped_arg = 0;
+ register char c = *p++;
- if (rest_args != 0)
+ *exp_p++ = c;
+
+ if (TRUE) { /* !cppReader_isTraditional (pfile)) { */
+ switch (c) {
+ case '\'':
+ case '\"':
+ if (expected_delimiter != '\0')
{
- cppReader_pedwarn (pfile,
- message ("another parameter follows `%s'",
- cstring_fromChars (rest_extension)));
+ if (c == expected_delimiter)
+ expected_delimiter = '\0';
}
-
- if (!is_idstart[(int) *bp])
+ else
{
- cppReader_pedwarnLit (pfile,
- cstring_makeLiteralTemp ("invalid character in macro parameter name"));
+ expected_delimiter = c;
}
+ /*@switchbreak@*/ break;
- /* Find the end of the arg name. */
- while (is_idchar[(int) *bp])
+ case '\\':
+ if (p < limit && (expected_delimiter != '\0'))
{
- bp++;
- /* do we have a "special" rest-args extension here? */
- if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
- && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
- {
- rest_args = 1;
- temp->rest_args = 1;
- /*@innerbreak@*/ break;
- }
+ /* In a string, backslash goes through
+ and makes next char ordinary. */
+ *exp_p++ = *p++;
}
+ /*@switchbreak@*/ break;
- temp->length = bp - temp->name;
-
- if (rest_args != 0)
+ case '@':
+ /* An '@' in a string or character constant stands for itself,
+ and does not need to be escaped. */
+ if (expected_delimiter == '\0')
{
- bp += REST_EXTENSION_LENGTH;
+ *exp_p++ = c;
}
- arglengths += temp->length + 2;
- SKIP_WHITE_SPACE (bp);
+ /*@switchbreak@*/ break;
- if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
- cppReader_errorLit (pfile,
- cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
- goto nope;
- }
+ case '#':
+ /* # is ordinary inside a string. */
+ if (expected_delimiter != '\0')
+ {
+ /*@switchbreak@*/ break;
+ }
- if (*bp == ',') {
- bp++;
- SKIP_WHITE_SPACE (bp);
- }
- if (bp >= limit) {
- cppReader_errorLit (pfile,
- cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));
- goto nope;
- }
- {
- struct arglist *otemp;
+ if (p < limit && *p == '#') {
+ /* ##: concatenate preceding and following tokens. */
+ /* Take out the first #, discard preceding whitespace. */
+ exp_p--;
- for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
+ /*@-usedef@*/
+ while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
{
- 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;
+ --exp_p;
+ }
+ /*@=usedef@*/
+
+ /* Skip the second #. */
+ p++;
+ /* Discard following whitespace. */
+ SKIP_WHITE_SPACE (p);
+ concat = p;
+ if (p == limit)
+ {
+ voptgenerror (FLG_PREPROC,
+ cstring_makeLiteral ("`##' at end of macro definition"),
+ loc);
+ }
+ } else if (nargs >= 0) {
+ /* Single #: stringify following argument ref.
+ Don't leave the # in the expansion. */
+ exp_p--;
+ SKIP_WHITE_SPACE (p);
+ if (p == limit || ! is_idstart[(int) *p]
+ || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '\"')))
+ {
+ voptgenerror
+ (FLG_PREPROC,
+ cstring_makeLiteral ("`#' operator is not followed by a macro argument name"),
+ loc);
+ }
+ else
+ stringify = p;
+ } else {
+ ; /* BADBRANCH; */
+ }
+
+ /*@switchbreak@*/ break;
+ }
+ } else {
+ /* In -traditional mode, recognize arguments inside strings and
+ and character constants, and ignore special properties of #.
+ Arguments inside strings are considered "stringified", but no
+ extra quote marks are supplied. */
+ switch (c) {
+ case '\'':
+ case '\"':
+ if (expected_delimiter != '\0') {
+ if (c == expected_delimiter)
+ expected_delimiter = '\0';
+ } else
+ expected_delimiter = c;
+ /*@switchbreak@*/ break;
+
+ case '\\':
+ /* Backslash quotes delimiters and itself, but not macro args. */
+ if (expected_delimiter != '\0' && p < limit
+ && (*p == expected_delimiter || *p == '\\')) {
+ *exp_p++ = *p++;
+ continue;
+ }
+ /*@switchbreak@*/ break;
+
+ case '/':
+ if (expected_delimiter != '\0') /* No comments inside strings. */
+ /*@switchbreak@*/ break;
+ if (*p == '*') {
+ /* If we find a comment that wasn't removed by cppReader_handleDirective,
+ this must be -traditional. So replace the comment with
+ nothing at all. */
+ exp_p--;
+ p += 1;
+ while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
+ {
+ p++;
+ }
+ }
+ /*@switchbreak@*/ break;
+ }
+ }
+
+ /* Handle the start of a symbol. */
+ if (is_idchar[(int) c] && nargs > 0) {
+ char *id_beg = p - 1;
+ size_t id_len;
+
+ --exp_p;
+ while (p != limit && is_idchar[(int) *p])
+ {
+ p++;
+ }
+
+ id_len = size_fromInt (p - id_beg);
+
+ if (is_idstart[(int) c]
+ && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) {
+ register struct arglist *arg;
+
+ for (arg = arglist; arg != NULL; arg = arg->next) {
+ struct reflist *tpat;
+
+ if (arg->name[0] == c
+ && arg->length == id_len
+ && strncmp (arg->name, id_beg, id_len) == 0) {
+ char *p1;
+
+ if (expected_delimiter) { /* && CPPOPTIONS (pfile)->warn_stringify) { */
+ if (FALSE) { /* cppReader_isTraditional (pfile)) { */
+ voptgenerror (FLG_PREPROC,
+ message ("macro argument `%x' is stringified.",
+ cstring_prefix (cstring_fromChars (arg->name), id_len)),
+ loc);
+
+ } else {
+ voptgenerror (FLG_PREPROC,
+ message ("Macro arg `%x' would be stringified with -traditional.",
+ cstring_prefix (cstring_fromChars (arg->name), id_len)),
+ loc);
+
}
}
+ /* If ANSI, don't actually substitute inside a string. */
+ if (TRUE /* !cppReader_isTraditional (pfile) */ && expected_delimiter)
+ /*@innerbreak@*/ break;
+ /* make a pat node for this arg and append it to the end of
+ the pat list */
+ tpat = (struct reflist *) dmalloc (sizeof (*tpat));
+ tpat->next = NULL;
+ tpat->raw_before = (concat == id_beg);
+ tpat->raw_after = 0;
+ tpat->rest_args = arg->rest_args;
+ tpat->stringify = (FALSE /* cppReader_isTraditional (pfile) */
+ ? expected_delimiter != '\0'
+ : stringify == id_beg);
+
+ if (endpat == NULL)
+ {
+ defn->pattern = tpat;
+ }
+ else
+ {
+ endpat->next = tpat;
+ /*@-branchstate@*/
+ } /*@=branchstate@*/ /* evs 2000 was =branchstate */
+
+ endpat = tpat;
+
+ tpat->argno = arg->argno;
+ tpat->nchars = exp_p - lastp;
+
+ p1 = p;
+
+ SKIP_WHITE_SPACE (p1);
+
+ if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
+ {
+ tpat->raw_after = 1;
+ }
+
+ lastp = exp_p; /* place to start copying from next time */
+ skipped_arg = 1;
+
+ /*@innerbreak@*/ break;
+ }
}
}
+ /* If this was not a macro arg, copy it into the expansion. */
+ if (skipped_arg == 0) {
+ register char *lim1 = p;
+ p = id_beg;
+
+ while (p != lim1)
+ {
+ *exp_p++ = *p++;
+ }
+
+ if (stringify == id_beg)
+ {
+ voptgenerror
+ (FLG_PREPROC,
+ cstring_makeLiteral ("# operator should be followed by a macro argument name"),
+ loc);
+ }
+ }
+ }
+ }
+
+ if (/*!cppReader_isTraditional (pfile) && */ expected_delimiter == '\0')
+ {
+ /* If ANSI, put in a "@ " marker to prevent token pasting.
+ But not if "inside a string" (which in ANSI mode
+ happens only for -D option). */
+ *exp_p++ = '@';
+ *exp_p++ = ' ';
+ }
+
+ *exp_p = '\0';
+
+ defn->length = size_fromInt (exp_p - defn->expansion);
+
+ /* Crash now if we overrun the allocated size. */
+ if (defn->length + 1 > maxsize)
+ {
+ llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
+ }
+
+ 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 */
+ size_t sym_length; /* and how long it is */
+ int rest_args = 0; /* really int! */
+ int line;
+ int col;
+ cstring file = (CPPBUFFER (pfile) != NULL)
+ ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");
+ DEFINITION *defn;
+ int arglengths = 0; /* Accumulate lengths of arg names
+ plus number of args. */
+ macroDef mdef;
+ char save = *limit;
+ *limit = '\0';
+ DPRINTF (("Create definition: %s", buf));
+ *limit = save;
+
+ cppBuffer_getLineAndColumn (CPPBUFFER (pfile), &line, &col);
+
+ bp = buf;
+
+ while (is_hor_space[(int) *bp])
+ {
+ bp++;
+ }
+
+ symname = bp; /* remember where it starts */
+
+ sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));
+
+ bp += sym_length;
+
+ /* Lossage will occur if identifiers or control keywords are broken
+ across lines using backslash. This is not the right place to take
+ care of that. */
+
+ if (*bp == '(') {
+ struct arglist *arg_ptrs = NULL;
+ int argno = 0;
+
+ bp++; /* skip '(' */
+ SKIP_WHITE_SPACE (bp);
+
+ /* Loop over macro argument names. */
+ while (*bp != ')')
+ {
+ struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
+ temp->name = bp;
+ temp->next = arg_ptrs;
+ temp->argno = argno++;
+ temp->rest_args = 0;
+
+ arg_ptrs = temp;
+
+ if (rest_args != 0)
+ {
+ cppReader_pedwarn (pfile,
+ message ("another parameter follows `%s'",
+ cstring_fromChars (rest_extension)));
+ }
+
+ if (!is_idstart[(int) *bp])
+ {
+ cppReader_pedwarnLit (pfile,
+ cstring_makeLiteralTemp ("Invalid character in macro parameter name"));
+ }
+
+ /* Find the end of the arg name. */
+ while (is_idchar[(int) *bp])
+ {
+ bp++;
+ /* do we have a "special" rest-args extension here? */
+ if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
+ && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
+ {
+ rest_args = 1;
+ temp->rest_args = 1;
+ /*@innerbreak@*/ break;
+ }
+ }
+
+ temp->length = size_fromInt (bp - temp->name);
+
+ if (rest_args != 0)
+ {
+ bp += REST_EXTENSION_LENGTH;
+ }
+
+ arglengths += temp->length + 2;
+ SKIP_WHITE_SPACE (bp);
+
+ if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
+ cppReader_errorLit (pfile,
+ cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
+ goto nope;
+ }
+
+ if (*bp == ',') {
+ bp++;
+ SKIP_WHITE_SPACE (bp);
+ }
+ if (bp >= limit) {
+ cppReader_errorLit (pfile,
+ cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));
+ goto nope;
+ }
+ {
+ struct arglist *otemp;
+
+ for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
+ {
+ if (temp->length == otemp->length &&
+ strncmp (temp->name, otemp->name, 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. */
the argument names in reverse order
with comma-space between them. */
defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
-
+
{
struct arglist *temp;
int i = 0;
- for (temp = arg_ptrs; temp != NULL; temp = temp->next) {
- memcpy (&defn->args.argnames[i], temp->name, size_fromInt (temp->length));
- i += temp->length;
- if (temp->next != 0) {
- defn->args.argnames[i++] = ',';
- defn->args.argnames[i++] = ' ';
+ for (temp = arg_ptrs; temp != NULL; temp = temp->next)
+ {
+ memcpy (&defn->args.argnames[i], temp->name, temp->length);
+ i += temp->length;
+ if (temp->next != 0)
+ {
+ defn->args.argnames[i++] = ',';
+ defn->args.argnames[i++] = ' ';
+ }
}
- }
-
+
defn->args.argnames[i] = '\0';
}
}
}
/* now everything from bp before limit is the definition. */
- defn = collect_expansion (pfile, bp, limit, -1, NULL);
+ defn = collect_expansion (pfile, bp, limit, -1, NULL);
+ defn->args.argnames = mstring_createEmpty ();
+ }
+
+ defn->noExpand = noExpand;
+ DPRINTF (("No expand: %d", noExpand));
+
+ defn->line = line;
+
+ /* not: llassert (cstring_isUndefined (defn->file)); */
+ defn->file = file;
+
+ /* OP is null if this is a predefinition */
+ defn->predefined = predefinition;
+ mdef.defn = defn;
+ mdef.symnam = symname;
+ mdef.symlen = sym_length;
+
+ return mdef;
+
+nope:
+ mdef.defn = NULL;
+ mdef.symnam = NULL;
+ return mdef;
+}
+
+/*@null@*/ macroDef
+cpplib_createDefinition (cstring def,
+ fileloc loc,
+ bool predefinition,
+ bool noExpand)
+{
+ char *buf = cstring_toCharsSafe (def);
+ char *limit = buf + cstring_length (def);
+ char *bp; /* temp ptr into input buffer */
+ char *symname; /* remember where symbol name starts */
+ size_t sym_length; /* and how long it is */
+ int rest_args = 0; /* really int! */
+ int line = fileloc_lineno (loc);
+ cstring file = fileloc_filename (loc);
+ DEFINITION *defn;
+ int arglengths = 0; /* Accumulate lengths of arg names
+ plus number of args. */
+ macroDef mdef;
+
+ bp = buf;
+
+ DPRINTF (("Creating definition: %s", buf));
+
+ while (is_hor_space[(int) *bp])
+ {
+ bp++;
+ }
+
+ symname = bp; /* remember where it starts */
+
+ sym_length = cppReader_checkMacroNameLoc (loc, symname, cstring_makeLiteralTemp ("macro"));
+
+ DPRINTF (("length: %d", sym_length));
+
+ bp += sym_length;
+
+ DPRINTF (("Here: %s", bp));
+
+ /* Lossage will occur if identifiers or control keywords are broken
+ across lines using backslash. This is not the right place to take
+ care of that. */
+
+ if (*bp == '(') {
+ struct arglist *arg_ptrs = NULL;
+ int argno = 0;
+
+ bp++; /* skip '(' */
+ SKIP_WHITE_SPACE (bp);
+
+ /* Loop over macro argument names. */
+ while (*bp != ')')
+ {
+ struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
+ temp->name = bp;
+ temp->next = arg_ptrs;
+ temp->argno = argno++;
+ temp->rest_args = 0;
+
+ arg_ptrs = temp;
+
+ if (rest_args != 0)
+ {
+ voptgenerror (FLG_PREPROC,
+ message ("Another parameter follows %s",
+ cstring_fromChars (rest_extension)),
+ loc);
+ }
+
+ if (!is_idstart[(int) *bp])
+ {
+ voptgenerror (FLG_PREPROC,
+ message ("Invalid character in macro parameter name: %c", *bp),
+ loc);
+ }
+
+ /* Find the end of the arg name. */
+ while (is_idchar[(int) *bp])
+ {
+ bp++;
+ /* do we have a "special" rest-args extension here? */
+ if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
+ && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
+ {
+ rest_args = 1;
+ temp->rest_args = 1;
+ /*@innerbreak@*/ break;
+ }
+ }
+
+ temp->length = size_fromInt (bp - temp->name);
+
+ if (rest_args != 0)
+ {
+ bp += REST_EXTENSION_LENGTH;
+ }
+
+ arglengths += temp->length + 2;
+ SKIP_WHITE_SPACE (bp);
+
+ if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
+ voptgenerror (FLG_PREPROC,
+ cstring_makeLiteral ("Parameter list for #define is not parseable"),
+ loc);
+ goto nope;
+ }
+
+ if (*bp == ',') {
+ bp++;
+ SKIP_WHITE_SPACE (bp);
+ }
+ if (bp >= limit) {
+ voptgenerror (FLG_PREPROC,
+ cstring_makeLiteral ("Unterminated parameter list in #define'"),
+ loc);
+ goto nope;
+ }
+ {
+ struct arglist *otemp;
+
+ for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
+ {
+ if (temp->length == otemp->length &&
+ strncmp (temp->name, otemp->name, temp->length) == 0) {
+ cstring name = cstring_copyLength (temp->name, temp->length);
+
+ voptgenerror (FLG_PREPROC,
+ message ("Duplicate argument name in #define: %s", name),
+ loc);
+ goto nope;
+ }
+ }
+ }
+ }
+
+ ++bp; /* skip paren */
+ SKIP_WHITE_SPACE (bp);
+ /* now everything from bp before limit is the definition. */
+ defn = collect_expansionLoc (loc, bp, limit, argno, arg_ptrs);
+ defn->rest_args = rest_args;
+
+ /* Now set defn->args.argnames to the result of concatenating
+ the argument names in reverse order
+ with comma-space between them. */
+ defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
+
+ {
+ struct arglist *temp;
+ int i = 0;
+ for (temp = arg_ptrs; temp != NULL; temp = temp->next) {
+ memcpy (&defn->args.argnames[i], temp->name, temp->length);
+ i += temp->length;
+ if (temp->next != 0) {
+ defn->args.argnames[i++] = ',';
+ defn->args.argnames[i++] = ' ';
+ }
+ }
+
+ defn->args.argnames[i] = '\0';
+ }
+
+ sfree (arg_ptrs);
+ } else {
+ /* Simple expansion or empty definition. */
+
+ if (bp < limit)
+ {
+ if (is_hor_space[(int) *bp]) {
+ bp++;
+ SKIP_WHITE_SPACE (bp);
+ } else {
+ switch (*bp) {
+ case '!': case '\"': case '#': case '%': case '&': case '\'':
+ case ')': case '*': case '+': case ',': case '-': case '.':
+ case '/': case ':': case ';': case '<': case '=': case '>':
+ case '?': case '[': case '\\': case ']': case '^': case '{':
+ case '|': case '}': case '~':
+ voptgenerror (FLG_PREPROC,
+ message ("Missing white space after #define %x",
+ cstring_prefix (cstring_fromChars (symname),
+ sym_length)),
+ loc);
+ break;
+
+ default:
+ voptgenerror (FLG_PREPROC,
+ message ("Missing white space after #define %x",
+ cstring_prefix (cstring_fromChars (symname),
+ sym_length)),
+ loc);
+ break;
+ }
+ }
+ }
+
+ /* now everything from bp before limit is the definition. */
+ llassert (limit > bp);
+ defn = collect_expansionLoc (loc, bp, limit, -1, NULL);
defn->args.argnames = mstring_createEmpty ();
}
/* OP is null if this is a predefinition */
defn->predefined = predefinition;
+
mdef.defn = defn;
mdef.symnam = symname;
mdef.symlen = sym_length;
/* Check a purported macro name SYMNAME, and yield its length.
USAGE is the kind of name this is intended for. */
-int cppReader_checkMacroName (cppReader *pfile,
- char *symname,
- cstring usage)
+size_t cppReader_checkMacroName (cppReader *pfile, char *symname, cstring usage)
{
char *p;
size_t sym_length;
-
+
for (p = symname; is_idchar[(int) *p]; p++)
{
;
}
-
+
sym_length = size_fromInt (p - symname);
-
+
if (sym_length == 0
|| (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '\"')))
- cppReader_error (pfile, message ("invalid %s name", usage));
+ {
+ cppReader_error (pfile, message ("invalid %s name", usage));
+ }
else if (!is_idstart[(int) *symname])
{
char *msg = (char *) dmalloc (sym_length + 1);
}
}
- return size_toInt (sym_length);
+ return sym_length;
}
+
+/*
+** evans 2001-12-31
+** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...)
+*/
+
+size_t cppReader_checkMacroNameLoc (fileloc loc, char *symname, cstring usage)
+{
+ char *p;
+ size_t sym_length;
+
+ for (p = symname; is_idchar[(int) *p]; p++)
+ {
+ ;
+ }
+
+ sym_length = size_fromInt (p - symname);
+
+ if (sym_length == 0
+ || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '\"')))
+ {
+ 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 sym_length;
+}
+
/* Return zero if two DEFINITIONs are isomorphic. */
static bool
if (a1 != a2)
return TRUE;
- if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
- p2, d2->length - (p2 - d2->expansion), 1))
+ if (comp_def_part (first, p1, size_toInt (d1->length - (p1 - d1->expansion)),
+ p2, size_toInt (d2->length - (p2 - d2->expansion)), 1))
return TRUE;
return FALSE;
}
-/* Return TRUE if two parts of two macro definitions are effectively different.
- One of the parts starts at BEG1 and has LEN1 chars;
- the other has LEN2 chars at BEG2.
- Any sequence of whitespace matches any other sequence of whitespace.
- FIRST means these parts are the first of a macro definition;
- so ignore leading whitespace entirely.
- LAST means these parts are the last of a macro definition;
- so ignore trailing whitespace entirely. */
+/*
+** Return TRUE if two parts of two macro definitions are effectively different.
+** One of the parts starts at BEG1 and has LEN1 chars;
+** the other has LEN2 chars at BEG2.
+** Any sequence of whitespace matches any other sequence of whitespace.
+** FIRST means these parts are the first of a macro definition;
+** so ignore leading whitespace entirely.
+** LAST means these parts are the last of a macro definition;
+** so ignore trailing whitespace entirely.
+*/
static bool
comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last)
return (beg1 != end1) || (beg2 != end2);
}
-/* Process a #define command.
- BUF points to the contents of the #define command, as a contiguous string.
- LIMIT points to the first character past the end of the definition.
- KEYWORD is the keyword-table entry for #define,
- or NULL for a "predefined" macro. */
+/*
+** Process a #define command.
+** BUF points to the contents of the #define command, as a contiguous string.
+** LIMIT points to the first character past the end of the definition.
+** KEYWORD is the keyword-table entry for #define,
+** or NULL for a "predefined" macro.
+*/
static int
do_defineAux (cppReader *pfile, struct directive *keyword,
/*@exposed@*/ char *buf, char *limit, bool noExpand)
{
int hashcode;
- MACRODEF mdef;
+ macroDef mdef;
hashNode hp;
-
- DPRINTF (("Define aux: %d", noExpand));
mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand);
if (mdef.defn == 0)
goto nope;
- hashcode = hashf (mdef.symnam, mdef.symlen, CPP_HASHSIZE);
+ 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, size_toInt (mdef.symlen), hashcode)) != NULL)
{
bool ok = FALSE;
message ("Macro %q already defined",
cstring_copyLength (mdef.symnam,
mdef.symlen)));
-
}
}
DPRINTF (("Define macro: %s / %d",
mdef.symnam, mdef.defn->noExpand));
- hn = cppReader_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
+ hn = cpphash_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
/*@-branchstate@*/
} /*@=branchstate@*/
return 0;
nope:
-
return 1;
}
return do_defineAux (pfile, keyword, buf, limit, FALSE);
}
-/* This structure represents one parsed argument in a macro call.
- `raw' points to the argument text as written (`raw_length' is its length).
- `expanded' points to the argument's macro-expansion
- (its length is `expand_length').
- `stringified_length' is the length the argument would have
- if stringified.
- `use_count' is the number of times this macro arg is substituted
- into the macro. If the actual use count exceeds 10,
- the value stored is 10. */
+/*
+** This structure represents one parsed argument in a macro call.
+** `raw' points to the argument text as written (`raw_length' is its length).
+** `expanded' points to the argument's macro-expansion
+** (its length is `expand_length').
+** `stringified_length' is the length the argument would have
+** if stringified.
+** `use_count' is the number of times this macro arg is substituted
+** into the macro. If the actual use count exceeds 10,
+** the value stored is 10.
+*/
/* raw and expanded are relative to ARG_BASE */
/*@notfunction@*/
int use_count;
};
-/* Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.
- If BUFFER != NULL, then use the LENGTH characters in BUFFER
- as the new input buffer.
- Return the new buffer, or NULL on failure. */
+/*
+** Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.
+** If BUFFER != NULL, then use the LENGTH characters in BUFFER
+** as the new input buffer.
+** Return the new buffer, or NULL on failure.
+*/
/*@null@*/ /*@exposed@*/ cppBuffer *
cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)
{
- cppBuffer *buf = cppReader_getBuffer (pfile);
+ cppBuffer *buf = cppReader_getBufferSafe (pfile);
if (buf == pfile->buffer_stack)
{
buf--;
memset ((char *) buf, 0, sizeof (*buf));
+ DPRINTF (("Pushing buffer: %s", cstring_copyLength (buffer, length)));
CPPBUFFER (pfile) = buf;
buf->if_stack = pfile->if_stack;
return ++CPPBUFFER (pfile);
}
-/* Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.
- Pop the buffer when done. */
+/*
+** Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.
+** Pop the buffer when done.
+*/
void
cppReader_scanBuffer (cppReader *pfile)
{
enum cpp_token token;
- token = cppGetToken (pfile);
+ token = cpplib_getToken (pfile);
if (token == CPP_EOF) /* Should not happen ... */
{
*
* 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
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)
}
void
-cppBuffer_lineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,
- /*@null@*/ /*@out@*/ int *colp)
+cppBuffer_getLineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,
+ /*@null@*/ /*@out@*/ int *colp)
{
int dummy;
if (line > pfile->lineno && line < pfile->lineno + 8)
{
- cppReader_reserve (pfile, 20);
+ cpplib_reserve (pfile, 20);
while (line > pfile->lineno)
{
cppReader_putCharQ (pfile, '\n');
}
}
- cppReader_reserve (pfile,
- size_fromInt (4 * cstring_length (ip->nominal_fname) + 50));
+ cpplib_reserve (pfile, 4 * cstring_length (ip->nominal_fname) + 50);
{
#ifdef OUTPUT_LINE_COMMANDS
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));
for (;;)
{
- token = cppGetToken (pfile);
+ token = cpplib_getToken (pfile);
switch (token)
{
string = "";
}
- cppReader_reserve (pfile, 3 + 4 * strlen (string));
+ cpplib_reserve (pfile, 3 + 4 * strlen (string));
+ quote_string (pfile, string);
+ return;
+ }
+ case T_FUNC: /* added in ISO C99 */
+ {
+ /* We don't know the actual name of the function, but it doesn't matter */
+ char *string = "** function-name **";
+ cpplib_reserve (pfile, 3 + 4 * strlen (string));
quote_string (pfile, string);
return;
}
break;
case T_VERSION:
- buf = message ("\"%s\"", cstring_makeLiteralTemp (CPP_VERSION));
+ buf = cstring_makeLiteral ("\"--- cpp version---\"");
break;
#ifndef NO_BUILTIN_SIZE_TYPE
case T_SPEC_DEFINED:
buf = cstring_makeLiteral (" 0 "); /* Assume symbol is not defined */
ip = cppReader_getBuffer (pfile);
-
+ llassert (ip != NULL);
llassert (ip->cur != NULL);
SKIP_WHITE_SPACE (ip->cur);
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 ");
llfatalerror (message ("Pre-processing error: invalid special hash type"));
}
- len = size_fromInt (cstring_length (buf));
+ len = cstring_length (buf);
- cppReader_reserve (pfile, len + 1);
+ cpplib_reserve (pfile, len + 1);
cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len);
cppReader_nullTerminateQ (pfile);
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, ' ');
/* 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);
;
}
- (void) cppReader_install (name, len, type, ivalue, value, hash);
+ (void) cpphash_install (name, len, type, ivalue, value, hash);
cstring_free (sname);
}
static void
-cppReader_installBuiltinType (/*@observer@*/ char *name, ctype ctyp,
- int len, enum node_type type,
- int ivalue,
- /*@only@*/ /*@null@*/ char *value, int hash)
+cpplib_installBuiltinType (/*@observer@*/ char *name, ctype ctyp,
+ int len, enum node_type type,
+ int ivalue,
+ /*@only@*/ /*@null@*/ char *value, int hash)
{
cstring sname = cstring_fromChars (name);
- /* evs 2000 07 10 - removed a memory leak, detected by lclint */
+ /* evs 2000 07 10 - removed a memory leak, detected by splint */
llassert (usymtab_inGlobalScope ());
if (!usymtab_existsTypeEither (sname))
{
uentry ue = uentry_makeDatatype (sname, ctyp,
- NO, NO,
+ NO, qual_createConcrete (),
fileloc_createBuiltin ());
llassert (!usymtab_existsEither (sname));
usymtab_addGlobalEntry (ue);
}
- (void) cppReader_install (name, len, type, ivalue, value, hash);
+ (void) cpphash_install (name, len, type, ivalue, value, hash);
}
static void
initialize_builtins (cppReader *pfile)
{
- cppReader_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);
- cppReader_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);
- cppReader_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);
- cppReader_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);
- cppReader_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);
- cppReader_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);
+ cpplib_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);
+ cpplib_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);
+ cpplib_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);
+ cpplib_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);
+ cpplib_installBuiltin ("__func__", ctype_string, -1, T_FUNC, 0, NULL, -1);
+ cpplib_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);
+ cpplib_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);
#ifndef NO_BUILTIN_SIZE_TYPE
- cppReader_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);
+ cpplib_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);
#endif
#ifndef NO_BUILTIN_PTRDIFF_TYPE
- cppReader_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);
+ cpplib_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);
#endif
- cppReader_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1);
- cppReader_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);
- cppReader_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);
- cppReader_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1);
+ 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__
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
/*
** so that it is present only when truly compiling with GNU C.
*/
- /* cppReader_install ("__GNUC__", -1, T_CONST, 2, 0, -1); */
+ /* cpplib_install ("__GNUC__", -1, T_CONST, 2, 0, -1); */
+
+ cpplib_installBuiltin ("S_SPLINT_S", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1);
+
+ /*drl 1/9/2001/ try to define the right symbol for the architecture
+ We use autoconf to determine the target cpu
+ */
+ cpplib_installBuiltin ("__" TARGET_CPU, ctype_int, -1, T_CONST, 2, NULL, -1);
+
+ /*drl 1/2/2002 set some flags based on uname
+ I'd like to be able to do this with autoconf macro instead...
+ */
- cppReader_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ /*Thanks to Nelson Beebe for suggesting possible values for these */
+
+ if (! strcmp (UNAME, "Linux"))
+ {
+#ifdef __ppc
+ cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
+#endif
+ }
+
+ else if(! strcmp (UNAME, "Darwin"))
+ {
+ cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ }
+ else if(! strcmp (UNAME, "HP-UX"))
+ {
+ cpplib_installBuiltin ("PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_HIUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_HPUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_PA_RISC1_1", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__PWB__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__STDC_EXT__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hp9000s700", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hp9000s800__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hp9k8__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hppa__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__hpux__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__unix__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
+ }
+ else if(! strcmp (UNAME, "IRIX64"))
+ {
+ cpplib_installBuiltin ("LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_ABIN32", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_COMPILER_VERSION", ctype_int, -1, T_CONST, 730, NULL, -1);
+ cpplib_installBuiltin ("_LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_LONGLONG", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_MIPS_FPSET", ctype_int, -1, T_CONST, 32, NULL, -1);
+ cpplib_installBuiltin ("_MIPS_ISA", ctype_int, -1, T_CONST, 3, NULL, -1);
+ /*_MIPS_SIM=_ABIN32*/
+ cpplib_installBuiltin ("_MIPS_SIM", ctype_int, -1, T_CONST, 2, NULL , -1);
+ cpplib_installBuiltin ("_MIPS_SZINT", ctype_int, -1, T_CONST, 32, NULL, -1);
+ cpplib_installBuiltin ("_MIPS_SZLONG", ctype_int, -1, T_CONST, 32, NULL, -1);
+ cpplib_installBuiltin ("_MIPS_SZPTR", ctype_int, -1, T_CONST, 32, NULL, -1);
+ cpplib_installBuiltin ("_MODERN_C", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_PIC", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_SGI_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_SIZE_INT", ctype_int, -1, T_CONST, 32, NULL, -1);
+ cpplib_installBuiltin ("_SIZE_LONG", ctype_int, -1, T_CONST, 32, NULL, -1);
+ cpplib_installBuiltin ("_SIZE_PTR", ctype_int, -1, T_CONST, 32, NULL, -1);
+ cpplib_installBuiltin ("_SVR4_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("_SYSTYPE_SVR4", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__DSO__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__EXTENSIONS__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__INLINE_INTRINSICS", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__MATH_HAS_NO_SIDE_EFFECTS", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__mips", ctype_int, -1, T_CONST, 3, NULL, -1);
+ cpplib_installBuiltin ("__sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("mips", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
+ }
+ else if(! strcmp (UNAME, "OSF1"))
+ {
+ cpplib_installBuiltin ("__alpha", ctype_int, -1, T_CONST, 2, NULL, -1);
+ }
+ else if (!strcmp (UNAME, "Rhapsody"))
+ {
+ cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ }
+
+ else if (!strcmp (UNAME, "SunOS"))
+ {
+ cpplib_installBuiltin ("__OPEN_MAX", ctype_int, -1, T_CONST, 20, NULL, -1);
+ cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, 2, NULL, -1);
+ cpplib_installBuiltin ("__sparc", ctype_int, -1, T_CONST, 2, NULL, -1);
+ /* This define "-Dfileno(f)=0" should be inserted but we're going to stick to deinfe constants for now...*/
+ }
+ else
+ {
+ /*
+ types which we have not explictedly handled.
+ AIX, FreeBSD, IRIX, Mach
+ */
+ }
+
if (CPPOPTIONS (pfile)->debug_output)
{
dump_special_to_buffer (pfile, "__BASE_FILE__");
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;
char *oxbuf = NULL;
int start_line;
int start_column;
+ int end_line;
+ int end_column;
size_t xbuf_len;
- size_t old_written = cppReader_getWritten (pfile);
+ size_t old_written = cpplib_getWritten (pfile);
int rest_args;
int rest_zero = 0;
int i;
struct argdata *args = NULL;
pfile->output_escapes++;
-
- cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
+ cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
+ DPRINTF (("Expand macro: %d:%d", start_line, start_column));
nargs = defn->nargs;
rest_args = 1;
}
- args[i].raw = size_toLong (cppReader_getWritten (pfile));
+ args[i].raw = size_toLong (cpplib_getWritten (pfile));
token = macarg (pfile, rest_args);
- args[i].raw_length = cppReader_getWritten (pfile) - args[i].raw;
+ args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw);
args[i].newlines = FALSE; /* FIXME */
}
else
}
}
+ /*
+ ** If the agrument list was multiple lines, need to insert new lines to keep line
+ ** numbers accurate.
+ */
+
+ cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &end_line, &end_column);
+ DPRINTF (("Expand macro: %d:%d", end_line, end_column));
+
/* If macro wants zero args, we parsed the arglist for checking only.
Read directly from the macro definition. */
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++)
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);
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);
}
if (!cppReader_isTraditional (pfile))
cppReader_putChar (pfile, '\"'); /* insert ending quote */
arg->stringified_length
- = size_toInt (cppReader_getWritten (pfile) - arg->stringified);
+ = size_toInt (cpplib_getWritten (pfile) - arg->stringified);
}
xbuf_len += args[ap->argno].stringified_length;
}
else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
{
- /* Add 4 for two newline-space markers to prevent
- token concatenation. */
- assertSet (args); /*@i534 shouldn't need this */
+ /* Add 4 for two newline-space markers to prevent token concatenation. */
+ assertSet (args); /* Splint shouldn't need this */
xbuf_len += args[ap->argno].raw_length + 4;
}
else
/* We have an ordinary (expanded) occurrence of the arg.
So compute its expansion, if we have not already. */
- assertSet (args); /*@i534 shouldn't need this */
+ assertSet (args); /* shouldn't need this */
if (args[ap->argno].expand_length < 0)
{
- args[ap->argno].expanded = cppReader_getWritten (pfile);
+ args[ap->argno].expanded = cpplib_getWritten (pfile);
cpp_expand_to_buffer (pfile,
ARG_BASE + args[ap->argno].raw,
size_fromInt (args[ap->argno].raw_length));
args[ap->argno].expand_length
- = size_toInt (cppReader_getWritten (pfile) - args[ap->argno].expanded);
+ = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded);
}
/* Add 4 for two newline-space markers to prevent
/* Now put the expansion on the input stack
so our caller will commence reading from it. */
+ DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
+
+ if (end_line != start_line)
+ {
+ /* xbuf must have enough newlines */
+ int newlines = end_line - start_line;
+ int foundnewlines = 0;
+ char *xbufptr = xbuf;
+
+ while ((xbufptr = strchr (xbufptr, '\n')) != NULL && foundnewlines <= newlines)
+ {
+ foundnewlines++;
+ xbufptr++;
+
+ if (*xbufptr == '\0')
+ {
+ break;
+ }
+ }
+
+ if (foundnewlines < newlines)
+ {
+ cstring newbuf = cstring_copyLength (xbuf, xbuf_len);
+
+ while (foundnewlines < newlines)
+ {
+ newbuf = cstring_appendChar (newbuf, '\n');
+ foundnewlines++;
+ }
+
+ sfree (oxbuf);
+ xbuf = cstring_toCharsSafe (newbuf);
+ xbuf_len = cstring_length (newbuf);
+ /*@-branchstate@*/
+ } /*@=branchstate@*/
+ }
+
+ DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
+
push_macro_expansion (pfile, xbuf, xbuf_len, hp);
- cppReader_getBuffer (pfile)->has_escapes = 1;
+ DPRINTF (("After pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
+ cppReader_getBufferSafe (pfile)->has_escapes = 1;
/* Pop the space we've used in the token_buffer for argument expansion. */
cppReader_setWritten (pfile, old_written);
-
+ DPRINTF (("Done set written"));
+
/* Recursive macro use sometimes works traditionally.
#define foo(x,y) bar (x (y,0), y)
foo (foo, baz) */
|| xbuf[2] == '\"'))
{
llassert (mbuf->cur != NULL);
+ DPRINTF (("Eating: %c", xbuf[2]));
mbuf->cur += 2;
}
+
}
-/* Like cppGetToken, except that it does not read past end-of-line.
+/* Like cpplib_getToken, except that it does not read past end-of-line.
Also, horizontal space is skipped, and macros are popped. */
static enum cpp_token
{
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')
return CPP_VSPACE;
}
- token = cppGetToken (pfile);
+ token = cpplib_getToken (pfile);
switch (token)
{
This function expects to see "fname" or <fname> 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. */
struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
struct file_name_list dsp[1]; /* First in chain, if #include "..." */
struct file_name_list *searchptr = NULL;
- size_t old_written = cppReader_getWritten (pfile);
-
- int flen;
+ size_t old_written = cpplib_getWritten (pfile);
+ size_t flen;
int f; /* file number */
int angle_brackets = 0; /* 0 for "...", 1 for <...> */
{
/* 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;
/*@=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
{
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
}
}
}
-
+
cppReader_setWritten (pfile, old_written);
- flen = fend - fbeg;
+ flen = size_fromInt (fend - fbeg);
DPRINTF (("fbeg: %s", fbeg));
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)
{
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;
}
searchptr != NULL;
searchptr = searchptr->next)
{
- if (!cstring_isEmpty (searchptr->fname)) {
- cstring sys_dir = searchptr->fname;
- int length = cstring_length (sys_dir);
-
- if (cstring_equalLen (sys_dir, filename, length)
- && osd_isConnectChar (cstring_getChar (filename, length)))
- {
- if (searchptr->c_system_include_path)
- return 2;
- else
- return 1;
- }
- }
+ if (!cstring_isEmpty (searchptr->fname))
+ {
+ cstring sys_dir = searchptr->fname;
+ size_t length = cstring_length (sys_dir);
+
+ if (cstring_equalLen (sys_dir, filename, length)
+ && osd_isConnectChar (cstring_getChar (filename, length)))
+ {
+ if (searchptr->c_system_include_path)
+ return 2;
+ else
+ return 1;
+ }
+ }
}
-
+
return 0;
}
{
cppBuffer *ip = cppReader_getBuffer (pfile);
int new_lineno;
- size_t old_written = cppReader_getWritten (pfile);
+ size_t old_written = cpplib_getWritten (pfile);
enum file_change_code file_change = same_file;
enum cpp_token token;
+ llassert (ip != NULL);
token = get_directive_token (pfile);
if (token != CPP_NUMBER
hashNode *hash_bucket;
char *p;
size_t num_start;
- int fname_length;
+ size_t fname_length;
/* Turn the file name, which is a character string literal,
into a null-terminated string. Do this in place. */
- end_name = convert_string (pfile, fname, fname, cppReader_getPWritten (pfile), 1);
+ end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1);
if (end_name == NULL)
{
cppReader_errorLit (pfile,
goto bad_line_directive;
}
- fname_length = end_name - fname;
- num_start = cppReader_getWritten (pfile);
+ fname_length = size_fromInt (end_name - fname);
+ num_start = cpplib_getWritten (pfile);
token = get_directive_token (pfile);
if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
}
hash_bucket =
- &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
+ &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)];
+
for (hp = *hash_bucket; hp != NULL; hp = hp->next)
{
- if (hp->length == fname_length &&
- strncmp (hp->value.cpval, fname, size_fromInt (fname_length)) == 0) {
- ip->nominal_fname = cstring_fromChars (hp->value.cpval);
- break;
- }
+ if (hp->length == fname_length)
+ {
+ llassert (hp->value.cpval != NULL);
+
+ if (strncmp (hp->value.cpval, fname, fname_length) == 0)
+ {
+ ip->nominal_fname = cstring_fromChars (hp->value.cpval);
+ break;
+ }
+ }
}
-
+
if (hp == 0) {
/* Didn't find it; cons up a new one. */
hp = (hashNode) dmalloc (sizeof (*hp));
hp->length = fname_length;
hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
- memcpy (hp->value.cpval, fname, size_fromInt (fname_length));
+ memcpy (hp->value.cpval, fname, fname_length);
hp->value.cpval[fname_length] = '\0';
ip->nominal_fname = cstring_fromChars (hp->value.cpval);
}
do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
{
- int sym_length;
+ size_t sym_length;
hashNode hp;
char *orig_buf = buf;
sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
- while ((hp = cppReader_lookup (buf, sym_length, -1)) != NULL)
+ while ((hp = cpphash_lookup (buf, size_toInt (sym_length), -1)) != NULL)
{
/* If we are generating additional info for debugging (with -g) we
need to pass through all effective #undef commands. */
do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
char *buf, char *limit)
{
- int length = limit - buf;
+ size_t length = size_fromInt (limit - buf);
cstring copy = cstring_copyLength (buf, length);
cstring adv = cstring_advanceWhiteSpace (copy);
do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
char *buf, char *limit)
{
- int length = limit - buf;
+ size_t length = size_fromInt (limit - buf);
cstring copy = cstring_copyLength (buf, length);
cstring adv = cstring_advanceWhiteSpace (copy);
cppReader_warning (pfile, message ("#warning %s", adv));
/*@unused@*/ char *buf, /*@unused@*/ char *limit)
{
/* Allow #ident in system headers, since that's not user's fault. */
- if (cppReader_isPedantic (pfile) && !cppReader_getBuffer (pfile)->system_header_p)
+ if (cppReader_isPedantic (pfile)
+ && !cppReader_getBufferSafe (pfile)->system_header_p)
cppReader_pedwarnLit (pfile,
cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
- /* Leave rest of line to be read by later calls to cppGetToken. */
+ /* Leave rest of line to be read by later calls to cpplib_getToken. */
return 0;
}
been included yet. */
struct file_name_list *ptr;
char *p = buf + 14, *fname, *inc_fname;
- int fname_len;
+ size_t fname_len;
SKIP_WHITE_SPACE (p);
if (*p == '\n' || *p != '\"')
return 0;
fname = p + 1;
p = (char *) strchr (fname, '\"');
- fname_len = p != NULL ? p - fname : mstring_length (fname);
+ fname_len = p != NULL ? size_fromInt (p - fname) : mstring_length (fname);
for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
{
? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
if ((inc_fname != NULL)
- && (strncmp (inc_fname, fname, size_fromInt (fname_len)) == 0))
+ && (strncmp (inc_fname, fname, fname_len) == 0))
{
cpp_setLocation (pfile);
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;
}
static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
char *buf, char *limit)
{
- if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
+ if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
{
cppReader_errorLit (pfile,
cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
cstring_makeLiteralTemp ("`#elif' after `#else'"));
if (pfile->if_stack->fname != NULL
- && cppReader_getBuffer (pfile)->fname != NULL
+ && cppReader_getBufferSafe (pfile)->fname != NULL
&& !cstring_equal (pfile->if_stack->fname,
- cppReader_getBuffer (pfile)->nominal_fname))
+ cppReader_getBufferSafe (pfile)->nominal_fname))
fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
fprintf (stderr, ")\n");
}
{
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;
/*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
{
int skip;
- cppBuffer *ip = cppReader_getBuffer (pfile);
+ cppBuffer *ip = cppReader_getBufferSafe (pfile);
char *ident;
- int ident_length;
+ size_t ident_length;
enum cpp_token token;
int start_of_file = 0;
char *control_macro = 0;
- size_t old_written = cppReader_getWritten (pfile);
+ size_t old_written = cpplib_getWritten (pfile);
DPRINTF (("do xifdef: %d",
keyword->type == T_IFNDEF));
pfile->no_macro_expand--;
ident = pfile->token_buffer + old_written;
- ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);
+ DPRINTF (("Ident: %s", ident));
+
+ ident_length = cpplib_getWritten (pfile) - old_written;
cppReader_setWritten (pfile, old_written); /* Pop */
if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
if (! cppReader_isTraditional (pfile))
{
cppReader_pedwarn (pfile,
- message ("`#%s' with no argument", keyword->name));
+ message ("`#%s' with no argument", keyword->name));
}
}
else if (token == CPP_NAME)
{
- hashNode hp = cppReader_lookup (ident, ident_length, -1);
- skip = (keyword->type == T_IFDEF)
- ? (hp == NULL) : (hp != NULL);
+ hashNode hp = cpphash_lookup (ident, size_toInt (ident_length), -1);
- DPRINTF (("hp null: %d / %d / %d",
- (hp == NULL),
- (keyword->type == T_IFNDEF),
- skip));
-
+ skip = (keyword->type == T_IFDEF) ? (hp == NULL) : (hp != NULL);
+
+ DPRINTF (("hp null: %d / %d / %d", hp == NULL, keyword->type == T_IFNDEF, skip));
+
if (start_of_file && !skip)
{
DPRINTF (("Not skipping!"));
- control_macro = (char *) dmalloc (size_fromInt (ident_length + 1));
- memcpy (control_macro, ident, size_fromInt (ident_length + 1));
+ control_macro = (char *) dmalloc (ident_length + 1);
+ memcpy (control_macro, ident, ident_length + 1);
}
}
else
{
cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
- temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
+ temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
temp->next = pfile->if_stack;
temp->control_macro = control_macro;
temp->lineno = 0;
beg_of_line:
if (CPPOPTIONS (pfile)->output_conditionals)
{
- cppBuffer *pbuf = cppReader_getBuffer (pfile);
+ cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
char *start_line;
llassert (pbuf->buf != NULL);
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;
case T_IFNDEF:
temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
temp->next = pfile->if_stack;
- temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
+ temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
temp->type = kt->type;
temp->lineno = 0;
temp->if_succeeded = 0;
cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
/*@fallthrough@*/
case T_ELIF:
- if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
+ if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
{
cppReader_error (pfile,
message ("Preprocessor command #%s is not within a conditional", kt->name));
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 '\\':
cppReader_skipRestOfLine (pfile);
- if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) {
+ if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) {
cppReader_errorLit (pfile,
cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
return 0;
cppReader_skipRestOfLine (pfile);
- if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
+ if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
{
cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
}
for ( ; ifile != NULL; ifile = ifile->next)
{
- if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname))
+ if (cstring_equal (ifile->fname, cppReader_getBufferSafe (pfile)->fname))
{
ifile->control_macro = temp->control_macro;
break;
*/
enum cpp_token
-cppGetToken (cppReader *pfile)
+cpplib_getToken (cppReader *pfile)
+{
+ return cpplib_getTokenAux (pfile, FALSE);
+}
+
+enum cpp_token
+cpplib_getTokenForceExpand (cppReader *pfile)
+{
+ return cpplib_getTokenAux (pfile, TRUE);
+}
+
+enum cpp_token
+cpplib_getTokenAux (cppReader *pfile, bool forceExpand)
{
int c, c2, c3;
size_t old_written = 0;
int start_line, start_column;
enum cpp_token token;
struct cppOptions *opts = CPPOPTIONS (pfile);
- cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur;
+ cppReader_getBufferSafe (pfile)->prev = cppReader_getBufferSafe (pfile)->cur;
get_next:
c = cppReader_getC (pfile);
+ DPRINTF (("Get next token: %c", c));
if (c == EOF)
{
handle_eof:
- if (cppReader_getBuffer (pfile)->seen_eof)
+ if (cppReader_getBufferSafe (pfile)->seen_eof)
{
cppBuffer *buf = cppReader_popBuffer (pfile);
}
else
{
- cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
- cppReader_getBuffer (pfile)->seen_eof = 1;
+ cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
+ cppReader_getBufferSafe (pfile)->seen_eof = 1;
- if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)
+ if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname)
&& next_buf != cppReader_nullBuffer (pfile))
{
/* We're about to return from an #include file.
}
newlines = 0;
- cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
+ cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
&start_line, &start_column);
c = skip_comment (pfile, &newlines);
-
+ DPRINTF (("c = %c", c));
if (opts->put_out_comments && (c == '/' || c == EOF))
{
assertSet (&start_mark);
}
else
{
- cppReader_reserve(pfile, 1);
+ cpplib_reserve(pfile, 1);
cppReader_putCharQ (pfile, ' ');
return CPP_HSPACE;
}
case '\'':
/* A single quoted string is treated like a double -- some
programs (e.g., troff) are perverse this way */
- cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
- &start_line, &start_column);
- old_written = cppReader_getWritten (pfile);
+ cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
+ &start_line, &start_column);
+ old_written = cpplib_getWritten (pfile);
string:
+ DPRINTF (("Reading string: %c", c));
cppReader_putChar (pfile, c);
while (TRUE)
{
- int cc = cppReader_getC (pfile);
- if (cc == EOF)
+ /* evans-2003-06-07
+ ** Because of ISO8859-1 characters in string literals, we need a special test here.
+ */
+
+ if (cppReader_reachedEOF (pfile))
{
+
+ DPRINTF (("Matches EOF!"));
if (cppBuffer_isMacro (CPPBUFFER (pfile)))
{
/* try harder: this string crosses a macro expansion
Otherwise, only -D can make a macro with an unmatched
quote. */
cppBuffer *next_buf
- = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
- (*cppReader_getBuffer (pfile)->cleanup)
- (cppReader_getBuffer (pfile), pfile);
+ = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
+ (*cppReader_getBufferSafe (pfile)->cleanup)
+ (cppReader_getBufferSafe (pfile), pfile);
CPPBUFFER (pfile) = next_buf;
continue;
}
+
if (!cppReader_isTraditional (pfile))
{
cpp_setLocation (pfile);
setLine (long_toInt (start_line));
setColumn (long_toInt (start_column));
-
+
if (pfile->multiline_string_line != long_toInt (start_line)
&& pfile->multiline_string_line != 0)
{
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:
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;
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;
return CPP_OTHER;
case '@':
- if (cppReader_getBuffer (pfile)->has_escapes)
+ DPRINTF (("Macro @!"));
+ if (cppReader_getBufferSafe (pfile)->has_escapes)
{
c = cppReader_getC (pfile);
+ DPRINTF (("got c: %c", c));
if (c == '-')
{
if (pfile->output_escapes)
}
else if (is_space [c])
{
- cppReader_reserve (pfile, 2);
+ cpplib_reserve (pfile, 2);
if (pfile->output_escapes)
cppReader_putCharQ (pfile, '@');
cppReader_putCharQ (pfile, c);
c2 = cppReader_peekC (pfile);
if (isdigit(c2))
{
- cppReader_reserve(pfile, 2);
+ cpplib_reserve(pfile, 2);
cppReader_putCharQ (pfile, '.');
c = cppReader_getC (pfile);
goto number;
/* 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, '.');
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);
c2 = '.';
for (;;)
{
- cppReader_reserve (pfile, 2);
+ cpplib_reserve (pfile, 2);
cppReader_putCharQ (pfile, c);
NEWLINE_FIX;
c = cppReader_peekC (pfile);
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);
}
if (c == '\'')
{
- cppReader_reserve (pfile, 2);
+ cpplib_reserve (pfile, 2);
cppReader_putCharQ (pfile, c);
cppReader_nullTerminateQ (pfile);
return CPP_STRING;
{
hashNode hp;
char *ident;
- size_t before_name_written = cppReader_getWritten (pfile);
- int ident_len;
+ size_t before_name_written = cpplib_getWritten (pfile);
+ size_t ident_len;
parse_name (pfile, c);
pfile->only_seen_white = 0;
+
if (pfile->no_macro_expand)
{
+ DPRINTF (("Not expanding: %s", pfile->token_buffer));
return CPP_NAME;
}
ident = pfile->token_buffer + before_name_written;
- ident_len = (cppReader_getPWritten (pfile)) - ident;
+ DPRINTF (("Ident: %s", ident));
- hp = cppReader_lookupExpand (ident, ident_len, -1);
+ ident_len = size_fromInt ((cpplib_getPWritten (pfile)) - ident);
+
+ hp = cpphash_lookupExpand (ident, size_toInt (ident_len), -1, forceExpand);
if (hp == NULL)
{
+ DPRINTF (("No expand: %s %d", ident, ident_len));
return CPP_NAME;
}
if (hp->type == T_DISABLED)
{
+ DPRINTF (("Disabled!"));
+
if (pfile->output_escapes)
{ /* Return "@-IDENT", followed by '\0'. */
int i;
- cppReader_reserve (pfile, 3);
+ cpplib_reserve (pfile, 3);
ident = pfile->token_buffer + before_name_written;
cppReader_adjustWritten (pfile, 2);
- for (i = ident_len; i >= 0; i--)
+ for (i = size_toInt (ident_len); i >= 0; i--)
{
ident[i+2] = ident[i];
}
return CPP_NAME;
}
- /* If macro wants an arglist, verify that a '(' follows.
- first skip all whitespace, copying it to the output
- after the macro name. Then, if there is no '(',
- decide this is not a macro call and leave things that way. */
-
+ /*
+ ** If macro wants an arglist, verify that a '(' follows.
+ ** first skip all whitespace, copying it to the output
+ ** after the macro name. Then, if there is no '(',
+ ** decide this is not a macro call and leave things that way.
+ */
+
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
{
struct parse_marker macro_mark;
int is_macro_call;
+ DPRINTF (("Arglist macro!"));
+
+ /*
+ ** evans 2002-07-03: Moved this here (from below).
+ ** This bug caused necessary whitespace to be lost
+ ** when parsing parameterized macros without parameters.
+ */
+
+ parseSetMark (¯o_mark, pfile);
+
while (cppBuffer_isMacro (CPPBUFFER (pfile)))
{
cppBuffer *next_buf;
cppSkipHspace (pfile);
if (cppReader_peekC (pfile) != EOF)
{
+ DPRINTF (("Peeking!"));
/*@loopbreak@*/ break;
}
- next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
- (*cppReader_getBuffer (pfile)->cleanup) (cppReader_getBuffer (pfile), pfile);
+ next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
+ (*cppReader_getBufferSafe (pfile)->cleanup) (cppReader_getBufferSafe (pfile), pfile);
CPPBUFFER (pfile) = next_buf;
}
- parseSetMark (¯o_mark, pfile);
+ /* parseSetMark (¯o_mark, pfile); */
for (;;)
{
cppSkipHspace (pfile);
c = cppReader_peekC (pfile);
+ DPRINTF (("c: %c", c));
is_macro_call = c == '(';
if (c != '\n')
/*@loopbreak@*/ break;
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. */
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);
}
&& 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;
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);
struct file_name_map_list
{
- struct file_name_map_list *map_list_next;
- cstring map_list_name;
- struct file_name_map *map_list_map;
+ /*@only@*/ struct file_name_map_list *map_list_next;
+ /*@only@*/ cstring map_list_name;
+ /*@null@*/ struct file_name_map *map_list_map;
};
/* Read the file name map file for DIRNAME. */
name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
- f = fileTable_openFile (context_fileTable (), name, "r");
+ f = fileTable_openReadFile (context_fileTable (), name);
cstring_free (name);
if (f == NULL)
if ((searchptr != NULL)
&& (cstring_isDefined (searchptr->fname))
- && (cstring_length (searchptr->fname) == p - filename)
+ && (size_toInt (cstring_length (searchptr->fname)) == p - filename)
&& !strncmp (cstring_toCharsSafe (searchptr->fname),
filename,
size_fromInt (p - filename)))
/*@=mustfree@*/
}
- fp = cppReader_getBuffer (pfile);
+ fp = cppReader_getBufferSafe (pfile);
/*@-temptrans@*/ /* fname shouldn't really be temp */
fp->nominal_fname = fp->fname = fname;
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;
}
}
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;
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);
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 ();
}
struct stat sbuf;
if (fstat (fd, &sbuf) < 0) {
+ *mode_pointer = 0;
+ *size_pointer = 0;
return (-1);
}
void
parseSetMark (struct parse_marker *pmark, cppReader *pfile)
{
- cppBuffer *pbuf = cppReader_getBuffer (pfile);
+ cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
pmark->next = pbuf->marks;
/*@-temptrans@*/
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. */
void
parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
{
- cppBuffer *pbuf = cppReader_getBuffer (pfile);
+ cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
if (pbuf != pmark->buf)
{
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
void
parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
{
- cppBuffer *pbuf = cppReader_getBuffer (pfile);
+ cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
if (pbuf != pmark->buf)
{
}
pmark->position = pbuf->cur - pbuf->buf;
+ DPRINTF (("move mark: %s", pmark->position));
}
-void cppReader_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
+void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
{
struct cppOptions *opts = CPPOPTIONS (pfile);
cstring xp;
cppReader_appendIncludeChain (pfile, opts->before_system,
opts->last_before_system);
+
opts->first_system_include = opts->before_system;
/* Unless -fnostdinc,
tack on the standard include file dirs to the specified list */
+
if (!opts->no_standard_includes) {
struct default_include *p = include_defaults;
char *specd_prefix = opts->include_prefix;
char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
- int default_len = 0;
-
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (default_prefix != NULL) {
- if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
- default_len = strlen (default_prefix) - 7;
- default_prefix[default_len] = 0;
+ size_t default_len = 0;
+
+ /* Remove the `include' from /usr/local/lib/gcc.../include. */
+ if (default_prefix != NULL) {
+ if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
+ default_len = strlen (default_prefix) - 7;
+ default_prefix[default_len] = 0;
+ }
}
- }
-
+
/* Search "translated" versions of GNU directories.
These have /usr/local/lib/gcc... replaced by specd_prefix. */
if (specd_prefix != 0 && default_len != 0)
if (!p->cplusplus
|| (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
/* Does this dir start with the prefix? */
- if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix,
- size_fromInt (default_len)))
+ llassert (default_prefix != NULL);
+
+ if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len))
{
/* Yes; change prefix and add to search list. */
struct file_name_list *nlist
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++)
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);
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;
return (buf->buf + buf->line_base);
}
-int cppBufPeek (cppBuffer *buf)
+int cpplib_bufPeek (cppBuffer *buf)
{
if (buf->cur == NULL || buf->rlimit == NULL) {
return EOF;
if (pfile->buffer != NULL)
{
- if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname))
+ if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname))
{
- cstring fname = cppReader_getBuffer (pfile)->nominal_fname;
+ cstring fname = cppReader_getBufferSafe (pfile)->nominal_fname;
DPRINTF (("Looking up: %s", fname));
DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
fid = fileTable_lookup (context_fileTable (),
- cppReader_getBuffer (pfile)->fname);
+ cppReader_getBufferSafe (pfile)->fname);
}
}
else
{
fid = fileTable_lookup (context_fileTable (),
- cppReader_getBuffer (pfile)->fname);
+ cppReader_getBufferSafe (pfile)->fname);
}
- line = cppReader_getBuffer (pfile)->lineno;
+ line = cppReader_getBufferSafe (pfile)->lineno;
fileloc_free (g_currentloc);
if (fileId_isValid (fid))
{
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);
}
static enum cpp_token
cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
{
- cppBuffer *pbuf = cppReader_getBuffer (pfile);
+ cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
char *start;
int len;
+ fileloc loc;
bool eliminateComment = FALSE;
llassert (pbuf->buf != NULL);
char c = ' ';
char *scomment = start + 2;
char savec = start[len];
+
+ cpp_setLocation (pfile);
+ loc = fileloc_copy (g_currentloc);
start[0] = BEFORE_COMMENT_MARKER[0];
start[1] = BEFORE_COMMENT_MARKER[1];
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);
{
if (!context_getFlag (FLG_NOCOMMENTS))
{
- context_enterSuppressRegion ();
+ context_enterSuppressRegion (loc);
}
}
else if (mstring_equalPrefix (scomment, "end"))
{
if (!context_getFlag (FLG_NOCOMMENTS))
{
- context_exitSuppressRegion ();
+ context_exitSuppressRegion (loc);
}
}
else if (mstring_equalPrefix (scomment, "notparseable"))
{
/* fix from Mike Miller <MikeM@xata.com> */
context_fileSetFlag (FLG_NESTCOMMENT,
- ynm_fromCodeChar (sChar));
+ ynm_fromCodeChar (sChar),
+ loc);
}
else if (mstring_equalPrefix (rest, "namechecks"))
{
context_fileSetFlag (FLG_NAMECHECKS,
- ynm_fromCodeChar (sChar));
+ ynm_fromCodeChar (sChar),
+ loc);
}
else if (mstring_equalPrefix (rest, "macroredef"))
{
context_fileSetFlag (FLG_MACROREDEF,
- ynm_fromCodeChar (sChar));
+ ynm_fromCodeChar (sChar),
+ loc);
}
else if (mstring_equalPrefix (rest, "usevarargs"))
{
context_fileSetFlag (FLG_USEVARARGS,
- ynm_fromCodeChar (sChar));
+ ynm_fromCodeChar (sChar),
+ loc);
}
else if (mstring_equalPrefix (rest, "nextlinemacros"))
{
context_fileSetFlag (FLG_MACRONEXTLINE,
- ynm_fromCodeChar (sChar));
+ ynm_fromCodeChar (sChar),
+ loc);
}
else if (mstring_equalPrefix (rest, "allmacros")
|| mstring_equalPrefix (rest, "fcnmacros")
fl = FLG_CONSTMACROS;
}
-
- context_fileSetFlag (fl, ynm_fromCodeChar (sChar));
+ context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc);
notfunction = FALSE;
}
else
c = BEFORE_COMMENT_MARKER[0];
start[0] = BEFORE_COMMENT_MARKER[1];
- llassert (cstring_length (lintcomment) == len - 3);
+ llassert (size_toLong (cstring_length (lintcomment)) == len - 3);
for (i = 1; i < len - 2; i++)
{
- start[i] = cstring_getChar (lintcomment, i);
+ start[i] = cstring_getChar (lintcomment, size_fromInt (i));
}
start[len - 2] = AFTER_COMMENT_MARKER[0];
if (start[i] == '/'
&& i < len - 1
&& start[i + 1] == '*') {
- (void) cppoptgenerror (FLG_NESTCOMMENT,
- message ("Comment starts inside comment"),
- pfile);
+ (void) cppoptgenerror
+ (FLG_NESTCOMMENT,
+ message ("Comment starts inside comment"),
+ pfile);
}
if (start[i] != '\n')
}
}
- 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);
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
{
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... */
+ }
}
}
static int cpp_peekN (cppReader *pfile, int n)
{
- cppBuffer *buf = cppReader_getBuffer (pfile);
+ cppBuffer *buf = cppReader_getBufferSafe (pfile);
llassert (buf->cur != NULL);
llassert (buf->cur != NULL);
buf->cur += n;
}
+
+/*@=bufferoverflowhigh@*/
+/*@=bounds@*/