diff options
Diffstat (limited to 'contrib/gcc/cppinit.c')
| -rw-r--r-- | contrib/gcc/cppinit.c | 2965 | 
1 files changed, 1581 insertions, 1384 deletions
diff --git a/contrib/gcc/cppinit.c b/contrib/gcc/cppinit.c index 453cc5836c3a..ab3dad78d90b 100644 --- a/contrib/gcc/cppinit.c +++ b/contrib/gcc/cppinit.c @@ -1,6 +1,6 @@  /* CPP Library.     Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, -   1999, 2000 Free Software Foundation, Inc. +   1999, 2000, 2001, 2002 Free Software Foundation, Inc.     Contributed by Per Bothner, 1994-95.     Based on CCCP program by Paul Rubin, June 1986     Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -21,164 +21,63 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */  #include "config.h"  #include "system.h" - -#define FAKE_CONST  #include "cpplib.h"  #include "cpphash.h" -#include "output.h"  #include "prefix.h"  #include "intl.h" +#include "version.h" +#include "mkdeps.h" +#include "cppdefault.h" +#include "except.h"	/* for USING_SJLJ_EXCEPTIONS */ -/* XXX Should be in a header file. */ -extern char *version_string; - -/* Predefined symbols, built-in macros, and the default include path. */ +/* Predefined symbols, built-in macros, and the default include path.  */  #ifndef GET_ENV_PATH_LIST  #define GET_ENV_PATH_LIST(VAR,NAME)	do { (VAR) = getenv (NAME); } while (0)  #endif -/* By default, colon separates directories in a path.  */ -#ifndef PATH_SEPARATOR -#define PATH_SEPARATOR ':' -#endif - -#ifndef STANDARD_INCLUDE_DIR -#define STANDARD_INCLUDE_DIR "/usr/include" -#endif - -/* We let tm.h override the types used here, to handle trivial differences -   such as the choice of unsigned int or long unsigned int for size_t. -   When machines start needing nontrivial differences in the size type, -   it would be best to do something here to figure out automatically -   from other information what type to use.  */ - -/* The string value for __SIZE_TYPE__.  */ - -#ifndef SIZE_TYPE -#define SIZE_TYPE "long unsigned int" -#endif - -/* The string value for __PTRDIFF_TYPE__.  */ - -#ifndef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" -#endif - -/* The string value for __WCHAR_TYPE__.  */ - -#ifndef WCHAR_TYPE -#define WCHAR_TYPE "int" -#endif -#define CPP_WCHAR_TYPE(PFILE) \ -	(CPP_OPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE) - -/* The string value for __USER_LABEL_PREFIX__ */ - -#ifndef USER_LABEL_PREFIX -#define USER_LABEL_PREFIX "" -#endif - -/* The string value for __REGISTER_PREFIX__ */ - -#ifndef REGISTER_PREFIX -#define REGISTER_PREFIX "" -#endif - -/* Suffix for object files, and known input-file extensions. */ -static char *known_suffixes[] = -{ -  ".c",  ".C",   ".s",   ".S",   ".m", -  ".cc", ".cxx", ".cpp", ".cp",  ".c++", -  NULL -}; - -#ifndef OBJECT_SUFFIX -# ifdef VMS -#  define OBJECT_SUFFIX ".obj" +/* 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))) +# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC)) +#else +# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__ +#  define INO_T_EQ(A, B) 0  # else -#  define OBJECT_SUFFIX ".o" +#  define INO_T_EQ(A, B) ((A) == (B))  # endif +# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)  #endif +/* Internal structures and prototypes.  */ -/* This is the default list of directories to search for include files. -   It may be overridden by the various -I and -ixxx options. - -   #include "file" looks in the same directory as the current file, -   then this list.  -   #include <file> just looks in this list. - -   All these directories are treated as `system' include directories -   (they are not subject to pedantic warnings in some cases).  */ - -static struct default_include -{ -  char *fname;			/* The name of the directory.  */ -  char *component;		/* The component containing the directory -				   (see update_path in prefix.c) */ -  int cplusplus;		/* Only look here if we're compiling C++.  */ -  int cxx_aware;		/* Includes in this directory don't need to -				   be wrapped in extern "C" when compiling -				   C++.  This is not used anymore.  */ -} -include_defaults_array[] -#ifdef INCLUDE_DEFAULTS -= INCLUDE_DEFAULTS; -#else -= { -    /* 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.  */ -    { LOCAL_INCLUDE_DIR, 0, 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, "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 -    { SYSTEM_INCLUDE_DIR, 0, 0, 0 }, -#endif -#ifndef STANDARD_INCLUDE_COMPONENT -#define STANDARD_INCLUDE_COMPONENT 0 -#endif -    { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 }, -#endif /* not CROSS_COMPILE */ -    { 0, 0, 0, 0 } -  }; -#endif /* no INCLUDE_DEFAULTS */ - -/* Internal structures and prototypes. */ - -/* A `struct pending_option' remembers one -D, -A, -U, -include, or -imacros -   switch.  There are four lists: one for -D and -U, one for -A, one -   for -include, one for -imacros.  `undef' is set for -U, clear for -   -D, ignored for the others. -   (Future: add an equivalent of -U for -A) */ +/* A `struct pending_option' remembers one -D, -A, -U, -include, or +   -imacros switch.  */ +typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *));  struct pending_option  {    struct pending_option *next; -  char *arg; -  int undef; +  const char *arg; +  cl_directive_handler handler; +}; + +/* The `pending' structure accumulates all the options that are not +   actually processed until we hit cpp_read_main_file.  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 *directive_head, *directive_tail; + +  struct search_path *quote_head, *quote_tail; +  struct search_path *brack_head, *brack_tail; +  struct search_path *systm_head, *systm_tail; +  struct search_path *after_head, *after_tail; + +  struct pending_option *imacros_head, *imacros_tail; +  struct pending_option *include_head, *include_tail;  };  #ifdef __STDC__ @@ -195,196 +94,73 @@ struct pending_option    } while (0)  #endif -static void initialize_char_syntax	PARAMS ((int));  static void print_help                  PARAMS ((void));  static void path_include		PARAMS ((cpp_reader *, -						 struct cpp_pending *,  						 char *, int)); -static void initialize_builtins		PARAMS ((cpp_reader *)); +static void init_library		PARAMS ((void)); +static void init_builtins		PARAMS ((cpp_reader *));  static void append_include_chain	PARAMS ((cpp_reader *, -						 struct cpp_pending *, -						 char *, int)); - -/* Last argument to append_include_chain: chain to use */ -enum { QUOTE = 0, BRACKET, SYSTEM, AFTER }; - -/* If gcc is in use (stage2/stage3) we can make these tables initialized -   data. */ -#if defined __GNUC__ && (__GNUC__ > 2 \ -			 || (__GNUC__ == 2 && __GNUC_MINOR__ > 8)) -/* Table to tell if a character is legal as the second or later character -   of a C identifier. */ -U_CHAR is_idchar[256] = -{ -  ['a'] = 1, ['b'] = 1, ['c'] = 1,  ['d'] = 1, ['e'] = 1, ['f'] = 1, -  ['g'] = 1, ['h'] = 1, ['i'] = 1,  ['j'] = 1, ['k'] = 1, ['l'] = 1, -  ['m'] = 1, ['n'] = 1, ['o'] = 1,  ['p'] = 1, ['q'] = 1, ['r'] = 1, -  ['s'] = 1, ['t'] = 1, ['u'] = 1,  ['v'] = 1, ['w'] = 1, ['x'] = 1, -  ['y'] = 1, ['z'] = 1, - -  ['A'] = 1, ['B'] = 1, ['C'] = 1,  ['D'] = 1, ['E'] = 1, ['F'] = 1, -  ['G'] = 1, ['H'] = 1, ['I'] = 1,  ['J'] = 1, ['K'] = 1, ['L'] = 1, -  ['M'] = 1, ['N'] = 1, ['O'] = 1,  ['P'] = 1, ['Q'] = 1, ['R'] = 1, -  ['S'] = 1, ['T'] = 1, ['U'] = 1,  ['V'] = 1, ['W'] = 1, ['X'] = 1, -  ['Y'] = 1, ['Z'] = 1, - -  ['1'] = 1, ['2'] = 1, ['3'] = 1,  ['4'] = 1, ['5'] = 1, ['6'] = 1, -  ['7'] = 1, ['8'] = 1, ['9'] = 1,  ['0'] = 1, - -  ['_']  = 1, -}; +						 char *, int, int)); +static struct search_path * remove_dup_dir	PARAMS ((cpp_reader *, +						 struct search_path *)); +static struct search_path * remove_dup_dirs PARAMS ((cpp_reader *, +						 struct search_path *)); +static void merge_include_chains	PARAMS ((cpp_reader *)); +static bool push_include		PARAMS ((cpp_reader *, +						 struct pending_option *)); +static void free_chain			PARAMS ((struct pending_option *)); +static void set_lang			PARAMS ((cpp_reader *, enum c_lang)); +static void init_dependency_output	PARAMS ((cpp_reader *)); +static void init_standard_includes	PARAMS ((cpp_reader *)); +static void read_original_filename	PARAMS ((cpp_reader *)); +static void new_pending_directive	PARAMS ((struct cpp_pending *, +						 const char *, +						 cl_directive_handler)); +static void output_deps			PARAMS ((cpp_reader *)); +static int parse_option			PARAMS ((const char *)); + +/* Fourth argument to append_include_chain: chain to use. +   Note it's never asked to append to the quote chain.  */ +enum { BRACKET = 0, SYSTEM, AFTER }; + +/* If we have designated initializers (GCC >2.7) these tables can be +   initialized, constant data.  Otherwise, they have to be filled in at +   runtime.  */ +#if HAVE_DESIGNATED_INITIALIZERS + +#define init_trigraph_map()  /* Nothing.  */ +#define TRIGRAPH_MAP \ +__extension__ const U_CHAR _cpp_trigraph_map[UCHAR_MAX + 1] = { + +#define END }; +#define s(p, v) [p] = v, -/* Table to tell if a character is legal as the first character of -   a C identifier. */ -U_CHAR is_idstart[256] = -{ -  ['a'] = 1, ['b'] = 1, ['c'] = 1,  ['d'] = 1, ['e'] = 1, ['f'] = 1, -  ['g'] = 1, ['h'] = 1, ['i'] = 1,  ['j'] = 1, ['k'] = 1, ['l'] = 1, -  ['m'] = 1, ['n'] = 1, ['o'] = 1,  ['p'] = 1, ['q'] = 1, ['r'] = 1, -  ['s'] = 1, ['t'] = 1, ['u'] = 1,  ['v'] = 1, ['w'] = 1, ['x'] = 1, -  ['y'] = 1, ['z'] = 1, - -  ['A'] = 1, ['B'] = 1, ['C'] = 1,  ['D'] = 1, ['E'] = 1, ['F'] = 1, -  ['G'] = 1, ['H'] = 1, ['I'] = 1,  ['J'] = 1, ['K'] = 1, ['L'] = 1, -  ['M'] = 1, ['N'] = 1, ['O'] = 1,  ['P'] = 1, ['Q'] = 1, ['R'] = 1, -  ['S'] = 1, ['T'] = 1, ['U'] = 1,  ['V'] = 1, ['W'] = 1, ['X'] = 1, -  ['Y'] = 1, ['Z'] = 1, - -  ['_']  = 1, -}; - -/* Table to tell if a character is horizontal space. -   \r is magical, so it is not in here.  */ -U_CHAR is_hor_space[256] = -{ -  [' '] = 1, ['\t'] = 1, ['\v'] = 1, ['\f'] = 1, -}; -/* table to tell if a character is horizontal or vertical space.  */ -U_CHAR is_space[256] = -{ -  [' '] = 1, ['\t'] = 1, ['\v'] = 1, ['\f'] = 1, ['\n'] = 1, -}; -/* Table to handle trigraph conversion, which occurs before all other -   processing, everywhere in the file.  (This is necessary since one -   of the trigraphs encodes backslash.)  Note it's off by default. - -	from	to	from	to	from	to -	?? =	#	?? )	]	?? !	| -	?? (	[	?? '	^	?? >	} -	?? /	\	?? <	{	?? -	~ - -   There is not a space between the ?? and the third char.  I put spaces -   there to avoid warnings when compiling this file. */ -U_CHAR trigraph_table[256] = -{ -  ['='] = '#',  [')'] = ']',  ['!'] = '|', -  ['('] = '[',  ['\''] = '^', ['>'] = '}', -  ['/'] = '\\', ['<'] = '{',  ['-'] = '~', -}; +#else -/* This function will be entirely removed soon. */ -static inline void -initialize_char_syntax (dollar_in_ident) -     int dollar_in_ident; -{ -  is_idchar['$'] = dollar_in_ident; -  is_idstart['$'] = dollar_in_ident; -} +#define TRIGRAPH_MAP U_CHAR _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \ + static void init_trigraph_map PARAMS ((void)) { \ + unsigned char *x = _cpp_trigraph_map; -#else /* Not GCC. */ +#define END } +#define s(p, v) x[p] = v; -U_CHAR is_idchar[256] = { 0 }; -U_CHAR is_idstart[256] = { 0 }; -U_CHAR is_hor_space[256] = { 0 }; -U_CHAR is_space[256] = { 0 }; -U_CHAR trigraph_table[256] = { 0 }; +#endif -/* Initialize syntactic classifications of characters. */ -static void -initialize_char_syntax (dollar_in_ident) -     int dollar_in_ident; -{ -  is_idstart['a'] = 1; is_idstart['b'] = 1; is_idstart['c'] = 1; -  is_idstart['d'] = 1; is_idstart['e'] = 1; is_idstart['f'] = 1; -  is_idstart['g'] = 1; is_idstart['h'] = 1; is_idstart['i'] = 1; -  is_idstart['j'] = 1; is_idstart['k'] = 1; is_idstart['l'] = 1; -  is_idstart['m'] = 1; is_idstart['n'] = 1; is_idstart['o'] = 1; -  is_idstart['p'] = 1; is_idstart['q'] = 1; is_idstart['r'] = 1; -  is_idstart['s'] = 1; is_idstart['t'] = 1; is_idstart['u'] = 1; -  is_idstart['v'] = 1; is_idstart['w'] = 1; is_idstart['x'] = 1; -  is_idstart['y'] = 1; is_idstart['z'] = 1; - -  is_idstart['A'] = 1; is_idstart['B'] = 1; is_idstart['C'] = 1; -  is_idstart['D'] = 1; is_idstart['E'] = 1; is_idstart['F'] = 1; -  is_idstart['G'] = 1; is_idstart['H'] = 1; is_idstart['I'] = 1; -  is_idstart['J'] = 1; is_idstart['K'] = 1; is_idstart['L'] = 1; -  is_idstart['M'] = 1; is_idstart['N'] = 1; is_idstart['O'] = 1; -  is_idstart['P'] = 1; is_idstart['Q'] = 1; is_idstart['R'] = 1; -  is_idstart['S'] = 1; is_idstart['T'] = 1; is_idstart['U'] = 1; -  is_idstart['V'] = 1; is_idstart['W'] = 1; is_idstart['X'] = 1; -  is_idstart['Y'] = 1; is_idstart['Z'] = 1; - -  is_idstart['_'] = 1; - -  is_idchar['a'] = 1; is_idchar['b'] = 1; is_idchar['c'] = 1; -  is_idchar['d'] = 1; is_idchar['e'] = 1; is_idchar['f'] = 1; -  is_idchar['g'] = 1; is_idchar['h'] = 1; is_idchar['i'] = 1; -  is_idchar['j'] = 1; is_idchar['k'] = 1; is_idchar['l'] = 1; -  is_idchar['m'] = 1; is_idchar['n'] = 1; is_idchar['o'] = 1; -  is_idchar['p'] = 1;  is_idchar['q'] = 1; is_idchar['r'] = 1; -  is_idchar['s'] = 1; is_idchar['t'] = 1;  is_idchar['u'] = 1; -  is_idchar['v'] = 1; is_idchar['w'] = 1; is_idchar['x'] = 1; -  is_idchar['y'] = 1; is_idchar['z'] = 1; - -  is_idchar['A'] = 1; is_idchar['B'] = 1; is_idchar['C'] = 1; -  is_idchar['D'] = 1; is_idchar['E'] = 1; is_idchar['F'] = 1; -  is_idchar['G'] = 1; is_idchar['H'] = 1; is_idchar['I'] = 1; -  is_idchar['J'] = 1; is_idchar['K'] = 1; is_idchar['L'] = 1; -  is_idchar['M'] = 1; is_idchar['N'] = 1; is_idchar['O'] = 1; -  is_idchar['P'] = 1; is_idchar['Q'] = 1; is_idchar['R'] = 1; -  is_idchar['S'] = 1; is_idchar['T'] = 1;  is_idchar['U'] = 1; -  is_idchar['V'] = 1; is_idchar['W'] = 1; is_idchar['X'] = 1; -  is_idchar['Y'] = 1; is_idchar['Z'] = 1; - -  is_idchar['1'] = 1; is_idchar['2'] = 1; is_idchar['3'] = 1; -  is_idchar['4'] = 1; is_idchar['5'] = 1; is_idchar['6'] = 1; -  is_idchar['7'] = 1; is_idchar['8'] = 1; is_idchar['9'] = 1; -  is_idchar['0'] = 1; - -  is_idchar['_']  = 1; - -  is_idchar['$']  = dollar_in_ident; -  is_idstart['$'] = dollar_in_ident; - -  /* white space tables */ -  is_hor_space[' '] = 1; -  is_hor_space['\t'] = 1; -  is_hor_space['\v'] = 1; -  is_hor_space['\f'] = 1; - -  is_space[' '] = 1; -  is_space['\t'] = 1; -  is_space['\v'] = 1; -  is_space['\f'] = 1; -  is_space['\n'] = 1; - -  /* trigraph conversion */ -  trigraph_table['='] = '#';  trigraph_table[')'] = ']'; -  trigraph_table['!'] = '|';  trigraph_table['('] = '['; -  trigraph_table['\''] = '^'; trigraph_table['>'] = '}'; -  trigraph_table['/'] = '\\'; trigraph_table['<'] = '{'; -  trigraph_table['-'] = '~'; -} +TRIGRAPH_MAP +  s('=', '#')	s(')', ']')	s('!', '|') +  s('(', '[')	s('\'', '^')	s('>', '}') +  s('/', '\\')	s('<', '{')	s('-', '~') +END -#endif /* Not GCC. */ +#undef s +#undef END +#undef TRIGRAPH_MAP  /* Given a colon-separated list of file names PATH,     add all the names to the search path for include files.  */ -  static void -path_include (pfile, pend, list, path) +path_include (pfile, list, path)       cpp_reader *pfile; -     struct cpp_pending *pend;       char *list;       int path;  { @@ -412,7 +188,7 @@ path_include (pfile, pend, list, path)  	  name[q - p] = 0;  	} -      append_include_chain (pfile, pend, name, path); +      append_include_chain (pfile, name, path, 0);        /* Advance past this name.  */        if (*q == 0) @@ -422,1274 +198,1555 @@ path_include (pfile, pend, list, path)    while (1);  } -/* Find the base name of a (partial) pathname FNAME. -   Returns a pointer into the string passed in. -   Accepts Unix (/-separated) paths on all systems, -   DOS and VMS paths on those systems.  */ -static char * -base_name (fname) -     const char *fname; -{ -  char *s = (char *)fname; -  char *p; -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) -  if (ISALPHA (s[0]) && s[1] == ':') s += 2; -  if ((p = rindex (s, '\\'))) s = p + 1; -#elif defined VMS -  if ((p = rindex (s, ':'))) s = p + 1; /* Skip device.  */ -  if ((p = rindex (s, ']'))) s = p + 1; /* Skip directory.  */ -  if ((p = rindex (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir.  */ -#endif -  if ((p = rindex (s, '/'))) s = p + 1; -  return s; -} -      - -/* Append DIR to include path PATH.  DIR must be permanently allocated -   and writable. */ +/* Append DIR to include path PATH.  DIR must be allocated on the +   heap; this routine takes responsibility for freeing it.  CXX_AWARE +   is non-zero if the header contains extern "C" guards for C++, +   otherwise it is zero.  */  static void -append_include_chain (pfile, pend, dir, path) +append_include_chain (pfile, dir, path, cxx_aware)       cpp_reader *pfile; -     struct cpp_pending *pend;       char *dir;       int path; +     int cxx_aware ATTRIBUTE_UNUSED;  { -  struct file_name_list *new; +  struct cpp_pending *pend = CPP_OPTION (pfile, pending); +  struct search_path *new;    struct stat st;    unsigned int len; -  simplify_pathname (dir); +  if (*dir == '\0') +    { +      free (dir); +      dir = xstrdup ("."); +    } +  _cpp_simplify_pathname (dir); +    if (stat (dir, &st))      { -      /* Dirs that don't exist are silently ignored. */ +      /* Dirs that don't exist are silently ignored.  */        if (errno != ENOENT) -	cpp_perror_with_name (pfile, dir); -      else if (CPP_OPTIONS (pfile)->verbose) -	cpp_notice ("ignoring nonexistent directory `%s'\n", dir); +	cpp_notice_from_errno (pfile, dir); +      else if (CPP_OPTION (pfile, verbose)) +	fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"), dir); +      free (dir);        return;      }    if (!S_ISDIR (st.st_mode))      { -      cpp_message (pfile, 1, "%s: %s: Not a directory", progname, dir); +      cpp_notice (pfile, "%s: Not a directory", dir); +      free (dir);        return;      }    len = strlen (dir);    if (len > pfile->max_include_len)      pfile->max_include_len = len; -   -  new = (struct file_name_list *)xmalloc (sizeof (struct file_name_list)); + +  new = (struct search_path *) xmalloc (sizeof (struct search_path));    new->name = dir; -  new->nlen = len; -  new->ino  = st.st_ino; +  new->len = len; +  INO_T_COPY (new->ino, st.st_ino);    new->dev  = st.st_dev; -  new->sysp = (path == SYSTEM); +  /* Both systm and after include file lists should be treated as system +     include files since these two lists are really just a concatenation +     of one "system" list.  */ +  if (path == SYSTEM || path == AFTER) +#ifdef NO_IMPLICIT_EXTERN_C +    new->sysp = 1; +#else +    new->sysp = cxx_aware ? 1 : 2; +#endif +  else +    new->sysp = 0;    new->name_map = NULL; +  new->next = NULL;    switch (path)      { -    case QUOTE:		APPEND (pend, quote, new); break;      case BRACKET:	APPEND (pend, brack, new); break;      case SYSTEM:	APPEND (pend, systm, new); break;      case AFTER:		APPEND (pend, after, new); break;      }  } +/* Handle a duplicated include path.  PREV is the link in the chain +   before the duplicate.  The duplicate is removed from the chain and +   freed.  Returns PREV.  */ +static struct search_path * +remove_dup_dir (pfile, prev) +     cpp_reader *pfile; +     struct search_path *prev; +{ +  struct search_path *cur = prev->next; -/* Write out a #define command for the special named MACRO_NAME -   to PFILE's token_buffer.  */ +  if (CPP_OPTION (pfile, verbose)) +    fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name); -static void -dump_special_to_buffer (pfile, macro_name) +  prev->next = cur->next; +  free ((PTR) cur->name); +  free (cur); + +  return prev; +} + +/* Remove duplicate directories from a chain.  Returns the tail of the +   chain, or NULL if the chain is empty.  This algorithm is quadratic +   in the number of -I switches, which is acceptable since there +   aren't usually that many of them.  */ +static struct search_path * +remove_dup_dirs (pfile, head)       cpp_reader *pfile; -     char *macro_name; +     struct search_path *head;  { -  static char define_directive[] = "#define "; -  int macro_name_length = strlen (macro_name); -  output_line_command (pfile, same_file); -  CPP_RESERVE (pfile, sizeof(define_directive) + macro_name_length); -  CPP_PUTS_Q (pfile, define_directive, sizeof(define_directive)-1); -  CPP_PUTS_Q (pfile, macro_name, macro_name_length); -  CPP_PUTC_Q (pfile, ' '); -  cpp_expand_to_buffer (pfile, macro_name, macro_name_length); -  CPP_PUTC (pfile, '\n'); +  struct search_path *prev = NULL, *cur, *other; + +  for (cur = head; cur; cur = cur->next) +    { +      for (other = head; other != cur; other = other->next) +        if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev) +	  { +	    if (cur->sysp && !other->sysp) +	      { +		cpp_warning (pfile, +			     "changing search order for system directory \"%s\"", +			     cur->name); +		if (strcmp (cur->name, other->name)) +		  cpp_warning (pfile,  +			       "  as it is the same as non-system directory \"%s\"", +			       other->name); +		else +		  cpp_warning (pfile,  +			       "  as it has already been specified as a non-system directory"); +	      } +	    cur = remove_dup_dir (pfile, prev); +	    break; +	  } +      prev = cur; +    } + +  return prev;  } -/* Initialize a cpp_options structure. */ -void -cpp_options_init (opts) -     cpp_options *opts; +/* 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.  */ +static void +merge_include_chains (pfile) +     cpp_reader *pfile;  { -  bzero ((char *) opts, sizeof (struct cpp_options)); +  struct search_path *quote, *brack, *systm, *qtail; + +  struct cpp_pending *pend = CPP_OPTION (pfile, pending); + +  quote = pend->quote_head; +  brack = pend->brack_head; +  systm = pend->systm_head; +  qtail = pend->quote_tail; + +  /* Paste together bracket, system, and after include chains.  */ +  if (systm) +    pend->systm_tail->next = pend->after_head; +  else +    systm = pend->after_head; -  opts->dollars_in_ident = 1; -  opts->cplusplus_comments = 1; -  opts->warn_import = 1; +  if (brack) +    pend->brack_tail->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 +     brack and move brack up to point to 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.  */ + +  remove_dup_dirs (pfile, brack); +  qtail = remove_dup_dirs (pfile, quote); + +  if (quote) +    { +      qtail->next = brack; -  opts->pending = (struct cpp_pending *) xmalloc (sizeof (struct cpp_pending)); -  bzero ((char *) opts->pending, sizeof (struct cpp_pending)); +      /* If brack == qtail, remove brack as it's simpler.  */ +      if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev) +	brack = remove_dup_dir (pfile, qtail); +    } +  else +    quote = brack; + +  CPP_OPTION (pfile, quote_include) = quote; +  CPP_OPTION (pfile, bracket_include) = brack;  } -/* Initialize a cpp_reader structure. */ -void -cpp_reader_init (pfile) +/* A set of booleans indicating what CPP features each source language +   requires.  */ +struct lang_flags +{ +  char c99; +  char objc; +  char cplusplus; +  char extended_numbers; +  char trigraphs; +  char dollars_in_ident; +  char cplusplus_comments; +  char digraphs; +}; + +/* ??? Enable $ in identifiers in assembly? */ +static const struct lang_flags lang_defaults[] = +{ /*              c99 objc c++ xnum trig dollar c++comm digr  */ +  /* GNUC89 */  { 0,  0,   0,  1,   0,   1,     1,      1     }, +  /* GNUC99 */  { 1,  0,   0,  1,   0,   1,     1,      1     }, +  /* STDC89 */  { 0,  0,   0,  0,   1,   0,     0,      0     }, +  /* STDC94 */  { 0,  0,   0,  0,   1,   0,     0,      1     }, +  /* STDC99 */  { 1,  0,   0,  1,   1,   0,     1,      1     }, +  /* GNUCXX */  { 0,  0,   1,  1,   0,   1,     1,      1     }, +  /* CXX98  */  { 0,  0,   1,  1,   1,   0,     1,      1     }, +  /* OBJC   */  { 0,  1,   0,  1,   0,   1,     1,      1     }, +  /* OBJCXX */  { 0,  1,   1,  1,   0,   1,     1,      1     }, +  /* ASM    */  { 0,  0,   0,  1,   0,   0,     1,      0     } +}; + +/* Sets internal flags correctly for a given language.  */ +static void +set_lang (pfile, lang)       cpp_reader *pfile; +     enum c_lang lang;  { -  bzero ((char *) pfile, sizeof (cpp_reader)); -#if 0 -  pfile->get_token = cpp_get_token; -#endif +  const struct lang_flags *l = &lang_defaults[(int) lang]; +   +  CPP_OPTION (pfile, lang) = lang; + +  CPP_OPTION (pfile, c99)		 = l->c99; +  CPP_OPTION (pfile, objc)		 = l->objc; +  CPP_OPTION (pfile, cplusplus)		 = l->cplusplus; +  CPP_OPTION (pfile, extended_numbers)	 = l->extended_numbers; +  CPP_OPTION (pfile, trigraphs)		 = l->trigraphs; +  CPP_OPTION (pfile, dollars_in_ident)	 = l->dollars_in_ident; +  CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; +  CPP_OPTION (pfile, digraphs)		 = l->digraphs; +} -  pfile->token_buffer_size = 200; -  pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size); -  CPP_SET_WRITTEN (pfile, 0); +#ifdef HOST_EBCDIC +static int opt_comp PARAMS ((const void *, const void *)); -  pfile->hashtab = (HASHNODE **) xcalloc (HASHSIZE, sizeof (HASHNODE *)); +/* Run-time sorting of options array.  */ +static int +opt_comp (p1, p2) +     const void *p1, *p2; +{ +  return strcmp (((struct cl_option *) p1)->opt_text, +		 ((struct cl_option *) p2)->opt_text);  } +#endif -/* Free resources used by PFILE. -   This is the cpp_reader 'finalizer' or 'destructor' (in C++ terminology).  */ -void -cpp_cleanup (pfile) -     cpp_reader *pfile; +/* init initializes library global state.  It might not need to +   do anything depending on the platform and compiler.  */ +static void +init_library ()  { -  int i; -  while (CPP_BUFFER (pfile) != CPP_NULL_BUFFER (pfile)) -    cpp_pop_buffer (pfile); +  static int initialized = 0; -  if (pfile->token_buffer) +  if (! initialized)      { -      free (pfile->token_buffer); -      pfile->token_buffer = NULL; -    } +      initialized = 1; -  if (pfile->deps_buffer) -    { -      free (pfile->deps_buffer); -      pfile->deps_buffer = NULL; -      pfile->deps_allocated_size = 0; +#ifdef HOST_EBCDIC +      /* For non-ASCII hosts, the cl_options array needs to be sorted at +	 runtime.  */ +      qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp); +#endif + +      /* Set up the trigraph map.  This doesn't need to do anything if +	 we were compiled with a compiler that supports C99 designated +	 initializers.  */ +      init_trigraph_map ();      } +} + +/* Initialize a cpp_reader structure.  */ +cpp_reader * +cpp_create_reader (lang) +     enum c_lang lang; +{ +  cpp_reader *pfile; + +  /* Initialise this instance of the library if it hasn't been already.  */ +  init_library (); + +  pfile = (cpp_reader *) xcalloc (1, sizeof (cpp_reader)); + +  set_lang (pfile, lang); +  CPP_OPTION (pfile, warn_import) = 1; +  CPP_OPTION (pfile, discard_comments) = 1; +  CPP_OPTION (pfile, show_column) = 1; +  CPP_OPTION (pfile, tabstop) = 8; +  CPP_OPTION (pfile, operator_names) = 1; + +  CPP_OPTION (pfile, pending) = +    (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending)); + +  /* It's simplest to just create this struct whether or not it will +     be needed.  */ +  pfile->deps = deps_init (); + +  /* Initialise the line map.  Start at logical line 1, so we can use +     a line number of zero for special states.  */ +  init_line_maps (&pfile->line_maps); +  pfile->line = 1; + +  /* Initialize lexer state.  */ +  pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + +  /* Set up static tokens.  */ +  pfile->date.type = CPP_EOF; +  pfile->avoid_paste.type = CPP_PADDING; +  pfile->avoid_paste.val.source = NULL; +  pfile->eof.type = CPP_EOF; +  pfile->eof.flags = 0; -  if (pfile->input_buffer) +  /* Create a token buffer for the lexer.  */ +  _cpp_init_tokenrun (&pfile->base_run, 250); +  pfile->cur_run = &pfile->base_run; +  pfile->cur_token = pfile->base_run.base; + +  /* Initialise the base context.  */ +  pfile->context = &pfile->base_context; +  pfile->base_context.macro = 0; +  pfile->base_context.prev = pfile->base_context.next = 0; + +  /* Aligned and unaligned storage.  */ +  pfile->a_buff = _cpp_get_buff (pfile, 0); +  pfile->u_buff = _cpp_get_buff (pfile, 0); + +  /* Initialise the buffer obstack.  */ +  gcc_obstack_init (&pfile->buffer_ob); + +  _cpp_init_includes (pfile); + +  return pfile; +} + +/* Free resources used by PFILE.  Accessing PFILE after this function +   returns leads to undefined behaviour.  Returns the error count.  */ +int +cpp_destroy (pfile) +     cpp_reader *pfile; +{ +  int result; +  struct search_path *dir, *dirn; +  cpp_context *context, *contextn; +  tokenrun *run, *runn; + +  while (CPP_BUFFER (pfile) != NULL) +    _cpp_pop_buffer (pfile); + +  if (pfile->macro_buffer)      { -      free (pfile->input_buffer); -      free (pfile->input_speccase); -      pfile->input_buffer = pfile->input_speccase = NULL; -      pfile->input_buffer_len = 0; +      free ((PTR) pfile->macro_buffer); +      pfile->macro_buffer = NULL; +      pfile->macro_buffer_len = 0;      } -  while (pfile->if_stack) +  deps_free (pfile->deps); +  obstack_free (&pfile->buffer_ob, 0); + +  _cpp_destroy_hashtable (pfile); +  _cpp_cleanup_includes (pfile); + +  _cpp_free_buff (pfile->a_buff); +  _cpp_free_buff (pfile->u_buff); +  _cpp_free_buff (pfile->free_buffs); + +  for (run = &pfile->base_run; run; run = runn)      { -      IF_STACK_FRAME *temp = pfile->if_stack; -      pfile->if_stack = temp->next; -      free (temp); +      runn = run->next; +      free (run->base); +      if (run != &pfile->base_run) +	free (run);      } -  for (i = ALL_INCLUDE_HASHSIZE; --i >= 0; ) +  for (dir = CPP_OPTION (pfile, quote_include); dir; dir = dirn)      { -      struct include_hash *imp = pfile->all_include_files[i]; -      while (imp) -	{ -	  struct include_hash *next = imp->next; -#if 0 -	  /* This gets freed elsewhere - I think. */ -	  free (imp->name); -#endif -	  free (imp); -	  imp = next; -	} -      pfile->all_include_files[i] = 0; +      dirn = dir->next; +      free ((PTR) dir->name); +      free (dir);      } -  for (i = HASHSIZE; --i >= 0;) +  for (context = pfile->base_context.next; context; context = contextn)      { -      while (pfile->hashtab[i]) -	delete_macro (pfile->hashtab[i]); +      contextn = context->next; +      free (context);      } -  free (pfile->hashtab); + +  free_line_maps (&pfile->line_maps); + +  result = pfile->errors; +  free (pfile); + +  return result;  } -/* Initialize the built-in macros.  */ -static void -initialize_builtins (pfile) -     cpp_reader *pfile; +/* This structure defines one built-in identifier.  A node will be +   entered in the hash table under the name NAME, with value VALUE (if +   any).  If flags has OPERATOR, the node's operator field is used; if +   flags has BUILTIN the node's builtin field is used.  Macros that are +   known at build time should not be flagged BUILTIN, as then they do +   not appear in macro dumps with e.g. -dM or -dD. + +   Two values are not compile time constants, so we tag +   them in the FLAGS field instead: +   VERS		value is the global version_string, quoted +   ULP		value is the global user_label_prefix + +   Also, macros with CPLUS set in the flags field are entered only for C++.  */ +struct builtin  { -#define NAME(str) (U_CHAR *)str, sizeof str - 1 -  cpp_install (pfile, NAME("__TIME__"),		  T_TIME,	0, -1); -  cpp_install (pfile, NAME("__DATE__"),		  T_DATE,	0, -1); -  cpp_install (pfile, NAME("__FILE__"),		  T_FILE,	0, -1); -  cpp_install (pfile, NAME("__BASE_FILE__"),	  T_BASE_FILE,	0, -1); -  cpp_install (pfile, NAME("__LINE__"),		  T_SPECLINE,	0, -1); -  cpp_install (pfile, NAME("__INCLUDE_LEVEL__"),  T_INCLUDE_LEVEL, 0, -1); -  cpp_install (pfile, NAME("__VERSION__"),	  T_VERSION,	0, -1); +  const U_CHAR *name; +  const char *value; +  unsigned char builtin; +  unsigned char operator; +  unsigned short flags; +  unsigned short len; +}; +#define VERS		0x01 +#define ULP		0x02 +#define CPLUS		0x04 +#define BUILTIN		0x08 +#define OPERATOR  	0x10 + +#define B(n, t)       { U n, 0, t, 0, BUILTIN, sizeof n - 1 } +#define C(n, v)       { U n, v, 0, 0, 0, sizeof n - 1 } +#define X(n, f)       { U n, 0, 0, 0, f, sizeof n - 1 } +#define O(n, c, f)    { U n, 0, 0, c, OPERATOR | f, sizeof n - 1 } +static const struct builtin builtin_array[] = +{ +  B("__TIME__",		 BT_TIME), +  B("__DATE__",		 BT_DATE), +  B("__FILE__",		 BT_FILE), +  B("__BASE_FILE__",	 BT_BASE_FILE), +  B("__LINE__",		 BT_SPECLINE), +  B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL), +  B("_Pragma",		 BT_PRAGMA), + +  X("__VERSION__",		VERS), +  X("__USER_LABEL_PREFIX__",	ULP), +  C("__REGISTER_PREFIX__",	REGISTER_PREFIX), +  C("__HAVE_BUILTIN_SETJMP__",	"1"), +#if USING_SJLJ_EXCEPTIONS +  /* libgcc needs to know this.  */ +  C("__USING_SJLJ_EXCEPTIONS__","1"), +#endif  #ifndef NO_BUILTIN_SIZE_TYPE -  cpp_install (pfile, NAME("__SIZE_TYPE__"),	  T_CONST, SIZE_TYPE, -1); +  C("__SIZE_TYPE__",		SIZE_TYPE),  #endif  #ifndef NO_BUILTIN_PTRDIFF_TYPE -  cpp_install (pfile, NAME("__PTRDIFF_TYPE__ "),  T_CONST, PTRDIFF_TYPE, -1); +  C("__PTRDIFF_TYPE__",		PTRDIFF_TYPE),  #endif -  cpp_install (pfile, NAME("__WCHAR_TYPE__"),	  T_CONST, WCHAR_TYPE, -1); -  cpp_install (pfile, NAME("__USER_LABEL_PREFIX__"), T_CONST, user_label_prefix, -1); -  cpp_install (pfile, NAME("__REGISTER_PREFIX__"),  T_CONST, REGISTER_PREFIX, -1); -  cpp_install (pfile, NAME("__HAVE_BUILTIN_SETJMP__"), T_CONST, "1", -1); -  if (!CPP_TRADITIONAL (pfile)) -    { -      cpp_install (pfile, NAME("__STDC__"),	  T_STDC,  0, -1); -#if 0 -      if (CPP_OPTIONS (pfile)->c9x) -	cpp_install (pfile, NAME("__STDC_VERSION__"),T_CONST, "199909L", -1); -      else +#ifndef NO_BUILTIN_WCHAR_TYPE +  C("__WCHAR_TYPE__",		WCHAR_TYPE),  #endif -	cpp_install (pfile, NAME("__STDC_VERSION__"),T_CONST, "199409L", -1); -    } -#undef NAME - -  if (CPP_OPTIONS (pfile)->debug_output) -    { -      dump_special_to_buffer (pfile, "__BASE_FILE__"); -      dump_special_to_buffer (pfile, "__VERSION__"); -#ifndef NO_BUILTIN_SIZE_TYPE -      dump_special_to_buffer (pfile, "__SIZE_TYPE__"); +#ifndef NO_BUILTIN_WINT_TYPE +  C("__WINT_TYPE__",		WINT_TYPE),  #endif -#ifndef NO_BUILTIN_PTRDIFF_TYPE -      dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__"); +#ifdef STDC_0_IN_SYSTEM_HEADERS +  B("__STDC__",		 BT_STDC), +#else +  C("__STDC__",		 "1"),  #endif -      dump_special_to_buffer (pfile, "__WCHAR_TYPE__"); -      dump_special_to_buffer (pfile, "__DATE__"); -      dump_special_to_buffer (pfile, "__TIME__"); -      if (!CPP_TRADITIONAL (pfile)) -	dump_special_to_buffer (pfile, "__STDC__"); -    } -} -/* Another subroutine of cpp_start_read.  This one sets up to do -   dependency-file output. */ +  /* Named operators known to the preprocessor.  These cannot be #defined +     and always have their stated meaning.  They are treated like normal +     identifiers except for the type code and the meaning.  Most of them +     are only for C++ (but see iso646.h).  */ +  O("and",	CPP_AND_AND, CPLUS), +  O("and_eq",	CPP_AND_EQ,  CPLUS), +  O("bitand",	CPP_AND,     CPLUS), +  O("bitor",	CPP_OR,      CPLUS), +  O("compl",	CPP_COMPL,   CPLUS), +  O("not",	CPP_NOT,     CPLUS), +  O("not_eq",	CPP_NOT_EQ,  CPLUS), +  O("or",	CPP_OR_OR,   CPLUS), +  O("or_eq",	CPP_OR_EQ,   CPLUS), +  O("xor",	CPP_XOR,     CPLUS), +  O("xor_eq",	CPP_XOR_EQ,  CPLUS) +}; +#undef B +#undef C +#undef X +#undef O +#define builtin_array_end \ + builtin_array + sizeof(builtin_array)/sizeof(struct builtin) + +/* Subroutine of cpp_read_main_file; reads the builtins table above and +   enters them, and language-specific macros, into the hash table.  */  static void -initialize_dependency_output (pfile) +init_builtins (pfile)       cpp_reader *pfile;  { -  cpp_options *opts = CPP_OPTIONS (pfile); -  char *spec, *s, *output_file; -   -  /* Either of two environment variables can specify output of deps. -     Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", -     where OUTPUT_FILE is the file to write deps info to -     and DEPS_TARGET is the target to mention in the deps.  */ +  const struct builtin *b; -  if (opts->print_deps == 0) +  for(b = builtin_array; b < builtin_array_end; b++)      { -      spec = getenv ("DEPENDENCIES_OUTPUT"); -      if (spec) -	opts->print_deps = 1; -      else +      if ((b->flags & CPLUS) && ! CPP_OPTION (pfile, cplusplus)) +	continue; + +      if ((b->flags & OPERATOR) && ! CPP_OPTION (pfile, operator_names)) +	continue; + +      if (b->flags & (OPERATOR | BUILTIN))  	{ -	  spec = getenv ("SUNPRO_DEPENDENCIES"); -	  if (spec) -	    opts->print_deps = 2; +	  cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); +	  if (b->flags & OPERATOR) +	    { +	      hp->flags |= NODE_OPERATOR; +	      hp->value.operator = b->operator; +	    }  	  else -	    return; +	    { +	      hp->type = NT_MACRO; +	      hp->flags |= NODE_BUILTIN | NODE_WARN; +	      hp->value.builtin = b->builtin; +	    }  	} - -      /* Find the space before the DEPS_TARGET, if there is one.  */ -      s = strchr (spec, ' '); -      if (s) +      else			/* A standard macro of some kind.  */  	{ -	  opts->deps_target = s + 1; -	  output_file = (char *) xmalloc (s - spec + 1); -	  memcpy (output_file, spec, s - spec); -	  output_file[s - spec] = 0; +	  const char *val; +	  char *str; + +	  if (b->flags & VERS) +	    { +	      /* Allocate enough space for 'name "value"\n\0'.  */ +	      str = alloca (b->len + strlen (version_string) + 5); +	      sprintf (str, "%s \"%s\"\n", b->name, version_string); +	    } +	  else +	    { +	      if (b->flags & ULP) +		val = CPP_OPTION (pfile, user_label_prefix); +	      else +		val = b->value; + +	      /* Allocate enough space for "name value\n\0".  */ +	      str = alloca (b->len + strlen (val) + 3); +	      sprintf(str, "%s %s\n", b->name, val); +	    } + +	  _cpp_define_builtin (pfile, str);  	} +    } + +  if (CPP_OPTION (pfile, cplusplus)) +    { +      _cpp_define_builtin (pfile, "__cplusplus 1"); +      if (SUPPORTS_ONE_ONLY) +	_cpp_define_builtin (pfile, "__GXX_WEAK__ 1");        else -	{ -	  opts->deps_target = 0; -	  output_file = spec; -	} +	_cpp_define_builtin (pfile, "__GXX_WEAK__ 0"); +    } +  if (CPP_OPTION (pfile, objc)) +    _cpp_define_builtin (pfile, "__OBJC__ 1"); + +  if (CPP_OPTION (pfile, lang) == CLK_STDC94) +    _cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L"); +  else if (CPP_OPTION (pfile, c99)) +    _cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L"); + +  if (CPP_OPTION (pfile, lang) == CLK_STDC89 +      || CPP_OPTION (pfile, lang) == CLK_STDC94 +      || CPP_OPTION (pfile, lang) == CLK_STDC99) +    _cpp_define_builtin (pfile, "__STRICT_ANSI__ 1"); +  else if (CPP_OPTION (pfile, lang) == CLK_ASM) +    _cpp_define_builtin (pfile, "__ASSEMBLER__ 1"); +} +#undef BUILTIN +#undef OPERATOR +#undef VERS +#undef ULP +#undef CPLUS +#undef builtin_array_end + +/* And another subroutine.  This one sets up the standard include path.  */ +static void +init_standard_includes (pfile) +     cpp_reader *pfile; +{ +  char *path; +  const struct default_include *p; +  const char *specd_prefix = CPP_OPTION (pfile, include_prefix); + +  /* Several environment variables may add to the include search path. +     CPATH specifies an additional list of directories to be searched +     as if specified with -I, while C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, +     etc. specify an additional list of directories to be searched as +     if specified with -isystem, for the language indicated.  */ + +  GET_ENV_PATH_LIST (path, "CPATH"); +  if (path != 0 && *path != 0) +    path_include (pfile, path, BRACKET); -      opts->deps_file = output_file; -      opts->print_deps_append = 1; +  switch ((CPP_OPTION (pfile, objc) << 1) + CPP_OPTION (pfile, cplusplus)) +    { +    case 0: +      GET_ENV_PATH_LIST (path, "C_INCLUDE_PATH"); +      break; +    case 1: +      GET_ENV_PATH_LIST (path, "CPLUS_INCLUDE_PATH"); +      break; +    case 2: +      GET_ENV_PATH_LIST (path, "OBJC_INCLUDE_PATH"); +      break; +    case 3: +      GET_ENV_PATH_LIST (path, "OBJCPLUS_INCLUDE_PATH"); +      break;      } +  if (path != 0 && *path != 0) +    path_include (pfile, path, SYSTEM); -  /* Print the expected object file name as the target of this Make-rule.  */ -  pfile->deps_allocated_size = 200; -  pfile->deps_buffer = (char *) xmalloc (pfile->deps_allocated_size); -  pfile->deps_buffer[0] = 0; -  pfile->deps_size = 0; -  pfile->deps_column = 0; - -  if (opts->deps_target) -    deps_output (pfile, opts->deps_target, ':'); -  else if (*opts->in_fname == 0) -    deps_output (pfile, "-", ':'); -  else +  /* Search "translated" versions of GNU directories. +     These have /usr/local/lib/gcc... replaced by specd_prefix.  */ +  if (specd_prefix != 0 && cpp_GCC_INCLUDE_DIR_len)      { -      char *p, *q, *r; -      int len, x; - -      /* Discard all directory prefixes from filename.  */ -      q = base_name (opts->in_fname); - -      /* Copy remainder to mungable area.  */ -      len = strlen (q); -      p = (char *) alloca (len + 8); -      strcpy (p, q); - -      /* Output P, but remove known suffixes.  */ -      q = p + len; -      /* Point to the filename suffix.  */ -      r = rindex (p, '.'); -      /* Compare against the known suffixes.  */ -      for (x = 0; known_suffixes[x]; x++) +      /* Remove the `include' from /usr/local/lib/gcc.../include. +	 GCC_INCLUDE_DIR will always end in /include.  */ +      int default_len = cpp_GCC_INCLUDE_DIR_len; +      char *default_prefix = (char *) alloca (default_len + 1); +      int specd_len = strlen (specd_prefix); + +      memcpy (default_prefix, cpp_GCC_INCLUDE_DIR, default_len); +      default_prefix[default_len] = '\0'; + +      for (p = cpp_include_defaults; p->fname; p++)  	{ -	  if (strncmp (known_suffixes[x], r, q - r) == 0) +	  /* Some standard dirs are only for C++.  */ +	  if (!p->cplusplus +	      || (CPP_OPTION (pfile, cplusplus) +		  && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))  	    { -	      /* Make q point to the bit we're going to overwrite -		 with an object suffix.  */ -	      q = r; -	      break; +	      /* Does this dir start with the prefix?  */ +	      if (!memcmp (p->fname, default_prefix, default_len)) +		{ +		  /* Yes; change prefix and add to search list.  */ +		  int flen = strlen (p->fname); +		  int this_len = specd_len + flen - default_len; +		  char *str = (char *) xmalloc (this_len + 1); +		  memcpy (str, specd_prefix, specd_len); +		  memcpy (str + specd_len, +			  p->fname + default_len, +			  flen - default_len + 1); + +		  append_include_chain (pfile, str, SYSTEM, p->cxx_aware); +		}  	    }  	} +    } -      /* Supply our own suffix.  */ -      strcpy (q, OBJECT_SUFFIX); - -      deps_output (pfile, p, ':'); -      deps_output (pfile, opts->in_fname, ' '); +  /* Search ordinary names for GNU include directories.  */ +  for (p = cpp_include_defaults; p->fname; p++) +    { +      /* Some standard dirs are only for C++.  */ +      if (!p->cplusplus +	  || (CPP_OPTION (pfile, cplusplus) +	      && !CPP_OPTION (pfile, no_standard_cplusplus_includes))) +	{ +	  char *str = update_path (p->fname, p->component); +	  append_include_chain (pfile, str, SYSTEM, p->cxx_aware); +	}      }  } -/* This is called after options have been processed. - * Check options for consistency, and setup for processing input - * from the file named FNAME.  (Use standard input if FNAME==NULL.) - * Return 1 on success, 0 on failure. - */ - -int -cpp_start_read (pfile, fname) +/* Pushes a command line -imacro and -include file indicated by P onto +   the buffer stack.  Returns non-zero if successful.  */ +static bool +push_include (pfile, p)       cpp_reader *pfile; -     char *fname; +     struct pending_option *p;  { -  struct cpp_options *opts = CPP_OPTIONS (pfile); -  struct pending_option *p, *q; -  int f; -  cpp_buffer *fp; -  struct include_hash *ih_fake; - -  /* -MG doesn't select the form of output and must be specified with one of -     -M or -MM.  -MG doesn't make sense with -MD or -MMD since they don't -     inhibit compilation.  */ -  if (opts->print_deps_missing_files -      && (opts->print_deps == 0 || !opts->no_output)) -    { -      cpp_fatal (pfile, "-MG must be specified with one of -M or -MM"); -      return 0; -    } +  cpp_token header; + +  /* Later: maybe update this to use the #include "" search path +     if cpp_read_file fails.  */ +  header.type = CPP_STRING; +  header.val.str.text = (const unsigned char *) p->arg; +  header.val.str.len = strlen (p->arg); +  /* Make the command line directive take up a line.  */ +  pfile->line++; + +  return _cpp_execute_include (pfile, &header, IT_CMDLINE); +} + +/* Frees a pending_option chain.  */ +static void +free_chain (head) +     struct pending_option *head; +{ +  struct pending_option *next; -  /* Chill should not be used with -trigraphs. */ -  if (opts->chill && opts->trigraphs) +  while (head)      { -      cpp_warning (pfile, "-lang-chill and -trigraphs are mutually exclusive"); -      opts->trigraphs = 0; +      next = head->next; +      free (head); +      head = next;      } +} -  /* Set this if it hasn't been set already. */ -  if (user_label_prefix == NULL) -    user_label_prefix = USER_LABEL_PREFIX; -   -  /* Now that we know dollars_in_ident, we can initialize the syntax -     tables. */ -  initialize_char_syntax (opts->dollars_in_ident); - -  /* Do partial setup of input buffer for the sake of generating -     early #line directives (when -g is in effect).  */ -  fp = cpp_push_buffer (pfile, NULL, 0); -  if (!fp) -    return 0; -  if (opts->in_fname == NULL || *opts->in_fname == 0) +/* This is called after options have been parsed, and partially +   processed.  Setup for processing input from the file named FNAME, +   or stdin if it is the empty string.  Return the original filename +   on success (e.g. foo.i->foo.c), or NULL on failure.  */ +const char * +cpp_read_main_file (pfile, fname, table) +     cpp_reader *pfile; +     const char *fname; +     hash_table *table; +{ +  /* The front ends don't set up the hash table until they have +     finished processing the command line options, so initializing the +     hashtable is deferred until now.  */ +  _cpp_init_hashtable (pfile, table); + +  /* Set up the include search path now.  */ +  if (! CPP_OPTION (pfile, no_standard_includes)) +    init_standard_includes (pfile); + +  merge_include_chains (pfile); + +  /* With -v, print the list of dirs to search.  */ +  if (CPP_OPTION (pfile, verbose))      { -      opts->in_fname = fname; -      if (opts->in_fname == NULL) -	opts->in_fname = ""; +      struct search_path *l; +      fprintf (stderr, _("#include \"...\" search starts here:\n")); +      for (l = CPP_OPTION (pfile, quote_include); l; l = l->next) +	{ +	  if (l == CPP_OPTION (pfile, bracket_include)) +	    fprintf (stderr, _("#include <...> search starts here:\n")); +	  fprintf (stderr, " %s\n", l->name); +	} +      fprintf (stderr, _("End of search list.\n"));      } -  fp->nominal_fname = fp->fname = opts->in_fname; -  fp->lineno = 0; -  /* Install __LINE__, etc.  Must follow initialize_char_syntax -     and option processing.  */ -  initialize_builtins (pfile); +  if (CPP_OPTION (pfile, print_deps)) +    /* Set the default target (if there is none already).  */ +    deps_add_default_target (pfile->deps, fname); -  /* Do -U's, -D's and -A's in the order they were seen.  */ -  p = opts->pending->define_head; -  while (p) -    { -      if (opts->debug_output) -	output_line_command (pfile, same_file); -      if (p->undef) -	cpp_undef (pfile, p->arg); -      else -	cpp_define (pfile, p->arg); +  /* Open the main input file.  */ +  if (!_cpp_read_file (pfile, fname)) +    return NULL; -      q = p->next; -      free (p); -      p = q; -    } +  /* Set this after cpp_post_options so the client can change the +     option if it wishes, and after stacking the main file so we don't +     trace the main file.  */ +  pfile->line_maps.trace_includes = CPP_OPTION (pfile, print_include_names); -  p = opts->pending->assert_head; -  while (p) -    { -      if (opts->debug_output) -	output_line_command (pfile, same_file); -      if (p->undef) -	cpp_unassert (pfile, p->arg); -      else -	cpp_assert (pfile, p->arg); +  /* For foo.i, read the original filename foo.c now, for the benefit +     of the front ends.  */ +  if (CPP_OPTION (pfile, preprocessed)) +    read_original_filename (pfile); -      q = p->next; -      free (p); -      p = q; -    } -   -  opts->done_initializing = 1; +  return pfile->map->to_file; +} -  /* Several environment variables may add to the include search path. -     CPATH specifies an additional list of directories to be searched -     as if specified with -I, while C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, -     etc. specify an additional list of directories to be searched as -     if specified with -isystem, for the language indicated. +/* For preprocessed files, if the first tokens are of the form # NUM. +   handle the directive so we know the original file name.  This will +   generate file_change callbacks, which the front ends must handle +   appropriately given their state of initialization.  */ +static void +read_original_filename (pfile) +     cpp_reader *pfile; +{ +  const cpp_token *token, *token1; -     These variables are ignored if -nostdinc is on.  */ -  if (! opts->no_standard_includes) +  /* Lex ahead; if the first tokens are of the form # NUM, then +     process the directive, otherwise back up.  */ +  token = _cpp_lex_direct (pfile); +  if (token->type == CPP_HASH)      { -      char *path; -      GET_ENV_PATH_LIST (path, "CPATH"); -      if (path != 0 && *path != 0) -	path_include (pfile, opts->pending, path, BRACKET); +      token1 = _cpp_lex_direct (pfile); +      _cpp_backup_tokens (pfile, 1); -      switch ((opts->objc << 1) + opts->cplusplus) +      /* If it's a #line directive, handle it.  */ +      if (token1->type == CPP_NUMBER)  	{ -	case 0: -	  GET_ENV_PATH_LIST (path, "C_INCLUDE_PATH"); -	  break; -	case 1: -	  GET_ENV_PATH_LIST (path, "CPLUS_INCLUDE_PATH"); -	  break; -	case 2: -	  GET_ENV_PATH_LIST (path, "OBJC_INCLUDE_PATH"); -	  break; -	case 3: -	  GET_ENV_PATH_LIST (path, "OBJCPLUS_INCLUDE_PATH"); -	  break; +	  _cpp_handle_directive (pfile, token->flags & PREV_WHITE); +	  return;  	} -      if (path != 0 && *path != 0) -	path_include (pfile, opts->pending, path, SYSTEM);      } -  /* Unless -nostdinc, add the compiled-in include path to the list, -     translating prefixes. */ -  if (!opts->no_standard_includes) -    { -      struct default_include *p = include_defaults_array; -      char *specd_prefix = opts->include_prefix; - -      /* Search "translated" versions of GNU directories. -	 These have /usr/local/lib/gcc... replaced by specd_prefix.  */ -      if (specd_prefix != 0) -	{ -	  char *default_prefix = alloca (sizeof GCC_INCLUDE_DIR - 7); -	  /* Remove the `include' from /usr/local/lib/gcc.../include. -	     GCC_INCLUDE_DIR will always end in /include. */ -	  int default_len = sizeof GCC_INCLUDE_DIR - 8; -	  int specd_len = strlen (specd_prefix); +  /* Backup as if nothing happened.  */ +  _cpp_backup_tokens (pfile, 1); +} -	  default_len = sizeof GCC_INCLUDE_DIR - 8; -	  memcpy (default_prefix, GCC_INCLUDE_DIR, default_len); -	  default_prefix[default_len] = '\0'; +/* Handle pending command line options: -D, -U, -A, -imacros and +   -include.  This should be called after debugging has been properly +   set up in the front ends.  */ +void +cpp_finish_options (pfile) +     cpp_reader *pfile; +{ +  /* Install builtins and process command line macros etc. in the order +     they appeared, but only if not already preprocessed.  */ +  if (! CPP_OPTION (pfile, preprocessed)) +    { +      struct pending_option *p; -	  for (p = include_defaults_array; p->fname; p++) -	    { -	      /* Some standard dirs are only for C++.  */ -	      if (!p->cplusplus -		  || (opts->cplusplus -		      && !opts->no_standard_cplusplus_includes)) -		{ -		  /* Does this dir start with the prefix?  */ -		  if (!strncmp (p->fname, default_prefix, default_len)) -		    { -		      /* Yes; change prefix and add to search list.  */ -		      int flen = strlen (p->fname); -		      int this_len = specd_len + flen - default_len; -		      char *str = (char *) xmalloc (this_len + 1); -		      memcpy (str, specd_prefix, specd_len); -		      memcpy (str + specd_len, -			      p->fname + default_len, -			      flen - default_len + 1); - -		      append_include_chain (pfile, opts->pending, -					    str, SYSTEM); -		    } -		} -	    } -	} +      _cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0); +      init_builtins (pfile); +      _cpp_do_file_change (pfile, LC_RENAME, _("<command line>"), 1, 0); +      for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next) +	(*p->handler) (pfile, p->arg); -      /* Search ordinary names for GNU include directories.  */ -      for (p = include_defaults_array; p->fname; p++) +      /* Scan -imacros files after command line defines, but before +	 files given with -include.  */ +      while ((p = CPP_OPTION (pfile, pending)->imacros_head) != NULL)  	{ -	  /* Some standard dirs are only for C++.  */ -	  if (!p->cplusplus -	      || (opts->cplusplus -		  && !opts->no_standard_cplusplus_includes)) +	  if (push_include (pfile, p))  	    { -	      char *str = (char *) update_path (p->fname, p->component); -	      str = xstrdup (str);  /* XXX Potential memory leak! */ -	      append_include_chain (pfile, opts->pending, str, SYSTEM); +	      pfile->buffer->return_at_eof = true; +	      cpp_scan_nooutput (pfile);  	    } +	  CPP_OPTION (pfile, pending)->imacros_head = p->next; +	  free (p);  	}      } -  merge_include_chains (opts); +  free_chain (CPP_OPTION (pfile, pending)->directive_head); +  _cpp_push_next_buffer (pfile); +} -  /* With -v, print the list of dirs to search.  */ -  if (opts->verbose) +/* Called to push the next buffer on the stack given by -include.  If +   there are none, free the pending structure and restore the line map +   for the main file.  */ +bool +_cpp_push_next_buffer (pfile) +     cpp_reader *pfile; +{ +  bool pushed = false; + +  /* This is't pretty; we'd rather not be relying on this as a boolean +     for reverting the line map.  Further, we only free the chains in +     this conditional, so an early call to cpp_finish / cpp_destroy +     will leak that memory.  */ +  if (CPP_OPTION (pfile, pending) +      && CPP_OPTION (pfile, pending)->imacros_head == NULL)      { -      struct file_name_list *p; -      cpp_message (pfile, -1, "#include \"...\" search starts here:\n"); -      for (p = opts->quote_include; p; p = p->next) +      while (!pushed)  	{ -	  if (p == opts->bracket_include) -	    cpp_message (pfile, -1, "#include <...> search starts here:\n"); -	  fprintf (stderr, " %s\n", p->name); +	  struct pending_option *p = CPP_OPTION (pfile, pending)->include_head; + +	  if (p == NULL) +	    break; +	  if (! CPP_OPTION (pfile, preprocessed)) +	    pushed = push_include (pfile, p); +	  CPP_OPTION (pfile, pending)->include_head = p->next; +	  free (p);  	} -      cpp_message (pfile, -1, "End of search list.\n"); -    } -  /* Open the main input file. -     We do this in nonblocking mode so we don't get stuck here if -     someone clever has asked cpp to process /dev/rmt0; -     finclude() will check that we have a real file to work with.  */ -  if (fname == NULL || *fname == 0) -    { -      fname = ""; -      f = 0; -    } -  else if ((f = open (fname, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666)) < 0) -    cpp_pfatal_with_name (pfile, fname); - -  initialize_dependency_output (pfile); - -  /* Must call finclude() on the main input before processing -     -include switches; otherwise the -included text winds up -     after the main input. */ -  ih_fake = (struct include_hash *) xmalloc (sizeof (struct include_hash)); -  ih_fake->next = 0; -  ih_fake->next_this_file = 0; -  ih_fake->foundhere = ABSOLUTE_PATH;  /* well sort of ... */ -  ih_fake->name = fname; -  ih_fake->control_macro = 0; -  ih_fake->buf = (char *)-1; -  ih_fake->limit = 0; -  if (!finclude (pfile, f, ih_fake)) -    return 0; -  output_line_command (pfile, same_file); -  pfile->only_seen_white = 2; - -  /* The -imacros files can be scanned now, but the -include files -     have to be pushed onto the include stack and processed later, -     in the main loop calling cpp_get_token.  */ -   -  pfile->no_record_file++; -  opts->no_output++; -  p = opts->pending->imacros_head; -  while (p) -    { -      int fd = open (p->arg, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666); -      if (fd < 0) +      if (!pushed)  	{ -	  cpp_perror_with_name (pfile, p->arg); -	  return 0; +	  free (CPP_OPTION (pfile, pending)); +	  CPP_OPTION (pfile, pending) = NULL; + +	  /* Restore the line map for the main file.  */ +	  if (! CPP_OPTION (pfile, preprocessed)) +	    _cpp_do_file_change (pfile, LC_RENAME, +				 pfile->line_maps.maps[0].to_file, 1, 0);  	} -      if (!cpp_push_buffer (pfile, NULL, 0)) -	return 0; - -      ih_fake = (struct include_hash *) -	xmalloc (sizeof (struct include_hash)); -      ih_fake->next = 0; -      ih_fake->next_this_file = 0; -      ih_fake->foundhere = ABSOLUTE_PATH;  /* well sort of ... */ -      ih_fake->name = p->arg; -      ih_fake->control_macro = 0; -      ih_fake->buf = (char *)-1; -      ih_fake->limit = 0; -      if (!finclude (pfile, fd, ih_fake)) -	cpp_scan_buffer (pfile); -      free (ih_fake); - -      q = p->next; -      free (p); -      p = q;      } -  opts->no_output--; +  return pushed; +} + +/* Use mkdeps.c to output dependency information.  */ +static void +output_deps (pfile) +     cpp_reader *pfile; +{ +  /* Stream on which to print the dependency information.  */ +  FILE *deps_stream = 0; +  const char *const deps_mode = +    CPP_OPTION (pfile, print_deps_append) ? "a" : "w"; -  p = opts->pending->include_head; -  while (p) +  if (CPP_OPTION (pfile, deps_file) == 0) +    deps_stream = stdout; +  else      { -      int fd = open (p->arg, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666); -      if (fd < 0) +      deps_stream = fopen (CPP_OPTION (pfile, deps_file), deps_mode); +      if (deps_stream == 0)  	{ -	  cpp_perror_with_name (pfile, p->arg); -	  return 0; +	  cpp_notice_from_errno (pfile, CPP_OPTION (pfile, deps_file)); +	  return;  	} -      if (!cpp_push_buffer (pfile, NULL, 0)) -	return 0; - -      ih_fake = (struct include_hash *) -	xmalloc (sizeof (struct include_hash)); -      ih_fake->next = 0; -      ih_fake->next_this_file = 0; -      ih_fake->foundhere = ABSOLUTE_PATH;  /* well sort of ... */ -      ih_fake->name = p->arg; -      ih_fake->control_macro = 0; -      ih_fake->buf = (char *)-1; -      ih_fake->limit = 0; -      if (finclude (pfile, fd, ih_fake)) -	output_line_command (pfile, enter_file); - -      q = p->next; -      free (p); -      p = q;      } -  pfile->no_record_file--; -  free (opts->pending); -  opts->pending = NULL; +  deps_write (pfile->deps, deps_stream, 72); + +  if (CPP_OPTION (pfile, deps_phony_targets)) +    deps_phony_targets (pfile->deps, deps_stream); -  return 1; +  /* Don't close stdout.  */ +  if (CPP_OPTION (pfile, deps_file)) +    { +      if (ferror (deps_stream) || fclose (deps_stream) != 0) +	cpp_fatal (pfile, "I/O error on output"); +    }  }  /* This is called at the end of preprocessing.  It pops the     last buffer and writes dependency output.  It should also     clear macro definitions, such that you could call cpp_start_read -   with a new filename to restart processing. */ +   with a new filename to restart processing.  */  void  cpp_finish (pfile)       cpp_reader *pfile;  { -  struct cpp_options *opts = CPP_OPTIONS (pfile); +  /* cpplex.c leaves the final buffer on the stack.  This it so that +     it returns an unending stream of CPP_EOFs to the client.  If we +     popped the buffer, we'd dereference a NULL buffer pointer and +     segfault.  It's nice to allow the client to do worry-free excess +     cpp_get_token calls.  */ +  while (pfile->buffer) +    _cpp_pop_buffer (pfile); + +  /* Don't write the deps file if preprocessing has failed.  */ +  if (CPP_OPTION (pfile, print_deps) && pfile->errors == 0) +    output_deps (pfile); + +  /* Report on headers that could use multiple include guards.  */ +  if (CPP_OPTION (pfile, print_include_names)) +    _cpp_report_missing_guards (pfile); +} -  if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) != CPP_NULL_BUFFER (pfile)) -    cpp_fatal (pfile, -	       "cpplib internal error: buffers still stacked in cpp_finish"); -  cpp_pop_buffer (pfile); -   -  if (opts->print_deps) +/* Add a directive to be handled later in the initialization phase.  */ +static void +new_pending_directive (pend, text, handler) +     struct cpp_pending *pend; +     const char *text; +     cl_directive_handler handler; +{ +  struct pending_option *o = (struct pending_option *) +    xmalloc (sizeof (struct pending_option)); + +  o->arg = text; +  o->next = NULL; +  o->handler = handler; +  APPEND (pend, directive, o); +} + +/* Irix6 "cc -n32" and OSF4 cc have problems with char foo[] = ("string"); +   I.e. a const string initializer with parens around it.  That is +   what N_("string") resolves to, so we make no_* be macros instead.  */ +#define no_arg N_("argument missing after %s") +#define no_ass N_("assertion missing after %s") +#define no_dir N_("directory name missing after %s") +#define no_fil N_("file name missing after %s") +#define no_mac N_("macro name missing after %s") +#define no_pth N_("path name missing after %s") +#define no_num N_("number missing after %s") +#define no_tgt N_("target missing after %s") + +/* This is the list of all command line options, with the leading +   "-" removed.  It must be sorted in ASCII collating order.  */ +#define COMMAND_LINE_OPTIONS                                                  \ +  DEF_OPT("$",                        0,      OPT_dollar)                     \ +  DEF_OPT("+",                        0,      OPT_plus)                       \ +  DEF_OPT("-help",                    0,      OPT__help)                      \ +  DEF_OPT("-target-help",             0,      OPT_target__help)               \ +  DEF_OPT("-version",                 0,      OPT__version)                   \ +  DEF_OPT("A",                        no_ass, OPT_A)                          \ +  DEF_OPT("C",                        0,      OPT_C)                          \ +  DEF_OPT("D",                        no_mac, OPT_D)                          \ +  DEF_OPT("H",                        0,      OPT_H)                          \ +  DEF_OPT("I",                        no_dir, OPT_I)                          \ +  DEF_OPT("M",                        0,      OPT_M)                          \ +  DEF_OPT("MD",                       no_fil, OPT_MD)                         \ +  DEF_OPT("MF",                       no_fil, OPT_MF)                         \ +  DEF_OPT("MG",                       0,      OPT_MG)                         \ +  DEF_OPT("MM",                       0,      OPT_MM)                         \ +  DEF_OPT("MMD",                      no_fil, OPT_MMD)                        \ +  DEF_OPT("MP",                       0,      OPT_MP)                         \ +  DEF_OPT("MQ",                       no_tgt, OPT_MQ)                         \ +  DEF_OPT("MT",                       no_tgt, OPT_MT)                         \ +  DEF_OPT("P",                        0,      OPT_P)                          \ +  DEF_OPT("U",                        no_mac, OPT_U)                          \ +  DEF_OPT("W",                        no_arg, OPT_W)  /* arg optional */      \ +  DEF_OPT("d",                        no_arg, OPT_d)                          \ +  DEF_OPT("fleading-underscore",      0,      OPT_fleading_underscore)        \ +  DEF_OPT("fno-leading-underscore",   0,      OPT_fno_leading_underscore)     \ +  DEF_OPT("fno-operator-names",       0,      OPT_fno_operator_names)         \ +  DEF_OPT("fno-preprocessed",         0,      OPT_fno_preprocessed)           \ +  DEF_OPT("fno-show-column",          0,      OPT_fno_show_column)            \ +  DEF_OPT("fpreprocessed",            0,      OPT_fpreprocessed)              \ +  DEF_OPT("fshow-column",             0,      OPT_fshow_column)               \ +  DEF_OPT("ftabstop=",                no_num, OPT_ftabstop)                   \ +  DEF_OPT("h",                        0,      OPT_h)                          \ +  DEF_OPT("idirafter",                no_dir, OPT_idirafter)                  \ +  DEF_OPT("imacros",                  no_fil, OPT_imacros)                    \ +  DEF_OPT("include",                  no_fil, OPT_include)                    \ +  DEF_OPT("iprefix",                  no_pth, OPT_iprefix)                    \ +  DEF_OPT("isystem",                  no_dir, OPT_isystem)                    \ +  DEF_OPT("iwithprefix",              no_dir, OPT_iwithprefix)                \ +  DEF_OPT("iwithprefixbefore",        no_dir, OPT_iwithprefixbefore)          \ +  DEF_OPT("lang-asm",                 0,      OPT_lang_asm)                   \ +  DEF_OPT("lang-c",                   0,      OPT_lang_c)                     \ +  DEF_OPT("lang-c++",                 0,      OPT_lang_cplusplus)             \ +  DEF_OPT("lang-c89",                 0,      OPT_lang_c89)                   \ +  DEF_OPT("lang-objc",                0,      OPT_lang_objc)                  \ +  DEF_OPT("lang-objc++",              0,      OPT_lang_objcplusplus)          \ +  DEF_OPT("nostdinc",                 0,      OPT_nostdinc)                   \ +  DEF_OPT("nostdinc++",               0,      OPT_nostdincplusplus)           \ +  DEF_OPT("o",                        no_fil, OPT_o)                          \ +  DEF_OPT("pedantic",                 0,      OPT_pedantic)                   \ +  DEF_OPT("pedantic-errors",          0,      OPT_pedantic_errors)            \ +  DEF_OPT("remap",                    0,      OPT_remap)                      \ +  DEF_OPT("std=c++98",                0,      OPT_std_cplusplus98)            \ +  DEF_OPT("std=c89",                  0,      OPT_std_c89)                    \ +  DEF_OPT("std=c99",                  0,      OPT_std_c99)                    \ +  DEF_OPT("std=c9x",                  0,      OPT_std_c9x)                    \ +  DEF_OPT("std=gnu89",                0,      OPT_std_gnu89)                  \ +  DEF_OPT("std=gnu99",                0,      OPT_std_gnu99)                  \ +  DEF_OPT("std=gnu9x",                0,      OPT_std_gnu9x)                  \ +  DEF_OPT("std=iso9899:1990",         0,      OPT_std_iso9899_1990)           \ +  DEF_OPT("std=iso9899:199409",       0,      OPT_std_iso9899_199409)         \ +  DEF_OPT("std=iso9899:1999",         0,      OPT_std_iso9899_1999)           \ +  DEF_OPT("std=iso9899:199x",         0,      OPT_std_iso9899_199x)           \ +  DEF_OPT("trigraphs",                0,      OPT_trigraphs)                  \ +  DEF_OPT("v",                        0,      OPT_v)                          \ +  DEF_OPT("version",                  0,      OPT_version)                    \ +  DEF_OPT("w",                        0,      OPT_w) + +#define DEF_OPT(text, msg, code) code, +enum opt_code +{ +  COMMAND_LINE_OPTIONS +  N_OPTS +}; +#undef DEF_OPT + +struct cl_option +{ +  const char *opt_text; +  const char *msg; +  size_t opt_len; +  enum opt_code opt_code; +}; + +#define DEF_OPT(text, msg, code) { text, msg, sizeof(text) - 1, code }, +#ifdef HOST_EBCDIC +static struct cl_option cl_options[] = +#else +static const struct cl_option cl_options[] = +#endif +{ +  COMMAND_LINE_OPTIONS +}; +#undef DEF_OPT +#undef COMMAND_LINE_OPTIONS + +/* Perform a binary search to find which, if any, option the given +   command-line matches.  Returns its index in the option array, +   negative on failure.  Complications arise since some options can be +   suffixed with an argument, and multiple complete matches can occur, +   e.g. -iwithprefix and -iwithprefixbefore.  Moreover, we need to +   accept options beginning with -W that we do not recognise, but not +   to swallow any subsequent command line argument; this is handled as +   special cases in cpp_handle_option.  */ +static int +parse_option (input) +     const char *input; +{ +  unsigned int md, mn, mx; +  size_t opt_len; +  int comp; + +  mn = 0; +  mx = N_OPTS; + +  while (mx > mn)      { -      /* Stream on which to print the dependency information.  */ -      FILE *deps_stream; +      md = (mn + mx) / 2; + +      opt_len = cl_options[md].opt_len; +      comp = memcmp (input, cl_options[md].opt_text, opt_len); -      /* Don't actually write the deps file if compilation has failed.  */ -      if (pfile->errors == 0) +      if (comp > 0) +	mn = md + 1; +      else if (comp < 0) +	mx = md; +      else  	{ -	  char *deps_mode = opts->print_deps_append ? "a" : "w"; -	  if (opts->deps_file == 0) -	    deps_stream = stdout; -	  else if ((deps_stream = fopen (opts->deps_file, deps_mode)) == 0) -	    cpp_pfatal_with_name (pfile, opts->deps_file); -	  fputs (pfile->deps_buffer, deps_stream); -	  putc ('\n', deps_stream); -	  if (opts->deps_file) +	  if (input[opt_len] == '\0') +	    return md; +	  /* We were passed more text.  If the option takes an argument, +	     we may match a later option or we may have been passed the +	     argument.  The longest possible option match succeeds. +	     If the option takes no arguments we have not matched and +	     continue the search (e.g. input="stdc++" match was "stdc").  */ +	  mn = md + 1; +	  if (cl_options[md].msg)  	    { -	      if (ferror (deps_stream) || fclose (deps_stream) != 0) -		cpp_fatal (pfile, "I/O error on output"); +	      /* Scan forwards.  If we get an exact match, return it. +		 Otherwise, return the longest option-accepting match. +		 This loops no more than twice with current options.  */ +	      mx = md; +	      for (; mn < (unsigned int) N_OPTS; mn++) +		{ +		  opt_len = cl_options[mn].opt_len; +		  if (memcmp (input, cl_options[mn].opt_text, opt_len)) +		    break; +		  if (input[opt_len] == '\0') +		    return mn; +		  if (cl_options[mn].msg) +		    mx = mn; +		} +	      return mx;  	    }  	}      } -  if (opts->dump_macros == dump_only) -    { -      int i; -      HASHNODE *h; -      MACRODEF m; -      for (i = HASHSIZE; --i >= 0;) -	{ -	  for (h = pfile->hashtab[i]; h; h = h->next) -	    if (h->type == T_MACRO) -	      { -		m.defn = h->value.defn; -		m.symnam = h->name; -		m.symlen = h->length; -		dump_definition (pfile, m); -		CPP_PUTC (pfile, '\n'); -	      } -	} -    } +  return -1;  }  /* Handle one command-line option in (argc, argv).     Can be called multiple times, to handle multiple sets of options. +   If ignore is non-zero, this will ignore unrecognized -W* options.     Returns number of strings consumed.  */  int -cpp_handle_option (pfile, argc, argv) +cpp_handle_option (pfile, argc, argv, ignore)       cpp_reader *pfile;       int argc;       char **argv; +     int ignore;  { -  struct cpp_options *opts = CPP_OPTIONS (pfile);    int i = 0; +  struct cpp_pending *pend = CPP_OPTION (pfile, pending); -  if (argv[i][0] != '-') +  /* Interpret "-" or a non-option as a file name.  */ +  if (argv[i][0] != '-' || argv[i][1] == '\0')      { -      if (opts->out_fname != NULL) -	{ -	  print_help (); -	  cpp_fatal (pfile, "Too many arguments"); -	} -      else if (opts->in_fname != NULL) -	opts->out_fname = argv[i]; +      if (CPP_OPTION (pfile, in_fname) == NULL) +	CPP_OPTION (pfile, in_fname) = argv[i]; +      else if (CPP_OPTION (pfile, out_fname) == NULL) +	CPP_OPTION (pfile, out_fname) = argv[i];        else -	opts->in_fname = argv[i]; +	cpp_fatal (pfile, "too many filenames. Type %s --help for usage info", +		   progname);      }    else -    switch (argv[i][1]) -      { -      case 'f': -	if (!strcmp (argv[i], "-fleading-underscore")) -	  user_label_prefix = "_"; -	else if (!strcmp (argv[i], "-fno-leading-underscore")) -	  user_label_prefix = ""; -	break; - -      case 'I':			/* Add directory to path for includes.  */ -	if (!strcmp (argv[i] + 2, "-")) -	  { -	    /* -I- means: -	       Use the preceding -I directories for #include "..." -	       but not #include <...>. -	       Don't search the directory of the present file -	       for #include "...".  (Note that -I. -I- is not the same as -	       the default setup; -I. uses the compiler's working dir.)  */ -	    if (! opts->ignore_srcdir) -	      { -		opts->ignore_srcdir = 1; -		opts->pending->quote_head = opts->pending->brack_head; -		opts->pending->quote_tail = opts->pending->brack_tail; -		opts->pending->brack_head = 0; -		opts->pending->brack_tail = 0; -	      } -	    else -	      { -		cpp_fatal (pfile, "-I- specified twice"); -		return argc; -	      } -	  } -	else -	  { -	    char *fname; -	    if (argv[i][2] != 0) -	      fname = argv[i] + 2; -	    else if (i + 1 == argc) -	      goto missing_dirname; -	    else -	      fname = argv[++i]; -	    append_include_chain (pfile, opts->pending, -				  xstrdup (fname), BRACKET); -	  } -	break; - -      case 'i': -	/* Add directory to beginning of system include path, as a system -	   include directory. */ -	if (!strcmp (argv[i], "-isystem")) -	  { -	    if (i + 1 == argc) -	      goto missing_filename; -	    append_include_chain (pfile, opts->pending, -				  xstrdup (argv[++i]), SYSTEM); -	  } -	else if (!strcmp (argv[i], "-include")) -	  { -	    if (i + 1 == argc) -	      goto missing_filename; -	    else -	      { -		struct pending_option *o = (struct pending_option *) -		  xmalloc (sizeof (struct pending_option)); -		o->arg = argv[++i]; - -		/* This list has to be built in reverse order so that -		   when cpp_start_read pushes all the -include files onto -		   the buffer stack, they will be scanned in forward order.  */ -		o->next = opts->pending->include_head; -		opts->pending->include_head = o; -	      } -	  } -	else if (!strcmp (argv[i], "-imacros")) -	  { -	    if (i + 1 == argc) -	      goto missing_filename; -	    else -	      { -		struct pending_option *o = (struct pending_option *) -		  xmalloc (sizeof (struct pending_option)); -		o->arg = argv[++i]; -		o->next = NULL; - -		APPEND (opts->pending, imacros, o); -	      } -	  } -	/* Add directory to end of path for includes, -	   with the default prefix at the front of its name.  */ -	else if (!strcmp (argv[i], "-iwithprefix")) -	  { -	    char *fname; -	    int len; -	    if (i + 1 == argc) -	      goto missing_dirname; -	    ++i; -	    len = strlen (argv[i]); +    { +      enum opt_code opt_code; +      int opt_index; +      const char *arg = 0; -	    if (opts->include_prefix != 0) -	      { -		fname = xmalloc (opts->include_prefix_len + len + 1); -		memcpy (fname, opts->include_prefix, opts->include_prefix_len); -		memcpy (fname + opts->include_prefix_len, argv[i], len + 1); -	      } -	    else -	      { -		fname = xmalloc (sizeof GCC_INCLUDE_DIR - 8 + len); -		memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9); -		memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, argv[i], len + 1); -	      } -	   -	    append_include_chain (pfile, opts->pending, fname, SYSTEM); -	  } -	/* Add directory to main path for includes, -	   with the default prefix at the front of its name.  */ -	else if (!strcmp (argv[i], "-iwithprefixbefore")) -	  { -	    char *fname; -	    int len; -	    if (i + 1 == argc) -	      goto missing_dirname; -	    ++i; -	    len = strlen (argv[i]); +      /* Skip over '-'.  */ +      opt_index = parse_option (&argv[i][1]); +      if (opt_index < 0) +	return i; -	    if (opts->include_prefix != 0) -	      { -		fname = xmalloc (opts->include_prefix_len + len + 1); -		memcpy (fname, opts->include_prefix, opts->include_prefix_len); -		memcpy (fname + opts->include_prefix_len, argv[i], len + 1); -	      } -	    else -	      { -		fname = xmalloc (sizeof GCC_INCLUDE_DIR - 8 + len); -		memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9); -		memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, argv[i], len + 1); -	      } -	   -	    append_include_chain (pfile, opts->pending, fname, BRACKET); -	  } -	/* Add directory to end of path for includes.  */ -	else if (!strcmp (argv[i], "-idirafter")) -	  { -	    if (i + 1 == argc) -	      goto missing_dirname; -	    append_include_chain (pfile, opts->pending, -				  xstrdup (argv[++i]), AFTER); -	  } -	else if (!strcmp (argv[i], "-iprefix")) -	  { -	    if (i + 1 == argc) -	      goto missing_filename; -	    else -	      { -		opts->include_prefix = argv[++i]; -		opts->include_prefix_len = strlen (argv[i]); -	      } -	  } -	else if (!strcmp (argv[i], "-ifoutput")) -	  opts->output_conditionals = 1; +      opt_code = cl_options[opt_index].opt_code; +      if (cl_options[opt_index].msg) +	{ +	  arg = &argv[i][cl_options[opt_index].opt_len + 1]; -	break; -       -      case 'o': -	if (opts->out_fname != NULL) -	  { -	    cpp_fatal (pfile, "Output filename specified twice"); -	    return argc; -	  } -	if (i + 1 == argc) -	  goto missing_filename; -	opts->out_fname = argv[++i]; -	if (!strcmp (opts->out_fname, "-")) -	  opts->out_fname = ""; -	break; -       -      case 'p': -	if (!strcmp (argv[i], "-pedantic")) -	  CPP_PEDANTIC (pfile) = 1; -	else if (!strcmp (argv[i], "-pedantic-errors")) -	  { -	    CPP_PEDANTIC (pfile) = 1; -	    opts->pedantic_errors = 1; -	  } -#if 0 -	else if (!strcmp (argv[i], "-pcp")) { -	  char *pcp_fname = argv[++i]; -	  pcp_outfile = ((pcp_fname[0] != '-' || pcp_fname[1] != '\0') -			 ? fopen (pcp_fname, "w") -			 : fdopen (dup (fileno (stdout)), "w")); -	  if (pcp_outfile == 0) -	    cpp_pfatal_with_name (pfile, pcp_fname); -	  no_precomp = 1; +	  /* Yuk. Special case for -W as it must not swallow +	     up any following argument.  If this becomes common, add +	     another field to the cl_options table.  */ +	  if (arg[0] == '\0' && opt_code != OPT_W) +	    { +	      arg = argv[++i]; +	      if (!arg) +		{ +		  cpp_fatal (pfile, cl_options[opt_index].msg, argv[i - 1]); +		  return argc; +		} +	    }  	} -#endif -	break; -       -      case 't': -	if (!strcmp (argv[i], "-traditional")) -	  { -	    opts->traditional = 1; -	    opts->cplusplus_comments = 0; -	  } -	else if (!strcmp (argv[i], "-trigraphs")) -	  opts->trigraphs = 1; -	break; -       -      case 'l': -	if (! strcmp (argv[i], "-lang-c")) -	  opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, -	    opts->c9x = 1, opts->objc = 0; -	if (! strcmp (argv[i], "-lang-c89")) -	  opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->c89 = 1, -	    opts->c9x = 0, opts->objc = 0; -	if (! strcmp (argv[i], "-lang-c++")) -	  opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0, -	    opts->c9x = 0, opts->objc = 0; -	if (! strcmp (argv[i], "-lang-objc")) -	  opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, -	    opts->c9x = 0, opts->objc = 1; -	if (! strcmp (argv[i], "-lang-objc++")) -	  opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0, -	    opts->c9x = 0, opts->objc = 1; -	if (! strcmp (argv[i], "-lang-asm")) -	  opts->lang_asm = 1; -	if (! strcmp (argv[i], "-lint")) -	  opts->for_lint = 1; -	if (! strcmp (argv[i], "-lang-chill")) -	  opts->objc = 0, opts->cplusplus = 0, opts->chill = 1, -	    opts->traditional = 1; -	break; -       -      case '+': -	opts->cplusplus = 1, opts->cplusplus_comments = 1; -	break; - -      case 's': -	if (!strcmp (argv[i], "-std=iso9899:1990") -	    || !strcmp (argv[i], "-std=iso9899:199409") -	    || !strcmp (argv[i], "-std=c89") -	    || !strcmp (argv[i], "-std=gnu89")) -	  opts->cplusplus = 0, opts->cplusplus_comments = 0, -	    opts->c89 = 1, opts->c9x = 0, opts->objc = 0; -	else if (!strcmp (argv[i], "-std=iso9899:199x") -		 || !strcmp (argv[i], "-std=c9x") -		 || !strcmp (argv[i], "-std=gnu9x")) -	  opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, -	    opts->c9x = 1, opts->objc = 0; -	break; -      case 'w': -	opts->inhibit_warnings = 1; -	break; -       -      case 'W': -	if (!strcmp (argv[i], "-Wtrigraphs")) -	  opts->warn_trigraphs = 1; -	else if (!strcmp (argv[i], "-Wno-trigraphs")) -	  opts->warn_trigraphs = 0; -	else if (!strcmp (argv[i], "-Wcomment")) -	  opts->warn_comments = 1; -	else if (!strcmp (argv[i], "-Wno-comment")) -	  opts->warn_comments = 0; -	else if (!strcmp (argv[i], "-Wcomments")) -	  opts->warn_comments = 1; -	else if (!strcmp (argv[i], "-Wno-comments")) -	  opts->warn_comments = 0; -	else if (!strcmp (argv[i], "-Wtraditional")) -	  opts->warn_stringify = 1; -	else if (!strcmp (argv[i], "-Wno-traditional")) -	  opts->warn_stringify = 0; -	else if (!strcmp (argv[i], "-Wundef")) -	  opts->warn_undef = 1; -	else if (!strcmp (argv[i], "-Wno-undef")) -	  opts->warn_undef = 0; -	else if (!strcmp (argv[i], "-Wimport")) -	  opts->warn_import = 1; -	else if (!strcmp (argv[i], "-Wno-import")) -	  opts->warn_import = 0; -	else if (!strcmp (argv[i], "-Werror")) -	  opts->warnings_are_errors = 1; -	else if (!strcmp (argv[i], "-Wno-error")) -	  opts->warnings_are_errors = 0; -	else if (!strcmp (argv[i], "-Wall")) -	  { -	    opts->warn_trigraphs = 1; -	    opts->warn_comments = 1; -	  } -	break; -       -      case 'M': -	/* The style of the choices here is a bit mixed. -	   The chosen scheme is a hybrid of keeping all options in one string -	   and specifying each option in a separate argument: -	   -M|-MM|-MD file|-MMD file [-MG].  An alternative is: -	   -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: -	   -M[M][G][D file].  This is awkward to handle in specs, and is not -	   as extensible.  */ -	/* ??? -MG must be specified in addition to one of -M or -MM. -	   This can be relaxed in the future without breaking anything. -	   The converse isn't true.  */ -       -	/* -MG isn't valid with -MD or -MMD.  This is checked for later.  */ -	if (!strcmp (argv[i], "-MG")) -	  { -	    opts->print_deps_missing_files = 1; -	    break; -	  } -	if (!strcmp (argv[i], "-M")) -	  opts->print_deps = 2; -	else if (!strcmp (argv[i], "-MM")) -	  opts->print_deps = 1; -	else if (!strcmp (argv[i], "-MD")) -	  opts->print_deps = 2; -	else if (!strcmp (argv[i], "-MMD")) -	  opts->print_deps = 1; -	/* For -MD and -MMD options, write deps on file named by next arg.  */ -	if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD")) -	  { -	    if (i+1 == argc) -	      goto missing_filename; -	    opts->deps_file = argv[++i]; -	  } -	else -	  { -	    /* For -M and -MM, write deps on standard output -	       and suppress the usual output.  */ -	    opts->no_output = 1; -	  }	   -	break; -       -      case 'd': +      switch (opt_code)  	{ -	  char *p = argv[i] + 2; -	  char c; -	  while ((c = *p++) != 0) +	case N_OPTS: /* Shut GCC up.  */ +	  break; +	case OPT_fleading_underscore: +	  CPP_OPTION (pfile, user_label_prefix) = "_"; +	  break; +	case OPT_fno_leading_underscore: +	  CPP_OPTION (pfile, user_label_prefix) = ""; +	  break; +	case OPT_fno_operator_names: +	  CPP_OPTION (pfile, operator_names) = 0; +	  break; +	case OPT_fpreprocessed: +	  CPP_OPTION (pfile, preprocessed) = 1; +	  break; +	case OPT_fno_preprocessed: +	  CPP_OPTION (pfile, preprocessed) = 0; +	  break; +	case OPT_fshow_column: +	  CPP_OPTION (pfile, show_column) = 1; +	  break; +	case OPT_fno_show_column: +	  CPP_OPTION (pfile, show_column) = 0; +	  break; +	case OPT_ftabstop: +	  /* Silently ignore empty string, non-longs and silly values.  */ +	  if (arg[0] != '\0')  	    { -	      /* Arg to -d specifies what parts of macros to dump */ -	      switch (c) -		{ -		case 'M': -		  opts->dump_macros = dump_only; -		  opts->no_output = 1; +	      char *endptr; +	      long tabstop = strtol (arg, &endptr, 10); +	      if (*endptr == '\0' && tabstop >= 1 && tabstop <= 100) +		CPP_OPTION (pfile, tabstop) = tabstop; +	    } +	  break; +	case OPT_w: +	  CPP_OPTION (pfile, inhibit_warnings) = 1; +	  break; +	case OPT_h: +	case OPT__help: +	  print_help (); +	  CPP_OPTION (pfile, help_only) = 1; +	  break; +	case OPT_target__help: +          /* Print if any target specific options. cpplib has none, but +	     make sure help_only gets set.  */ +	  CPP_OPTION (pfile, help_only) = 1; +          break; + +	  /* --version inhibits compilation, -version doesn't. -v means +	     verbose and -version.  Historical reasons, don't ask.  */ +	case OPT__version: +	  CPP_OPTION (pfile, help_only) = 1; +	  pfile->print_version = 1; +	  break; +	case OPT_v: +	  CPP_OPTION (pfile, verbose) = 1; +	  pfile->print_version = 1; +	  break; +	case OPT_version: +	  pfile->print_version = 1; +	  break; + +	case OPT_C: +	  CPP_OPTION (pfile, discard_comments) = 0; +	  break; +	case OPT_P: +	  CPP_OPTION (pfile, no_line_commands) = 1; +	  break; +	case OPT_dollar:	/* Don't include $ in identifiers.  */ +	  CPP_OPTION (pfile, dollars_in_ident) = 0; +	  break; +	case OPT_H: +	  CPP_OPTION (pfile, print_include_names) = 1; +	  break; +	case OPT_D: +	  new_pending_directive (pend, arg, cpp_define); +	  break; +	case OPT_pedantic_errors: +	  CPP_OPTION (pfile, pedantic_errors) = 1; +	  /* fall through */ +	case OPT_pedantic: + 	  CPP_OPTION (pfile, pedantic) = 1; +	  break; +	case OPT_trigraphs: + 	  CPP_OPTION (pfile, trigraphs) = 1; +	  break; +	case OPT_plus: +	  CPP_OPTION (pfile, cplusplus) = 1; +	  CPP_OPTION (pfile, cplusplus_comments) = 1; +	  break; +	case OPT_remap: +	  CPP_OPTION (pfile, remap) = 1; +	  break; +	case OPT_iprefix: +	  CPP_OPTION (pfile, include_prefix) = arg; +	  CPP_OPTION (pfile, include_prefix_len) = strlen (arg); +	  break; +	case OPT_lang_c: +	  set_lang (pfile, CLK_GNUC89); +	  break; +	case OPT_lang_cplusplus: +	  set_lang (pfile, CLK_GNUCXX); +	  break; +	case OPT_lang_objc: +	  set_lang (pfile, CLK_OBJC); +	  break; +	case OPT_lang_objcplusplus: +	  set_lang (pfile, CLK_OBJCXX); +	  break; +	case OPT_lang_asm: +	  set_lang (pfile, CLK_ASM); +	  break; +	case OPT_std_cplusplus98: +	  set_lang (pfile, CLK_CXX98); +	  break; +	case OPT_std_gnu89: +	  set_lang (pfile, CLK_GNUC89); +	  break; +	case OPT_std_gnu9x: +	case OPT_std_gnu99: +	  set_lang (pfile, CLK_GNUC99); +	  break; +	case OPT_std_iso9899_199409: +	  set_lang (pfile, CLK_STDC94); +	  break; +	case OPT_std_iso9899_1990: +	case OPT_std_c89: +	case OPT_lang_c89: +	  set_lang (pfile, CLK_STDC89); +	  break; +	case OPT_std_iso9899_199x: +	case OPT_std_iso9899_1999: +	case OPT_std_c9x: +	case OPT_std_c99: +	  set_lang (pfile, CLK_STDC99); +	  break; +	case OPT_nostdinc: +	  /* -nostdinc causes no default include directories. +	     You must specify all include-file directories with -I.  */ +	  CPP_OPTION (pfile, no_standard_includes) = 1; +	  break; +	case OPT_nostdincplusplus: +	  /* -nostdinc++ causes no default C++-specific include directories.  */ +	  CPP_OPTION (pfile, no_standard_cplusplus_includes) = 1; +	  break; +	case OPT_o: +	  if (CPP_OPTION (pfile, out_fname) == NULL) +	    CPP_OPTION (pfile, out_fname) = arg; +	  else +	    { +	      cpp_fatal (pfile, "output filename specified twice"); +	      return argc; +	    } +	  break; +	case OPT_d: +	  /* Args to -d specify what parts of macros to dump. +	     Silently ignore unrecognised options; they may +	     be aimed at the compiler proper.  */ + 	  { +	    char c; + +	    while ((c = *arg++) != '\0') + 	      switch (c) + 		{ + 		case 'M': +		  CPP_OPTION (pfile, dump_macros) = dump_only; +		  CPP_OPTION (pfile, no_output) = 1;  		  break;  		case 'N': -		  opts->dump_macros = dump_names; +		  CPP_OPTION (pfile, dump_macros) = dump_names;  		  break;  		case 'D': -		  opts->dump_macros = dump_definitions; +		  CPP_OPTION (pfile, dump_macros) = dump_definitions;  		  break;  		case 'I': -		  opts->dump_includes = 1; +		  CPP_OPTION (pfile, dump_includes) = 1;  		  break;  		} -	    } -	} -	break; -     -      case 'g': -	if (argv[i][2] == '3') -	  opts->debug_output = 1; -	break; -       -      case '-': -	if (!strcmp (argv[i], "--help")) -	  print_help (); -	else if (!strcmp (argv[i], "--version")) -	  cpp_notice ("GNU CPP version %s\n", version_string); -	exit (0);  /* XXX */ -	break; -	 -      case 'v': -	cpp_notice ("GNU CPP version %s", version_string); -#ifdef TARGET_VERSION -	TARGET_VERSION; -#endif -	fputc ('\n', stderr); -	opts->verbose = 1; -	break; -       -      case 'H': -	opts->print_include_names = 1; -	break; -       -      case 'D': -	{ -	  struct pending_option *o = (struct pending_option *) -	    xmalloc (sizeof (struct pending_option)); -	  if (argv[i][2] != 0) -	    o->arg = argv[i] + 2; -	  else if (i + 1 == argc) -	    { -	      cpp_fatal (pfile, "Macro name missing after -D option"); -	      return argc; -	    } -	  else -	    o->arg = argv[++i]; +	  } +	  break; -	  o->next = NULL; -	  o->undef = 0; -	  APPEND (opts->pending, define, o); -	} -	break; -       -      case 'A': -	{ -	  char *p; -	 -	  if (argv[i][2] != 0) -	    p = argv[i] + 2; -	  else if (i + 1 == argc) -	    { -	      cpp_fatal (pfile, "Assertion missing after -A option"); -	      return argc; -	    } -	  else -	    p = argv[++i]; -	 -	  if (strcmp (p, "-")) -	    { -	      struct pending_option *o = (struct pending_option *) -		xmalloc (sizeof (struct pending_option)); +	case OPT_MG: +	  CPP_OPTION (pfile, print_deps_missing_files) = 1; +	  break; +	case OPT_M: +	  CPP_OPTION (pfile, print_deps) = 2; +	  break; +	case OPT_MM: +	  CPP_OPTION (pfile, print_deps) = 1; +	  break; +	case OPT_MF: +	  CPP_OPTION (pfile, deps_file) = arg; +	  break; + 	case OPT_MP: +	  CPP_OPTION (pfile, deps_phony_targets) = 1; +	  break; +	case OPT_MQ: +	case OPT_MT: +	  /* Add a target.  -MQ quotes for Make.  */ +	  deps_add_target (pfile->deps, arg, opt_code == OPT_MQ); +	  break; -	      o->arg = p; -	      o->next = NULL; -	      o->undef = 0; -	      APPEND (opts->pending, assert, o); +	  /* -MD and -MMD for cpp0 are deprecated and undocumented +	     (use -M or -MM with -MF instead), and probably should be +	     removed with the next major GCC version.  For the moment +	     we allow these for the benefit of Automake 1.4, which +	     uses these when dependency tracking is enabled.  Automake +	     1.5 will fix this.  */ +	case OPT_MD: +	  CPP_OPTION (pfile, print_deps) = 2; +	  CPP_OPTION (pfile, deps_file) = arg; +	  break; +	case OPT_MMD: +	  CPP_OPTION (pfile, print_deps) = 1; +	  CPP_OPTION (pfile, deps_file) = arg; +	  break; + +	case OPT_A: +	  if (arg[0] == '-') +	    { +	      /* -A with an argument beginning with '-' acts as +		 #unassert on whatever immediately follows the '-'. +		 If "-" is the whole argument, we eliminate all +		 predefined macros and assertions, including those +		 that were specified earlier on the command line. +		 That way we can get rid of any that were passed +		 automatically in from GCC.  */ + +	      if (arg[1] == '\0') +		{ +		  free_chain (pend->directive_head); +		  pend->directive_head = NULL; +		  pend->directive_tail = NULL; +		} +	      else +		new_pending_directive (pend, arg + 1, cpp_unassert);  	    }  	  else -	    { -	      /* -A- eliminates all predefined macros and assertions. -		 Let's include also any that were specified earlier -		 on the command line.  That way we can get rid of any -		 that were passed automatically in from GCC.  */ -	      struct pending_option *o1, *o2; - -	      o1 = opts->pending->define_head; -	      while (o1) +	    new_pending_directive (pend, arg, cpp_assert); +	  break; +	case OPT_U: +	  new_pending_directive (pend, arg, cpp_undef); +	  break; +	case OPT_I:           /* Add directory to path for includes.  */ +	  if (!strcmp (arg, "-")) + 	    { +	      /* -I- means: +		 Use the preceding -I directories for #include "..." +		 but not #include <...>. +		 Don't search the directory of the present file +		 for #include "...".  (Note that -I. -I- is not the same as +		 the default setup; -I. uses the compiler's working dir.)  */ +	      if (! CPP_OPTION (pfile, ignore_srcdir))  		{ -		  o2 = o1->next; -		  free (o1); -		  o1 = o2; +		  pend->quote_head = pend->brack_head; +		  pend->quote_tail = pend->brack_tail; +		  pend->brack_head = 0; +		  pend->brack_tail = 0; +		  CPP_OPTION (pfile, ignore_srcdir) = 1;  		} -	      o1 = opts->pending->assert_head; -	      while (o1) +	      else  		{ -		  o2 = o1->next; -		  free (o1); -		  o1 = o2; +		  cpp_fatal (pfile, "-I- specified twice"); +		  return argc;  		} -	      opts->pending->assert_head = NULL; -	      opts->pending->assert_tail = NULL; -	      opts->pending->define_head = NULL; -	      opts->pending->define_tail = NULL; -	    } -	} -	break; -     -      case 'U': -	{ -	  struct pending_option *o = (struct pending_option *) -	    xmalloc (sizeof (struct pending_option)); -	   -	  if (argv[i][2] != 0) -	    o->arg = argv[i] + 2; -	  else if (i + 1 == argc) -	    { -	      cpp_fatal (pfile, "Macro name missing after -U option"); -	      return argc; -	    } -	  else -	    o->arg = argv[++i]; + 	    } + 	  else +	    append_include_chain (pfile, xstrdup (arg), BRACKET, 0); +	  break; +	case OPT_isystem: +	  /* Add directory to beginning of system include path, as a system +	     include directory.  */ +	  append_include_chain (pfile, xstrdup (arg), SYSTEM, 0); +	  break; +	case OPT_include: +	case OPT_imacros: +	  { +	    struct pending_option *o = (struct pending_option *) +	      xmalloc (sizeof (struct pending_option)); +	    o->arg = arg; +	    o->next = NULL; -	  o->next = NULL; -	  o->undef = 1; -	  APPEND (opts->pending, define, o); -	} -	break; -       -      case 'C': -	opts->put_out_comments = 1; -	break; -       -      case 'E':			/* -E comes from cc -E; ignore it.  */ -	break; -       -      case 'P': -	opts->no_line_commands = 1; -	break; -       -      case '$':			/* Don't include $ in identifiers.  */ -	opts->dollars_in_ident = 0; -	break; -       -      case 'n': -	if (!strcmp (argv[i], "-nostdinc")) -	  /* -nostdinc causes no default include directories. -	     You must specify all include-file directories with -I.  */ -	  opts->no_standard_includes = 1; -	else if (!strcmp (argv[i], "-nostdinc++")) -	  /* -nostdinc++ causes no default C++-specific include directories. */ -	  opts->no_standard_cplusplus_includes = 1; -#if 0 -	else if (!strcmp (argv[i], "-noprecomp")) -	  no_precomp = 1; -#endif -	break; -       -      case 'r': -	if (!strcmp (argv[i], "-remap")) -	  opts->remap = 1; -	break; -       -      case '\0': /* JF handle '-' as file name meaning stdin or stdout */ -	if (opts->in_fname == NULL) -	  opts->in_fname = ""; -	else if (opts->out_fname == NULL) -	  opts->out_fname = ""; -	else -	  return i;  /* error */ -	break; +	    if (opt_code == OPT_include) +	      APPEND (pend, include, o); +	    else +	      APPEND (pend, imacros, o); +	  } +	  break; +	case OPT_iwithprefix: +	  /* Add directory to end of path for includes, +	     with the default prefix at the front of its name.  */ +	  /* fall through */ +	case OPT_iwithprefixbefore: +	  /* Add directory to main path for includes, +	     with the default prefix at the front of its name.  */ +	  { +	    char *fname; +	    int len; -      default: -	return i; -      } +	    len = strlen (arg); -  return i + 1; +	    if (CPP_OPTION (pfile, include_prefix) != 0) +	      { +		size_t ipl = CPP_OPTION (pfile, include_prefix_len); +		fname = xmalloc (ipl + len + 1); +		memcpy (fname, CPP_OPTION (pfile, include_prefix), ipl); +		memcpy (fname + ipl, arg, len + 1); +	      } +	    else if (cpp_GCC_INCLUDE_DIR_len) +	      { +		fname = xmalloc (cpp_GCC_INCLUDE_DIR_len + len + 1); +		memcpy (fname, cpp_GCC_INCLUDE_DIR, cpp_GCC_INCLUDE_DIR_len); +		memcpy (fname + cpp_GCC_INCLUDE_DIR_len, arg, len + 1); +	      } +	    else +	      fname = xstrdup (arg); - missing_filename: -  cpp_fatal (pfile, "Filename missing after `%s' option", argv[i]); -  return argc; - missing_dirname: -  cpp_fatal (pfile, "Directory name missing after `%s' option", argv[i]); -  return argc; +	    append_include_chain (pfile, fname, +			  opt_code == OPT_iwithprefix ? SYSTEM: BRACKET, 0); +	  } +	  break; +	case OPT_idirafter: +	  /* Add directory to end of path for includes.  */ +	  append_include_chain (pfile, xstrdup (arg), AFTER, 0); +	  break; +	case OPT_W: +	  /* Silently ignore unrecognised options.  */ +	  if (!strcmp (argv[i], "-Wall")) +	    { +	      CPP_OPTION (pfile, warn_trigraphs) = 1; +	      CPP_OPTION (pfile, warn_comments) = 1; +	    } +	  else if (!strcmp (argv[i], "-Wtraditional")) +	    CPP_OPTION (pfile, warn_traditional) = 1; +	  else if (!strcmp (argv[i], "-Wtrigraphs")) +	    CPP_OPTION (pfile, warn_trigraphs) = 1; +	  else if (!strcmp (argv[i], "-Wcomment")) +	    CPP_OPTION (pfile, warn_comments) = 1; +	  else if (!strcmp (argv[i], "-Wcomments")) +	    CPP_OPTION (pfile, warn_comments) = 1; +	  else if (!strcmp (argv[i], "-Wundef")) +	    CPP_OPTION (pfile, warn_undef) = 1; +	  else if (!strcmp (argv[i], "-Wimport")) +	    CPP_OPTION (pfile, warn_import) = 1; +	  else if (!strcmp (argv[i], "-Werror")) +	    CPP_OPTION (pfile, warnings_are_errors) = 1; +	  else if (!strcmp (argv[i], "-Wsystem-headers")) +	    CPP_OPTION (pfile, warn_system_headers) = 1; +	  else if (!strcmp (argv[i], "-Wno-traditional")) +	    CPP_OPTION (pfile, warn_traditional) = 0; +	  else if (!strcmp (argv[i], "-Wno-trigraphs")) +	    CPP_OPTION (pfile, warn_trigraphs) = 0; +	  else if (!strcmp (argv[i], "-Wno-comment")) +	    CPP_OPTION (pfile, warn_comments) = 0; +	  else if (!strcmp (argv[i], "-Wno-comments")) +	    CPP_OPTION (pfile, warn_comments) = 0; +	  else if (!strcmp (argv[i], "-Wno-undef")) +	    CPP_OPTION (pfile, warn_undef) = 0; +	  else if (!strcmp (argv[i], "-Wno-import")) +	    CPP_OPTION (pfile, warn_import) = 0; +	  else if (!strcmp (argv[i], "-Wno-error")) +	    CPP_OPTION (pfile, warnings_are_errors) = 0; +	  else if (!strcmp (argv[i], "-Wno-system-headers")) +	    CPP_OPTION (pfile, warn_system_headers) = 0; +	  else if (! ignore) +	    return i; +	  break; + 	} +    } +  return i + 1;  }  /* Handle command-line options in (argc, argv).     Can be called multiple times, to handle multiple sets of options.     Returns if an unrecognized option is seen.     Returns number of strings consumed.  */ -  int  cpp_handle_options (pfile, argc, argv)       cpp_reader *pfile; @@ -1698,19 +1755,132 @@ cpp_handle_options (pfile, argc, argv)  {    int i;    int strings_processed; +    for (i = 0; i < argc; i += strings_processed)      { -      strings_processed = cpp_handle_option (pfile, argc - i, argv + i); +      strings_processed = cpp_handle_option (pfile, argc - i, argv + i, 1);        if (strings_processed == 0)  	break;      } +    return i;  } +/* Extra processing when all options are parsed, after all calls to +   cpp_handle_option[s].  Consistency checks etc.  */ +void +cpp_post_options (pfile) +     cpp_reader *pfile; +{ +  if (pfile->print_version) +    { +      fprintf (stderr, _("GNU CPP version %s (cpplib)"), version_string); +#ifdef TARGET_VERSION +      TARGET_VERSION; +#endif +      fputc ('\n', stderr); +    } + +  /* Canonicalize in_fname and out_fname.  We guarantee they are not +     NULL, and that the empty string represents stdin / stdout.  */ +  if (CPP_OPTION (pfile, in_fname) == NULL +      || !strcmp (CPP_OPTION (pfile, in_fname), "-")) +    CPP_OPTION (pfile, in_fname) = ""; + +  if (CPP_OPTION (pfile, out_fname) == NULL +      || !strcmp (CPP_OPTION (pfile, out_fname), "-")) +    CPP_OPTION (pfile, out_fname) = ""; + +  /* -Wtraditional is not useful in C++ mode.  */ +  if (CPP_OPTION (pfile, cplusplus)) +    CPP_OPTION (pfile, warn_traditional) = 0; + +  /* Set this if it hasn't been set already.  */ +  if (CPP_OPTION (pfile, user_label_prefix) == NULL) +    CPP_OPTION (pfile, user_label_prefix) = USER_LABEL_PREFIX; + +  /* Permanently disable macro expansion if we are rescanning +     preprocessed text.  */ +  if (CPP_OPTION (pfile, preprocessed)) +    pfile->state.prevent_expansion = 1; + +  /* We need to do this after option processing and before +     cpp_start_read, as cppmain.c relies on the options->no_output to +     set its callbacks correctly before calling cpp_start_read.  */ +  init_dependency_output (pfile); + +  /* After checking the environment variables, check if -M or -MM has +     not been specified, but other -M options have.  */ +  if (CPP_OPTION (pfile, print_deps) == 0 && +      (CPP_OPTION (pfile, print_deps_missing_files) +       || CPP_OPTION (pfile, deps_file) +       || CPP_OPTION (pfile, deps_phony_targets))) +    cpp_fatal (pfile, "you must additionally specify either -M or -MM"); +} + +/* Set up dependency-file output.  */ +static void +init_dependency_output (pfile) +     cpp_reader *pfile; +{ +  char *spec, *s, *output_file; + +  /* Either of two environment variables can specify output of deps. +     Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", +     where OUTPUT_FILE is the file to write deps info to +     and DEPS_TARGET is the target to mention in the deps.  */ + +  if (CPP_OPTION (pfile, print_deps) == 0) +    { +      spec = getenv ("DEPENDENCIES_OUTPUT"); +      if (spec) +	CPP_OPTION (pfile, print_deps) = 1; +      else +	{ +	  spec = getenv ("SUNPRO_DEPENDENCIES"); +	  if (spec) +	    CPP_OPTION (pfile, print_deps) = 2; +	  else +	    return; +	} + +      /* Find the space before the DEPS_TARGET, if there is one.  */ +      s = strchr (spec, ' '); +      if (s) +	{ +	  /* Let the caller perform MAKE quoting.  */ +	  deps_add_target (pfile->deps, s + 1, 0); +	  output_file = (char *) xmalloc (s - spec + 1); +	  memcpy (output_file, spec, s - spec); +	  output_file[s - spec] = 0; +	} +      else +	output_file = spec; + +      /* Command line overrides environment variables.  */ +      if (CPP_OPTION (pfile, deps_file) == 0) +	CPP_OPTION (pfile, deps_file) = output_file; +      CPP_OPTION (pfile, print_deps_append) = 1; +    } + +  /* If dependencies go to standard output, or -MG is used, we should +     suppress output, including -dM, -dI etc.  */ +  if (CPP_OPTION (pfile, deps_file) == 0 +      || CPP_OPTION (pfile, print_deps_missing_files)) +    { +      CPP_OPTION (pfile, no_output) = 1; +      CPP_OPTION (pfile, dump_macros) = 0; +      CPP_OPTION (pfile, dump_includes) = 0; +    } +} + +/* Handle --help output.  */  static void  print_help ()  { -  cpp_notice ("Usage: %s [switches] input output\n", progname); +  fprintf (stderr, _("Usage: %s [switches] input output\n"), progname); +  /* To keep the lines from getting too long for some compilers, limit +     to about 500 characters (6 lines) per chunk.  */    fputs (_("\  Switches:\n\    -include <file>           Include the contents of <file> before other files\n\ @@ -1719,62 +1889,89 @@ Switches:\n\    -iwithprefix <dir>        Add <dir> to the end of the system include path\n\    -iwithprefixbefore <dir>  Add <dir> to the end of the main include path\n\    -isystem <dir>            Add <dir> to the start of the system include path\n\ +"), stdout); +  fputs (_("\    -idirafter <dir>          Add <dir> to the end of the system include path\n\    -I <dir>                  Add <dir> to the end of the main include path\n\ +  -I-                       Fine-grained include path control; see info docs\n\    -nostdinc                 Do not search system include directories\n\                               (dirs specified with -isystem will still be used)\n\    -nostdinc++               Do not search system include directories for C++\n\    -o <file>                 Put output into <file>\n\ -  -pedantic                 Issue all warnings demanded by strict ANSI C\n\ -  -traditional              Follow K&R pre-processor behaviour\n\ -  -trigraphs                Support ANSI C trigraphs\n\ +"), stdout); +  fputs (_("\ +  -pedantic                 Issue all warnings demanded by strict ISO C\n\ +  -pedantic-errors          Issue -pedantic warnings as errors instead\n\ +  -trigraphs                Support ISO C trigraphs\n\    -lang-c                   Assume that the input sources are in C\n\    -lang-c89                 Assume that the input sources are in C89\n\ +"), stdout); +  fputs (_("\    -lang-c++                 Assume that the input sources are in C++\n\    -lang-objc                Assume that the input sources are in ObjectiveC\n\    -lang-objc++              Assume that the input sources are in ObjectiveC++\n\    -lang-asm                 Assume that the input sources are in assembler\n\ -  -lang-chill               Assume that the input sources are in Chill\n\ +"), stdout); +  fputs (_("\    -std=<std name>           Specify the conformance standard; one of:\n\ -                            gnu89, gnu9x, c89, c9x, iso9899:1990,\n\ -                            iso9899:199409, iso9899:199x\n\ +                            gnu89, gnu99, c89, c99, iso9899:1990,\n\ +                            iso9899:199409, iso9899:1999\n\    -+                        Allow parsing of C++ style features\n\    -w                        Inhibit warning messages\n\    -Wtrigraphs               Warn if trigraphs are encountered\n\    -Wno-trigraphs            Do not warn about trigraphs\n\    -Wcomment{s}              Warn if one comment starts inside another\n\ +"), stdout); +  fputs (_("\    -Wno-comment{s}           Do not warn about comments\n\ -  -Wtraditional             Warn if a macro argument is/would be turned into\n\ -                             a string if -traditional is specified\n\ -  -Wno-traditional          Do not warn about stringification\n\ +  -Wtraditional             Warn about features not present in traditional C\n\ +  -Wno-traditional          Do not warn about traditional C\n\    -Wundef                   Warn if an undefined macro is used by #if\n\    -Wno-undef                Do not warn about testing undefined macros\n\    -Wimport                  Warn about the use of the #import directive\n\ +"), stdout); +  fputs (_("\    -Wno-import               Do not warn about the use of #import\n\    -Werror                   Treat all warnings as errors\n\    -Wno-error                Do not treat warnings as errors\n\ +  -Wsystem-headers          Do not suppress warnings from system headers\n\ +  -Wno-system-headers       Suppress warnings from system headers\n\    -Wall                     Enable all preprocessor warnings\n\ +"), stdout); +  fputs (_("\    -M                        Generate make dependencies\n\    -MM                       As -M, but ignore system header files\n\ -  -MD                       As -M, but put output in a .d file\n\ -  -MMD                      As -MD, but ignore system header files\n\ +  -MF <file>                Write dependency output to the given file\n\    -MG                       Treat missing header file as generated files\n\ -  -g                        Include #define and #undef directives in the output\n\ +"), stdout); +  fputs (_("\ +  -MP			    Generate phony targets for all headers\n\ +  -MQ <target>              Add a MAKE-quoted target\n\ +  -MT <target>              Add an unquoted target\n\ +"), stdout); +  fputs (_("\    -D<macro>                 Define a <macro> with string '1' as its value\n\    -D<macro>=<val>           Define a <macro> with <val> as its value\n\    -A<question> (<answer>)   Assert the <answer> to <question>\n\ +  -A-<question> (<answer>)  Disable the <answer> to <question>\n\    -U<macro>                 Undefine <macro> \n\    -v                        Display the version number\n\ +"), stdout); +  fputs (_("\    -H                        Print the name of header files as they are used\n\    -C                        Do not discard comments\n\    -dM                       Display a list of macro definitions active at end\n\    -dD                       Preserve macro definitions in output\n\    -dN                       As -dD except that only the names are preserved\n\    -dI                       Include #include directives in the output\n\ -  -ifoutput                 Describe skipped code blocks in output \n\ +"), stdout); +  fputs (_("\ +  -fpreprocessed            Treat the input file as already preprocessed\n\ +  -ftabstop=<number>        Distance between tab stops for column reporting\n\    -P                        Do not generate #line directives\n\    -$                        Do not allow '$' in identifiers\n\    -remap                    Remap file names when including files.\n\ +  --version                 Display version information\n\    -h or --help              Display this information\n\  "), stdout);  }  | 
