cpplib: more namespace work

Zack Weinberg zack@wolery.cumb.org
Wed Mar 8 15:35:00 GMT 2000


This takes most of the internal declarations out of cpplib.h - they
are moved to cpphash.h, or individual source files.

Compiles with no regressions, and does not break fix-header.  It may
break --enable-c-cpplib; as mentioned previously, I don't care right
now.

Also, _cpp_parse_expr now returns true or false, not the actual value;
that's all we need and it avoids passing HOST_WIDEST_INTs around.

zw

	* Makefile.in (LIBCPP_DEPS): New macro.
	(cpplib.o, cpphash.o, cpperror.o, cppexp.o, cppfiles.o): Use
	it to declare deps.
	* cpperror.c: Include cpphash.h.
	* cppexp.c: Include cpphash.h.  Remove MULTIBYTE_CHARS
	dingleberry.
	(lex): Don't use CPP_WARN_UNDEF.
	(_cpp_parse_expr): Return an int, the truth value.
	* cppfiles.c: Include cpphash.h.
	(_cpp_merge_include_chains): Move to cppinit.c and make static.
	* cppinit.c (include_defaults_array): Disentangle.
	(cpp_cleanup): Don't free the if stack here.
	(cpp_finish): Pop off all buffers, not just one.
	* cpplib.c (eval_if_expr): Return int.
	(do_xifdef): Rename do_ifdef.
	(handle_directive): Don't use CPP_PREPROCESSED.	
	(cpp_get_token): Don't use CPP_C89.
	* fix-header.c: Don't use CPP_OPTIONS.

	* cpplib.h: Move U_CHAR, enum node_type, struct
	file_name_list, struct ihash, is_idchar, is_idstart,
	is_numchar, is_numstart, is_hspace, is_space, CPP_BUF_PEEK,
	CPP_BUF_GET, CPP_FORWARD, CPP_PUTS, CPP_PUTS_Q, CPP_PUTC,
	CPP_PUTC_Q, CPP_NUL_TERMINATE, CPP_NUL_TERMINATE_Q,
	CPP_BUMP_BUFFER_LINE, CPP_BUMP_LINE, CPP_PREV_BUFFER,
	CPP_PRINT_DEPS, CPP_TRADITIONAL, CPP_PEDANTIC, and prototypes
	of _cpp_simplify_pathname, _cpp_find_include_file,
	_cpp_read_include_file, and _cpp_parse_expr to cpphash.h.
	Move struct if_stack to cpplib.c.  Move struct cpp_pending to
	cppinit.c.
	Change all uses of U_CHAR to be unsigned char instead.
	Delete CPP_WARN_UNDEF, CPP_C89, and CPP_PREPROCESSED.

===================================================================
Index: Makefile.in
--- Makefile.in	2000/03/06 18:05:52	1.394
+++ Makefile.in	2000/03/08 23:20:36
@@ -2025,6 +2025,8 @@ LIBCPP_OBJS =	cpplib.o cpphash.o cpperro
 		cppinit.o cppulp.o mkdeps.o \
 		prefix.o version.o mbchar.o @extra_cpp_objs@
 
+LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h
+
 # All the other archives built/used by this makefile are for targets.  This
 # one is strictly for the host.
 #
@@ -2040,11 +2042,11 @@ cppmain$(exeext): cppmain.o intl.o libcp
 cppmain.o: cppmain.c $(CONFIG_H) cpplib.h intl.h system.h
 
 cppulp.o:  cppulp.c  $(CONFIG_H) system.h output.h
-cpplib.o:  cpplib.c  $(CONFIG_H) cpplib.h intl.h system.h cpphash.h mkdeps.h
-cpphash.o: cpphash.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h version.h
-cpperror.o: cpperror.c $(CONFIG_H) cpplib.h intl.h system.h
-cppexp.o:   cppexp.c   $(CONFIG_H) cpplib.h intl.h system.h
-cppfiles.o: cppfiles.c $(CONFIG_H) cpplib.h intl.h system.h
+cpplib.o:  cpplib.c  $(CONFIG_H) $(LIBCPP_DEPS) mkdeps.h
+cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) version.h
+cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
+cppexp.o:   cppexp.c   $(CONFIG_H) $(LIBCPP_DEPS)
+cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS)
 
 cppinit.o:  cppinit.c $(CONFIG_H) cpplib.h intl.h system.h \
 		cpphash.h prefix.h output.h Makefile version.h mkdeps.h
===================================================================
Index: cpperror.c
--- cpperror.c	2000/03/08 20:37:23	1.27
+++ cpperror.c	2000/03/08 23:20:36
@@ -26,6 +26,7 @@ Foundation, 59 Temple Place - Suite 330,
 #include "config.h"
 #include "system.h"
 #include "cpplib.h"
+#include "cpphash.h"
 #include "intl.h"
 
 static void print_containing_files	PARAMS ((cpp_reader *, cpp_buffer *));
===================================================================
Index: cppexp.c
--- cppexp.c	2000/03/07 23:11:05	1.37
+++ cppexp.c	2000/03/08 23:20:36
@@ -27,11 +27,8 @@ Written by Per Bothner 1994.  */
 #include "config.h"
 #include "system.h"
 #include "cpplib.h"
+#include "cpphash.h"
 
-#ifdef MULTIBYTE_CHARS
-#include <locale.h>
-#endif
-
 #ifndef CHAR_TYPE_SIZE
 #define CHAR_TYPE_SIZE BITS_PER_UNIT
 #endif
@@ -453,7 +450,7 @@ lex (pfile, skip_evaluation)
       op.unsignedp = 0;
       op.value = 0;
 
-      if (CPP_WARN_UNDEF (pfile) && !skip_evaluation)
+      if (CPP_OPTIONS (pfile)->warn_undef && !skip_evaluation)
 	cpp_warning (pfile, "`%.*s' is not defined",
 		     (int) (tok_end - tok_start), tok_start);
       return op;
@@ -669,9 +666,9 @@ right_shift (pfile, a, unsignedp, b)
   ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2)
 
 /* Parse and evaluate a C expression, reading from PFILE.
-   Returns the value of the expression.  */
+   Returns the truth value of the expression.  */
 
