OSDN Git Service

($(OBJC_O)): Also depend on $(GCC_PASSES).
[pf3gnuchains/gcc-fork.git] / gcc / cccp.c
index 6f92186..5e13227 100644 (file)
@@ -1,5 +1,5 @@
 /* C Compatible Compiler Preprocessor (CCCP)
-   Copyright (C) 1986, 87, 89, 92-95, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1986, 87, 89, 92-96, 1997 Free Software Foundation, Inc.
    Written by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
 
@@ -44,10 +44,6 @@ typedef unsigned char U_CHAR;
 #define STANDARD_INCLUDE_DIR "/usr/include"
 #endif
 
-#ifndef LOCAL_INCLUDE_DIR
-#define LOCAL_INCLUDE_DIR "/usr/local/include"
-#endif
-
 #include "pcp.h"
 
 /* By default, colon separates directories in a path.  */
@@ -178,7 +174,7 @@ my_bzero (b, length)
 # endif /* !defined (BSTRING) && (defined (USG) || defined (VMS)) */
 #endif /* ! STDC_HEADERS */
 
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
 # define __attribute__(x)
 #endif
 
@@ -195,13 +191,13 @@ my_bzero (b, length)
 # define VA_START(va_list, var) va_start (va_list, var)
 # define PRINTF_ALIST(msg) char *msg, ...
 # define PRINTF_DCL(msg)
-# define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (printf, m, n)))
+# define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (__printf__, m, n)))
 #else
 # include <varargs.h>
 # define VA_START(va_list, var) va_start (va_list)
 # define PRINTF_ALIST(msg) msg, va_alist
 # define PRINTF_DCL(msg) char *msg; va_dcl
-# define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (printf, m, n)))
+# define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (__printf__, m, n)))
 # define vfprintf(file, msg, args) \
     { \
       char *a0 = va_arg(args, char *); \
@@ -223,17 +219,11 @@ my_bzero (b, length)
 /* VMS-specific definitions */
 #ifdef VMS
 #include <descrip.h>
-#define O_RDONLY       0       /* Open arg for Read/Only  */
-#define O_WRONLY       1       /* Open arg for Write/Only */
-#define read(fd,buf,size)      VMS_read (fd,buf,size)
-#define write(fd,buf,size)     VMS_write (fd,buf,size)
 #define open(fname,mode,prot)  VMS_open (fname,mode,prot)
 #define fopen(fname,mode)      VMS_fopen (fname,mode)
 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
 #define fstat(fd,stbuf)                VMS_fstat (fd,stbuf)
 static int VMS_fstat (), VMS_stat ();
-static int VMS_read ();
-static int VMS_write ();
 static int VMS_open ();
 static FILE * VMS_fopen ();
 static FILE * VMS_freopen ();
@@ -241,11 +231,13 @@ static void hack_vms_include_specification ();
 #define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
 #define INO_T_HASH(a) 0
 #define INCLUDE_LEN_FUDGE 12   /* leave room for VMS syntax conversion */
-#ifdef __GNUC__
-#define BSTRING                        /* VMS/GCC supplies the bstring routines */
-#endif /* __GNUC__ */
 #endif /* VMS */
 
+/* Windows does not natively support inodes */
+#if defined (_WIN32) && ! defined (CYGWIN32)
+#define INO_T_EQ(a, b) 0
+#endif
+
 #ifndef O_RDONLY
 #define O_RDONLY 0
 #endif
@@ -301,7 +293,7 @@ static void hack_vms_include_specification ();
 #endif
 
 #ifndef NULL_PTR
-#define NULL_PTR ((GENERIC_PTR)0)
+#define NULL_PTR ((GENERIC_PTR) 0)
 #endif
 
 #ifndef INCLUDE_LEN_FUDGE
@@ -427,7 +419,7 @@ static FILE *pcp_outfile;
 
 /* Nonzero means we are inside an IF during a -pcp run.  In this mode
    macro expansion is done, and preconditions are output for all macro
-   uses requiring them. */
+   uses requiring them.  */
 static int pcp_inside_if;
 
 /* Nonzero means never to include precompiled files.
@@ -461,6 +453,10 @@ static int warn_stringify;
 
 static int warn_trigraphs;
 
+/* Nonzero means warn if undefined identifiers are evaluated in an #if.  */
+
+int warn_undef;
+
 /* Nonzero means warn if #import is used.  */
 
 static int warn_import = 1;
@@ -473,6 +469,10 @@ static int warnings_are_errors;
 
 int traditional;
 
+/* Nonzero for the 1989 C Standard, including corrigenda and amendments.  */
+
+int c89;
+
 /* Nonzero causes output not to be done,
    but directives such as #define that have side effects
    are still obeyed.  */
@@ -547,7 +547,7 @@ typedef struct file_buf FILE_BUF;
 
 /* The output buffer.  Its LENGTH field is the amount of room allocated
    for the buffer, not the number of chars actually present.  To get
-   that, subtract outbuf.buf from outbuf.bufp. */
+   that, subtract outbuf.buf from outbuf.bufp.  */
 
 #define OUTBUF_SIZE 10 /* initial size of output buffer */
 static FILE_BUF outbuf;
@@ -577,9 +577,9 @@ struct file_name_list
     char fname[1];
   };
 
