]> andersk Git - splint.git/blobdiff - src/cpplib.c
Fixed problem with NULL being changed.
[splint.git] / src / cpplib.c
index 86fc538f7e342524a3225d319fb1e50c919610fc..d927c7b7193e74e891b6c73fe50eed8bff43fa31 100644 (file)
@@ -1,41 +1,6 @@
 /*
-See
-http://src.openresources.com/debian/src/devel/HTML/S/altgcc_2.7.2.2.orig%20altgcc-2.7.2.2.orig%20protoize.c.html
-static char *
-abspath (cwd, rel_filename)
-
-*/
-
-/*!!!!
-*** cpplib.c.old Tue Nov 28 2000 09:04:09 AM
---- cpplib.c Tue Nov 28 2000 08:55:18 AM
-***************
-*** 5715,5722 ****
-     c2 = cppReader_peekC (pfile)
-     if (c2 != '\n'
-       goto randomchar
-!    token = CPP_HSPACE
-!    goto op2any
---- 5714,5723 ----
-          case '\\'
-     c2 = cppReader_peekC (pfile)
-     if (c2 != '\n'
-       goto randomchar
-!    cppReader_forward (pfile, 1)
-!    pfile->lineno++
-!    return CPP_HSPACE
-  
-   case '\n'
-     cppReader_putChar (pfile, c)
-
-
-Carl J. Appellof ( mailto:cappello@legato.com <mailto:cappello@legato.com> )
-*/ /*@i8@*/
-
-/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
 **         Massachusetts Institute of Technology
 **
 ** This program is free software; you can redistribute it and/or modify it
@@ -52,9 +17,9 @@ Carl J. Appellof ( mailto:cappello@legato.com <mailto:cappello@legato.com> )
 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 ** MA 02111-1307, USA.
 **
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
+** For information on splint: info@splint.org
+** To report a bug: splint-bug@splint.org
+** For more information: http://www.splint.org
 */
 /*
 ** cpplib.c
@@ -97,22 +62,26 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 # endif
 
 # include <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>
+/* SMF */
+# ifndef BCC32
 # include <sys/utime.h>                /* for __DATE__ and __TIME__ */
+# endif
+
 # 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>
@@ -127,15 +96,14 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 /* This defines "errno" properly for VMS, and gives us EACCES.  */
 # include <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"
 
 /*
@@ -145,6 +113,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 /*@+boolint@*/
 /*@+charint@*/
 
+/* Warnings for using sprintf - suppress them all for now... */
+/*@-bufferoverflowhigh@*/
+/*@-bounds@*/
+
 #define NO_SHORTNAMES
 
 # ifdef open
@@ -183,9 +155,11 @@ static void cpp_setLocation (cppReader *p_pfile)
 
 static enum cpp_token cpp_handleComment (cppReader *p_pfile,
                                         struct parse_marker *p_smark)
-     /*@modifies p_pfile, p_smark@*/;
+   /*@modifies p_pfile, p_smark@*/;
+  
+static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@modifies p_p@*/ ;
 
-static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@*/ ;
+static size_t cppReader_checkMacroNameLoc (fileloc p_loc, char *p_symname, cstring p_usage) ;
 
 static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ;
 
@@ -194,7 +168,7 @@ static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ;
 #endif
 
 /* Symbols to predefine.  */
-
+  
 #ifdef CPP_PREDEFINES
 static /*@observer@*/ char *predefs = CPP_PREDEFINES;
 #else
@@ -227,7 +201,7 @@ static /*@observer@*/ char *predefs = "";
 /*@constant observer char *WCHAR_TYPE@*/
 #define WCHAR_TYPE "int"
 #endif
-
+  
 /* The string value for __USER_LABEL_PREFIX__ */
 
 #ifndef USER_LABEL_PREFIX
@@ -250,7 +224,7 @@ static bool is_idstart[256];
 static bool is_hor_space[256];
 /* table to tell if c is horizontal or vertical space.  */
 static bool is_space[256];
-
+  
 static /*@exposed@*/ /*@null@*/ cppBuffer *
 cppReader_getBuffer (/*@special@*/ cppReader *p_pfile)
      /*@uses p_pfile->buffer@*/
@@ -268,23 +242,33 @@ static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ;
 # define cppBuffer_get(BUFFER) \
   ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
 
+/*@function static int cppBuffer_reachedEOF (sef cppBuffer *p_b) modifies nothing; @*/
+# define cppBuffer_reachedEOF(b) \
+  ((b)->cur < (b)->rlimit ? FALSE : TRUE)
+
 /* Append string STR (of length N) to PFILE's output buffer.  Make space. */
 /*@function static void cppReader_puts (sef cppReader *p_file, char *p_str, sef size_t p_n)
                      modifies *p_file; @*/
 # define cppReader_puts(PFILE, STR, N) \
-  cppReader_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)
-
+  cpplib_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)
+  
 /* Append character CH to PFILE's output buffer.  Assume sufficient space. */
 
 /*@function static void cppReader_putCharQ (cppReader *p_file, char p_ch)
                     modifies *p_file; @*/
 # define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH))
-
+/*
+static void cppReader_putCharQ (cppReader *p_file, char p_ch)
+{
+  fprintf (stderr, "put char: %c\n", p_ch);
+  (*(p_file)->limit++ = (p_ch));
+}
+*/
 /* Append character CH to PFILE's output buffer.  Make space if need be. */
 
 /*@function static void cppReader_putChar (sef cppReader *p_file, char p_ch)
                     modifies *p_file; @*/
-#define cppReader_putChar(PFILE, CH) (cppReader_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))
+#define cppReader_putChar(PFILE, CH) (cpplib_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))
 
 /* Make sure PFILE->limit is followed by '\0'. */
 /*@function static void cppReader_nullTerminateQ (cppReader *p_file)
@@ -295,7 +279,7 @@ static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ;
 /*@function static void cppReader_nullTerminate (sef cppReader *p_file)
                            modifies *p_file; @*/
 # define cppReader_nullTerminate(PFILE) \
-  (cppReader_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0)
+  (cpplib_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0)
 
 /*@function static void cppReader_adjustWritten (cppReader *p_file, size_t)
                            modifies *p_file; @*/
@@ -319,8 +303,11 @@ static void cppBuffer_forward (cppBuffer *p_buf, int p_n) /*@modifies *p_buf@*/
 /*@function static int cppReader_getC (cppReader *p_pfile) modifies *p_pfile; @*/
 # define cppReader_getC(pfile)   (cppBuffer_get (cppReader_getBufferSafe (pfile)))
 
+/*@function static int cppReader_reachedEOF (sef cppReader *p_pfile) modifies *p_pfile; @*/
+# define cppReader_reachedEOF(pfile)   (cppBuffer_reachedEOF (cppReader_getBufferSafe (pfile)))
+
 /*@function static int cppReader_peekC (cppReader *) modifies nothing;@*/
-# define cppReader_peekC(pfile)  (cppBufPeek (cppReader_getBufferSafe (pfile)))
+# define cppReader_peekC(pfile)  (cpplib_bufPeek (cppReader_getBufferSafe (pfile)))
 
 /* Move all backslash-newline pairs out of embarrassing places.
    Exchange all such pairs following BP
@@ -373,6 +360,8 @@ static void cppReader_scanBuffer (cppReader *p_pfile);
 
 # if defined (WIN32) || defined (OS2) && defined (__IBMC__)
 
+/* SMF */
+# ifndef BCC32
 /*
 ** WIN32 (at least the VC++ include files) does not define mode_t.
 */
@@ -380,10 +369,11 @@ static void cppReader_scanBuffer (cppReader *p_pfile);
 /*@-incondefs@*/ /*@-czechtypes@*/
 typedef unsigned int mode_t;
 /*@=incondefs@*/ /*@=czechtypes@*/
+# endif
 
 # endif
 
-static int file_size_and_mode (int p_fd, /*@out@*/ mode_t *p_mode_pointer,
+static int file_size_and_mode (int p_fd, /*@out@*/ __mode_t *p_mode_pointer,
                               /*@out@*/ size_t *p_size_pointer);
 static int safe_read (int p_desc, /*@out@*/ char *p_ptr, int p_len);
 
@@ -409,7 +399,7 @@ static int /*@alt void@*/ finclude (cppReader *p_pfile, int p_f,
                                    /*@dependent@*/ /*@null@*/ struct file_name_list *p_dirptr);
 
 static void validate_else (cppReader *p_pfile, cstring p_directive);
-
+  
 static void conditional_skip (cppReader *p_pfile, int p_skip,
                              enum node_type p_type,
                              /*@dependent@*/ /*@null@*/ char *p_control_macro);
@@ -465,9 +455,9 @@ struct directive {
    pointers to functions returning void.  */
 
 static int do_define (cppReader *, /*@null@*/ struct directive *, 
-                     char *, char *);
+                     /*@exposed@*/ char *, char *);
 static int do_defineAux (cppReader *, /*@null@*/ struct directive *,
-                        char *, char *, bool);
+                        /*@exposed@*/ char *, char *, bool);
      
 static int do_line (cppReader *, /*@null@*/ struct directive *);
 static int do_include (cppReader *, struct directive *, char *, char *);
@@ -493,7 +483,7 @@ static int do_warning (cppReader *, struct directive *, char *, char *);
 /* -I directories are added to the end, then the defaults are added.  */
 
 /*@access cstring@*/
-
+  
 static struct default_include {
   /*@dependent@*/ /*@observer@*/ cstring fname;        /* The name of the directory.  */
   int cplusplus;               /* Only look here if we're compiling C++.  */
@@ -532,7 +522,7 @@ static struct directive directive_table[] = {
   {  4, do_line, "line", T_LINE, TRUE, FALSE, FALSE },
   {  5, do_ident, "ident", T_IDENT, TRUE, FALSE, TRUE },
   /* {  8, do_unassert, "unassert", T_UNASSERT, TRUE, FALSE, FALSE }, */
-  {  -1, 0, "", T_UNUSED, FALSE, FALSE, FALSE },
+  {  -1, NULL, "", T_UNUSED, FALSE, FALSE, FALSE },
 };
 /*@noaccess cstring@*/
 
@@ -612,7 +602,7 @@ static void
 quote_string (cppReader *pfile, char *src)
 {
   char c;
-
+  
   cppReader_putCharQ (pfile, '\"');
   for (;;)
     {
@@ -623,7 +613,7 @@ quote_string (cppReader *pfile, char *src)
            cppReader_putCharQ (pfile, c);
          else
            {
-             sprintf (cppReader_getPWritten (pfile), "\\%03o",
+             sprintf (cpplib_getPWritten (pfile), "\\%03o",
                       (unsigned int) c);
              cppReader_adjustWritten (pfile, (size_t) 4);
            }
@@ -648,7 +638,7 @@ quote_string (cppReader *pfile, char *src)
 void
 cppReader_growBuffer (cppReader *pfile, size_t n)
 {
-  size_t old_written = cppReader_getWritten (pfile);
+  size_t old_written = cpplib_getWritten (pfile);
   pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;
   pfile->token_buffer = (char *)
     drealloc (pfile->token_buffer, pfile->token_buffer_size);
@@ -753,7 +743,7 @@ cppReader_define (cppReader *pfile, char *str)
   (void) do_define (pfile, NULL, buf, buf + strlen (buf));
   sfree (buf);
 }
-
+  
 /* Append a chain of `struct file_name_list's
    to the end of the main include chain.
    FIRST is gthe beginning of the chain to append, and LAST is the end.  */
@@ -786,11 +776,17 @@ cppReader_appendIncludeChain (cppReader *pfile,
       opts->first_bracket_include = first;
 
       for (dir = first; ; dir = dir->next) {
-       int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
+       size_t len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
+
        if (len > pfile->max_include_len)
-         pfile->max_include_len = len;
+         {
+           pfile->max_include_len = len;
+         }
+
        if (dir == last)
-         break;
+         {
+           break;
+         }
       }
     }
 
@@ -798,7 +794,8 @@ cppReader_appendIncludeChain (cppReader *pfile,
   /* last->next = NULL; */
   opts->last_include = last;
 }
-
+  
+# if 0
 static /*@unused@*/ void 
 cppReader_showIncludeChain (cppReader *pfile)
 {
@@ -819,7 +816,8 @@ cppReader_showIncludeChain (cppReader *pfile)
       fprintf (stderr, "No includes\n");
     }
 }
-
+# endif
+  
 cstring 
 cppReader_getIncludePath ()
 {
@@ -844,11 +842,11 @@ cppReader_getIncludePath ()
 }
 
 void
-cppReader_addIncludeChain (cppReader *pfile, struct file_name_list *dir)
+cppReader_addIncludeChain (cppReader *pfile, /*@only@*/ struct file_name_list *dir)
 {
   struct cppOptions *opts = CPPOPTIONS (pfile);
 
-  if (dir == 0)
+  if (dir == NULL)
     {
       return;
     }
@@ -865,8 +863,9 @@ cppReader_addIncludeChain (cppReader *pfile, struct file_name_list *dir)
 
   if (opts->first_bracket_include == 0)
     {
-      int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
+      size_t len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
       opts->first_bracket_include = dir;
+      
       if (len > pfile->max_include_len)
        {
          pfile->max_include_len = len;
@@ -885,7 +884,7 @@ static void
 path_include (cppReader *pfile, char *path)
 {
   char *p;
-
+  
 #ifdef __CYGWIN32__
   char *win32temp;
 
@@ -941,7 +940,7 @@ path_include (cppReader *pfile, char *path)
       p++;
     }
 }
-
+  
 void
 cppOptions_init (cppOptions *opts)
 {
@@ -971,6 +970,9 @@ cppOptions_init (cppOptions *opts)
   opts->warn_comments = 0;
   opts->warnings_are_errors = 0;
 
+  /* Added 2003-07-10: */
+  opts->traditional = FALSE;
+  opts->c89 = TRUE;
   initialize_char_syntax (opts);
 }
 
@@ -982,7 +984,7 @@ cppReader_nullUnderflow (/*@unused@*/ cppReader *pfile)
 
 void
 cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf,
-             /*@unused@*/ cppReader *pfile)
+                      /*@unused@*/ cppReader *pfile)
 {
   ;
 }
@@ -1076,6 +1078,13 @@ skip_comment (cppReader *pfile, /*@null@*/ long *linep)
   else if (cppReader_peekC (pfile) == '/' 
           && CPPOPTIONS (pfile)->cplusplus_comments)
     {
+      
+      (void) cppoptgenerror 
+       (FLG_SLASHSLASHCOMMENT,
+        message ("C++ style // comment" 
+                ),
+        pfile);
+      
       cppReader_forward (pfile, 1);
 
       for (;;)
@@ -1191,17 +1200,34 @@ copy_rest_of_line (cppReader *pfile)
       llassert (pfile->buffer != NULL);
 
       c = cppReader_getC (pfile);
+
       switch (c)
        {
        case EOF:
          goto end_directive;
        case '\\':
-         if (cppReader_peekC (pfile) == '\n')
+         /*
+         ** Patch from Brian St. Pierre for handling MS-DOS files.
+         */
+
+         DPRINTF (("Reading directive: %d", (int) c));
+
+         if (cppReader_peekC (pfile) == '\n'
+             || cppReader_peekC (pfile) == '\r')
            {
+             DPRINTF (("Reading directive..."));
+             if (cppReader_peekC (pfile) == '\r')
+               {
+                 DPRINTF (("Reading directive..."));
+                 cppReader_forward (pfile, 1);
+               }
+             
+             DPRINTF (("Reading directive..."));
              cppReader_forward (pfile, 1);
              continue;
            }
 
+         DPRINTF (("Falling..."));
        /*@fallthrough@*/ case '\'': case '\"':
          goto scan_directive_token;
 
@@ -1234,7 +1260,7 @@ copy_rest_of_line (cppReader *pfile)
          goto end_directive;
        scan_directive_token:
          cppReader_forward (pfile, -1);
-         (void) cppGetToken (pfile);
+         (void) cpplib_getToken (pfile);
          continue;
        }
       cppReader_putChar (pfile, c);
@@ -1246,7 +1272,7 @@ end_directive: ;
 void
 cppReader_skipRestOfLine (cppReader *pfile)
 {
-  size_t old = cppReader_getWritten (pfile);
+  size_t old = cpplib_getWritten (pfile);
   copy_rest_of_line (pfile);
   cppReader_setWritten (pfile, old);
 }
@@ -1261,8 +1287,9 @@ cppReader_handleDirective (cppReader *pfile)
   struct directive *kt = NULL;
   int ident_length;
   size_t after_ident = 0;
-  char *ident, *line_end = NULL;
-  size_t old_written = cppReader_getWritten (pfile);
+  char *ident = NULL;
+  char *line_end = NULL;
+  size_t old_written = cpplib_getWritten (pfile);
   int nspaces = cppSkipHspace (pfile);
 
   c = cppReader_peekC (pfile);
@@ -1291,7 +1318,7 @@ cppReader_handleDirective (cppReader *pfile)
   llassert (pfile->token_buffer != NULL);
   ident = pfile->token_buffer + old_written + 1;
 
-  ident_length = cppReader_getPWritten (pfile) - ident;
+  ident_length = cpplib_getPWritten (pfile) - ident;
 
   if (ident_length == 0 && cppReader_peekC (pfile) == '\n')
     {
@@ -1307,7 +1334,7 @@ cppReader_handleDirective (cppReader *pfile)
        }
 
       if (kt->length == ident_length
-         && (cstring_equalPrefix (kt->name, ident)))
+         && (cstring_equalPrefix (kt->name, cstring_fromChars (ident))))
        {
          break;
        }
@@ -1324,7 +1351,7 @@ cppReader_handleDirective (cppReader *pfile)
       bool comments = 1; /*cppReader_isTraditional (pfile) && kt->traditional_comments;  */
       int save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
       CPPOPTIONS (pfile)->put_out_comments = comments;
-      after_ident = cppReader_getWritten (pfile);
+      after_ident = cpplib_getWritten (pfile);
       copy_rest_of_line (pfile);
       CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
     }
@@ -1339,7 +1366,7 @@ cppReader_handleDirective (cppReader *pfile)
      so these parameters are invalid as soon as something gets appended
      to the token_buffer.  */
 
-  line_end = cppReader_getPWritten (pfile);
+  line_end = cpplib_getPWritten (pfile);
 
 
   if (!kt->pass_thru && kt->type != T_DEFINE)
@@ -1452,7 +1479,7 @@ pass_thru_directive (char *buf, char *limit,
 {
   int keyword_length = keyword->length;
 
-  cppReader_reserve (pfile,
+  cpplib_reserve (pfile,
                     size_fromInt (2 + keyword_length + (limit - buf)));
   cppReader_putCharQ (pfile, '#');
   /*@-observertrans@*/
@@ -1546,7 +1573,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit,
   p = buf;
 
   /* Add one initial space escape-marker to prevent accidental
-     token-pasting (often removed by macroexpand).  */
+     token-pasting (often removed by cpplib_macroExpand).  */
   *exp_p++ = '@';
   *exp_p++ = ' ';
 
@@ -1632,7 +1659,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit,
          exp_p--;
          SKIP_WHITE_SPACE (p);
          if (p == limit || ! is_idstart[(int) *p]
-             || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '"')))
+             || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '\"')))
            cppReader_errorLit (pfile,
                          cstring_makeLiteralTemp ("`#' operator is not followed by a macro argument name"));
          else