-HOST_WIDEST_INT
+int
 _cpp_parse_expr (pfile)
      cpp_reader *pfile;
 {
@@ -1004,7 +1001,7 @@ _cpp_parse_expr (pfile)
 	    cpp_ice (pfile, "unbalanced stack in #if expression");
 	  if (stack != init_stack)
 	    free (stack);
-	  return top->value;
+	  return (top->value != 0);
 	}
       top++;
       
===================================================================
Index: cppfiles.c
--- cppfiles.c	2000/03/08 20:37:23	1.42
+++ cppfiles.c	2000/03/08 23:20:36
@@ -27,6 +27,7 @@ Foundation, 59 Temple Place - Suite 330,
 #include "config.h"
 #include "system.h"
 #include "cpplib.h"
+#include "cpphash.h"
 #include "intl.h"
 
 static IHASH *include_hash	PARAMS ((cpp_reader *, const char *, int));
@@ -49,150 +50,9 @@ static U_CHAR *find_position	PARAMS ((U_
 static void hack_vms_include_specification PARAMS ((char *));
 #endif
 
-/* Windows does not natively support inodes, and neither does MSDOS.
-   Cygwin's emulation can generate non-unique inodes, so don't use it.
-   VMS has non-numeric inodes. */
-#ifdef VMS
-#define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
-#elif (defined _WIN32 && ! defined (_UWIN)) \
-       || defined __MSDOS__
-#define INO_T_EQ(a, b) 0
-#else
-#define INO_T_EQ(a, b) ((a) == (b))
-#endif
-
 #ifndef INCLUDE_LEN_FUDGE
 #define INCLUDE_LEN_FUDGE 0
 #endif
-
-/* Merge the four include chains together in the order quote, bracket,
-   system, after.  Remove duplicate dirs (as determined by
-   INO_T_EQ()).  The system_include and after_include chains are never
-   referred to again after this function; all access is through the
-   bracket_include path.
-
-   For the future: Check if the directory is empty (but
-   how?) and possibly preload the include hash. */
-
-void
-_cpp_merge_include_chains (opts)
-     struct cpp_options *opts;
-{
-  struct file_name_list *prev, *cur, *other;
-  struct file_name_list *quote, *brack, *systm, *after;
-  struct file_name_list *qtail, *btail, *stail, *atail;
-
-  qtail = opts->pending->quote_tail;
-  btail = opts->pending->brack_tail;
-  stail = opts->pending->systm_tail;
-  atail = opts->pending->after_tail;
-
-  quote = opts->pending->quote_head;
-  brack = opts->pending->brack_head;
-  systm = opts->pending->systm_head;
-  after = opts->pending->after_head;
-
-  /* Paste together bracket, system, and after include chains. */
-  if (stail)
-    stail->next = after;
-  else
-    systm = after;
-  if (btail)
-    btail->next = systm;
-  else
-    brack = systm;
-
-  /* This is a bit tricky.
-     First we drop dupes from the quote-include list.
-     Then we drop dupes from the bracket-include list.
-     Finally, if qtail and brack are the same directory,
-     we cut out qtail.
-
-     We can't just merge the lists and then uniquify them because
-     then we may lose directories from the <> search path that should
-     be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
-     safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
-     -Ibar -I- -Ifoo -Iquux.
-
-     Note that this algorithm is quadratic in the number of -I switches,
-     which is acceptable since there aren't usually that many of them.  */
-
-  for (cur = quote, prev = NULL; cur; cur = cur->next)
-    {
-      for (other = quote; other != cur; other = other->next)
-        if (INO_T_EQ (cur->ino, other->ino)
-	    && cur->dev == other->dev)
-          {
-	    if (opts->verbose)
-	      fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
-		       cur->name);
-
-	    prev->next = cur->next;
-	    free (cur->name);
-	    free (cur);
-	    cur = prev;
-	    break;
-	  }
-      prev = cur;
-    }
-  qtail = prev;
-
-  for (cur = brack; cur; cur = cur->next)
-    {
-      for (other = brack; other != cur; other = other->next)
-        if (INO_T_EQ (cur->ino, other->ino)
-	    && cur->dev == other->dev)
-          {
-	    if (opts->verbose)
-	      fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
-		       cur->name);
-
-	    prev->next = cur->next;
-	    free (cur->name);
-	    free (cur);
-	    cur = prev;
-	    break;
-	  }
-      prev = cur;
-    }
-
-  if (quote)
-    {
-      if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
-        {
-	  if (quote == qtail)
-	    {
-	      if (opts->verbose)
-		fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
-			 quote->name);
-
-	      free (quote->name);
-	      free (quote);
-	      quote = brack;
-	    }
-	  else
-	    {
-	      cur = quote;
-	      while (cur->next != qtail)
-		  cur = cur->next;
-	      cur->next = brack;
-	      if (opts->verbose)
-		fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
-			 qtail->name);
-
-	      free (qtail->name);
-	      free (qtail);
-	    }
-	}
-      else
-	  qtail->next = brack;
-    }
-  else
-      quote = brack;
-
-  opts->quote_include = quote;
-  opts->bracket_include = brack;
-}
 
 /* Look up or add an entry to the table of all includes.  This table
  is indexed by the name as it appears in the #include line.  The
===================================================================
Index: cpphash.h
--- cpphash.h	2000/03/08 20:37:23	1.19
+++ cpphash.h	2000/03/08 23:20:36
@@ -1,5 +1,5 @@
-/* Part of CPP library.  (Macro hash table support.)
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Part of CPP library.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -15,9 +15,15 @@ You should have received a copy of the G
 along with this program; if not, write to the Free Software
 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+/* This header defines all the internal data structures and functions
+   that need to be visible across files.  It's called cpphash.h for
+   historical reasons.  */
+
 #ifndef __GCC_CPPHASH__
 #define __GCC_CPPHASH__
 