-/* #include "file" looks in source file dir, then stack. */
-/* #include <file> just looks in the stack. */
-/* -I directories are added to the end, then the defaults are added. */
+/* #include "file" looks in source file dir, then stack.  */
+/* #include <file> just looks in the stack.  */
+/* -I directories are added to the end, then the defaults are added.  */
 /* The */
 static struct default_include {
   char *fname;                 /* The name of the directory.  */
@@ -594,6 +594,7 @@ static struct default_include {
   = {
     /* Pick up GNU C++ specific include files.  */
     { GPLUSPLUS_INCLUDE_DIR, 1, 1 },
+    { OLD_GPLUSPLUS_INCLUDE_DIR, 1, 1 },
 #ifdef CROSS_COMPILE
     /* This is the dir for fixincludes.  Put it just before
        the files that we fix.  */
@@ -601,15 +602,21 @@ static struct default_include {
     /* For cross-compilation, this dir name is generated
        automatically in Makefile.in.  */
     { CROSS_INCLUDE_DIR, 0, 0 },
+#ifdef TOOL_INCLUDE_DIR
     /* This is another place that the target system's headers might be.  */
     { TOOL_INCLUDE_DIR, 0, 0 },
+#endif
 #else /* not CROSS_COMPILE */
+#ifdef LOCAL_INCLUDE_DIR
     /* This should be /usr/local/include and should come before
        the fixincludes-fixed header files.  */
     { LOCAL_INCLUDE_DIR, 0, 1 },
+#endif
+#ifdef TOOL_INCLUDE_DIR
     /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
        Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h.  */
     { TOOL_INCLUDE_DIR, 0, 0 },
+#endif
     /* This is the dir for fixincludes.  Put it just before
        the files that we fix.  */
     { GCC_INCLUDE_DIR, 0, 0 },
@@ -720,7 +727,7 @@ enum sharp_token_type {
    #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
    pattern list
      { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
-   where (x, y) means (nchars, argno). */
+   where (x, y) means (nchars, argno).  */
 
 typedef struct definition DEFINITION;
 struct definition {
@@ -754,7 +761,7 @@ struct definition {
 };
 
 /* different kinds of things that can appear in the value field
-   of a hash node.  Actually, this may be useless now. */
+   of a hash node.  Actually, this may be useless now.  */
 union hashval {
   char *cpval;
   DEFINITION *defn;
@@ -781,7 +788,7 @@ static char rest_extension[] = "...";
    plus some special tokens like __LINE__ (these each have their own
    type, and the appropriate code is run when that type of node is seen.
    It does not contain control words like "#define", which are recognized
-   by a separate piece of code. */
+   by a separate piece of code.  */
 
 /* different flavors of hash nodes --- also used in keyword table */
 enum node_type {
@@ -830,7 +837,7 @@ struct hashnode {
   struct hashnode *prev;
   struct hashnode **bucket_hdr;        /* also, a back pointer to this node's hash
                                   chain is kept, in case the node is the head
-                                  of the chain and gets deleted. */
+                                  of the chain and gets deleted.  */
   enum node_type type;         /* type of special token */
   int length;                  /* length of token, for quick comparison */
   U_CHAR *name;                        /* the actual name */
@@ -844,7 +851,7 @@ typedef struct hashnode HASHNODE;
    loop computes the hash value `on the fly' for most tokens,
    in order to avoid the overhead of a lot of procedure calls to
    the hashf () function.  Hashf () only exists for the sake of
-   politeness, for use when speed isn't so important. */
+   politeness, for use when speed isn't so important.  */
 
 #define HASHSIZE 1403
 static HASHNODE *hashtab[HASHSIZE];
@@ -918,7 +925,7 @@ struct assertion_hashnode {
   struct assertion_hashnode *prev;
   /* also, a back pointer to this node's hash
      chain is kept, in case the node is the head
-     of the chain and gets deleted. */
+     of the chain and gets deleted.  */
   struct assertion_hashnode **bucket_hdr;
   int length;                  /* length of token, for quick comparison */
   U_CHAR *name;                        /* the actual name */
@@ -933,7 +940,7 @@ typedef struct assertion_hashnode ASSERTION_HASHNODE;
    loop computes the hash value `on the fly' for most tokens,
    in order to avoid the overhead of a lot of procedure calls to
    the hashf function.  hashf only exists for the sake of
-   politeness, for use when speed isn't so important. */
+   politeness, for use when speed isn't so important.  */
 
 #define ASSERTION_HASHSIZE 37
 static ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE];
@@ -950,10 +957,12 @@ struct directive {
   int length;                  /* Length of name */
   int (*func) DO_PROTO;        /* Function to handle directive */
   char *name;                  /* Name of directive */
-  enum node_type type;         /* Code which describes which directive. */
+  enum node_type type;         /* Code which describes which directive.  */
   char angle_brackets;         /* Nonzero => <...> is special.  */
   char traditional_comments;   /* Nonzero: keep comments if -traditional.  */
-  char pass_thru;              /* Copy preprocessed directive to output file.  */
+  char pass_thru;              /* Copy directive to output:
+                                  if 1, copy if dumping definitions;
+                                  if 2, always copy, after preprocessing.  */
 };
 
 /* These functions are declared to return int instead of void since they
@@ -982,7 +991,7 @@ static int do_xifdef DO_PROTO;
 /* Here is the actual list of #-directives, most-often-used first.  */
 
 static struct directive directive_table[] = {
-  {  6, do_define, "define", T_DEFINE, 0, 1},
+  {  6, do_define, "define", T_DEFINE, 0, 1, 1},
   {  2, do_if, "if", T_IF},
   {  5, do_xifdef, "ifdef", T_IFDEF},
   {  6, do_xifdef, "ifndef", T_IFNDEF},
@@ -999,7 +1008,7 @@ static struct directive directive_table[] = {
 #ifdef SCCS_DIRECTIVE
   {  4, do_sccs, "sccs", T_SCCS},
 #endif
-  {  6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1},
+  {  6, do_pragma, "pragma", T_PRAGMA, 0, 0, 2},
   {  5, do_ident, "ident", T_IDENT},
   {  6, do_assert, "assert", T_ASSERT},
   {  8, do_unassert, "unassert", T_UNASSERT},
@@ -1010,14 +1019,14 @@ static struct directive directive_table[] = {
    this points to the # (or the : of the %:) that started the directive.  */
 U_CHAR *directive_start;
 
-/* table to tell if char can be part of a C identifier. */
+/* table to tell if char can be part of a C identifier.  */
 U_CHAR is_idchar[256];
-/* table to tell if char can be first char of a c identifier. */
+/* table to tell if char can be first char of a c identifier.  */
 U_CHAR is_idstart[256];
 /* table to tell if c is horizontal space.  */
-U_CHAR is_hor_space[256];
+static U_CHAR is_hor_space[256];
 /* table to tell if c is horizontal or vertical space.  */
-static U_CHAR is_space[256];
+U_CHAR is_space[256];
 /* names of some characters */
 static char *char_name[256];
 
@@ -1029,18 +1038,6 @@ static int errors = 0;                   /* Error counter for exit code */
 /* Name of output file, for error messages.  */
 static char *out_fname;
 
-/* Zero means dollar signs are punctuation.
-   -$ stores 0; -traditional may store 1.  Default is 1 for VMS, 0 otherwise.
-   This must be 0 for correct processing of this ANSI C program:
-       #define foo(a) #a
-       #define lose(b) foo (b)
-       #define test$
-       lose (test)     */
-static int dollars_in_ident;
-#ifndef DOLLARS_IN_IDENTIFIERS
-#define DOLLARS_IN_IDENTIFIERS 1
-#endif
-
 
 /* Stack of conditionals currently in progress
    (including both successful and failing conditionals).  */
@@ -1220,7 +1217,8 @@ static GENERIC_PTR xcalloc PROTO((size_t, size_t));
 static char *savestring PROTO((char *));
 \f
 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
-   retrying if necessary.  Return a negative value if an error occurs,
+   retrying if necessary.  If MAX_READ_LEN is defined, read at most
+   that bytes at a time.  Return a negative value if an error occurs,
    otherwise return the actual number of bytes read,
    which must be LEN unless end-of-file was reached.  */
 
@@ -1230,9 +1228,16 @@ safe_read (desc, ptr, len)
      char *ptr;
      int len;
 {
-  int left = len;
+  int left, rcount, nchars;
+
+  left = len;
   while (left > 0) {
-    int nchars = read (desc, ptr, left);
+    rcount = left;
+#ifdef MAX_READ_LEN
+    if (rcount > MAX_READ_LEN)
+      rcount = MAX_READ_LEN;
+#endif
+    nchars = read (desc, ptr, rcount);
     if (nchars < 0)
       {
 #ifdef EINTR
@@ -1250,7 +1255,8 @@ safe_read (desc, ptr, len)
 }
 
 /* Write LEN bytes at PTR to descriptor DESC,
-   retrying if necessary, and treating any real error as fatal.  */
+   retrying if necessary, and treating any real error as fatal.
+   If MAX_WRITE_LEN is defined, write at most that many bytes at a time.  */
 
 static void
 safe_write (desc, ptr, len)
@@ -1258,8 +1264,15 @@ safe_write (desc, ptr, len)
      char *ptr;
      int len;
 {
+  int wcount, written;
+
   while (len > 0) {
-    int written = write (desc, ptr, len);
+    wcount = len;
+#ifdef MAX_WRITE_LEN
+    if (wcount > MAX_WRITE_LEN)
+      wcount = MAX_WRITE_LEN;
+#endif
+    written = write (desc, ptr, wcount);
     if (written < 0)
       {
 #ifdef EINTR
@@ -1319,7 +1332,7 @@ main (argc, argv)
     struct rlimit rlim;
 
     /* Set the stack limit huge so that alloca (particularly stringtab
-     * in dbxread.c) does not fail. */
+       in dbxread.c) does not fail.  */
     getrlimit (RLIMIT_STACK, &rlim);
     rlim.rlim_cur = rlim.rlim_max;
     setrlimit (RLIMIT_STACK, &rlim);
@@ -1351,10 +1364,8 @@ main (argc, argv)
   in_fname = NULL;
   out_fname = NULL;
 
-  /* Initialize is_idchar to allow $.  */
-  dollars_in_ident = 1;
+  /* Initialize is_idchar.  */
   initialize_char_syntax ();
-  dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0;
 
   no_line_directives = 0;
   no_trigraphs = 1;
@@ -1495,10 +1506,10 @@ main (argc, argv)
          if (i + 1 == argc)
            fatal ("Filename missing after -pcp option");
          pcp_fname = argv[++i];
-         pcp_outfile = 
-           ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
-            ? fopen (pcp_fname, "w")
-            : stdout);
+         pcp_outfile
+           ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
+              ? fopen (pcp_fname, "w")
+              : stdout);
          if (pcp_outfile == 0)
            pfatal_with_name (pcp_fname);
          no_precomp = 1;
@@ -1509,8 +1520,6 @@ main (argc, argv)
        if (!strcmp (argv[i], "-traditional")) {
          traditional = 1;
          cplusplus_comments = 0;
-         if (dollars_in_ident > 0)
-           dollars_in_ident = 1;
        } else if (!strcmp (argv[i], "-trigraphs")) {
          no_trigraphs = 0;
        }
@@ -1518,15 +1527,15 @@ main (argc, argv)
 
       case 'l':
        if (! strcmp (argv[i], "-lang-c"))
-         cplusplus = 0, cplusplus_comments = 1, objc = 0;
+         cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 0;
        if (! strcmp (argv[i], "-lang-c89"))
-         cplusplus = 0, cplusplus_comments = 0, objc = 0;
+         cplusplus = 0, cplusplus_comments = 0, c89 = 1, objc = 0;
        if (! strcmp (argv[i], "-lang-c++"))
-         cplusplus = 1, cplusplus_comments = 1, objc = 0;
+         cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 0;
        if (! strcmp (argv[i], "-lang-objc"))
-         objc = 1, cplusplus = 0, cplusplus_comments = 1;
+         cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 1;
        if (! strcmp (argv[i], "-lang-objc++"))
-         objc = 1, cplusplus = 1, cplusplus_comments = 1;
+         cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 1;
        if (! strcmp (argv[i], "-lang-asm"))
          lang_asm = 1;
        if (! strcmp (argv[i], "-lint"))
@@ -1558,6 +1567,10 @@ main (argc, argv)
          warn_stringify = 1;
        else if (!strcmp (argv[i], "-Wno-traditional"))
          warn_stringify = 0;
+       else if (!strcmp (argv[i], "-Wundef"))
+         warn_undef = 1;
+       else if (!strcmp (argv[i], "-Wno-undef"))
+         warn_undef = 0;
        else if (!strcmp (argv[i], "-Wimport"))
          warn_import = 1;
        else if (!strcmp (argv[i], "-Wno-import"))
@@ -1712,7 +1725,7 @@ main (argc, argv)
        break;
 
       case '$':                        /* Don't include $ in identifiers.  */
-       dollars_in_ident = 0;
+       is_idchar['$'] = is_idstart['$'] = 0;
        break;
 
       case 'I':                        /* Add directory to path for includes.  */
@@ -1775,9 +1788,6 @@ main (argc, argv)
   if (cp && ! no_standard_includes)
     path_include (cp);
 
-  /* Now that dollars_in_ident is known, initialize is_idchar.  */
-  initialize_char_syntax ();
-
   /* Initialize output buffer */
 
   outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);
@@ -1894,8 +1904,8 @@ main (argc, argv)
 
   done_initializing = 1;
 
-  { /* read the appropriate environment variable and if it exists
-       replace include_defaults with the listed path. */
+  { /* Read the appropriate environment variable and if it exists
+       replace include_defaults with the listed path.  */
     char *epath = 0;
     switch ((objc << 1) + cplusplus)
       {
@@ -2350,7 +2360,7 @@ index0 (s, c, n)
    Using an extra pass through the buffer takes a little extra time,
    but is infinitely less hairy than trying to handle trigraphs inside
    strings, etc. everywhere, and also makes sure that trigraphs are
-   only translated in the top level of processing. */
+   only translated in the top level of processing.  */
 
 static void
 trigraph_pcp (buf)
@@ -2401,7 +2411,7 @@ trigraph_pcp (buf)
     len = sptr - fptr - 2;
 
     /* BSD doc says bcopy () works right for overlapping strings.  In ANSI
-       C, this will be memmove (). */
+       C, this will be memmove ().  */
     if (bptr != fptr && len > 0)
       bcopy ((char *) fptr, (char *) bptr, len);
 
@@ -2496,8 +2506,7 @@ name_newline_fix (bp)
 
    Upon return, any arg will be pointed to with argstart and will be
    arglen long.  Note that we don't parse that arg since it will just
-   be printed out again.
-*/
+   be printed out again.  */
 
 static char *
 get_lintcmd (ibp, limit, argstart, arglen, cmdlen)
@@ -2701,7 +2710,7 @@ do { ip = &instack[indepth];              \
        if (ident_length)
          goto specialchar;
        /* Copy #foo (bar lose) without macro expansion.  */
-       obp[-1] = '#';  /* In case it was '%'. */
+       obp[-1] = '#';  /* In case it was '%'.  */
        SKIP_WHITE_SPACE (ibp);
        while (is_idchar[*ibp])
          *obp++ = *ibp++;
@@ -2828,7 +2837,10 @@ do { ip = &instack[indepth];             \
       /* A single quoted string is treated like a double -- some
         programs (e.g., troff) are perverse this way */
 
-      if (ident_length)
+      /* Handle any pending identifier;
+        but the L in L'...' or L"..." is not an identifier.  */
+      if (ident_length
+         && ! (ident_length == 1 && hash == HASHSTEP (0, 'L')))
        goto specialchar;
 
       start_line = ip->lineno;
@@ -2921,10 +2933,10 @@ do { ip = &instack[indepth];            \
        goto specialchar;
 
       if (*ibp == '/') {
-       /* C++ style comment... */
+       /* C++ style comment...  */
        start_line = ip->lineno;
 
-       /* Comments are equivalent to spaces. */
+       /* Comments are equivalent to spaces.  */
        if (! put_out_comments)
          obp[-1] = ' ';
 
@@ -2959,7 +2971,7 @@ do { ip = &instack[indepth];              \
 
       start_line = ip->lineno;
 
-      ++ibp;                   /* Skip the star. */
+      ++ibp;                   /* Skip the star.  */
 
       /* If this cpp is for lint, we peek inside the comments: */
       if (for_lint) {
@@ -3051,8 +3063,10 @@ do { ip = &instack[indepth];             \
       break;
 
     case '$':
-      if (!dollars_in_ident)
+      if (! is_idchar['$'])
        goto randomchar;
+      if (pedantic)
+       pedwarn ("`$' in identifier");
       goto letter;
 
     case '0': case '1': case '2': case '3': case '4':
@@ -3076,16 +3090,17 @@ do { ip = &instack[indepth];            \
          }
          *obp++ = c;
          /* A sign can be part of a preprocessing number
-            if it follows an e.  */
-         if (c == 'e' || c == 'E') {
+            if it follows an `e' or `p'.  */
+         if (c == 'e' || c == 'E' || c == 'p' || c == 'P') {
            while (ibp[0] == '\\' && ibp[1] == '\n') {
              ++ip->lineno;
              ibp += 2;
            }
            if (*ibp == '+' || *ibp == '-') {
              *obp++ = *ibp++;
-             /* But traditional C does not let the token go past the sign.  */
-             if (traditional)
+             /* But traditional C does not let the token go past the sign,
+                and C89 does not allow `p'.  */
+             if (traditional || (c89 && (c == 'p' || c == 'P')))
                break;
            }
          }
@@ -3427,9 +3442,9 @@ randomchar:
              if (!traditional && obp != op->buf) {
                switch (obp[-1]) {
                case '!':  case '%':  case '&':  case '*':
-               case '+':  case '-':  case '/':  case ':':
-               case '<':  case '=':  case '>':  case '^':
-               case '|':
+               case '+':  case '-':  case '.':  case '/':
+               case ':':  case '<':  case '=':  case '>':
+               case '^':  case '|':
                  /* If we are expanding a macro arg, make a newline marker
                     to separate the tokens.  If we are making real output,
                     a plain space will do.  */
@@ -3776,9 +3791,14 @@ handle_directive (ip, op)
            bp = ip->bufp;
            /* No need to copy the directive because of a comment at the end;
               just don't include the comment in the directive.  */
-           if (bp == limit || *bp == '\n') {
-             bp = obp;
-             goto endloop1;
+           if (!put_out_comments) {
+             U_CHAR *p;
+             for (p = bp;  *p == ' ' || *p == '\t';  p++)
+               continue;
+             if (*p == '\n') {
+               bp = obp;
+               goto endloop1;
+             }
            }
            /* Don't remove the comments if -traditional.  */
            if (! keep_comments)
@@ -3809,7 +3829,8 @@ handle_directive (ip, op)
 
       /* If a directive should be copied through, and -E was given,
         pass it through before removing comments.  */
-      if (!no_output && kt->pass_thru && put_out_comments) {
+      if (!no_output && put_out_comments
+         && (dump_macros != dump_definitions) < kt->pass_thru) {
         int len;
 
        /* Output directive name.  */
@@ -3936,10 +3957,7 @@ handle_directive (ip, op)
         definitions through.  */
 
       if (!no_output && already_output == 0
-         && (kt->pass_thru
-             || (kt->type == T_DEFINE
-                 && (dump_macros == dump_names
-                     || dump_macros == dump_definitions)))) {
+         && (dump_macros < dump_names) < kt->pass_thru) {
         int len;
 
        /* Output directive name.  */
@@ -3948,7 +3966,7 @@ handle_directive (ip, op)
         bcopy (kt->name, (char *) op->bufp, kt->length);
         op->bufp += kt->length;
 
-       if (kt->pass_thru || dump_macros == dump_definitions) {
+       if ((dump_macros != dump_definitions) < kt->pass_thru) {
          /* Output arguments.  */
          len = (cp - buf);
          check_expand (op, len);
@@ -3972,7 +3990,7 @@ handle_directive (ip, op)
         either the appropriate place in the input buffer, or to
         the temp buffer if it was necessary to make one.  cp
         points to the first char after the contents of the (possibly
-        copied) directive, in either case. */
+        copied) directive, in either case.  */
       (*kt->func) (buf, cp, op, kt);
       check_expand (op, ip->length - (ip->bufp - ip->buf));
 
@@ -3990,7 +4008,7 @@ timestamp ()
 {
   static struct tm *timebuf;
   if (!timebuf) {
-    time_t t = time ((time_t *)0);
+    time_t t = time ((time_t *) 0);
     timebuf = localtime (&t);
   }
   return timebuf;
@@ -4133,11 +4151,13 @@ special_symbol (hp, op)
 
     if (!is_idstart[*ip->bufp])
       goto oops;
+    if (ip->bufp[0] == 'L' && (ip->bufp[1] == '\'' || ip->bufp[1] == '"'))
+      goto oops;
     if ((hp = lookup (ip->bufp, -1, -1))) {
       if (pcp_outfile && pcp_inside_if
          && (hp->type == T_CONST
              || (hp->type == T_MACRO && hp->value.defn->predefined)))
-       /* Output a precondition for this macro use. */
+       /* Output a precondition for this macro use.  */
        fprintf (pcp_outfile, "#define %s\n", hp->name);
       buf = " 1 ";
     }
@@ -4209,11 +4229,22 @@ do_include (buf, limit, op, keyword)
   int retried = 0;             /* Have already tried macro
                                   expanding the include line*/
   int angle_brackets = 0;      /* 0 for "...", 1 for <...> */
+#ifdef VMS
+  int vaxc_include = 0;                /* 1 for token without punctuation */
+#endif
   int pcf = -1;
   char *pcfbuf;
   char *pcfbuflimit;
   int pcfnum;
 
+  if (pedantic && !instack[indepth].system_header_p)
+    {
+      if (importing)
+       pedwarn ("ANSI C does not allow `#import'");
+      if (skip_dirs)
+       pedwarn ("ANSI C does not allow `#include_next'");
+    }
+
   if (importing && warn_import && !inhibit_warnings
       && !instack[indepth].system_header_p && !import_warning) {
     import_warning = 1;
@@ -4262,9 +4293,9 @@ get_filename:
       }
 
       /* We have "filename".  Figure out directory this source
-        file is coming from and put it on the front of the list. */
+        file is coming from and put it on the front of the list.  */
 
-      /* If -I- was specified, don't search current dir, only spec'd ones. */
+      /* If -I- was specified, don't search current dir, only spec'd ones.  */
       if (ignore_srcdir) break;
 
       for (fp = &instack[indepth]; fp >= instack; fp--)
@@ -4316,10 +4347,11 @@ get_filename:
      * code from case '<' is repeated here) and generates a warning.
      * (Note: macro expansion of `xyz' takes precedence.)
      */
-    if (retried && isalpha(*(U_CHAR *)(--fbeg))) {
+    if (retried && isalpha(*(U_CHAR *) (--fbeg))) {
       while (fin != limit && (!isspace(*fin)))
        *fend++ = *fin++;
       warning ("VAX-C-style include specification found, use '#include <filename.h>' !");
+      vaxc_include = 1;
       if (fin == limit) {
        angle_brackets = 1;
        /* If -I-, start with the first -I dir after the -I-.  */
@@ -4437,12 +4469,12 @@ get_filename:
          full VMS file specification */
       if (searchptr->fname[0]) {
        /* Fix up the filename */
-       hack_vms_include_specification (fname);
+       hack_vms_include_specification (fname, vaxc_include);
       } else {
-       /* This is a normal VMS filespec, so use it unchanged.  */
+       /* This is a normal VMS filespec, so use it unchanged.  */
        strcpy (fname, fbeg);
        /* if it's '#include filename', add the missing .h */
-       if (index(fname,'.')==NULL) {
+       if (vaxc_include && index(fname,'.')==NULL) {
          strcat (fname, ".h");
        }
       }
@@ -4468,7 +4500,7 @@ get_filename:
       if (errno == EACCES)
        break;
 #else
-      if (errno != ENOENT)
+      if (errno != ENOENT && errno != ENOTDIR)
        break;
 #endif
     }
@@ -4621,13 +4653,18 @@ base_name (fname)
 }
 
 /* Yield nonzero if FILENAME is absolute (i.e. not relative).  */
+
 static int
 absolute_filename (filename)
      char *filename;
 {
-#if defined (__MSDOS__) || defined (_WIN32)
+#if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN32__))
   if (isalpha (filename[0]) && filename[1] == ':') filename += 2;
 #endif
+#if defined (__CYGWIN32__)
+  /* At present, any path that begins with a drive spec is absolute.  */
+  if (isalpha (filename[0]) && filename[1] == ':') return 1;
+#endif
   if (filename[0] == '/') return 1;
 #ifdef DIR_SEPARATOR
   if (filename[0] == DIR_SEPARATOR) return 1;
@@ -5037,7 +5074,7 @@ finclude (f, inc, op, system_header_p, dirptr)
   } else {
     /* Cannot count its file size before reading.
        First read the entire file into heap and
-       copy them into buffer on stack. */
+       copy them into buffer on stack.  */
 
     int bsize = 2000;
     int st_size = 0;
@@ -5124,8 +5161,8 @@ record_control_macro (inc, macro_name)
    the address of the buffer following the preconditions.  The buffer, in
    this case, should never be freed because various pieces of it will
    be referred to until all precompiled strings are output at the end of
-   the run.
-*/
+   the run.  */
+
 static char *
 check_precompiled (pcf, st, fname, limit)
      int pcf;
@@ -5156,7 +5193,7 @@ check_precompiled (pcf, st, fname, limit)
   
   *limit = buf + length;
 
-  /* File is in core.  Check the preconditions. */
+  /* File is in core.  Check the preconditions.  */
   if (!check_preconditions (buf))
     goto nope;
   for (cp = buf; *cp; cp++)
@@ -5178,6 +5215,7 @@ check_precompiled (pcf, st, fname, limit)
    precompiled header.  These are a series of #define and #undef
    lines which must match the current contents of the hash
    table.  */
+
 static int 
 check_preconditions (prec)
      char *prec;
@@ -5236,7 +5274,8 @@ check_preconditions (prec)
 /* Process the main body of a precompiled file.  BUF points to the
    string section of the file, following the preconditions.  LIMIT is one
    character past the end.  NAME is the name of the file being read
-   in.  OP is the main output buffer */
+   in.  OP is the main output buffer.  */
+
 static void
 pcfinclude (buf, limit, name, op)
      U_CHAR *buf, *limit, *name;
@@ -5253,7 +5292,7 @@ pcfinclude (buf, limit, name, op)
   nstrings = (nstrings << 8) | *cp++;
   nstrings = (nstrings << 8) | *cp++;
   
-  /* Looping over each string... */
+  /* Looping over each string...  */
   while (nstrings--) {
     U_CHAR *string_start;
     U_CHAR *endofthiskey;
@@ -5272,7 +5311,7 @@ pcfinclude (buf, limit, name, op)
     if ((HOST_WIDE_INT) cp & 3)
       cp += 4 - ((HOST_WIDE_INT) cp & 3);
     
-    /* Now get the string. */
+    /* Now get the string.  */
     str = (STRINGDEF *) (GENERIC_PTR) cp;
     string_start = cp += sizeof (STRINGDEF);
     
@@ -5282,7 +5321,7 @@ pcfinclude (buf, limit, name, op)
     /* We need to macro expand the string here to ensure that the
        proper definition environment is in place.  If it were only
        expanded when we find out it is needed, macros necessary for
-       its proper expansion might have had their definitions changed. */
+       its proper expansion might have had their definitions changed.  */
     tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0);
     /* Lineno is already set in the precompiled file */
     str->contents = tmpbuf.buf;
@@ -5295,14 +5334,14 @@ pcfinclude (buf, limit, name, op)
     *stringlist_tailp = str;
     stringlist_tailp = &str->chain;
     
-    /* Next comes a fourbyte number indicating the number of keys */
-    /* for this string. */
+    /* Next comes a fourbyte number indicating the number of keys
+       for this string.  */
     nkeys = *cp++;
     nkeys = (nkeys << 8) | *cp++;
     nkeys = (nkeys << 8) | *cp++;
     nkeys = (nkeys << 8) | *cp++;
 
-    /* If this number is -1, then the string is mandatory. */
+    /* If this number is -1, then the string is mandatory.  */
     if (nkeys == -1)
       str->writeflag = 1;
     else
@@ -5315,11 +5354,11 @@ pcfinclude (buf, limit, name, op)
        cp += sizeof (KEYDEF);
        
        /* Find the end of the key.  At the end of this for loop we
-          advance CP to the start of the next key using this variable. */
+          advance CP to the start of the next key using this variable.  */
        endofthiskey = cp + strlen ((char *) cp);
        kp->str = str;
        
-       /* Expand the key, and enter it into the hash table. */
+       /* Expand the key, and enter it into the hash table.  */
        tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0);
        tmpbuf.bufp = tmpbuf.buf;
        
@@ -5346,12 +5385,13 @@ pcfinclude (buf, limit, name, op)
   }
   /* This output_line_directive serves to switch us back to the current
      input file in case some of these strings get output (which will 
-     result in line directives for the header file being output). */
+     result in line directives for the header file being output).   */
   output_line_directive (&instack[indepth], op, 0, enter_file);
 }
 
-/* Called from rescan when it hits a key for strings.  Mark them all */
- /* used and clean up. */
+/* Called from rescan when it hits a key for strings.  Mark them all
+   used and clean up.  */
+
 static void
 pcstring_used (hp)
      HASHNODE *hp;
@@ -5363,8 +5403,9 @@ pcstring_used (hp)
   delete_macro (hp);
 }
 
-/* Write the output, interspersing precompiled strings in their */
- /* appropriate places. */
+/* Write the output, interspersing precompiled strings in their
+   appropriate places.  */
+
 static void
 write_output ()
 {
@@ -5374,10 +5415,10 @@ write_output ()
   char *line_directive = xmalloc (line_directive_len);
   int len;
 
-  /* In each run through the loop, either cur_buf_loc == */
-  /* next_string_loc, in which case we print a series of strings, or */
-  /* it is less than next_string_loc, in which case we write some of */
-  /* the buffer. */
+  /* In each run through the loop, either cur_buf_loc ==
+     next_string_loc, in which case we print a series of strings, or
+     it is less than next_string_loc, in which case we write some of
+     the buffer.  */
   cur_buf_loc = outbuf.buf; 
   next_string = stringlist;
   
@@ -5450,7 +5491,7 @@ pass_thru_directive (buf, limit, op, keyword)
    appeared.  So the arglist is just convenience data passed
    between these two routines.  It is not kept around after
    the current #define has been processed and entered into the
-   hash table. */
+   hash table.  */
 
 struct arglist {
   struct arglist *next;
@@ -5461,7 +5502,8 @@ struct arglist {
 };
 
 /* Create a DEFINITION node from a #define directive.  Arguments are 
-   as for do_define. */
+   as for do_define.  */
+
 static MACRODEF
 create_definition (buf, limit, op)
      U_CHAR *buf, *limit;
@@ -5490,7 +5532,7 @@ create_definition (buf, limit, op)
 
   /* 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. */
+     care of that.  */
 
   if (*bp == '(') {
     struct arglist *arg_ptrs = NULL;
@@ -5521,8 +5563,8 @@ create_definition (buf, limit, op)
       while (is_idchar[*bp]) {
        bp++;
        /* do we have a "special" rest-args extension here? */
-       if (limit - bp > REST_EXTENSION_LENGTH &&
-           bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
+       if (limit - bp > REST_EXTENSION_LENGTH
+           && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
          rest_args = 1;
          temp->rest_args = 1;
          break;
@@ -5554,8 +5596,8 @@ create_definition (buf, limit, op)
        struct arglist *otemp;
 
        for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
-         if (temp->length == otemp->length &&
-             bcmp (temp->name, otemp->name, temp->length) == 0) {
+         if (temp->length == otemp->length
+             && bcmp (temp->name, otemp->name, temp->length) == 0) {
              error ("duplicate argument name `%.*s' in `#define'",
                     temp->length, temp->name);
              goto nope;
@@ -5565,7 +5607,7 @@ create_definition (buf, limit, op)
 
     ++bp;                      /* skip paren */
     SKIP_WHITE_SPACE (bp);
-    /* now everything from bp before limit is the definition. */
+    /* now everything from bp before limit is the definition.  */
     defn = collect_expansion (bp, limit, argno, arg_ptrs);
     defn->rest_args = rest_args;
 
@@ -5594,7 +5636,7 @@ create_definition (buf, limit, op)
        if (is_hor_space[*bp]) {
          bp++;
          SKIP_WHITE_SPACE (bp);
-       } else {
+       } else if (sym_length) {
          switch (*bp) {
            case '!':  case '"':  case '#':  case '%':  case '&':  case '\'':
            case ')':  case '*':  case '+':  case ',':  case '-':  case '.':
@@ -5612,7 +5654,7 @@ create_definition (buf, limit, op)
          }
        }
       }
-    /* Now everything from bp before limit is the definition. */
+    /* Now everything from bp before limit is the definition.  */
     defn = collect_expansion (bp, limit, -1, NULL_PTR);
     defn->args.argnames = (U_CHAR *) "";
   }
@@ -5716,7 +5758,8 @@ check_macro_name (symname, usage)
   for (p = symname; is_idchar[*p]; p++)
     ;
   sym_length = p - symname;
-  if (sym_length == 0)
+  if (sym_length == 0
+      || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
     error ("invalid %s name", usage);
   else if (!is_idstart[*symname]
           || (sym_length == 7 && ! bcmp (symname, "defined", 7)))
@@ -5724,9 +5767,8 @@ check_macro_name (symname, usage)
   return sym_length;
 }
 
-/*
- * return zero if two DEFINITIONs are isomorphic
- */
+/* Return zero if two DEFINITIONs are isomorphic.  */
+     
 static int
 compare_defs (d1, d2)
      DEFINITION *d1, *d2;
@@ -5835,7 +5877,7 @@ collect_expansion (buf, end, nargs, arglist)
   /* 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. */
+     that something smarter should happen.  */
 
   if (end < buf)
     abort ();
@@ -5943,7 +5985,8 @@ collect_expansion (buf, end, nargs, arglist)
            p++;
            SKIP_WHITE_SPACE (p);
          }
-         if (! is_idstart[*p] || nargs == 0)
+         if (! is_idstart[*p] || nargs == 0
+             || (*p == 'L' && (p[1] == '\'' || p[1] == '"')))
            error ("`#' operator is not followed by a macro argument name");
          else
            stringify = p;
@@ -6006,7 +6049,8 @@ collect_expansion (buf, end, nargs, arglist)
       while (p != limit && is_idchar[*p]) p++;
       id_len = p - id_beg;
 
-      if (is_idstart[c]) {
+      if (is_idstart[c]
+         && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
        register struct arglist *arg;
 
        for (arg = arglist; arg != NULL; arg = arg->next) {
@@ -6132,7 +6176,7 @@ do_assert (buf, limit, op, keyword)
 
   /* Lossage will occur if identifiers or control tokens are broken
      across lines using backslash.  This is not the right place to take
-     care of that. */
+     care of that.  */
 
   if (*bp != '(') {
     error ("missing token-sequence in `#assert'");
@@ -6211,7 +6255,7 @@ do_unassert (buf, limit, op, keyword)
 
   /* Lossage will occur if identifiers or control tokens are broken
      across lines using backslash.  This is not the right place to take
-     care of that. */
+     care of that.  */
 
   if (*bp == '(') {
     int error_flag = 0;
@@ -6425,15 +6469,14 @@ free_token_list (tokens)
   }
 }
 \f
-/*
- * Install a name in the assertion hash table.
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
+/* Install a name in the assertion hash table.
+
+   If LEN is >= 0, it is the length of the name.
+   Otherwise, compute the length by scanning the entire name.
+
+   If HASH is >= 0, it is the precomputed hash code.
+   Otherwise, compute the hash code.  */
+
 static ASSERTION_HASHNODE *
 assertion_install (name, len, hash)
      U_CHAR *name;
@@ -6464,16 +6507,15 @@ assertion_install (name, len, hash)
   return hp;
 }
 
-/*
- * find the most recent hash node for name name (ending with first
- * non-identifier char) installed by install
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
+/* Find the most recent hash node for name name (ending with first
+   non-identifier char) installed by install
+
+   If LEN is >= 0, it is the length of the name.
+   Otherwise, compute the length by scanning the entire name.
+
+   If HASH is >= 0, it is the precomputed hash code.
+   Otherwise, compute the hash code.  */
+
 static ASSERTION_HASHNODE *
 assertion_lookup (name, len, hash)
      U_CHAR *name;
@@ -6501,8 +6543,8 @@ delete_assertion (hp)
   if (hp->next != NULL)
     hp->next->prev = hp->prev;
 
-  /* make sure that the bucket chain header that
-     the deleted guy was on points to the right thing afterwards. */
+  /* Make sure that the bucket chain header that the deleted guy was
+     on points to the right thing afterwards.  */
   if (hp == *hp->bucket_hdr)
     *hp->bucket_hdr = hp->next;
 
@@ -6632,8 +6674,7 @@ do_line (buf, limit, op, keyword)
       }
     }
 
-    hash_bucket =
-      &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
+    hash_bucket = &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
     for (hp = *hash_bucket; hp != NULL; hp = hp->next)
       if (hp->length == fname_length &&
          bcmp (hp->value.cpval, fname, fname_length) == 0) {
@@ -6661,11 +6702,9 @@ do_line (buf, limit, op, keyword)
   return 0;
 }
 
-/*
- * remove the definition of a symbol from the symbol table.
- * according to un*x /lib/cpp, it is not an error to undef
- * something that has no definitions, so it isn't one here either.
- */
+/* Remove the definition of a symbol from the symbol table.
+   according to un*x /lib/cpp, it is not an error to undef
+   something that has no definitions, so it isn't one here either.  */
 
 static int
 do_undef (buf, limit, op, keyword)
@@ -6703,11 +6742,9 @@ do_undef (buf, limit, op, keyword)
   return 0;
 }
 \f
-/*
- * Report an error detected by the program we are processing.
- * Use the text of the line in the error message.
- * (We use error because it prints the filename & line#.)
- */
+/* Report an error detected by the program we are processing.
+   Use the text of the line in the error message.
+   (We use error because it prints the filename & line#.)  */
 
 static int
 do_error (buf, limit, op, keyword)
@@ -6716,7 +6753,7 @@ do_error (buf, limit, op, keyword)
      struct directive *keyword;
 {
   int length = limit - buf;
-  U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
+  U_CHAR *copy = (U_CHAR *) alloca (length + 1);
   bcopy ((char *) buf, (char *) copy, length);
   copy[length] = 0;
   SKIP_WHITE_SPACE (copy);
@@ -6724,11 +6761,9 @@ do_error (buf, limit, op, keyword)
   return 0;
 }
 
-/*
- * Report a warning detected by the program we are processing.
- * Use the text of the line in the warning message, then continue.
- * (We use error because it prints the filename & line#.)
- */
+/* Report a warning detected by the program we are processing.
+   Use the text of the line in the warning message, then continue.
+   (We use error because it prints the filename & line#.)  */
 
 static int
 do_warning (buf, limit, op, keyword)
@@ -6737,11 +6772,13 @@ do_warning (buf, limit, op, keyword)
      struct directive *keyword;
 {
   int length = limit - buf;
-  U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
+  U_CHAR *copy = (U_CHAR *) alloca (length + 1);
   bcopy ((char *) buf, (char *) copy, length);
   copy[length] = 0;
   SKIP_WHITE_SPACE (copy);
-  warning ("#warning %s", copy);
+  /* Use `pedwarn' not `warning', because #warning isn't in the C Standard;
+     if -pedantic-errors is given, #warning should cause an error.  */
+  pedwarn ("#warning %s", copy);
   return 0;
 }
 
@@ -6844,10 +6881,8 @@ do_pragma (buf, limit, op, keyword)
 /* This was a fun hack, but #pragma seems to start to be useful.
    By failing to recognize it, we pass it through unchanged to cc1.  */
 
-/*
- * the behavior of the #pragma directive is implementation defined.
- * this implementation defines it as follows.
- */
+/* The behavior of the #pragma directive is implementation defined.
+   this implementation defines it as follows.  */
 
 static int
 do_pragma ()
@@ -6884,18 +6919,16 @@ do_sccs (buf, limit, op, keyword)
 
 #endif /* defined (SCCS_DIRECTIVE) */
 \f
-/*
- * handle #if directive by
- *   1) inserting special `defined' keyword into the hash table
- *     that gets turned into 0 or 1 by special_symbol (thus,
- *     if the luser has a symbol called `defined' already, it won't
- *      work inside the #if directive)
- *   2) rescan the input into a temporary output buffer
- *   3) pass the output buffer to the yacc parser and collect a value
- *   4) clean up the mess left from steps 1 and 2.
- *   5) call conditional_skip to skip til the next #endif (etc.),
- *      or not, depending on the value from step 3.
- */
+/* Handle #if directive by
+     1) inserting special `defined' keyword into the hash table
+       that gets turned into 0 or 1 by special_symbol (thus,
+       if the luser has a symbol called `defined' already, it won't
+        work inside the #if directive)
+     2) rescan the input into a temporary output buffer
+     3) pass the output buffer to the yacc parser and collect a value
+     4) clean up the mess left from steps 1 and 2.
+     5) call conditional_skip to skip til the next #endif (etc.),
+        or not, depending on the value from step 3.  */
 
 static int
 do_if (buf, limit, op, keyword)
@@ -6911,10 +6944,8 @@ do_if (buf, limit, op, keyword)
   return 0;
 }
 
-/*
- * handle a #elif directive by not changing  if_stack  either.
- * see the comment above do_else.
- */
+/* Handle a #elif directive by not changing  if_stack  either.
+   see the comment above do_else.  */
 
 static int
 do_elif (buf, limit, op, keyword)
@@ -6932,8 +6963,8 @@ do_elif (buf, limit, op, keyword)
     if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
       error ("`#elif' after `#else'");
       fprintf (stderr, " (matches line %d", if_stack->lineno);
-      if (if_stack->fname != NULL && ip->fname != NULL &&
-         strcmp (if_stack->fname, ip->nominal_fname) != 0)
+      if (if_stack->fname != NULL && ip->fname != NULL
+         && strcmp (if_stack->fname, ip->nominal_fname) != 0)
        fprintf (stderr, ", file %s", if_stack->fname);
       fprintf (stderr, ")\n");
     }
@@ -6954,10 +6985,9 @@ do_elif (buf, limit, op, keyword)
   return 0;
 }
 
-/*
- * evaluate a #if expression in BUF, of length LENGTH,
- * then parse the result as a C expression and return the value as an int.
- */
+/* Evaluate a #if expression in BUF, of length LENGTH, then parse the
+   result as a C expression and return the value as an int.  */
+
 static HOST_WIDE_INT
 eval_if_expression (buf, length)
      U_CHAR *buf;
@@ -6982,11 +7012,9 @@ eval_if_expression (buf, length)
   return value;
 }
 
-/*
- * routine to handle ifdef/ifndef.  Try to look up the symbol,
- * then do or don't skip to the #endif/#else/#elif depending
- * on what directive is actually being processed.
- */
+/* routine to handle ifdef/ifndef.  Try to look up the symbol, then do
+   or don't skip to the #endif/#else/#elif depending on what directive
+   is actually being processed.  */
 
 static int
 do_xifdef (buf, limit, op, keyword)
@@ -7054,9 +7082,9 @@ do_xifdef (buf, limit, op, keyword)
 
     if (pcp_outfile) {
       /* Output a precondition for this macro.  */
-      if (hp &&
-         (hp->type == T_CONST
-          || (hp->type == T_MACRO && hp->value.defn->predefined)))
+      if (hp
+         && (hp->type == T_CONST
+             || (hp->type == T_MACRO && hp->value.defn->predefined)))
        fprintf (pcp_outfile, "#define %s\n", hp->name);
       else {
        U_CHAR *cp = buf;
@@ -7112,11 +7140,10 @@ conditional_skip (ip, skip, type, control_macro, op)
   }
 }
 
-/*
- * skip to #endif, #else, or #elif.  adjust line numbers, etc.
- * leaves input ptr at the sharp sign found.
- * If ANY is nonzero, return at next directive of any sort.
- */
+/* Skip to #endif, #else, or #elif.  adjust line numbers, etc.
+   Leaves input ptr at the sharp sign found.
+   If ANY is nonzero, return at next directive of any sort.  */
+     
 static void
 skip_if_group (ip, any, op)
      FILE_BUF *ip;
@@ -7404,12 +7431,10 @@ skip_if_group (ip, any, op)
   }
 }
 
-/*
- * handle a #else directive.  Do this by just continuing processing
- * without changing  if_stack ;  this is so that the error message
- * for missing #endif's etc. will point to the original #if.  It
- * is possible that something different would be better.
- */
+/* Handle a #else directive.  Do this by just continuing processing
+   without changing  if_stack ;  this is so that the error message
+   for missing #endif's etc. will point to the original #if.  It
+   is possible that something different would be better.  */
 
 static int
 do_else (buf, limit, op, keyword)
@@ -7452,9 +7477,7 @@ do_else (buf, limit, op, keyword)
   return 0;
 }
 
-/*
- * unstack after #endif directive
- */
+/* Unstack after #endif directive.  */
 
 static int
 do_endif (buf, limit, op, keyword)
@@ -7516,7 +7539,8 @@ do_endif (buf, limit, op, keyword)
 
 /* When an #else or #endif is found while skipping failed conditional,
    if -pedantic was specified, this is called to warn about text after
-   the directive name.  P points to the first char after the directive name.  */
+   the directive name.  P points to the first char after the directive
+   name.  */
 
 static void
 validate_else (p, limit)
@@ -7564,9 +7588,10 @@ validate_else (p, limit)
    counter is not sufficient to deal with newlines in the string.
 
    If NOWARN is nonzero, don't warn about slash-star inside a comment.
-   This feature is useful when processing a comment that is going to be
-   processed or was processed at another point in the preprocessor,
-   to avoid a duplicate warning.  Likewise for unterminated comment errors.  */
+   This feature is useful when processing a comment that is going to
+   be processed or was processed at another point in the preprocessor,
+   to avoid a duplicate warning.  Likewise for unterminated comment
+   errors.  */
 
 static U_CHAR *
 skip_to_end_of_comment (ip, line_counter, nowarn)
@@ -7588,8 +7613,6 @@ skip_to_end_of_comment (ip, line_counter, nowarn)
   }
   if (cplusplus_comments && bp[-1] == '/') {
     for (; bp < limit; bp++) {
-      if (op)
-       *op->bufp++ = *bp;
       if (*bp == '\n') {
        if (bp[-1] != '\\')
          break;
@@ -7600,6 +7623,8 @@ skip_to_end_of_comment (ip, line_counter, nowarn)
        if (op)
          ++op->lineno;
       }
+      if (op)
+       *op->bufp++ = *bp;
     }
     ip->bufp = bp;
     return bp;
@@ -7644,22 +7669,21 @@ skip_to_end_of_comment (ip, line_counter, nowarn)
   return bp;
 }
 
-/*
- * Skip over a quoted string.  BP points to the opening quote.
- * Returns a pointer after the closing quote.  Don't go past LIMIT.
- * START_LINE is the line number of the starting point (but it need
- * not be valid if the starting point is inside a macro expansion).
- *
- * The input stack state is not changed.
- *
- * If COUNT_NEWLINES is nonzero, it points to an int to increment
- * for each newline passed.
- *
- * If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
- * if we pass a backslash-newline.
- *
- * If EOFP is nonzero, set *EOFP to 1 if the string is unterminated.
- */
+/* Skip over a quoted string.  BP points to the opening quote.
+   Returns a pointer after the closing quote.  Don't go past LIMIT.
+   START_LINE is the line number of the starting point (but it need
+   not be valid if the starting point is inside a macro expansion).
+
+   The input stack state is not changed.
+
+   If COUNT_NEWLINES is nonzero, it points to an int to increment
+   for each newline passed.
+
+   If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
+   if we pass a backslash-newline.
+
+   If EOFP is nonzero, set *EOFP to 1 if the string is unterminated.  */
+
 static U_CHAR *
 skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
      register U_CHAR *bp;
@@ -7701,7 +7725,7 @@ skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p,
     } else if (c == '\n') {
       if (traditional) {
        /* Unterminated strings and character constants are 'valid'.  */
-       bp--;   /* Don't consume the newline. */
+       bp--;   /* Don't consume the newline.  */
        if (eofp)
          *eofp = 1;
        break;
@@ -7731,6 +7755,7 @@ skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p,
 
 /* Place into DST a quoted string representing the string SRC.
    Return the address of DST's terminating null.  */
+
 static char *
 quote_string (dst, src)
      char *dst, *src;
@@ -7815,13 +7840,11 @@ skip_paren_group (ip)
   return p;
 }
 \f
-/*
- * write out a #line directive, for instance, after an #include file.
- * If CONDITIONAL is nonzero, we can omit the #line if it would
- * appear to be a no-op, and we can output a few newlines instead
- * if we want to increase the line number by a small amount.
- * FILE_CHANGE says whether we are entering a file, leaving, or neither.
- */
+/* Write out a #line directive, for instance, after an #include file.
+   If CONDITIONAL is nonzero, we can omit the #line if it would
+   appear to be a no-op, and we can output a few newlines instead
+   if we want to increase the line number by a small amount.
+   FILE_CHANGE says whether we are entering a file, leaving, or neither.  */
 
 static void
 output_line_directive (ip, op, conditional, file_change)
@@ -7855,9 +7878,9 @@ output_line_directive (ip, op, conditional, file_change)
     }
   }
 
-  /* Don't output a line number of 0 if we can help it.  */
-  if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length
-      && *ip->bufp == '\n') {
+  /* Output a positive line number if possible.  */
+  while (ip->lineno <= 0 && ip->bufp - ip->buf < ip->length
+        && *ip->bufp == '\n') {
     ip->lineno++;
     ip->bufp++;
   }
@@ -7977,7 +8000,7 @@ macroexpand (hp, op)
       if (rest_args)
        continue;
       if (i < nargs || (nargs == 0 && i == 0)) {
-       /* if we are working on last arg which absorbs rest of args... */
+       /* If we are working on last arg which absorbs rest of args...  */
        if (i == nargs - 1 && defn->rest_args)
          rest_args = 1;
        parse_error = macarg (&args[i], rest_args);
@@ -8255,8 +8278,8 @@ macroexpand (hp, op)
          abort ();
       }
 
-      /* if there is anything left of the definition
-        after handling the arg list, copy that in too. */
+      /* If there is anything left of the definition after handling
+        the arg list, copy that in too.  */
 
       for (i = offset; i < defn->length; i++) {
        /* if we've reached the end of the macro */
@@ -8312,11 +8335,9 @@ macroexpand (hp, op)
   }
 }
 \f
-/*
- * Parse a macro argument and store the info on it into *ARGPTR.
- * REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
- * Return nonzero to indicate a syntax error.
- */
+/* Parse a macro argument and store the info on it into *ARGPTR.
+   REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
+   Return nonzero to indicate a syntax error.  */
 
 static char *
 macarg (argptr, rest_args)
@@ -8714,9 +8735,8 @@ change_newlines (start, length)
   return obp - start;
 }
 \f
-/*
- * my_strerror - return the descriptive text associated with an `errno' code.
- */
+/* my_strerror - return the descriptive text associated with an
+   `errno' code.  */
 
 char *
 my_strerror (errnum)
@@ -8747,9 +8767,7 @@ my_strerror (errnum)
   return result;
 }
 
-/*
- * error - print error message and increment count of errors.
- */
+/* error - print error message and increment count of errors.  */
 
 void
 error (PRINTF_ALIST (msg))
@@ -8938,7 +8956,7 @@ vwarning_with_line (line, msg, args)
   fprintf (stderr, "\n");
 }
 
-/* print an error message and maybe count it.  */
+/* Print an error message and maybe count it.  */
 
 void
 pedwarn (PRINTF_ALIST (msg))
@@ -9086,6 +9104,7 @@ line_for_error (line)
 
 /* You might think void was cleaner for the return type,
    but that would get type mismatch in check_expand in strict ANSI.  */
+
 static int
 grow_outbuf (obuf, needed)
      register FILE_BUF *obuf;
@@ -9127,8 +9146,9 @@ grow_outbuf (obuf, needed)
  * Otherwise, compute the length by scanning the entire name.
  *
  * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
+ * Otherwise, compute the hash code. 
  */
+
 static HASHNODE *
 install (name, len, type, value, hash)
      U_CHAR *name;
@@ -9182,6 +9202,7 @@ install (name, len, type, value, hash)
  * If HASH is >= 0, it is the precomputed hash code.
  * Otherwise, compute the hash code.
  */
+
 HASHNODE *
 lookup (name, len, hash)
      U_CHAR *name;
@@ -9232,8 +9253,8 @@ delete_macro (hp)
   if (hp->next != NULL)
     hp->next->prev = hp->prev;
 
-  /* make sure that the bucket chain header that
-     the deleted guy was on points to the right thing afterwards. */
+  /* Make sure that the bucket chain header that the deleted guy was
+     on points to the right thing afterwards.  */
   if (hp == *hp->bucket_hdr)
     *hp->bucket_hdr = hp->next;
 
@@ -9256,6 +9277,7 @@ delete_macro (hp)
  * return hash function on name.  must be compatible with the one
  * computed a step at a time, elsewhere
  */
+
 static int
 hashf (name, len, hashsize)
      register U_CHAR *name;
@@ -9272,6 +9294,7 @@ hashf (name, len, hashsize)
 \f
 
 /* Dump the definition of a single macro HP to OF.  */
+
 static void
 dump_single_macro (hp, of)
      register HASHNODE *hp;
@@ -9453,8 +9476,8 @@ initialize_char_syntax ()
     is_idchar[i] = 1;
   is_idchar['_'] = 1;
   is_idstart['_'] = 1;
-  is_idchar['$'] = dollars_in_ident;
-  is_idstart['$'] = dollars_in_ident;
+  is_idchar['$'] = 1;
+  is_idstart['$'] = 1;
 
   /* horizontal space table */
   is_hor_space[' '] = 1;
@@ -9752,8 +9775,8 @@ make_assertion (option, str)
   for (kt = directive_table; kt->type != T_ASSERT; kt++)
     ;
 
-  /* pass NULL as output ptr to do_define since we KNOW it never
-     does any output.... */
+  /* Pass NULL as output ptr to do_define since we KNOW it never does
+     any output....  */
   do_assert (buf, buf + strlen ((char *) buf) , NULL_PTR, kt);
   --indepth;
 }
@@ -10019,13 +10042,14 @@ savestring (input)
 \f
 #ifdef VMS
 
-/* Under VMS we need to fix up the "include" specification
-   filename so that everything following the 1st slash is
-   changed into its correct VMS file specification. */
+/* Under VMS we need to fix up the "include" specification filename so
+   that everything following the 1st slash is changed into its correct
+   VMS file specification.  */
 
 static void
-hack_vms_include_specification (fname)
+hack_vms_include_specification (fname, vaxc_include)
      char *fname;
+     int vaxc_include;
 {
   register char *cp, *cp1, *cp2;
   int f, check_filename_before_returning;
@@ -10039,7 +10063,7 @@ hack_vms_include_specification (fname)
    * Check if we have a vax-c style '#include filename'
    * and add the missing .h
    */
-  if (!index (cp,'.'))
+  if (vaxc_include && !index (cp,'.'))
     strcat (cp, ".h");
 
   cp2 = Local;                 /* initialize */
@@ -10053,7 +10077,7 @@ hack_vms_include_specification (fname)
      needed to get things working properly.
      
      If no device is specified, then the first directory name is taken to be
-     a device name (or a rooted logical). */
+     a device name (or a rooted logical).  */
 
   /* See if we found that 1st slash */
   if (cp == 0) return;         /* Nothing to do!!! */
@@ -10103,14 +10127,14 @@ hack_vms_include_specification (fname)
 
   /* If there are no other slashes then the filename will be
      in the "root" directory.  Otherwise, we need to add
-     directory specifications. */
+     directory specifications.  */
   if (index (cp1, '/') == 0) {
     /* Just add "000000]" as the directory string */
     strcpy (cp2, "000000]");
     cp2 += strlen (cp2);
     check_filename_before_returning = 1; /* we might need to fool with this later */
   } else {
-    /* As long as there are still subdirectories to add, do them. */
+    /* As long as there are still subdirectories to add, do them.  */
     while (index (cp1, '/') != 0) {
       /* If this token is "." we can ignore it */
       if ((cp1[0] == '.') && (cp1[1] == '/')) {
@@ -10139,7 +10163,7 @@ hack_vms_include_specification (fname)
   /* Now add the filename */
   while (*cp1) *cp2++ = *cp1++;
   *cp2 = 0;
-  /* Now append it to the original VMS spec. */
+  /* Now append it to the original VMS spec.  */
   strcpy (cp, Local);
 
   /* If we put a [000000] in the filename, try to open it first. If this fails,
@@ -10166,67 +10190,13 @@ hack_vms_include_specification (fname)
 \f
 #ifdef VMS
 
-/* These are the read/write replacement routines for
-   VAX-11 "C".  They make read/write behave enough
-   like their UNIX counterparts that CCCP will work */
-
-static int
-read (fd, buf, size)
-     int fd;
-     char *buf;
-     int size;
-{
-#undef read    /* Get back the REAL read routine */
-  register int i;
-  register int total = 0;
-
-  /* Read until the buffer is exhausted */
-  while (size > 0) {
-    /* Limit each read to 32KB */
-    i = (size > (32*1024)) ? (32*1024) : size;
-    i = read (fd, buf, i);
-    if (i <= 0) {
-      if (i == 0) return (total);
-      return (i);
-    }
-    /* Account for this read */
-    total += i;
-    buf += i;
-    size -= i;
-  }
-  return (total);
-}
-
-static int
-write (fd, buf, size)
-     int fd;
-     char *buf;
-     int size;
-{
-#undef write   /* Get back the REAL write routine */
-  int i;
-  int j;
-
-  /* Limit individual writes to 32Kb */
-  i = size;
-  while (i > 0) {
-    j = (i > (32*1024)) ? (32*1024) : i;
-    if (write (fd, buf, j) < 0) return (-1);
-    /* Account for the data written */
-    buf += j;
-    i -= j;
-  }
-  return (size);
-}
-
 /* The following wrapper functions supply additional arguments to the VMS
    I/O routines to optimize performance with file handling.  The arguments
    are:
      "mbc=16" - Set multi-block count to 16 (use a 8192 byte buffer).
      "deq=64" - When extending the file, extend it in chunks of 32Kbytes.
      "fop=tef"- Truncate unused portions of file when closing file.
-     "shr=nil"- Disallow file sharing while file is open.
- */
+     "shr=nil"- Disallow file sharing while file is open.  */
 
 static FILE *
 freopen (fname, type, oldfile)