@@ -1688,7 +1715,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit,
     /* Handle the start of a symbol.  */
     if (is_idchar[(int) c] && nargs > 0) {
       char *id_beg = p - 1;
-      int id_len;
+      size_t id_len;
 
       --exp_p;
       while (p != limit && is_idchar[(int) *p])
@@ -1696,10 +1723,10 @@ collect_expansion (cppReader *pfile, char *buf, char *limit,
          p++;
        }
 
-      id_len = p - id_beg;
+      id_len = size_fromInt (p - id_beg);
 
       if (is_idstart[(int) c]
-         && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
+         && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) {
        register struct arglist *arg;
 
        for (arg = arglist; arg != NULL; arg = arg->next) {
@@ -1707,7 +1734,7 @@ collect_expansion (cppReader *pfile, char *buf, char *limit,
 
          if (arg->name[0] == c
              && arg->length == id_len
-             && strncmp (arg->name, id_beg, size_fromInt (id_len)) == 0) {
+             && strncmp (arg->name, id_beg, id_len) == 0) {
            char *p1;
 
            if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) {
@@ -1803,146 +1830,497 @@ collect_expansion (cppReader *pfile, char *buf, char *limit,
       llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
     }
 
-  return defn;
+  /*@i1@*/ return defn; /* Spurious warning here */
 }
 
 /*
- * special extension string that can be added to the last macro argument to
- * allow it to absorb the "rest" of the arguments when expanded.  Ex:
- *             #define wow(a, b...)            process (b, a, b)
- *             { wow (1, 2, 3); }      ->      { process (2, 3, 1, 2, 3); }
- *             { wow (one, two); }     ->      { process (two, one, two); }
- * if this "rest_arg" is used with the concat token '##' and if it is not
- * supplied then the token attached to with ## will not be outputted.  Ex:
- *             #define wow (a, b...)           process (b ## , a, ## b)
- *             { wow (1, 2); }         ->      { process (2, 1, 2); }
- *             { wow (one); }          ->      { process (one); {
- */
+** evans 2001-12-31
+** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...)
+*/
 
-/*@-readonlytrans@*/
-static char rest_extension[] = "...";
-/*:=readonlytrans@*/
+static DEFINITION *
+collect_expansionLoc (fileloc loc, char *buf, char *limit,
+                     int nargs, /*@null@*/ struct arglist *arglist)
+{
+  DEFINITION *defn;
+  char *p, *lastp, *exp_p;
+  struct reflist *endpat = NULL;
+  /* Pointer to first nonspace after last ## seen.  */
+  char *concat = 0;
+  /* Pointer to first nonspace after last single-# seen.  */
+  char *stringify = 0;
+  size_t maxsize;
+  char expected_delimiter = '\0';
 
-/*@notfunction@*/
-#define REST_EXTENSION_LENGTH  (sizeof (rest_extension) - 1)
 
-/* Create a DEFINITION node from a #define directive.  Arguments are
-   as for do_define.  */
+  /* Scan thru the replacement list, ignoring comments and quoted
+     strings, picking up on the macro calls.  It does a linear search
+     thru the arg list on every potential symbol.  Profiling might say
+     that something smarter should happen.  */
 
-static /*@null@*/ MACRODEF
-create_definition (char *buf, char *limit,
-                  cppReader *pfile, bool predefinition,
-                  bool noExpand)
-{
-  char *bp;                    /* temp ptr into input buffer */
-  char *symname;               /* remember where symbol name starts */
-  int sym_length;              /* and how long it is */
-  int rest_args = 0;   /* really int! */
-  int line;
-  int col;
-  cstring file = (CPPBUFFER (pfile) != NULL)
-    ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");
-  DEFINITION *defn;
-  int arglengths = 0;          /* Accumulate lengths of arg names
-                                  plus number of args.  */
-  MACRODEF mdef;
+  if (limit < buf)
+    {
+      llfatalbug (message ("%q: Limit is less than initial buffer pointer",
+                          fileloc_unparse (loc)));
+    }
 
-  cppBuffer_lineAndColumn (CPPBUFFER (pfile), &line, &col);
+  /* Find the beginning of the trailing whitespace.  */
+  p = buf;
 
-  bp = buf;
+  while (p < limit && is_space[(int) limit[-1]])
+    {
+      limit--;
+    }
 
-  while (is_hor_space[(int) *bp])
+  /* Allocate space for the text in the macro definition.
+     Leading and trailing whitespace chars need 2 bytes each.
+     Each other input char may or may not need 1 byte,
+     so this is an upper bound.  The extra 5 are for invented
+     leading and trailing newline-marker and final null.  */
+  maxsize = (sizeof (*defn) + (limit - p) + 5);
+
+  /* Occurrences of '@' get doubled, so allocate extra space for them.  */
+  while (p < limit)
     {
-      bp++;
+      if (*p++ == '@')
+       {
+         maxsize++;
+       }
     }
 
-  symname = bp;                        /* remember where it starts */
+  defn = (DEFINITION *) dmalloc (maxsize);
+  defn->noExpand = FALSE;
+  defn->file = NULL;
+  defn->pattern = NULL;
+  defn->nargs = nargs;
+  defn->predefined = NULL;
+  exp_p = defn->expansion = (char *) defn + sizeof (*defn);
 
-  sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));
+  defn->line = 0;
+  defn->rest_args = NULL;
+  defn->args.argnames = NULL;
 
-  bp += sym_length;
+  lastp = exp_p;
 
-  /* Lossage will occur if identifiers or control keywords are broken
-     across lines using backslash.  This is not the right place to take
-     care of that.  */
+  p = buf;
 
-  if (*bp == '(') {
-    struct arglist *arg_ptrs = NULL;
-    int argno = 0;
+  /* Add one initial space escape-marker to prevent accidental
+     token-pasting (often removed by cpplib_macroExpand).  */
+  *exp_p++ = '@';
+  *exp_p++ = ' ';
 
-    bp++;                      /* skip '(' */
-    SKIP_WHITE_SPACE (bp);
+  if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
+    voptgenerror (FLG_PREPROC,
+                 cstring_makeLiteral ("Paste marker ## at start of macro definition"),
+                 loc);
+    p += 2;
+  }
 
-    /* Loop over macro argument names.  */
-    while (*bp != ')')
-      {
-       struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
-       temp->name = bp;
-       temp->next = arg_ptrs;
-       temp->argno = argno++;
-       temp->rest_args = 0;
+  /* Process the main body of the definition.  */
+  while (p < limit) {
+    int skipped_arg = 0;
+    register char c = *p++;
 
-       arg_ptrs = temp;
+    *exp_p++ = c;
 
-       if (rest_args != 0)
+    if (TRUE) { /* !cppReader_isTraditional (pfile)) { */
+      switch (c) {
+      case '\'':
+      case '\"':
+       if (expected_delimiter != '\0')
          {
-           cppReader_pedwarn (pfile,
-                        message ("another parameter follows `%s'",
-                                 cstring_fromChars (rest_extension)));
+           if (c == expected_delimiter)
+             expected_delimiter = '\0';
+         }
+       else
+         {
+           expected_delimiter = c;
          }
+       /*@switchbreak@*/ break;
 
-       if (!is_idstart[(int) *bp])
+      case '\\':
+       if (p < limit && (expected_delimiter != '\0'))
          {
-           cppReader_pedwarnLit (pfile,
-                           cstring_makeLiteralTemp ("invalid character in macro parameter name"));
+           /* In a string, backslash goes through
+              and makes next char ordinary.  */
+           *exp_p++ = *p++;
          }
+       /*@switchbreak@*/ break;
 
-       /* Find the end of the arg name.  */
-       while (is_idchar[(int) *bp])
+      case '@':
+       /* An '@' in a string or character constant stands for itself,
+          and does not need to be escaped.  */
+       if (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;
-             }
+           *exp_p++ = c;
          }
 
-       temp->length = bp - temp->name;
+       /*@switchbreak@*/ break;
 
-       if (rest_args != 0)
+      case '#':
+       /* # is ordinary inside a string.  */
+       if (expected_delimiter != '\0')
          {
-           bp += REST_EXTENSION_LENGTH;
+           /*@switchbreak@*/ break;
          }
 
-       arglengths += temp->length + 2;
-       SKIP_WHITE_SPACE (bp);
+       if (p < limit && *p == '#') {
+         /* ##: concatenate preceding and following tokens.  */
+         /* Take out the first #, discard preceding whitespace.  */
+         exp_p--;
 
-       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
-         cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
-         goto nope;
-       }
+         /*@-usedef@*/
+         while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
+           {
+             --exp_p;
+           }
+         /*@=usedef@*/
 
-       if (*bp == ',') {
-         bp++;
-         SKIP_WHITE_SPACE (bp);
-       }
-       if (bp >= limit) {
-         cppReader_errorLit (pfile,
-                       cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));
-         goto nope;
-       }
+         /* Skip the second #.  */
+         p++;
+         /* Discard following whitespace.  */
+         SKIP_WHITE_SPACE (p);
+         concat = p;
+         if (p == limit)
+           {
+               voptgenerror (FLG_PREPROC,
+                             cstring_makeLiteral ("`##' at end of macro definition"),
+                             loc);
+           }
+       } else if (nargs >= 0) {
+         /* Single #: stringify following argument ref.
+            Don't leave the # in the expansion.  */
+         exp_p--;
+         SKIP_WHITE_SPACE (p);
+         if (p == limit || ! is_idstart[(int) *p]
+             || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '\"')))
+           {
+               voptgenerror 
+                 (FLG_PREPROC,
+                  cstring_makeLiteral ("`#' operator is not followed by a macro argument name"),
+                  loc);
+           }
+         else
+           stringify = p;
+       } else {
+         ; /* BADBRANCH; */
+       }
+
+       /*@switchbreak@*/ break;
+      }
+    } else {
+      /* In -traditional mode, recognize arguments inside strings and
+        and character constants, and ignore special properties of #.
+        Arguments inside strings are considered "stringified", but no
+        extra quote marks are supplied.  */
+      switch (c) {
+      case '\'':
+      case '\"':
+       if (expected_delimiter != '\0') {
+         if (c == expected_delimiter)
+           expected_delimiter = '\0';
+       } else
+         expected_delimiter = c;
+       /*@switchbreak@*/ break;
+
+      case '\\':
+       /* Backslash quotes delimiters and itself, but not macro args.  */
+       if (expected_delimiter != '\0' && p < limit
+           && (*p == expected_delimiter || *p == '\\')) {
+         *exp_p++ = *p++;
+         continue;
+       }
+       /*@switchbreak@*/ break;
+  
+      case '/':
+       if (expected_delimiter != '\0') /* No comments inside strings.  */
+         /*@switchbreak@*/ break;
+       if (*p == '*') {
+         /* If we find a comment that wasn't removed by cppReader_handleDirective,
+            this must be -traditional.  So replace the comment with
+            nothing at all.  */
+         exp_p--;
+         p += 1;
+         while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
+           {
+             p++;
+           }
+       }
+       /*@switchbreak@*/ break;
+      }
+    }
+
+    /* Handle the start of a symbol.  */
+    if (is_idchar[(int) c] && nargs > 0) {
+      char *id_beg = p - 1;
+      size_t id_len;
+
+      --exp_p;
+      while (p != limit && is_idchar[(int) *p])
+       {
+         p++;
+       }
+
+      id_len = size_fromInt (p - id_beg);
+
+      if (is_idstart[(int) c]
+         && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) {
+       register struct arglist *arg;
+
+       for (arg = arglist; arg != NULL; arg = arg->next) {
+         struct reflist *tpat;
+
+         if (arg->name[0] == c
+             && arg->length == id_len
+             && strncmp (arg->name, id_beg, id_len) == 0) {
+           char *p1;
+
+           if (expected_delimiter) { /* && CPPOPTIONS (pfile)->warn_stringify) { */
+             if (FALSE) { /* cppReader_isTraditional (pfile)) { */
+               voptgenerror (FLG_PREPROC,
+                             message ("macro argument `%x' is stringified.",
+                                      cstring_prefix (cstring_fromChars (arg->name), id_len)),
+                             loc);
+
+             } else {
+               voptgenerror (FLG_PREPROC,
+                             message ("Macro arg `%x' would be stringified with -traditional.",
+                                      cstring_prefix (cstring_fromChars (arg->name), id_len)),
+                             loc);
+               
+             }
+           }
+           /* If ANSI, don't actually substitute inside a string.  */
+           if (TRUE /* !cppReader_isTraditional (pfile) */ && expected_delimiter)
+             /*@innerbreak@*/ break;
+           /* make a pat node for this arg and append it to the end of
+              the pat list */
+           tpat = (struct reflist *) dmalloc (sizeof (*tpat));
+           tpat->next = NULL;
+           tpat->raw_before = (concat == id_beg);
+           tpat->raw_after = 0;
+           tpat->rest_args = arg->rest_args;
+           tpat->stringify = (FALSE /* cppReader_isTraditional (pfile) */
+                              ? expected_delimiter != '\0'
+                              : stringify == id_beg);
+
+           if (endpat == NULL)
+             {
+               defn->pattern = tpat;
+             }
+           else
+             {
+               endpat->next = tpat;
+               /*@-branchstate@*/
+             } /*@=branchstate@*/ /* evs 2000 was =branchstate */
+
+           endpat = tpat;
+
+           tpat->argno = arg->argno;
+           tpat->nchars = exp_p - lastp;
+
+           p1 = p;
+
+           SKIP_WHITE_SPACE (p1);
+
+           if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
+             {
+               tpat->raw_after = 1;
+             }
+
+           lastp = exp_p;      /* place to start copying from next time */
+           skipped_arg = 1;
+
+           /*@innerbreak@*/ break;
+         }
+       }
+      }
+
+      /* If this was not a macro arg, copy it into the expansion.  */
+      if (skipped_arg == 0) {
+       register char *lim1 = p;
+       p = id_beg;
+
+       while (p != lim1)
+         {
+           *exp_p++ = *p++;
+         }
+
+       if (stringify == id_beg)
+         {
+           voptgenerror
+             (FLG_PREPROC,
+              cstring_makeLiteral ("# operator should be followed by a macro argument name"),
+              loc);
+         }
+      }
+    }
+  }
+
+  if (/*!cppReader_isTraditional (pfile) && */ expected_delimiter == '\0')
+    {
+      /* If ANSI, put in a "@ " marker to prevent token pasting.
+        But not if "inside a string" (which in ANSI mode
+        happens only for -D option).  */
+      *exp_p++ = '@';
+      *exp_p++ = ' ';
+    }
+
+  *exp_p = '\0';
+
+  defn->length = size_fromInt (exp_p - defn->expansion);
+
+  /* Crash now if we overrun the allocated size.  */
+  if (defn->length + 1 > maxsize)
+    {
+      llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
+    }
+
+  /*@i1@*/ return defn; /* Spurious warning here */
+}
+
+/*
+ * special extension string that can be added to the last macro argument to
+ * allow it to absorb the "rest" of the arguments when expanded.  Ex:
+ *             #define wow(a, b...)            process (b, a, b)
+ *             { wow (1, 2, 3); }      ->      { process (2, 3, 1, 2, 3); }
+ *             { wow (one, two); }     ->      { process (two, one, two); }
+ * if this "rest_arg" is used with the concat token '##' and if it is not
+ * supplied then the token attached to with ## will not be outputted.  Ex:
+ *             #define wow (a, b...)           process (b ## , a, ## b)
+ *             { wow (1, 2); }         ->      { process (2, 1, 2); }
+ *             { wow (one); }          ->      { process (one); {
+ */
+
+/*@-readonlytrans@*/
+static char rest_extension[] = "...";
+/*:=readonlytrans@*/
+
+/*@notfunction@*/
+#define REST_EXTENSION_LENGTH  (sizeof (rest_extension) - 1)
+
+/* Create a DEFINITION node from a #define directive.  Arguments are
+   as for do_define.  */
+
+  
+static /*@null@*/ macroDef
+create_definition (/*@exposed@*/ char *buf, char *limit,
+                  cppReader *pfile, bool predefinition,
+                  bool noExpand)
+{
+  char *bp;                    /* temp ptr into input buffer */
+  char *symname;               /* remember where symbol name starts */
+  size_t sym_length;           /* and how long it is */
+  int rest_args = 0;   /* really int! */
+  int line;
+  int col;
+  cstring file = (CPPBUFFER (pfile) != NULL)
+    ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");
+  DEFINITION *defn;
+  int arglengths = 0;          /* Accumulate lengths of arg names
+                                  plus number of args.  */
+  macroDef mdef;
+  char save = *limit;
+  *limit = '\0';
+  DPRINTF (("Create definition: %s", buf));
+  *limit = save;
+
+  cppBuffer_getLineAndColumn (CPPBUFFER (pfile), &line, &col);
+
+  bp = buf;
+
+  while (is_hor_space[(int) *bp])
+    {
+      bp++;
+    }
+
+  symname = bp;                        /* remember where it starts */
+
+  sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));
+
+  bp += sym_length;
+
+  /* Lossage will occur if identifiers or control keywords are broken
+     across lines using backslash.  This is not the right place to take
+     care of that.  */
+
+  if (*bp == '(') {
+    struct arglist *arg_ptrs = NULL;
+    int argno = 0;
+
+    bp++;                      /* skip '(' */
+    SKIP_WHITE_SPACE (bp);
+
+    /* Loop over macro argument names.  */
+    while (*bp != ')')
+      {
+       struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
+       temp->name = bp;
+       temp->next = arg_ptrs;
+       temp->argno = argno++;
+       temp->rest_args = 0;
+
+       arg_ptrs = temp;
+
+       if (rest_args != 0)
+         {
+           cppReader_pedwarn (pfile,
+                        message ("another parameter follows `%s'",
+                                 cstring_fromChars (rest_extension)));
+         }
+
+       if (!is_idstart[(int) *bp])
+         {
+           cppReader_pedwarnLit (pfile,
+                           cstring_makeLiteralTemp ("Invalid character in macro parameter name"));
+         }
+
+       /* Find the end of the arg name.  */
+       while (is_idchar[(int) *bp])
+         {
+           bp++;
+           /* do we have a "special" rest-args extension here? */
+           if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
+               && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
+             {
+               rest_args = 1;
+               temp->rest_args = 1;
+               /*@innerbreak@*/ break;
+             }
+         }
+
+       temp->length = size_fromInt (bp - temp->name);
+
+       if (rest_args != 0)
+         {
+           bp += REST_EXTENSION_LENGTH;
+         }
+
+       arglengths += temp->length + 2;
+       SKIP_WHITE_SPACE (bp);
+
+       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
+         cppReader_errorLit (pfile,
+                       cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
+         goto nope;
+       }
+
+       if (*bp == ',') {
+         bp++;
+         SKIP_WHITE_SPACE (bp);
+       }
+       if (bp >= limit) {
+         cppReader_errorLit (pfile,
+                       cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));
+         goto nope;
+       }
        {
          struct arglist *otemp;
 
          for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
            {
              if (temp->length == otemp->length &&
-                 strncmp (temp->name, otemp->name, size_fromInt (temp->length)) == 0) {
+                 strncmp (temp->name, otemp->name, temp->length) == 0) {
                cstring name = cstring_copyLength (temp->name, temp->length);
                cppReader_error (pfile,
                           message ("duplicate argument name `%x' in `#define'", name));
@@ -1951,7 +2329,7 @@ create_definition (char *buf, char *limit,
            }
        }
       }
-
+  
     ++bp;                      /* skip paren */
     SKIP_WHITE_SPACE (bp);
     /* now everything from bp before limit is the definition.  */
@@ -1962,19 +2340,21 @@ create_definition (char *buf, char *limit,
        the argument names in reverse order
        with comma-space between them.  */
     defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
-
+  
     {
       struct arglist *temp;
       int i = 0;
-      for (temp = arg_ptrs; temp != NULL; temp = temp->next) {
-       memcpy (&defn->args.argnames[i], temp->name, size_fromInt (temp->length));
-       i += temp->length;
-       if (temp->next != 0) {
-         defn->args.argnames[i++] = ',';
-         defn->args.argnames[i++] = ' ';
+      for (temp = arg_ptrs; temp != NULL; temp = temp->next) 
+       {
+         memcpy (&defn->args.argnames[i], temp->name, temp->length);
+         i += temp->length;
+         if (temp->next != 0)
+           {
+             defn->args.argnames[i++] = ',';
+             defn->args.argnames[i++] = ' ';
+           }
        }
-      }
-
+      
       defn->args.argnames[i] = '\0';
     }
 
@@ -1989,7 +2369,7 @@ create_definition (char *buf, char *limit,
          SKIP_WHITE_SPACE (bp);
        } else {
          switch (*bp) {
-         case '!':  case '"':  case '#':  case '%':  case '&':  case '\'':
+         case '!':  case '\"':  case '#':  case '%':  case '&':  case '\'':
          case ')':  case '*':  case '+':  case ',':  case '-':  case '.':
          case '/':  case ':':  case ';':  case '<':  case '=':  case '>':
          case '?':  case '[':  case '\\': case ']':  case '^':  case '{':
@@ -2036,46 +2416,313 @@ nope:
   return mdef;
 }
 
+/*@null@*/ macroDef
+cpplib_createDefinition (cstring def,
+                        fileloc loc,
+                        bool predefinition,
+                        bool noExpand)
+{
+  char *buf = cstring_toCharsSafe (def);
+  char *limit = buf + cstring_length (def);
+  char *bp;                    /* temp ptr into input buffer */
+  char *symname;               /* remember where symbol name starts */
+  size_t sym_length;           /* and how long it is */
+  int rest_args = 0;   /* really int! */
+  int line = fileloc_lineno (loc);
+  cstring file = fileloc_filename (loc);
+  DEFINITION *defn;
+  int arglengths = 0;          /* Accumulate lengths of arg names
+                                  plus number of args.  */
+  macroDef mdef;
+
+  bp = buf;
+
+  DPRINTF (("Creating definition: %s", buf));
+
+  while (is_hor_space[(int) *bp])
+    {
+      bp++;
+    }
+
+  symname = bp;        /* remember where it starts */
+
+  sym_length = cppReader_checkMacroNameLoc (loc, symname, cstring_makeLiteralTemp ("macro"));
+
+  DPRINTF (("length: %d", sym_length));
+
+  bp += sym_length;
+
+  DPRINTF (("Here: %s", bp));
+
+  /* Lossage will occur if identifiers or control keywords are broken
+     across lines using backslash.  This is not the right place to take
+     care of that.  */
+
+  if (*bp == '(') {
+    struct arglist *arg_ptrs = NULL;
+    int argno = 0;
+  
+    bp++;                      /* skip '(' */
+    SKIP_WHITE_SPACE (bp);
+
+    /* Loop over macro argument names.  */
+    while (*bp != ')')
+      {
+       struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
+       temp->name = bp;
+       temp->next = arg_ptrs;
+       temp->argno = argno++;
+       temp->rest_args = 0;
+
+       arg_ptrs = temp;
+
+       if (rest_args != 0)
+         {
+           voptgenerror (FLG_PREPROC,
+                         message ("Another parameter follows %s",
+                                  cstring_fromChars (rest_extension)),
+                         loc);
+         }
+
+       if (!is_idstart[(int) *bp])
+         {
+           voptgenerror (FLG_PREPROC,
+                         message ("Invalid character in macro parameter name: %c", *bp),
+                         loc);
+         }
+
+       /* Find the end of the arg name.  */
+       while (is_idchar[(int) *bp])
+         {
+           bp++;
+           /* do we have a "special" rest-args extension here? */
+           if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
+               && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
+             {
+               rest_args = 1;
+               temp->rest_args = 1;
+               /*@innerbreak@*/ break;
+             }
+         }
+
+       temp->length = size_fromInt (bp - temp->name);
+       
+       if (rest_args != 0)
+         {
+           bp += REST_EXTENSION_LENGTH;
+         }
+
+       arglengths += temp->length + 2;
+       SKIP_WHITE_SPACE (bp);
+       
+       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
+         voptgenerror (FLG_PREPROC,
+                       cstring_makeLiteral ("Parameter list for #define is not parseable"),
+                       loc);
+         goto nope;
+       }
+
+       if (*bp == ',') {
+         bp++;
+         SKIP_WHITE_SPACE (bp);
+       }
+       if (bp >= limit) {
+         voptgenerror (FLG_PREPROC,
+                       cstring_makeLiteral ("Unterminated parameter list in #define'"),
+                       loc);
+         goto nope;
+       }
+       {
+         struct arglist *otemp;
+
+         for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
+           {
+             if (temp->length == otemp->length &&
+                 strncmp (temp->name, otemp->name, temp->length) == 0) {
+               cstring name = cstring_copyLength (temp->name, temp->length);
+
+               voptgenerror (FLG_PREPROC,
+                             message ("Duplicate argument name in #define: %s", name),
+                             loc);
+               goto nope;
+             }
+           }
+       }
+      }
+    
+    ++bp;                      /* skip paren */
+    SKIP_WHITE_SPACE (bp);
+    /* now everything from bp before limit is the definition.  */
+    defn = collect_expansionLoc (loc, bp, limit, argno, arg_ptrs);
+    defn->rest_args = rest_args;
+    
+    /* Now set defn->args.argnames to the result of concatenating
+       the argument names in reverse order
+       with comma-space between them.  */
+    defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
+
+    {
+      struct arglist *temp;
+      int i = 0;
+      for (temp = arg_ptrs; temp != NULL; temp = temp->next) {
+       memcpy (&defn->args.argnames[i], temp->name, temp->length);
+       i += temp->length;
+       if (temp->next != 0) {
+         defn->args.argnames[i++] = ',';
+         defn->args.argnames[i++] = ' ';
+       }
+      }
+
+      defn->args.argnames[i] = '\0';
+    }
+
+    sfree (arg_ptrs);
+  } else {
+    /* Simple expansion or empty definition.  */
+
+    if (bp < limit)
+      {
+       if (is_hor_space[(int) *bp]) {
+         bp++;
+         SKIP_WHITE_SPACE (bp);
+       } else {
+         switch (*bp) {
+         case '!':  case '\"':  case '#':  case '%':  case '&':  case '\'':
+         case ')':  case '*':  case '+':  case ',':  case '-':  case '.':
+         case '/':  case ':':  case ';':  case '<':  case '=':  case '>':
+         case '?':  case '[':  case '\\': case ']':  case '^':  case '{':
+         case '|':  case '}':  case '~':
+           voptgenerror (FLG_PREPROC,
+                         message ("Missing white space after #define %x",
+                                  cstring_prefix (cstring_fromChars (symname),
+                                                  sym_length)),
+                         loc);
+           break;
+
+         default:
+           voptgenerror (FLG_PREPROC,
+                         message ("Missing white space after #define %x",
+                                  cstring_prefix (cstring_fromChars (symname),
+                                                  sym_length)),
+                         loc);
+           break;
+         }
+       }
+      }
+
+    /* now everything from bp before limit is the definition.  */
+    llassert (limit > bp);
+    defn = collect_expansionLoc (loc, bp, limit, -1, NULL);
+    defn->args.argnames = mstring_createEmpty ();
+  }
+
+  defn->noExpand = noExpand;
+  DPRINTF (("No expand: %d", noExpand));
+
+  defn->line = line;
+
+  /* not: llassert (cstring_isUndefined (defn->file)); */
+  defn->file = file;
+
+  /* OP is null if this is a predefinition */
+  defn->predefined = predefinition;
+
+  mdef.defn = defn;
+  mdef.symnam = symname;
+  mdef.symlen = sym_length;
+
+  return mdef;
+
+nope:
+  mdef.defn = NULL;
+  mdef.symnam = NULL;
+  return mdef;
+}
+
 /* Check a purported macro name SYMNAME, and yield its length.
    USAGE is the kind of name this is intended for.  */
 
-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));
+    }
+  else if (!is_idstart[(int) *symname])
+    {
+      char *msg = (char *) dmalloc (sym_length + 1);
+      memcpy (msg, symname, sym_length);
+      msg[sym_length] = '\0';
+      cppReader_error (pfile, message ("invalid %s name `%s'", usage,
+                                      cstring_fromChars (msg)));
+      sfree (msg);
+    }
+  else
+    {
+      if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7)
+       {
+         cppReader_error (pfile, message ("invalid %s name `defined'", usage));
+       }
+    }
+
+  return sym_length;
+}
+  
+/*
+** evans 2001-12-31
+** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...)
+*/
 