+typedef unsigned char U_CHAR;
+
 /* Structure allocated for every #define.  For a simple replacement
    such as
    	#define foo bar ,
@@ -70,6 +76,50 @@ struct definition
   U_CHAR *argnames;
 };
 
+/* The structure of a node in the hash table.  The hash table
+   has entries for all tokens defined by #define commands (type T_MACRO),
+   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. */
+
+/* different flavors of hash nodes --- also used in keyword table */
+enum node_type
+{
+  T_DEFINE = 1,	   /* `#define' */
+  T_INCLUDE,	   /* `#include' */
+  T_INCLUDE_NEXT,  /* `#include_next' */
+  T_IMPORT,        /* `#import' */
+  T_IFDEF,	   /* `#ifdef' */
+  T_IFNDEF,	   /* `#ifndef' */
+  T_IF,		   /* `#if' */
+  T_ELSE,	   /* `#else' */
+  T_PRAGMA,	   /* `#pragma' */
+  T_ELIF,	   /* `#elif' */
+  T_UNDEF,	   /* `#undef' */
+  T_LINE,	   /* `#line' */
+  T_ERROR,	   /* `#error' */
+  T_WARNING,	   /* `#warning' */
+  T_ENDIF,	   /* `#endif' */
+  T_SCCS,	   /* `#sccs' */
+  T_IDENT,	   /* `#ident' */
+  T_ASSERT,	   /* `#assert' */
+  T_UNASSERT,	   /* `#unassert', */
+  T_SPECLINE,	   /* `__LINE__' */
+  T_DATE,	   /* `__DATE__' */
+  T_FILE,	   /* `__FILE__' */
+  T_BASE_FILE,	   /* `__BASE_FILE__' */
+  T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
+  T_VERSION,	   /* `__VERSION__' */
+  T_TIME,	   /* `__TIME__' */
+  T_STDC,	   /* `__STDC__' */
+  T_CONST,	   /* Constant string, used by `__SIZE_TYPE__' etc */
+  T_MACRO,	   /* macro defined by `#define' */
+  T_DISABLED,	   /* macro temporarily turned off for rescan */
+  T_POISON,	   /* macro defined with `#pragma poison' */
+  T_UNUSED	   /* Used for something not defined.  */
+};
+
 /* different kinds of things that can appear in the value field
    of a hash node. */
 union hashval
@@ -80,7 +130,8 @@ union hashval
 };
 
 typedef struct hashnode HASHNODE;
-struct hashnode {
+struct hashnode
+{
   struct hashnode *next;	/* double links for easy deletion */
   struct hashnode *prev;
   struct hashnode **bucket_hdr;	/* also, a back pointer to this node's hash
@@ -92,6 +143,110 @@ struct hashnode {
   union hashval value;		/* pointer to expansion, or whatever */
 };
 
+/* List of directories to look for include files in. */
+struct file_name_list
+{
+  struct file_name_list *next;
+  struct file_name_list *alloc; /* for the cache of
+				   current directory entries */
+  char *name;
+  unsigned int nlen;
+  /* We use these to tell if the directory mentioned here is a duplicate
+     of an earlier directory on the search path. */
+  ino_t ino;
+  dev_t dev;
+  /* If the following is nonzero, it is a C-language system include
+     directory.  */
+  int sysp;
+  /* Mapping of file names for this directory.
+     Only used on MS-DOS and related platforms. */
+  struct file_name_map *name_map;
+};
+#define ABSOLUTE_PATH ((struct file_name_list *)-1)
+
+/* This structure is used for the table of all includes.  It is
+   indexed by the `short name' (the name as it appeared in the
+   #include statement) which is stored in *nshort.  */
+struct ihash
+{
+  struct ihash *next;
+  /* Next file with the same short name but a
+     different (partial) pathname). */
+  struct ihash *next_this_file;
+
+  /* Location of the file in the include search path.
+     Used for include_next */
+  struct file_name_list *foundhere;
+  const char *name;		/* (partial) pathname of file */
+  const char *nshort;		/* name of file as referenced in #include */
+  const U_CHAR *control_macro;	/* macro, if any, preventing reinclusion -
+				   see redundant_include_p */
+  char *buf, *limit;		/* for file content cache,
+				   not yet implemented */
+};
+typedef struct ihash IHASH;
+
+/* Character classes.
+   If the definition of `numchar' looks odd to you, please look up the
+   definition of a pp-number in the C standard [section 6.4.8 of C99] */
+#define ISidnum		0x01	/* a-zA-Z0-9_ */
+#define ISidstart	0x02	/* _a-zA-Z */
+#define ISnumstart	0x04	/* 0-9 */
+#define IShspace	0x08	/* ' ' \t \f \v */
+#define ISspace		0x10	/* ' ' \t \f \v \n */
+
+#define _dollar_ok(x)	((x) == '$' && CPP_OPTIONS (pfile)->dollars_in_ident)
+
+#define is_idchar(x)	((_cpp_IStable[x] & ISidnum) || _dollar_ok(x))
+#define is_idstart(x)	((_cpp_IStable[x] & ISidstart) || _dollar_ok(x))
+#define is_numchar(x)	(_cpp_IStable[x] & ISidnum)
+#define is_numstart(x)	(_cpp_IStable[x] & ISnumstart)
+#define is_hspace(x)	(_cpp_IStable[x] & IShspace)
+#define is_space(x)	(_cpp_IStable[x] & ISspace)
+
+/* This table is constant if it can be initialized at compile time,
+   which is the case if cpp was compiled with GCC >=2.7, or another
+   compiler that supports C99.  */
+#if (GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)
+extern const unsigned char _cpp_IStable[256];
+#else
+extern unsigned char _cpp_IStable[256];
+#endif
+
+/* Macros.  */
+
+#define CPP_BUF_PEEK(BUFFER) \
+  ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF)
+#define CPP_BUF_GET(BUFFER) \
+  ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
+#define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N))
+
+/* Append string STR (of length N) to PFILE's output buffer.
+   Assume there is enough space. */
+#define CPP_PUTS_Q(PFILE, STR, N) \
+  (memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N))
+/* Append string STR (of length N) to PFILE's output buffer.  Make space. */
+#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
+/* Append character CH to PFILE's output buffer.  Assume sufficient space. */
+#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH))
+/* Append character CH to PFILE's output buffer.  Make space if need be. */
+#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
+/* Make sure PFILE->limit is followed by '\0'. */
+#define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0)
+#define CPP_NUL_TERMINATE(PFILE) (CPP_RESERVE(PFILE, 1), *(PFILE)->limit = 0)
+
+/* Advance the current line by one. */
+#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
+				    (PBUF)->line_base = (PBUF)->cur)
+#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
+#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
+
+#define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps)
+#define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)->traditional)
+#define CPP_PEDANTIC(PFILE) \
+  (CPP_OPTIONS (PFILE)->pedantic && !CPP_BUFFER (pfile)->system_header_p)
+
+/* In cpphash.c */
 extern HASHNODE *_cpp_install	  PARAMS ((cpp_reader *, const U_CHAR *, int,
 					   enum node_type, const char *));
 extern HASHNODE *_cpp_lookup	  PARAMS ((cpp_reader *, const U_CHAR *, int));