+size_t cppReader_checkMacroNameLoc (fileloc loc, char *symname, cstring usage)
+{
+  char *p;
+  size_t sym_length;
+  
   for (p = symname; is_idchar[(int) *p]; p++)
     {
       ;
     }
-
+  
   sym_length = size_fromInt (p - symname);
-
+  
   if (sym_length == 0
-      || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
-    cppReader_error (pfile, message ("invalid %s name", usage));
+      || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '\"')))
+    {
+      voptgenerror (FLG_PREPROC, message ("Invalid %s name: %s", usage, 
+                                         cstring_fromChars (symname)), loc);
+    }
   else if (!is_idstart[(int) *symname])
     {
       char *msg = (char *) dmalloc (sym_length + 1);
       memcpy (msg, symname, sym_length);
       msg[sym_length] = '\0';
-      cppReader_error (pfile, message ("invalid %s name `%s'", usage,
-                                      cstring_fromChars (msg)));
+      voptgenerror (FLG_PREPROC, message ("Invalid %s name: %s", usage, 
+                                         cstring_fromChars (msg)),
+                   loc);
       sfree (msg);
     }
   else
     {
       if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7)
        {
-         cppReader_error (pfile, message ("invalid %s name `defined'", usage));
+         voptgenerror (FLG_PREPROC, message ("Invalid %s name: defined", usage), loc);
        }
     }
 
-  return size_toInt (sym_length);
+  return sym_length;
 }
-
+  
 /* Return zero if two DEFINITIONs are isomorphic.  */
 
 static bool
@@ -2117,21 +2764,23 @@ compare_defs (DEFINITION *d1, DEFINITION *d2)
   if (a1 != a2)
     return TRUE;
 
-  if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
-                    p2, d2->length - (p2 - d2->expansion), 1))
+  if (comp_def_part (first, p1, size_toInt (d1->length - (p1 - d1->expansion)),
+                    p2, size_toInt (d2->length - (p2 - d2->expansion)), 1))
     return TRUE;
 
   return FALSE;
 }
 
-/* Return TRUE if two parts of two macro definitions are effectively different.
-   One of the parts starts at BEG1 and has LEN1 chars;
-   the other has LEN2 chars at BEG2.
-   Any sequence of whitespace matches any other sequence of whitespace.
-   FIRST means these parts are the first of a macro definition;
-   so ignore leading whitespace entirely.
-   LAST means these parts are the last of a macro definition;
-   so ignore trailing whitespace entirely.  */
+/*
+** Return TRUE if two parts of two macro definitions are effectively different.
+**    One of the parts starts at BEG1 and has LEN1 chars;
+**    the other has LEN2 chars at BEG2.
+**    Any sequence of whitespace matches any other sequence of whitespace.
+**    FIRST means these parts are the first of a macro definition;
+**    so ignore leading whitespace entirely.
+**    LAST means these parts are the last of a macro definition;
+**    so ignore trailing whitespace entirely.  
+*/
 
 static bool
 comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last)
@@ -2158,34 +2807,30 @@ comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last
   return (beg1 != end1) || (beg2 != end2);
 }
 
-/* Process a #define command.
-   BUF points to the contents of the #define command, as a contiguous string.
-   LIMIT points to the first character past the end of the definition.
-   KEYWORD is the keyword-table entry for #define,
-   or NULL for a "predefined" macro.  */
+/* 
+** Process a #define command.
+**    BUF points to the contents of the #define command, as a contiguous string.
+**    LIMIT points to the first character past the end of the definition.
+**    KEYWORD is the keyword-table entry for #define,
+**    or NULL for a "predefined" macro.  
+*/
 
 static int
 do_defineAux (cppReader *pfile, struct directive *keyword,
-             char *buf, char *limit, bool noExpand)
+             /*@exposed@*/ char *buf, char *limit, bool noExpand)
 {
   int hashcode;
-  MACRODEF mdef;
+  macroDef mdef;
   hashNode hp;
-  
-  DPRINTF (("Define aux: %d", noExpand));
 
   mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand);
 
   if (mdef.defn == 0)
     goto nope;
 
-  hashcode = hashf (mdef.symnam, mdef.symlen, CPP_HASHSIZE);
-
-  DPRINTF (("Macro: %s / %s", 
-           cstring_copyLength (mdef.symnam, mdef.symlen),
-           bool_unparse (noExpand)));
+  hashcode = cpphash_hashCode (mdef.symnam, mdef.symlen, CPP_HASHSIZE);
 
-  if ((hp = cppReader_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL)
+  if ((hp = cpphash_lookup (mdef.symnam, size_toInt (mdef.symlen), hashcode)) != NULL)
     {
       bool ok = FALSE;
 
@@ -2199,7 +2844,7 @@ do_defineAux (cppReader *pfile, struct directive *keyword,
       else if (hp->type == T_CONST)
        ok = !CPPOPTIONS (pfile)->done_initializing;
       else {
-       BADBRANCH;
+       ok = FALSE; /* Redefining anything else is bad. */
       }
 
       /* Print the warning if it's not ok.  */
@@ -2242,7 +2887,6 @@ do_defineAux (cppReader *pfile, struct directive *keyword,
                            message ("Macro %q already defined",
                                     cstring_copyLength (mdef.symnam,
                                                         mdef.symlen)));
-
            }
        }
 
@@ -2267,34 +2911,35 @@ do_defineAux (cppReader *pfile, struct directive *keyword,
       DPRINTF (("Define macro: %s / %d", 
                mdef.symnam, mdef.defn->noExpand));
       
-      hn = cppReader_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
+      hn = cpphash_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
       /*@-branchstate@*/
     } /*@=branchstate@*/
 
   return 0;
 
 nope:
-
   return 1;
 }
 
 static int
 do_define (cppReader *pfile, struct directive *keyword,
-          char *buf, char *limit)
+          /*@exposed@*/ char *buf, char *limit)
 {
   DPRINTF (("Regular do define"));
   return do_defineAux (pfile, keyword, buf, limit, FALSE);
 }
 
-/* This structure represents one parsed argument in a macro call.
-   `raw' points to the argument text as written (`raw_length' is its length).
-   `expanded' points to the argument's macro-expansion
-   (its length is `expand_length').
-   `stringified_length' is the length the argument would have
-   if stringified.
-   `use_count' is the number of times this macro arg is substituted
-   into the macro.  If the actual use count exceeds 10,
-   the value stored is 10.  */
+/*
+** This structure represents one parsed argument in a macro call.
+** `raw' points to the argument text as written (`raw_length' is its length).
+** `expanded' points to the argument's macro-expansion
+** (its length is `expand_length').
+**  `stringified_length' is the length the argument would have
+** if stringified.
+**  `use_count' is the number of times this macro arg is substituted
+** into the macro.  If the actual use count exceeds 10,
+** the value stored is 10.  
+*/
 
 /* raw and expanded are relative to ARG_BASE */
 /*@notfunction@*/
@@ -2312,15 +2957,17 @@ struct argdata {
   int use_count;
 };
 
-/* Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.
-   If BUFFER != NULL, then use the LENGTH characters in BUFFER
-   as the new input buffer.
-   Return the new buffer, or NULL on failure.  */
+/* 
+** Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.
+**   If BUFFER != NULL, then use the LENGTH characters in BUFFER
+**   as the new input buffer.
+**   Return the new buffer, or NULL on failure.  
+*/
 
 /*@null@*/ /*@exposed@*/ cppBuffer *
 cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)
 {
-  cppBuffer *buf = cppReader_getBuffer (pfile);
+  cppBuffer *buf = cppReader_getBufferSafe (pfile);
 
   if (buf == pfile->buffer_stack)
     {
@@ -2338,6 +2985,7 @@ cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)
 
   buf--;
   memset ((char *) buf, 0, sizeof (*buf));
+  DPRINTF (("Pushing buffer: %s", cstring_copyLength (buffer, length)));
   CPPBUFFER (pfile) = buf;
 
   buf->if_stack = pfile->if_stack;
@@ -2369,8 +3017,10 @@ cppReader_popBuffer (cppReader *pfile)
   return ++CPPBUFFER (pfile);
 }
 
-/* Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.
-   Pop the buffer when done.  */
+/*
+** Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.
+** Pop the buffer when done.  
+*/
 
 void
 cppReader_scanBuffer (cppReader *pfile)
@@ -2380,7 +3030,7 @@ cppReader_scanBuffer (cppReader *pfile)
     {
       enum cpp_token token;
       
-      token = cppGetToken (pfile);
+      token = cpplib_getToken (pfile);
 
       if (token == CPP_EOF) /* Should not happen ...  */
        {
@@ -2401,7 +3051,7 @@ cppReader_scanBuffer (cppReader *pfile)
  *
  * The input is copied before it is scanned, so it is safe to pass
  * it something from the token_buffer that will get overwritten
- * (because it follows cppReader_getWritten).  This is used by do_include.
+ * (because it follows cpplib_getWritten).  This is used by do_include.
  */
 
 static void
@@ -2411,8 +3061,14 @@ cpp_expand_to_buffer (cppReader *pfile, char *buf, size_t length)
   char *limit = buf + length;
   char *buf1, *p1, *p2;
 
+  DPRINTF (("Expand to buffer: %s", cstring_copyLength (buf, length)));
+
+  /* evans - 2001-08-26
+  ** length is unsigned - this doesn't make sense
   if (length < 0)
     abort ();
+  **
+  */
 
   /* Set up the input on the input stack.  */
 
@@ -2480,8 +3136,8 @@ update_position (cppBuffer *pbuf)
 }
 
 void
-cppBuffer_lineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,
-                        /*@null@*/ /*@out@*/ int *colp)
+cppBuffer_getLineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,
+                           /*@null@*/ /*@out@*/ int *colp)
 {
   int dummy;
 
@@ -2591,7 +3247,7 @@ output_line_command (cppReader *pfile, bool conditional,
 
     if (line > pfile->lineno && line < pfile->lineno + 8)
       {
-       cppReader_reserve (pfile, 20);
+       cpplib_reserve (pfile, 20);
        while (line > pfile->lineno)
          {
            cppReader_putCharQ (pfile, '\n');
@@ -2602,8 +3258,7 @@ output_line_command (cppReader *pfile, bool conditional,
       }
   }
 
-  cppReader_reserve (pfile,
-                    size_fromInt (4 * cstring_length (ip->nominal_fname) + 50));
+  cpplib_reserve (pfile, 4 * cstring_length (ip->nominal_fname) + 50);
 
   {
 #ifdef OUTPUT_LINE_COMMANDS
@@ -2614,8 +3269,8 @@ output_line_command (cppReader *pfile, bool conditional,
     cppReader_putStrN (pfile, sharp_line, sizeof(sharp_line)-1);
   }
 
-  sprintf (cppReader_getPWritten (pfile), "%d ", line);
-  cppReader_adjustWritten (pfile, strlen (cppReader_getPWritten (pfile)));
+  sprintf (cpplib_getPWritten (pfile), "%d ", line);
+  cppReader_adjustWritten (pfile, strlen (cpplib_getPWritten (pfile)));
 
   quote_string (pfile, cstring_toCharsSafe (ip->nominal_fname));
 
@@ -2662,7 +3317,7 @@ macarg (cppReader *pfile, int rest_args)
 
   for (;;)
     {
-      token = cppGetToken (pfile);
+      token = cpplib_getToken (pfile);
 
       switch (token)
        {
@@ -2817,7 +3472,15 @@ special_symbol (hashNode hp, cppReader *pfile)
            string = "";
          }
 
-       cppReader_reserve (pfile, 3 + 4 * strlen (string));
+       cpplib_reserve (pfile, 3 + 4 * strlen (string));
+       quote_string (pfile, string);
+       return;
+      }
+    case T_FUNC: /* added in ISO C99 */
+      {
+       /* We don't know the actual name of the function, but it doesn't matter */
+       char *string = "** function-name **";
+       cpplib_reserve (pfile, 3 + 4 * strlen (string));
        quote_string (pfile, string);
        return;
       }
@@ -2839,7 +3502,7 @@ special_symbol (hashNode hp, cppReader *pfile)
       break;
 
     case T_VERSION:
-      buf = message ("\"%s\"", cstring_makeLiteralTemp (CPP_VERSION));
+      buf = cstring_makeLiteral ("\"--- cpp version---\"");
       break;
 
 #ifndef NO_BUILTIN_SIZE_TYPE
@@ -2913,7 +3576,7 @@ special_symbol (hashNode hp, cppReader *pfile)
     case T_SPEC_DEFINED:
       buf = cstring_makeLiteral (" 0 ");     /* Assume symbol is not defined */
       ip = cppReader_getBuffer (pfile);
-
+      llassert (ip != NULL);
       llassert (ip->cur != NULL);
       SKIP_WHITE_SPACE (ip->cur);
 
@@ -2926,10 +3589,10 @@ special_symbol (hashNode hp, cppReader *pfile)
 
       if (!is_idstart[(int) *ip->cur])
        goto oops;
-      if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
+      if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '\"'))
        goto oops;
 
-      if ((hp = cppReader_lookup (ip->cur, -1, -1)) != 0)
+      if ((hp = cpphash_lookup (ip->cur, -1, -1)) != 0)
        {
          cstring_free (buf);
          buf = cstring_makeLiteral (" 1 ");
@@ -2961,9 +3624,9 @@ special_symbol (hashNode hp, cppReader *pfile)
       llfatalerror (message ("Pre-processing error: invalid special hash type"));
     }
 
-  len = size_fromInt (cstring_length (buf));
+  len = cstring_length (buf);
 
-  cppReader_reserve (pfile, len + 1);
+  cpplib_reserve (pfile, len + 1);
   cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len);
   cppReader_nullTerminateQ (pfile);
 
@@ -2980,7 +3643,7 @@ dump_special_to_buffer (cppReader *pfile, char *macro_name)
   static char define_directive[] = "#define ";
   size_t macro_name_length = strlen (macro_name);
   output_line_command (pfile, 0, same_file);
-  cppReader_reserve (pfile, sizeof(define_directive) + macro_name_length);
+  cpplib_reserve (pfile, sizeof(define_directive) + macro_name_length);
   cppReader_putStrN (pfile, define_directive, sizeof(define_directive)-1);
   cppReader_putStrN (pfile, macro_name, macro_name_length);
   cppReader_putCharQ (pfile, ' ');
@@ -2991,10 +3654,10 @@ dump_special_to_buffer (cppReader *pfile, char *macro_name)
 /* Initialize the built-in macros.  */
 
 static void
-cppReader_installBuiltin (/*@observer@*/ char *name, ctype ctyp,
-                         int len, enum node_type type,
-                         int ivalue, /*@null@*/ /*@only@*/ char *value,
-                         int hash)
+cpplib_installBuiltin (/*@observer@*/ char *name, ctype ctyp,
+                      int len, enum node_type type,
+                      int ivalue, /*@null@*/ /*@only@*/ char *value,
+                      int hash)
 {
   cstring sname = cstring_fromCharsNew (name);
 
@@ -3024,67 +3687,61 @@ cppReader_installBuiltin (/*@observer@*/ char *name, ctype ctyp,
       ;
     }
 
-  (void) cppReader_install (name, len, type, ivalue, value, hash);
+  (void) cpphash_install (name, len, type, ivalue, value, hash);
   cstring_free (sname);
 }
 
 static void
-cppReader_installBuiltinType (/*@observer@*/ char *name, ctype ctyp,
-                             int len, enum node_type type,
-                             int ivalue,
-                             /*@only@*/ /*@null@*/ char *value, int hash)
+cpplib_installBuiltinType (/*@observer@*/ char *name, ctype ctyp,
+                          int len, enum node_type type,
+                          int ivalue,
+                          /*@only@*/ /*@null@*/ char *value, int hash)
 {
   cstring sname = cstring_fromChars (name);
-  /* evs 2000 07 10 - removed a memory leak, detected by lclint */
+  /* evs 2000 07 10 - removed a memory leak, detected by splint */
 
   llassert (usymtab_inGlobalScope ());
 
   if (!usymtab_existsTypeEither (sname))
     {
       uentry ue = uentry_makeDatatype (sname, ctyp,
-                                      NO, NO,
+                                      NO, qual_createConcrete (),
                                       fileloc_createBuiltin ());
       llassert (!usymtab_existsEither (sname));
       usymtab_addGlobalEntry (ue);
     }
 
-  (void) cppReader_install (name, len, type, ivalue, value, hash);
+  (void) cpphash_install (name, len, type, ivalue, value, hash);
 }
 
 static void
 initialize_builtins (cppReader *pfile)
 {
-  cppReader_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);
-  cppReader_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);
-  cppReader_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);
-  cppReader_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);
-  cppReader_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);
-  cppReader_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);
+  cpplib_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);
+  cpplib_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);
+  cpplib_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);
+  cpplib_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);
+  cpplib_installBuiltin ("__func__", ctype_string, -1, T_FUNC, 0, NULL, -1);
+  cpplib_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);
+  cpplib_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);
 #ifndef NO_BUILTIN_SIZE_TYPE