@@ -105,5 +260,15 @@ extern int _cpp_compare_defs		  PARAMS (
 extern void _cpp_macroexpand	  PARAMS ((cpp_reader *, HASHNODE *));
 extern void _cpp_dump_definition  PARAMS ((cpp_reader *, const U_CHAR *, long,
 					   DEFINITION *));
+
+/* In cppfiles.c */
+extern void _cpp_simplify_pathname	PARAMS ((char *));
+extern int _cpp_find_include_file	PARAMS ((cpp_reader *, const char *,
+						struct file_name_list *,
+						IHASH **, int *));
+extern int _cpp_read_include_file	PARAMS ((cpp_reader *, int, IHASH *));
+
+/* In cppexp.c */
+extern int _cpp_parse_expr		PARAMS ((cpp_reader *));
 
 #endif
===================================================================
Index: cppinit.c
--- cppinit.c	2000/03/08 20:37:23	1.55
+++ cppinit.c	2000/03/08 23:20:37
@@ -36,6 +36,17 @@ Foundation, 59 Temple Place - Suite 330,
 #define GET_ENV_PATH_LIST(VAR,NAME)	do { (VAR) = getenv (NAME); } while (0)
 #endif
 
+/* Windows does not natively support inodes, and neither does MSDOS.
+   Cygwin's emulation can generate non-unique inodes, so don't use it.
+   VMS has non-numeric inodes. */
+#ifdef VMS
+#define INO_T_EQ(a, b) (!memcmp (&(a), &(b), sizeof (a)))
+#elif (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
+#define INO_T_EQ(a, b) 0
+#else
+#define INO_T_EQ(a, b) ((a) == (b))
+#endif
+
 #ifndef STANDARD_INCLUDE_DIR
 #define STANDARD_INCLUDE_DIR "/usr/include"
 #endif
@@ -97,47 +108,51 @@ struct default_include
 				   C++.  */
 };
 
+#ifndef STANDARD_INCLUDE_COMPONENT
+#define STANDARD_INCLUDE_COMPONENT 0
+#endif
+
+#ifdef CROSS_COMPILE
+#undef LOCAL_INCLUDE_DIR
+#undef SYSTEM_INCLUDE_DIR
+#undef STANDARD_INCLUDE_DIR
+#else
+#undef CROSS_INCLUDE_DIR
+#endif
+
 static const struct default_include include_defaults_array[]
 #ifdef INCLUDE_DEFAULTS
 = INCLUDE_DEFAULTS;
 #else
 = {
+#ifdef GPLUSPLUS_INCLUDE_DIR
     /* Pick up GNU C++ specific include files.  */
     { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
-#ifdef CROSS_COMPILE
-    /* This is the dir for fixincludes.  Put it just before
-       the files that we fix.  */
-    { GCC_INCLUDE_DIR, "GCC", 0, 0 },
-    /* For cross-compilation, this dir name is generated
-       automatically in Makefile.in.  */
-    { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
-#ifdef TOOL_INCLUDE_DIR
-    /* This is another place that the target system's headers might be.  */
-    { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
 #endif
-#else /* not CROSS_COMPILE */
 #ifdef LOCAL_INCLUDE_DIR
-    /* This should be /usr/local/include and should come before
-       the fixincludes-fixed header files.  */
+    /* /usr/local/include comes before the fixincluded header files.  */
     { LOCAL_INCLUDE_DIR, 0, 0, 1 },
 #endif
+#ifdef GCC_INCLUDE_DIR
+    /* This is the dir for fixincludes and for gcc's private headers.  */
+    { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+#endif
+#ifdef CROSS_INCLUDE_DIR
+    /* One place the target system's headers might be.  */
+    { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
+#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.  */
+    /* Another place the target system's headers might be.  */
     { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
 #endif
-    /* This is the dir for fixincludes.  Put it just before
-       the files that we fix.  */
-    { GCC_INCLUDE_DIR, "GCC", 0, 0 },
-    /* Some systems have an extra dir of include files.  */
 #ifdef SYSTEM_INCLUDE_DIR
+    /* Some systems have an extra dir of include files.  */
     { SYSTEM_INCLUDE_DIR, 0, 0, 0 },
 #endif
-#ifndef STANDARD_INCLUDE_COMPONENT
-#define STANDARD_INCLUDE_COMPONENT 0
-#endif
+#ifdef STANDARD_INCLUDE_DIR
+    /* /usr/include comes dead last.  */
     { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
-#endif /* not CROSS_COMPILE */
+#endif
     { 0, 0, 0, 0 }
   };
 #endif /* no INCLUDE_DEFAULTS */
@@ -156,6 +171,24 @@ struct pending_option
   int undef;
 };
 
+/* The `pending' structure accumulates all the options that are not
+   actually processed until we hit cpp_start_read.  It consists of
+   several lists, one for each type of option.  We keep both head and
+   tail pointers for quick insertion. */
+struct cpp_pending
+{
+  struct pending_option *define_head, *define_tail;
+  struct pending_option *assert_head, *assert_tail;
+
+  struct file_name_list *quote_head, *quote_tail;
+  struct file_name_list *brack_head, *brack_tail;
+  struct file_name_list *systm_head, *systm_tail;
+  struct file_name_list *after_head, *after_tail;
+
+  struct pending_option *imacros_head, *imacros_tail;
+  struct pending_option *include_head, *include_tail;
+};
+
 #ifdef __STDC__
 #define APPEND(pend, list, elt) \
   do {  if (!(pend)->list##_head) (pend)->list##_head = (elt); \
@@ -178,6 +211,8 @@ static void initialize_builtins		PARAMS 
 static void append_include_chain	PARAMS ((cpp_reader *,
 						 struct cpp_pending *,
 						 char *, int, int));
+static void merge_include_chains	PARAMS ((struct cpp_options *));
+
 static void dump_special_to_buffer	PARAMS ((cpp_reader *, const char *));
 static void initialize_dependency_output PARAMS ((cpp_reader *));
 static void initialize_standard_includes PARAMS ((cpp_reader *));
@@ -341,7 +376,136 @@ append_include_chain (pfile, pend, dir, 
     }
 }
 
+/* Merge the four include chains together in the order quote, bracket,
+   system, after.  Remove duplicate dirs (as determined by
+   INO_T_EQ()).  The system_include and after_include chains are never
+   referred to again after this function; all access is through the
+   bracket_include path.
+
+   For the future: Check if the directory is empty (but
+   how?) and possibly preload the include hash. */
+
+static void
+merge_include_chains (opts)
+     struct cpp_options *opts;
+{
+  struct file_name_list *prev, *cur, *other;
+  struct file_name_list *quote, *brack, *systm, *after;
+  struct file_name_list *qtail, *btail, *stail, *atail;
+
+  qtail = opts->pending->quote_tail;
+  btail = opts->pending->brack_tail;
+  stail = opts->pending->systm_tail;
+  atail = opts->pending->after_tail;
+
+  quote = opts->pending->quote_head;
+  brack = opts->pending->brack_head;
+  systm = opts->pending->systm_head;
+  after = opts->pending->after_head;
+
+  /* Paste together bracket, system, and after include chains. */
+  if (stail)
+    stail->next = after;
+  else
+    systm = after;
+  if (btail)
+    btail->next = systm;
+  else
+    brack = systm;
+
+  /* This is a bit tricky.
+     First we drop dupes from the quote-include list.
+     Then we drop dupes from the bracket-include list.
+     Finally, if qtail and brack are the same directory,
+     we cut out qtail.
+
+     We can't just merge the lists and then uniquify them because
+     then we may lose directories from the <> search path that should
+     be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
+     safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
+     -Ibar -I- -Ifoo -Iquux.
+
+     Note that this algorithm is quadratic in the number of -I switches,
+     which is acceptable since there aren't usually that many of them.  */
+
+  for (cur = quote, prev = NULL; cur; cur = cur->next)
+    {
+      for (other = quote; other != cur; other = other->next)
+        if (INO_T_EQ (cur->ino, other->ino)
+	    && cur->dev == other->dev)
+          {
+	    if (opts->verbose)
+	      fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+		       cur->name);
+
+	    prev->next = cur->next;
+	    free (cur->name);
+	    free (cur);
+	    cur = prev;
+	    break;
+	  }
+      prev = cur;
+    }
+  qtail = prev;
+
+  for (cur = brack; cur; cur = cur->next)
+    {
+      for (other = brack; other != cur; other = other->next)
+        if (INO_T_EQ (cur->ino, other->ino)
+	    && cur->dev == other->dev)
+          {
+	    if (opts->verbose)
+	      fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+		       cur->name);
+
+	    prev->next = cur->next;
+	    free (cur->name);
+	    free (cur);
+	    cur = prev;
+	    break;
+	  }
+      prev = cur;
+    }
+
+  if (quote)
+    {
+      if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
+        {
+	  if (quote == qtail)
+	    {
+	      if (opts->verbose)
+		fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+			 quote->name);
+
+	      free (quote->name);
+	      free (quote);
+	      quote = brack;
+	    }
+	  else
+	    {
+	      cur = quote;
+	      while (cur->next != qtail)
+		  cur = cur->next;
+	      cur->next = brack;
+	      if (opts->verbose)
+		fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+			 qtail->name);
 
+	      free (qtail->name);
+	      free (qtail);
+	    }
+	}
+      else
+	  qtail->next = brack;
+    }
+  else
+      quote = brack;
+
+  opts->quote_include = quote;
+  opts->bracket_include = brack;
+}
+
+
 /* Write out a #define command for the special named MACRO_NAME
    to PFILE's token_buffer.  */
 
@@ -418,13 +582,6 @@ cpp_cleanup (pfile)
   if (pfile->deps)
     deps_free (pfile->deps);
 
-  while (pfile->if_stack)
-    {
-      IF_STACK *temp = pfile->if_stack;
-      pfile->if_stack = temp->next;
-      free (temp);
-    }
-
   for (i = ALL_INCLUDE_HASHSIZE; --i >= 0; )
     {
       IHASH *imp, *next;
@@ -723,7 +880,7 @@ cpp_start_read (pfile, fname)
   if (! opts->no_standard_includes)
     initialize_standard_includes (pfile);
 
-  _cpp_merge_include_chains (opts);
+  merge_include_chains (opts);
 
   /* With -v, print the list of dirs to search.  */
   if (opts->verbose)
@@ -844,9 +1001,10 @@ cpp_finish (pfile)
 {
   struct cpp_options *opts = CPP_OPTIONS (pfile);
 
-  if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) != NULL)
+  if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)))
     cpp_ice (pfile, "buffers still stacked in cpp_finish");
-  cpp_pop_buffer (pfile);
+  while (CPP_BUFFER (pfile))
+    cpp_pop_buffer (pfile);
 
   /* Don't write the deps file if preprocessing has failed.  */
   if (opts->print_deps && pfile->errors == 0)
===================================================================
Index: cpplib.c
--- cpplib.c	2000/03/08 20:37:23	1.128
+++ cpplib.c	2000/03/08 23:20:37
@@ -52,6 +52,20 @@ struct directive
   enum node_type type;		/* Code which describes which directive.  */
 };
 
+/* Stack of conditionals currently in progress
+   (including both successful and failing conditionals).  */
+
+struct if_stack
+{
+  struct if_stack *next;
+  int lineno;			/* line number where condition started */
+  int if_succeeded;		/* truth of last condition in this group */
+  const U_CHAR *control_macro;	/* macro name for #ifndef around entire file */
+  enum node_type type;		/* type of last directive seen in this group */
+};
+typedef struct if_stack IF_STACK;
+
+
 /* These functions are declared to return int instead of void since they
    are going to be placed in a table and some old compilers have trouble with
    pointers to functions returning void.  */