-  cppReader_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);
+  cpplib_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);
 #endif
 #ifndef NO_BUILTIN_PTRDIFF_TYPE
-  cppReader_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);
+  cpplib_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);
 #endif
-  cppReader_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1);
-  cppReader_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);
-  cppReader_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);
-  cppReader_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1);
-
-  /*
-  ** No, don't define __STDC__
-  **
+  cpplib_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1);
+  cpplib_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);
+  cpplib_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);
+  cpplib_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1);
 
   if (!cppReader_isTraditional (pfile))
     {
-      cppReader_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
+      cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
     }
 
-  **
-  */
-
 # ifdef WIN32
-    cppReader_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
+    cpplib_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
 # endif
 
   /*
@@ -3092,10 +3749,125 @@ initialize_builtins (cppReader *pfile)
   ** so that it is present only when truly compiling with GNU C.
   */
 
-  /*  cppReader_install ("__GNUC__", -1, T_CONST, 2, 0, -1);  */
+  /*  cpplib_install ("__GNUC__", -1, T_CONST, 2, 0, -1);  */
+
+  cpplib_installBuiltin ("S_SPLINT_S", ctype_int, -1, T_CONST, 2, NULL, -1);
+  cpplib_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1);
+
+  /*drl 1/9/2001/ try to define the right symbol for the architecture
+    We use autoconf to determine the target cpu 
+   */
+# ifndef S_SPLINT_S
+  cpplib_installBuiltin ("__" TARGET_CPU, ctype_int, -1, T_CONST, 2, NULL, -1);
+# endif
+
+  /*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__");
@@ -3168,7 +3940,7 @@ unsafe_chars (char c1, char c2)
    an argument list follows; arguments come from the input stack.  */
 
 static void
-macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
+cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
 {
   int nargs;
   DEFINITION *defn = hp->value.defn;
@@ -3176,16 +3948,18 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
   char *oxbuf = NULL;
   int start_line;
   int start_column;
+  int end_line;
+  int end_column;
   size_t xbuf_len;
-  size_t old_written = cppReader_getWritten (pfile);
+  size_t old_written = cpplib_getWritten (pfile);
   int rest_args;
   int rest_zero = 0;
   int i;
   struct argdata *args = NULL;
 
   pfile->output_escapes++;
-
-  cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
+  cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
+  DPRINTF (("Expand macro: %d:%d", start_line, start_column));
 
   nargs = defn->nargs;
 
@@ -3230,9 +4004,9 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
                  rest_args = 1;
                }
 
-             args[i].raw = size_toLong (cppReader_getWritten (pfile));
+             args[i].raw = size_toLong (cpplib_getWritten (pfile));
              token = macarg (pfile, rest_args);
-             args[i].raw_length = cppReader_getWritten (pfile) - args[i].raw;
+             args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw);
              args[i].newlines = FALSE; /* FIXME */
            }
          else
@@ -3319,6 +4093,14 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
        }
     }
 
+  /*
+  ** If the agrument list was multiple lines, need to insert new lines to keep line
+  ** numbers accurate.
+  */
+
+  cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &end_line, &end_column);
+  DPRINTF (("Expand macro: %d:%d", end_line, end_column));
+  
   /* If macro wants zero args, we parsed the arglist for checking only.
      Read directly from the macro definition.  */
 
@@ -3368,7 +4150,7 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
                  int need_space = -1;
 
                  i = 0;
-                 arg->stringified = cppReader_getWritten (pfile);
+                 arg->stringified = cpplib_getWritten (pfile);
                  if (!cppReader_isTraditional (pfile))
                    cppReader_putChar (pfile, '\"'); /* insert beginning quote */
                  for (; i < arglen; i++)
@@ -3381,8 +4163,8 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
                             one space except within an string or char token.*/
                          if (is_space[(int) c])
                            {
-                             if (cppReader_getWritten (pfile) > arg->stringified
-                                 && (cppReader_getPWritten (pfile))[-1] == '@')
+                             if (cpplib_getWritten (pfile) > arg->stringified
+                                 && (cpplib_getPWritten (pfile))[-1] == '@')
                                {
                                  /* "@ " escape markers are removed */
                                  cppReader_adjustWritten (pfile, -1);
@@ -3431,8 +4213,8 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
                        cppReader_putChar (pfile, c);
                      else
                        {
-                         cppReader_reserve (pfile, 4);
-                         sprintf (cppReader_getPWritten (pfile), "\\%03o",
+                         cpplib_reserve (pfile, 4);
+                         sprintf (cpplib_getPWritten (pfile), "\\%03o",
                                   (unsigned int) c);
                          cppReader_adjustWritten (pfile, 4);
                        }
@@ -3440,16 +4222,15 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
                  if (!cppReader_isTraditional (pfile))
                    cppReader_putChar (pfile, '\"'); /* insert ending quote */
                  arg->stringified_length
-                   = size_toInt (cppReader_getWritten (pfile) - arg->stringified);
+                   = size_toInt (cpplib_getWritten (pfile) - arg->stringified);
                }
 
              xbuf_len += args[ap->argno].stringified_length;
            }
          else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
            {
-             /* Add 4 for two newline-space markers to prevent
-                token concatenation.  */
-             assertSet (args); /*@i534 shouldn't need this */
+             /* Add 4 for two newline-space markers to prevent token concatenation. */
+             assertSet (args); /* Splint shouldn't need this */
              xbuf_len += args[ap->argno].raw_length + 4;
            }
          else
@@ -3457,17 +4238,17 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
              /* We have an ordinary (expanded) occurrence of the arg.
                 So compute its expansion, if we have not already.  */
 
-             assertSet (args); /*@i534 shouldn't need this */
+             assertSet (args); /* shouldn't need this */
 
              if (args[ap->argno].expand_length < 0)
                {
-                 args[ap->argno].expanded = cppReader_getWritten (pfile);
+                 args[ap->argno].expanded = cpplib_getWritten (pfile);
                  cpp_expand_to_buffer (pfile,
                                        ARG_BASE + args[ap->argno].raw,
                                        size_fromInt (args[ap->argno].raw_length));
 
                  args[ap->argno].expand_length
-                   = size_toInt (cppReader_getWritten (pfile) - args[ap->argno].expanded);
+                   = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded);
                }
 
              /* Add 4 for two newline-space markers to prevent
@@ -3664,12 +4445,53 @@ macroexpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
 
   /* Now put the expansion on the input stack
      so our caller will commence reading from it.  */
+  DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
+  
+  if (end_line != start_line)
+    {
+      /* xbuf must have enough newlines */
+      int newlines = end_line - start_line;
+      int foundnewlines = 0;
+      char *xbufptr = xbuf;
+
+      while ((xbufptr = strchr (xbufptr, '\n')) != NULL && foundnewlines <= newlines)
+       {
+         foundnewlines++;
+         xbufptr++;
+
+         if (*xbufptr == '\0') 
+           {
+             break;
+           }
+       }
+         
+      if (foundnewlines < newlines)
+       {
+         cstring newbuf = cstring_copyLength (xbuf, xbuf_len);
+         
+         while (foundnewlines < newlines)
+           {
+             newbuf = cstring_appendChar (newbuf, '\n');
+             foundnewlines++;
+           }
+
+         sfree (oxbuf);
+         xbuf = cstring_toCharsSafe (newbuf);
+         xbuf_len = cstring_length (newbuf);
+         /*@-branchstate@*/ 
+       } /*@=branchstate@*/ 
+    }
+  
+  DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
+
   push_macro_expansion (pfile, xbuf, xbuf_len, hp);
-  cppReader_getBuffer (pfile)->has_escapes = 1;
+  DPRINTF (("After pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
+  cppReader_getBufferSafe (pfile)->has_escapes = 1;
 
   /* Pop the space we've used in the token_buffer for argument expansion.  */
   cppReader_setWritten (pfile, old_written);
-
+  DPRINTF (("Done set written"));
+  
   /* Recursive macro use sometimes works traditionally.
      #define foo(x,y) bar (x (y,0), y)
      foo (foo, baz)  */
@@ -3719,12 +4541,14 @@ push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
          || xbuf[2] == '\"'))
   {
     llassert (mbuf->cur != NULL);
+    DPRINTF (("Eating: %c", xbuf[2]));
     mbuf->cur += 2;
   }
+  
 }
 
 
-/* Like cppGetToken, except that it does not read past end-of-line.
+/* Like cpplib_getToken, except that it does not read past end-of-line.
    Also, horizontal space is skipped, and macros are popped.  */
 
 static enum cpp_token
@@ -3732,7 +4556,7 @@ get_directive_token (cppReader *pfile)
 {
   for (;;)
     {
-      size_t old_written = cppReader_getWritten (pfile);
+      size_t old_written = cpplib_getWritten (pfile);
       enum cpp_token token;
       cppSkipHspace (pfile);
       if (cppReader_peekC (pfile) == '\n')
@@ -3740,7 +4564,7 @@ get_directive_token (cppReader *pfile)
          return CPP_VSPACE;
        }
 
-      token = cppGetToken (pfile);
+      token = cpplib_getToken (pfile);
 
       switch (token)
        {
@@ -3763,24 +4587,10 @@ get_directive_token (cppReader *pfile)
    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.  */
 
-# ifdef WIN32
-static void replace_unixdir_with_windir(char *filename)
-{
-  int i=0;
-  
-  while(filename[i] != '\0')
-    {
-      if(filename[i] == '/')
-       filename[i] = '\\';
-      i++;
-    }
-}
-# endif
-
 static int
 do_include (cppReader *pfile, struct directive *keyword,
            /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
@@ -3794,9 +4604,8 @@ do_include (cppReader *pfile, struct directive *keyword,
   struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
   struct file_name_list dsp[1];        /* First in chain, if #include "..." */
   struct file_name_list *searchptr = NULL;
-  size_t old_written = cppReader_getWritten (pfile);
-
-  int flen;
+  size_t old_written = cpplib_getWritten (pfile);
+  size_t flen;
 
   int f;                       /* file number */
   int angle_brackets = 0;      /* 0 for "...", 1 for <...> */
@@ -3810,7 +4619,7 @@ do_include (cppReader *pfile, struct directive *keyword,
     {
       /* FIXME - check no trailing garbage */
       fbeg = pfile->token_buffer + old_written + 1;
-      fend = cppReader_getPWritten (pfile) - 1;
+      fend = cpplib_getPWritten (pfile) - 1;
       if (fbeg[-1] == '<')
        {
          angle_brackets = 1;
@@ -3864,8 +4673,8 @@ do_include (cppReader *pfile, struct directive *keyword,
                      /*@=onlytrans@*/
                      nam[n] = save;
 
-                     if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len)
-                       pfile->max_include_len = n + INCLUDE_LEN_FUDGE;
+                     if (n + INCLUDE_LEN_FUDGE > size_toInt (pfile->max_include_len))
+                       pfile->max_include_len = size_fromInt (n + INCLUDE_LEN_FUDGE);
                    }
                  else
                    {
@@ -3897,7 +4706,7 @@ do_include (cppReader *pfile, struct directive *keyword,
       if (CPPOPTIONS (pfile)->first_bracket_include)
        search_start = CPPOPTIONS (pfile)->first_bracket_include;
       fbeg = pfile->token_buffer + old_written;
-      fend = cppReader_getPWritten (pfile);
+      fend = cpplib_getPWritten (pfile);
     }
 #endif
   else
@@ -3959,10 +4768,10 @@ do_include (cppReader *pfile, struct directive *keyword,
            }
        }
     }
-
+  
   cppReader_setWritten (pfile, old_written);
 
-  flen = fend - fbeg;
+  flen = size_fromInt (fend - fbeg);
 
   DPRINTF (("fbeg: %s", fbeg));
 
@@ -4036,11 +4845,11 @@ do_include (cppReader *pfile, struct directive *keyword,
          DPRINTF (("fname: %s", fname));
          
          /* Win32 directory fix from Kay Buschner. */
-#ifdef WIN32
+#if defined (WIN32) || defined (OS2)
          /* Fix all unixdir slashes to win dir slashes */
          if (searchptr->fname && (searchptr->fname[0] != 0)) 
            {
-             replace_unixdir_with_windir(fname);
+             cstring_replaceAll (fname, '/', '\\');
            }
 #endif /* WIN32 */
 
@@ -4076,7 +4885,7 @@ do_include (cppReader *pfile, struct directive *keyword,
          
          if (f == IMPORT_FOUND)
            {
-             return 0;                 /* Already included this file */
+             return 0; /* Already included this file */
            }
 #ifdef EACCES
          else if (f == IMPORT_NOT_FOUND && errno == EACCES)
@@ -4187,7 +4996,7 @@ redundant_include_p (cppReader *pfile, cstring name)
     {
       if (cstring_equal (name, l->fname)
          && (l->control_macro != NULL)
-         && (cppReader_lookup (l->control_macro, -1, -1) != NULL))
+         && (cpphash_lookup (l->control_macro, -1, -1) != NULL))
        {
          return TRUE;
        }
@@ -4216,21 +5025,22 @@ is_system_include (cppReader *pfile, cstring filename)
        searchptr != NULL;
        searchptr = searchptr->next)
     {
-      if (!cstring_isEmpty (searchptr->fname)) {
-       cstring sys_dir = searchptr->fname;
-       int length = cstring_length (sys_dir);
-
-       if (cstring_equalLen (sys_dir, filename, length)
-           && osd_isConnectChar (cstring_getChar (filename, length)))
-         {
-           if (searchptr->c_system_include_path)
-             return 2;
-           else
-             return 1;
-         }
-      }
+      if (!cstring_isEmpty (searchptr->fname)) 
+       {
+         cstring sys_dir = searchptr->fname;
+         size_t length = cstring_length (sys_dir);
+         
+         if (cstring_equalLen (sys_dir, filename, length)
+             && osd_isConnectChar (cstring_getChar (filename, length)))
+           {
+             if (searchptr->c_system_include_path)
+               return 2;
+             else
+               return 1;
+           }
+       }
     }
-
+  
   return 0;
 }
 
@@ -4297,10 +5107,11 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
 {
   cppBuffer *ip = cppReader_getBuffer (pfile);
   int new_lineno;
-  size_t old_written = cppReader_getWritten (pfile);
+  size_t old_written = cpplib_getWritten (pfile);
   enum file_change_code file_change = same_file;
   enum cpp_token token;
 
+  llassert (ip != NULL);
   token = get_directive_token (pfile);
 
   if (token != CPP_NUMBER
@@ -4333,11 +5144,11 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
     hashNode *hash_bucket;
     char *p;
     size_t num_start;
-    int fname_length;
+    size_t fname_length;
 
     /* Turn the file name, which is a character string literal,
        into a null-terminated string.  Do this in place.  */
-    end_name = convert_string (pfile, fname, fname, cppReader_getPWritten (pfile), 1);
+    end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1);
     if (end_name == NULL)
       {
        cppReader_errorLit (pfile,
@@ -4345,8 +5156,8 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
        goto bad_line_directive;
       }
 
-    fname_length = end_name - fname;
-    num_start = cppReader_getWritten (pfile);
+    fname_length = size_fromInt (end_name - fname);
+    num_start = cpplib_getWritten (pfile);
 
     token = get_directive_token (pfile);
     if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
@@ -4386,16 +5197,22 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
     }
 
     hash_bucket =
-      &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
+      &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)];
+
     for (hp = *hash_bucket; hp != NULL; hp = hp->next)
       {
-       if (hp->length == fname_length &&
-           strncmp (hp->value.cpval, fname, size_fromInt (fname_length)) == 0) {
-         ip->nominal_fname = cstring_fromChars (hp->value.cpval);
-         break;
-       }
+       if (hp->length == fname_length)
+         {
+           llassert (hp->value.cpval != NULL);
+           
+           if (strncmp (hp->value.cpval, fname, fname_length) == 0) 
+             {
+               ip->nominal_fname = cstring_fromChars (hp->value.cpval);
+               break;
+             }
+         }
       }
-
+    
     if (hp == 0) {
       /* Didn't find it; cons up a new one.  */
       hp = (hashNode) dmalloc (sizeof (*hp));
@@ -4410,7 +5227,7 @@ do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
 
       hp->length = fname_length;
       hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
-      memcpy (hp->value.cpval, fname, size_fromInt (fname_length));
+      memcpy (hp->value.cpval, fname, fname_length);
       hp->value.cpval[fname_length] = '\0';
       ip->nominal_fname = cstring_fromChars (hp->value.cpval);
     }
@@ -4444,7 +5261,7 @@ static int
 do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
 {
 
-  int sym_length;
+  size_t sym_length;
   hashNode hp;
   char *orig_buf = buf;
 
@@ -4452,7 +5269,7 @@ do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
 
   sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
 
-  while ((hp = cppReader_lookup (buf, sym_length, -1)) != NULL)
+  while ((hp = cpphash_lookup (buf, size_toInt (sym_length), -1)) != NULL)
     {
       /* If we are generating additional info for debugging (with -g) we
         need to pass through all effective #undef commands.  */
@@ -4495,7 +5312,7 @@ static int
 do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
          char *buf, char *limit)
 {
-  int length = limit - buf;
+  size_t length = size_fromInt (limit - buf);
   cstring copy = cstring_copyLength (buf, length);
   cstring adv = cstring_advanceWhiteSpace (copy);
 
@@ -4514,7 +5331,7 @@ static int
 do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
            char *buf, char *limit)
 {
-  int length = limit - buf;
+  size_t length = size_fromInt (limit - buf);
   cstring copy = cstring_copyLength (buf, length);
   cstring adv = cstring_advanceWhiteSpace (copy);
   cppReader_warning (pfile, message ("#warning %s", adv));
@@ -4530,11 +5347,12 @@ do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,
          /*@unused@*/ char *buf, /*@unused@*/ char *limit)
 {
   /* Allow #ident in system headers, since that's not user's fault.  */
-  if (cppReader_isPedantic (pfile) && !cppReader_getBuffer (pfile)->system_header_p)
+  if (cppReader_isPedantic (pfile) 
+      && !cppReader_getBufferSafe (pfile)->system_header_p)
     cppReader_pedwarnLit (pfile,
                    cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
 
-  /* Leave rest of line to be read by later calls to cppGetToken.  */
+  /* Leave rest of line to be read by later calls to cpplib_getToken.  */
 
   return 0;
 }
@@ -4556,14 +5374,14 @@ do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
        been included yet.  */
     struct file_name_list *ptr;
     char *p = buf + 14, *fname, *inc_fname;
-    int fname_len;
+    size_t fname_len;
     SKIP_WHITE_SPACE (p);
     if (*p == '\n' || *p != '\"')
       return 0;
 
     fname = p + 1;
     p = (char *) strchr (fname, '\"');
-    fname_len = p != NULL ? p - fname : mstring_length (fname);
+    fname_len = p != NULL ? size_fromInt (p - fname) : mstring_length (fname);
 
     for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
       {
@@ -4572,7 +5390,7 @@ do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
          ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
 
        if ((inc_fname != NULL)
-           && (strncmp (inc_fname, fname, size_fromInt (fname_len)) == 0))
+           && (strncmp (inc_fname, fname, fname_len) == 0))
          {
            cpp_setLocation (pfile);
 
@@ -4603,7 +5421,9 @@ static int
 do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
        char *buf, char *limit)
 {
-  HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
+  HOST_WIDE_INT value;
+  DPRINTF (("Do if: %s", buf));
+  value = eval_if_expression (pfile, buf, limit - buf);
   conditional_skip (pfile, value == 0, T_IF, NULL);
   return 0;
 }
@@ -4616,7 +5436,7 @@ do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
 static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
                    char *buf, char *limit)
 {
-  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
+  if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
     {
       cppReader_errorLit (pfile,
                    cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
@@ -4632,9 +5452,9 @@ static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
                        cstring_makeLiteralTemp ("`#elif' after `#else'"));
 
          if (pfile->if_stack->fname != NULL
-             && cppReader_getBuffer (pfile)->fname != NULL
+             && cppReader_getBufferSafe (pfile)->fname != NULL
              && !cstring_equal (pfile->if_stack->fname,
-                                cppReader_getBuffer (pfile)->nominal_fname))
+                                cppReader_getBufferSafe (pfile)->nominal_fname))
            fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
          fprintf (stderr, ")\n");
        }
@@ -4672,17 +5492,18 @@ eval_if_expression (cppReader *pfile,
 {
   hashNode save_defined;
   HOST_WIDE_INT value;
-  size_t old_written = cppReader_getWritten (pfile);
+  size_t old_written = cpplib_getWritten (pfile);
 
-  save_defined = cppReader_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
+  DPRINTF (("Saving defined..."));
+  save_defined = cpphash_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
   pfile->pcp_inside_if = 1;
 
   value = cppReader_parseExpression (pfile);
   pfile->pcp_inside_if = 0;
 
   /* Clean up special symbol */
+  DPRINTF (("Removing defined..."));
   cppReader_deleteMacro (save_defined);
-
   cppReader_setWritten (pfile, old_written); /* Pop */
 
   return value;
@@ -4699,13 +5520,13 @@ do_xifdef (cppReader *pfile, struct directive *keyword,
           /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
 {
   int skip;
-  cppBuffer *ip = cppReader_getBuffer (pfile);
+  cppBuffer *ip = cppReader_getBufferSafe (pfile);
   char *ident;
-  int ident_length;
+  size_t ident_length;
   enum cpp_token token;
   int start_of_file = 0;
   char *control_macro = 0;
-  size_t old_written = cppReader_getWritten (pfile);
+  size_t old_written = cpplib_getWritten (pfile);
 
   DPRINTF (("do xifdef: %d",
            keyword->type == T_IFNDEF));
@@ -4721,7 +5542,9 @@ do_xifdef (cppReader *pfile, struct directive *keyword,
   pfile->no_macro_expand--;
 
   ident = pfile->token_buffer + old_written;
-  ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);
+  DPRINTF (("Ident: %s", ident));
+
+  ident_length = cpplib_getWritten (pfile) - old_written;
   cppReader_setWritten (pfile, old_written); /* Pop */
 
   if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
@@ -4730,25 +5553,22 @@ do_xifdef (cppReader *pfile, struct directive *keyword,
       if (! cppReader_isTraditional (pfile))
        {
          cppReader_pedwarn (pfile,
-                      message ("`#%s' with no argument", keyword->name));
+                            message ("`#%s' with no argument", keyword->name));
        }
     }
   else if (token == CPP_NAME)
     {
-      hashNode hp = cppReader_lookup (ident, ident_length, -1);
-      skip = (keyword->type == T_IFDEF) 
-       ? (hp == NULL) : (hp != NULL);
+      hashNode hp = cpphash_lookup (ident, size_toInt (ident_length), -1);
 
-      DPRINTF (("hp null: %d / %d / %d",
-               (hp == NULL),
-               (keyword->type == T_IFNDEF),
-               skip));
-               
+      skip = (keyword->type == T_IFDEF) ? (hp == NULL) : (hp != NULL);
+      
+      DPRINTF (("hp null: %d / %d / %d", hp == NULL, keyword->type == T_IFNDEF, skip));
+      
       if (start_of_file && !skip)
        {
          DPRINTF (("Not skipping!"));
-         control_macro = (char *) dmalloc (size_fromInt (ident_length + 1));
-         memcpy (control_macro, ident, size_fromInt (ident_length + 1));
+         control_macro = (char *) dmalloc (ident_length + 1);
+         memcpy (control_macro, ident, ident_length + 1);
        }
     }
   else
@@ -4792,7 +5612,7 @@ conditional_skip (cppReader *pfile, int skip,
 {
   cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
 
-  temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
+  temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
   temp->next = pfile->if_stack;
   temp->control_macro = control_macro;
   temp->lineno = 0;
@@ -4841,7 +5661,7 @@ skip_if_group (cppReader *pfile, int any)
 beg_of_line:
   if (CPPOPTIONS (pfile)->output_conditionals)
     {
-      cppBuffer *pbuf = cppReader_getBuffer (pfile);
+      cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
       char *start_line;
 
       llassert (pbuf->buf != NULL);
@@ -4860,11 +5680,11 @@ beg_of_line:
   c  = cppReader_getC (pfile);
   if (c == '#')
     {
-      size_t old_written = cppReader_getWritten (pfile);
+      size_t old_written = cpplib_getWritten (pfile);
       cppSkipHspace (pfile);
 
       parse_name (pfile, cppReader_getC (pfile));
-      ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);
+      ident_length = size_toInt (cpplib_getWritten (pfile) - old_written);
       ident = pfile->token_buffer + old_written;
       pfile->limit = ident;
 
@@ -4872,7 +5692,7 @@ beg_of_line:
        {
          cppIfStackFrame *temp;
          if (ident_length == kt->length
-             && cstring_equalPrefix (kt->name, ident))
+             && cstring_equalPrefix (kt->name, cstring_fromChars (ident)))
            {
              /* If we are asked to return on next directive, do so now.  */
              if (any)
@@ -4887,7 +5707,7 @@ beg_of_line:
                case T_IFNDEF:
                  temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
                  temp->next = pfile->if_stack;
-                 temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
+                 temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
                  temp->type = kt->type;
                  temp->lineno = 0;
                  temp->if_succeeded = 0;
@@ -4902,7 +5722,7 @@ beg_of_line:
                                   cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
                  /*@fallthrough@*/
                case T_ELIF:
-                 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
+                 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
                    {
                      cppReader_error (pfile,
                                 message ("Preprocessor command #%s is not within a conditional", kt->name));
@@ -4938,6 +5758,11 @@ beg_of_line:
                  /*@switchbreak@*/ break;
                default: ;
                  /*@-branchstate@*/ 
+#if defined (OS2) && defined (__IBMC__)
+      /* Dummy code to eleminate optimization problems with icc */
+      c = 0;
+# endif
+
                }
              /*@=branchstate@*/
              break;
@@ -4971,8 +5796,8 @@ beg_of_line:
       case '\"':
       case '\'':
        cppReader_forward (pfile, -1);
-       old = cppReader_getWritten (pfile);
-       (void) cppGetToken (pfile);
+       old = cpplib_getWritten (pfile);
+       (void) cpplib_getToken (pfile);
        cppReader_setWritten (pfile, old);
        /*@switchbreak@*/ break;
       case '\\':
@@ -5018,7 +5843,7 @@ do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
 
   cppReader_skipRestOfLine (pfile);
 
-  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) {
+  if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) {
     cppReader_errorLit (pfile,
                  cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
     return 0;
@@ -5068,7 +5893,7 @@ do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
 
   cppReader_skipRestOfLine (pfile);
 
-  if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
+  if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
     {
       cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
     }
@@ -5113,7 +5938,7 @@ do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
 
              for ( ; ifile != NULL; ifile = ifile->next)
                {
-                 if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname))
+                 if (cstring_equal (ifile->fname, cppReader_getBufferSafe (pfile)->fname))
                    {
                      ifile->control_macro = temp->control_macro;
                      break;
@@ -5151,22 +5976,35 @@ validate_else (cppReader *pfile, cstring directive)
 */
 
 enum cpp_token
-cppGetToken (cppReader *pfile)
+cpplib_getToken (cppReader *pfile)
+{
+  return cpplib_getTokenAux (pfile, FALSE);
+}
+
+enum cpp_token
+cpplib_getTokenForceExpand (cppReader *pfile)
+{
+  return cpplib_getTokenAux (pfile, TRUE);
+}
+
+enum cpp_token
+cpplib_getTokenAux (cppReader *pfile, bool forceExpand)
 {
   int c, c2, c3;
   size_t old_written = 0;
   int start_line, start_column;
   enum cpp_token token;
   struct cppOptions *opts = CPPOPTIONS (pfile);
-  cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur;
+  cppReader_getBufferSafe (pfile)->prev = cppReader_getBufferSafe (pfile)->cur;
 
 get_next:
   c = cppReader_getC (pfile);
+  DPRINTF (("Get next token: %c", c));
 
   if (c == EOF)
     {
     handle_eof:
-      if (cppReader_getBuffer (pfile)->seen_eof)
+      if (cppReader_getBufferSafe (pfile)->seen_eof)
        {
          cppBuffer *buf = cppReader_popBuffer (pfile);
 
@@ -5181,10 +6019,10 @@ get_next:
        }
       else
        {
-         cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
-         cppReader_getBuffer (pfile)->seen_eof = 1;
+         cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
+         cppReader_getBufferSafe (pfile)->seen_eof = 1;
 
-         if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)
+         if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname)
              && next_buf != cppReader_nullBuffer (pfile))
            {
              /* We're about to return from an #include file.
@@ -5218,10 +6056,10 @@ get_next:
            }
 
          newlines = 0;
-         cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
+         cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
                                   &start_line, &start_column);
          c = skip_comment (pfile, &newlines);
-
+         DPRINTF (("c = %c", c));
          if (opts->put_out_comments && (c == '/' || c == EOF))
            {
              assertSet (&start_mark);
@@ -5256,7 +6094,7 @@ get_next:
            }
          else
            {
-             cppReader_reserve(pfile, 1);
+             cpplib_reserve(pfile, 1);
              cppReader_putCharQ (pfile, ' ');
              return CPP_HSPACE;
            }
@@ -5279,16 +6117,22 @@ get_next:
        case '\'':
          /* A single quoted string is treated like a double -- some
             programs (e.g., troff) are perverse this way */
-         cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
-                                  &start_line, &start_column);
-         old_written = cppReader_getWritten (pfile);
+         cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
+                                     &start_line, &start_column);
+         old_written = cpplib_getWritten (pfile);
        string:
+         DPRINTF (("Reading string: %c", c));
          cppReader_putChar (pfile, c);
          while (TRUE)
            {
-             int cc = cppReader_getC (pfile);
-             if (cc == EOF)
+             /* evans-2003-06-07
+             ** Because of ISO8859-1 characters in string literals, we need a special test here.
+             */
+
+             if (cppReader_reachedEOF (pfile)) 
                {
+                 
+                 DPRINTF (("Matches EOF!"));
                  if (cppBuffer_isMacro (CPPBUFFER (pfile)))
                    {
                      /* try harder: this string crosses a macro expansion
@@ -5296,19 +6140,20 @@ get_next:
                         Otherwise, only -D can make a macro with an unmatched
                         quote.  */
                      cppBuffer *next_buf
-                       = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
-                     (*cppReader_getBuffer (pfile)->cleanup)
-                       (cppReader_getBuffer (pfile), pfile);
+                       = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
+                     (*cppReader_getBufferSafe (pfile)->cleanup)
+                       (cppReader_getBufferSafe (pfile), pfile);
                      CPPBUFFER (pfile) = next_buf;
                      continue;
                    }
+                 
                  if (!cppReader_isTraditional (pfile))
                    {
                      cpp_setLocation (pfile);
 
                      setLine (long_toInt (start_line));
                      setColumn (long_toInt (start_column));
-
+                     
                      if (pfile->multiline_string_line != long_toInt (start_line)
                          && pfile->multiline_string_line != 0)
                        {
@@ -5328,63 +6173,71 @@ get_next:
                             message ("Unterminated string or character constant"));
                        }
                    }
-                 /*@loopbreak@*/ break;
-               }
-             cppReader_putChar (pfile, cc);
-             switch (cc)
+                 /*@loopbreak@*/ break;                  
+               } 
+             else
                {
-               case '\n':
-                 /* Traditionally, end of line ends a string constant with
-                    no error.  So exit the loop and record the new line.  */
-                 if (cppReader_isTraditional (pfile))
-                   goto while2end;
-                 if (c == '\'')
-                   {
-                     goto while2end;
-                   }
-                 if (cppReader_isPedantic (pfile)
-                     && pfile->multiline_string_line == 0)
-                   {
-                     cppReader_pedwarnWithLine
-                       (pfile, long_toInt (start_line),
-                        long_toInt (start_column),
-                        cstring_makeLiteral ("String constant runs past end of line"));
-                   }
-                 if (pfile->multiline_string_line == 0)
-                   {
-                     pfile->multiline_string_line = start_line;
-                   }
-
-                 /*@switchbreak@*/ break;
-
-               case '\\':
-                 cc = cppReader_getC (pfile);
-                 if (cc == '\n')
-                   {
-                     /* Backslash newline is replaced by nothing at all.  */
-                     cppReader_adjustWritten (pfile, -1);
-                     pfile->lineno++;
-                   }
-                 else
+                 int cc = cppReader_getC (pfile); 
+                 DPRINTF (("cc: %c [%d] [%d]", cc, cc, EOF));
+                 DPRINTF (("putting char: %c", cc));
+                 cppReader_putChar (pfile, cc);
+                 switch (cc)
                    {
-                     /* ANSI stupidly requires that in \\ the second \
-                        is *not* prevented from combining with a newline.  */
-                     NEWLINE_FIX1(cc);
-                     if (cc != EOF)
-                       cppReader_putChar (pfile, cc);
+                   case '\n':
+                     /* Traditionally, end of line ends a string constant with
+                        no error.  So exit the loop and record the new line.  */
+                     if (cppReader_isTraditional (pfile))
+                       goto while2end;
+                     if (c == '\'')
+                       {
+                         goto while2end;
+                       }
+                     if (cppReader_isPedantic (pfile)
+                         && pfile->multiline_string_line == 0)
+                       {
+                         cppReader_pedwarnWithLine
+                           (pfile, long_toInt (start_line),
+                            long_toInt (start_column),
+                            cstring_makeLiteral ("String constant runs past end of line"));
+                       }
+                     if (pfile->multiline_string_line == 0)
+                       {
+                         pfile->multiline_string_line = start_line;
+                       }
+                     
+                     /*@switchbreak@*/ break;
+                     
+                   case '\\':
+                     cc = cppReader_getC (pfile);
+                     if (cc == '\n')
+                       {
+                         /* Backslash newline is replaced by nothing at all.  */
+                         pfile->lineno++; /* 2003-11-03: AMiller suggested adding this, but
+                                             its not clear why it is needed. */
+                         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;
 
@@ -5477,7 +6330,7 @@ get_next:
          if (c2 != c)
            goto randomchar;
          cppReader_forward (pfile, 1);
-         cppReader_reserve (pfile, 4);
+         cpplib_reserve (pfile, 4);
          cppReader_putChar (pfile, c);
          cppReader_putChar (pfile, c2);
          NEWLINE_FIX;
@@ -5489,9 +6342,11 @@ get_next:
          return CPP_OTHER;
 
        case '@':
-         if (cppReader_getBuffer (pfile)->has_escapes)
+         DPRINTF (("Macro @!"));
+         if (cppReader_getBufferSafe (pfile)->has_escapes)
            {
              c = cppReader_getC (pfile);
+             DPRINTF (("got c: %c", c));
              if (c == '-')
                {
                  if (pfile->output_escapes)
@@ -5501,7 +6356,7 @@ get_next:
                }
              else if (is_space [c])
                {
-                 cppReader_reserve (pfile, 2);
+                 cpplib_reserve (pfile, 2);
                  if (pfile->output_escapes)
                    cppReader_putCharQ (pfile, '@');
                  cppReader_putCharQ (pfile, c);
@@ -5523,7 +6378,7 @@ get_next:
          c2 = cppReader_peekC (pfile);
          if (isdigit(c2))
            {
-             cppReader_reserve(pfile, 2);
+             cpplib_reserve(pfile, 2);
              cppReader_putCharQ (pfile, '.');
              c = cppReader_getC (pfile);
              goto number;
@@ -5532,7 +6387,7 @@ get_next:
          /* FIXME - misses the case "..\\\n." */
          if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
            {
-             cppReader_reserve(pfile, 4);
+             cpplib_reserve(pfile, 4);
              cppReader_putCharQ (pfile, '.');
              cppReader_putCharQ (pfile, '.');
              cppReader_putCharQ (pfile, '.');
@@ -5545,10 +6400,20 @@ get_next:
        op2:
          token = CPP_OTHER;
          pfile->only_seen_white = 0;
-        op2any:
-         cppReader_reserve(pfile, 3);
+        op2any: /* jumped to for \ continuations */
+         cpplib_reserve(pfile, 3);
          cppReader_putCharQ (pfile, c);
-         cppReader_putCharQ (pfile, cppReader_getC (pfile));
+
+         /* evans 2003-08-24: This is a hack to fix line output for \
+            continuations.  Someday I really should get a decent pre-processor! 
+         */
+
+         if (c == '\\') {
+           (void) cppReader_getC (pfile); /* skip the newline to avoid extra lines */
+         } else {
+           cppReader_putCharQ (pfile, cppReader_getC (pfile)); 
+         }
+
          cppReader_nullTerminateQ (pfile);
          return token;
 
@@ -5569,7 +6434,7 @@ get_next:
          c2  = '.';
          for (;;)
            {
-             cppReader_reserve (pfile, 2);
+             cpplib_reserve (pfile, 2);
              cppReader_putCharQ (pfile, c);
              NEWLINE_FIX;
              c = cppReader_peekC (pfile);
@@ -5593,7 +6458,7 @@ get_next:
          if (opts->chill && cppReader_peekC (pfile) == '\'')
            {
              pfile->only_seen_white = 0;
-             cppReader_reserve (pfile, 2);
+             cpplib_reserve (pfile, 2);
              cppReader_putCharQ (pfile, c);
              cppReader_putCharQ (pfile, '\'');
              cppReader_forward (pfile, 1);
@@ -5615,7 +6480,7 @@ get_next:
                }
              if (c == '\'')
                {
-                 cppReader_reserve (pfile, 2);
+                 cpplib_reserve (pfile, 2);
                  cppReader_putCharQ (pfile, c);
                  cppReader_nullTerminateQ (pfile);
                  return CPP_STRING;
@@ -5643,35 +6508,42 @@ get_next:
           {
            hashNode hp;
            char *ident;
-           size_t before_name_written = cppReader_getWritten (pfile);
-           int ident_len;
+           size_t before_name_written = cpplib_getWritten (pfile);
+           size_t ident_len;
            parse_name (pfile, c);
            pfile->only_seen_white = 0;
+
            if (pfile->no_macro_expand)
              {
+               DPRINTF (("Not expanding: %s", pfile->token_buffer));
                return CPP_NAME;
              }
 
            ident = pfile->token_buffer + before_name_written;
-           ident_len = (cppReader_getPWritten (pfile)) - ident;
+           DPRINTF (("Ident: %s", ident));
 
-           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];
                      }
@@ -5682,36 +6554,50 @@ get_next:
                return CPP_NAME;
              }
 
-           /* If macro wants an arglist, verify that a '(' follows.
-              first skip all whitespace, copying it to the output
-              after the macro name.  Then, if there is no '(',
-              decide this is not a macro call and leave things that way.  */
-
+           /* 
+           ** If macro wants an arglist, verify that a '(' follows.
+           ** first skip all whitespace, copying it to the output
+           ** after the macro name.  Then, if there is no '(',
+           ** decide this is not a macro call and leave things that way.  
+           */
+           
            if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
              {
                struct parse_marker macro_mark;
                int is_macro_call;
 
+               DPRINTF (("Arglist macro!"));
+
+               /*
+               ** evans 2002-07-03: Moved this here (from below).
+               **   This bug caused necessary whitespace to be lost
+               **   when parsing parameterized macros without parameters.
+               */
+
+               parseSetMark (&macro_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 (&macro_mark, pfile);
+               /* parseSetMark (&macro_mark, pfile); */
 
                for (;;)
                  {
                    cppSkipHspace (pfile);
                    c = cppReader_peekC (pfile);
+                   DPRINTF (("c: %c", c));
                    is_macro_call = c == '(';
                    if (c != '\n')
                      /*@loopbreak@*/ break;
@@ -5727,9 +6613,11 @@ get_next:
 
                if (!is_macro_call)
                  {
+                   DPRINTF (("not macro call!"));
                    return CPP_NAME;
                  }
              }
+
            /* This is now known to be a macro call.  */
 
            /* it might not actually be a macro.  */
@@ -5740,17 +6628,20 @@ get_next:
 
                cppReader_setWritten (pfile, before_name_written);
                special_symbol (hp, pfile);
-               xbuf_len = cppReader_getWritten (pfile) - before_name_written;
+               xbuf_len = cpplib_getWritten (pfile) - before_name_written;
                xbuf = (char *) dmalloc (xbuf_len + 1);
                cppReader_setWritten (pfile, before_name_written);
-               memcpy (xbuf, cppReader_getPWritten (pfile), xbuf_len + 1);
+               memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1);
                push_macro_expansion (pfile, xbuf, xbuf_len, hp);
              }
            else
              {
-               /* Expand the macro, reading arguments as needed,
-                  and push the expansion on the input stack.  */
-                               macroexpand (pfile, hp);
+               /*
+               ** Expand the macro, reading arguments as needed,
+               ** and push the expansion on the input stack. 
+               */
+
+               cpplib_macroExpand (pfile, hp);
                cppReader_setWritten (pfile, before_name_written);
              }
 
@@ -5766,7 +6657,7 @@ get_next:
                && pfile->buffer->rlimit[-1] == ' ')
              {
                int c1 = pfile->buffer->rlimit[-3];
-               int cl2 = cppBufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
+               int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
 
                if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
                  pfile->buffer->rlimit -= 2;
@@ -5788,6 +6679,8 @@ get_next:
 
         case '\\':
          c2 = cppReader_peekC (pfile);
+         /* allow other stuff here if a flag is set? */
+         DPRINTF (("Got continuation!"));
          if (c2 != '\n')
            goto randomchar;
          token = CPP_HSPACE;
@@ -5847,7 +6740,7 @@ parse_name (cppReader *pfile, int c)
                          cstring_makeLiteralTemp ("`$' in identifier"));
        }
 
-      cppReader_reserve(pfile, 2); /* One more for final NUL.  */
+      cpplib_reserve(pfile, 2); /* One more for final NUL.  */
       cppReader_putCharQ (pfile, c);
       c = cppReader_getC (pfile);
 
@@ -5912,9 +6805,9 @@ static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
 
 struct file_name_map_list
 {
-  struct file_name_map_list *map_list_next;
-  cstring map_list_name;
-  struct file_name_map *map_list_map;
+  /*@only@*/ struct file_name_map_list *map_list_next;
+  /*@only@*/ cstring map_list_name;
+  /*@null@*/ struct file_name_map *map_list_map;
 };
 
 /* Read the file name map file for DIRNAME.  */
@@ -5949,7 +6842,7 @@ read_name_map (cppReader *pfile, cstring dirname)
 
   name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
 
-  f = fopen (cstring_toCharsSafe (name), "r");
+  f = fileTable_openReadFile (context_fileTable (), name);
   cstring_free (name);
 
   if (f == NULL)
@@ -6007,7 +6900,7 @@ read_name_map (cppReader *pfile, cstring dirname)
        }
 
       assertSet (map_list_ptr->map_list_map);
-      check (fclose (f) == 0);
+      check (fileTable_closeFile (context_fileTable (),f) == 0);
     }
 
   map_list_ptr->map_list_next = pfile->opts->map_list;
@@ -6102,7 +6995,7 @@ open_include_file (cppReader *pfile,
 
   if ((searchptr != NULL)
       && (cstring_isDefined (searchptr->fname))
-      && (cstring_length (searchptr->fname) == p - filename)
+      && (size_toInt (cstring_length (searchptr->fname)) == p - filename)
       && !strncmp (cstring_toCharsSafe (searchptr->fname),
                   filename,
                   size_fromInt (p - filename)))
@@ -6180,7 +7073,7 @@ finclude (cppReader *pfile, int f,
          bool system_header_p,
          /*@dependent@*/ struct file_name_list *dirptr)
 {
-  mode_t st_mode;
+  __mode_t st_mode;
   size_t st_size;
   long i;
   int length = 0;
@@ -6196,7 +7089,7 @@ finclude (cppReader *pfile, int f,
       /*@=mustfree@*/
     }
 
-  fp = cppReader_getBuffer (pfile);
+  fp = cppReader_getBufferSafe (pfile);
 
   /*@-temptrans@*/ /* fname shouldn't really be temp */
   fp->nominal_fname = fp->fname = fname;
@@ -6224,7 +7117,7 @@ finclude (cppReader *pfile, int f,
   else if (S_ISDIR (st_mode))
     {
       cppReader_error (pfile,
-                      message ("Directory specified in #include: %s", fname));
+                      message ("Directory specified where file is expected: %s", fname));
       check (close (f) == 0);
       return 0;
     }
@@ -6290,11 +7183,11 @@ finclude (cppReader *pfile, int f,
 }
 
 void
-cppReader_init (cppReader *pfile)
+cpplib_init (cppReader *pfile)
 {
   memset ((char *) pfile, 0, sizeof (*pfile));
 
-  pfile->get_token = cppGetToken;
+  pfile->get_token = cpplib_getToken;
   pfile->token_buffer_size = 200;
   pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
   pfile->all_include_files = NULL;
@@ -6321,8 +7214,12 @@ cppReader_finish (/*@unused@*/ cppReader *pfile)
    This is the cppReader 'finalizer' or 'destructor' (in C++ terminology).  */
 
 void
-cppCleanup (cppReader *pfile)
+cppCleanup (/*@special@*/ cppReader *pfile) 
+     /*@uses pfile@*/
+     /*@releases pfile@*/
 {
+  DPRINTF (("cppCleanup!"));
+
   while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
     {
       (void) cppReader_popBuffer (pfile);
@@ -6351,6 +7248,25 @@ cppCleanup (cppReader *pfile)
       sfree (temp);
     }
 
+  /* evans 2002-07-12 */
+  while (pfile->opts->map_list != NULL)
+    {
+      struct file_name_map_list *temp = pfile->opts->map_list;
+      pfile->opts->map_list = pfile->opts->map_list->map_list_next;
+      cstring_free (temp->map_list_name);
+      sfree (temp);
+    }
+
+  while (pfile->opts->include != NULL)
+    {
+      struct file_name_list *temp = pfile->opts->include;
+      pfile->opts->include = pfile->opts->include->next;
+      /* cstring_free (temp->fname); */
+      sfree (temp);
+    }
+
+  sfree (pfile->opts);
+  pfile->opts = NULL;
   cppReader_hashCleanup ();
 }
 
@@ -6360,12 +7276,14 @@ cppCleanup (cppReader *pfile)
 */
 
 static int
-file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
+file_size_and_mode (int fd, __mode_t *mode_pointer, size_t *size_pointer)
 {
   struct stat sbuf;
 
   if (fstat (fd, &sbuf) < 0) {
-    return (-1);
+    *mode_pointer = 0;
+    *size_pointer = 0;
+    /*@i2@*/ return (-1); /* Spurious warnings! */
   }
 
   if (mode_pointer != NULL)
@@ -6378,7 +7296,7 @@ file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
       *size_pointer = (size_t) sbuf.st_size;
     }
 
-  return 0;
+  /*@i4@*/ return 0; /* spurious warnings here */
 }
 
 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
@@ -6425,7 +7343,7 @@ static int safe_read (int desc, char *ptr, int len)
 void
 parseSetMark (struct parse_marker *pmark, cppReader *pfile)
 {
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
+  cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
 
   pmark->next = pbuf->marks;
   /*@-temptrans@*/
@@ -6434,6 +7352,7 @@ parseSetMark (struct parse_marker *pmark, cppReader *pfile)
 
   pmark->buf = pbuf;
   pmark->position = pbuf->cur - pbuf->buf;
+  DPRINTF (("set mark: %d / %s", pmark->position, pbuf->cur));
 }
 
 /* Cleanup PMARK - we no longer need it.  */
@@ -6456,7 +7375,7 @@ void parseClearMark (struct parse_marker *pmark)
 void
 parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
 {
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
+  cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
 
   if (pbuf != pmark->buf)
     {
@@ -6466,6 +7385,7 @@ parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
 
   llassert (pbuf->buf != NULL);
   pbuf->cur = pbuf->buf + pmark->position;
+  DPRINTF (("goto mark: %d / %s", pmark->position, pbuf->cur));
 }
 
 /* Reset PMARK to point to the current position of PFILE.  (Same
@@ -6474,7 +7394,7 @@ parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
 void
 parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
 {
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
+  cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
 
   if (pbuf != pmark->buf)
     {
@@ -6483,9 +7403,10 @@ parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
     }
 
   pmark->position = pbuf->cur - pbuf->buf;
+  DPRINTF (("move mark: %s", pmark->position));
 }
 
-void cppReader_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
+void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
 {
   struct cppOptions *opts = CPPOPTIONS (pfile);
   cstring xp;
@@ -6496,7 +7417,7 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library
 
   struct default_include *include_defaults = include_defaults_array;
 
-  /* Add dirs from CPATH after dirs from -I.  */
+  /* Add dirs from INCLUDEPATH_VAR after dirs from -I.  */
   /* There seems to be confusion about what CPATH should do,
      so for the moment it is not documented.  */
   /* Some people say that CPATH should replace the standard include dirs,
@@ -6665,24 +7586,26 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library
 
   cppReader_appendIncludeChain (pfile, opts->before_system,
                                opts->last_before_system);
+
   opts->first_system_include = opts->before_system;
 
   /* Unless -fnostdinc,
      tack on the standard include file dirs to the specified list */
+
   if (!opts->no_standard_includes) {
     struct default_include *p = include_defaults;
     char *specd_prefix = opts->include_prefix;
     char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
-    int default_len = 0;
-
-       /* Remove the `include' from /usr/local/lib/gcc.../include.  */
-       if (default_prefix != NULL) {
-    if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
-      default_len = strlen (default_prefix) - 7;
-      default_prefix[default_len] = 0;
+    size_t default_len = 0;
+    
+    /* Remove the `include' from /usr/local/lib/gcc.../include.  */
+    if (default_prefix != NULL) {
+      if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
+       default_len = strlen (default_prefix) - 7;
+       default_prefix[default_len] = 0;
+      }
     }
-       }
-
+    
     /* Search "translated" versions of GNU directories.
        These have /usr/local/lib/gcc... replaced by specd_prefix.  */
     if (specd_prefix != 0 && default_len != 0)
@@ -6691,8 +7614,9 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library
        if (!p->cplusplus
            || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
          /* Does this dir start with the prefix?  */
-         if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix,
-                       size_fromInt (default_len)))
+         llassert (default_prefix != NULL);
+
+         if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len))
            {
              /* Yes; change prefix and add to search list.  */
              struct file_name_list *nlist
@@ -6708,15 +7632,16 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library
              nlist->c_system_include_path = !p->cxx_aware;
              nlist->got_name_map = 0;
 
-             cppReader_addIncludeChain (pfile, nlist);
              if (opts->first_system_include == 0)
                {
                  opts->first_system_include = nlist;
                }
+         
+             cppReader_addIncludeChain (pfile, nlist);
            }
        }
       }
-
+    
     /* Search ordinary names for GNU include directories.  */
 
     for (p = include_defaults; p->fname != NULL; p++)
@@ -6733,12 +7658,14 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library
            nlist->got_name_map = 0;
            nlist->next = NULL;
 
-           cppReader_addIncludeChain (pfile, nlist);
-
-           if (opts->first_system_include == 0)
+           /* Spurious warning reported for opts->first_system_include */
+           /*@-usereleased@*/ if (opts->first_system_include == NULL) 
              {
                opts->first_system_include = nlist;
              }
+           /*@=usereleased@*/
+
+           cppReader_addIncludeChain (pfile, nlist);
          }
       }
     sfree (default_prefix);
@@ -6748,11 +7675,14 @@ void cppReader_initializeReader (cppReader *pfile) /* Must be done after library
   cppReader_appendIncludeChain (pfile, opts->after_include,
                                opts->last_after_include);
 
-  if (opts->first_system_include == 0)
+  /* Spurious warnings for opts->first_system_include */
+  /*@-usereleased@*/
+  if (opts->first_system_include == NULL)
     {
       opts->first_system_include = opts->after_include;
     }
-
+  /*@=usereleased@*/
+  
   /* With -v, print the list of dirs to search.  */
   if (opts->verbose) {
     struct file_name_list *p;
@@ -6836,7 +7766,7 @@ static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile
   return (buf->buf + buf->line_base);
 }
 
-int cppBufPeek (cppBuffer *buf)
+int cpplib_bufPeek (cppBuffer *buf)
 {
   if (buf->cur == NULL || buf->rlimit == NULL) {
     return EOF;
@@ -6879,9 +7809,9 @@ static void cpp_setLocation (cppReader *pfile)
 
   if (pfile->buffer != NULL)
     {
-      if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname))
+      if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname))
        {
-         cstring fname = cppReader_getBuffer (pfile)->nominal_fname;
+         cstring fname = cppReader_getBufferSafe (pfile)->nominal_fname;
          
          DPRINTF (("Looking up: %s", fname));
          
@@ -6894,16 +7824,16 @@ static void cpp_setLocation (cppReader *pfile)
              DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
 
              fid = fileTable_lookup (context_fileTable (),
-                                     cppReader_getBuffer (pfile)->fname);
+                                     cppReader_getBufferSafe (pfile)->fname);
            }
        }
       else
        {
          fid = fileTable_lookup (context_fileTable (),
-                                 cppReader_getBuffer (pfile)->fname);
+                                 cppReader_getBufferSafe (pfile)->fname);
        }
       
-      line = cppReader_getBuffer (pfile)->lineno;
+      line = cppReader_getBufferSafe (pfile)->lineno;
       fileloc_free (g_currentloc);
 
       if (fileId_isValid (fid))
@@ -6922,7 +7852,7 @@ static void cpp_setLocation (cppReader *pfile)
     }
 }
 
-static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/
+static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@modifies p*/
 {
   bool checkmacro = FALSE;
   bool hasParams = FALSE;
@@ -6991,7 +7921,6 @@ static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/
   hasParams = (c == '(');
   *p = '\0';
 
-
   if (notparseable)
     {
       notparseable = FALSE;
@@ -7150,8 +8079,7 @@ static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/
                            {
                              fileloc loc = fileloc_makePreproc (g_currentloc);
                              DPRINTF (("Make constant: %s", sname));
-                             le = uentry_makeConstant (sname,
-                                                       ctype_unknown, loc);
+                             le = uentry_makeMacroConstant (sname, ctype_unknown, loc);
                              (void) usymtab_addEntry (le);
                            }
 
@@ -7203,9 +8131,10 @@ static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/
 static enum cpp_token
 cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
 {
-  cppBuffer *pbuf = cppReader_getBuffer (pfile);
+  cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
   char *start;
   int len;
+  fileloc loc;
   bool eliminateComment = FALSE;
 
   llassert (pbuf->buf != NULL);
@@ -7221,6 +8150,10 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
       int i;
       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];
@@ -7231,23 +8164,36 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
       llassert (start[len - 1] == '/');
       start[len - 1] = AFTER_COMMENT_MARKER[1];
 
-      cppReader_reserve(pfile, size_fromInt (1 + len));
+      cpplib_reserve(pfile, size_fromInt (1 + len));
       cppReader_putCharQ (pfile, c);
 
       cpp_setLocation (pfile);
 
+      start[len] = '\0';
+
+      if (mstring_containsString (scomment, "/*"))
+       {
+         (void) cppoptgenerror 
+           (FLG_NESTCOMMENT,
+            message ("Comment starts inside syntactic comment: %s", 
+                     cstring_fromChars (scomment)),
+            pfile);
+       }
+
+      start[len] = savec;
+
       if (mstring_equalPrefix (scomment, "ignore"))
        {
          if (!context_getFlag (FLG_NOCOMMENTS))
            {
-             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"))
@@ -7327,27 +8273,32 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
                {
                  /* 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")
@@ -7369,8 +8320,7 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
                      fl = FLG_CONSTMACROS;
                    }
 
-
-                 context_fileSetFlag (fl, ynm_fromCodeChar (sChar));
+                 context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc);
                  notfunction = FALSE;
                }
              else
@@ -7456,11 +8406,11 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
            c = BEFORE_COMMENT_MARKER[0];
            start[0] = BEFORE_COMMENT_MARKER[1];
 
-           llassert (cstring_length (lintcomment) == len - 3);
+           llassert (size_toLong (cstring_length (lintcomment)) == len - 3);
 
            for (i = 1; i < len - 2; i++)
              {
-               start[i] = cstring_getChar (lintcomment, i);
+               start[i] = cstring_getChar (lintcomment, size_fromInt (i));
              }
            
            start[len - 2] = AFTER_COMMENT_MARKER[0];
@@ -7474,9 +8424,10 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
                if (start[i] == '/'
                    && i < len - 1
                    && start[i + 1] == '*') {
-                 (void) cppoptgenerror (FLG_NESTCOMMENT,
-                                        message ("Comment starts inside comment"),
-                                        pfile);
+                 (void) cppoptgenerror 
+                   (FLG_NESTCOMMENT,
+                    message ("Comment starts inside comment"),
+                    pfile);
                }
                
                if (start[i] != '\n')
@@ -7486,7 +8437,7 @@ cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
              }
          }
 
-       cppReader_reserve (pfile, size_fromInt (1 + len));
+       cpplib_reserve (pfile, size_fromInt (1 + len));
        cppReader_putCharQ (pfile, c);
        cppReader_putStrN (pfile, start, size_fromInt (len));
        parseClearMark (smark);
@@ -7499,20 +8450,32 @@ static int cpp_openIncludeFile (char *filename)
 {
   int res = open (filename, O_RDONLY, 0666);
 
-  if (res) 
+  /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
+  if (res >= 0)
     {
       if (!fileTable_exists (context_fileTable (),
                             cstring_fromChars (filename)))
        {
-         (void) fileTable_addHeaderFile (context_fileTable (),
+         if (fileloc_isXHFile (g_currentloc))
+           {
+             /*
+             ** Files includes by XH files are also XH files
+             */
+
+             (void) fileTable_addXHFile (context_fileTable (),
                                          cstring_fromChars (filename));
+           }
+         else
+           {
+             (void) fileTable_addHeaderFile (context_fileTable (),
+                                             cstring_fromChars (filename));
+           }
        }
       else
        {
          DPRINTF (("File already exists: %s", filename));
        }
     }
-               
 
   return res;
 }
@@ -7531,8 +8494,27 @@ static bool cpp_skipIncludeFile (cstring fname)
       
       if (context_getFlag (FLG_SKIPSYSHEADERS))
        {
-         DPRINTF (("Skip include TRUE: %s", fname));
-         return TRUE;
+         /*
+         ** 2003-04-18: Patch from Randal Parsons
+         */
+
+         /*
+         ** Don't skip include file unless the file actually exists.  
+         ** It may be in a different directory.
+         */
+
+         int f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666);
+
+         if (f >= 0)
+           {
+             check (close (f) == 0);
+             DPRINTF (("Skip include TRUE: %s", fname));
+             return TRUE;
+           }
+         else
+           {
+             /* Keep looking... */
+           }
        }
     }
 
@@ -7557,7 +8539,7 @@ static bool cpp_skipIncludeFile (cstring fname)
 
 static int cpp_peekN (cppReader *pfile, int n)
 {
-  cppBuffer *buf = cppReader_getBuffer (pfile);
+  cppBuffer *buf = cppReader_getBufferSafe (pfile);
 
   llassert (buf->cur != NULL);
 
@@ -7576,3 +8558,6 @@ void cppBuffer_forward (cppBuffer *buf, int n)
   llassert (buf->cur != NULL);
   buf->cur += n;
 }
+
+/*@=bufferoverflowhigh@*/
+/*@=bounds@*/
This page took 0.252093 seconds and 4 git commands to generate.