@@ -64,7 +78,7 @@ static int do_error PARAMS ((cpp_reader 
 static int do_pragma PARAMS ((cpp_reader *, const struct directive *));
 static int do_ident PARAMS ((cpp_reader *, const struct directive *));
 static int do_if PARAMS ((cpp_reader *, const struct directive *));
-static int do_xifdef PARAMS ((cpp_reader *, const struct directive *));
+static int do_ifdef PARAMS ((cpp_reader *, const struct directive *));
 static int do_else PARAMS ((cpp_reader *, const struct directive *));
 static int do_elif PARAMS ((cpp_reader *, const struct directive *));
 static int do_endif PARAMS ((cpp_reader *, const struct directive *));
@@ -78,7 +92,7 @@ static int do_warning PARAMS ((cpp_reade
 /* Forward declarations.  */
 
 static void validate_else		PARAMS ((cpp_reader *, const char *));
-static HOST_WIDEST_INT eval_if_expr	PARAMS ((cpp_reader *));
+static int eval_if_expr			PARAMS ((cpp_reader *));
 static void conditional_skip		PARAMS ((cpp_reader *, int,
 						enum node_type, U_CHAR *));
 static void skip_if_group		PARAMS ((cpp_reader *));
@@ -118,10 +132,10 @@ static const struct directive directive_
   {  6, do_define,   "define",       T_DEFINE },	/* 270554 */
   {  7, do_include,  "include",      T_INCLUDE },	/*  52262 */
   {  5, do_endif,    "endif",        T_ENDIF },		/*  45855 */
-  {  5, do_xifdef,   "ifdef",        T_IFDEF },		/*  22000 */
+  {  5, do_ifdef,   "ifdef",        T_IFDEF },		/*  22000 */
   {  2, do_if,       "if",           T_IF },		/*  18162 */
   {  4, do_else,     "else",         T_ELSE },		/*   9863 */
-  {  6, do_xifdef,   "ifndef",       T_IFNDEF },	/*   9675 */
+  {  6, do_ifdef,   "ifndef",       T_IFNDEF },	/*   9675 */
   {  5, do_undef,    "undef",        T_UNDEF },		/*   4837 */
   {  4, do_line,     "line",         T_LINE },		/*   2465 */
   {  4, do_elif,     "elif",         T_ELIF },		/*    610 */
@@ -529,7 +543,7 @@ handle_directive (pfile)
 	return 0;
 
       if (CPP_PEDANTIC (pfile)
-	  && ! CPP_PREPROCESSED (pfile)
+	  && ! CPP_OPTIONS (pfile)->preprocessed
 	  && ! CPP_BUFFER (pfile)->manual_pop)
 	cpp_pedwarn (pfile, "`#' followed by integer");
       do_line (pfile, NULL);
@@ -538,7 +552,7 @@ handle_directive (pfile)
 
   /* If we are rescanning preprocessed input, don't obey any directives
      other than # nnn.  */
-  if (CPP_PREPROCESSED (pfile))
+  if (CPP_OPTIONS (pfile)->preprocessed)
     return 0;
 
   /* Now find the directive name.  */
@@ -1842,16 +1856,8 @@ detect_if_not_defined (pfile)
 }
 
 /*
- * handle #if command 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 command)
- *   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.
+ * #if is straightforward; just call eval_if_expr, then conditional_skip.
+ * Also, check for a reinclude preventer of the form #if !defined (MACRO).
  */
 
 static int
@@ -1860,7 +1866,7 @@ do_if (pfile, keyword)
      const struct directive *keyword ATTRIBUTE_UNUSED;
 {
   U_CHAR *control_macro = detect_if_not_defined (pfile);
-  HOST_WIDEST_INT value = eval_if_expr (pfile);
+  int value = eval_if_expr (pfile);
   conditional_skip (pfile, value == 0, T_IF, control_macro);
   return 0;
 }
@@ -1895,7 +1901,7 @@ do_elif (pfile, keyword)
     skip_if_group (pfile);
   else
     {
-      HOST_WIDEST_INT value = eval_if_expr (pfile);
+      int value = eval_if_expr (pfile);
       if (value == 0)
 	skip_if_group (pfile);
       else
@@ -1907,16 +1913,15 @@ do_elif (pfile, 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.
+/* Thin wrapper around _cpp_parse_expr, which doesn't have access to
+ * skip_rest_of_line.  Also centralizes toggling parsing_if_directive.
  */
 
-static HOST_WIDEST_INT
+static int
 eval_if_expr (pfile)
      cpp_reader *pfile;
 {
-  HOST_WIDEST_INT value;
+  int value;
   long old_written = CPP_WRITTEN (pfile);
 
   pfile->parsing_if_directive++;
@@ -1936,7 +1941,7 @@ eval_if_expr (pfile)
  */
 
 static int
-do_xifdef (pfile, keyword)
+do_ifdef (pfile, keyword)
      cpp_reader *pfile;
      const struct directive *keyword;
 {
@@ -2578,7 +2583,8 @@ cpp_get_token (pfile)
 		break;
 	      if (!is_numchar(c) && c != '.'
 		  && ((c2 != 'e' && c2 != 'E'
-		       && ((c2 != 'p' && c2 != 'P') || CPP_C89 (pfile)))
+		       && ((c2 != 'p' && c2 != 'P')
+			   || CPP_OPTIONS (pfile)->c89))
 		      || (c != '+' && c != '-')))
 		break;
 	      FORWARD(1);
===================================================================
Index: cpplib.h
--- cpplib.h	2000/03/08 20:37:23	1.67
+++ cpplib.h	2000/03/08 23:20:37
@@ -28,8 +28,6 @@ Foundation, 59 Temple Place - Suite 330,
 extern "C" {
 #endif
 
-typedef unsigned char U_CHAR;
-
 typedef struct cpp_reader cpp_reader;
 typedef struct cpp_buffer cpp_buffer;
 typedef struct cpp_options cpp_options;
@@ -63,14 +61,6 @@ enum cpp_token
 
 typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
 
-extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
-extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
-extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
-extern enum cpp_token get_directive_token PARAMS ((cpp_reader *));
-
-/* This frees resources used by PFILE. */
-extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
-
 struct cpp_buffer
 {
   unsigned char *cur;	 /* current position */
@@ -227,8 +217,8 @@ struct cpp_reader
   /* A buffer and a table, used only by read_and_prescan (in cppfiles.c)
      which are allocated once per cpp_reader object to keep them off the
      stack and avoid setup costs.  */
-  U_CHAR *input_buffer;
-  U_CHAR *input_speccase;
+  unsigned char *input_buffer;
+  unsigned char *input_speccase;
   size_t input_buffer_len;
 };
 
@@ -236,70 +226,25 @@ struct cpp_reader
 /* True if we have seen a "fatal" error. */
 #define CPP_FATAL_ERRORS(READER) ((READER)->errors >= CPP_FATAL_LIMIT)
 
-#define CPP_BUF_PEEK(BUFFER) \
-  ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF)
-#define CPP_BUF_GET(BUFFER) \
-  ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
-#define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N))
-
 /* Macros for manipulating the token_buffer. */
 
-#define CPP_OUT_BUFFER(PFILE) ((PFILE)->token_buffer)
-
 /* Number of characters currently in PFILE's output buffer. */
 #define CPP_WRITTEN(PFILE) ((size_t)((PFILE)->limit - (PFILE)->token_buffer))
 #define CPP_PWRITTEN(PFILE) ((PFILE)->limit)
+#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
+#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
 
 /* Make sure PFILE->token_buffer has space for at least N more characters. */
 #define CPP_RESERVE(PFILE, N) \
   (CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \
    && (cpp_grow_buffer (PFILE, N), 0))
 
-/* Append string STR (of length N) to PFILE's output buffer.
-   Assume there is enough space. */
-#define CPP_PUTS_Q(PFILE, STR, N) \
-  (memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N))
-/* Append string STR (of length N) to PFILE's output buffer.  Make space. */
-#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
-/* Append character CH to PFILE's output buffer.  Assume sufficient space. */
-#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH))
-/* Append character CH to PFILE's output buffer.  Make space if need be. */
-#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
-/* Make sure PFILE->limit is followed by '\0'. */
-#define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0)
-#define CPP_NUL_TERMINATE(PFILE) (CPP_RESERVE(PFILE, 1), *(PFILE)->limit = 0)
-#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
-#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
-
-/* Advance the current line by one. */
-#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
-				    (PBUF)->line_base = (PBUF)->cur)
-#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
-
 #define CPP_OPTIONS(PFILE) ((PFILE)->opts)
 #define CPP_BUFFER(PFILE) ((PFILE)->buffer)
-#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
-
-/* The `pending' structure accumulates all the options that are not
-   actually processed until we hit cpp_start_read.  It consists of
-   several lists, one for each type of option.  We keep both head and
-   tail pointers for quick insertion. */
-struct cpp_pending
-{
-  struct pending_option *define_head, *define_tail;
-  struct pending_option *assert_head, *assert_tail;
-
-  struct file_name_list *quote_head, *quote_tail;
-  struct file_name_list *brack_head, *brack_tail;
-  struct file_name_list *systm_head, *systm_tail;
-  struct file_name_list *after_head, *after_tail;
 
-  struct pending_option *imacros_head, *imacros_tail;
-  struct pending_option *include_head, *include_tail;
-};
-
 /* Pointed to by cpp_reader.opts. */
-struct cpp_options {
+struct cpp_options
+{
   char *in_fname;
 
   /* Name of output file, for error messages.  */
@@ -488,144 +433,19 @@ struct cpp_options {
   char *deps_target;
 };
 
-#define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)-> traditional)
-#define CPP_WARN_UNDEF(PFILE) (CPP_OPTIONS(PFILE)->warn_undef)
-#define CPP_C89(PFILE) (CPP_OPTIONS(PFILE)->c89)
-#define CPP_PREPROCESSED(PFILE) (CPP_OPTIONS (PFILE)->preprocessed)
-#define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps)
-
-#define CPP_PEDANTIC(PFILE) \
-  (CPP_OPTIONS (PFILE)->pedantic && !CPP_BUFFER (pfile)->system_header_p)
-
-/* List of directories to look for include files in. */
-struct file_name_list
-{
-  struct file_name_list *next;
-  struct file_name_list *alloc; /* for the cache of
-				   current directory entries */
-  char *name;
-  unsigned int nlen;
-  /* We use these to tell if the directory mentioned here is a duplicate
-     of an earlier directory on the search path. */
-  ino_t ino;
-  dev_t dev;
-  /* If the following is nonzero, it is a C-language system include
-     directory.  */
-  int sysp;
-  /* Mapping of file names for this directory.
-     Only used on MS-DOS and related platforms. */
-  struct file_name_map *name_map;
-};
-#define ABSOLUTE_PATH ((struct file_name_list *)-1)
-
-/* This structure is used for the table of all includes.  It is
-   indexed by the `short name' (the name as it appeared in the
-   #include statement) which is stored in *nshort.  */
-struct ihash
-{
-  struct ihash *next;
-  /* Next file with the same short name but a
-     different (partial) pathname). */
-  struct ihash *next_this_file;
-
-  /* Location of the file in the include search path.
-     Used for include_next */
-  struct file_name_list *foundhere;
-  const char *name;		/* (partial) pathname of file */
-  const char *nshort;		/* name of file as referenced in #include */
-  const U_CHAR *control_macro;	/* macro, if any, preventing reinclusion -
-				   see redundant_include_p */
-  char *buf, *limit;		/* for file content cache,
-				   not yet implemented */
-};
-typedef struct ihash IHASH;
-
 /* Name under which this program was invoked.  */
-
 extern const char *progname;
-
-/* The structure of a node in the hash table.  The hash table
-   has entries for all tokens defined by #define commands (type T_MACRO),
-   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. */
-
-/* different flavors of hash nodes --- also used in keyword table */
-enum node_type {
- T_DEFINE = 1,	/* the `#define' keyword */
- T_INCLUDE,	/* the `#include' keyword */
- T_INCLUDE_NEXT, /* the `#include_next' keyword */
- T_IMPORT,      /* the `#import' keyword */
- T_IFDEF,	/* the `#ifdef' keyword */
- T_IFNDEF,	/* the `#ifndef' keyword */
- T_IF,		/* the `#if' keyword */
- T_ELSE,	/* `#else' */
- T_PRAGMA,	/* `#pragma' */
- T_ELIF,	/* `#elif' */
- T_UNDEF,	/* `#undef' */
- T_LINE,	/* `#line' */
- T_ERROR,	/* `#error' */
- T_WARNING,	/* `#warning' */
- T_ENDIF,	/* `#endif' */
- T_SCCS,	/* `#sccs', used on system V.  */
- T_IDENT,	/* `#ident', used on system V.  */
- T_ASSERT,	/* `#assert', taken from system V.  */
- T_UNASSERT,	/* `#unassert', taken from system V.  */
- T_SPECLINE,	/* special symbol `__LINE__' */
- T_DATE,	/* `__DATE__' */
- T_FILE,	/* `__FILE__' */
- T_BASE_FILE,	/* `__BASE_FILE__' */
- T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
- T_VERSION,	/* `__VERSION__' */
- T_TIME,	/* `__TIME__' */
- T_STDC,	/* `__STDC__' */
- T_CONST,	/* Constant string, used by `__SIZE_TYPE__' etc */
- T_MACRO,	/* macro defined by `#define' */
- T_DISABLED,	/* macro temporarily turned off for rescan */
- T_POISON,	/* defined with `#pragma poison' */
- T_UNUSED	/* Used for something not defined.  */
- };
-
-/* Character classes.
-   If the definition of `numchar' looks odd to you, please look up the
-   definition of a pp-number in the C standard [section 6.4.8 of C99] */
-#define ISidnum		0x01	/* a-zA-Z0-9_ */
-#define ISidstart	0x02	/* _a-zA-Z */
-#define ISnumstart	0x04	/* 0-9 */
-#define IShspace	0x08	/* ' ' \t \f \v */
-#define ISspace		0x10	/* ' ' \t \f \v \n */
-
-#define _dollar_ok(x)	((x) == '$' && CPP_OPTIONS (pfile)->dollars_in_ident)
-
-#define is_idchar(x)	((_cpp_IStable[x] & ISidnum) || _dollar_ok(x))
-#define is_idstart(x)	((_cpp_IStable[x] & ISidstart) || _dollar_ok(x))
-#define is_numchar(x)	(_cpp_IStable[x] & ISidnum)
-#define is_numstart(x)	(_cpp_IStable[x] & ISnumstart)
-#define is_hspace(x)	(_cpp_IStable[x] & IShspace)
-#define is_space(x)	(_cpp_IStable[x] & ISspace)
-
-/* This table is constant if it can be initialized at compile time,
-   which is the case if cpp was compiled with GCC >=2.7, or another
-   compiler that supports C99.  */
-#if (GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)
-extern const unsigned char _cpp_IStable[256];
-#else
-extern unsigned char _cpp_IStable[256];
-#endif
 
-/* Stack of conditionals currently in progress
-   (including both successful and failing conditionals).  */
+extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
+extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
+extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
+extern enum cpp_token get_directive_token PARAMS ((cpp_reader *));
 
-struct if_stack
-{
-  struct if_stack *next;
-  int lineno;			/* line number where condition started */
-  int if_succeeded;		/* truth of last condition in this group */
-  const U_CHAR *control_macro;	/* macro name for #ifndef around entire file */
-  enum node_type type;		/* type of last directive seen in this group */
-};
-typedef struct if_stack IF_STACK;
+extern void cpp_reader_init PARAMS ((cpp_reader *));
+extern void cpp_options_init PARAMS ((cpp_options *));
+extern int cpp_start_read PARAMS ((cpp_reader *, char *));
+extern void cpp_finish PARAMS ((cpp_reader *));
+extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
 
 extern void cpp_buf_line_and_col PARAMS((cpp_buffer *, long *, long *));
 extern cpp_buffer *cpp_file_buffer PARAMS((cpp_reader *));
@@ -667,16 +487,11 @@ extern void cpp_grow_buffer PARAMS ((cpp
 extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
 					    unsigned char *, long));
 extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
-extern int cpp_defined PARAMS ((cpp_reader *, const U_CHAR *, int));
-
-extern void cpp_reader_init PARAMS ((cpp_reader *));
-extern void cpp_options_init PARAMS ((cpp_options *));
-extern int cpp_start_read PARAMS ((cpp_reader *, char *));
-extern void cpp_finish PARAMS ((cpp_reader *));
+extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
 
 extern void quote_string		PARAMS ((cpp_reader *, const char *));
-extern void cpp_expand_to_buffer	PARAMS ((cpp_reader *, const U_CHAR *,
-						 int));
+extern void cpp_expand_to_buffer	PARAMS ((cpp_reader *,
+						 const unsigned char *, int));
 extern void cpp_scan_buffer		PARAMS ((cpp_reader *));
 
 /* Last arg to output_line_command.  */
@@ -687,16 +502,6 @@ extern void output_line_command		PARAMS 
 /* In cppfiles.c */
 extern int cpp_included			PARAMS ((cpp_reader *, const char *));
 extern int cpp_read_file		PARAMS ((cpp_reader *, const char *));
-
-extern void _cpp_simplify_pathname	PARAMS ((char *));
-extern void _cpp_merge_include_chains	PARAMS ((struct cpp_options *));
-extern int _cpp_find_include_file	PARAMS ((cpp_reader *, const char *,
-						struct file_name_list *,
-						IHASH **, int *));
-extern int _cpp_read_include_file	PARAMS ((cpp_reader *, int, IHASH *));
-
-/* In cppexp.c */
-extern HOST_WIDEST_INT _cpp_parse_expr	PARAMS ((cpp_reader *));
 
 
 #ifdef __cplusplus
===================================================================
Index: fix-header.c
--- fix-header.c	2000/02/27 02:25:05	1.37
+++ fix-header.c	2000/03/08 23:20:38
@@ -631,6 +631,7 @@ read_scan_file (in_fname, argc, argv)
      so ignore warnings and errors.  */
   scan_options.inhibit_warnings = 1;
   scan_options.inhibit_errors = 1;
+  scan_options.no_line_commands = 1;
   i = cpp_handle_options (&scan_in, argc, argv);
   if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
     cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]);
@@ -639,7 +640,6 @@ read_scan_file (in_fname, argc, argv)
 
   if (! cpp_start_read (&scan_in, in_fname))
     exit (FATAL_EXIT_CODE);
-  CPP_OPTIONS (&scan_in)->no_line_commands = 1;
 
   scan_decls (&scan_in, argc, argv);
   for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++)


More information about the Gcc-patches mailing list