Annotation of gcc/cpplib.c, revision 1.1

1.1     ! root        1: /* CPP Library.
        !             2:    Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
        !             3:    Written by Per Bothner, 1994-95.
        !             4:    Based on CCCP program by by Paul Rubin, June 1986
        !             5:    Adapted to ANSI C, Richard Stallman, Jan 1987
        !             6: 
        !             7: This program is free software; you can redistribute it and/or modify it
        !             8: under the terms of the GNU General Public License as published by the
        !             9: Free Software Foundation; either version 2, or (at your option) any
        !            10: later version.
        !            11: 
        !            12: This program is distributed in the hope that it will be useful,
        !            13: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15: GNU General Public License for more details.
        !            16: 
        !            17: You should have received a copy of the GNU General Public License
        !            18: along with this program; if not, write to the Free Software
        !            19: Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
        !            20: 
        !            21:  In other words, you are welcome to use, share and improve this program.
        !            22:  You are forbidden to forbid anyone else to use, share and improve
        !            23:  what you give them.   Help stamp out software-hoarding!  */
        !            24: 
        !            25: #ifdef EMACS
        !            26: #define NO_SHORTNAMES
        !            27: #include "../src/config.h"
        !            28: #ifdef open
        !            29: #undef open
        !            30: #undef read
        !            31: #undef write
        !            32: #endif /* open */
        !            33: #endif /* EMACS */
        !            34: 
        !            35: /* The macro EMACS is defined when cpp is distributed as part of Emacs,
        !            36:    for the sake of machines with limited C compilers.  */
        !            37: #ifndef EMACS
        !            38: #include "config.h"
        !            39: #endif /* not EMACS */
        !            40: 
        !            41: #ifndef STANDARD_INCLUDE_DIR
        !            42: #define STANDARD_INCLUDE_DIR "/usr/include"
        !            43: #endif
        !            44: 
        !            45: #ifndef LOCAL_INCLUDE_DIR
        !            46: #define LOCAL_INCLUDE_DIR "/usr/local/include"
        !            47: #endif
        !            48: 
        !            49: #if 0 /* We can't get ptrdiff_t, so I arranged not to need PTR_INT_TYPE.  */
        !            50: #ifdef __STDC__
        !            51: #define PTR_INT_TYPE ptrdiff_t
        !            52: #else
        !            53: #define PTR_INT_TYPE long
        !            54: #endif
        !            55: #endif /* 0 */
        !            56: 
        !            57: #include "cpplib.h"
        !            58: #include "cpphash.h"
        !            59: 
        !            60: #ifndef STDC_VALUE
        !            61: #define STDC_VALUE 1
        !            62: #endif
        !            63: 
        !            64: /* By default, colon separates directories in a path.  */
        !            65: #ifndef PATH_SEPARATOR
        !            66: #define PATH_SEPARATOR ':'
        !            67: #endif
        !            68: 
        !            69: #include <ctype.h>
        !            70: #include <stdio.h>
        !            71: #include <signal.h>
        !            72: #ifdef __STDC__
        !            73: #include <stdlib.h>
        !            74: #endif
        !            75: 
        !            76: #ifndef VMS
        !            77: #ifndef USG
        !            78: #include <sys/time.h>          /* for __DATE__ and __TIME__ */
        !            79: #include <sys/resource.h>
        !            80: #else
        !            81: #include <sys/param.h>                 /* CYGNUS LOCAL: shebs -noquiet */
        !            82: #include <sys/times.h>
        !            83: #include <time.h>
        !            84: #include <fcntl.h>
        !            85: #endif /* USG */
        !            86: #endif /* not VMS */
        !            87: 
        !            88: /* This defines "errno" properly for VMS, and gives us EACCES. */
        !            89: #include <errno.h>
        !            90: 
        !            91: extern char *index ();
        !            92: extern char *rindex ();
        !            93: 
        !            94: #ifndef O_RDONLY
        !            95: #define O_RDONLY 0
        !            96: #endif
        !            97: 
        !            98: #undef MIN
        !            99: #undef MAX
        !           100: #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
        !           101: #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
        !           102: 
        !           103: /* Find the largest host integer type and set its size and type.  */
        !           104: 
        !           105: #ifndef HOST_BITS_PER_WIDE_INT
        !           106: 
        !           107: #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
        !           108: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
        !           109: #define HOST_WIDE_INT long
        !           110: #else
        !           111: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
        !           112: #define HOST_WIDE_INT int
        !           113: #endif
        !           114: 
        !           115: #endif
        !           116: 
        !           117: #ifndef S_ISREG
        !           118: #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
        !           119: #endif
        !           120: 
        !           121: #ifndef S_ISDIR
        !           122: #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
        !           123: #endif
        !           124: 
        !           125: /* Define a generic NULL if one hasn't already been defined.  */
        !           126: 
        !           127: #ifndef NULL
        !           128: #define NULL 0
        !           129: #endif
        !           130: 
        !           131: #ifndef GENERIC_PTR
        !           132: #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
        !           133: #define GENERIC_PTR void *
        !           134: #else
        !           135: #define GENERIC_PTR char *
        !           136: #endif
        !           137: #endif
        !           138: 
        !           139: #ifndef NULL_PTR
        !           140: #define NULL_PTR ((GENERIC_PTR)0)
        !           141: #endif
        !           142: 
        !           143: #ifndef INCLUDE_LEN_FUDGE
        !           144: #define INCLUDE_LEN_FUDGE 0
        !           145: #endif
        !           146: 
        !           147: /* Symbols to predefine.  */
        !           148: 
        !           149: #ifdef CPP_PREDEFINES
        !           150: static char *predefs = CPP_PREDEFINES;
        !           151: #else
        !           152: static char *predefs = "";
        !           153: #endif
        !           154: 
        !           155: /* We let tm.h override the types used here, to handle trivial differences
        !           156:    such as the choice of unsigned int or long unsigned int for size_t.
        !           157:    When machines start needing nontrivial differences in the size type,
        !           158:    it would be best to do something here to figure out automatically
        !           159:    from other information what type to use.  */
        !           160: 
        !           161: /* The string value for __SIZE_TYPE__.  */
        !           162: 
        !           163: #ifndef SIZE_TYPE
        !           164: #define SIZE_TYPE "long unsigned int"
        !           165: #endif
        !           166: 
        !           167: /* The string value for __PTRDIFF_TYPE__.  */
        !           168: 
        !           169: #ifndef PTRDIFF_TYPE
        !           170: #define PTRDIFF_TYPE "long int"
        !           171: #endif
        !           172: 
        !           173: /* The string value for __WCHAR_TYPE__.  */
        !           174: 
        !           175: #ifndef WCHAR_TYPE
        !           176: #define WCHAR_TYPE "int"
        !           177: #endif
        !           178: #define CPP_WCHAR_TYPE(PFILE) \
        !           179:        (CPP_OPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE)
        !           180: 
        !           181: /* The string value for __USER_LABEL_PREFIX__ */
        !           182: 
        !           183: #ifndef USER_LABEL_PREFIX
        !           184: #define USER_LABEL_PREFIX ""
        !           185: #endif
        !           186: 
        !           187: /* The string value for __REGISTER_PREFIX__ */
        !           188: 
        !           189: #ifndef REGISTER_PREFIX
        !           190: #define REGISTER_PREFIX ""
        !           191: #endif
        !           192: 
        !           193: /* In the definition of a #assert name, this structure forms
        !           194:    a list of the individual values asserted.
        !           195:    Each value is itself a list of "tokens".
        !           196:    These are strings that are compared by name.  */
        !           197: 
        !           198: struct tokenlist_list {
        !           199:   struct tokenlist_list *next;
        !           200:   struct arglist *tokens;
        !           201: };
        !           202: 
        !           203: struct assertion_hashnode {
        !           204:   struct assertion_hashnode *next;     /* double links for easy deletion */
        !           205:   struct assertion_hashnode *prev;
        !           206:   /* also, a back pointer to this node's hash
        !           207:      chain is kept, in case the node is the head
        !           208:      of the chain and gets deleted. */
        !           209:   struct assertion_hashnode **bucket_hdr;
        !           210:   int length;                  /* length of token, for quick comparison */
        !           211:   U_CHAR *name;                        /* the actual name */
        !           212:   /* List of token-sequences.  */
        !           213:   struct tokenlist_list *value;
        !           214: };
        !           215: 
        !           216: #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
        !           217: #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
        !           218: 
        !           219: #define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) ? CPP_BUFFER (pfile)->cur[N] : EOF)
        !           220: #define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
        !           221: #define GETC() CPP_BUF_GET (CPP_BUFFER (pfile))
        !           222: #define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
        !           223: /* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion.
        !           224:    (Note that it is false while we're expanding marco *arguments*.) */
        !           225: #define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->cleanup == macro_cleanup)
        !           226: 
        !           227: /* Move all backslash-newline pairs out of embarrassing places.
        !           228:    Exchange all such pairs following BP
        !           229:    with any potentially-embarrassing characters that follow them.
        !           230:    Potentially-embarrassing characters are / and *
        !           231:    (because a backslash-newline inside a comment delimiter
        !           232:    would cause it not to be recognized).  */
        !           233: 
        !           234: #define NEWLINE_FIX \
        !           235:   do {while (PEEKC() == '\\' && PEEKN(1) == '\n') FORWARD(2); } while(0)
        !           236: 
        !           237: /* Same, but assume we've already read the potential '\\' into C. */
        !           238: #define NEWLINE_FIX1(C) do { \
        !           239:     while ((C) == '\\' && PEEKC() == '\n') { FORWARD(1); (C) = GETC(); }\
        !           240:   } while(0)
        !           241: 
        !           242: struct cpp_pending {
        !           243:   struct cpp_pending *next;
        !           244:   char *cmd;
        !           245:   char *arg;
        !           246: };
        !           247: 
        !           248: /* Forward declarations.  */
        !           249: 
        !           250: extern char *xmalloc ();
        !           251: 
        !           252: static void add_import ();
        !           253: static void append_include_chain ();
        !           254: static void make_undef ();
        !           255: static void make_assertion ();
        !           256: static void path_include ();
        !           257: static void initialize_builtins ();
        !           258: static void initialize_char_syntax ();
        !           259: static void dump_arg_n ();
        !           260: static void dump_defn_1 ();
        !           261: extern void delete_macro ();
        !           262: static void trigraph_pcp ();
        !           263: static int finclude ();
        !           264: static void validate_else ();
        !           265: static int comp_def_part ();
        !           266: extern void fancy_abort ();
        !           267: static void pipe_closed ();
        !           268: static void print_containing_files ();
        !           269: static int lookup_import ();
        !           270: static int redundant_include_p ();
        !           271: static is_system_include ();
        !           272: static struct file_name_map *read_name_map ();
        !           273: static char *read_filename_string ();
        !           274: static int open_include_file ();
        !           275: static int check_preconditions ();
        !           276: static void pcfinclude ();
        !           277: static void pcstring_used ();
        !           278: static int check_macro_name ();
        !           279: static int compare_defs ();
        !           280: static int compare_token_lists ();
        !           281: static HOST_WIDE_INT eval_if_expression ();
        !           282: static int change_newlines ();
        !           283: extern int hashf ();
        !           284: static int file_size_and_mode ();
        !           285: static struct arglist *read_token_list ();
        !           286: static void free_token_list ();
        !           287: static int safe_read ();
        !           288: static void push_macro_expansion PARAMS ((cpp_reader *,
        !           289:                                          U_CHAR*, int, HASHNODE*));
        !           290: static struct cpp_pending *nreverse_pending PARAMS ((struct cpp_pending*));
        !           291: extern char *xrealloc ();
        !           292: extern char *xcalloc ();
        !           293: static char *savestring ();
        !           294: 
        !           295: static void conditional_skip ();
        !           296: static void skip_if_group ();
        !           297: 
        !           298: /* Last arg to output_line_command.  */
        !           299: enum file_change_code {same_file, enter_file, leave_file};
        !           300: 
        !           301: /* External declarations.  */
        !           302: 
        !           303: extern HOST_WIDE_INT cpp_parse_expr PARAMS ((cpp_reader*));
        !           304: 
        !           305: extern char *getenv ();
        !           306: extern FILE *fdopen ();
        !           307: extern char *version_string;
        !           308: extern struct tm *localtime ();
        !           309: 
        !           310: /* These functions are declared to return int instead of void since they
        !           311:    are going to be placed in a table and some old compilers have trouble with
        !           312:    pointers to functions returning void.  */
        !           313: 
        !           314: static int do_define ();
        !           315: static int do_line ();
        !           316: static int do_include ();
        !           317: static int do_undef ();
        !           318: static int do_error ();
        !           319: static int do_pragma ();
        !           320: static int do_ident ();
        !           321: static int do_if ();
        !           322: static int do_xifdef ();
        !           323: static int do_else ();
        !           324: static int do_elif ();
        !           325: static int do_endif ();
        !           326: static int do_sccs ();
        !           327: static int do_once ();
        !           328: static int do_assert ();
        !           329: static int do_unassert ();
        !           330: static int do_warning ();
        !           331: 
        !           332: struct file_name_list
        !           333:   {
        !           334:     struct file_name_list *next;
        !           335:     char *fname;
        !           336:     /* If the following is nonzero, it is a macro name.
        !           337:        Don't include the file again if that macro is defined.  */
        !           338:     U_CHAR *control_macro;
        !           339:     /* If the following is nonzero, it is a C-language system include
        !           340:        directory.  */
        !           341:     int c_system_include_path;
        !           342:     /* Mapping of file names for this directory.  */
        !           343:     struct file_name_map *name_map;
        !           344:     /* Non-zero if name_map is valid.  */
        !           345:     int got_name_map;
        !           346:   };
        !           347: 
        !           348: /* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found
        !           349:    via the same directory as the file that #included it. */
        !           350: #define SELF_DIR_DUMMY ((struct file_name_list*)(~0))
        !           351: 
        !           352: /* #include "file" looks in source file dir, then stack. */
        !           353: /* #include <file> just looks in the stack. */
        !           354: /* -I directories are added to the end, then the defaults are added. */
        !           355: /* The */
        !           356: static struct default_include {
        !           357:   char *fname;                 /* The name of the directory.  */
        !           358:   int cplusplus;               /* Only look here if we're compiling C++.  */
        !           359:   int cxx_aware;               /* Includes in this directory don't need to
        !           360:                                   be wrapped in extern "C" when compiling
        !           361:                                   C++.  */
        !           362: } include_defaults_array[]
        !           363: #ifdef INCLUDE_DEFAULTS
        !           364:   = INCLUDE_DEFAULTS;
        !           365: #else
        !           366:   = {
        !           367:     /* Pick up GNU C++ specific include files.  */
        !           368:     { GPLUSPLUS_INCLUDE_DIR, 1, 1 },
        !           369: #ifdef CROSS_COMPILE
        !           370:     /* This is the dir for fixincludes.  Put it just before
        !           371:        the files that we fix.  */
        !           372:     { GCC_INCLUDE_DIR, 0, 0 },
        !           373:     /* For cross-compilation, this dir name is generated
        !           374:        automatically in Makefile.in.  */
        !           375:     { CROSS_INCLUDE_DIR, 0, 0 },
        !           376:     /* This is another place that the target system's headers might be.  */
        !           377:     { TOOL_INCLUDE_DIR, 0, 1 },
        !           378: #else /* not CROSS_COMPILE */
        !           379:     /* This should be /usr/local/include and should come before
        !           380:        the fixincludes-fixed header files.  */
        !           381:     { LOCAL_INCLUDE_DIR, 0, 1 },
        !           382:     /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
        !           383:        Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h.  */
        !           384:     { TOOL_INCLUDE_DIR, 0, 1 },
        !           385:     /* This is the dir for fixincludes.  Put it just before
        !           386:        the files that we fix.  */
        !           387:     { GCC_INCLUDE_DIR, 0, 0 },
        !           388:     /* Some systems have an extra dir of include files.  */
        !           389: #ifdef SYSTEM_INCLUDE_DIR
        !           390:     { SYSTEM_INCLUDE_DIR, 0, 0 },
        !           391: #endif
        !           392:     { STANDARD_INCLUDE_DIR, 0, 0 },
        !           393: #endif /* not CROSS_COMPILE */
        !           394:     { 0, 0, 0 }
        !           395:     };
        !           396: #endif /* no INCLUDE_DEFAULTS */
        !           397: 
        !           398: /* `struct directive' defines one #-directive, including how to handle it.  */
        !           399: 
        !           400: struct directive {
        !           401:   int length;                  /* Length of name */
        !           402:   int (*func)();               /* Function to handle directive */
        !           403:   char *name;                  /* Name of directive */
        !           404:   enum node_type type;         /* Code which describes which directive. */
        !           405:   char command_reads_line;      /* One if rest of line is read by func. */
        !           406:   char traditional_comments;   /* Nonzero: keep comments if -traditional.  */
        !           407:   char pass_thru;              /* Copy preprocessed directive to output file.*/
        !           408: };
        !           409: 
        !           410: /* Here is the actual list of #-directives, most-often-used first.
        !           411:    The initialize_builtins function assumes #define is the very first.  */
        !           412: 
        !           413: static struct directive directive_table[] = {
        !           414:   {  6, do_define, "define", T_DEFINE, 0, 1},
        !           415:   {  5, do_xifdef, "ifdef", T_IFDEF, 1},
        !           416:   {  6, do_xifdef, "ifndef", T_IFNDEF, 1},
        !           417:   {  7, do_include, "include", T_INCLUDE, 1},
        !           418:   { 12, do_include, "include_next", T_INCLUDE_NEXT, 1},
        !           419:   {  6, do_include, "import", T_IMPORT, 1},
        !           420:   {  5, do_endif, "endif", T_ENDIF, 1},
        !           421:   {  4, do_else, "else", T_ELSE, 1},
        !           422:   {  2, do_if, "if", T_IF, 1},
        !           423:   {  4, do_elif, "elif", T_ELIF, 1},
        !           424:   {  5, do_undef, "undef", T_UNDEF},
        !           425:   {  5, do_error, "error", T_ERROR},
        !           426:   {  7, do_warning, "warning", T_WARNING},
        !           427:   {  6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1},
        !           428:   {  4, do_line, "line", T_LINE, 1},
        !           429:   {  5, do_ident, "ident", T_IDENT, 1, 0, 1},
        !           430: #ifdef SCCS_DIRECTIVE
        !           431:   {  4, do_sccs, "sccs", T_SCCS},
        !           432: #endif
        !           433:   {  6, do_assert, "assert", T_ASSERT, 1},
        !           434:   {  8, do_unassert, "unassert", T_UNASSERT, 1},
        !           435:   {  -1, 0, "", T_UNUSED},
        !           436: };
        !           437: 
        !           438: /* table to tell if char can be part of a C identifier. */
        !           439: U_CHAR is_idchar[256];
        !           440: /* table to tell if char can be first char of a c identifier. */
        !           441: U_CHAR is_idstart[256];
        !           442: /* table to tell if c is horizontal space.  */
        !           443: U_CHAR is_hor_space[256];
        !           444: /* table to tell if c is horizontal or vertical space.  */
        !           445: static U_CHAR is_space[256];
        !           446: 
        !           447: /* Initialize syntactic classifications of characters.  */
        !           448: 
        !           449: static void
        !           450: initialize_char_syntax (opts)
        !           451:      struct cpp_options *opts;
        !           452: {
        !           453:   register int i;
        !           454: 
        !           455:   /*
        !           456:    * Set up is_idchar and is_idstart tables.  These should be
        !           457:    * faster than saying (is_alpha (c) || c == '_'), etc.
        !           458:    * Set up these things before calling any routines tthat
        !           459:    * refer to them.
        !           460:    */
        !           461:   for (i = 'a'; i <= 'z'; i++) {
        !           462:     is_idchar[i - 'a' + 'A'] = 1;
        !           463:     is_idchar[i] = 1;
        !           464:     is_idstart[i - 'a' + 'A'] = 1;
        !           465:     is_idstart[i] = 1;
        !           466:   }
        !           467:   for (i = '0'; i <= '9'; i++)
        !           468:     is_idchar[i] = 1;
        !           469:   is_idchar['_'] = 1;
        !           470:   is_idstart['_'] = 1;
        !           471:   is_idchar['$'] = opts->dollars_in_ident;
        !           472:   is_idstart['$'] = opts->dollars_in_ident;
        !           473: 
        !           474:   /* horizontal space table */
        !           475:   is_hor_space[' '] = 1;
        !           476:   is_hor_space['\t'] = 1;
        !           477:   is_hor_space['\v'] = 1;
        !           478:   is_hor_space['\f'] = 1;
        !           479:   is_hor_space['\r'] = 1;
        !           480: 
        !           481:   is_space[' '] = 1;
        !           482:   is_space['\t'] = 1;
        !           483:   is_space['\v'] = 1;
        !           484:   is_space['\f'] = 1;
        !           485:   is_space['\n'] = 1;
        !           486:   is_space['\r'] = 1;
        !           487: }
        !           488: 
        !           489: 
        !           490: /* Place into PFILE a quoted string representing the string SRC.
        !           491:    Caller must reserve enough space in pfile->token_buffer. */
        !           492: static void
        !           493: quote_string (pfile, src)
        !           494:      cpp_reader *pfile;
        !           495:      char *src;
        !           496: {
        !           497:   U_CHAR c;
        !           498: 
        !           499:   CPP_PUTC_Q (pfile, '\"');
        !           500:   for (;;)
        !           501:     switch ((c = *src++))
        !           502:       {
        !           503:       default:
        !           504:         if (isprint (c))
        !           505:          CPP_PUTC_Q (pfile, c);
        !           506:        else
        !           507:          {
        !           508:            sprintf (CPP_PWRITTEN (pfile), "\\%03o", c);
        !           509:            CPP_ADJUST_WRITTEN (pfile, 4);
        !           510:          }
        !           511:        break;
        !           512: 
        !           513:       case '\"':
        !           514:       case '\\':
        !           515:        CPP_PUTC_Q (pfile, '\\');
        !           516:        CPP_PUTC_Q (pfile, c);
        !           517:        break;
        !           518:       
        !           519:       case '\0':
        !           520:        CPP_PUTC_Q (pfile, '\"');
        !           521:        CPP_NUL_TERMINATE_Q (pfile);
        !           522:        return;
        !           523:       }
        !           524: }
        !           525: 
        !           526: /* Make sure PFILE->token_buffer will hold at least N more chars. */
        !           527: 
        !           528: void
        !           529: cpp_grow_buffer (pfile, n)
        !           530:      cpp_reader *pfile;
        !           531:      long n;
        !           532: {
        !           533:   long old_written = CPP_WRITTEN (pfile);
        !           534:   pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;
        !           535:   pfile->token_buffer = (U_CHAR*)
        !           536:     xrealloc(pfile->token_buffer, pfile->token_buffer_size);
        !           537:   CPP_SET_WRITTEN (pfile, old_written);
        !           538: }
        !           539: 
        !           540: 
        !           541: /*
        !           542:  * process a given definition string, for initialization
        !           543:  * If STR is just an identifier, define it with value 1.
        !           544:  * If STR has anything after the identifier, then it should
        !           545:  * be identifier=definition.
        !           546:  */
        !           547: 
        !           548: void
        !           549: cpp_define (pfile, str)
        !           550:      cpp_reader *pfile;
        !           551:      U_CHAR *str;
        !           552: {
        !           553:   U_CHAR *buf, *p;
        !           554: 
        !           555:   buf = str;
        !           556:   p = str;
        !           557:   if (!is_idstart[*p])
        !           558:     {
        !           559:       cpp_error (pfile, "malformed option `-D %s'", str);
        !           560:       return;
        !           561:     }
        !           562:   while (is_idchar[*++p])
        !           563:     ;
        !           564:   if (*p == 0)
        !           565:     {
        !           566:       buf = (U_CHAR *) alloca (p - buf + 4);
        !           567:       strcpy ((char *)buf, str);
        !           568:       strcat ((char *)buf, " 1");
        !           569:     }
        !           570:   else if (*p != '=')
        !           571:     {
        !           572:       cpp_error (pfile, "malformed option `-D %s'", str);
        !           573:       return;
        !           574:     }
        !           575:   else
        !           576:     {
        !           577:       U_CHAR *q;
        !           578:       /* Copy the entire option so we can modify it.  */
        !           579:       buf = (U_CHAR *) alloca (2 * strlen (str) + 1);
        !           580:       strncpy (buf, str, p - str);
        !           581:       /* Change the = to a space.  */
        !           582:       buf[p - str] = ' ';
        !           583:       /* Scan for any backslash-newline and remove it.  */
        !           584:       p++;
        !           585:       q = &buf[p - str];
        !           586:       while (*p)
        !           587:        {
        !           588:       if (*p == '\\' && p[1] == '\n')
        !           589:        p += 2;
        !           590:       else
        !           591:        *q++ = *p++;
        !           592:     }
        !           593:     *q = 0;
        !           594:   }
        !           595:   
        !           596:   do_define (pfile, NULL, buf, buf + strlen (buf));
        !           597: }
        !           598: 
        !           599: /* Process the string STR as if it appeared as the body of a #assert.
        !           600:    OPTION is the option name for which STR was the argument.  */
        !           601: 
        !           602: static void
        !           603: make_assertion (pfile, option, str)
        !           604:      cpp_reader *pfile;
        !           605:      char *option;
        !           606:      U_CHAR *str;
        !           607: {
        !           608:   cpp_buffer *ip;
        !           609:   struct directive *kt;
        !           610:   U_CHAR *buf, *p, *q;
        !           611: 
        !           612:   /* Copy the entire option so we can modify it.  */
        !           613:   buf = (U_CHAR *) alloca (strlen (str) + 1);
        !           614:   strcpy ((char *) buf, str);
        !           615:   /* Scan for any backslash-newline and remove it.  */
        !           616:   p = q = buf;
        !           617:   while (*p) {
        !           618: #if 0
        !           619:     if (*p == '\\' && p[1] == '\n')
        !           620:       p += 2;
        !           621:     else
        !           622: #endif
        !           623:       *q++ = *p++;
        !           624:   }
        !           625:   *q = 0;
        !           626: 
        !           627:   p = buf;
        !           628:   if (!is_idstart[*p]) {
        !           629:     cpp_error (pfile, "malformed option `%s %s'", option, str);
        !           630:     return;
        !           631:   }
        !           632:   while (is_idchar[*++p])
        !           633:     ;
        !           634:   while (*p == ' ' || *p == '\t') p++;
        !           635:   if (! (*p == 0 || *p == '(')) {
        !           636:     cpp_error (pfile, "malformed option `%s %s'", option, str);
        !           637:     return;
        !           638:   }
        !           639:   
        !           640:   ip = cpp_push_buffer (pfile, buf, strlen (buf));
        !           641:   do_assert (pfile, NULL, NULL, NULL);
        !           642:   cpp_pop_buffer (pfile);
        !           643: }
        !           644: 
        !           645: /* Append a chain of `struct file_name_list's
        !           646:    to the end of the main include chain.
        !           647:    FIRST is the beginning of the chain to append, and LAST is the end.  */
        !           648: 
        !           649: static void
        !           650: append_include_chain (pfile, first, last)
        !           651:      cpp_reader *pfile;
        !           652:      struct file_name_list *first, *last;
        !           653: {
        !           654:   struct cpp_options *opts = CPP_OPTIONS (pfile);
        !           655:   struct file_name_list *dir;
        !           656: 
        !           657:   if (!first || !last)
        !           658:     return;
        !           659: 
        !           660:   if (opts->include == 0)
        !           661:     opts->include = first;
        !           662:   else
        !           663:     opts->last_include->next = first;
        !           664: 
        !           665:   if (opts->first_bracket_include == 0)
        !           666:     opts->first_bracket_include = first;
        !           667: 
        !           668:   for (dir = first; ; dir = dir->next) {
        !           669:     int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
        !           670:     if (len > pfile->max_include_len)
        !           671:       pfile->max_include_len = len;
        !           672:     if (dir == last)
        !           673:       break;
        !           674:   }
        !           675: 
        !           676:   last->next = NULL;
        !           677:   opts->last_include = last;
        !           678: }
        !           679: 
        !           680: /* Add output to `deps_buffer' for the -M switch.
        !           681:    STRING points to the text to be output.
        !           682:    SPACER is ':' for targets, ' ' for dependencies, zero for text
        !           683:    to be inserted literally.  */
        !           684: 
        !           685: static void
        !           686: deps_output (pfile, string, spacer)
        !           687:      cpp_reader *pfile;
        !           688:      char *string;
        !           689:      int spacer;
        !           690: {
        !           691:   int size = strlen (string);
        !           692: 
        !           693:   if (size == 0)
        !           694:     return;
        !           695: 
        !           696: #ifndef MAX_OUTPUT_COLUMNS
        !           697: #define MAX_OUTPUT_COLUMNS 72
        !           698: #endif
        !           699:   if (spacer
        !           700:       && pfile->deps_column > 0
        !           701:       && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
        !           702:     {
        !           703:       deps_output (pfile, " \\\n  ", 0);
        !           704:       pfile->deps_column = 0;
        !           705:     }
        !           706: 
        !           707:   if (pfile->deps_size + size + 8 > pfile->deps_allocated_size)
        !           708:     {
        !           709:       pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
        !           710:       pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
        !           711:                                              pfile->deps_allocated_size);
        !           712:     }
        !           713:   if (spacer == ' ' && pfile->deps_column > 0)
        !           714:     pfile->deps_buffer[pfile->deps_size++] = ' ';
        !           715:   bcopy (string, &pfile->deps_buffer[pfile->deps_size], size);
        !           716:   pfile->deps_size += size;
        !           717:   pfile->deps_column += size;
        !           718:   if (spacer == ':')
        !           719:     pfile->deps_buffer[pfile->deps_size++] = ':';
        !           720:   pfile->deps_buffer[pfile->deps_size] = 0;
        !           721: }
        !           722: 
        !           723: /* Given a colon-separated list of file names PATH,
        !           724:    add all the names to the search path for include files.  */
        !           725: 
        !           726: static void
        !           727: path_include (pfile, path)
        !           728:      cpp_reader *pfile;
        !           729:      char *path;
        !           730: {
        !           731:   char *p;
        !           732: 
        !           733:   p = path;
        !           734: 
        !           735:   if (*p)
        !           736:     while (1) {
        !           737:       char *q = p;
        !           738:       char *name;
        !           739:       struct file_name_list *dirtmp;
        !           740: 
        !           741:       /* Find the end of this name.  */
        !           742:       while (*q != 0 && *q != PATH_SEPARATOR) q++;
        !           743:       if (p == q) {
        !           744:        /* An empty name in the path stands for the current directory.  */
        !           745:        name = (char *) xmalloc (2);
        !           746:        name[0] = '.';
        !           747:        name[1] = 0;
        !           748:       } else {
        !           749:        /* Otherwise use the directory that is named.  */
        !           750:        name = (char *) xmalloc (q - p + 1);
        !           751:        bcopy (p, name, q - p);
        !           752:        name[q - p] = 0;
        !           753:       }
        !           754: 
        !           755:       dirtmp = (struct file_name_list *)
        !           756:        xmalloc (sizeof (struct file_name_list));
        !           757:       dirtmp->next = 0;                /* New one goes on the end */
        !           758:       dirtmp->control_macro = 0;
        !           759:       dirtmp->c_system_include_path = 0;
        !           760:       dirtmp->fname = name;
        !           761:       dirtmp->got_name_map = 0;
        !           762:       append_include_chain (pfile, dirtmp, dirtmp);
        !           763: 
        !           764:       /* Advance past this name.  */
        !           765:       p = q;
        !           766:       if (*p == 0)
        !           767:        break;
        !           768:       /* Skip the colon.  */
        !           769:       p++;
        !           770:     }
        !           771: }
        !           772: 
        !           773: void
        !           774: init_parse_options (opts)
        !           775:      struct cpp_options *opts;
        !           776: {
        !           777:   bzero ((char *) opts, sizeof *opts);
        !           778:   opts->in_fname = NULL;
        !           779:   opts->out_fname = NULL;
        !           780: 
        !           781:   /* Initialize is_idchar to allow $.  */
        !           782:   opts->dollars_in_ident = 1;
        !           783:   initialize_char_syntax (opts);
        !           784:   opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0;
        !           785: 
        !           786:   opts->no_line_commands = 0;
        !           787:   opts->no_trigraphs = 1;
        !           788:   opts->put_out_comments = 0;
        !           789:   opts->print_include_names = 0;
        !           790:   opts->dump_macros = dump_none;
        !           791:   opts->no_output = 0;
        !           792:   opts->cplusplus = 0;
        !           793:   opts->cplusplus_comments = 0;
        !           794: 
        !           795:   opts->verbose = 0;
        !           796:   opts->objc = 0;
        !           797:   opts->lang_asm = 0;
        !           798:   opts->for_lint = 0;
        !           799:   opts->chill = 0;
        !           800:   opts->pedantic_errors = 0;
        !           801:   opts->inhibit_warnings = 0;
        !           802:   opts->warn_comments = 0;
        !           803:   opts->warn_import = 1;
        !           804:   opts->warnings_are_errors = 0;
        !           805: }
        !           806: 
        !           807: enum cpp_token
        !           808: null_underflow (pfile)
        !           809:      cpp_reader *pfile;
        !           810: {
        !           811:   return CPP_EOF;
        !           812: }
        !           813: 
        !           814: int
        !           815: null_cleanup (pbuf, pfile)
        !           816:      cpp_buffer *pbuf;
        !           817:      cpp_reader *pfile;
        !           818: {
        !           819:   return 0;
        !           820: }
        !           821: 
        !           822: int
        !           823: macro_cleanup (pbuf, pfile)
        !           824:      cpp_buffer *pbuf;
        !           825:      cpp_reader *pfile;
        !           826: {
        !           827:   HASHNODE *macro = (HASHNODE*)pbuf->data;
        !           828:   if (macro->type == T_DISABLED)
        !           829:     macro->type = T_MACRO;
        !           830:   if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
        !           831:     free (pbuf->buf);
        !           832:   return 0;
        !           833: }
        !           834: 
        !           835: int
        !           836: file_cleanup (pbuf, pfile)
        !           837:      cpp_buffer *pbuf;
        !           838:      cpp_reader *pfile;
        !           839: {
        !           840:   if (pbuf->buf)
        !           841:     {
        !           842:       free (pbuf->buf);
        !           843:       pbuf->buf = 0;
        !           844:     }
        !           845:   return 0;
        !           846: }
        !           847: 
        !           848: static void
        !           849: newline_fix (pfile)
        !           850:      cpp_reader *pfile;
        !           851: {
        !           852: #if 1
        !           853:   NEWLINE_FIX;
        !           854: #else
        !           855:   register U_CHAR *p = bp;
        !           856: 
        !           857:   /* First count the backslash-newline pairs here.  */
        !           858: 
        !           859:   while (p[0] == '\\' && p[1] == '\n')
        !           860:     p += 2;
        !           861: 
        !           862:   /* What follows the backslash-newlines is not embarrassing.  */
        !           863: 
        !           864:   if (*p != '/' && *p != '*')
        !           865:     return;
        !           866: 
        !           867:   /* Copy all potentially embarrassing characters
        !           868:      that follow the backslash-newline pairs
        !           869:      down to where the pairs originally started.  */
        !           870: 
        !           871:   while (*p == '*' || *p == '/')
        !           872:     *bp++ = *p++;
        !           873: 
        !           874:   /* Now write the same number of pairs after the embarrassing chars.  */
        !           875:   while (bp < p) {
        !           876:     *bp++ = '\\';
        !           877:     *bp++ = '\n';
        !           878:   }
        !           879: #endif
        !           880: }
        !           881: 
        !           882: /* Assuming we have read '/'.
        !           883:    If this is the start of a comment (followed by '*' or '/'),
        !           884:    skip to the end of the comment, and return ' '.
        !           885:    Return EOF if we reached the end of file before the end of the comment.
        !           886:    If not the start of a comment, return '/'. */
        !           887: 
        !           888: static int
        !           889: skip_comment (pfile, linep)
        !           890:      cpp_reader *pfile;
        !           891:      long *linep;
        !           892: {
        !           893:   int c;
        !           894:   while (PEEKC() == '\\' && PEEKN(1) == '\n')
        !           895:     {
        !           896:       if (linep)
        !           897:        (*linep)++;
        !           898:       FORWARD(2);
        !           899:     }
        !           900:   if (PEEKC() == '*')
        !           901:     {
        !           902:       FORWARD(1);
        !           903:       for (;;)
        !           904:        {
        !           905:          int prev_c = c;
        !           906:          c = GETC ();
        !           907:          if (c == EOF)
        !           908:            return EOF;
        !           909:          while (c == '\\' && PEEKC() == '\n')
        !           910:            {
        !           911:              if (linep)
        !           912:                (*linep)++;
        !           913:              FORWARD(1), c = GETC();
        !           914:            }
        !           915:          if (prev_c == '*' && c == '/')
        !           916:            return ' ';
        !           917:          if (c == '\n' && linep)
        !           918:            (*linep)++;
        !           919:        }
        !           920:     }
        !           921:   else if (PEEKC() == '/' && CPP_OPTIONS (pfile)->cplusplus_comments)
        !           922:     {
        !           923:       FORWARD(1);
        !           924:       for (;;)
        !           925:        {
        !           926:          c = GETC ();
        !           927:          if (c == EOF)
        !           928:            return ' '; /* Allow // to be terminated by EOF. */
        !           929:          while (c == '\\' && PEEKC() == '\n')
        !           930:            {
        !           931:              FORWARD(1);
        !           932:              c = GETC();
        !           933:              if (linep)
        !           934:                (*linep)++;
        !           935:            }
        !           936:          if (c == '\n')
        !           937:            {
        !           938:              /* Don't consider final '\n' to be part of comment. */
        !           939:              FORWARD(-1);
        !           940:              return ' ';
        !           941:            }
        !           942:        }
        !           943:     }
        !           944:   else
        !           945:     return '/';
        !           946: }     
        !           947: 
        !           948: /* Skip whitespace \-newline and comments.  Does not macro-expand.  */
        !           949: void
        !           950: cpp_skip_hspace (pfile)
        !           951:      cpp_reader *pfile;
        !           952: {
        !           953:   while (1)
        !           954:     {
        !           955:       int c = PEEKC();
        !           956:       if (c == EOF)
        !           957:        return; /* FIXME */
        !           958:       if (is_hor_space[c])
        !           959:        {
        !           960:          if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile))
        !           961:            cpp_pedwarn (pfile, "%s in preprocessing directive",
        !           962:                         c == '\f' ? "formfeed" : "vertical tab");
        !           963:          FORWARD(1);
        !           964:        }
        !           965:       else if (c == '/')
        !           966:        {
        !           967:          FORWARD (1);
        !           968:          c = skip_comment (pfile, NULL);
        !           969:          if (c == '/')
        !           970:            FORWARD(-1);
        !           971:          if (c == EOF || c == '/')
        !           972:            return;
        !           973:        }
        !           974:       else if (c == '\\' && PEEKN(1) == '\n') {
        !           975:        FORWARD(2);
        !           976:       }
        !           977:       else if (c == '@' && CPP_BUFFER (pfile)->has_escapes
        !           978:               && is_hor_space[PEEKN(1)])
        !           979:        FORWARD(2);
        !           980:       else return;
        !           981:     }
        !           982: }
        !           983: 
        !           984: /* Read the rest of the current line.
        !           985:    The line is appended to PFILE's output buffer. */
        !           986: 
        !           987: void
        !           988: copy_rest_of_line (pfile)
        !           989:      cpp_reader *pfile;
        !           990: {
        !           991:   struct cpp_options *opts = CPP_OPTIONS (pfile);
        !           992:   for (;;)
        !           993:     {
        !           994:       int c = GETC();
        !           995:       int nextc;
        !           996:       switch (c)
        !           997:        {
        !           998:        case EOF:
        !           999:          goto end_directive;
        !          1000:        case '\\':
        !          1001:          if (PEEKC() == '\n')
        !          1002:            {
        !          1003:              FORWARD (1);
        !          1004:              continue;
        !          1005:            }
        !          1006:        case '\'':
        !          1007:        case '\"':
        !          1008:          goto scan_directive_token;
        !          1009:          break;
        !          1010:        case '/':
        !          1011:          nextc = PEEKC();
        !          1012:          if (nextc == '*' || (opts->cplusplus_comments && nextc == '*'))
        !          1013:            goto scan_directive_token;
        !          1014:          break;
        !          1015:        case '\f':
        !          1016:        case '\v':
        !          1017:          if (CPP_PEDANTIC (pfile))
        !          1018:            cpp_pedwarn (pfile, "%s in preprocessing directive",
        !          1019:                         c == '\f' ? "formfeed" : "vertical tab");
        !          1020:          break;
        !          1021: 
        !          1022:        case '\n':
        !          1023:          FORWARD(-1);
        !          1024:          goto end_directive;
        !          1025:        scan_directive_token:
        !          1026:          FORWARD(-1);
        !          1027:          cpp_get_token (pfile);
        !          1028:          continue;
        !          1029:        }
        !          1030:       CPP_PUTC (pfile, c);
        !          1031:     }
        !          1032:  end_directive: ;
        !          1033:   CPP_NUL_TERMINATE (pfile);
        !          1034: }
        !          1035: 
        !          1036: void
        !          1037: skip_rest_of_line (pfile)
        !          1038:      cpp_reader *pfile;
        !          1039: {
        !          1040:   long old = CPP_WRITTEN (pfile);
        !          1041:   copy_rest_of_line (pfile);
        !          1042:   CPP_SET_WRITTEN (pfile, old);
        !          1043: }
        !          1044: 
        !          1045: /* Handle a possible # directive.
        !          1046:    '#' has already been read.  */
        !          1047: 
        !          1048: int
        !          1049: handle_directive (pfile)
        !          1050:      cpp_reader *pfile;
        !          1051: { int c;
        !          1052:   register struct directive *kt;
        !          1053:   int ident_length;
        !          1054:   long after_ident;
        !          1055:   U_CHAR *ident, *line_end;
        !          1056:   long old_written = CPP_WRITTEN (pfile);
        !          1057: 
        !          1058:   cpp_skip_hspace (pfile);
        !          1059: 
        !          1060:   c = PEEKC ();
        !          1061:   if (c >= '0' && c <= '9')
        !          1062:     {
        !          1063:       /* Handle # followed by a line number.  */
        !          1064:       if (CPP_PEDANTIC (pfile))
        !          1065:        cpp_pedwarn (pfile, "`#' followed by integer");
        !          1066:       do_line (pfile, NULL);
        !          1067:       goto done_a_directive;
        !          1068:     }
        !          1069: 
        !          1070:   /* Now find the directive name. */
        !          1071:   CPP_PUTC (pfile, '#');
        !          1072:   parse_name (pfile, GETC());
        !          1073:   ident = pfile->token_buffer + old_written + 1;
        !          1074:   ident_length = CPP_PWRITTEN (pfile) - ident;
        !          1075:   if (ident_length == 0 && PEEKC() == '\n')
        !          1076:     {
        !          1077:       /* A line of just `#' becomes blank.  */
        !          1078:       goto done_a_directive;
        !          1079:     }
        !          1080: 
        !          1081: #if 0
        !          1082:   if (ident_length == 0 || !is_idstart[*ident]) {
        !          1083:     U_CHAR *p = ident;
        !          1084:     while (is_idchar[*p]) {
        !          1085:       if (*p < '0' || *p > '9')
        !          1086:        break;
        !          1087:       p++;
        !          1088:     }
        !          1089:     /* Avoid error for `###' and similar cases unless -pedantic.  */
        !          1090:     if (p == ident) {
        !          1091:       while (*p == '#' || is_hor_space[*p]) p++;
        !          1092:       if (*p == '\n') {
        !          1093:        if (pedantic && !lang_asm)
        !          1094:          cpp_warning (pfile, "invalid preprocessor directive");
        !          1095:        return 0;
        !          1096:       }
        !          1097:     }
        !          1098: 
        !          1099:     if (!lang_asm)
        !          1100:       cpp_error (pfile, "invalid preprocessor directive name");
        !          1101: 
        !          1102:     return 0;
        !          1103:   }
        !          1104: #endif
        !          1105:   /*
        !          1106:    * Decode the keyword and call the appropriate expansion
        !          1107:    * routine, after moving the input pointer up to the next line.
        !          1108:    */
        !          1109:   for (kt = directive_table; ; kt++) {
        !          1110:     if (kt->length <= 0)
        !          1111:       goto not_a_directive;
        !          1112:     if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length)) 
        !          1113:       break;
        !          1114:   }
        !          1115: 
        !          1116:   if (! kt->command_reads_line)
        !          1117:     {
        !          1118:       /* Nonzero means do not delete comments within the directive.
        !          1119:          #define needs this when -traditional.  */
        !          1120:        int comments = CPP_TRADITIONAL (pfile) && kt->traditional_comments; 
        !          1121:        int save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments;
        !          1122:        CPP_OPTIONS (pfile)->put_out_comments = comments;
        !          1123:        after_ident = CPP_WRITTEN (pfile);
        !          1124:        copy_rest_of_line (pfile);
        !          1125:        CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments;
        !          1126:     }
        !          1127: 
        !          1128:   /* For #pragma and #define, we may want to pass through the directive.
        !          1129:      Other directives may create output, but we don't want the directive
        !          1130:      itself out, so we pop it now.  For example #include may write a #line
        !          1131:      command (see comment in do_include), and conditionals may emit
        !          1132:      #failed ... #endfailed stuff.  But note that popping the buffer
        !          1133:      means the parameters to kt->func may point after pfile->limit
        !          1134:      so these parameters are invalid as soon as something gets appended
        !          1135:      to the token_buffer.  */
        !          1136: 
        !          1137:   line_end = CPP_PWRITTEN (pfile);
        !          1138:   if (!kt->pass_thru && kt->type != T_DEFINE)
        !          1139:     CPP_SET_WRITTEN (pfile, old_written);
        !          1140: 
        !          1141:   (*kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end);
        !          1142:   if (kt->pass_thru
        !          1143:       || (kt->type == T_DEFINE
        !          1144:          && CPP_OPTIONS (pfile)->dump_macros == dump_definitions))
        !          1145:     {
        !          1146:       /* Just leave the entire #define in the output stack. */
        !          1147:     }
        !          1148:   else if (kt->type == T_DEFINE
        !          1149:           && CPP_OPTIONS (pfile)->dump_macros == dump_names)
        !          1150:     {
        !          1151:       U_CHAR *p = pfile->token_buffer + old_written + 7;  /* Skip "#define". */
        !          1152:       SKIP_WHITE_SPACE (p);
        !          1153:       while (is_idchar[*p]) p++;
        !          1154:       pfile->limit = p;
        !          1155:       CPP_PUTC (pfile, '\n');
        !          1156:     }
        !          1157:   else if (kt->type == T_DEFINE)
        !          1158:     CPP_SET_WRITTEN (pfile, old_written);
        !          1159:  done_a_directive:
        !          1160:   return 1;
        !          1161: 
        !          1162:  not_a_directive:
        !          1163:   return 0;
        !          1164: }
        !          1165: 
        !          1166: /* Pass a directive through to the output file.
        !          1167:    BUF points to the contents of the directive, as a contiguous string.
        !          1168:    LIMIT points to the first character past the end of the directive.
        !          1169:    KEYWORD is the keyword-table entry for the directive.  */
        !          1170: 
        !          1171: static void
        !          1172: pass_thru_directive (buf, limit, pfile, keyword)
        !          1173:      U_CHAR *buf, *limit;
        !          1174:      cpp_reader *pfile;
        !          1175:      struct directive *keyword;
        !          1176: {
        !          1177:   register unsigned keyword_length = keyword->length;
        !          1178: 
        !          1179:   CPP_RESERVE (pfile, 1 + keyword_length + (limit - buf));
        !          1180:   CPP_PUTC_Q (pfile, '#');
        !          1181:   CPP_PUTS_Q (pfile, keyword->name, keyword_length);
        !          1182:   if (limit != buf && buf[0] != ' ')
        !          1183:     CPP_PUTC_Q (pfile, ' ');
        !          1184:   CPP_PUTS_Q (pfile, buf, limit - buf);
        !          1185: #if 0
        !          1186:   CPP_PUTS_Q (pfile, '\n');
        !          1187:   /* Count the line we have just made in the output,
        !          1188:      to get in sync properly.  */
        !          1189:   pfile->lineno++;
        !          1190: #endif
        !          1191: }
        !          1192: 
        !          1193: /* The arglist structure is built by do_define to tell
        !          1194:    collect_definition where the argument names begin.  That
        !          1195:    is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
        !          1196:    would contain pointers to the strings x, y, and z.
        !          1197:    Collect_definition would then build a DEFINITION node,
        !          1198:    with reflist nodes pointing to the places x, y, and z had
        !          1199:    appeared.  So the arglist is just convenience data passed
        !          1200:    between these two routines.  It is not kept around after
        !          1201:    the current #define has been processed and entered into the
        !          1202:    hash table. */
        !          1203: 
        !          1204: struct arglist {
        !          1205:   struct arglist *next;
        !          1206:   U_CHAR *name;
        !          1207:   int length;
        !          1208:   int argno;
        !          1209:   char rest_args;
        !          1210: };
        !          1211: 
        !          1212: /* Read a replacement list for a macro with parameters.
        !          1213:    Build the DEFINITION structure.
        !          1214:    Reads characters of text starting at BUF until END.
        !          1215:    ARGLIST specifies the formal parameters to look for
        !          1216:    in the text of the definition; NARGS is the number of args
        !          1217:    in that list, or -1 for a macro name that wants no argument list.
        !          1218:    MACRONAME is the macro name itself (so we can avoid recursive expansion)
        !          1219:    and NAMELEN is its length in characters.
        !          1220:    
        !          1221:    Note that comments, backslash-newlines, and leading white space
        !          1222:    have already been deleted from the argument.  */
        !          1223: 
        !          1224: static DEFINITION *
        !          1225: collect_expansion (pfile, buf, limit, nargs, arglist)
        !          1226:      cpp_reader *pfile;
        !          1227:      U_CHAR *buf, *limit;
        !          1228:      int nargs;
        !          1229:      struct arglist *arglist;
        !          1230: {
        !          1231:   DEFINITION *defn;
        !          1232:   register U_CHAR *p, *lastp, *exp_p;
        !          1233:   struct reflist *endpat = NULL;
        !          1234:   /* Pointer to first nonspace after last ## seen.  */
        !          1235:   U_CHAR *concat = 0;
        !          1236:   /* Pointer to first nonspace after last single-# seen.  */
        !          1237:   U_CHAR *stringify = 0;
        !          1238:   int maxsize;
        !          1239:   int expected_delimiter = '\0';
        !          1240: 
        !          1241:   /* Scan thru the replacement list, ignoring comments and quoted
        !          1242:      strings, picking up on the macro calls.  It does a linear search
        !          1243:      thru the arg list on every potential symbol.  Profiling might say
        !          1244:      that something smarter should happen. */
        !          1245: 
        !          1246:   if (limit < buf)
        !          1247:     abort ();
        !          1248: 
        !          1249:   /* Find the beginning of the trailing whitespace.  */
        !          1250:   p = buf;
        !          1251:   while (p < limit && is_space[limit[-1]]) limit--;
        !          1252: 
        !          1253:   /* Allocate space for the text in the macro definition.
        !          1254:      Leading and trailing whitespace chars need 2 bytes each.
        !          1255:      Each other input char may or may not need 1 byte,
        !          1256:      so this is an upper bound.  The extra 5 are for invented
        !          1257:      leading and trailing newline-marker and final null.  */
        !          1258:   maxsize = (sizeof (DEFINITION)
        !          1259:             + (limit - p) + 5);
        !          1260:   /* Occurrences of '@' get doubled, so allocate extra space for them. */
        !          1261:   while (p < limit)
        !          1262:     if (*p++ == '@')
        !          1263:       maxsize++;
        !          1264:   defn = (DEFINITION *) xcalloc (1, maxsize);
        !          1265: 
        !          1266:   defn->nargs = nargs;
        !          1267:   exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
        !          1268:   lastp = exp_p;
        !          1269: 
        !          1270:   p = buf;
        !          1271: 
        !          1272:   /* Add one initial space escape-marker to prevent accidental
        !          1273:      token-pasting (often removed by macroexpand). */
        !          1274:   *exp_p++ = '@';
        !          1275:   *exp_p++ = ' ';
        !          1276: 
        !          1277:   if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
        !          1278:     cpp_error (pfile, "`##' at start of macro definition");
        !          1279:     p += 2;
        !          1280:   }
        !          1281: 
        !          1282:   /* Process the main body of the definition.  */
        !          1283:   while (p < limit) {
        !          1284:     int skipped_arg = 0;
        !          1285:     register U_CHAR c = *p++;
        !          1286: 
        !          1287:     *exp_p++ = c;
        !          1288: 
        !          1289:     if (!CPP_TRADITIONAL (pfile)) {
        !          1290:       switch (c) {
        !          1291:       case '\'':
        !          1292:       case '\"':
        !          1293:         if (expected_delimiter != '\0') {
        !          1294:           if (c == expected_delimiter)
        !          1295:             expected_delimiter = '\0';
        !          1296:         } else
        !          1297:           expected_delimiter = c;
        !          1298:        break;
        !          1299: 
        !          1300:       case '\\':
        !          1301:        if (p < limit && expected_delimiter) {
        !          1302:          /* In a string, backslash goes through
        !          1303:             and makes next char ordinary.  */
        !          1304:          *exp_p++ = *p++;
        !          1305:        }
        !          1306:        break;
        !          1307: 
        !          1308:       case '@':
        !          1309:        /* An '@' in a string or character constant stands for itself,
        !          1310:           and does not need to be escaped. */
        !          1311:        if (!expected_delimiter)
        !          1312:          *exp_p++ = c;
        !          1313:        break;
        !          1314: 
        !          1315:       case '#':
        !          1316:        /* # is ordinary inside a string.  */
        !          1317:        if (expected_delimiter)
        !          1318:          break;
        !          1319:        if (p < limit && *p == '#') {
        !          1320:          /* ##: concatenate preceding and following tokens.  */
        !          1321:          /* Take out the first #, discard preceding whitespace.  */
        !          1322:          exp_p--;
        !          1323:          while (exp_p > lastp && is_hor_space[exp_p[-1]])
        !          1324:            --exp_p;
        !          1325:          /* Skip the second #.  */
        !          1326:          p++;
        !          1327:          /* Discard following whitespace.  */
        !          1328:          SKIP_WHITE_SPACE (p);
        !          1329:          concat = p;
        !          1330:          if (p == limit)
        !          1331:            cpp_error (pfile, "`##' at end of macro definition");
        !          1332:        } else if (nargs >= 0) {
        !          1333:          /* Single #: stringify following argument ref.
        !          1334:             Don't leave the # in the expansion.  */
        !          1335:          exp_p--;
        !          1336:          SKIP_WHITE_SPACE (p);
        !          1337:          if (p == limit || ! is_idstart[*p])
        !          1338:            cpp_error (pfile,
        !          1339:                     "`#' operator is not followed by a macro argument name");
        !          1340:          else
        !          1341:            stringify = p;
        !          1342:        }
        !          1343:        break;
        !          1344:       }
        !          1345:     } else {
        !          1346:       /* In -traditional mode, recognize arguments inside strings and
        !          1347:         and character constants, and ignore special properties of #.
        !          1348:         Arguments inside strings are considered "stringified", but no
        !          1349:         extra quote marks are supplied.  */
        !          1350:       switch (c) {
        !          1351:       case '\'':
        !          1352:       case '\"':
        !          1353:        if (expected_delimiter != '\0') {
        !          1354:          if (c == expected_delimiter)
        !          1355:            expected_delimiter = '\0';
        !          1356:        } else
        !          1357:          expected_delimiter = c;
        !          1358:        break;
        !          1359: 
        !          1360:       case '\\':
        !          1361:        /* Backslash quotes delimiters and itself, but not macro args.  */
        !          1362:        if (expected_delimiter != 0 && p < limit
        !          1363:            && (*p == expected_delimiter || *p == '\\')) {
        !          1364:          *exp_p++ = *p++;
        !          1365:          continue;
        !          1366:        }
        !          1367:        break;
        !          1368: 
        !          1369:       case '/':
        !          1370:        if (expected_delimiter != '\0') /* No comments inside strings.  */
        !          1371:          break;
        !          1372:        if (*p == '*') {
        !          1373:          /* If we find a comment that wasn't removed by handle_directive,
        !          1374:             this must be -traditional.  So replace the comment with
        !          1375:             nothing at all.  */
        !          1376:          exp_p--;
        !          1377:          p += 1;
        !          1378:          while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
        !          1379:            p++;
        !          1380: #if 0
        !          1381:          /* Mark this as a concatenation-point, as if it had been ##.  */
        !          1382:          concat = p;
        !          1383: #endif
        !          1384:        }
        !          1385:        break;
        !          1386:       }
        !          1387:     }
        !          1388: 
        !          1389:     /* Handle the start of a symbol.  */
        !          1390:     if (is_idchar[c] && nargs > 0) {
        !          1391:       U_CHAR *id_beg = p - 1;
        !          1392:       int id_len;
        !          1393: 
        !          1394:       --exp_p;
        !          1395:       while (p != limit && is_idchar[*p]) p++;
        !          1396:       id_len = p - id_beg;
        !          1397: 
        !          1398:       if (is_idstart[c]) {
        !          1399:        register struct arglist *arg;
        !          1400: 
        !          1401:        for (arg = arglist; arg != NULL; arg = arg->next) {
        !          1402:          struct reflist *tpat;
        !          1403: 
        !          1404:          if (arg->name[0] == c
        !          1405:              && arg->length == id_len
        !          1406:              && strncmp (arg->name, id_beg, id_len) == 0) {
        !          1407:            if (expected_delimiter && CPP_OPTIONS (pfile)->warn_stringify) {
        !          1408:              if (CPP_TRADITIONAL (pfile)) {
        !          1409:                cpp_warning (pfile, "macro argument `%.*s' is stringified.",
        !          1410:                             id_len, arg->name);
        !          1411:              } else {
        !          1412:                cpp_warning (pfile,
        !          1413:                    "macro arg `%.*s' would be stringified with -traditional.",
        !          1414:                             id_len, arg->name);
        !          1415:              }
        !          1416:            }
        !          1417:            /* If ANSI, don't actually substitute inside a string.  */
        !          1418:            if (!CPP_TRADITIONAL (pfile) && expected_delimiter)
        !          1419:              break;
        !          1420:            /* make a pat node for this arg and append it to the end of
        !          1421:               the pat list */
        !          1422:            tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
        !          1423:            tpat->next = NULL;
        !          1424:            tpat->raw_before = concat == id_beg;
        !          1425:            tpat->raw_after = 0;
        !          1426:            tpat->rest_args = arg->rest_args;
        !          1427:            tpat->stringify = (CPP_TRADITIONAL (pfile)
        !          1428:                               ? expected_delimiter != '\0'
        !          1429:                               : stringify == id_beg);
        !          1430: 
        !          1431:            if (endpat == NULL)
        !          1432:              defn->pattern = tpat;
        !          1433:            else
        !          1434:              endpat->next = tpat;
        !          1435:            endpat = tpat;
        !          1436: 
        !          1437:            tpat->argno = arg->argno;
        !          1438:            tpat->nchars = exp_p - lastp;
        !          1439:            {
        !          1440:              register U_CHAR *p1 = p;
        !          1441:              SKIP_WHITE_SPACE (p1);
        !          1442:              if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
        !          1443:                tpat->raw_after = 1;
        !          1444:            }
        !          1445:            lastp = exp_p;      /* place to start copying from next time */
        !          1446:            skipped_arg = 1;
        !          1447:            break;
        !          1448:          }
        !          1449:        }
        !          1450:       }
        !          1451: 
        !          1452:       /* If this was not a macro arg, copy it into the expansion.  */
        !          1453:       if (! skipped_arg) {
        !          1454:        register U_CHAR *lim1 = p;
        !          1455:        p = id_beg;
        !          1456:        while (p != lim1)
        !          1457:          *exp_p++ = *p++;
        !          1458:        if (stringify == id_beg)
        !          1459:          cpp_error (pfile,
        !          1460:                   "`#' operator should be followed by a macro argument name");
        !          1461:       }
        !          1462:     }
        !          1463:   }
        !          1464: 
        !          1465:   if (!CPP_TRADITIONAL (pfile) && expected_delimiter == 0)
        !          1466:     {
        !          1467:       /* If ANSI, put in a "@ " marker to prevent token pasting.
        !          1468:          But not if "inside a string" (which in ANSI mode
        !          1469:          happens only for -D option).  */
        !          1470:       *exp_p++ = '@';
        !          1471:       *exp_p++ = ' ';
        !          1472:     }
        !          1473: 
        !          1474:   *exp_p = '\0';
        !          1475: 
        !          1476:   defn->length = exp_p - defn->expansion;
        !          1477: 
        !          1478:   /* Crash now if we overrun the allocated size.  */
        !          1479:   if (defn->length + 1 > maxsize)
        !          1480:     abort ();
        !          1481: 
        !          1482: #if 0
        !          1483: /* This isn't worth the time it takes.  */
        !          1484:   /* give back excess storage */
        !          1485:   defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
        !          1486: #endif
        !          1487: 
        !          1488:   return defn;
        !          1489: }
        !          1490: 
        !          1491: /*
        !          1492:  * special extension string that can be added to the last macro argument to 
        !          1493:  * allow it to absorb the "rest" of the arguments when expanded.  Ex:
        !          1494:  *             #define wow(a, b...)            process (b, a, b)
        !          1495:  *             { wow (1, 2, 3); }      ->      { process (2, 3, 1, 2, 3); }
        !          1496:  *             { wow (one, two); }     ->      { process (two, one, two); }
        !          1497:  * if this "rest_arg" is used with the concat token '##' and if it is not
        !          1498:  * supplied then the token attached to with ## will not be outputted.  Ex:
        !          1499:  *             #define wow (a, b...)           process (b ## , a, ## b)
        !          1500:  *             { wow (1, 2); }         ->      { process (2, 1, 2); }
        !          1501:  *             { wow (one); }          ->      { process (one); {
        !          1502:  */
        !          1503: static char rest_extension[] = "...";
        !          1504: #define REST_EXTENSION_LENGTH  (sizeof (rest_extension) - 1)
        !          1505: 
        !          1506: /* Create a DEFINITION node from a #define directive.  Arguments are 
        !          1507:    as for do_define. */
        !          1508: static MACRODEF
        !          1509: create_definition (buf, limit, pfile, predefinition)
        !          1510:      U_CHAR *buf, *limit;
        !          1511:      cpp_reader *pfile;
        !          1512:      int predefinition;
        !          1513: {
        !          1514:   U_CHAR *bp;                  /* temp ptr into input buffer */
        !          1515:   U_CHAR *symname;             /* remember where symbol name starts */
        !          1516:   int sym_length;              /* and how long it is */
        !          1517:   int rest_args = 0;
        !          1518:   long line, col;
        !          1519:   char *file = CPP_BUFFER (pfile) ? CPP_BUFFER (pfile)->nominal_fname : "";
        !          1520:   DEFINITION *defn;
        !          1521:   int arglengths = 0;          /* Accumulate lengths of arg names
        !          1522:                                   plus number of args.  */
        !          1523:   MACRODEF mdef;
        !          1524:   cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
        !          1525: 
        !          1526:   bp = buf;
        !          1527: 
        !          1528:   while (is_hor_space[*bp])
        !          1529:     bp++;
        !          1530: 
        !          1531:   symname = bp;                        /* remember where it starts */
        !          1532: 
        !          1533:   sym_length = check_macro_name (pfile, bp, "macro");
        !          1534:   bp += sym_length;
        !          1535: 
        !          1536:   /* Lossage will occur if identifiers or control keywords are broken
        !          1537:      across lines using backslash.  This is not the right place to take
        !          1538:      care of that. */
        !          1539: 
        !          1540:   if (*bp == '(') {
        !          1541:     struct arglist *arg_ptrs = NULL;
        !          1542:     int argno = 0;
        !          1543: 
        !          1544:     bp++;                      /* skip '(' */
        !          1545:     SKIP_WHITE_SPACE (bp);
        !          1546: 
        !          1547:     /* Loop over macro argument names.  */
        !          1548:     while (*bp != ')') {
        !          1549:       struct arglist *temp;
        !          1550: 
        !          1551:       temp = (struct arglist *) alloca (sizeof (struct arglist));
        !          1552:       temp->name = bp;
        !          1553:       temp->next = arg_ptrs;
        !          1554:       temp->argno = argno++;
        !          1555:       temp->rest_args = 0;
        !          1556:       arg_ptrs = temp;
        !          1557: 
        !          1558:       if (rest_args)
        !          1559:        cpp_pedwarn (pfile, "another parameter follows `%s'", rest_extension);
        !          1560: 
        !          1561:       if (!is_idstart[*bp])
        !          1562:        cpp_pedwarn (pfile, "invalid character in macro parameter name");
        !          1563:       
        !          1564:       /* Find the end of the arg name.  */
        !          1565:       while (is_idchar[*bp]) {
        !          1566:        bp++;
        !          1567:        /* do we have a "special" rest-args extension here? */
        !          1568:        if (limit - bp > REST_EXTENSION_LENGTH &&
        !          1569:            strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
        !          1570:          rest_args = 1;
        !          1571:          temp->rest_args = 1;
        !          1572:          break;
        !          1573:        }
        !          1574:       }
        !          1575:       temp->length = bp - temp->name;
        !          1576:       if (rest_args == 1)
        !          1577:        bp += REST_EXTENSION_LENGTH;
        !          1578:       arglengths += temp->length + 2;
        !          1579:       SKIP_WHITE_SPACE (bp);
        !          1580:       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
        !          1581:        cpp_error (pfile, "badly punctuated parameter list in `#define'");
        !          1582:        goto nope;
        !          1583:       }
        !          1584:       if (*bp == ',') {
        !          1585:        bp++;
        !          1586:        SKIP_WHITE_SPACE (bp);
        !          1587:       }
        !          1588:       if (bp >= limit) {
        !          1589:        cpp_error (pfile, "unterminated parameter list in `#define'");
        !          1590:        goto nope;
        !          1591:       }
        !          1592:       {
        !          1593:        struct arglist *otemp;
        !          1594: 
        !          1595:        for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
        !          1596:          if (temp->length == otemp->length &&
        !          1597:            strncmp (temp->name, otemp->name, temp->length) == 0) {
        !          1598:              U_CHAR *name;
        !          1599: 
        !          1600:              name = (U_CHAR *) alloca (temp->length + 1);
        !          1601:              (void) strncpy (name, temp->name, temp->length);
        !          1602:              name[temp->length] = '\0';
        !          1603:              cpp_error (pfile,
        !          1604:                         "duplicate argument name `%s' in `#define'", name);
        !          1605:              goto nope;
        !          1606:          }
        !          1607:       }
        !          1608:     }
        !          1609: 
        !          1610:     ++bp;                      /* skip paren */
        !          1611:     SKIP_WHITE_SPACE (bp);
        !          1612:     /* now everything from bp before limit is the definition. */
        !          1613:     defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
        !          1614:     defn->rest_args = rest_args;
        !          1615: 
        !          1616:     /* Now set defn->args.argnames to the result of concatenating
        !          1617:        the argument names in reverse order
        !          1618:        with comma-space between them.  */
        !          1619:     defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
        !          1620:     {
        !          1621:       struct arglist *temp;
        !          1622:       int i = 0;
        !          1623:       for (temp = arg_ptrs; temp; temp = temp->next) {
        !          1624:        bcopy (temp->name, &defn->args.argnames[i], temp->length);
        !          1625:        i += temp->length;
        !          1626:        if (temp->next != 0) {
        !          1627:          defn->args.argnames[i++] = ',';
        !          1628:          defn->args.argnames[i++] = ' ';
        !          1629:        }
        !          1630:       }
        !          1631:       defn->args.argnames[i] = 0;
        !          1632:     }
        !          1633:   } else {
        !          1634:     /* Simple expansion or empty definition.  */
        !          1635: 
        !          1636:     if (bp < limit)
        !          1637:       {
        !          1638:        if (is_hor_space[*bp]) {
        !          1639:          bp++;
        !          1640:          SKIP_WHITE_SPACE (bp);
        !          1641:        } else {
        !          1642:          switch (*bp) {
        !          1643:            case '!':  case '"':  case '#':  case '%':  case '&':  case '\'':
        !          1644:            case ')':  case '*':  case '+':  case ',':  case '-':  case '.':
        !          1645:            case '/':  case ':':  case ';':  case '<':  case '=':  case '>':
        !          1646:            case '?':  case '[':  case '\\': case ']':  case '^':  case '{':
        !          1647:            case '|':  case '}':  case '~':
        !          1648:              cpp_warning (pfile, "missing white space after `#define %.*s'",
        !          1649:                           sym_length, symname);
        !          1650:              break;
        !          1651: 
        !          1652:            default:
        !          1653:              cpp_pedwarn (pfile, "missing white space after `#define %.*s'",
        !          1654:                           sym_length, symname);
        !          1655:              break;
        !          1656:          }
        !          1657:        }
        !          1658:       }
        !          1659:     /* now everything from bp before limit is the definition. */
        !          1660:     defn = collect_expansion (pfile, bp, limit, -1, NULL_PTR);
        !          1661:     defn->args.argnames = (U_CHAR *) "";
        !          1662:   }
        !          1663: 
        !          1664:   defn->line = line;
        !          1665:   defn->file = file;
        !          1666: 
        !          1667:   /* OP is null if this is a predefinition */
        !          1668:   defn->predefined = predefinition;
        !          1669:   mdef.defn = defn;
        !          1670:   mdef.symnam = symname;
        !          1671:   mdef.symlen = sym_length;
        !          1672: 
        !          1673:   return mdef;
        !          1674: 
        !          1675:  nope:
        !          1676:   mdef.defn = 0;
        !          1677:   return mdef;
        !          1678: }
        !          1679: 
        !          1680: /* Check a purported macro name SYMNAME, and yield its length.
        !          1681:    USAGE is the kind of name this is intended for.  */
        !          1682: 
        !          1683: static int
        !          1684: check_macro_name (pfile, symname, usage)
        !          1685:      cpp_reader *pfile;
        !          1686:      U_CHAR *symname;
        !          1687:      char *usage;
        !          1688: {
        !          1689:   U_CHAR *p;
        !          1690:   int sym_length;
        !          1691: 
        !          1692:   for (p = symname; is_idchar[*p]; p++)
        !          1693:     ;
        !          1694:   sym_length = p - symname;
        !          1695:   if (sym_length == 0)
        !          1696:     cpp_error (pfile, "invalid %s name", usage);
        !          1697:   else if (!is_idstart[*symname]) {
        !          1698:     U_CHAR *msg;                       /* what pain... */
        !          1699:     msg = (U_CHAR *) alloca (sym_length + 1);
        !          1700:     bcopy (symname, msg, sym_length);
        !          1701:     msg[sym_length] = 0;
        !          1702:     cpp_error (pfile, "invalid %s name `%s'", usage, msg);
        !          1703:   } else {
        !          1704:     if (! strncmp (symname, "defined", 7) && sym_length == 7)
        !          1705:       cpp_error (pfile, "invalid %s name `defined'", usage);
        !          1706:   }
        !          1707:   return sym_length;
        !          1708: }
        !          1709: 
        !          1710: /*
        !          1711:  * return zero if two DEFINITIONs are isomorphic
        !          1712:  */
        !          1713: static int
        !          1714: compare_defs (d1, d2)
        !          1715:      DEFINITION *d1, *d2;
        !          1716: {
        !          1717:   register struct reflist *a1, *a2;
        !          1718:   register U_CHAR *p1 = d1->expansion;
        !          1719:   register U_CHAR *p2 = d2->expansion;
        !          1720:   int first = 1;
        !          1721: 
        !          1722:   if (d1->nargs != d2->nargs)
        !          1723:     return 1;
        !          1724:   if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames))
        !          1725:     return 1;
        !          1726:   for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
        !          1727:        a1 = a1->next, a2 = a2->next) {
        !          1728:     if (!((a1->nchars == a2->nchars && ! strncmp (p1, p2, a1->nchars))
        !          1729:          || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
        !          1730:        || a1->argno != a2->argno
        !          1731:        || a1->stringify != a2->stringify
        !          1732:        || a1->raw_before != a2->raw_before
        !          1733:        || a1->raw_after != a2->raw_after)
        !          1734:       return 1;
        !          1735:     first = 0;
        !          1736:     p1 += a1->nchars;
        !          1737:     p2 += a2->nchars;
        !          1738:   }
        !          1739:   if (a1 != a2)
        !          1740:     return 1;
        !          1741:   if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
        !          1742:                     p2, d2->length - (p2 - d2->expansion), 1))
        !          1743:     return 1;
        !          1744:   return 0;
        !          1745: }
        !          1746: 
        !          1747: /* Return 1 if two parts of two macro definitions are effectively different.
        !          1748:    One of the parts starts at BEG1 and has LEN1 chars;
        !          1749:    the other has LEN2 chars at BEG2.
        !          1750:    Any sequence of whitespace matches any other sequence of whitespace.
        !          1751:    FIRST means these parts are the first of a macro definition;
        !          1752:     so ignore leading whitespace entirely.
        !          1753:    LAST means these parts are the last of a macro definition;
        !          1754:     so ignore trailing whitespace entirely.  */
        !          1755: 
        !          1756: static int
        !          1757: comp_def_part (first, beg1, len1, beg2, len2, last)
        !          1758:      int first;
        !          1759:      U_CHAR *beg1, *beg2;
        !          1760:      int len1, len2;
        !          1761:      int last;
        !          1762: {
        !          1763:   register U_CHAR *end1 = beg1 + len1;
        !          1764:   register U_CHAR *end2 = beg2 + len2;
        !          1765:   if (first) {
        !          1766:     while (beg1 != end1 && is_space[*beg1]) beg1++;
        !          1767:     while (beg2 != end2 && is_space[*beg2]) beg2++;
        !          1768:   }
        !          1769:   if (last) {
        !          1770:     while (beg1 != end1 && is_space[end1[-1]]) end1--;
        !          1771:     while (beg2 != end2 && is_space[end2[-1]]) end2--;
        !          1772:   }
        !          1773:   while (beg1 != end1 && beg2 != end2) {
        !          1774:     if (is_space[*beg1] && is_space[*beg2]) {
        !          1775:       while (beg1 != end1 && is_space[*beg1]) beg1++;
        !          1776:       while (beg2 != end2 && is_space[*beg2]) beg2++;
        !          1777:     } else if (*beg1 == *beg2) {
        !          1778:       beg1++; beg2++;
        !          1779:     } else break;
        !          1780:   }
        !          1781:   return (beg1 != end1) || (beg2 != end2);
        !          1782: }
        !          1783: 
        !          1784: /* Process a #define command.
        !          1785: BUF points to the contents of the #define command, as a contiguous string.
        !          1786: LIMIT points to the first character past the end of the definition.
        !          1787: KEYWORD is the keyword-table entry for #define,
        !          1788: or NULL for a "predefined" macro.  */
        !          1789: 
        !          1790: static int
        !          1791: do_define (pfile, keyword, buf, limit)
        !          1792:      cpp_reader *pfile;
        !          1793:      struct directive *keyword;
        !          1794:      U_CHAR *buf, *limit;
        !          1795: {
        !          1796:   int hashcode;
        !          1797:   MACRODEF mdef;
        !          1798:   HASHNODE *hp;
        !          1799: 
        !          1800: #if 0
        !          1801:   /* If this is a precompiler run (with -pcp) pass thru #define commands.  */
        !          1802:   if (pcp_outfile && keyword)
        !          1803:     pass_thru_directive (buf, limit, pfile, keyword);
        !          1804: #endif
        !          1805: 
        !          1806:   mdef = create_definition (buf, limit, pfile, keyword == NULL);
        !          1807:   if (mdef.defn == 0)
        !          1808:     goto nope;
        !          1809: 
        !          1810:   hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
        !          1811: 
        !          1812:   if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen, hashcode)) != NULL)
        !          1813:     {
        !          1814:       int ok = 0;
        !          1815:       /* Redefining a precompiled key is ok.  */
        !          1816:       if (hp->type == T_PCSTRING)
        !          1817:        ok = 1;
        !          1818:       /* Redefining a macro is ok if the definitions are the same.  */
        !          1819:       else if (hp->type == T_MACRO)
        !          1820:        ok = ! compare_defs (mdef.defn, hp->value.defn);
        !          1821:       /* Redefining a constant is ok with -D.  */
        !          1822:       else if (hp->type == T_CONST)
        !          1823:         ok = ! CPP_OPTIONS (pfile)->done_initializing;
        !          1824:       /* Print the warning if it's not ok.  */
        !          1825:       if (!ok)
        !          1826:        {
        !          1827:          U_CHAR *msg;          /* what pain... */
        !          1828: 
        !          1829:          /* If we are passing through #define and #undef directives, do
        !          1830:             that for this re-definition now.  */
        !          1831:          if (CPP_OPTIONS (pfile)->debug_output && keyword)
        !          1832:            pass_thru_directive (buf, limit, pfile, keyword);
        !          1833: 
        !          1834:          msg = (U_CHAR *) alloca (mdef.symlen + 22);
        !          1835:          *msg = '`';
        !          1836:          bcopy (mdef.symnam, msg + 1, mdef.symlen);
        !          1837:          strcpy ((char *) (msg + mdef.symlen + 1), "' redefined");
        !          1838:          cpp_pedwarn (pfile, msg);
        !          1839:          if (hp->type == T_MACRO)
        !          1840:            cpp_pedwarn_with_file_and_line (pfile, hp->value.defn->file, hp->value.defn->line,
        !          1841:                                      "this is the location of the previous definition");
        !          1842:        }
        !          1843:       /* Replace the old definition.  */
        !          1844:       hp->type = T_MACRO;
        !          1845:       hp->value.defn = mdef.defn;
        !          1846:     }
        !          1847:   else
        !          1848:     {
        !          1849:       /* If we are passing through #define and #undef directives, do
        !          1850:         that for this new definition now.  */
        !          1851:       if (CPP_OPTIONS (pfile)->debug_output && keyword)
        !          1852:        pass_thru_directive (buf, limit, pfile, keyword);
        !          1853:       install (mdef.symnam, mdef.symlen, T_MACRO, 0,
        !          1854:               (char *) mdef.defn, hashcode);
        !          1855:     }
        !          1856: 
        !          1857:   return 0;
        !          1858: 
        !          1859: nope:
        !          1860: 
        !          1861:   return 1;
        !          1862: }
        !          1863: 
        !          1864: /* This structure represents one parsed argument in a macro call.
        !          1865:    `raw' points to the argument text as written (`raw_length' is its length).
        !          1866:    `expanded' points to the argument's macro-expansion
        !          1867:    (its length is `expand_length').
        !          1868:    `stringified_length' is the length the argument would have
        !          1869:    if stringified.
        !          1870:    `use_count' is the number of times this macro arg is substituted
        !          1871:    into the macro.  If the actual use count exceeds 10, 
        !          1872:    the value stored is 10. */
        !          1873: 
        !          1874: /* raw and expanded are relative to ARG_BASE */
        !          1875: #define ARG_BASE ((pfile)->token_buffer)
        !          1876: 
        !          1877: struct argdata {
        !          1878:   /* Strings relative to pfile->token_buffer */
        !          1879:   long raw, expanded, stringified;
        !          1880:   int raw_length, expand_length;
        !          1881:   int stringified_length;
        !          1882:   char newlines;
        !          1883:   char use_count;
        !          1884: };
        !          1885: 
        !          1886: 
        !          1887: cpp_buffer*
        !          1888: cpp_push_buffer (pfile, buffer, length)
        !          1889:      cpp_reader *pfile;
        !          1890:      U_CHAR *buffer;
        !          1891:      long length;
        !          1892: {
        !          1893: #ifdef STATIC_BUFFERS
        !          1894:   register cpp_buffer *buf = CPP_BUFFER (pfile);
        !          1895:   if (buf == pfile->buffer_stack)
        !          1896:     fatal ("%s: macro or `#include' recursion too deep", buf->fname);
        !          1897:   buf--;
        !          1898:   bzero ((char *) buf, sizeof (cpp_buffer));
        !          1899:   CPP_BUFFER (pfile) = buf;
        !          1900: #else
        !          1901:   register cpp_buffer *buf = (cpp_buffer*) xmalloc (sizeof(cpp_buffer));
        !          1902:   bzero ((char *) buf, sizeof (cpp_buffer));
        !          1903:   CPP_PREV_BUFFER (buf) = CPP_BUFFER (pfile);
        !          1904:   CPP_BUFFER (pfile) = buf;
        !          1905: #endif
        !          1906:   buf->if_stack = pfile->if_stack;
        !          1907:   buf->cleanup = null_cleanup;
        !          1908:   buf->underflow = null_underflow;
        !          1909:   buf->buf = buf->cur = buffer;
        !          1910:   buf->alimit = buf->rlimit = buffer + length;
        !          1911:   
        !          1912:   return buf;
        !          1913: }
        !          1914: 
        !          1915: cpp_buffer*
        !          1916: cpp_pop_buffer (pfile)
        !          1917:      cpp_reader *pfile;
        !          1918: {
        !          1919:   cpp_buffer *buf = CPP_BUFFER (pfile);
        !          1920: #ifdef STATIC_BUFFERS
        !          1921:   (*buf->cleanup) (buf, pfile);
        !          1922:   return ++CPP_BUFFER (pfile);
        !          1923: #else
        !          1924:   cpp_buffer *next_buf = CPP_PREV_BUFFER (buf);
        !          1925:   (*buf->cleanup) (buf, pfile);
        !          1926:   CPP_BUFFER (pfile) = next_buf;
        !          1927:   free (buf);
        !          1928:   return next_buf;
        !          1929: #endif
        !          1930: }
        !          1931: 
        !          1932: /* Scan until CPP_BUFFER (PFILE) is exhausted into PFILE->token_buffer.
        !          1933:    Pop the buffer when done. */
        !          1934: 
        !          1935: void
        !          1936: cpp_scan_buffer (pfile)
        !          1937:      cpp_reader *pfile;
        !          1938: {
        !          1939:   cpp_buffer *buffer = CPP_BUFFER (pfile);
        !          1940:   for (;;)
        !          1941:     {
        !          1942:       enum cpp_token token = cpp_get_token (pfile);
        !          1943:       if (token == CPP_EOF) /* Should not happen ... */
        !          1944:        break;
        !          1945:       if (token == CPP_POP && CPP_BUFFER (pfile) == buffer)
        !          1946:        {
        !          1947:          cpp_pop_buffer (pfile);
        !          1948:          break;
        !          1949:        }
        !          1950:     }
        !          1951: }
        !          1952: 
        !          1953: /*
        !          1954:  * Rescan a string (which may have escape marks) into pfile's buffer.
        !          1955:  * Place the result in pfile->token_buffer.
        !          1956:  *
        !          1957:  * The input is copied before it is scanned, so it is safe to pass
        !          1958:  * it something from the token_buffer that will get overwritten
        !          1959:  * (because it follows CPP_WRITTEN).  This is used by do_include.
        !          1960:  */
        !          1961: 
        !          1962: static void
        !          1963: cpp_expand_to_buffer (pfile, buf, length)
        !          1964:      cpp_reader *pfile;
        !          1965:      U_CHAR *buf;
        !          1966:      int length;
        !          1967: {
        !          1968:   register cpp_buffer *ip;
        !          1969:   cpp_buffer obuf;
        !          1970:   U_CHAR *limit = buf + length;
        !          1971:   U_CHAR *buf1;
        !          1972: #if 0
        !          1973:   int odepth = indepth;
        !          1974: #endif
        !          1975: 
        !          1976:   if (length < 0)
        !          1977:     abort ();
        !          1978: 
        !          1979:   /* Set up the input on the input stack.  */
        !          1980: 
        !          1981:   buf1 = (U_CHAR *) alloca (length + 1);
        !          1982:   {
        !          1983:     register U_CHAR *p1 = buf;
        !          1984:     register U_CHAR *p2 = buf1;
        !          1985: 
        !          1986:     while (p1 != limit)
        !          1987:       *p2++ = *p1++;
        !          1988:   }
        !          1989:   buf1[length] = 0;
        !          1990: 
        !          1991:   ip = cpp_push_buffer (pfile, buf1, length);
        !          1992:   ip->has_escapes = 1;
        !          1993: #if 0
        !          1994:   ip->lineno = obuf.lineno = 1;
        !          1995: #endif
        !          1996: 
        !          1997:   /* Scan the input, create the output.  */
        !          1998:   cpp_scan_buffer (pfile);
        !          1999: 
        !          2000: #if 0
        !          2001:   if (indepth != odepth)
        !          2002:     abort ();
        !          2003: #endif
        !          2004: 
        !          2005:   CPP_NUL_TERMINATE (pfile);
        !          2006: }
        !          2007: 
        !          2008: 
        !          2009: static void
        !          2010: adjust_position (buf, limit, linep, colp)
        !          2011:      U_CHAR *buf;
        !          2012:      U_CHAR *limit;
        !          2013:      long *linep;
        !          2014:      long *colp;
        !          2015: {
        !          2016:   while (buf < limit)
        !          2017:     {
        !          2018:       U_CHAR ch = *buf++;
        !          2019:       if (ch == '\n')
        !          2020:        (*linep)++, (*colp) = 1;
        !          2021:       else
        !          2022:        (*colp)++;
        !          2023:     }
        !          2024: }
        !          2025: 
        !          2026: /* Move line_base forward, updating lineno and colno. */
        !          2027: 
        !          2028: static void
        !          2029: update_position (pbuf)
        !          2030:      register cpp_buffer *pbuf;
        !          2031: {
        !          2032:   unsigned char *old_pos = pbuf->buf + pbuf->line_base;
        !          2033:   unsigned char *new_pos = pbuf->cur;
        !          2034:   register struct parse_marker *mark;
        !          2035:   for (mark = pbuf->marks;  mark != NULL; mark = mark->next)
        !          2036:     {
        !          2037:       if (pbuf->buf + mark->position < new_pos)
        !          2038:        new_pos = pbuf->buf + mark->position;
        !          2039:     }
        !          2040:   pbuf->line_base += new_pos - old_pos;
        !          2041:   adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);
        !          2042: }
        !          2043: 
        !          2044: void
        !          2045: cpp_buf_line_and_col (pbuf, linep, colp)
        !          2046:      register cpp_buffer *pbuf;
        !          2047:      long *linep, *colp;
        !          2048: {
        !          2049:   long dummy;
        !          2050:   if (colp == NULL)
        !          2051:     colp = &dummy;
        !          2052:   if (pbuf)
        !          2053:     {
        !          2054:       *linep = pbuf->lineno;
        !          2055:       *colp = pbuf->colno;
        !          2056:       adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp);
        !          2057:     }
        !          2058:   else
        !          2059:     {
        !          2060:       *linep = 0;
        !          2061:       *colp = 0;
        !          2062:     }
        !          2063: }
        !          2064: 
        !          2065: /* Return the cpp_buffer that corresponds to a file (not a macro). */
        !          2066: 
        !          2067: cpp_buffer*
        !          2068: cpp_file_buffer (pfile)
        !          2069:      cpp_reader *pfile;
        !          2070: {
        !          2071:   cpp_buffer *ip = CPP_BUFFER (pfile);
        !          2072: 
        !          2073:   for ( ; ip != CPP_NULL_BUFFER (pfile); ip = CPP_PREV_BUFFER (ip))
        !          2074:     if (ip->fname != NULL)
        !          2075:       return ip;
        !          2076:   return NULL;
        !          2077: }
        !          2078: 
        !          2079: static long
        !          2080: count_newlines (buf, limit)
        !          2081:      register U_CHAR *buf;
        !          2082:      register U_CHAR *limit;
        !          2083: {
        !          2084:   register long count = 0;
        !          2085:   while (buf < limit)
        !          2086:     {
        !          2087:       U_CHAR ch = *buf++;
        !          2088:       if (ch == '\n')
        !          2089:        count++;
        !          2090:     }
        !          2091:   return count;
        !          2092: }
        !          2093: 
        !          2094: /*
        !          2095:  * write out a #line command, for instance, after an #include file.
        !          2096:  * If CONDITIONAL is nonzero, we can omit the #line if it would
        !          2097:  * appear to be a no-op, and we can output a few newlines instead
        !          2098:  * if we want to increase the line number by a small amount.
        !          2099:  * FILE_CHANGE says whether we are entering a file, leaving, or neither.
        !          2100:  */
        !          2101: 
        !          2102: static void
        !          2103: output_line_command (pfile, conditional, file_change)
        !          2104:      cpp_reader *pfile;
        !          2105:      int conditional;
        !          2106:      enum file_change_code file_change;
        !          2107: {
        !          2108:   int len;
        !          2109:   char *line_cmd_buf, *line_end;
        !          2110:   long line, col;
        !          2111:   cpp_buffer *ip = CPP_BUFFER (pfile);
        !          2112: 
        !          2113:   if (ip->fname == NULL || CPP_OPTIONS (pfile)->no_output) {
        !          2114:     return;
        !          2115:   }
        !          2116: 
        !          2117:   update_position (ip);
        !          2118:   line = CPP_BUFFER (pfile)->lineno;
        !          2119:   col = CPP_BUFFER (pfile)->colno;
        !          2120:   adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col);
        !          2121: 
        !          2122:   if (CPP_OPTIONS (pfile)->no_line_commands)
        !          2123:     return;
        !          2124: 
        !          2125:   if (conditional) {
        !          2126:     if (line == pfile->lineno)
        !          2127:       return;
        !          2128: 
        !          2129:     /* If the inherited line number is a little too small,
        !          2130:        output some newlines instead of a #line command.  */
        !          2131:     if (line > pfile->lineno && line < pfile->lineno + 8) {
        !          2132:       CPP_RESERVE (pfile, 20);
        !          2133:       while (line > pfile->lineno) {
        !          2134:        CPP_PUTC_Q (pfile, '\n');
        !          2135:        pfile->lineno++;
        !          2136:       }
        !          2137:       return;
        !          2138:     }
        !          2139:   }
        !          2140: 
        !          2141: #if 0
        !          2142:   /* Don't output a line number of 0 if we can help it.  */
        !          2143:   if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length
        !          2144:       && *ip->bufp == '\n') {
        !          2145:     ip->lineno++;
        !          2146:     ip->bufp++;
        !          2147:   }
        !          2148: #endif
        !          2149: 
        !          2150:   CPP_RESERVE (pfile, 4 * strlen (ip->nominal_fname) + 50);
        !          2151:   {
        !          2152: #ifdef OUTPUT_LINE_COMMANDS
        !          2153:     static char sharp_line[] = "#line ";
        !          2154: #else
        !          2155:     static char sharp_line[] = "# ";
        !          2156: #endif
        !          2157:     CPP_PUTS_Q (pfile, sharp_line, sizeof(sharp_line)-1);
        !          2158:   }
        !          2159: 
        !          2160:   sprintf (CPP_PWRITTEN (pfile), "%d ", line);
        !          2161:   CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
        !          2162: 
        !          2163:   quote_string (pfile, ip->nominal_fname); 
        !          2164:   if (file_change != same_file) {
        !          2165:     CPP_PUTC_Q (pfile, ' ');
        !          2166:     CPP_PUTC_Q (pfile, file_change == enter_file ? '1' : '2');
        !          2167:   }
        !          2168:   /* Tell cc1 if following text comes from a system header file.  */
        !          2169:   if (ip->system_header_p) {
        !          2170:     CPP_PUTC_Q (pfile, ' ');
        !          2171:     CPP_PUTC_Q (pfile, '3');
        !          2172:   }
        !          2173: #ifndef NO_IMPLICIT_EXTERN_C
        !          2174:   /* Tell cc1plus if following text should be treated as C.  */
        !          2175:   if (ip->system_header_p == 2 && CPP_OPTIONS (pfile)->cplusplus) {
        !          2176:     CPP_PUTC_Q (pfile, ' ');
        !          2177:     CPP_PUTC_Q (pfile, '4');
        !          2178:   }
        !          2179: #endif
        !          2180:   CPP_PUTC_Q (pfile, '\n');
        !          2181:   pfile->lineno = line;
        !          2182: }
        !          2183: 
        !          2184: /*
        !          2185:  * Parse a macro argument and append the info on PFILE's token_buffer.
        !          2186:  * REST_ARGS means to absorb the rest of the args.
        !          2187:  * Return nonzero to indicate a syntax error.
        !          2188:  */
        !          2189: 
        !          2190: static enum cpp_token
        !          2191: macarg (pfile, rest_args)
        !          2192:      cpp_reader *pfile;
        !          2193:      int rest_args;
        !          2194: {
        !          2195:   int paren = 0;
        !          2196:   enum cpp_token token;
        !          2197:   long arg_start = CPP_WRITTEN (pfile);
        !          2198:   char save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments;
        !          2199:   CPP_OPTIONS (pfile)->put_out_comments = 0;
        !          2200: 
        !          2201:   /* Try to parse as much of the argument as exists at this
        !          2202:      input stack level.  */
        !          2203:   pfile->no_macro_expand++;
        !          2204:   for (;;)
        !          2205:     {
        !          2206:       token = cpp_get_token (pfile);
        !          2207:       switch (token)
        !          2208:        {
        !          2209:        case CPP_EOF:
        !          2210:          goto done;
        !          2211:        case CPP_POP:
        !          2212:          /* If we've hit end of file, it's an error (reported by caller).
        !          2213:             Ditto if it's the end of cpp_expand_to_buffer text.
        !          2214:             If we've hit end of macro, just continue.  */
        !          2215:          if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
        !          2216:            goto done;
        !          2217:          break;
        !          2218:        case CPP_LPAREN:
        !          2219:          paren++;
        !          2220:          break;
        !          2221:        case CPP_RPAREN:
        !          2222:          if (--paren < 0)
        !          2223:            goto found;
        !          2224:          break;
        !          2225:        case CPP_COMMA:
        !          2226:          /* if we've returned to lowest level and
        !          2227:             we aren't absorbing all args */
        !          2228:          if (paren == 0 && rest_args == 0)
        !          2229:            goto found;
        !          2230:          break;
        !          2231:        found:
        !          2232:          /* Remove ',' or ')' from argument buffer. */
        !          2233:          CPP_ADJUST_WRITTEN (pfile, -1);
        !          2234:          goto done;
        !          2235:       default: ;
        !          2236:        }
        !          2237:     }
        !          2238: 
        !          2239:  done:
        !          2240:   CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments;
        !          2241:   pfile->no_macro_expand--;
        !          2242: 
        !          2243:   return token;
        !          2244: }
        !          2245: 
        !          2246: /* Turn newlines to spaces in the string of length LENGTH at START,
        !          2247:    except inside of string constants.
        !          2248:    The string is copied into itself with its beginning staying fixed.  */
        !          2249: 
        !          2250: static int
        !          2251: change_newlines (start, length)
        !          2252:      U_CHAR *start;
        !          2253:      int length;
        !          2254: {
        !          2255:   register U_CHAR *ibp;
        !          2256:   register U_CHAR *obp;
        !          2257:   register U_CHAR *limit;
        !          2258:   register int c;
        !          2259: 
        !          2260:   ibp = start;
        !          2261:   limit = start + length;
        !          2262:   obp = start;
        !          2263: 
        !          2264:   while (ibp < limit) {
        !          2265:     *obp++ = c = *ibp++;
        !          2266:     switch (c) {
        !          2267: 
        !          2268:     case '\'':
        !          2269:     case '\"':
        !          2270:       /* Notice and skip strings, so that we don't delete newlines in them.  */
        !          2271:       {
        !          2272:        int quotec = c;
        !          2273:        while (ibp < limit) {
        !          2274:          *obp++ = c = *ibp++;
        !          2275:          if (c == quotec)
        !          2276:            break;
        !          2277:          if (c == '\n' && quotec == '\'')
        !          2278:            break;
        !          2279:        }
        !          2280:       }
        !          2281:       break;
        !          2282:     }
        !          2283:   }
        !          2284: 
        !          2285:   return obp - start;
        !          2286: }
        !          2287: 
        !          2288: 
        !          2289: static struct tm *
        !          2290: timestamp (pfile)
        !          2291:      cpp_reader *pfile;
        !          2292: {
        !          2293:   if (!pfile->timebuf) {
        !          2294:     time_t t = time ((time_t *)0);
        !          2295:     pfile->timebuf = localtime (&t);
        !          2296:   }
        !          2297:   return pfile->timebuf;
        !          2298: }
        !          2299: 
        !          2300: static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
        !          2301:                             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
        !          2302:                            };
        !          2303: 
        !          2304: /*
        !          2305:  * expand things like __FILE__.  Place the expansion into the output
        !          2306:  * buffer *without* rescanning.
        !          2307:  */
        !          2308: 
        !          2309: static void
        !          2310: special_symbol (hp, pfile)
        !          2311:      HASHNODE *hp;
        !          2312:      cpp_reader *pfile;
        !          2313: {
        !          2314:   char *buf;
        !          2315:   int i, len;
        !          2316:   int true_indepth;
        !          2317:   cpp_buffer *ip = NULL;
        !          2318:   struct tm *timebuf;
        !          2319: 
        !          2320:   int paren = 0;               /* For special `defined' keyword */
        !          2321: 
        !          2322: #if 0
        !          2323:   if (pcp_outfile && pcp_inside_if
        !          2324:       && hp->type != T_SPEC_DEFINED && hp->type != T_CONST)
        !          2325:     cpp_error (pfile,
        !          2326:               "Predefined macro `%s' used inside `#if' during precompilation",
        !          2327:               hp->name);
        !          2328: #endif
        !          2329:     
        !          2330:   for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip))
        !          2331:     {
        !          2332:       if (ip == NULL)
        !          2333:        {
        !          2334:          cpp_error (pfile, "cccp error: not in any file?!");
        !          2335:          return;                       /* the show must go on */
        !          2336:        }
        !          2337:       if (ip->fname != NULL)
        !          2338:        break;
        !          2339:     }
        !          2340: 
        !          2341:   switch (hp->type)
        !          2342:     {
        !          2343:     case T_FILE:
        !          2344:     case T_BASE_FILE:
        !          2345:       {
        !          2346:        char *string;
        !          2347:        if (hp->type == T_BASE_FILE)
        !          2348:          {
        !          2349:            while (CPP_PREV_BUFFER (ip))
        !          2350:              ip = CPP_PREV_BUFFER (ip);
        !          2351:          }
        !          2352:        string = ip->nominal_fname;
        !          2353: 
        !          2354:        if (!string)
        !          2355:          string = "";
        !          2356:        CPP_RESERVE (pfile, 3 + 4 * strlen (string));
        !          2357:        quote_string (pfile, string);
        !          2358:        return;
        !          2359:       }
        !          2360: 
        !          2361:     case T_INCLUDE_LEVEL:
        !          2362:       true_indepth = 0;
        !          2363:       for (ip = CPP_BUFFER (pfile);  ip != NULL; ip = CPP_PREV_BUFFER (ip))
        !          2364:        if (ip->fname != NULL)
        !          2365:          true_indepth++;
        !          2366: 
        !          2367:       buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */
        !          2368:       sprintf (buf, "%d", true_indepth - 1);
        !          2369:       break;
        !          2370: 
        !          2371:   case T_VERSION:
        !          2372:       buf = (char *) alloca (3 + strlen (version_string));
        !          2373:       sprintf (buf, "\"%s\"", version_string);
        !          2374:       break;
        !          2375: 
        !          2376: #ifndef NO_BUILTIN_SIZE_TYPE
        !          2377:     case T_SIZE_TYPE:
        !          2378:       buf = SIZE_TYPE;
        !          2379:       break;
        !          2380: #endif
        !          2381: 
        !          2382: #ifndef NO_BUILTIN_PTRDIFF_TYPE
        !          2383:     case T_PTRDIFF_TYPE:
        !          2384:       buf = PTRDIFF_TYPE;
        !          2385:       break;
        !          2386: #endif
        !          2387: 
        !          2388:     case T_WCHAR_TYPE:
        !          2389:       buf = CPP_WCHAR_TYPE (pfile);
        !          2390:     break;
        !          2391: 
        !          2392:     case T_USER_LABEL_PREFIX_TYPE:
        !          2393:       buf = USER_LABEL_PREFIX;
        !          2394:       break;
        !          2395: 
        !          2396:     case T_REGISTER_PREFIX_TYPE:
        !          2397:       buf = REGISTER_PREFIX;
        !          2398:       break;
        !          2399: 
        !          2400:   case T_CONST:
        !          2401:       buf = (char *) alloca (4 * sizeof (int));
        !          2402:       sprintf (buf, "%d", hp->value.ival);
        !          2403: #if 0
        !          2404:       if (pcp_inside_if && pcp_outfile)
        !          2405:        /* Output a precondition for this macro use */
        !          2406:        fprintf (pcp_outfile, "#define %s %d\n", hp->name, hp->value.ival);
        !          2407: #endif
        !          2408:       break;
        !          2409: 
        !          2410:     case T_SPECLINE:
        !          2411:       {
        !          2412:        long line = ip->lineno;
        !          2413:        long col = ip->colno;
        !          2414:        adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col);
        !          2415: 
        !          2416:        buf = (char *) alloca (10);
        !          2417:        sprintf (buf, "%d", line);
        !          2418:       }
        !          2419:       break;
        !          2420: 
        !          2421:     case T_DATE:
        !          2422:     case T_TIME:
        !          2423:       buf = (char *) alloca (20);
        !          2424:       timebuf = timestamp (pfile);
        !          2425:       if (hp->type == T_DATE)
        !          2426:        sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
        !          2427:                 timebuf->tm_mday, timebuf->tm_year + 1900);
        !          2428:       else
        !          2429:        sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
        !          2430:                 timebuf->tm_sec);
        !          2431:       break;
        !          2432: 
        !          2433:     case T_SPEC_DEFINED:
        !          2434:       buf = " 0 ";             /* Assume symbol is not defined */
        !          2435:       ip = CPP_BUFFER (pfile);
        !          2436:       SKIP_WHITE_SPACE (ip->cur);
        !          2437:       if (*ip->cur == '(')
        !          2438:        {
        !          2439:          paren++;
        !          2440:          ip->cur++;                    /* Skip over the paren */
        !          2441:          SKIP_WHITE_SPACE (ip->cur);
        !          2442:        }
        !          2443: 
        !          2444:       if (!is_idstart[*ip->cur])
        !          2445:        goto oops;
        !          2446:       if (hp = cpp_lookup (pfile, ip->cur, -1, -1))
        !          2447:        {
        !          2448: #if 0
        !          2449:          if (pcp_outfile && pcp_inside_if
        !          2450:              && (hp->type == T_CONST
        !          2451:                  || (hp->type == T_MACRO && hp->value.defn->predefined)))
        !          2452:            /* Output a precondition for this macro use. */
        !          2453:            fprintf (pcp_outfile, "#define %s\n", hp->name);
        !          2454: #endif
        !          2455:          buf = " 1 ";
        !          2456:        }
        !          2457: #if 0
        !          2458:       else
        !          2459:        if (pcp_outfile && pcp_inside_if)
        !          2460:          {
        !          2461:            /* Output a precondition for this macro use */
        !          2462:            U_CHAR *cp = ip->bufp;
        !          2463:            fprintf (pcp_outfile, "#undef ");
        !          2464:            while (is_idchar[*cp]) /* Ick! */
        !          2465:              fputc (*cp++, pcp_outfile);
        !          2466:            putc ('\n', pcp_outfile);
        !          2467:          }
        !          2468: #endif
        !          2469:       while (is_idchar[*ip->cur])
        !          2470:        ++ip->cur;
        !          2471:       SKIP_WHITE_SPACE (ip->cur);
        !          2472:       if (paren)
        !          2473:        {
        !          2474:          if (*ip->cur != ')')
        !          2475:            goto oops;
        !          2476:          ++ip->cur;
        !          2477:        }
        !          2478:       break;
        !          2479: 
        !          2480:     oops:
        !          2481: 
        !          2482:       cpp_error (pfile, "`defined' without an identifier");
        !          2483:       break;
        !          2484: 
        !          2485:     default:
        !          2486:       cpp_error (pfile, "cccp error: invalid special hash type"); /* time for gdb */
        !          2487:       abort ();
        !          2488:     }
        !          2489:   len = strlen (buf);
        !          2490:   CPP_RESERVE (pfile, len + 1);
        !          2491:   CPP_PUTS_Q (pfile, buf, len);
        !          2492:   CPP_NUL_TERMINATE_Q (pfile);
        !          2493: 
        !          2494:   return;
        !          2495: }
        !          2496: 
        !          2497: /* Initialize the built-in macros.  */
        !          2498: 
        !          2499: static void
        !          2500: initialize_builtins (pfile)
        !          2501:      cpp_reader *pfile;
        !          2502: {
        !          2503:   install ("__LINE__", -1, T_SPECLINE, 0, 0, -1);
        !          2504:   install ("__DATE__", -1, T_DATE, 0, 0, -1);
        !          2505:   install ("__FILE__", -1, T_FILE, 0, 0, -1);
        !          2506:   install ("__BASE_FILE__", -1, T_BASE_FILE, 0, 0, -1);
        !          2507:   install ("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, 0, -1);
        !          2508:   install ("__VERSION__", -1, T_VERSION, 0, 0, -1);
        !          2509: #ifndef NO_BUILTIN_SIZE_TYPE
        !          2510:   install ("__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, 0, -1);
        !          2511: #endif
        !          2512: #ifndef NO_BUILTIN_PTRDIFF_TYPE
        !          2513:   install ("__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0, 0, -1);
        !          2514: #endif
        !          2515:   install ("__WCHAR_TYPE__", -1, T_WCHAR_TYPE, 0, 0, -1);
        !          2516:   install ("__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE, 0, 0, -1);
        !          2517:   install ("__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE, 0, 0, -1);
        !          2518:   install ("__TIME__", -1, T_TIME, 0, 0, -1);
        !          2519:   if (!CPP_TRADITIONAL (pfile))
        !          2520:     install ("__STDC__", -1, T_CONST, STDC_VALUE, 0, -1);
        !          2521:   if (CPP_OPTIONS (pfile)->objc)
        !          2522:     install ("__OBJC__", -1, T_CONST, 1, 0, -1);
        !          2523: /*  This is supplied using a -D by the compiler driver
        !          2524:     so that it is present only when truly compiling with GNU C.  */
        !          2525: /*  install ("__GNUC__", -1, T_CONST, 2, 0, -1);  */
        !          2526: 
        !          2527:   if (CPP_OPTIONS (pfile)->debug_output)
        !          2528:     {
        !          2529:       char directive[2048];
        !          2530:       register struct directive *dp = &directive_table[0];
        !          2531:       struct tm *timebuf = timestamp (pfile);
        !          2532:       cpp_buffer *pbuffer = CPP_BUFFER (pfile);
        !          2533: 
        !          2534:       while (CPP_PREV_BUFFER (pbuffer))
        !          2535:        pbuffer = CPP_PREV_BUFFER (pbuffer);
        !          2536:       sprintf (directive, " __BASE_FILE__ \"%s\"\n",
        !          2537:               pbuffer->nominal_fname);
        !          2538:       output_line_command (pfile, 0, same_file);
        !          2539:       pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp);
        !          2540: 
        !          2541:       sprintf (directive, " __VERSION__ \"%s\"\n", version_string);
        !          2542:       output_line_command (pfile, 0, same_file);
        !          2543:       pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp);
        !          2544: 
        !          2545: #ifndef NO_BUILTIN_SIZE_TYPE
        !          2546:       sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE);
        !          2547:       output_line_command (pfile, 0, same_file);
        !          2548:       pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp);
        !          2549: #endif
        !          2550: 
        !          2551: #ifndef NO_BUILTIN_PTRDIFF_TYPE
        !          2552:       sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE);
        !          2553:       output_line_command (pfile, 0, same_file);
        !          2554:       pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp);
        !          2555: #endif
        !          2556: 
        !          2557:       sprintf (directive, " __WCHAR_TYPE__ %s\n", CPP_WCHAR_TYPE (pfile));
        !          2558:       output_line_command (pfile, 0, same_file);
        !          2559:       pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp);
        !          2560: 
        !          2561:       sprintf (directive, " __DATE__ \"%s %2d %4d\"\n",
        !          2562:               monthnames[timebuf->tm_mon],
        !          2563:               timebuf->tm_mday, timebuf->tm_year + 1900);
        !          2564:       output_line_command (pfile, 0, same_file);
        !          2565:       pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp);
        !          2566: 
        !          2567:       sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n",
        !          2568:               timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec);
        !          2569:       output_line_command (pfile, 0, same_file);
        !          2570:       pass_thru_directive (directive, &directive[strlen (directive)], pfile, dp);
        !          2571: 
        !          2572:       if (!CPP_TRADITIONAL (pfile))
        !          2573:        {
        !          2574:           sprintf (directive, " __STDC__ 1");
        !          2575:           output_line_command (pfile, 0, same_file);
        !          2576:           pass_thru_directive (directive, &directive[strlen (directive)],
        !          2577:                               pfile, dp);
        !          2578:        }
        !          2579:       if (CPP_OPTIONS (pfile)->objc)
        !          2580:        {
        !          2581:           sprintf (directive, " __OBJC__ 1");
        !          2582:           output_line_command (pfile, 0, same_file);
        !          2583:           pass_thru_directive (directive, &directive[strlen (directive)],
        !          2584:                               pfile, dp);
        !          2585:        }
        !          2586:     }
        !          2587: }
        !          2588: 
        !          2589: /* Return 1 iff a token ending in C1 followed directly by a token C2
        !          2590:    could cause mis-tokenization. */
        !          2591: 
        !          2592: static int
        !          2593: unsafe_chars (c1, c2)
        !          2594:      int c1, c2;
        !          2595: {
        !          2596:   switch (c1)
        !          2597:     {
        !          2598:     case '+': case '-':
        !          2599:       if (c2 == c1 || c2 == '=')
        !          2600:        return 1;
        !          2601:       goto letter;
        !          2602:     case '.':
        !          2603:     case '0': case '1': case '2': case '3': case '4':
        !          2604:     case '5': case '6': case '7': case '8': case '9':
        !          2605:     case 'e': case 'E':
        !          2606:       if (c2 == '-' || c2 == '+')
        !          2607:        return 1; /* could extend a pre-processing number */
        !          2608:       goto letter;
        !          2609:     case 'L':
        !          2610:       if (c2 == '\'' || c2 == '\"')
        !          2611:        return 1;   /* Could turn into L"xxx" or L'xxx'. */
        !          2612:       goto letter;
        !          2613:     letter:
        !          2614:     case '_':
        !          2615:     case 'a': case 'b': case 'c': case 'd':           case 'f':
        !          2616:     case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
        !          2617:     case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
        !          2618:     case 's': case 't': case 'u': case 'v': case 'w': case 'x':
        !          2619:     case 'y': case 'z':
        !          2620:     case 'A': case 'B': case 'C': case 'D':           case 'F':
        !          2621:     case 'G': case 'H': case 'I': case 'J': case 'K':
        !          2622:     case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
        !          2623:     case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
        !          2624:     case 'Y': case 'Z':
        !          2625:       /* We're in the middle of either a name or a pre-processing number. */
        !          2626:       return (is_idchar[c2] || c2 == '.');
        !          2627:     case '<': case '>': case '!': case '%': case '#': case ':':
        !          2628:     case '^': case '&': case '|': case '*': case '/': case '=':
        !          2629:       return (c2 == c1 || c2 == '=');
        !          2630:     }
        !          2631:   return 0;
        !          2632: }
        !          2633: 
        !          2634: /* Expand a macro call.
        !          2635:    HP points to the symbol that is the macro being called.
        !          2636:    Put the result of expansion onto the input stack
        !          2637:    so that subsequent input by our caller will use it.
        !          2638: 
        !          2639:    If macro wants arguments, caller has already verified that
        !          2640:    an argument list follows; arguments come from the input stack.  */
        !          2641: 
        !          2642: static void
        !          2643: macroexpand (pfile, hp)
        !          2644:      cpp_reader *pfile;
        !          2645:      HASHNODE *hp;
        !          2646: {
        !          2647:   int nargs;
        !          2648:   DEFINITION *defn = hp->value.defn;
        !          2649:   register U_CHAR *xbuf;
        !          2650:   long start_line, start_column;
        !          2651:   int xbuf_len;
        !          2652:   struct argdata *args;
        !          2653:   long old_written = CPP_WRITTEN (pfile);
        !          2654: #if 0
        !          2655:   int start_line = instack[indepth].lineno;
        !          2656: #endif
        !          2657:   int rest_args, rest_zero;
        !          2658:       register int i;
        !          2659: 
        !          2660: #if 0
        !          2661:   CHECK_DEPTH (return;);
        !          2662: #endif
        !          2663: 
        !          2664: #if 0
        !          2665:   /* This macro is being used inside a #if, which means it must be */
        !          2666:   /* recorded as a precondition.  */
        !          2667:   if (pcp_inside_if && pcp_outfile && defn->predefined)
        !          2668:     dump_single_macro (hp, pcp_outfile);
        !          2669: #endif
        !          2670: 
        !          2671:   pfile->output_escapes++;
        !          2672:   cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
        !          2673: 
        !          2674:   nargs = defn->nargs;
        !          2675: 
        !          2676:   if (nargs >= 0)
        !          2677:     {
        !          2678:       enum cpp_token token;
        !          2679: 
        !          2680:       args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
        !          2681: 
        !          2682:       for (i = 0; i < nargs; i++)
        !          2683:        {
        !          2684:          args[i].raw = args[i].expanded = 0;
        !          2685:          args[i].raw_length = 0; 
        !          2686:          args[i].expand_length = args[i].stringified_length = -1;
        !          2687:          args[i].use_count = 0;
        !          2688:        }
        !          2689: 
        !          2690:       /* Parse all the macro args that are supplied.  I counts them.
        !          2691:         The first NARGS args are stored in ARGS.
        !          2692:         The rest are discarded.  If rest_args is set then we assume
        !          2693:         macarg absorbed the rest of the args. */
        !          2694:       i = 0;
        !          2695:       rest_args = 0;
        !          2696:       rest_args = 0;
        !          2697:       FORWARD(1); /* Discard the open-parenthesis before the first arg.  */
        !          2698:       do
        !          2699:        {
        !          2700:          if (rest_args)
        !          2701:            continue;
        !          2702:          if (i < nargs || (nargs == 0 && i == 0))
        !          2703:            {
        !          2704:              /* if we are working on last arg which absorbs rest of args... */
        !          2705:              if (i == nargs - 1 && defn->rest_args)
        !          2706:                rest_args = 1;
        !          2707:              args[i].raw = CPP_WRITTEN (pfile);
        !          2708:              token = macarg (pfile, rest_args);
        !          2709:              args[i].raw_length = CPP_WRITTEN (pfile) - args[i].raw;
        !          2710:              args[i].newlines = 0; /* FIXME */
        !          2711:            }
        !          2712:          else
        !          2713:            token = macarg (pfile, 0);
        !          2714:          if (token == CPP_EOF || token == CPP_POP)
        !          2715:            {
        !          2716:              cpp_error_with_line (pfile, start_line, start_column,
        !          2717:                                   "unterminated macro call");
        !          2718:              return;
        !          2719:            }
        !          2720:          i++;
        !          2721:        } while (token == CPP_COMMA);
        !          2722: 
        !          2723:       /* If we got one arg but it was just whitespace, call that 0 args.  */
        !          2724:       if (i == 1)
        !          2725:        {
        !          2726:          register U_CHAR *bp = ARG_BASE + args[0].raw;
        !          2727:          register U_CHAR *lim = bp + args[0].raw_length;
        !          2728:          /* cpp.texi says for foo ( ) we provide one argument.
        !          2729:             However, if foo wants just 0 arguments, treat this as 0.  */
        !          2730:          if (nargs == 0)
        !          2731:            while (bp != lim && is_space[*bp]) bp++;
        !          2732:          if (bp == lim)
        !          2733:            i = 0;
        !          2734:        }
        !          2735: 
        !          2736:       /* Don't output an error message if we have already output one for
        !          2737:         a parse error above.  */
        !          2738:       rest_zero = 0;
        !          2739:       if (nargs == 0 && i > 0)
        !          2740:        {
        !          2741:          cpp_error (pfile, "arguments given to macro `%s'", hp->name);
        !          2742:        }
        !          2743:       else if (i < nargs)
        !          2744:        {
        !          2745:          /* traditional C allows foo() if foo wants one argument.  */
        !          2746:          if (nargs == 1 && i == 0 && CPP_TRADITIONAL (pfile))
        !          2747:            ;
        !          2748:          /* the rest args token is allowed to absorb 0 tokens */
        !          2749:          else if (i == nargs - 1 && defn->rest_args)
        !          2750:            rest_zero = 1;
        !          2751:          else if (i == 0)
        !          2752:            cpp_error (pfile, "macro `%s' used without args", hp->name);
        !          2753:          else if (i == 1)
        !          2754:            cpp_error (pfile, "macro `%s' used with just one arg", hp->name);
        !          2755:          else
        !          2756:            cpp_error (pfile, "macro `%s' used with only %d args",
        !          2757:                       hp->name, i);
        !          2758:       }
        !          2759:       else if (i > nargs)
        !          2760:        {
        !          2761:          cpp_error (pfile,
        !          2762:                     "macro `%s' used with too many (%d) args", hp->name, i);
        !          2763:        }
        !          2764:     }
        !          2765: 
        !          2766:   /* If macro wants zero args, we parsed the arglist for checking only.
        !          2767:      Read directly from the macro definition.  */
        !          2768:   if (nargs <= 0)
        !          2769:     {
        !          2770:       xbuf = defn->expansion;
        !          2771:       xbuf_len = defn->length;
        !          2772:     }
        !          2773:   else
        !          2774:     {
        !          2775:       register U_CHAR *exp = defn->expansion;
        !          2776:       register int offset;     /* offset in expansion,
        !          2777:                                   copied a piece at a time */
        !          2778:       register int totlen;     /* total amount of exp buffer filled so far */
        !          2779: 
        !          2780:       register struct reflist *ap, *last_ap;
        !          2781: 
        !          2782:       /* Macro really takes args.  Compute the expansion of this call.  */
        !          2783: 
        !          2784:       /* Compute length in characters of the macro's expansion.
        !          2785:         Also count number of times each arg is used.  */
        !          2786:       xbuf_len = defn->length;
        !          2787:       for (ap = defn->pattern; ap != NULL; ap = ap->next)
        !          2788:        {
        !          2789:          if (ap->stringify)
        !          2790:            {
        !          2791:              register struct argdata *arg = &args[ap->argno];
        !          2792:              /* Stringify it it hasn't already been */
        !          2793:              if (arg->stringified_length < 0)
        !          2794:                {
        !          2795:                  int arglen = arg->raw_length;
        !          2796:                  int escaped = 0;
        !          2797:                  int in_string = 0;
        !          2798:                  int c;
        !          2799:                  /* Initially need_space is -1.  Otherwise, 1 means the
        !          2800:                     previous character was a space, but we suppressed it;
        !          2801:                     0 means the previous character was a non-space. */
        !          2802:                  int need_space = -1;
        !          2803:                  i = 0;
        !          2804:                  arg->stringified = CPP_WRITTEN (pfile);
        !          2805:                  if (!CPP_TRADITIONAL (pfile))
        !          2806:                    CPP_PUTC (pfile, '\"'); /* insert beginning quote */
        !          2807:                  for (; i < arglen; i++)
        !          2808:                    {
        !          2809:                      c = (ARG_BASE + arg->raw)[i];
        !          2810: 
        !          2811:                      if (! in_string)
        !          2812:                        {
        !          2813:                          /* Internal sequences of whitespace are replaced by
        !          2814:                             one space except within an string or char token.*/
        !          2815:                          if (is_space[c])
        !          2816:                            {
        !          2817:                              if (CPP_WRITTEN (pfile) > arg->stringified
        !          2818:                                  && (CPP_PWRITTEN (pfile))[-1] == '@')
        !          2819:                                {
        !          2820:                                  /* "@ " escape markers are removed */
        !          2821:                                  CPP_ADJUST_WRITTEN (pfile, -1);
        !          2822:                                  continue;
        !          2823:                                }
        !          2824:                              if (need_space == 0)
        !          2825:                                need_space = 1;
        !          2826:                              continue;
        !          2827:                            }
        !          2828:                          else if (need_space > 0)
        !          2829:                            CPP_PUTC (pfile, ' ');
        !          2830:                          need_space = 0;
        !          2831:                        }
        !          2832: 
        !          2833:                      if (escaped)
        !          2834:                        escaped = 0;
        !          2835:                      else
        !          2836:                        {
        !          2837:                          if (c == '\\')
        !          2838:                            escaped = 1;
        !          2839:                          if (in_string)
        !          2840:                            {
        !          2841:                              if (c == in_string)
        !          2842:                                in_string = 0;
        !          2843:                            }
        !          2844:                          else if (c == '\"' || c == '\'')
        !          2845:                            in_string = c;
        !          2846:                        }
        !          2847: 
        !          2848:                      /* Escape these chars */
        !          2849:                      if (c == '\"' || (in_string && c == '\\'))
        !          2850:                        CPP_PUTC (pfile, '\\');
        !          2851:                      if (isprint (c))
        !          2852:                        CPP_PUTC (pfile, c);
        !          2853:                      else
        !          2854:                        {
        !          2855:                          CPP_RESERVE (pfile, 4);
        !          2856:                          sprintf (CPP_PWRITTEN (pfile), "\\%03o",
        !          2857:                                   (unsigned int) c);
        !          2858:                          CPP_ADJUST_WRITTEN (pfile, 4);
        !          2859:                        }
        !          2860:                    }
        !          2861:                  if (!CPP_TRADITIONAL (pfile))
        !          2862:                    CPP_PUTC (pfile, '\"'); /* insert ending quote */
        !          2863:                  arg->stringified_length
        !          2864:                    = CPP_WRITTEN (pfile) - arg->stringified;
        !          2865:                }
        !          2866:              xbuf_len += args[ap->argno].stringified_length;
        !          2867:            }
        !          2868:          else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile))
        !          2869:            /* Add 4 for two newline-space markers to prevent
        !          2870:               token concatenation.  */
        !          2871:            xbuf_len += args[ap->argno].raw_length + 4;
        !          2872:          else
        !          2873:            {
        !          2874:              /* We have an ordinary (expanded) occurrence of the arg.
        !          2875:                 So compute its expansion, if we have not already.  */
        !          2876:              if (args[ap->argno].expand_length < 0)
        !          2877:                {
        !          2878:                  args[ap->argno].expanded = CPP_WRITTEN (pfile);
        !          2879:                  cpp_expand_to_buffer (pfile,
        !          2880:                                        ARG_BASE + args[ap->argno].raw,
        !          2881:                                        args[ap->argno].raw_length);
        !          2882: 
        !          2883:                  args[ap->argno].expand_length
        !          2884:                    = CPP_WRITTEN (pfile) - args[ap->argno].expanded;
        !          2885:                }
        !          2886: 
        !          2887:              /* Add 4 for two newline-space markers to prevent
        !          2888:                 token concatenation.  */
        !          2889:              xbuf_len += args[ap->argno].expand_length + 4;
        !          2890:            }
        !          2891:          if (args[ap->argno].use_count < 10)
        !          2892:            args[ap->argno].use_count++;
        !          2893:        }
        !          2894: 
        !          2895:       xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
        !          2896: 
        !          2897:       /* Generate in XBUF the complete expansion
        !          2898:         with arguments substituted in.
        !          2899:         TOTLEN is the total size generated so far.
        !          2900:         OFFSET is the index in the definition
        !          2901:         of where we are copying from.  */
        !          2902:       offset = totlen = 0;
        !          2903:       for (last_ap = NULL, ap = defn->pattern; ap != NULL;
        !          2904:           last_ap = ap, ap = ap->next)
        !          2905:        {
        !          2906:          register struct argdata *arg = &args[ap->argno];
        !          2907:          int count_before = totlen;
        !          2908: 
        !          2909:          /* Add chars to XBUF.  */
        !          2910:          for (i = 0; i < ap->nchars; i++, offset++)
        !          2911:            xbuf[totlen++] = exp[offset];
        !          2912: 
        !          2913:          /* If followed by an empty rest arg with concatenation,
        !          2914:             delete the last run of nonwhite chars.  */
        !          2915:          if (rest_zero && totlen > count_before
        !          2916:              && ((ap->rest_args && ap->raw_before)
        !          2917:                  || (last_ap != NULL && last_ap->rest_args
        !          2918:                      && last_ap->raw_after)))
        !          2919:            {
        !          2920:              /* Delete final whitespace.  */
        !          2921:              while (totlen > count_before && is_space[xbuf[totlen - 1]])
        !          2922:                totlen--;
        !          2923: 
        !          2924:              /* Delete the nonwhites before them.  */
        !          2925:              while (totlen > count_before && ! is_space[xbuf[totlen - 1]])
        !          2926:                totlen--;
        !          2927:            }
        !          2928: 
        !          2929:          if (ap->stringify != 0)
        !          2930:            {
        !          2931:              bcopy (ARG_BASE + arg->stringified,
        !          2932:                     xbuf + totlen, arg->stringified_length);
        !          2933:              totlen += arg->stringified_length;
        !          2934:            }
        !          2935:          else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile))
        !          2936:            {
        !          2937:              U_CHAR *p1 = ARG_BASE + arg->raw;
        !          2938:              U_CHAR *l1 = p1 + arg->raw_length;
        !          2939:              if (ap->raw_before)
        !          2940:                {
        !          2941:                  while (p1 != l1 && is_space[*p1]) p1++;
        !          2942:                  while (p1 != l1 && is_idchar[*p1])
        !          2943:                    xbuf[totlen++] = *p1++;
        !          2944:                }
        !          2945:              if (ap->raw_after)
        !          2946:                {
        !          2947:                  /* Arg is concatenated after: delete trailing whitespace,
        !          2948:                     whitespace markers, and no-reexpansion markers.  */
        !          2949:                  while (p1 != l1)
        !          2950:                    {
        !          2951:                      if (is_space[l1[-1]]) l1--;
        !          2952:                      else if (l1[-1] == '-')
        !          2953:                        {
        !          2954:                          U_CHAR *p2 = l1 - 1;
        !          2955:                          /* If a `-' is preceded by an odd number of newlines then it
        !          2956:                             and the last newline are a no-reexpansion marker.  */
        !          2957:                          while (p2 != p1 && p2[-1] == '\n') p2--;
        !          2958:                          if ((l1 - 1 - p2) & 1) {
        !          2959:                            l1 -= 2;
        !          2960:                          }
        !          2961:                          else break;
        !          2962:                        }
        !          2963:                      else break;
        !          2964:                    }
        !          2965:                }
        !          2966: 
        !          2967:              bcopy (p1, xbuf + totlen, l1 - p1);
        !          2968:              totlen += l1 - p1;
        !          2969:            }
        !          2970:          else
        !          2971:            {
        !          2972:              U_CHAR *expanded = ARG_BASE + arg->expanded;
        !          2973:              if (!ap->raw_before && totlen > 0 && arg->expand_length
        !          2974:                  && !CPP_TRADITIONAL(pfile)
        !          2975:                  && unsafe_chars (xbuf[totlen-1], expanded[0]))
        !          2976:                {
        !          2977:                  xbuf[totlen++] = '@';
        !          2978:                  xbuf[totlen++] = ' ';
        !          2979:                }
        !          2980: 
        !          2981:              bcopy (expanded, xbuf + totlen, arg->expand_length);
        !          2982:              totlen += arg->expand_length;
        !          2983: 
        !          2984:              if (!ap->raw_after && totlen > 0 && offset < defn->length
        !          2985:                  && !CPP_TRADITIONAL(pfile)
        !          2986:                  && unsafe_chars (xbuf[totlen-1], exp[offset]))
        !          2987:                {
        !          2988:                  xbuf[totlen++] = '@';
        !          2989:                  xbuf[totlen++] = ' ';
        !          2990:                }
        !          2991: 
        !          2992:              /* If a macro argument with newlines is used multiple times,
        !          2993:                 then only expand the newlines once.  This avoids creating
        !          2994:                 output lines which don't correspond to any input line,
        !          2995:                 which confuses gdb and gcov.  */
        !          2996:              if (arg->use_count > 1 && arg->newlines > 0)
        !          2997:                {
        !          2998:                  /* Don't bother doing change_newlines for subsequent
        !          2999:                     uses of arg.  */
        !          3000:                  arg->use_count = 1;
        !          3001:                  arg->expand_length
        !          3002:                    = change_newlines (expanded, arg->expand_length);
        !          3003:                }
        !          3004:            }
        !          3005: 
        !          3006:          if (totlen > xbuf_len)
        !          3007:            abort ();
        !          3008:       }
        !          3009: 
        !          3010:       /* if there is anything left of the definition
        !          3011:         after handling the arg list, copy that in too. */
        !          3012: 
        !          3013:       for (i = offset; i < defn->length; i++)
        !          3014:        {
        !          3015:          /* if we've reached the end of the macro */
        !          3016:          if (exp[i] == ')')
        !          3017:            rest_zero = 0;
        !          3018:          if (! (rest_zero && last_ap != NULL && last_ap->rest_args
        !          3019:                 && last_ap->raw_after))
        !          3020:            xbuf[totlen++] = exp[i];
        !          3021:        }
        !          3022: 
        !          3023:       xbuf[totlen] = 0;
        !          3024:       xbuf_len = totlen;
        !          3025: 
        !          3026:     }
        !          3027: 
        !          3028:   pfile->output_escapes--;
        !          3029: 
        !          3030:   /* Now put the expansion on the input stack
        !          3031:      so our caller will commence reading from it.  */
        !          3032:   push_macro_expansion (pfile, xbuf, xbuf_len, hp);
        !          3033:   CPP_BUFFER (pfile)->has_escapes = 1;
        !          3034: 
        !          3035:   /* Pop the space we've used in the token_buffer for argument expansion. */
        !          3036:   CPP_SET_WRITTEN (pfile, old_written);
        !          3037:     
        !          3038:   /* Recursive macro use sometimes works traditionally.
        !          3039:      #define foo(x,y) bar (x (y,0), y)
        !          3040:      foo (foo, baz)  */
        !          3041:   
        !          3042:   if (!CPP_TRADITIONAL (pfile))
        !          3043:     hp->type = T_DISABLED;
        !          3044: }
        !          3045: 
        !          3046: static void
        !          3047: push_macro_expansion (pfile, xbuf, xbuf_len, hp)
        !          3048:      cpp_reader *pfile;
        !          3049:      register U_CHAR *xbuf;
        !          3050:      int xbuf_len;
        !          3051:      HASHNODE *hp;
        !          3052: {
        !          3053:   register cpp_buffer *mbuf = cpp_push_buffer (pfile, xbuf, xbuf_len);
        !          3054:   mbuf->cleanup = macro_cleanup;
        !          3055:   mbuf->data = hp;
        !          3056: 
        !          3057:   /* The first chars of the expansion should be a "@ " added by
        !          3058:      collect_expansion.  This is to prevent accidental token-pasting
        !          3059:      between the text preceding the macro invocation, and the macro
        !          3060:      expansion text.
        !          3061: 
        !          3062:      We would like to avoid adding unneeded spaces (for the sake of
        !          3063:      tools that use cpp, such as imake).  In some common cases we can
        !          3064:      tell that it is safe to omit the space.
        !          3065: 
        !          3066:      The character before the macro invocation cannot have been an
        !          3067:      idchar (or else it would have been pasted with the idchars of
        !          3068:      the macro name).  Therefore, if the first non-space character
        !          3069:      of the expansion is an idchar, we do not need the extra space
        !          3070:      to prevent token pasting.
        !          3071: 
        !          3072:      Also, we don't need the extra space if the first char is '(',
        !          3073:      or some other (less common) characters.  */
        !          3074: 
        !          3075:   if (xbuf[0] == '@' && xbuf[1] == ' '
        !          3076:       && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
        !          3077:          || xbuf[2] == '\"'))
        !          3078:     mbuf->cur += 2;
        !          3079: }
        !          3080: 
        !          3081: /* Like cpp_get_token, except that it does not read past end-of-line.
        !          3082:    Also, horizontal space is skipped, and macros are popped.  */
        !          3083: 
        !          3084: static enum cpp_token
        !          3085: get_directive_token (pfile)
        !          3086:      cpp_reader *pfile;
        !          3087: {
        !          3088:   for (;;)
        !          3089:     {
        !          3090:       long old_written = CPP_WRITTEN (pfile);
        !          3091:       enum cpp_token token;
        !          3092:       cpp_skip_hspace (pfile);
        !          3093:       if (PEEKC () == '\n')
        !          3094:          return CPP_VSPACE;
        !          3095:       token = cpp_get_token (pfile);
        !          3096:       switch (token)
        !          3097:       {
        !          3098:       case CPP_POP:
        !          3099:          if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
        !          3100:              return token;
        !          3101:          /* ... else fall though ... */
        !          3102:       case CPP_HSPACE:  case CPP_COMMENT:
        !          3103:          CPP_SET_WRITTEN (pfile, old_written);
        !          3104:          break;
        !          3105:       default:
        !          3106:          return token;
        !          3107:       }
        !          3108:     }
        !          3109: }
        !          3110: 
        !          3111: /* Handle #include and #import.
        !          3112:    This function expects to see "fname" or <fname> on the input.
        !          3113: 
        !          3114:    The input is normally in part of the output_buffer following
        !          3115:    CPP_WRITTEN, and will get overwritten by output_line_command.
        !          3116:    I.e. in input file specification has been popped by handle_directive.
        !          3117:    This is safe. */
        !          3118: 
        !          3119: static int
        !          3120: do_include (pfile, keyword, unused1, unused2)
        !          3121:      cpp_reader *pfile;
        !          3122:      struct directive *keyword;
        !          3123:      U_CHAR *unused1, *unused2;
        !          3124: {
        !          3125:   int importing = (keyword->type == T_IMPORT);
        !          3126:   int skip_dirs = (keyword->type == T_INCLUDE_NEXT);
        !          3127:   char *fname;         /* Dynamically allocated fname buffer */
        !          3128:   char *pcftry;
        !          3129:   char *pcfname;
        !          3130:   U_CHAR *fbeg, *fend;         /* Beginning and end of fname */
        !          3131:   enum cpp_token token;
        !          3132: 
        !          3133:   /* Chain of dirs to search */
        !          3134:   struct file_name_list *search_start = CPP_OPTIONS (pfile)->include;
        !          3135:   struct file_name_list dsp[1];        /* First in chain, if #include "..." */
        !          3136:   struct file_name_list *searchptr = 0;
        !          3137:   long old_written = CPP_WRITTEN (pfile);
        !          3138: 
        !          3139:   int flen;
        !          3140: 
        !          3141:   int f;                       /* file number */
        !          3142: 
        !          3143:   int retried = 0;             /* Have already tried macro
        !          3144:                                   expanding the include line*/
        !          3145:   int angle_brackets = 0;      /* 0 for "...", 1 for <...> */
        !          3146:   int pcf = -1;
        !          3147:   char *pcfbuf;
        !          3148:   char *pcfbuflimit;
        !          3149:   int pcfnum;
        !          3150:   f= -1;                       /* JF we iz paranoid! */
        !          3151: 
        !          3152:   if (importing && CPP_OPTIONS (pfile)->warn_import
        !          3153:       && !CPP_OPTIONS (pfile)->inhibit_warnings
        !          3154:       && !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning)
        !          3155:     {
        !          3156:       pfile->import_warning = 1;
        !          3157:       cpp_warning (pfile, "using `#import' is not recommended");
        !          3158:       fprintf (stderr, "The fact that a certain header file need not be processed more than once\n");
        !          3159:       fprintf (stderr, "should be indicated in the header file, not where it is used.\n");
        !          3160:       fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n");
        !          3161:       fprintf (stderr, "  #ifndef _FOO_H_INCLUDED\n");
        !          3162:       fprintf (stderr, "  #define _FOO_H_INCLUDED\n");
        !          3163:       fprintf (stderr, "  ... <real contents of file> ...\n");
        !          3164:       fprintf (stderr, "  #endif /* Not _FOO_H_INCLUDED */\n\n");
        !          3165:       fprintf (stderr, "Then users can use `#include' any number of times.\n");
        !          3166:       fprintf (stderr, "GNU C automatically avoids processing the file more than once\n");
        !          3167:       fprintf (stderr, "when it is equipped with such a conditional.\n");
        !          3168:     }
        !          3169: 
        !          3170:   pfile->parsing_include_directive++;
        !          3171:   token = get_directive_token (pfile);
        !          3172:   pfile->parsing_include_directive--;
        !          3173: 
        !          3174:   if (token == CPP_STRING)
        !          3175:     {
        !          3176:       /* FIXME - check no trailing garbage */
        !          3177:       fbeg = pfile->token_buffer + old_written + 1;
        !          3178:       fend = CPP_PWRITTEN (pfile) - 1;
        !          3179:       if (fbeg[-1] == '<')
        !          3180:        {
        !          3181:          angle_brackets = 1;
        !          3182:          /* If -I-, start with the first -I dir after the -I-.  */
        !          3183:          if (CPP_OPTIONS (pfile)->first_bracket_include)
        !          3184:            search_start = CPP_OPTIONS (pfile)->first_bracket_include;
        !          3185:        }
        !          3186:       /* If -I- was specified, don't search current dir, only spec'd ones. */
        !          3187:       else if (! CPP_OPTIONS (pfile)->ignore_srcdir)
        !          3188:        {
        !          3189:          cpp_buffer *fp;
        !          3190:          /* We have "filename".  Figure out directory this source
        !          3191:             file is coming from and put it on the front of the list. */
        !          3192: 
        !          3193:          for (fp = CPP_BUFFER (pfile); fp != NULL; fp = CPP_PREV_BUFFER (fp))
        !          3194:            {
        !          3195:              int n;
        !          3196:              char *ep,*nam;
        !          3197: 
        !          3198:              if ((nam = fp->nominal_fname) != NULL)
        !          3199:                {
        !          3200:                  /* Found a named file.  Figure out dir of the file,
        !          3201:                     and put it in front of the search list.  */
        !          3202:                  dsp[0].next = search_start;
        !          3203:                  search_start = dsp;
        !          3204: #ifndef VMS
        !          3205:                  ep = rindex (nam, '/');
        !          3206: #else                          /* VMS */
        !          3207:                  ep = rindex (nam, ']');
        !          3208:                  if (ep == NULL) ep = rindex (nam, '>');
        !          3209:                  if (ep == NULL) ep = rindex (nam, ':');
        !          3210:                  if (ep != NULL) ep++;
        !          3211: #endif                         /* VMS */
        !          3212:                  if (ep != NULL)
        !          3213:                    {
        !          3214:                      n = ep - nam;
        !          3215:                      dsp[0].fname = (char *) alloca (n + 1);
        !          3216:                      strncpy (dsp[0].fname, nam, n);
        !          3217:                      dsp[0].fname[n] = '\0';
        !          3218:                      if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len)
        !          3219:                        pfile->max_include_len = n + INCLUDE_LEN_FUDGE;
        !          3220:                    }
        !          3221:                  else
        !          3222:                    {
        !          3223:                      dsp[0].fname = 0; /* Current directory */
        !          3224:                    }
        !          3225:                  dsp[0].got_name_map = 0;
        !          3226:                  break;
        !          3227:                }
        !          3228:            }
        !          3229:        }
        !          3230:     }
        !          3231: #ifdef VMS
        !          3232:   else if (token == CPP_NAME)
        !          3233:     {
        !          3234:       /*
        !          3235:        * Support '#include xyz' like VAX-C to allow for easy use of all the
        !          3236:        * decwindow include files. It defaults to '#include <xyz.h>' (so the
        !          3237:        * code from case '<' is repeated here) and generates a warning.
        !          3238:        */
        !          3239:       cpp_warning (pfile,
        !          3240:                   "VAX-C-style include specification found, use '#include <filename.h>' !");
        !          3241:       angle_brackets = 1;
        !          3242:       /* If -I-, start with the first -I dir after the -I-.  */
        !          3243:       if (CPP_OPTIONS (pfile)->first_bracket_include)
        !          3244:        search_start = CPP_OPTIONS (pfile)->first_bracket_include;
        !          3245:       fbeg = pfile->token_buffer + old_written;
        !          3246:       fend = CPP_PWRITTEN (pfile);
        !          3247:     }
        !          3248: #endif
        !          3249:   else
        !          3250:     {
        !          3251:       cpp_error (pfile,
        !          3252:                 "`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name);
        !          3253:       CPP_SET_WRITTEN (pfile, old_written);
        !          3254:       skip_rest_of_line (pfile);
        !          3255:       return 0;
        !          3256:     }
        !          3257: 
        !          3258:   *fend = 0;
        !          3259: 
        !          3260:   token = get_directive_token (pfile);
        !          3261:   if (token != CPP_VSPACE)
        !          3262:     {
        !          3263:       cpp_error (pfile, "junk at end of `#include'");
        !          3264:       while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
        !          3265:        token = get_directive_token (pfile);
        !          3266:     }
        !          3267: 
        !          3268:   /* For #include_next, skip in the search path
        !          3269:      past the dir in which the containing file was found.  */
        !          3270:   if (skip_dirs)
        !          3271:     {
        !          3272:       cpp_buffer *fp;
        !          3273:       for (fp = CPP_BUFFER (pfile); fp != NULL; fp = CPP_PREV_BUFFER (fp))
        !          3274:        if (fp->fname != NULL)
        !          3275:          {
        !          3276:            /* fp->dir is null if the containing file was specified with
        !          3277:               an absolute file name.  In that case, don't skip anything.  */
        !          3278:            if (fp->dir == SELF_DIR_DUMMY)
        !          3279:              search_start = CPP_OPTIONS (pfile)->include;
        !          3280:            else if (fp->dir)
        !          3281:              search_start = fp->dir->next;
        !          3282:            break;
        !          3283:          }
        !          3284:     }
        !          3285: 
        !          3286:   CPP_SET_WRITTEN (pfile, old_written);
        !          3287: 
        !          3288:   flen = fend - fbeg;
        !          3289: 
        !          3290:   if (flen == 0)
        !          3291:     {
        !          3292:       cpp_error (pfile, "empty file name in `#%s'", keyword->name);
        !          3293:       return 0;
        !          3294:     }
        !          3295: 
        !          3296:   /* Allocate this permanently, because it gets stored in the definitions
        !          3297:      of macros.  */
        !          3298:   fname = (char *) xmalloc (pfile->max_include_len + flen + 4);
        !          3299:   /* + 2 above for slash and terminating null.  */
        !          3300:   /* + 2 added for '.h' on VMS (to support '#include filename') */
        !          3301: 
        !          3302:   /* If specified file name is absolute, just open it.  */
        !          3303: 
        !          3304:   if (*fbeg == '/') {
        !          3305:     strncpy (fname, fbeg, flen);
        !          3306:     fname[flen] = 0;
        !          3307:     if (redundant_include_p (pfile, fname))
        !          3308:       return 0;
        !          3309:     if (importing)
        !          3310:       f = lookup_import (pfile, fname, NULL_PTR);
        !          3311:     else
        !          3312:       f = open_include_file (pfile, fname, NULL_PTR);
        !          3313:     if (f == -2)
        !          3314:       return 0;                /* Already included this file */
        !          3315:   } else {
        !          3316:     /* Search directory path, trying to open the file.
        !          3317:        Copy each filename tried into FNAME.  */
        !          3318: 
        !          3319:     for (searchptr = search_start; searchptr; searchptr = searchptr->next) {
        !          3320:       if (searchptr->fname) {
        !          3321:        /* The empty string in a search path is ignored.
        !          3322:           This makes it possible to turn off entirely
        !          3323:           a standard piece of the list.  */
        !          3324:        if (searchptr->fname[0] == 0)
        !          3325:          continue;
        !          3326:        strcpy (fname, searchptr->fname);
        !          3327:        strcat (fname, "/");
        !          3328:        fname[strlen (fname) + flen] = 0;
        !          3329:       } else {
        !          3330:        fname[0] = 0;
        !          3331:       }
        !          3332:       strncat (fname, fbeg, flen);
        !          3333: #ifdef VMS
        !          3334:       /* Change this 1/2 Unix 1/2 VMS file specification into a
        !          3335:          full VMS file specification */
        !          3336:       if (searchptr->fname && (searchptr->fname[0] != 0)) {
        !          3337:        /* Fix up the filename */
        !          3338:        hack_vms_include_specification (fname);
        !          3339:       } else {
        !          3340:        /* This is a normal VMS filespec, so use it unchanged.  */
        !          3341:        strncpy (fname, fbeg, flen);
        !          3342:        fname[flen] = 0;
        !          3343:        /* if it's '#include filename', add the missing .h */
        !          3344:        if (index(fname,'.')==NULL) {
        !          3345:          strcat (fname, ".h");
        !          3346:        }
        !          3347:       }
        !          3348: #endif /* VMS */
        !          3349:       /* ??? There are currently 3 separate mechanisms for avoiding processing
        !          3350:         of redundant include files: #import, #pragma once, and
        !          3351:         redundant_include_p.  It would be nice if they were unified.  */
        !          3352:       if (redundant_include_p (pfile, fname))
        !          3353:        return 0;
        !          3354:       if (importing)
        !          3355:        f = lookup_import (pfile, fname, searchptr);
        !          3356:       else
        !          3357:        f = open_include_file (pfile, fname, searchptr);
        !          3358:       if (f == -2)
        !          3359:        return 0;                       /* Already included this file */
        !          3360: #ifdef EACCES
        !          3361:       else if (f == -1 && errno == EACCES)
        !          3362:        cpp_warning (pfile, "Header file %s exists, but is not readable",
        !          3363:                     fname);
        !          3364: #endif
        !          3365:       if (f >= 0)
        !          3366:        break;
        !          3367:     }
        !          3368:   }
        !          3369: 
        !          3370:   if (f < 0)
        !          3371:     {
        !          3372:       /* A file that was not found.  */
        !          3373:       strncpy (fname, fbeg, flen);
        !          3374:       fname[flen] = 0;
        !          3375:       /* If generating dependencies and -MG was specified, we assume missing
        !          3376:         files are leaf files, living in the same directory as the source file
        !          3377:         or other similar place; these missing files may be generated from
        !          3378:         other files and may not exist yet (eg: y.tab.h).  */
        !          3379: 
        !          3380:       if (CPP_OPTIONS(pfile)->print_deps_missing_files
        !          3381:          && CPP_PRINT_DEPS (pfile)
        !          3382:          > (angle_brackets || (pfile->system_include_depth > 0)))
        !          3383:        {
        !          3384:          /* If it was requested as a system header file,
        !          3385:             then assume it belongs in the first place to look for such.  */
        !          3386:          if (angle_brackets)
        !          3387:            {
        !          3388:              for (searchptr = search_start; searchptr;
        !          3389:                   searchptr = searchptr->next)
        !          3390:                {
        !          3391:                  if (searchptr->fname)
        !          3392:                    {
        !          3393:                      char *p;
        !          3394: 
        !          3395:                      if (searchptr->fname[0] == 0)
        !          3396:                        continue;
        !          3397:                      p = (char *) alloca (strlen (searchptr->fname)
        !          3398:                                           + strlen (fname) + 2);
        !          3399:                      strcpy (p, searchptr->fname);
        !          3400:                      strcat (p, "/");
        !          3401:                      strcat (p, fname);
        !          3402:                      deps_output (pfile, p, ' ');
        !          3403:                      break;
        !          3404:                    }
        !          3405:                }
        !          3406:            }
        !          3407:          else
        !          3408:            {
        !          3409:              /* Otherwise, omit the directory, as if the file existed
        !          3410:                 in the directory with the source.  */
        !          3411:              deps_output (pfile, fname, ' ');
        !          3412:            }
        !          3413:        }
        !          3414:       /* If -M was specified, and this header file won't be added to the
        !          3415:         dependency list, then don't count this as an error, because we can
        !          3416:         still produce correct output.  Otherwise, we can't produce correct
        !          3417:         output, because there may be dependencies we need inside the missing
        !          3418:         file, and we don't know what directory this missing file exists in.*/
        !          3419:       else if (CPP_PRINT_DEPS (pfile)
        !          3420:               && (CPP_PRINT_DEPS (pfile)
        !          3421:                   <= (angle_brackets || (pfile->system_include_depth > 0))))
        !          3422:        cpp_warning (pfile, "No include path in which to find %s", fname);
        !          3423:       else if (search_start)
        !          3424:        cpp_error_from_errno (pfile, fname);
        !          3425:       else
        !          3426:        cpp_error (pfile, "No include path in which to find %s", fname);
        !          3427:     }
        !          3428:   else {
        !          3429:     /* Check to see if this include file is a once-only include file.
        !          3430:        If so, give up.  */
        !          3431: 
        !          3432:     struct file_name_list* ptr;
        !          3433: 
        !          3434:     for (ptr = pfile->dont_repeat_files; ptr; ptr = ptr->next) {
        !          3435:       if (!strcmp (ptr->fname, fname)) {
        !          3436:        close (f);
        !          3437:         return 0;                              /* This file was once'd. */
        !          3438:       }
        !          3439:     }
        !          3440: 
        !          3441:     for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) {
        !          3442:       if (!strcmp (ptr->fname, fname))
        !          3443:         break;                         /* This file was included before. */
        !          3444:     }
        !          3445: 
        !          3446:     if (ptr == 0) {
        !          3447:       /* This is the first time for this file.  */
        !          3448:       /* Add it to list of files included.  */
        !          3449: 
        !          3450:       ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
        !          3451:       ptr->control_macro = 0;
        !          3452:       ptr->c_system_include_path = 0;
        !          3453:       ptr->next = pfile->all_include_files;
        !          3454:       pfile->all_include_files = ptr;
        !          3455:       ptr->fname = savestring (fname);
        !          3456:       ptr->got_name_map = 0;
        !          3457: 
        !          3458:       /* For -M, add this file to the dependencies.  */
        !          3459:       if (CPP_PRINT_DEPS (pfile)
        !          3460:          > (angle_brackets || (pfile->system_include_depth > 0)))
        !          3461:        deps_output (pfile, fname, ' ');
        !          3462:     }   
        !          3463: 
        !          3464:     /* Handle -H option.  */
        !          3465:     if (CPP_OPTIONS(pfile)->print_include_names)
        !          3466:       {
        !          3467:        cpp_buffer *buf = CPP_BUFFER (pfile);
        !          3468:        while ((buf = CPP_PREV_BUFFER (buf)) != NULL)
        !          3469:          putc ('.', stderr);
        !          3470:        fprintf (stderr, "%s\n", fname);
        !          3471:       }
        !          3472: 
        !          3473:     if (angle_brackets)
        !          3474:       pfile->system_include_depth++;
        !          3475: 
        !          3476:     /* Actually process the file.  */
        !          3477: 
        !          3478:     /* Record file on "seen" list for #import. */
        !          3479:     add_import (pfile, f, fname);
        !          3480: 
        !          3481:     pcftry = (char *) alloca (strlen (fname) + 30);
        !          3482:     pcfbuf = 0;
        !          3483:     pcfnum = 0;
        !          3484: 
        !          3485: #if 0
        !          3486:     if (!no_precomp)
        !          3487:       {
        !          3488:        struct stat stat_f;
        !          3489: 
        !          3490:        fstat (f, &stat_f);
        !          3491: 
        !          3492:        do {
        !          3493:          sprintf (pcftry, "%s%d", fname, pcfnum++);
        !          3494: 
        !          3495:          pcf = open (pcftry, O_RDONLY, 0666);
        !          3496:          if (pcf != -1)
        !          3497:            {
        !          3498:              struct stat s;
        !          3499: 
        !          3500:              fstat (pcf, &s);
        !          3501:              if (bcmp ((char *) &stat_f.st_ino, (char *) &s.st_ino,
        !          3502:                        sizeof (s.st_ino))
        !          3503:                  || stat_f.st_dev != s.st_dev)
        !          3504:                {
        !          3505:                  pcfbuf = check_precompiled (pcf, fname, &pcfbuflimit);
        !          3506:                  /* Don't need it any more.  */
        !          3507:                  close (pcf);
        !          3508:                }
        !          3509:              else
        !          3510:                {
        !          3511:                  /* Don't need it at all.  */
        !          3512:                  close (pcf);
        !          3513:                  break;
        !          3514:                }
        !          3515:            }
        !          3516:        } while (pcf != -1 && !pcfbuf);
        !          3517:       }
        !          3518: #endif
        !          3519:     
        !          3520:     /* Actually process the file */
        !          3521:     cpp_push_buffer (pfile, NULL, 0);
        !          3522:     if (finclude (pfile, f, fname, is_system_include (pfile, fname),
        !          3523:                  searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
        !          3524:       {
        !          3525:        output_line_command (pfile, 0, enter_file);
        !          3526:        pfile->only_seen_white = 2;
        !          3527:       }
        !          3528: 
        !          3529:     if (angle_brackets)
        !          3530:       pfile->system_include_depth--;
        !          3531:   }
        !          3532:   return 0;
        !          3533: }
        !          3534: 
        !          3535: /* Return nonzero if there is no need to include file NAME
        !          3536:    because it has already been included and it contains a conditional
        !          3537:    to make a repeated include do nothing.  */
        !          3538: 
        !          3539: static int
        !          3540: redundant_include_p (pfile, name)
        !          3541:      cpp_reader *pfile;
        !          3542:      char *name;
        !          3543: {
        !          3544:   struct file_name_list *l = pfile->all_include_files;
        !          3545:   for (; l; l = l->next)
        !          3546:     if (! strcmp (name, l->fname)
        !          3547:        && l->control_macro
        !          3548:        && cpp_lookup (pfile, l->control_macro, -1, -1))
        !          3549:       return 1;
        !          3550:   return 0;
        !          3551: }
        !          3552: 
        !          3553: /* Return nonzero if the given FILENAME is an absolute pathname which
        !          3554:    designates a file within one of the known "system" include file
        !          3555:    directories.  We assume here that if the given FILENAME looks like
        !          3556:    it is the name of a file which resides either directly in a "system"
        !          3557:    include file directory, or within any subdirectory thereof, then the
        !          3558:    given file must be a "system" include file.  This function tells us
        !          3559:    if we should suppress pedantic errors/warnings for the given FILENAME.
        !          3560: 
        !          3561:    The value is 2 if the file is a C-language system header file
        !          3562:    for which C++ should (on most systems) assume `extern "C"'.  */
        !          3563: 
        !          3564: static int
        !          3565: is_system_include (pfile, filename)
        !          3566:      cpp_reader *pfile;
        !          3567:      register char *filename;
        !          3568: {
        !          3569:   struct file_name_list *searchptr;
        !          3570: 
        !          3571:   for (searchptr = CPP_OPTIONS (pfile)->first_system_include; searchptr;
        !          3572:        searchptr = searchptr->next)
        !          3573:     if (searchptr->fname) {
        !          3574:       register char *sys_dir = searchptr->fname;
        !          3575:       register unsigned length = strlen (sys_dir);
        !          3576: 
        !          3577:       if (! strncmp (sys_dir, filename, length) && filename[length] == '/')
        !          3578:        {
        !          3579:          if (searchptr->c_system_include_path)
        !          3580:            return 2;
        !          3581:          else
        !          3582:            return 1;
        !          3583:        }
        !          3584:     }
        !          3585:   return 0;
        !          3586: }
        !          3587: 
        !          3588: 
        !          3589: /*
        !          3590:  * Install a name in the assertion hash table.
        !          3591:  *
        !          3592:  * If LEN is >= 0, it is the length of the name.
        !          3593:  * Otherwise, compute the length by scanning the entire name.
        !          3594:  *
        !          3595:  * If HASH is >= 0, it is the precomputed hash code.
        !          3596:  * Otherwise, compute the hash code.
        !          3597:  */
        !          3598: static ASSERTION_HASHNODE *
        !          3599: assertion_install (pfile, name, len, hash)
        !          3600:      cpp_reader *pfile;
        !          3601:      U_CHAR *name;
        !          3602:      int len;
        !          3603:      int hash;
        !          3604: {
        !          3605:   register ASSERTION_HASHNODE *hp;
        !          3606:   register int i, bucket;
        !          3607:   register U_CHAR *p, *q;
        !          3608: 
        !          3609:   i = sizeof (ASSERTION_HASHNODE) + len + 1;
        !          3610:   hp = (ASSERTION_HASHNODE *) xmalloc (i);
        !          3611:   bucket = hash;
        !          3612:   hp->bucket_hdr = &pfile->assertion_hashtab[bucket];
        !          3613:   hp->next = pfile->assertion_hashtab[bucket];
        !          3614:   pfile->assertion_hashtab[bucket] = hp;
        !          3615:   hp->prev = NULL;
        !          3616:   if (hp->next != NULL)
        !          3617:     hp->next->prev = hp;
        !          3618:   hp->length = len;
        !          3619:   hp->value = 0;
        !          3620:   hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE);
        !          3621:   p = hp->name;
        !          3622:   q = name;
        !          3623:   for (i = 0; i < len; i++)
        !          3624:     *p++ = *q++;
        !          3625:   hp->name[len] = 0;
        !          3626:   return hp;
        !          3627: }
        !          3628: /*
        !          3629:  * find the most recent hash node for name name (ending with first
        !          3630:  * non-identifier char) installed by install
        !          3631:  *
        !          3632:  * If LEN is >= 0, it is the length of the name.
        !          3633:  * Otherwise, compute the length by scanning the entire name.
        !          3634:  *
        !          3635:  * If HASH is >= 0, it is the precomputed hash code.
        !          3636:  * Otherwise, compute the hash code.
        !          3637:  */
        !          3638: 
        !          3639: static ASSERTION_HASHNODE *
        !          3640: assertion_lookup (pfile, name, len, hash)
        !          3641:      cpp_reader *pfile;
        !          3642:      U_CHAR *name;
        !          3643:      int len;
        !          3644:      int hash;
        !          3645: {
        !          3646:   register ASSERTION_HASHNODE *bucket;
        !          3647: 
        !          3648:   bucket = pfile->assertion_hashtab[hash];
        !          3649:   while (bucket) {
        !          3650:     if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
        !          3651:       return bucket;
        !          3652:     bucket = bucket->next;
        !          3653:   }
        !          3654:   return NULL;
        !          3655: }
        !          3656: 
        !          3657: static void
        !          3658: delete_assertion (hp)
        !          3659:      ASSERTION_HASHNODE *hp;
        !          3660: {
        !          3661:   struct tokenlist_list *tail;
        !          3662:   if (hp->prev != NULL)
        !          3663:     hp->prev->next = hp->next;
        !          3664:   if (hp->next != NULL)
        !          3665:     hp->next->prev = hp->prev;
        !          3666: 
        !          3667:   for (tail = hp->value; tail; )
        !          3668:     {
        !          3669:       struct tokenlist_list *next = tail->next;
        !          3670:       free_token_list (tail->tokens);
        !          3671:       free (tail);
        !          3672:       tail = next;
        !          3673:     }
        !          3674: 
        !          3675:   /* make sure that the bucket chain header that
        !          3676:      the deleted guy was on points to the right thing afterwards. */
        !          3677:   if (hp == *hp->bucket_hdr)
        !          3678:     *hp->bucket_hdr = hp->next;
        !          3679: 
        !          3680:   free (hp);
        !          3681: }
        !          3682: 
        !          3683: /* Convert a character string literal into a nul-terminated string.
        !          3684:    The input string is [IN ... LIMIT).
        !          3685:    The result is placed in RESULT.  RESULT can be the same as IN.
        !          3686:    The value returned in the end of the string written to RESULT,
        !          3687:    or NULL on error.  */
        !          3688: 
        !          3689: static U_CHAR*
        !          3690: convert_string (pfile, result, in, limit, handle_escapes)
        !          3691:      cpp_reader *pfile;
        !          3692:      register U_CHAR *result, *in, *limit;
        !          3693:      int handle_escapes;
        !          3694: {
        !          3695:   U_CHAR c;
        !          3696:   c = *in++;
        !          3697:   if (c != '\"')
        !          3698:     return NULL;
        !          3699:   while (in < limit)
        !          3700:     {
        !          3701:       U_CHAR c = *in++;
        !          3702:       switch (c)
        !          3703:        {
        !          3704:        case '\0':
        !          3705:          return NULL;
        !          3706:        case '\"':
        !          3707:          limit = in;
        !          3708:          break;
        !          3709:        case '\\':
        !          3710:          if (handle_escapes)
        !          3711:            {
        !          3712:              char *bpc = (char *) in;
        !          3713:              int i = (U_CHAR) cpp_parse_escape (pfile, &bpc);
        !          3714:              in = (U_CHAR *) bpc;
        !          3715:              if (i >= 0)
        !          3716:                *result++ = (U_CHAR)c;
        !          3717:              break;
        !          3718:            }
        !          3719:          /* else fall through */
        !          3720:        default:
        !          3721:          *result++ = c;
        !          3722:        }
        !          3723:     }
        !          3724:   *result = 0;
        !          3725:   return result;
        !          3726: }
        !          3727: 
        !          3728: /*
        !          3729:  * interpret #line command.  Remembers previously seen fnames
        !          3730:  * in its very own hash table.
        !          3731:  */
        !          3732: #define FNAME_HASHSIZE 37
        !          3733: 
        !          3734: static int
        !          3735: do_line (pfile, keyword)
        !          3736:      cpp_reader *pfile;
        !          3737:      struct directive *keyword;
        !          3738: {
        !          3739:   cpp_buffer *ip = CPP_BUFFER (pfile);
        !          3740:   int new_lineno;
        !          3741:   long old_written = CPP_WRITTEN (pfile);
        !          3742:   enum file_change_code file_change = same_file;
        !          3743:   enum cpp_token token;
        !          3744:   int i;
        !          3745: 
        !          3746:   token = get_directive_token (pfile);
        !          3747: 
        !          3748:   if (token != CPP_NUMBER
        !          3749:       || !isdigit(pfile->token_buffer[old_written]))
        !          3750:     {
        !          3751:       cpp_error (pfile, "invalid format `#line' command");
        !          3752:       goto bad_line_directive;
        !          3753:     }
        !          3754: 
        !          3755:   /* The Newline at the end of this line remains to be processed.
        !          3756:      To put the next line at the specified line number,
        !          3757:      we must store a line number now that is one less.  */
        !          3758:   new_lineno = atoi (pfile->token_buffer + old_written) - 1;
        !          3759:   CPP_SET_WRITTEN (pfile, old_written);
        !          3760: 
        !          3761:   /* NEW_LINENO is one less than the actual line number here.  */
        !          3762:   if (CPP_PEDANTIC (pfile) && new_lineno < 0)
        !          3763:     cpp_pedwarn (pfile, "line number out of range in `#line' command");
        !          3764: 
        !          3765: #if 0 /* #line 10"foo.c" is supposed to be allowed.  */
        !          3766:   if (PEEKC() && !is_space[PEEKC()]) {
        !          3767:     cpp_error (pfile, "invalid format `#line' command");
        !          3768:     goto bad_line_directive;
        !          3769:   }
        !          3770: #endif
        !          3771: 
        !          3772:   token = get_directive_token (pfile);
        !          3773: 
        !          3774:   if (token == CPP_STRING) {
        !          3775:     U_CHAR *fname = pfile->token_buffer + old_written;
        !          3776:     U_CHAR *end_name;
        !          3777:     static HASHNODE *fname_table[FNAME_HASHSIZE];
        !          3778:     HASHNODE *hp, **hash_bucket;
        !          3779:     U_CHAR *p;
        !          3780:     long num_start;
        !          3781:     int fname_length;
        !          3782: 
        !          3783:     /* Turn the file name, which is a character string literal,
        !          3784:        into a null-terminated string.  Do this in place.  */
        !          3785:     end_name = convert_string (pfile, fname, fname, CPP_PWRITTEN (pfile), 1);
        !          3786:     if (end_name == NULL)
        !          3787:     {
        !          3788:        cpp_error (pfile, "invalid format `#line' command");
        !          3789:        goto bad_line_directive;
        !          3790:     }
        !          3791: 
        !          3792:     fname_length = end_name - fname;
        !          3793: 
        !          3794:     num_start = CPP_WRITTEN (pfile);
        !          3795:     token = get_directive_token (pfile);
        !          3796:     if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
        !          3797:       p = pfile->token_buffer + num_start;
        !          3798:       if (CPP_PEDANTIC (pfile))
        !          3799:        cpp_pedwarn (pfile, "garbage at end of `#line' command");
        !          3800: 
        !          3801:       if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
        !          3802:       {
        !          3803:        cpp_error (pfile, "invalid format `#line' command");
        !          3804:        goto bad_line_directive;
        !          3805:       }
        !          3806:       if (*p == '1')
        !          3807:        file_change = enter_file;
        !          3808:       else if (*p == 2)
        !          3809:        file_change = leave_file;
        !          3810:       else if (*p == 3)
        !          3811:        ip->system_header_p = 1;
        !          3812:       else /* if (*p == 4) */
        !          3813:        ip->system_header_p = 2;
        !          3814: 
        !          3815:       CPP_SET_WRITTEN (pfile, num_start);
        !          3816:       token = get_directive_token (pfile);
        !          3817:       p = pfile->token_buffer + num_start;
        !          3818:       if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
        !          3819:        ip->system_header_p = *p == 3 ? 1 : 2;
        !          3820:        token = get_directive_token (pfile);
        !          3821:       }
        !          3822:       if (token != CPP_VSPACE) {
        !          3823:        cpp_error (pfile, "invalid format `#line' command");
        !          3824:        goto bad_line_directive;
        !          3825:       }
        !          3826:     }
        !          3827: 
        !          3828:     hash_bucket =
        !          3829:       &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
        !          3830:     for (hp = *hash_bucket; hp != NULL; hp = hp->next)
        !          3831:       if (hp->length == fname_length &&
        !          3832:          strncmp (hp->value.cpval, fname, fname_length) == 0) {
        !          3833:        ip->nominal_fname = hp->value.cpval;
        !          3834:        break;
        !          3835:       }
        !          3836:     if (hp == 0) {
        !          3837:       /* Didn't find it; cons up a new one.  */
        !          3838:       hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
        !          3839:       hp->next = *hash_bucket;
        !          3840:       *hash_bucket = hp;
        !          3841: 
        !          3842:       hp->length = fname_length;
        !          3843:       ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
        !          3844:       bcopy (fname, hp->value.cpval, fname_length);
        !          3845:     }
        !          3846:   }
        !          3847:   else if (token != CPP_VSPACE && token != CPP_EOF) {
        !          3848:     cpp_error (pfile, "invalid format `#line' command");
        !          3849:     goto bad_line_directive;
        !          3850:   }
        !          3851: 
        !          3852:   ip->lineno = new_lineno;
        !          3853:  bad_line_directive:
        !          3854:   skip_rest_of_line (pfile);
        !          3855:   CPP_SET_WRITTEN (pfile, old_written);
        !          3856:   output_line_command (pfile, 0, file_change);
        !          3857:   return 0;
        !          3858: }
        !          3859: 
        !          3860: /*
        !          3861:  * remove the definition of a symbol from the symbol table.
        !          3862:  * according to un*x /lib/cpp, it is not an error to undef
        !          3863:  * something that has no definitions, so it isn't one here either.
        !          3864:  */
        !          3865: 
        !          3866: static int
        !          3867: do_undef (pfile, keyword, buf, limit)
        !          3868:      cpp_reader *pfile;
        !          3869:      struct directive *keyword;
        !          3870:      U_CHAR *buf, *limit;
        !          3871: {
        !          3872:   int sym_length;
        !          3873:   HASHNODE *hp;
        !          3874:   U_CHAR *orig_buf = buf;
        !          3875: 
        !          3876: #if 0
        !          3877:   /* If this is a precompiler run (with -pcp) pass thru #undef commands.  */
        !          3878:   if (pcp_outfile && keyword)
        !          3879:     pass_thru_directive (buf, limit, pfile, keyword);
        !          3880: #endif
        !          3881: 
        !          3882:   SKIP_WHITE_SPACE (buf);
        !          3883:   sym_length = check_macro_name (pfile, buf, "macro");
        !          3884: 
        !          3885:   while ((hp = cpp_lookup (pfile, buf, sym_length, -1)) != NULL)
        !          3886:     {
        !          3887:       /* If we are generating additional info for debugging (with -g) we
        !          3888:         need to pass through all effective #undef commands.  */
        !          3889:       if (CPP_OPTIONS (pfile)->debug_output && keyword)
        !          3890:        pass_thru_directive (orig_buf, limit, pfile, keyword);
        !          3891:       if (hp->type != T_MACRO)
        !          3892:        cpp_warning (pfile, "undefining `%s'", hp->name);
        !          3893:       delete_macro (hp);
        !          3894:     }
        !          3895: 
        !          3896:   if (CPP_PEDANTIC (pfile)) {
        !          3897:     buf += sym_length;
        !          3898:     SKIP_WHITE_SPACE (buf);
        !          3899:     if (buf != limit)
        !          3900:       cpp_pedwarn (pfile, "garbage after `#undef' directive");
        !          3901:   }
        !          3902:   return 0;
        !          3903: }
        !          3904: 
        !          3905: /*
        !          3906:  * Report an error detected by the program we are processing.
        !          3907:  * Use the text of the line in the error message.
        !          3908:  * (We use error because it prints the filename & line#.)
        !          3909:  */
        !          3910: 
        !          3911: static int
        !          3912: do_error (pfile, keyword, buf, limit)
        !          3913:      cpp_reader *pfile;
        !          3914:      struct directive *keyword;
        !          3915:      U_CHAR *buf, *limit;
        !          3916: {
        !          3917:   int length = limit - buf;
        !          3918:   U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
        !          3919:   bcopy (buf, copy, length);
        !          3920:   copy[length] = 0;
        !          3921:   SKIP_WHITE_SPACE (copy);
        !          3922:   cpp_error (pfile, "#error %s", copy);
        !          3923:   return 0;
        !          3924: }
        !          3925: 
        !          3926: /*
        !          3927:  * Report a warning detected by the program we are processing.
        !          3928:  * Use the text of the line in the warning message, then continue.
        !          3929:  * (We use error because it prints the filename & line#.)
        !          3930:  */
        !          3931: 
        !          3932: static int
        !          3933: do_warning (pfile, keyword, buf, limit)
        !          3934:      cpp_reader *pfile;
        !          3935:      struct directive *keyword;
        !          3936:      U_CHAR *buf, *limit;
        !          3937: {
        !          3938:   int length = limit - buf;
        !          3939:   U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
        !          3940:   bcopy (buf, copy, length);
        !          3941:   copy[length] = 0;
        !          3942:   SKIP_WHITE_SPACE (copy);
        !          3943:   cpp_warning (pfile, "#warning %s", copy);
        !          3944:   return 0;
        !          3945: }
        !          3946: 
        !          3947: /* Remember the name of the current file being read from so that we can
        !          3948:    avoid ever including it again.  */
        !          3949: 
        !          3950: static int
        !          3951: do_once (pfile)
        !          3952:      cpp_reader *pfile;
        !          3953: {
        !          3954:   cpp_buffer *ip = NULL;
        !          3955:   struct file_name_list *new;
        !          3956: 
        !          3957:   for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip))
        !          3958:     {
        !          3959:       if (ip == NULL)
        !          3960:        return 0;
        !          3961:       if (ip->fname != NULL)
        !          3962:        break;
        !          3963:     }
        !          3964: 
        !          3965:     
        !          3966:   new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
        !          3967:   new->next = pfile->dont_repeat_files;
        !          3968:   pfile->dont_repeat_files = new;
        !          3969:   new->fname = savestring (ip->fname);
        !          3970:   new->control_macro = 0;
        !          3971:   new->got_name_map = 0;
        !          3972:   new->c_system_include_path = 0;
        !          3973: 
        !          3974:   return 0;
        !          3975: }
        !          3976: 
        !          3977: /* #ident has already been copied to the output file, so just ignore it.  */
        !          3978: 
        !          3979: static int
        !          3980: do_ident (pfile, keyword, buf, limit)
        !          3981:      cpp_reader *pfile;
        !          3982:      struct directive *keyword;
        !          3983:      U_CHAR *buf, *limit;
        !          3984: {
        !          3985: /*  long old_written = CPP_WRITTEN (pfile);*/
        !          3986:   int len;
        !          3987: 
        !          3988:   /* Allow #ident in system headers, since that's not user's fault.  */
        !          3989:   if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
        !          3990:     cpp_pedwarn (pfile, "ANSI C does not allow `#ident'");
        !          3991: 
        !          3992:   /* Leave rest of line to be read by later calls to cpp_get_token. */
        !          3993: 
        !          3994:   return 0;
        !          3995: }
        !          3996: 
        !          3997: /* #pragma and its argument line have already been copied to the output file.
        !          3998:    Just check for some recognized pragmas that need validation here.  */
        !          3999: 
        !          4000: static int
        !          4001: do_pragma (pfile, keyword, buf, limit)
        !          4002:      cpp_reader *pfile;
        !          4003:      struct directive *keyword;
        !          4004:      U_CHAR *buf, *limit;
        !          4005: {
        !          4006:   while (*buf == ' ' || *buf == '\t')
        !          4007:     buf++;
        !          4008:   if (!strncmp (buf, "once", 4)) {
        !          4009:     /* Allow #pragma once in system headers, since that's not the user's
        !          4010:        fault.  */
        !          4011:     if (!CPP_BUFFER (pfile)->system_header_p)
        !          4012:       cpp_warning (pfile, "`#pragma once' is obsolete");
        !          4013:     do_once (pfile);
        !          4014:   }
        !          4015: 
        !          4016:   if (!strncmp (buf, "implementation", 14)) {
        !          4017:     /* Be quiet about `#pragma implementation' for a file only if it hasn't
        !          4018:        been included yet.  */
        !          4019:     struct file_name_list *ptr;
        !          4020:     U_CHAR *p = buf + 14, *fname, *inc_fname;
        !          4021:     int fname_len;
        !          4022:     SKIP_WHITE_SPACE (p);
        !          4023:     if (*p == '\n' || *p != '\"')
        !          4024:       return 0;
        !          4025: 
        !          4026:     fname = p + 1;
        !          4027:     p = (U_CHAR *) index (fname, '\"');
        !          4028:     fname_len = p != NULL ? p - fname : strlen (fname);
        !          4029:     
        !          4030:     for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) {
        !          4031:       inc_fname = (U_CHAR *) rindex (ptr->fname, '/');
        !          4032:       inc_fname = inc_fname ? inc_fname + 1 : (U_CHAR *) ptr->fname;
        !          4033:       if (inc_fname && !strncmp (inc_fname, fname, fname_len))
        !          4034:        cpp_warning (pfile,
        !          4035:           "`#pragma implementation' for `%s' appears after file is included",
        !          4036:                     fname);
        !          4037:     }
        !          4038:   }
        !          4039: 
        !          4040:   return 0;
        !          4041: }
        !          4042: 
        !          4043: #if 0
        !          4044: /* This was a fun hack, but #pragma seems to start to be useful.
        !          4045:    By failing to recognize it, we pass it through unchanged to cc1.  */
        !          4046: 
        !          4047: /*
        !          4048:  * the behavior of the #pragma directive is implementation defined.
        !          4049:  * this implementation defines it as follows.
        !          4050:  */
        !          4051: 
        !          4052: static int
        !          4053: do_pragma ()
        !          4054: {
        !          4055:   close (0);
        !          4056:   if (open ("/dev/tty", O_RDONLY, 0666) != 0)
        !          4057:     goto nope;
        !          4058:   close (1);
        !          4059:   if (open ("/dev/tty", O_WRONLY, 0666) != 1)
        !          4060:     goto nope;
        !          4061:   execl ("/usr/games/hack", "#pragma", 0);
        !          4062:   execl ("/usr/games/rogue", "#pragma", 0);
        !          4063:   execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
        !          4064:   execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
        !          4065: nope:
        !          4066:   fatal ("You are in a maze of twisty compiler features, all different");
        !          4067: }
        !          4068: #endif
        !          4069: 
        !          4070: /* Just ignore #sccs, on systems where we define it at all.  */
        !          4071: 
        !          4072: static int
        !          4073: do_sccs (pfile, keyword, buf, limit)
        !          4074:      cpp_reader *pfile;
        !          4075:      struct directive *keyword;
        !          4076:      U_CHAR *buf, *limit;
        !          4077: {
        !          4078:   if (CPP_PEDANTIC (pfile))
        !          4079:     cpp_pedwarn (pfile, "ANSI C does not allow `#sccs'");
        !          4080:   return 0;
        !          4081: }
        !          4082: 
        !          4083: /*
        !          4084:  * handle #if command by
        !          4085:  *   1) inserting special `defined' keyword into the hash table
        !          4086:  *     that gets turned into 0 or 1 by special_symbol (thus,
        !          4087:  *     if the luser has a symbol called `defined' already, it won't
        !          4088:  *      work inside the #if command)
        !          4089:  *   2) rescan the input into a temporary output buffer
        !          4090:  *   3) pass the output buffer to the yacc parser and collect a value
        !          4091:  *   4) clean up the mess left from steps 1 and 2.
        !          4092:  *   5) call conditional_skip to skip til the next #endif (etc.),
        !          4093:  *      or not, depending on the value from step 3.
        !          4094:  */
        !          4095: 
        !          4096: static int
        !          4097: do_if (pfile, keyword, buf, limit)
        !          4098:      cpp_reader *pfile;
        !          4099:      struct directive *keyword;
        !          4100:      U_CHAR *buf, *limit;
        !          4101: {
        !          4102:   HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
        !          4103:   conditional_skip (pfile, value == 0, T_IF, NULL_PTR);
        !          4104:   return 0;
        !          4105: }
        !          4106: 
        !          4107: /*
        !          4108:  * handle a #elif directive by not changing  if_stack  either.
        !          4109:  * see the comment above do_else.
        !          4110:  */
        !          4111: 
        !          4112: static int
        !          4113: do_elif (pfile, keyword, buf, limit)
        !          4114:      cpp_reader *pfile;
        !          4115:      struct directive *keyword;
        !          4116:      U_CHAR *buf, *limit;
        !          4117: {
        !          4118:   if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) {
        !          4119:     cpp_error (pfile, "`#elif' not within a conditional");
        !          4120:     return 0;
        !          4121:   } else {
        !          4122:     if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) {
        !          4123:       cpp_error (pfile, "`#elif' after `#else'");
        !          4124: #if 0
        !          4125:       fprintf (stderr, " (matches line %d", pfile->if_stack->lineno);
        !          4126: #endif
        !          4127:       if (pfile->if_stack->fname != NULL && CPP_BUFFER (pfile)->fname != NULL
        !          4128:          && strcmp (pfile->if_stack->fname,
        !          4129:                     CPP_BUFFER (pfile)->nominal_fname) != 0)
        !          4130:        fprintf (stderr, ", file %s", pfile->if_stack->fname);
        !          4131:       fprintf (stderr, ")\n");
        !          4132:     }
        !          4133:     pfile->if_stack->type = T_ELIF;
        !          4134:   }
        !          4135: 
        !          4136:   if (pfile->if_stack->if_succeeded)
        !          4137:     skip_if_group (pfile, 0);
        !          4138:   else {
        !          4139:     HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
        !          4140:     if (value == 0)
        !          4141:       skip_if_group (pfile, 0);
        !          4142:     else {
        !          4143:       ++pfile->if_stack->if_succeeded; /* continue processing input */
        !          4144:       output_line_command (pfile, 1, same_file);
        !          4145:     }
        !          4146:   }
        !          4147:   return 0;
        !          4148: }
        !          4149: 
        !          4150: /*
        !          4151:  * evaluate a #if expression in BUF, of length LENGTH,
        !          4152:  * then parse the result as a C expression and return the value as an int.
        !          4153:  */
        !          4154: static HOST_WIDE_INT
        !          4155: eval_if_expression (pfile, buf, length)
        !          4156:      cpp_reader *pfile;
        !          4157:      U_CHAR *buf;
        !          4158:      int length;
        !          4159: {
        !          4160:   HASHNODE *save_defined;
        !          4161:   HOST_WIDE_INT value;
        !          4162:   long old_written = CPP_WRITTEN (pfile);
        !          4163: 
        !          4164:   save_defined = install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
        !          4165:   pfile->pcp_inside_if = 1;
        !          4166: 
        !          4167:   value = cpp_parse_expr (pfile);
        !          4168:   pfile->pcp_inside_if = 0;
        !          4169:   delete_macro (save_defined); /* clean up special symbol */
        !          4170: 
        !          4171:   CPP_SET_WRITTEN (pfile, old_written); /* Pop */
        !          4172: 
        !          4173:   return value;
        !          4174: }
        !          4175: 
        !          4176: /*
        !          4177:  * routine to handle ifdef/ifndef.  Try to look up the symbol,
        !          4178:  * then do or don't skip to the #endif/#else/#elif depending
        !          4179:  * on what directive is actually being processed.
        !          4180:  */
        !          4181: 
        !          4182: static int
        !          4183: do_xifdef (pfile, keyword, unused1, unused2)
        !          4184:      cpp_reader *pfile;
        !          4185:      struct directive *keyword;
        !          4186:      U_CHAR *unused1, *unused2;
        !          4187: {
        !          4188:   int skip;
        !          4189:   cpp_buffer *ip = CPP_BUFFER (pfile);
        !          4190:   U_CHAR* ident;
        !          4191:   int ident_length;
        !          4192:   enum cpp_token token;
        !          4193:   int start_of_file = 0;
        !          4194:   U_CHAR *control_macro = 0;
        !          4195:   int old_written = CPP_WRITTEN (pfile);
        !          4196: 
        !          4197:   /* Detect a #ifndef at start of file (not counting comments).  */
        !          4198:   if (ip->fname != 0 && keyword->type == T_IFNDEF)
        !          4199:     start_of_file = pfile->only_seen_white == 2;
        !          4200: 
        !          4201:   pfile->no_macro_expand++;
        !          4202:   token = get_directive_token (pfile);
        !          4203:   pfile->no_macro_expand--;
        !          4204: 
        !          4205:   ident = pfile->token_buffer + old_written;
        !          4206:   ident_length = CPP_WRITTEN (pfile) - old_written;
        !          4207:   CPP_SET_WRITTEN (pfile, old_written); /* Pop */
        !          4208: 
        !          4209:   if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
        !          4210:     {
        !          4211:       skip = (keyword->type == T_IFDEF);
        !          4212:       if (! CPP_TRADITIONAL (pfile))
        !          4213:        cpp_pedwarn (pfile, "`#%s' with no argument", keyword->name);
        !          4214:     }
        !          4215:   else if (token == CPP_NAME)
        !          4216:     {
        !          4217:       HASHNODE *hp = cpp_lookup (pfile, ident, ident_length, -1);
        !          4218:       skip = (hp == NULL) ^ (keyword->type == T_IFNDEF);
        !          4219:       if (start_of_file && !skip)
        !          4220:        {
        !          4221:          control_macro = (U_CHAR *) xmalloc (ident_length + 1);
        !          4222:          bcopy (ident, control_macro, ident_length + 1);
        !          4223:        }
        !          4224:     }
        !          4225:   else
        !          4226:     {
        !          4227:       skip = (keyword->type == T_IFDEF);
        !          4228:       if (! CPP_TRADITIONAL (pfile))
        !          4229:        cpp_error (pfile, "`#%s' with invalid argument", keyword->name);
        !          4230:     }
        !          4231: 
        !          4232:   if (!CPP_TRADITIONAL (pfile))
        !          4233:     { int c;
        !          4234:       cpp_skip_hspace (pfile);
        !          4235:       c = PEEKC ();
        !          4236:       if (c != EOF && c != '\n')
        !          4237:        cpp_pedwarn (pfile, "garbage at end of `#%s' argument", keyword->name);
        !          4238:     }
        !          4239:   skip_rest_of_line (pfile);
        !          4240: 
        !          4241: #if 0
        !          4242:     if (pcp_outfile) {
        !          4243:       /* Output a precondition for this macro.  */
        !          4244:       if (hp && hp->value.defn->predefined)
        !          4245:        fprintf (pcp_outfile, "#define %s\n", hp->name);
        !          4246:       else {
        !          4247:        U_CHAR *cp = buf;
        !          4248:        fprintf (pcp_outfile, "#undef ");
        !          4249:        while (is_idchar[*cp]) /* Ick! */
        !          4250:          fputc (*cp++, pcp_outfile);
        !          4251:        putc ('\n', pcp_outfile);
        !          4252:       }
        !          4253: #endif
        !          4254: 
        !          4255:   conditional_skip (pfile, skip, T_IF, control_macro);
        !          4256:   return 0;
        !          4257: }
        !          4258: 
        !          4259: /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
        !          4260:    If this is a #ifndef starting at the beginning of a file,
        !          4261:    CONTROL_MACRO is the macro name tested by the #ifndef.
        !          4262:    Otherwise, CONTROL_MACRO is 0.  */
        !          4263: 
        !          4264: static void
        !          4265: conditional_skip (pfile, skip, type, control_macro)
        !          4266:      cpp_reader *pfile;
        !          4267:      int skip;
        !          4268:      enum node_type type;
        !          4269:      U_CHAR *control_macro;
        !          4270: {
        !          4271:   IF_STACK_FRAME *temp;
        !          4272: 
        !          4273:   temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
        !          4274:   temp->fname = CPP_BUFFER (pfile)->nominal_fname;
        !          4275: #if 0
        !          4276:   temp->lineno = CPP_BUFFER (pfile)->lineno;
        !          4277: #endif
        !          4278:   temp->next = pfile->if_stack;
        !          4279:   temp->control_macro = control_macro;
        !          4280:   pfile->if_stack = temp;
        !          4281: 
        !          4282:   pfile->if_stack->type = type;
        !          4283: 
        !          4284:   if (skip != 0) {
        !          4285:     skip_if_group (pfile, 0);
        !          4286:     return;
        !          4287:   } else {
        !          4288:     ++pfile->if_stack->if_succeeded;
        !          4289:     output_line_command (pfile, 1, same_file);
        !          4290:   }
        !          4291: }
        !          4292: 
        !          4293: /*
        !          4294:  * skip to #endif, #else, or #elif.  adjust line numbers, etc.
        !          4295:  * leaves input ptr at the sharp sign found.
        !          4296:  * If ANY is nonzero, return at next directive of any sort.
        !          4297:  */
        !          4298: static void
        !          4299: skip_if_group (pfile, any)
        !          4300:      cpp_reader *pfile;
        !          4301:      int any;
        !          4302: {
        !          4303:   int c;
        !          4304:   int at_beg_of_line = 1;
        !          4305:   struct directive *kt;
        !          4306:   IF_STACK_FRAME *save_if_stack = pfile->if_stack; /* don't pop past here */
        !          4307: #if 0
        !          4308:   U_CHAR *beg_of_line = bp;
        !          4309: #endif
        !          4310:   register int ident_length;
        !          4311:   U_CHAR *ident, *after_ident;
        !          4312:   struct parse_marker line_start_mark;
        !          4313: 
        !          4314:   parse_set_mark (&line_start_mark, pfile);
        !          4315: 
        !          4316:   if (CPP_OPTIONS (pfile)->output_conditionals) {
        !          4317:     static char failed[] = "#failed\n";
        !          4318:     CPP_PUTS (pfile, failed, sizeof(failed)-1);
        !          4319:     pfile->lineno++;
        !          4320:     output_line_command (pfile, 1, same_file);
        !          4321:   }
        !          4322: 
        !          4323:  beg_of_line:
        !          4324:   if (CPP_OPTIONS (pfile)->output_conditionals)
        !          4325:     {
        !          4326:       cpp_buffer *pbuf = CPP_BUFFER (pfile);
        !          4327:       U_CHAR *start_line = pbuf->buf + line_start_mark.position;
        !          4328:       CPP_PUTS (pfile, start_line, pbuf->cur - start_line);
        !          4329:     }
        !          4330:   parse_move_mark (&line_start_mark, pfile);
        !          4331:   if (!CPP_TRADITIONAL (pfile))
        !          4332:       cpp_skip_hspace (pfile);
        !          4333:   c  = GETC();
        !          4334:   if (c == '#')
        !          4335:     {
        !          4336:       int old_written = CPP_WRITTEN (pfile);
        !          4337:       cpp_skip_hspace (pfile);
        !          4338: 
        !          4339:       parse_name (pfile, GETC());
        !          4340:       ident_length = CPP_WRITTEN (pfile) - old_written;
        !          4341:       ident = pfile->token_buffer + old_written;
        !          4342:       pfile->limit = ident;
        !          4343: #if 0
        !          4344:       if (ident_length == 0)
        !          4345:        goto not_a_directive;
        !          4346: 
        !          4347:       /* Handle # followed by a line number.  */
        !          4348: 
        !          4349:       /* Avoid error for `###' and similar cases unless -pedantic.  */
        !          4350: #endif
        !          4351: 
        !          4352:       for (kt = directive_table; kt->length >= 0; kt++)
        !          4353:        {
        !          4354:          IF_STACK_FRAME *temp;
        !          4355:          if (ident_length == kt->length
        !          4356:              && strncmp (ident, kt->name, kt->length) == 0)
        !          4357:            {
        !          4358:              /* If we are asked to return on next directive, do so now.  */
        !          4359:              if (any)
        !          4360:                goto done;
        !          4361: 
        !          4362:              switch (kt->type)
        !          4363:                {
        !          4364:                case T_IF:
        !          4365:                case T_IFDEF:
        !          4366:                case T_IFNDEF:
        !          4367:                  temp
        !          4368:                    = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
        !          4369:                  temp->next = pfile->if_stack;
        !          4370:                  pfile->if_stack = temp;
        !          4371: #if 0
        !          4372:                  temp->lineno = CPP_BUFFER(pfile)->lineno;
        !          4373: #endif
        !          4374:                  temp->fname = CPP_BUFFER(pfile)->nominal_fname;
        !          4375:                  temp->type = kt->type;
        !          4376:                  break;
        !          4377:                case T_ELSE:
        !          4378:                case T_ENDIF:
        !          4379:                  if (CPP_PEDANTIC (pfile) && pfile->if_stack != save_if_stack)
        !          4380:                    validate_else (pfile,
        !          4381:                                   kt->type == T_ELSE ? "#else" : "#endif");
        !          4382:                case T_ELIF:
        !          4383:                  if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack)
        !          4384:                    {
        !          4385:                      cpp_error (pfile,
        !          4386:                                 "`#%s' not within a conditional", kt->name);
        !          4387:                      break;
        !          4388:                    }
        !          4389:                  else if (pfile->if_stack == save_if_stack)
        !          4390:                    goto done;          /* found what we came for */
        !          4391: 
        !          4392:                  if (kt->type != T_ENDIF)
        !          4393:                    {
        !          4394:                      if (pfile->if_stack->type == T_ELSE)
        !          4395:                        cpp_error (pfile, "`#else' or `#elif' after `#else'");
        !          4396:                      pfile->if_stack->type = kt->type;
        !          4397:                      break;
        !          4398:                    }
        !          4399: 
        !          4400:                  temp = pfile->if_stack;
        !          4401:                  pfile->if_stack = temp->next;
        !          4402:                  free (temp);
        !          4403:                  break;
        !          4404:              default: ;
        !          4405:                }
        !          4406:              break;
        !          4407:            }
        !          4408:          /* Don't let erroneous code go by.  */
        !          4409:          if (kt->length < 0 && !CPP_OPTIONS (pfile)->lang_asm
        !          4410:              && CPP_PEDANTIC (pfile))
        !          4411:            cpp_pedwarn (pfile, "invalid preprocessor directive name");
        !          4412:        }
        !          4413:       c = GETC ();
        !          4414:     }
        !          4415:   /* We're in the middle of a line.  Skip the rest of it. */
        !          4416:   for (;;) {
        !          4417:     switch (c)
        !          4418:       {
        !          4419:        long old;
        !          4420:       case EOF:
        !          4421:        goto done;
        !          4422:       case '/':                        /* possible comment */
        !          4423:        c = skip_comment (pfile, NULL);
        !          4424:        if (c == EOF)
        !          4425:          goto done;
        !          4426:        break;
        !          4427:       case '\"':
        !          4428:       case '\'':
        !          4429:        FORWARD(-1);
        !          4430:        old = CPP_WRITTEN (pfile);
        !          4431:        cpp_get_token (pfile);
        !          4432:        CPP_SET_WRITTEN (pfile, old);
        !          4433:        break;
        !          4434:       case '\\':
        !          4435:        /* Char after backslash loses its special meaning.  */
        !          4436:        if (PEEKC() == '\n')
        !          4437:          FORWARD (1);
        !          4438:        break;
        !          4439:       case '\n':
        !          4440:        goto beg_of_line;
        !          4441:        break;
        !          4442:       }
        !          4443:     c = GETC ();
        !          4444:   }
        !          4445:  done:
        !          4446:   if (CPP_OPTIONS (pfile)->output_conditionals) {
        !          4447:     static char end_failed[] = "#endfailed\n";
        !          4448:     CPP_PUTS (pfile, end_failed, sizeof(end_failed)-1);
        !          4449:     pfile->lineno++;
        !          4450:   }
        !          4451:   pfile->only_seen_white = 1;
        !          4452:   parse_goto_mark (&line_start_mark, pfile);
        !          4453:   parse_clear_mark (&line_start_mark);
        !          4454: }
        !          4455: 
        !          4456: /*
        !          4457:  * handle a #else directive.  Do this by just continuing processing
        !          4458:  * without changing  if_stack ;  this is so that the error message
        !          4459:  * for missing #endif's etc. will point to the original #if.  It
        !          4460:  * is possible that something different would be better.
        !          4461:  */
        !          4462: 
        !          4463: static int
        !          4464: do_else (pfile, keyword, buf, limit)
        !          4465:      cpp_reader *pfile;
        !          4466:      struct directive *keyword;
        !          4467:      U_CHAR *buf, *limit;
        !          4468: {
        !          4469:   cpp_buffer *ip = CPP_BUFFER (pfile);
        !          4470: 
        !          4471:   if (CPP_PEDANTIC (pfile))
        !          4472:     validate_else (pfile, "#else");
        !          4473:   skip_rest_of_line (pfile);
        !          4474: 
        !          4475:   if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) {
        !          4476:     cpp_error (pfile, "`#else' not within a conditional");
        !          4477:     return 0;
        !          4478:   } else {
        !          4479:     /* #ifndef can't have its special treatment for containing the whole file
        !          4480:        if it has a #else clause.  */
        !          4481:     pfile->if_stack->control_macro = 0;
        !          4482: 
        !          4483:     if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) {
        !          4484:       cpp_error (pfile, "`#else' after `#else'");
        !          4485:       fprintf (stderr, " (matches line %d", pfile->if_stack->lineno);
        !          4486:       if (strcmp (pfile->if_stack->fname, ip->nominal_fname) != 0)
        !          4487:        fprintf (stderr, ", file %s", pfile->if_stack->fname);
        !          4488:       fprintf (stderr, ")\n");
        !          4489:     }
        !          4490:     pfile->if_stack->type = T_ELSE;
        !          4491:   }
        !          4492: 
        !          4493:   if (pfile->if_stack->if_succeeded)
        !          4494:     skip_if_group (pfile, 0);
        !          4495:   else {
        !          4496:     ++pfile->if_stack->if_succeeded;   /* continue processing input */
        !          4497:     output_line_command (pfile, 1, same_file);
        !          4498:   }
        !          4499:   return 0;
        !          4500: }
        !          4501: 
        !          4502: /*
        !          4503:  * unstack after #endif command
        !          4504:  */
        !          4505: 
        !          4506: static int
        !          4507: do_endif (pfile, keyword, buf, limit)
        !          4508:      cpp_reader *pfile;
        !          4509:      struct directive *keyword;
        !          4510:      U_CHAR *buf, *limit;
        !          4511: {
        !          4512:   if (CPP_PEDANTIC (pfile))
        !          4513:     validate_else (pfile, "#endif");
        !          4514:   skip_rest_of_line (pfile);
        !          4515: 
        !          4516:   if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack)
        !          4517:     cpp_error (pfile, "unbalanced `#endif'");
        !          4518:   else
        !          4519:     {
        !          4520:       IF_STACK_FRAME *temp = pfile->if_stack;
        !          4521:       pfile->if_stack = temp->next;
        !          4522:       if (temp->control_macro != 0)
        !          4523:        {
        !          4524:          /* This #endif matched a #ifndef at the start of the file.
        !          4525:             See if it is at the end of the file.  */
        !          4526:          struct parse_marker start_mark;
        !          4527:          int c;
        !          4528: 
        !          4529:          parse_set_mark (&start_mark, pfile);
        !          4530: 
        !          4531:          for (;;)
        !          4532:            {
        !          4533:              cpp_skip_hspace (pfile);
        !          4534:              c = GETC ();
        !          4535:              if (c != '\n')
        !          4536:                break;
        !          4537:            }
        !          4538:          parse_goto_mark (&start_mark, pfile);
        !          4539:          parse_clear_mark (&start_mark);
        !          4540: 
        !          4541:          if (c == EOF)
        !          4542:            {
        !          4543:              /* If we get here, this #endif ends a #ifndef
        !          4544:                 that contains all of the file (aside from whitespace).
        !          4545:                 Arrange not to include the file again
        !          4546:                 if the macro that was tested is defined.
        !          4547: 
        !          4548:                 Do not do this for the top-level file in a -include or any
        !          4549:                 file in a -imacros.  */
        !          4550: #if 0
        !          4551: FIXME!
        !          4552:              if (indepth != 0
        !          4553:                  && ! (indepth == 1 && pfile->no_record_file)
        !          4554:                  && ! (pfile->no_record_file && no_output))
        !          4555: #endif
        !          4556:                {
        !          4557:                  struct file_name_list *ifile = pfile->all_include_files;
        !          4558:                  
        !          4559:                  for ( ; ifile != NULL; ifile = ifile->next)
        !          4560:                    {
        !          4561:                      if (!strcmp (ifile->fname, CPP_BUFFER (pfile)->fname))
        !          4562:                        {
        !          4563:                          ifile->control_macro = temp->control_macro;
        !          4564:                          break;
        !          4565:                        }
        !          4566:                    }
        !          4567:                }
        !          4568:            }
        !          4569:         }
        !          4570:       free (temp);
        !          4571:       output_line_command (pfile, 1, same_file);
        !          4572:     }
        !          4573:   return 0;
        !          4574: }
        !          4575: 
        !          4576: /* When an #else or #endif is found while skipping failed conditional,
        !          4577:    if -pedantic was specified, this is called to warn about text after
        !          4578:    the command name.  P points to the first char after the command name.  */
        !          4579: 
        !          4580: static void
        !          4581: validate_else (pfile, directive)
        !          4582:      cpp_reader *pfile;
        !          4583:      char *directive;
        !          4584: {
        !          4585:   int c;
        !          4586:   cpp_skip_hspace (pfile);
        !          4587:   c = PEEKC ();
        !          4588:   if (c != EOF && c != '\n')
        !          4589:     cpp_pedwarn (pfile,
        !          4590:                 "text following `%s' violates ANSI standard", directive);
        !          4591: }
        !          4592: 
        !          4593: /* Get the next token, and add it to the text in pfile->token_buffer.
        !          4594:    Return the kind of token we got. */
        !          4595:   
        !          4596: 
        !          4597: enum cpp_token
        !          4598: cpp_get_token (pfile)
        !          4599:      cpp_reader *pfile;
        !          4600: {
        !          4601:   register int c, c2, c3;
        !          4602:   long old_written;
        !          4603:   long start_line, start_column;
        !          4604:   enum cpp_token token;
        !          4605:   struct cpp_options *opts = CPP_OPTIONS (pfile);
        !          4606:   CPP_BUFFER (pfile)->prev = CPP_BUFFER (pfile)->cur;
        !          4607:  get_next:
        !          4608:   c = GETC();
        !          4609:   if (c == EOF)
        !          4610:     {
        !          4611:     handle_eof:
        !          4612:       if (CPP_BUFFER (pfile)->seen_eof)
        !          4613:        {
        !          4614:          if (cpp_pop_buffer (pfile) != CPP_NULL_BUFFER (pfile))
        !          4615:            goto get_next;
        !          4616:          else
        !          4617:            return CPP_EOF;
        !          4618:        }
        !          4619:       else
        !          4620:        {
        !          4621:          cpp_buffer *next_buf
        !          4622:            = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
        !          4623:          CPP_BUFFER (pfile)->seen_eof = 1;
        !          4624:          if (CPP_BUFFER (pfile)->nominal_fname && next_buf != 0)
        !          4625:            {
        !          4626:              /* We're about to return from an #include file.
        !          4627:                 Emit #line information now (as part of the CPP_POP) result.
        !          4628:                 But the #line refers to the file we will pop to. */
        !          4629:              cpp_buffer *cur_buffer = CPP_BUFFER (pfile);
        !          4630:              CPP_BUFFER (pfile) = next_buf;
        !          4631:              pfile->input_stack_listing_current = 0;
        !          4632:              output_line_command (pfile, 0, leave_file);
        !          4633:              CPP_BUFFER (pfile) = cur_buffer;
        !          4634:            }
        !          4635:          return CPP_POP;
        !          4636:        }
        !          4637:     }
        !          4638:   else
        !          4639:     {
        !          4640:       switch (c)
        !          4641:        {
        !          4642:          long newlines;
        !          4643:          struct parse_marker start_mark;
        !          4644:        case '/':
        !          4645:          if (PEEKC () == '=')
        !          4646:            goto op2;
        !          4647:          if (opts->put_out_comments)
        !          4648:            parse_set_mark (&start_mark, pfile);
        !          4649:          newlines = 0;
        !          4650:          cpp_buf_line_and_col (cpp_file_buffer (pfile),
        !          4651:                                &start_line, &start_column);
        !          4652:          c = skip_comment (pfile, &newlines);
        !          4653:          if (opts->put_out_comments && (c == '/' || c == EOF))
        !          4654:            parse_clear_mark (&start_mark);
        !          4655:          if (c == '/')
        !          4656:            goto randomchar;
        !          4657:          if (c == EOF)
        !          4658:            {
        !          4659:              cpp_error_with_line (pfile, start_line, start_column,
        !          4660:                                   "unterminated comment");
        !          4661:              goto handle_eof;
        !          4662:            }
        !          4663:          c = '/';  /* Initial letter of comment. */
        !          4664:        return_comment:
        !          4665:          /* Comments are equivalent to spaces.
        !          4666:             For -traditional, a comment is equivalent to nothing.  */
        !          4667:          if (opts->put_out_comments)
        !          4668:            {
        !          4669:              cpp_buffer *pbuf = CPP_BUFFER (pfile);
        !          4670:              long dummy;
        !          4671:              U_CHAR *start = pbuf->buf + start_mark.position;
        !          4672:              int len = pbuf->cur - start;
        !          4673:              CPP_RESERVE(pfile, 1 + len);
        !          4674:              CPP_PUTC_Q (pfile, c);
        !          4675:              CPP_PUTS_Q (pfile, start, len);
        !          4676:              pfile->lineno += newlines;
        !          4677:              parse_clear_mark (&start_mark);
        !          4678:              return CPP_COMMENT;
        !          4679:            }
        !          4680:          else if (CPP_TRADITIONAL (pfile))
        !          4681:            {
        !          4682:              return CPP_COMMENT;
        !          4683:            }
        !          4684:          else
        !          4685:            {
        !          4686: #if 0
        !          4687:              /* This may not work if cpp_get_token is called recursively,
        !          4688:                 since many places look for horizontal space. */
        !          4689:              if (newlines)
        !          4690:                {
        !          4691:                  /* Copy the newlines into the output buffer, in order to
        !          4692:                     avoid the pain of a #line every time a multiline comment
        !          4693:                     is seen.  */
        !          4694:                  CPP_RESERVE(pfile, newlines);
        !          4695:                  while (--newlines >= 0)
        !          4696:                    {
        !          4697:                      CPP_PUTC_Q (pfile, '\n');
        !          4698:                      pfile->lineno++;
        !          4699:                    }
        !          4700:                  return CPP_VSPACE;
        !          4701:                }
        !          4702: #endif
        !          4703:              CPP_RESERVE(pfile, 1);
        !          4704:              CPP_PUTC_Q (pfile, ' ');
        !          4705:              return CPP_HSPACE;
        !          4706:            }
        !          4707: #if 0
        !          4708:          if (opts->for_lint) {
        !          4709:            U_CHAR *argbp;
        !          4710:            int cmdlen, arglen;
        !          4711:            char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
        !          4712:            
        !          4713:            if (lintcmd != NULL) {
        !          4714:              /* I believe it is always safe to emit this newline: */
        !          4715:              obp[-1] = '\n';
        !          4716:              bcopy ("#pragma lint ", (char *) obp, 13);
        !          4717:              obp += 13;
        !          4718:              bcopy (lintcmd, (char *) obp, cmdlen);
        !          4719:              obp += cmdlen;
        !          4720: 
        !          4721:              if (arglen != 0) {
        !          4722:                *(obp++) = ' ';
        !          4723:                bcopy (argbp, (char *) obp, arglen);
        !          4724:                obp += arglen;
        !          4725:              }
        !          4726: 
        !          4727:              /* OK, now bring us back to the state we were in before we entered
        !          4728:                 this branch.  We need #line b/c the newline for the pragma
        !          4729:                 could fuck things up. */
        !          4730:              output_line_command (pfile, 0, same_file);
        !          4731:              *(obp++) = ' ';   /* just in case, if comments are copied thru */
        !          4732:              *(obp++) = '/';
        !          4733:            }
        !          4734:          }
        !          4735: #endif
        !          4736: 
        !          4737:        case '#':
        !          4738: #if 0
        !          4739:          /* If this is expanding a macro definition, don't recognize
        !          4740:             preprocessor directives.  */
        !          4741:          if (ip->macro != 0)
        !          4742:            goto randomchar;
        !          4743:          /* If this is expand_into_temp_buffer, recognize them
        !          4744:             only after an actual newline at this level,
        !          4745:             not at the beginning of the input level.  */
        !          4746:          if (ip->fname == 0 && beg_of_line == ip->buf)
        !          4747:            goto randomchar;
        !          4748:          if (ident_length)
        !          4749:            goto specialchar;
        !          4750: #endif
        !          4751: 
        !          4752:          if (!pfile->only_seen_white)
        !          4753:            goto randomchar;
        !          4754:          if (handle_directive (pfile))
        !          4755:            return CPP_DIRECTIVE;
        !          4756:          pfile->only_seen_white = 0;
        !          4757:          return CPP_OTHER;
        !          4758: 
        !          4759:        case '\"':
        !          4760:        case '\'':
        !          4761:          /* A single quoted string is treated like a double -- some
        !          4762:             programs (e.g., troff) are perverse this way */
        !          4763:          cpp_buf_line_and_col (cpp_file_buffer (pfile),
        !          4764:                                &start_line, &start_column);
        !          4765:          old_written = CPP_WRITTEN (pfile);
        !          4766:        string:
        !          4767:          CPP_PUTC (pfile, c);
        !          4768:          while (1)
        !          4769:            {
        !          4770:              int cc = GETC();
        !          4771:              if (cc == EOF)
        !          4772:                {
        !          4773:                  if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
        !          4774:                    {
        !          4775:                      /* try harder: this string crosses a macro expansion
        !          4776:                         boundary.  This can happen naturally if -traditional.
        !          4777:                         Otherwise, only -D can make a macro with an unmatched
        !          4778:                         quote.  */
        !          4779:                        cpp_buffer *next_buf
        !          4780:                            = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
        !          4781:                        (*CPP_BUFFER (pfile)->cleanup)
        !          4782:                            (CPP_BUFFER (pfile), pfile);
        !          4783:                        CPP_BUFFER (pfile) = next_buf;
        !          4784:                        continue;
        !          4785:                    }
        !          4786:                  if (!CPP_TRADITIONAL (pfile))
        !          4787:                    {
        !          4788:                      cpp_error_with_line (pfile, start_line, start_column,
        !          4789:                              "unterminated string or character constant");
        !          4790:                      if (pfile->multiline_string_line != start_line
        !          4791:                          && pfile->multiline_string_line != 0)
        !          4792:                        cpp_error_with_line (pfile,
        !          4793:                                             pfile->multiline_string_line, -1,
        !          4794:                               "possible real start of unterminated constant");
        !          4795:                      pfile->multiline_string_line = 0;
        !          4796:                    }
        !          4797:                  break;
        !          4798:                }
        !          4799:              CPP_PUTC (pfile, cc);
        !          4800:              switch (cc)
        !          4801:                {
        !          4802:                case '\n':
        !          4803:                  /* Traditionally, end of line ends a string constant with
        !          4804:                 no error.  So exit the loop and record the new line.  */
        !          4805:                  if (CPP_TRADITIONAL (pfile))
        !          4806:                    goto while2end;
        !          4807:                  if (c == '\'')
        !          4808:                    {
        !          4809:                      cpp_error_with_line (pfile, start_line, start_column,
        !          4810:                                           "unterminated character constant");
        !          4811:                      goto while2end;
        !          4812:                    }
        !          4813:                  if (CPP_PEDANTIC (pfile)
        !          4814:                      && pfile->multiline_string_line == 0)
        !          4815:                    {
        !          4816:                      cpp_pedwarn_with_line (pfile, start_line, start_column,
        !          4817:                               "string constant runs past end of line");
        !          4818:                    }
        !          4819:                  if (pfile->multiline_string_line == 0)
        !          4820:                    pfile->multiline_string_line = start_line;
        !          4821:                  break;
        !          4822:                
        !          4823:                case '\\':
        !          4824:                  cc = GETC();
        !          4825:                  if (cc == '\n')
        !          4826:                    {
        !          4827:                      /* Backslash newline is replaced by nothing at all. */
        !          4828:                      CPP_ADJUST_WRITTEN (pfile, -1);
        !          4829:                      pfile->lineno++;
        !          4830:                    }
        !          4831:                  else
        !          4832:                    {
        !          4833:                      /* ANSI stupidly requires that in \\ the second \
        !          4834:                         is *not* prevented from combining with a newline.  */
        !          4835:                      NEWLINE_FIX1(cc);
        !          4836:                      if (cc != EOF)
        !          4837:                        CPP_PUTC (pfile, cc);
        !          4838:                    }
        !          4839:                  break;
        !          4840: 
        !          4841:                case '\"':
        !          4842:                case '\'':
        !          4843:                  if (cc == c)
        !          4844:                    goto while2end;
        !          4845:                  break;
        !          4846:                }
        !          4847:            }
        !          4848:        while2end:
        !          4849:          pfile->lineno += count_newlines (pfile->token_buffer + old_written,
        !          4850:                                           CPP_PWRITTEN (pfile));
        !          4851:          pfile->only_seen_white = 0;
        !          4852:          return c == '\'' ? CPP_CHAR : CPP_STRING;
        !          4853: 
        !          4854:        case '$':
        !          4855:          if (!opts->dollars_in_ident)
        !          4856:            goto randomchar;
        !          4857:          goto letter;
        !          4858: 
        !          4859:        case ':':
        !          4860:          if (opts->cplusplus && PEEKC () == ':')
        !          4861:            goto op2;
        !          4862:          goto randomchar;
        !          4863: 
        !          4864:        case '&':
        !          4865:        case '+':
        !          4866:        case '|':
        !          4867:          NEWLINE_FIX;
        !          4868:          c2 = PEEKC ();
        !          4869:          if (c2 == c || c2 == '=')
        !          4870:            goto op2;
        !          4871:          goto randomchar;
        !          4872: 
        !          4873:        case '*':
        !          4874:        case '!':
        !          4875:        case '%':
        !          4876:        case '=':
        !          4877:        case '^':
        !          4878:          NEWLINE_FIX;
        !          4879:          if (PEEKC () == '=')
        !          4880:            goto op2;
        !          4881:          goto randomchar;
        !          4882: 
        !          4883:        case '-':
        !          4884:          NEWLINE_FIX;
        !          4885:          c2 = PEEKC ();
        !          4886:          if (c2 == '-' && opts->chill)
        !          4887:            {
        !          4888:              /* Chill style comment */
        !          4889:              if (opts->put_out_comments)
        !          4890:                parse_set_mark (&start_mark, pfile);
        !          4891:              FORWARD(1);  /* Skip second '-'. */
        !          4892:              for (;;)
        !          4893:                {
        !          4894:                  c = GETC ();
        !          4895:                  if (c == EOF)
        !          4896:                    break;
        !          4897:                  if (c == '\n')
        !          4898:                    {
        !          4899:                      /* Don't consider final '\n' to be part of comment. */
        !          4900:                      FORWARD(-1);
        !          4901:                      break;
        !          4902:                    }
        !          4903:                }
        !          4904:              c = '-';
        !          4905:              goto return_comment;
        !          4906:            }
        !          4907:          if (c2 == '-' || c2 == '=' || c2 == '>')
        !          4908:            goto op2;
        !          4909:          goto randomchar;
        !          4910: 
        !          4911:        case '<':
        !          4912:          if (pfile->parsing_include_directive)
        !          4913:            {
        !          4914:              for (;;)
        !          4915:                {
        !          4916:                  CPP_PUTC (pfile, c);
        !          4917:                  if (c == '>')
        !          4918:                    break;
        !          4919:                  c = GETC ();
        !          4920:                  NEWLINE_FIX1 (c);
        !          4921:                  if (c == '\n' || c == EOF)
        !          4922:                    {
        !          4923:                      cpp_error (pfile,
        !          4924:                                 "missing '>' in `#include <FILENAME>'");
        !          4925:                      break;
        !          4926:                    }
        !          4927:                }
        !          4928:              return CPP_STRING;
        !          4929:            }
        !          4930:          /* else fall through */
        !          4931:        case '>':
        !          4932:          NEWLINE_FIX;
        !          4933:          c2 = PEEKC ();
        !          4934:          if (c2 == '=')
        !          4935:            goto op2;
        !          4936:          if (c2 != c)
        !          4937:            goto randomchar;
        !          4938:          FORWARD(1);
        !          4939:          CPP_RESERVE (pfile, 4);
        !          4940:          CPP_PUTC (pfile, c);
        !          4941:          CPP_PUTC (pfile, c2);
        !          4942:          NEWLINE_FIX;
        !          4943:          c3 = PEEKC ();
        !          4944:          if (c3 == '=')
        !          4945:            CPP_PUTC_Q (pfile, GETC ());
        !          4946:          CPP_NUL_TERMINATE_Q (pfile);
        !          4947:          pfile->only_seen_white = 0;
        !          4948:          return CPP_OTHER;
        !          4949: 
        !          4950:        case '@':
        !          4951:          if (CPP_BUFFER (pfile)->has_escapes)
        !          4952:            {
        !          4953:              c = GETC ();
        !          4954:              if (c == '-')
        !          4955:                {
        !          4956:                  if (pfile->output_escapes)
        !          4957:                    CPP_PUTS (pfile, "@-", 2);
        !          4958:                  parse_name (pfile, GETC ());
        !          4959:                  return CPP_NAME;
        !          4960:                }
        !          4961:              else if (is_space [c])
        !          4962:                {
        !          4963:                  CPP_RESERVE (pfile, 2);
        !          4964:                  if (pfile->output_escapes)
        !          4965:                    CPP_PUTC_Q (pfile, '@');
        !          4966:                  CPP_PUTC_Q (pfile, c);
        !          4967:                  return CPP_HSPACE;
        !          4968:                }
        !          4969:            }
        !          4970:          if (pfile->output_escapes)
        !          4971:            {
        !          4972:              CPP_PUTS (pfile, "@@", 2);
        !          4973:              return CPP_OTHER;
        !          4974:            }
        !          4975:          goto randomchar;
        !          4976: 
        !          4977:        case '.':
        !          4978:          NEWLINE_FIX;
        !          4979:          c2 = PEEKC ();
        !          4980:          if (isdigit(c2))
        !          4981:            {
        !          4982:              CPP_RESERVE(pfile, 2);
        !          4983:              CPP_PUTC_Q (pfile, '.');
        !          4984:              c = GETC ();
        !          4985:              goto number;
        !          4986:            }
        !          4987:          /* FIXME - misses the case "..\\\n." */
        !          4988:          if (c2 == '.' && PEEKN(1) == '.')
        !          4989:            {
        !          4990:              CPP_RESERVE(pfile, 4);
        !          4991:              CPP_PUTC_Q (pfile, '.');
        !          4992:              CPP_PUTC_Q (pfile, '.');
        !          4993:              CPP_PUTC_Q (pfile, '.');
        !          4994:              FORWARD (2);
        !          4995:              CPP_NUL_TERMINATE_Q (pfile);
        !          4996:              pfile->only_seen_white = 0;
        !          4997:              return CPP_3DOTS;
        !          4998:            }
        !          4999:          goto randomchar;
        !          5000: 
        !          5001:        op2:
        !          5002:          token = CPP_OTHER;
        !          5003:          pfile->only_seen_white = 0;
        !          5004:         op2any:
        !          5005:          CPP_RESERVE(pfile, 3);
        !          5006:          CPP_PUTC_Q (pfile, c);
        !          5007:          CPP_PUTC_Q (pfile, GETC ());
        !          5008:          CPP_NUL_TERMINATE_Q (pfile);
        !          5009:          return token;
        !          5010: 
        !          5011:        case 'L':
        !          5012:          NEWLINE_FIX;
        !          5013:          c2 = PEEKC ();
        !          5014:          if ((c2 == '\'' || c2 == '\"') && !CPP_TRADITIONAL (pfile))
        !          5015:            {
        !          5016:              CPP_PUTC (pfile, c);
        !          5017:              c = GETC ();
        !          5018:              goto string;
        !          5019:            }
        !          5020:          goto letter;
        !          5021: 
        !          5022:        case '0': case '1': case '2': case '3': case '4':
        !          5023:        case '5': case '6': case '7': case '8': case '9':
        !          5024:        number:
        !          5025:          c2  = '.';
        !          5026:          for (;;)
        !          5027:            {
        !          5028:              CPP_RESERVE (pfile, 2);
        !          5029:              CPP_PUTC_Q (pfile, c);
        !          5030:              NEWLINE_FIX;
        !          5031:              c = PEEKC ();
        !          5032:              if (c == EOF)
        !          5033:                break;
        !          5034:              if (!is_idchar[c] && c != '.'
        !          5035:                  && ((c2 != 'e' && c2 != 'E') || (c != '+' && c != '-')))
        !          5036:                break;
        !          5037:              FORWARD(1);
        !          5038:              c2= c;
        !          5039:            }
        !          5040:          CPP_NUL_TERMINATE_Q (pfile);
        !          5041:          pfile->only_seen_white = 0;
        !          5042:          return CPP_NUMBER;
        !          5043:        case 'b': case 'c': case 'd': case 'h': case 'o':
        !          5044:        case 'B': case 'C': case 'D': case 'H': case 'O':
        !          5045:          if (opts->chill && PEEKC () == '\'')
        !          5046:            {
        !          5047:              pfile->only_seen_white = 0;
        !          5048:              CPP_RESERVE (pfile, 2);
        !          5049:              CPP_PUTC_Q (pfile, c);
        !          5050:              CPP_PUTC_Q (pfile, '\'');
        !          5051:              FORWARD(1);
        !          5052:              for (;;)
        !          5053:                {
        !          5054:                  c = GETC();
        !          5055:                  if (c == EOF)
        !          5056:                    goto chill_number_eof;
        !          5057:                  if (!is_idchar[c])
        !          5058:                    {
        !          5059:                      if (c == '\\' && PEEKC() == '\n')
        !          5060:                        {
        !          5061:                          FORWARD(2);
        !          5062:                          continue;
        !          5063:                        }
        !          5064:                      break;
        !          5065:                    }
        !          5066:                  CPP_PUTC (pfile, c);
        !          5067:                }
        !          5068:              if (c == '\'')
        !          5069:                {
        !          5070:                  CPP_RESERVE (pfile, 2);
        !          5071:                  CPP_PUTC_Q (pfile, c);
        !          5072:                  CPP_NUL_TERMINATE_Q (pfile);
        !          5073:                  return CPP_STRING;
        !          5074:                }
        !          5075:              else
        !          5076:                {
        !          5077:                  FORWARD(-1);
        !          5078:                chill_number_eof:
        !          5079:                  CPP_NUL_TERMINATE (pfile);
        !          5080:                  return CPP_NUMBER;
        !          5081:                }
        !          5082:            }
        !          5083:          else
        !          5084:            goto letter;
        !          5085:        case '_':
        !          5086:        case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
        !          5087:        case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
        !          5088:        case 'r': case 's': case 't': case 'u': case 'v': case 'w':
        !          5089:        case 'x': case 'y': case 'z':
        !          5090:        case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
        !          5091:        case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
        !          5092:        case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
        !          5093:        case 'Y': case 'Z':
        !          5094:         letter:
        !          5095:           {
        !          5096:            HASHNODE *hp;
        !          5097:            unsigned char *ident;
        !          5098:            int before_name_written = CPP_WRITTEN (pfile);
        !          5099:            int ident_len;
        !          5100:            parse_name (pfile, c);
        !          5101:            pfile->only_seen_white = 0;
        !          5102:            if (pfile->no_macro_expand)
        !          5103:              return CPP_NAME;
        !          5104:            ident = pfile->token_buffer + before_name_written;
        !          5105:            ident_len = CPP_PWRITTEN (pfile) - ident;
        !          5106:            hp = cpp_lookup (pfile, ident, ident_len, -1);
        !          5107:            if (!hp)
        !          5108:              return CPP_NAME;
        !          5109:            if (hp->type == T_DISABLED)
        !          5110:              {
        !          5111:                if (pfile->output_escapes)
        !          5112:                  { /* Return "@-IDENT", followed by '\0'. */
        !          5113:                    int i;
        !          5114:                    CPP_RESERVE (pfile, 3);
        !          5115:                    ident = pfile->token_buffer + before_name_written;
        !          5116:                    CPP_ADJUST_WRITTEN (pfile, 2);
        !          5117:                    for (i = ident_len; i >= 0; i--) ident[i+2] = ident[i];
        !          5118:                    ident[0] = '@';
        !          5119:                    ident[1] = '-';
        !          5120:                  }
        !          5121:                return CPP_NAME;
        !          5122:              }
        !          5123: 
        !          5124:            /* If macro wants an arglist, verify that a '(' follows.
        !          5125:               first skip all whitespace, copying it to the output
        !          5126:               after the macro name.  Then, if there is no '(',
        !          5127:               decide this is not a macro call and leave things that way.  */
        !          5128:            if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
        !          5129:            {
        !          5130:              struct parse_marker macro_mark;
        !          5131:              int is_macro_call;
        !          5132:              while (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
        !          5133:                {
        !          5134:                  cpp_buffer *next_buf;
        !          5135:                  cpp_skip_hspace (pfile);
        !          5136:                  if (PEEKC () != EOF)
        !          5137:                    break;
        !          5138:                  next_buf = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
        !          5139:                  (*CPP_BUFFER (pfile)->cleanup) (CPP_BUFFER (pfile), pfile);
        !          5140:                  CPP_BUFFER (pfile) = next_buf;
        !          5141:                }
        !          5142:              parse_set_mark (&macro_mark, pfile);
        !          5143:              for (;;)
        !          5144:                {
        !          5145:                  cpp_skip_hspace (pfile);
        !          5146:                  c = PEEKC ();
        !          5147:                  is_macro_call = c == '(';
        !          5148:                  if (c != '\n')
        !          5149:                    break;
        !          5150:                  FORWARD (1);
        !          5151:                }
        !          5152:              if (!is_macro_call)
        !          5153:                parse_goto_mark (&macro_mark, pfile);
        !          5154:              parse_clear_mark (&macro_mark);
        !          5155:              if (!is_macro_call)
        !          5156:                return CPP_NAME;
        !          5157:            }
        !          5158:            /* This is now known to be a macro call. */
        !          5159: 
        !          5160:            /* it might not actually be a macro.  */
        !          5161:            if (hp->type != T_MACRO) {
        !          5162:              int xbuf_len;  U_CHAR *xbuf;
        !          5163:              CPP_SET_WRITTEN (pfile, before_name_written);
        !          5164:              special_symbol (hp, pfile);
        !          5165:              xbuf_len = CPP_WRITTEN (pfile) - before_name_written;
        !          5166:              xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
        !          5167:              CPP_SET_WRITTEN (pfile, before_name_written);
        !          5168:              bcopy (CPP_PWRITTEN (pfile), xbuf, xbuf_len + 1);
        !          5169:              push_macro_expansion (pfile, xbuf, xbuf_len, hp);
        !          5170:            }
        !          5171:            else
        !          5172:              {
        !          5173:                /* Expand the macro, reading arguments as needed,
        !          5174:                   and push the expansion on the input stack.  */
        !          5175:                macroexpand (pfile, hp);
        !          5176:                CPP_SET_WRITTEN (pfile, before_name_written);
        !          5177:              }
        !          5178: 
        !          5179:            /* An extra "@ " is added to the end of a macro expansion
        !          5180:               to prevent accidental token pasting.  We prefer to avoid
        !          5181:               unneeded extra spaces (for the sake of cpp-using tools like
        !          5182:               imake).  Here we remove the space if it is safe to do so. */
        !          5183:            if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
        !          5184:                && pfile->buffer->rlimit[-2] == '@'
        !          5185:                && pfile->buffer->rlimit[-1] == ' ')
        !          5186:              {
        !          5187:                int c1 = pfile->buffer->rlimit[-3];
        !          5188:                int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile)));
        !          5189:                if (c2 == EOF || ! unsafe_chars (c1, c2))
        !          5190:                  pfile->buffer->rlimit -= 2;
        !          5191:              }
        !          5192:          }
        !          5193:          goto get_next;
        !          5194: 
        !          5195:        case ' ':  case '\t':  case '\v':  case '\r':
        !          5196:          for (;;)
        !          5197:            {
        !          5198:              CPP_PUTC (pfile, c);
        !          5199:              c = PEEKC ();
        !          5200:              if (c == EOF || !is_hor_space[c])
        !          5201:                break;
        !          5202:              FORWARD(1);
        !          5203:            }
        !          5204:          return CPP_HSPACE;
        !          5205: 
        !          5206:         case '\\':
        !          5207:          c2 = PEEKC ();
        !          5208:          if (c2 != '\n')
        !          5209:            goto randomchar;
        !          5210:          token = CPP_HSPACE;
        !          5211:          goto op2any;
        !          5212: 
        !          5213:        case '\n':
        !          5214:          CPP_PUTC (pfile, c);
        !          5215:          if (pfile->only_seen_white == 0)
        !          5216:            pfile->only_seen_white = 1;
        !          5217:          pfile->lineno++;
        !          5218:          output_line_command (pfile, 1, same_file);
        !          5219:          return CPP_VSPACE;
        !          5220: 
        !          5221:        case '(': token = CPP_LPAREN;    goto char1;
        !          5222:        case ')': token = CPP_RPAREN;    goto char1;
        !          5223:        case '{': token = CPP_LBRACE;    goto char1;
        !          5224:        case '}': token = CPP_RBRACE;    goto char1;
        !          5225:        case ',': token = CPP_COMMA;     goto char1;
        !          5226:        case ';': token = CPP_SEMICOLON; goto char1;
        !          5227: 
        !          5228:        randomchar:
        !          5229:        default:
        !          5230:          token = CPP_OTHER;
        !          5231:        char1:
        !          5232:          pfile->only_seen_white = 0;
        !          5233:          CPP_PUTC (pfile, c);
        !          5234:          return token;
        !          5235:        }
        !          5236:     }
        !          5237: }
        !          5238: 
        !          5239: /* Like cpp_get_token, but skip spaces and comments. */
        !          5240: enum cpp_token
        !          5241: cpp_get_non_space_token (pfile)
        !          5242:      cpp_reader *pfile;
        !          5243: {
        !          5244:   int old_written = CPP_WRITTEN (pfile);
        !          5245:   for (;;)
        !          5246:     {
        !          5247:       enum cpp_token token = cpp_get_token (pfile);
        !          5248:       if (token != CPP_COMMENT && token != CPP_POP
        !          5249:          && token != CPP_HSPACE && token != CPP_VSPACE)
        !          5250:        return token;
        !          5251:       CPP_SET_WRITTEN (pfile, old_written);
        !          5252:     }
        !          5253: }
        !          5254: 
        !          5255: /* Parse an identifier starting with C. */
        !          5256: 
        !          5257: int
        !          5258: parse_name (pfile, c)
        !          5259:      cpp_reader *pfile; int c;
        !          5260: {
        !          5261:   for (;;)
        !          5262:   {
        !          5263:       if (! is_idchar[c])
        !          5264:       {
        !          5265:          if (c == '\\' && PEEKC() == '\n')
        !          5266:          {
        !          5267:              FORWARD(2);
        !          5268:              continue;
        !          5269:          }
        !          5270:          FORWARD (-1);
        !          5271:          break;
        !          5272:       }
        !          5273: 
        !          5274:       CPP_RESERVE(pfile, 2); /* One more for final NUL. */
        !          5275:       CPP_PUTC_Q (pfile, c);
        !          5276:       c = GETC();
        !          5277:       if (c == EOF)
        !          5278:        break;
        !          5279:   }
        !          5280:   CPP_NUL_TERMINATE_Q (pfile);
        !          5281:   return 1;
        !          5282: }
        !          5283: 
        !          5284: 
        !          5285: /* Maintain and search list of included files, for #import.  */
        !          5286: 
        !          5287: /* Hash a file name for import_hash_table.  */
        !          5288: 
        !          5289: static int 
        !          5290: import_hash (f)
        !          5291:      char *f;
        !          5292: {
        !          5293:   int val = 0;
        !          5294: 
        !          5295:   while (*f) val += *f++;
        !          5296:   return (val%IMPORT_HASH_SIZE);
        !          5297: }
        !          5298: 
        !          5299: /* Search for file FILENAME in import_hash_table.
        !          5300:    Return -2 if found, either a matching name or a matching inode.
        !          5301:    Otherwise, open the file and return a file descriptor if successful
        !          5302:    or -1 if unsuccessful.  */
        !          5303: 
        !          5304: static int
        !          5305: lookup_import (pfile, filename, searchptr)
        !          5306:      cpp_reader *pfile;
        !          5307:      char *filename;
        !          5308:      struct file_name_list *searchptr;
        !          5309: {
        !          5310:   struct import_file *i;
        !          5311:   int h;
        !          5312:   int hashval;
        !          5313:   struct stat sb;
        !          5314:   int fd;
        !          5315: 
        !          5316:   hashval = import_hash (filename);
        !          5317: 
        !          5318:   /* Attempt to find file in list of already included files */
        !          5319:   i = pfile->import_hash_table[hashval];
        !          5320: 
        !          5321:   while (i) {
        !          5322:     if (!strcmp (filename, i->name))
        !          5323:       return -2;               /* return found */
        !          5324:     i = i->next;
        !          5325:   }
        !          5326:   /* Open it and try a match on inode/dev */
        !          5327:   fd = open_include_file (pfile, filename, searchptr);
        !          5328:   if (fd < 0)
        !          5329:     return fd;
        !          5330:   fstat (fd, &sb);
        !          5331:   for (h = 0; h < IMPORT_HASH_SIZE; h++) {
        !          5332:     i = pfile->import_hash_table[h];
        !          5333:     while (i) {
        !          5334:       /* Compare the inode and the device.
        !          5335:         Supposedly on some systems the inode is not a scalar.  */
        !          5336:       if (!bcmp ((char *) &i->inode, (char *) &sb.st_ino, sizeof (sb.st_ino))
        !          5337:          && i->dev == sb.st_dev) {
        !          5338:         close (fd);
        !          5339:         return -2;             /* return found */
        !          5340:       }
        !          5341:       i = i->next;
        !          5342:     }
        !          5343:   }
        !          5344:   return fd;                   /* Not found, return open file */
        !          5345: }
        !          5346: 
        !          5347: /* Add the file FNAME, open on descriptor FD, to import_hash_table.  */
        !          5348: 
        !          5349: static void
        !          5350: add_import (pfile, fd, fname)
        !          5351:      cpp_reader *pfile;
        !          5352:      int fd;
        !          5353:      char *fname;
        !          5354: {
        !          5355:   struct import_file *i;
        !          5356:   int hashval;
        !          5357:   struct stat sb;
        !          5358: 
        !          5359:   hashval = import_hash (fname);
        !          5360:   fstat (fd, &sb);
        !          5361:   i = (struct import_file *)xmalloc (sizeof (struct import_file));
        !          5362:   i->name = (char *)xmalloc (strlen (fname)+1);
        !          5363:   strcpy (i->name, fname);
        !          5364:   bcopy ((char *) &sb.st_ino, (char *) &i->inode, sizeof (sb.st_ino));
        !          5365:   i->dev = sb.st_dev;
        !          5366:   i->next = pfile->import_hash_table[hashval];
        !          5367:   pfile->import_hash_table[hashval] = i;
        !          5368: }
        !          5369: 
        !          5370: /* The file_name_map structure holds a mapping of file names for a
        !          5371:    particular directory.  This mapping is read from the file named
        !          5372:    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
        !          5373:    map filenames on a file system with severe filename restrictions,
        !          5374:    such as DOS.  The format of the file name map file is just a series
        !          5375:    of lines with two tokens on each line.  The first token is the name
        !          5376:    to map, and the second token is the actual name to use.  */
        !          5377: 
        !          5378: struct file_name_map
        !          5379: {
        !          5380:   struct file_name_map *map_next;
        !          5381:   char *map_from;
        !          5382:   char *map_to;
        !          5383: };
        !          5384: 
        !          5385: #define FILE_NAME_MAP_FILE "header.gcc"
        !          5386: 
        !          5387: /* Read a space delimited string of unlimited length from a stdio
        !          5388:    file.  */
        !          5389: 
        !          5390: static char *
        !          5391: read_filename_string (ch, f)
        !          5392:      int ch;
        !          5393:      FILE *f;
        !          5394: {
        !          5395:   char *alloc, *set;
        !          5396:   int len;
        !          5397: 
        !          5398:   len = 20;
        !          5399:   set = alloc = xmalloc (len + 1);
        !          5400:   if (! is_space[ch])
        !          5401:     {
        !          5402:       *set++ = ch;
        !          5403:       while ((ch = getc (f)) != EOF && ! is_space[ch])
        !          5404:        {
        !          5405:          if (set - alloc == len)
        !          5406:            {
        !          5407:              len *= 2;
        !          5408:              alloc = xrealloc (alloc, len + 1);
        !          5409:              set = alloc + len / 2;
        !          5410:            }
        !          5411:          *set++ = ch;
        !          5412:        }
        !          5413:     }
        !          5414:   *set = '\0';
        !          5415:   ungetc (ch, f);
        !          5416:   return alloc;
        !          5417: }
        !          5418: 
        !          5419: /* This structure holds a linked list of file name maps, one per directory. */
        !          5420: struct file_name_map_list
        !          5421: {
        !          5422:   struct file_name_map_list *map_list_next;
        !          5423:   char *map_list_name;
        !          5424:   struct file_name_map *map_list_map;
        !          5425: };
        !          5426: 
        !          5427: /* Read the file name map file for DIRNAME.  */
        !          5428: 
        !          5429: static struct file_name_map *
        !          5430: read_name_map (pfile, dirname)
        !          5431:      cpp_reader *pfile;
        !          5432:      char *dirname;
        !          5433: {
        !          5434:   register struct file_name_map_list *map_list_ptr;
        !          5435:   char *name;
        !          5436:   FILE *f;
        !          5437: 
        !          5438:   for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
        !          5439:        map_list_ptr = map_list_ptr->map_list_next)
        !          5440:     if (! strcmp (map_list_ptr->map_list_name, dirname))
        !          5441:       return map_list_ptr->map_list_map;
        !          5442: 
        !          5443:   map_list_ptr = ((struct file_name_map_list *)
        !          5444:                  xmalloc (sizeof (struct file_name_map_list)));
        !          5445:   map_list_ptr->map_list_name = savestring (dirname);
        !          5446:   map_list_ptr->map_list_map = NULL;
        !          5447: 
        !          5448:   name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
        !          5449:   strcpy (name, dirname);
        !          5450:   if (*dirname)
        !          5451:     strcat (name, "/");
        !          5452:   strcat (name, FILE_NAME_MAP_FILE);
        !          5453:   f = fopen (name, "r");
        !          5454:   if (!f)
        !          5455:     map_list_ptr->map_list_map = NULL;
        !          5456:   else
        !          5457:     {
        !          5458:       int ch;
        !          5459:       int dirlen = strlen (dirname);
        !          5460: 
        !          5461:       while ((ch = getc (f)) != EOF)
        !          5462:        {
        !          5463:          char *from, *to;
        !          5464:          struct file_name_map *ptr;
        !          5465: 
        !          5466:          if (is_space[ch])
        !          5467:            continue;
        !          5468:          from = read_filename_string (ch, f);
        !          5469:          while ((ch = getc (f)) != EOF && is_hor_space[ch])
        !          5470:            ;
        !          5471:          to = read_filename_string (ch, f);
        !          5472: 
        !          5473:          ptr = ((struct file_name_map *)
        !          5474:                 xmalloc (sizeof (struct file_name_map)));
        !          5475:          ptr->map_from = from;
        !          5476: 
        !          5477:          /* Make the real filename absolute.  */
        !          5478:          if (*to == '/')
        !          5479:            ptr->map_to = to;
        !          5480:          else
        !          5481:            {
        !          5482:              ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
        !          5483:              strcpy (ptr->map_to, dirname);
        !          5484:              ptr->map_to[dirlen] = '/';
        !          5485:              strcpy (ptr->map_to + dirlen + 1, to);
        !          5486:              free (to);
        !          5487:            }         
        !          5488: 
        !          5489:          ptr->map_next = map_list_ptr->map_list_map;
        !          5490:          map_list_ptr->map_list_map = ptr;
        !          5491: 
        !          5492:          while ((ch = getc (f)) != '\n')
        !          5493:            if (ch == EOF)
        !          5494:              break;
        !          5495:        }
        !          5496:       fclose (f);
        !          5497:     }
        !          5498:   
        !          5499:   map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
        !          5500:   CPP_OPTIONS (pfile)->map_list = map_list_ptr;
        !          5501: 
        !          5502:   return map_list_ptr->map_list_map;
        !          5503: }  
        !          5504: 
        !          5505: /* Try to open include file FILENAME.  SEARCHPTR is the directory
        !          5506:    being tried from the include file search path.  This function maps
        !          5507:    filenames on file systems based on information read by
        !          5508:    read_name_map.  */
        !          5509: 
        !          5510: static int
        !          5511: open_include_file (pfile, filename, searchptr)
        !          5512:      cpp_reader *pfile;
        !          5513:      char *filename;
        !          5514:      struct file_name_list *searchptr;
        !          5515: {
        !          5516:   register struct file_name_map *map;
        !          5517:   register char *from;
        !          5518:   char *p, *dir;
        !          5519: 
        !          5520:   if (searchptr && ! searchptr->got_name_map)
        !          5521:     {
        !          5522:       searchptr->name_map = read_name_map (pfile,
        !          5523:                                           searchptr->fname
        !          5524:                                           ? searchptr->fname : ".");
        !          5525:       searchptr->got_name_map = 1;
        !          5526:     }
        !          5527: 
        !          5528:   /* First check the mapping for the directory we are using.  */
        !          5529:   if (searchptr && searchptr->name_map)
        !          5530:     {
        !          5531:       from = filename;
        !          5532:       if (searchptr->fname)
        !          5533:        from += strlen (searchptr->fname) + 1;
        !          5534:       for (map = searchptr->name_map; map; map = map->map_next)
        !          5535:        {
        !          5536:          if (! strcmp (map->map_from, from))
        !          5537:            {
        !          5538:              /* Found a match.  */
        !          5539:              return open (map->map_to, O_RDONLY, 0666);
        !          5540:            }
        !          5541:        }
        !          5542:     }
        !          5543: 
        !          5544:   /* Try to find a mapping file for the particular directory we are
        !          5545:      looking in.  Thus #include <sys/types.h> will look up sys/types.h
        !          5546:      in /usr/include/header.gcc and look up types.h in
        !          5547:      /usr/include/sys/header.gcc.  */
        !          5548:   p = rindex (filename, '/');
        !          5549:   if (! p)
        !          5550:     p = filename;
        !          5551:   if (searchptr
        !          5552:       && searchptr->fname
        !          5553:       && strlen (searchptr->fname) == p - filename
        !          5554:       && ! strncmp (searchptr->fname, filename, p - filename))
        !          5555:     {
        !          5556:       /* FILENAME is in SEARCHPTR, which we've already checked.  */
        !          5557:       return open (filename, O_RDONLY, 0666);
        !          5558:     }
        !          5559: 
        !          5560:   if (p == filename)
        !          5561:     {
        !          5562:       dir = ".";
        !          5563:       from = filename;
        !          5564:     }
        !          5565:   else
        !          5566:     {
        !          5567:       dir = (char *) alloca (p - filename + 1);
        !          5568:       bcopy (filename, dir, p - filename);
        !          5569:       dir[p - filename] = '\0';
        !          5570:       from = p + 1;
        !          5571:     }
        !          5572:   for (map = read_name_map (pfile, dir); map; map = map->map_next)
        !          5573:     if (! strcmp (map->map_from, from))
        !          5574:       return open (map->map_to, O_RDONLY, 0666);
        !          5575: 
        !          5576:   return open (filename, O_RDONLY, 0666);
        !          5577: }
        !          5578: 
        !          5579: /* Process the contents of include file FNAME, already open on descriptor F,
        !          5580:    with output to OP.
        !          5581:    SYSTEM_HEADER_P is 1 if this file resides in any one of the known
        !          5582:    "system" include directories (as decided by the `is_system_include'
        !          5583:    function above).
        !          5584:    DIRPTR is the link in the dir path through which this file was found,
        !          5585:    or 0 if the file name was absolute or via the current directory.
        !          5586:    Return 1 on success, 0 on failure.
        !          5587: 
        !          5588:    The caller is responsible for the cpp_push_buffer.  */
        !          5589: 
        !          5590: static int
        !          5591: finclude (pfile, f, fname, system_header_p, dirptr)
        !          5592:      cpp_reader *pfile;
        !          5593:      int f;
        !          5594:      char *fname;
        !          5595:      int system_header_p;
        !          5596:      struct file_name_list *dirptr;
        !          5597: {
        !          5598:   int st_mode;
        !          5599:   long st_size;
        !          5600:   long i;
        !          5601:   int length;
        !          5602:   cpp_buffer *fp;                      /* For input stack frame */
        !          5603:   int missing_newline = 0;
        !          5604: 
        !          5605:   if (file_size_and_mode (f, &st_mode, &st_size) < 0)
        !          5606:     {
        !          5607:       cpp_perror_with_name (pfile, fname);
        !          5608:       close (f);
        !          5609:       cpp_pop_buffer (pfile);
        !          5610:       return 0;
        !          5611:     }
        !          5612: 
        !          5613:   fp = CPP_BUFFER (pfile);
        !          5614:   fp->nominal_fname = fp->fname = fname;
        !          5615: #if 0
        !          5616:   fp->length = 0;
        !          5617: #endif
        !          5618:   fp->dir = dirptr;
        !          5619:   fp->system_header_p = system_header_p;
        !          5620:   fp->lineno = 1;
        !          5621:   fp->colno = 1;
        !          5622:   fp->cleanup = file_cleanup;
        !          5623: 
        !          5624:   if (S_ISREG (st_mode)) {
        !          5625:     fp->buf = (U_CHAR *) xmalloc (st_size + 2);
        !          5626:     fp->alimit = fp->buf + st_size + 2;
        !          5627:     fp->cur = fp->buf;
        !          5628: 
        !          5629:     /* Read the file contents, knowing that st_size is an upper bound
        !          5630:        on the number of bytes we can read.  */
        !          5631:     length = safe_read (f, fp->buf, st_size);
        !          5632:     fp->rlimit = fp->buf + length;
        !          5633:     if (length < 0) goto nope;
        !          5634:   }
        !          5635:   else if (S_ISDIR (st_mode)) {
        !          5636:     cpp_error (pfile, "directory `%s' specified in #include", fname);
        !          5637:     close (f);
        !          5638:     return 0;
        !          5639:   } else {
        !          5640:     /* Cannot count its file size before reading.
        !          5641:        First read the entire file into heap and
        !          5642:        copy them into buffer on stack. */
        !          5643: 
        !          5644:     int bsize = 2000;
        !          5645: 
        !          5646:     st_size = 0;
        !          5647:     fp->buf = (U_CHAR *) xmalloc (bsize + 2);
        !          5648: 
        !          5649:     for (;;) {
        !          5650:       i = safe_read (f, fp->buf + st_size, bsize - st_size);
        !          5651:       if (i < 0)
        !          5652:        goto nope;      /* error! */
        !          5653:       st_size += i;
        !          5654:       if (st_size != bsize)
        !          5655:        break;  /* End of file */
        !          5656:       bsize *= 2;
        !          5657:       fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
        !          5658:     }
        !          5659:     fp->cur = fp->buf;
        !          5660:     length = st_size;
        !          5661:   }
        !          5662: 
        !          5663:   if ((length > 0 && fp->buf[length - 1] != '\n')
        !          5664:       /* Backslash-newline at end is not good enough.  */
        !          5665:       || (length > 1 && fp->buf[length - 2] == '\\')) {
        !          5666:     fp->buf[length++] = '\n';
        !          5667: #if 0
        !          5668:     missing_newline = 1;
        !          5669: #endif
        !          5670:   }
        !          5671:   fp->buf[length] = '\0';
        !          5672:   fp->rlimit = fp->buf + length;
        !          5673: 
        !          5674:   /* Close descriptor now, so nesting does not use lots of descriptors.  */
        !          5675:   close (f);
        !          5676: 
        !          5677:   /* Must do this before calling trigraph_pcp, so that the correct file name
        !          5678:      will be printed in warning messages.  */
        !          5679: 
        !          5680:   pfile->input_stack_listing_current = 0;
        !          5681: 
        !          5682: #if 0
        !          5683:   if (!no_trigraphs)
        !          5684:     trigraph_pcp (fp);
        !          5685: #endif
        !          5686: 
        !          5687: #if 0
        !          5688:   rescan (op, 0);
        !          5689: 
        !          5690:   if (missing_newline)
        !          5691:     fp->lineno--;
        !          5692: 
        !          5693:   if (CPP_PEDANTIC (pfile) && missing_newline)
        !          5694:     pedwarn ("file does not end in newline");
        !          5695: 
        !          5696:   indepth--;
        !          5697:   input_file_stack_tick++;
        !          5698:   free (fp->buf);
        !          5699: #endif
        !          5700:   return 1;
        !          5701: 
        !          5702:  nope:
        !          5703: 
        !          5704:   cpp_perror_with_name (pfile, fname);
        !          5705:   close (f);
        !          5706:   free (fp->buf);
        !          5707:   return 1;
        !          5708: }
        !          5709: 
        !          5710: int
        !          5711: push_parse_file (pfile, fname)
        !          5712:      cpp_reader *pfile;
        !          5713:      char *fname;
        !          5714: {
        !          5715:   struct cpp_options *opts = CPP_OPTIONS (pfile);
        !          5716:   struct cpp_pending *pend;
        !          5717:   char *p;
        !          5718:   int f;
        !          5719:   cpp_buffer *fp;
        !          5720: 
        !          5721:   /* The code looks at the defaults through this pointer, rather than through
        !          5722:      the constant structure above.  This pointer gets changed if an environment
        !          5723:      variable specifies other defaults.  */
        !          5724:   struct default_include *include_defaults = include_defaults_array;
        !          5725: 
        !          5726:   /* Add dirs from CPATH after dirs from -I.  */
        !          5727:   /* There seems to be confusion about what CPATH should do,
        !          5728:      so for the moment it is not documented.  */
        !          5729:   /* Some people say that CPATH should replace the standard include dirs,
        !          5730:      but that seems pointless: it comes before them, so it overrides them
        !          5731:      anyway.  */
        !          5732:   p = (char *) getenv ("CPATH");
        !          5733:   if (p != 0 && ! opts->no_standard_includes)
        !          5734:     path_include (pfile, p);
        !          5735: 
        !          5736:   /* Now that dollars_in_ident is known, initialize is_idchar.  */
        !          5737:   initialize_char_syntax (opts);
        !          5738: 
        !          5739:   /* Do partial setup of input buffer for the sake of generating
        !          5740:      early #line directives (when -g is in effect).  */
        !          5741:   fp = cpp_push_buffer (pfile, NULL, 0);
        !          5742:   if (opts->in_fname == NULL)
        !          5743:     opts->in_fname = "";
        !          5744:   fp->nominal_fname = fp->fname = opts->in_fname;
        !          5745:   fp->lineno = 0;
        !          5746: 
        !          5747:   /* Install __LINE__, etc.  Must follow initialize_char_syntax
        !          5748:      and option processing.  */
        !          5749:   initialize_builtins (pfile);
        !          5750: 
        !          5751:   /* Do standard #defines and assertions
        !          5752:      that identify system and machine type.  */
        !          5753: 
        !          5754:   if (!opts->inhibit_predefs) {
        !          5755:     char *p = (char *) alloca (strlen (predefs) + 1);
        !          5756:     strcpy (p, predefs);
        !          5757:     while (*p) {
        !          5758:       char *q;
        !          5759:       while (*p == ' ' || *p == '\t')
        !          5760:        p++;
        !          5761:       /* Handle -D options.  */ 
        !          5762:       if (p[0] == '-' && p[1] == 'D') {
        !          5763:        q = &p[2];
        !          5764:        while (*p && *p != ' ' && *p != '\t')
        !          5765:          p++;
        !          5766:        if (*p != 0)
        !          5767:          *p++= 0;
        !          5768:        if (opts->debug_output)
        !          5769:          output_line_command (pfile, 0, same_file);
        !          5770:        cpp_define (pfile, q);
        !          5771:        while (*p == ' ' || *p == '\t')
        !          5772:          p++;
        !          5773:       } else if (p[0] == '-' && p[1] == 'A') {
        !          5774:        /* Handle -A options (assertions).  */ 
        !          5775:        char *assertion;
        !          5776:        char *past_name;
        !          5777:        char *value;
        !          5778:        char *past_value;
        !          5779:        char *termination;
        !          5780:        int save_char;
        !          5781: 
        !          5782:        assertion = &p[2];
        !          5783:        past_name = assertion;
        !          5784:        /* Locate end of name.  */
        !          5785:        while (*past_name && *past_name != ' '
        !          5786:               && *past_name != '\t' && *past_name != '(')
        !          5787:          past_name++;
        !          5788:        /* Locate `(' at start of value.  */
        !          5789:        value = past_name;
        !          5790:        while (*value && (*value == ' ' || *value == '\t'))
        !          5791:          value++;
        !          5792:        if (*value++ != '(')
        !          5793:          abort ();
        !          5794:        while (*value && (*value == ' ' || *value == '\t'))
        !          5795:          value++;
        !          5796:        past_value = value;
        !          5797:        /* Locate end of value.  */
        !          5798:        while (*past_value && *past_value != ' '
        !          5799:               && *past_value != '\t' && *past_value != ')')
        !          5800:          past_value++;
        !          5801:        termination = past_value;
        !          5802:        while (*termination && (*termination == ' ' || *termination == '\t'))
        !          5803:          termination++;
        !          5804:        if (*termination++ != ')')
        !          5805:          abort ();
        !          5806:        if (*termination && *termination != ' ' && *termination != '\t')
        !          5807:          abort ();
        !          5808:        /* Temporarily null-terminate the value.  */
        !          5809:        save_char = *termination;
        !          5810:        *termination = '\0';
        !          5811:        /* Install the assertion.  */
        !          5812:        make_assertion (pfile, "-A", assertion);
        !          5813:        *termination = (char) save_char;
        !          5814:        p = termination;
        !          5815:        while (*p == ' ' || *p == '\t')
        !          5816:          p++;
        !          5817:       } else {
        !          5818:        abort ();
        !          5819:       }
        !          5820:     }
        !          5821:   }
        !          5822: 
        !          5823:   /* Now handle the command line options.  */
        !          5824: 
        !          5825:   /* Do -U's, -D's and -A's in the order they were seen.  */
        !          5826:   /* First reverse the list. */
        !          5827:   opts->pending = nreverse_pending (opts->pending);
        !          5828: 
        !          5829:   for (pend = opts->pending;  pend;  pend = pend->next)
        !          5830:     {
        !          5831:       if (pend->cmd != NULL && pend->cmd[0] == '-')
        !          5832:        {
        !          5833:          switch (pend->cmd[1])
        !          5834:            {
        !          5835:            case 'U':
        !          5836:              if (opts->debug_output)
        !          5837:                output_line_command (pfile, 0, same_file);
        !          5838:              do_undef (pfile, NULL, pend->arg, pend->arg + strlen (pend->arg));
        !          5839:              break;
        !          5840:            case 'D':
        !          5841:              if (opts->debug_output)
        !          5842:                output_line_command (pfile, 0, same_file);
        !          5843:              cpp_define (pfile, pend->arg);
        !          5844:              break;
        !          5845:            case 'A':
        !          5846:              make_assertion (pfile, "-A", pend->arg);
        !          5847:              break;
        !          5848:            }
        !          5849:        }
        !          5850:     }
        !          5851: 
        !          5852:   opts->done_initializing = 1;
        !          5853: 
        !          5854:   { /* read the appropriate environment variable and if it exists
        !          5855:        replace include_defaults with the listed path. */
        !          5856:     char *epath = 0;
        !          5857:     switch ((opts->objc << 1) + opts->cplusplus)
        !          5858:       {
        !          5859:       case 0:
        !          5860:        epath = getenv ("C_INCLUDE_PATH");
        !          5861:        break;
        !          5862:       case 1:
        !          5863:        epath = getenv ("CPLUS_INCLUDE_PATH");
        !          5864:        break;
        !          5865:       case 2:
        !          5866:        epath = getenv ("OBJC_INCLUDE_PATH");
        !          5867:        break;
        !          5868:       case 3:
        !          5869:        epath = getenv ("OBJCPLUS_INCLUDE_PATH");
        !          5870:        break;
        !          5871:       }
        !          5872:     /* If the environment var for this language is set,
        !          5873:        add to the default list of include directories.  */
        !          5874:     if (epath) {
        !          5875:       char *nstore = (char *) alloca (strlen (epath) + 2);
        !          5876:       int num_dirs;
        !          5877:       char *startp, *endp;
        !          5878: 
        !          5879:       for (num_dirs = 1, startp = epath; *startp; startp++)
        !          5880:        if (*startp == PATH_SEPARATOR)
        !          5881:          num_dirs++;
        !          5882:       include_defaults
        !          5883:        = (struct default_include *) xmalloc ((num_dirs
        !          5884:                                               * sizeof (struct default_include))
        !          5885:                                              + sizeof (include_defaults_array));
        !          5886:       startp = endp = epath;
        !          5887:       num_dirs = 0;
        !          5888:       while (1) {
        !          5889:         /* Handle cases like c:/usr/lib:d:/gcc/lib */
        !          5890:         if ((*endp == PATH_SEPARATOR)
        !          5891:             || *endp == 0) {
        !          5892:          strncpy (nstore, startp, endp-startp);
        !          5893:          if (endp == startp)
        !          5894:            strcpy (nstore, ".");
        !          5895:          else
        !          5896:            nstore[endp-startp] = '\0';
        !          5897: 
        !          5898:          include_defaults[num_dirs].fname = savestring (nstore);
        !          5899:          include_defaults[num_dirs].cplusplus = opts->cplusplus;
        !          5900:          include_defaults[num_dirs].cxx_aware = 1;
        !          5901:          num_dirs++;
        !          5902:          if (*endp == '\0')
        !          5903:            break;
        !          5904:          endp = startp = endp + 1;
        !          5905:        } else
        !          5906:          endp++;
        !          5907:       }
        !          5908:       /* Put the usual defaults back in at the end.  */
        !          5909:       bcopy ((char *) include_defaults_array,
        !          5910:             (char *) &include_defaults[num_dirs],
        !          5911:             sizeof (include_defaults_array));
        !          5912:     }
        !          5913:   }
        !          5914: 
        !          5915:   append_include_chain (pfile, opts->before_system, opts->last_before_system);
        !          5916:   opts->first_system_include = opts->before_system;
        !          5917: 
        !          5918:   /* Unless -fnostdinc,
        !          5919:      tack on the standard include file dirs to the specified list */
        !          5920:   if (!opts->no_standard_includes) {
        !          5921:     struct default_include *p = include_defaults;
        !          5922:     char *specd_prefix = opts->include_prefix;
        !          5923:     char *default_prefix = savestring (GCC_INCLUDE_DIR);
        !          5924:     int default_len = 0;
        !          5925:     /* Remove the `include' from /usr/local/lib/gcc.../include.  */
        !          5926:     if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
        !          5927:       default_len = strlen (default_prefix) - 7;
        !          5928:       default_prefix[default_len] = 0;
        !          5929:     }
        !          5930:     /* Search "translated" versions of GNU directories.
        !          5931:        These have /usr/local/lib/gcc... replaced by specd_prefix.  */
        !          5932:     if (specd_prefix != 0 && default_len != 0)
        !          5933:       for (p = include_defaults; p->fname; p++) {
        !          5934:        /* Some standard dirs are only for C++.  */
        !          5935:        if (!p->cplusplus
        !          5936:            || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
        !          5937:          /* Does this dir start with the prefix?  */
        !          5938:          if (!strncmp (p->fname, default_prefix, default_len)) {
        !          5939:            /* Yes; change prefix and add to search list.  */
        !          5940:            struct file_name_list *new
        !          5941:              = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
        !          5942:            int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len;
        !          5943:            char *str = (char *) xmalloc (this_len + 1);
        !          5944:            strcpy (str, specd_prefix);
        !          5945:            strcat (str, p->fname + default_len);
        !          5946:            new->fname = str;
        !          5947:            new->control_macro = 0;
        !          5948:            new->c_system_include_path = !p->cxx_aware;
        !          5949:            new->got_name_map = 0;
        !          5950:            append_include_chain (pfile, new, new);
        !          5951:            if (opts->first_system_include == 0)
        !          5952:              opts->first_system_include = new;
        !          5953:          }
        !          5954:        }
        !          5955:       }
        !          5956:     /* Search ordinary names for GNU include directories.  */
        !          5957:     for (p = include_defaults; p->fname; p++) {
        !          5958:       /* Some standard dirs are only for C++.  */
        !          5959:       if (!p->cplusplus
        !          5960:          || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
        !          5961:        struct file_name_list *new
        !          5962:          = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
        !          5963:        new->control_macro = 0;
        !          5964:        new->c_system_include_path = !p->cxx_aware;
        !          5965:        new->fname = p->fname;
        !          5966:        new->got_name_map = 0;
        !          5967:        append_include_chain (pfile, new, new);
        !          5968:        if (opts->first_system_include == 0)
        !          5969:          opts->first_system_include = new;
        !          5970:       }
        !          5971:     }
        !          5972:   }
        !          5973: 
        !          5974:   /* Tack the after_include chain at the end of the include chain.  */
        !          5975:   append_include_chain (pfile, opts->after_include, opts->last_after_include);
        !          5976:   if (opts->first_system_include == 0)
        !          5977:     opts->first_system_include = opts->after_include;
        !          5978: 
        !          5979:   /* With -v, print the list of dirs to search.  */
        !          5980:   if (opts->verbose) {
        !          5981:     struct file_name_list *p;
        !          5982:     fprintf (stderr, "#include \"...\" search starts here:\n");
        !          5983:     for (p = opts->include; p; p = p->next) {
        !          5984:       if (p == opts->first_bracket_include)
        !          5985:        fprintf (stderr, "#include <...> search starts here:\n");
        !          5986:       fprintf (stderr, " %s\n", p->fname);
        !          5987:     }
        !          5988:     fprintf (stderr, "End of search list.\n");
        !          5989:   }
        !          5990: 
        !          5991:   /* Scan the -imacros files before the main input.
        !          5992:      Much like #including them, but with no_output set
        !          5993:      so that only their macro definitions matter.  */
        !          5994: 
        !          5995:   opts->no_output++; pfile->no_record_file++;
        !          5996:   for (pend = opts->pending;  pend;  pend = pend->next)
        !          5997:     {
        !          5998:       if (pend->cmd != NULL && strcmp (pend->cmd, "-imacros") == 0)
        !          5999:        {
        !          6000:          int fd = open (pend->arg, O_RDONLY, 0666);
        !          6001:          if (fd < 0)
        !          6002:            {
        !          6003:              cpp_perror_with_name (pfile, pend->arg);
        !          6004:              return FATAL_EXIT_CODE;
        !          6005:            }
        !          6006:          cpp_push_buffer (pfile, NULL, 0);
        !          6007:          finclude (pfile, fd, pend->arg, 0, NULL_PTR);
        !          6008:          cpp_scan_buffer (pfile);
        !          6009:        }
        !          6010:     }
        !          6011:   opts->no_output--; pfile->no_record_file--;
        !          6012: 
        !          6013:   /* Copy the entire contents of the main input file into
        !          6014:      the stacked input buffer previously allocated for it.  */
        !          6015:   if (fname == NULL || *fname == 0) {
        !          6016:     fname = "";
        !          6017:     f = 0;
        !          6018:   } else if ((f = open (fname, O_RDONLY, 0666)) < 0)
        !          6019:     cpp_pfatal_with_name (pfile, fname);
        !          6020: 
        !          6021:   /* -MG doesn't select the form of output and must be specified with one of
        !          6022:      -M or -MM.  -MG doesn't make sense with -MD or -MMD since they don't
        !          6023:      inhibit compilation.  */
        !          6024:   if (opts->print_deps_missing_files
        !          6025:       && (opts->print_deps == 0 || !opts->no_output))
        !          6026:     fatal (pfile, "-MG must be specified with one of -M or -MM");
        !          6027: 
        !          6028:   /* Either of two environment variables can specify output of deps.
        !          6029:      Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
        !          6030:      where OUTPUT_FILE is the file to write deps info to
        !          6031:      and DEPS_TARGET is the target to mention in the deps.  */
        !          6032: 
        !          6033:   if (opts->print_deps == 0
        !          6034:       && (getenv ("SUNPRO_DEPENDENCIES") != 0
        !          6035:          || getenv ("DEPENDENCIES_OUTPUT") != 0)) {
        !          6036:     char *spec = getenv ("DEPENDENCIES_OUTPUT");
        !          6037:     char *s;
        !          6038:     char *output_file;
        !          6039: 
        !          6040:     if (spec == 0)
        !          6041:       {
        !          6042:        spec = getenv ("SUNPRO_DEPENDENCIES");
        !          6043:        opts->print_deps = 2;
        !          6044:       }
        !          6045:     else
        !          6046:       opts->print_deps = 1;
        !          6047: 
        !          6048:     s = spec;
        !          6049:     /* Find the space before the DEPS_TARGET, if there is one.  */
        !          6050:     /* This should use index.  (mrs) */
        !          6051:     while (*s != 0 && *s != ' ') s++;
        !          6052:     if (*s != 0)
        !          6053:       {
        !          6054:        opts->deps_target = s + 1;
        !          6055:        output_file = (char *) xmalloc (s - spec + 1);
        !          6056:        bcopy (spec, output_file, s - spec);
        !          6057:        output_file[s - spec] = 0;
        !          6058:       }
        !          6059:     else
        !          6060:       {
        !          6061:        opts->deps_target = 0;
        !          6062:        output_file = spec;
        !          6063:       }
        !          6064: 
        !          6065:     opts->deps_file = output_file;
        !          6066:     opts->print_deps_append = 1;
        !          6067:   }
        !          6068: 
        !          6069:   /* For -M, print the expected object file name
        !          6070:      as the target of this Make-rule.  */
        !          6071:   if (opts->print_deps)
        !          6072:     {
        !          6073:       pfile->deps_allocated_size = 200;
        !          6074:       pfile->deps_buffer = (char *) xmalloc (pfile->deps_allocated_size);
        !          6075:       pfile->deps_buffer[0] = 0;
        !          6076:       pfile->deps_size = 0;
        !          6077:       pfile->deps_column = 0;
        !          6078: 
        !          6079:       if (opts->deps_target)
        !          6080:        deps_output (pfile, opts->deps_target, ':');
        !          6081:       else if (*opts->in_fname == 0)
        !          6082:        deps_output (pfile, "-", ':');
        !          6083:       else
        !          6084:        {
        !          6085:          char *p, *q;
        !          6086:          int len;
        !          6087: 
        !          6088:          /* Discard all directory prefixes from filename.  */
        !          6089:          if ((q = rindex (opts->in_fname, '/')) != NULL
        !          6090: #ifdef DIR_SEPARATOR
        !          6091:              && (q = rindex (opts->in_fname, DIR_SEPARATOR)) != NULL
        !          6092: #endif
        !          6093:              )
        !          6094:            ++q;
        !          6095:          else
        !          6096:            q = opts->in_fname;
        !          6097: 
        !          6098:          /* Copy remainder to mungable area.  */
        !          6099:          p = (char *) alloca (strlen(q) + 8);
        !          6100:          strcpy (p, q);
        !          6101: 
        !          6102:          /* Output P, but remove known suffixes.  */
        !          6103:          len = strlen (p);
        !          6104:          q = p + len;
        !          6105:          if (len >= 2
        !          6106:              && p[len - 2] == '.'
        !          6107:              && index("cCsSm", p[len - 1]))
        !          6108:            q = p + (len - 2);
        !          6109:          else if (len >= 3
        !          6110:                   && p[len - 3] == '.'
        !          6111:                   && p[len - 2] == 'c'
        !          6112:                   && p[len - 1] == 'c')
        !          6113:            q = p + (len - 3);
        !          6114:          else if (len >= 4
        !          6115:                   && p[len - 4] == '.'
        !          6116:                   && p[len - 3] == 'c'
        !          6117:                   && p[len - 2] == 'x'
        !          6118:                   && p[len - 1] == 'x')
        !          6119:            q = p + (len - 4);
        !          6120:          else if (len >= 4
        !          6121:                   && p[len - 4] == '.'
        !          6122:                   && p[len - 3] == 'c'
        !          6123:                   && p[len - 2] == 'p'
        !          6124:                   && p[len - 1] == 'p')
        !          6125:            q = p + (len - 4);
        !          6126: 
        !          6127:          /* Supply our own suffix.  */
        !          6128: #ifndef VMS
        !          6129:          strcpy (q, ".o");
        !          6130: #else
        !          6131:          strcpy (q, ".obj");
        !          6132: #endif
        !          6133: 
        !          6134:          deps_output (pfile, p, ':');
        !          6135:          deps_output (pfile, opts->in_fname, ' ');
        !          6136:        }
        !          6137:     }
        !          6138: 
        !          6139: #if 0
        !          6140:   /* Make sure data ends with a newline.  And put a null after it.  */
        !          6141: 
        !          6142:   if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
        !          6143:       /* Backslash-newline at end is not good enough.  */
        !          6144:       || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
        !          6145:     fp->buf[fp->length++] = '\n';
        !          6146:     missing_newline = 1;
        !          6147:   }
        !          6148:   fp->buf[fp->length] = '\0';
        !          6149: 
        !          6150:   /* Unless inhibited, convert trigraphs in the input.  */
        !          6151: 
        !          6152:   if (!no_trigraphs)
        !          6153:     trigraph_pcp (fp);
        !          6154: #endif
        !          6155: 
        !          6156:   /* Scan the -include files before the main input.
        !          6157:    We push these in reverse order, so that the first one is handled first.  */
        !          6158: 
        !          6159:   pfile->no_record_file++;
        !          6160:   opts->pending = nreverse_pending (opts->pending);
        !          6161:   for (pend = opts->pending;  pend;  pend = pend->next)
        !          6162:     {
        !          6163:       if (pend->cmd != NULL && strcmp (pend->cmd, "-include") == 0)
        !          6164:        {
        !          6165:          int fd = open (pend->arg, O_RDONLY, 0666);
        !          6166:          if (fd < 0)
        !          6167:            {
        !          6168:              cpp_perror_with_name (pfile, pend->arg);
        !          6169:              return FATAL_EXIT_CODE;
        !          6170:            }
        !          6171:          cpp_push_buffer (pfile, NULL, 0);
        !          6172:          finclude (pfile, fd, pend->arg, 0, NULL_PTR);
        !          6173:        }
        !          6174:     }
        !          6175:   pfile->no_record_file--;
        !          6176: 
        !          6177:   /* Free the pending list. */
        !          6178:   for (pend = opts->pending;  pend; )
        !          6179:     {
        !          6180:       struct cpp_pending *next = pend->next;
        !          6181:       free (pend);
        !          6182:       pend = next;
        !          6183:     }
        !          6184:   opts->pending = NULL;
        !          6185: 
        !          6186: #if 0
        !          6187:   /* Scan the input, processing macros and directives.  */
        !          6188: 
        !          6189:   rescan (&outbuf, 0);
        !          6190: 
        !          6191:   if (missing_newline)
        !          6192:     fp->lineno--;
        !          6193: 
        !          6194:   if (CPP_PEDANTIC (pfile) && missing_newline)
        !          6195:     pedwarn ("file does not end in newline");
        !          6196: 
        !          6197: #endif
        !          6198:   if (finclude (pfile, f, fname, 0, NULL_PTR))
        !          6199:     output_line_command (pfile, 0, same_file);
        !          6200:   return SUCCESS_EXIT_CODE;
        !          6201: }
        !          6202: 
        !          6203: void
        !          6204: init_parse_file (pfile)
        !          6205:      cpp_reader *pfile;
        !          6206: {
        !          6207:   bzero ((char *) pfile, sizeof (cpp_reader));
        !          6208:   pfile->get_token = cpp_get_token;
        !          6209: 
        !          6210:   pfile->token_buffer_size = 200;
        !          6211:   pfile->token_buffer = (U_CHAR*)xmalloc (pfile->token_buffer_size);
        !          6212:   CPP_SET_WRITTEN (pfile, 0);
        !          6213: 
        !          6214:   pfile->system_include_depth = 0;
        !          6215:   pfile->dont_repeat_files = 0;
        !          6216:   pfile->all_include_files = 0;
        !          6217:   pfile->max_include_len = 0;
        !          6218:   pfile->timebuf = NULL;
        !          6219:   pfile->only_seen_white = 1;
        !          6220:   pfile->buffer = CPP_NULL_BUFFER(pfile);
        !          6221: }
        !          6222: 
        !          6223: static struct cpp_pending *
        !          6224: nreverse_pending (list)
        !          6225:      struct cpp_pending *list;
        !          6226:      
        !          6227: {
        !          6228:   register struct cpp_pending *prev = 0, *next, *pend;
        !          6229:   for (pend = list;  pend;  pend = next)
        !          6230:     {
        !          6231:       next = pend->next;
        !          6232:       pend->next = prev;
        !          6233:       prev = pend;
        !          6234:     }
        !          6235:   return prev;
        !          6236: }
        !          6237: 
        !          6238: static void
        !          6239: push_pending (pfile, cmd, arg)
        !          6240:      cpp_reader *pfile;
        !          6241:      char *cmd;
        !          6242:      char *arg;
        !          6243: {
        !          6244:   struct cpp_pending *pend
        !          6245:     = (struct cpp_pending*)xmalloc (sizeof (struct cpp_pending));
        !          6246:   pend->cmd = cmd;
        !          6247:   pend->arg = arg;
        !          6248:   pend->next = CPP_OPTIONS (pfile)->pending;
        !          6249:   CPP_OPTIONS (pfile)->pending = pend;
        !          6250: }
        !          6251: 
        !          6252: /* Handle command-line options in (argc, argv).
        !          6253:    Can be called multiple times, to handle multiple sets of options.
        !          6254:    Returns if an unrecognized option is seen.
        !          6255:    Returns number of handled arguments.  */
        !          6256: 
        !          6257: int
        !          6258: cpp_handle_options (pfile, argc, argv)
        !          6259:      cpp_reader *pfile;
        !          6260:      int argc;
        !          6261:      char **argv;
        !          6262: {
        !          6263:   int i;
        !          6264:   struct cpp_options *opts = CPP_OPTIONS (pfile);
        !          6265:   for (i = 0; i < argc; i++) {
        !          6266:     if (argv[i][0] != '-') {
        !          6267:       if (opts->out_fname != NULL)
        !          6268:        fatal ("Usage: %s [switches] input output", argv[0]);
        !          6269:       else if (opts->in_fname != NULL)
        !          6270:        opts->out_fname = argv[i];
        !          6271:       else
        !          6272:        opts->in_fname = argv[i];
        !          6273:     } else {
        !          6274:       switch (argv[i][1]) {
        !          6275: 
        !          6276:       case 'i':
        !          6277:        if (!strcmp (argv[i], "-include")
        !          6278:            || !strcmp (argv[i], "-imacros")) {
        !          6279:          if (i + 1 == argc)
        !          6280:            fatal ("Filename missing after `%s' option", argv[i]);
        !          6281:          else
        !          6282:            push_pending (pfile, argv[i], argv[i+1]), i++;
        !          6283:        }
        !          6284:        if (!strcmp (argv[i], "-iprefix")) {
        !          6285:          if (i + 1 == argc)
        !          6286:            fatal ("Filename missing after `-iprefix' option");
        !          6287:          else
        !          6288:            opts->include_prefix = argv[++i];
        !          6289:        }
        !          6290:        if (!strcmp (argv[i], "-ifoutput")) {
        !          6291:          opts->output_conditionals = 1;
        !          6292:        }
        !          6293:        if (!strcmp (argv[i], "-isystem")) {
        !          6294:          struct file_name_list *dirtmp;
        !          6295: 
        !          6296:          if (i + 1 == argc)
        !          6297:            fatal ("Filename missing after `-isystem' option");
        !          6298: 
        !          6299:          dirtmp = (struct file_name_list *)
        !          6300:            xmalloc (sizeof (struct file_name_list));
        !          6301:          dirtmp->next = 0;
        !          6302:          dirtmp->control_macro = 0;
        !          6303:          dirtmp->c_system_include_path = 1;
        !          6304:          dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) + 1);
        !          6305:          strcpy (dirtmp->fname, argv[++i]);
        !          6306:          dirtmp->got_name_map = 0;
        !          6307: 
        !          6308:          if (opts->before_system == 0)
        !          6309:            opts->before_system = dirtmp;
        !          6310:          else
        !          6311:            opts->last_before_system->next = dirtmp;
        !          6312:          opts->last_before_system = dirtmp; /* Tail follows the last one */
        !          6313:        }
        !          6314:        /* Add directory to end of path for includes,
        !          6315:           with the default prefix at the front of its name.  */
        !          6316:        if (!strcmp (argv[i], "-iwithprefix")) {
        !          6317:          struct file_name_list *dirtmp;
        !          6318:          char *prefix;
        !          6319: 
        !          6320:          if (opts->include_prefix != 0)
        !          6321:            prefix = opts->include_prefix;
        !          6322:          else {
        !          6323:            prefix = savestring (GCC_INCLUDE_DIR);
        !          6324:            /* Remove the `include' from /usr/local/lib/gcc.../include.  */
        !          6325:            if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
        !          6326:              prefix[strlen (prefix) - 7] = 0;
        !          6327:          }
        !          6328: 
        !          6329:          dirtmp = (struct file_name_list *)
        !          6330:            xmalloc (sizeof (struct file_name_list));
        !          6331:          dirtmp->next = 0;     /* New one goes on the end */
        !          6332:          dirtmp->control_macro = 0;
        !          6333:          dirtmp->c_system_include_path = 0;
        !          6334:          if (i + 1 == argc)
        !          6335:            fatal ("Directory name missing after `-iwithprefix' option");
        !          6336: 
        !          6337:          dirtmp->fname = (char *) xmalloc (strlen (argv[i+1])
        !          6338:                                            + strlen (prefix) + 1);
        !          6339:          strcpy (dirtmp->fname, prefix);
        !          6340:          strcat (dirtmp->fname, argv[++i]);
        !          6341:          dirtmp->got_name_map = 0;
        !          6342: 
        !          6343:          if (opts->after_include == 0)
        !          6344:            opts->after_include = dirtmp;
        !          6345:          else
        !          6346:            opts->last_after_include->next = dirtmp;
        !          6347:          opts->last_after_include = dirtmp; /* Tail follows the last one */
        !          6348:        }
        !          6349:        /* Add directory to main path for includes,
        !          6350:           with the default prefix at the front of its name.  */
        !          6351:        if (!strcmp (argv[i], "-iwithprefixbefore")) {
        !          6352:          struct file_name_list *dirtmp;
        !          6353:          char *prefix;
        !          6354: 
        !          6355:          if (opts->include_prefix != 0)
        !          6356:            prefix = opts->include_prefix;
        !          6357:          else {
        !          6358:            prefix = savestring (GCC_INCLUDE_DIR);
        !          6359:            /* Remove the `include' from /usr/local/lib/gcc.../include.  */
        !          6360:            if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
        !          6361:              prefix[strlen (prefix) - 7] = 0;
        !          6362:          }
        !          6363: 
        !          6364:          dirtmp = (struct file_name_list *)
        !          6365:            xmalloc (sizeof (struct file_name_list));
        !          6366:          dirtmp->next = 0;     /* New one goes on the end */
        !          6367:          dirtmp->control_macro = 0;
        !          6368:          dirtmp->c_system_include_path = 0;
        !          6369:          if (i + 1 == argc)
        !          6370:            fatal ("Directory name missing after `-iwithprefixbefore' option");
        !          6371: 
        !          6372:          dirtmp->fname = (char *) xmalloc (strlen (argv[i+1])
        !          6373:                                            + strlen (prefix) + 1);
        !          6374:          strcpy (dirtmp->fname, prefix);
        !          6375:          strcat (dirtmp->fname, argv[++i]);
        !          6376:          dirtmp->got_name_map = 0;
        !          6377: 
        !          6378:          append_include_chain (pfile, dirtmp, dirtmp);
        !          6379:        }
        !          6380:        /* Add directory to end of path for includes.  */
        !          6381:        if (!strcmp (argv[i], "-idirafter")) {
        !          6382:          struct file_name_list *dirtmp;
        !          6383: 
        !          6384:          dirtmp = (struct file_name_list *)
        !          6385:            xmalloc (sizeof (struct file_name_list));
        !          6386:          dirtmp->next = 0;     /* New one goes on the end */
        !          6387:          dirtmp->control_macro = 0;
        !          6388:          dirtmp->c_system_include_path = 0;
        !          6389:          if (i + 1 == argc)
        !          6390:            fatal ("Directory name missing after `-idirafter' option");
        !          6391:          else
        !          6392:            dirtmp->fname = argv[++i];
        !          6393:          dirtmp->got_name_map = 0;
        !          6394: 
        !          6395:          if (opts->after_include == 0)
        !          6396:            opts->after_include = dirtmp;
        !          6397:          else
        !          6398:            opts->last_after_include->next = dirtmp;
        !          6399:          opts->last_after_include = dirtmp; /* Tail follows the last one */
        !          6400:        }
        !          6401:        break;
        !          6402: 
        !          6403:       case 'o':
        !          6404:        if (opts->out_fname != NULL)
        !          6405:          fatal ("Output filename specified twice");
        !          6406:        if (i + 1 == argc)
        !          6407:          fatal ("Filename missing after -o option");
        !          6408:        opts->out_fname = argv[++i];
        !          6409:        if (!strcmp (opts->out_fname, "-"))
        !          6410:          opts->out_fname = "";
        !          6411:        break;
        !          6412: 
        !          6413:       case 'p':
        !          6414:        if (!strcmp (argv[i], "-pedantic"))
        !          6415:          CPP_PEDANTIC (pfile) = 1;
        !          6416:        else if (!strcmp (argv[i], "-pedantic-errors")) {
        !          6417:          CPP_PEDANTIC (pfile) = 1;
        !          6418:          opts->pedantic_errors = 1;
        !          6419:        }
        !          6420: #if 0
        !          6421:        else if (!strcmp (argv[i], "-pcp")) {
        !          6422:          char *pcp_fname = argv[++i];
        !          6423:          pcp_outfile = 
        !          6424:            ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
        !          6425:             ? fopen (pcp_fname, "w")
        !          6426:             : fdopen (dup (fileno (stdout)), "w"));
        !          6427:          if (pcp_outfile == 0)
        !          6428:            cpp_pfatal_with_name (pfile, pcp_fname);
        !          6429:          no_precomp = 1;
        !          6430:        }
        !          6431: #endif
        !          6432:        break;
        !          6433: 
        !          6434:       case 't':
        !          6435:        if (!strcmp (argv[i], "-traditional")) {
        !          6436:          opts->traditional = 1;
        !          6437:          if (opts->dollars_in_ident > 0)
        !          6438:            opts->dollars_in_ident = 1;
        !          6439:        } else if (!strcmp (argv[i], "-trigraphs")) {
        !          6440:          if (!opts->chill)
        !          6441:            opts->no_trigraphs = 0;
        !          6442:        }
        !          6443:        break;
        !          6444: 
        !          6445:       case 'l':
        !          6446:        if (! strcmp (argv[i], "-lang-c"))
        !          6447:          opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->objc = 0;
        !          6448:        if (! strcmp (argv[i], "-lang-c++"))
        !          6449:          opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->objc = 0;
        !          6450:        if (! strcmp (argv[i], "-lang-c-c++-comments"))
        !          6451:          opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->objc = 0;
        !          6452:        if (! strcmp (argv[i], "-lang-objc"))
        !          6453:          opts->objc = 1, opts->cplusplus = 0, opts->cplusplus_comments = 1;
        !          6454:        if (! strcmp (argv[i], "-lang-objc++"))
        !          6455:          opts->objc = 1, opts->cplusplus = 1, opts->cplusplus_comments = 1;
        !          6456:        if (! strcmp (argv[i], "-lang-asm"))
        !          6457:          opts->lang_asm = 1;
        !          6458:        if (! strcmp (argv[i], "-lint"))
        !          6459:          opts->for_lint = 1;
        !          6460:        if (! strcmp (argv[i], "-lang-chill"))
        !          6461:          opts->objc = 0, opts->cplusplus = 0, opts->chill = 1,
        !          6462:          opts->traditional = 1, opts->no_trigraphs = 1;
        !          6463:        break;
        !          6464: 
        !          6465:       case '+':
        !          6466:        opts->cplusplus = 1, opts->cplusplus_comments = 1;
        !          6467:        break;
        !          6468: 
        !          6469:       case 'w':
        !          6470:        opts->inhibit_warnings = 1;
        !          6471:        break;
        !          6472: 
        !          6473:       case 'W':
        !          6474:        if (!strcmp (argv[i], "-Wtrigraphs"))
        !          6475:          opts->warn_trigraphs = 1;
        !          6476:        else if (!strcmp (argv[i], "-Wno-trigraphs"))
        !          6477:          opts->warn_trigraphs = 0;
        !          6478:        else if (!strcmp (argv[i], "-Wcomment"))
        !          6479:          opts->warn_comments = 1;
        !          6480:        else if (!strcmp (argv[i], "-Wno-comment"))
        !          6481:          opts->warn_comments = 0;
        !          6482:        else if (!strcmp (argv[i], "-Wcomments"))
        !          6483:          opts->warn_comments = 1;
        !          6484:        else if (!strcmp (argv[i], "-Wno-comments"))
        !          6485:          opts->warn_comments = 0;
        !          6486:        else if (!strcmp (argv[i], "-Wtraditional"))
        !          6487:          opts->warn_stringify = 1;
        !          6488:        else if (!strcmp (argv[i], "-Wno-traditional"))
        !          6489:          opts->warn_stringify = 0;
        !          6490:        else if (!strcmp (argv[i], "-Wimport"))
        !          6491:          opts->warn_import = 1;
        !          6492:        else if (!strcmp (argv[i], "-Wno-import"))
        !          6493:          opts->warn_import = 0;
        !          6494:        else if (!strcmp (argv[i], "-Werror"))
        !          6495:          opts->warnings_are_errors = 1;
        !          6496:        else if (!strcmp (argv[i], "-Wno-error"))
        !          6497:          opts->warnings_are_errors = 0;
        !          6498:        else if (!strcmp (argv[i], "-Wall"))
        !          6499:          {
        !          6500:            opts->warn_trigraphs = 1;
        !          6501:            opts->warn_comments = 1;
        !          6502:          }
        !          6503:        break;
        !          6504: 
        !          6505:       case 'M':
        !          6506:        /* The style of the choices here is a bit mixed.
        !          6507:           The chosen scheme is a hybrid of keeping all options in one string
        !          6508:           and specifying each option in a separate argument:
        !          6509:           -M|-MM|-MD file|-MMD file [-MG].  An alternative is:
        !          6510:           -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely:
        !          6511:           -M[M][G][D file].  This is awkward to handle in specs, and is not
        !          6512:           as extensible.  */
        !          6513:        /* ??? -MG must be specified in addition to one of -M or -MM.
        !          6514:           This can be relaxed in the future without breaking anything.
        !          6515:           The converse isn't true.  */
        !          6516: 
        !          6517:        /* -MG isn't valid with -MD or -MMD.  This is checked for later.  */
        !          6518:        if (!strcmp (argv[i], "-MG"))
        !          6519:          {
        !          6520:            opts->print_deps_missing_files = 1;
        !          6521:            break;
        !          6522:          }
        !          6523:        if (!strcmp (argv[i], "-M"))
        !          6524:          opts->print_deps = 2;
        !          6525:        else if (!strcmp (argv[i], "-MM"))
        !          6526:          opts->print_deps = 1;
        !          6527:        else if (!strcmp (argv[i], "-MD"))
        !          6528:          opts->print_deps = 2;
        !          6529:        else if (!strcmp (argv[i], "-MMD"))
        !          6530:          opts->print_deps = 1;
        !          6531:        /* For -MD and -MMD options, write deps on file named by next arg.  */
        !          6532:        if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD"))
        !          6533:          {
        !          6534:            if (i+1 == argc)
        !          6535:              fatal ("Filename missing after %s option", argv[i]);
        !          6536:            opts->deps_file = argv[++i];
        !          6537:          }
        !          6538:        else
        !          6539:          {
        !          6540:            /* For -M and -MM, write deps on standard output
        !          6541:               and suppress the usual output.  */
        !          6542:            opts->no_output = 1;
        !          6543:          }       
        !          6544:        break;
        !          6545: 
        !          6546:       case 'd':
        !          6547:        {
        !          6548:          char *p = argv[i] + 2;
        !          6549:          char c;
        !          6550:          while ((c = *p++) != 0) {
        !          6551:            /* Arg to -d specifies what parts of macros to dump */
        !          6552:            switch (c) {
        !          6553:            case 'M':
        !          6554:              opts->dump_macros = dump_only;
        !          6555:              opts->no_output = 1;
        !          6556:              break;
        !          6557:            case 'N':
        !          6558:              opts->dump_macros = dump_names;
        !          6559:              break;
        !          6560:            case 'D':
        !          6561:              opts->dump_macros = dump_definitions;
        !          6562:              break;
        !          6563:            }
        !          6564:          }
        !          6565:        }
        !          6566:        break;
        !          6567: 
        !          6568:       case 'g':
        !          6569:        if (argv[i][2] == '3')
        !          6570:          opts->debug_output = 1;
        !          6571:        break;
        !          6572: 
        !          6573:       case 'v':
        !          6574:        fprintf (stderr, "GNU CPP version %s", version_string);
        !          6575: #ifdef TARGET_VERSION
        !          6576:        TARGET_VERSION;
        !          6577: #endif
        !          6578:        fprintf (stderr, "\n");
        !          6579:        opts->verbose = 1;
        !          6580:        break;
        !          6581: 
        !          6582:       case 'H':
        !          6583:        opts->print_include_names = 1;
        !          6584:        break;
        !          6585: 
        !          6586:       case 'D':
        !          6587:        if (argv[i][2] != 0)
        !          6588:          push_pending (pfile, "-D", argv[i] + 2);
        !          6589:        else if (i + 1 == argc)
        !          6590:          fatal ("Macro name missing after -D option");
        !          6591:        else
        !          6592:          i++, push_pending (pfile, "-D", argv[i]);
        !          6593:        break;
        !          6594: 
        !          6595:       case 'A':
        !          6596:        {
        !          6597:          char *p;
        !          6598: 
        !          6599:          if (argv[i][2] != 0)
        !          6600:            p = argv[i] + 2;
        !          6601:          else if (i + 1 == argc)
        !          6602:            fatal ("Assertion missing after -A option");
        !          6603:          else
        !          6604:            p = argv[++i];
        !          6605: 
        !          6606:          if (!strcmp (p, "-")) {
        !          6607:            struct cpp_pending **ptr;
        !          6608:            /* -A- eliminates all predefined macros and assertions.
        !          6609:               Let's include also any that were specified earlier
        !          6610:               on the command line.  That way we can get rid of any
        !          6611:               that were passed automatically in from GCC.  */
        !          6612:            int j;
        !          6613:            opts->inhibit_predefs = 1;
        !          6614:            for (ptr = &opts->pending; *ptr != NULL; )
        !          6615:              {
        !          6616:                struct cpp_pending *pend = *ptr;
        !          6617:                if (pend->cmd && pend->cmd[0] == '-'
        !          6618:                    && (pend->cmd[1] == 'D' || pend->cmd[1] == 'A'))
        !          6619:                  {
        !          6620:                    *ptr = pend->next;
        !          6621:                    free (pend);
        !          6622:                  }
        !          6623:                else
        !          6624:                  ptr = &pend->next;
        !          6625:              }
        !          6626:          } else {
        !          6627:            push_pending (pfile, "-A", p);
        !          6628:          }
        !          6629:        }
        !          6630:        break;
        !          6631: 
        !          6632:       case 'U':                /* JF #undef something */
        !          6633:        if (argv[i][2] != 0)
        !          6634:          push_pending (pfile, "-U", argv[i] + 2);
        !          6635:        else if (i + 1 == argc)
        !          6636:          fatal ("Macro name missing after -U option");
        !          6637:        else
        !          6638:          push_pending (pfile, "-U", argv[i+1]), i++;
        !          6639:        break;
        !          6640: 
        !          6641:       case 'C':
        !          6642:        opts->put_out_comments = 1;
        !          6643:        break;
        !          6644: 
        !          6645:       case 'E':                        /* -E comes from cc -E; ignore it.  */
        !          6646:        break;
        !          6647: 
        !          6648:       case 'P':
        !          6649:        opts->no_line_commands = 1;
        !          6650:        break;
        !          6651: 
        !          6652:       case '$':                        /* Don't include $ in identifiers.  */
        !          6653:        opts->dollars_in_ident = 0;
        !          6654:        break;
        !          6655: 
        !          6656:       case 'I':                        /* Add directory to path for includes.  */
        !          6657:        {
        !          6658:          struct file_name_list *dirtmp;
        !          6659: 
        !          6660:          if (! CPP_OPTIONS(pfile)->ignore_srcdir
        !          6661:              && !strcmp (argv[i] + 2, "-")) {
        !          6662:            CPP_OPTIONS (pfile)->ignore_srcdir = 1;
        !          6663:            /* Don't use any preceding -I directories for #include <...>.  */
        !          6664:            CPP_OPTIONS (pfile)->first_bracket_include = 0;
        !          6665:          }
        !          6666:          else {
        !          6667:            dirtmp = (struct file_name_list *)
        !          6668:              xmalloc (sizeof (struct file_name_list));
        !          6669:            dirtmp->next = 0;           /* New one goes on the end */
        !          6670:            dirtmp->control_macro = 0;
        !          6671:            dirtmp->c_system_include_path = 0;
        !          6672:            if (argv[i][2] != 0)
        !          6673:              dirtmp->fname = argv[i] + 2;
        !          6674:            else if (i + 1 == argc)
        !          6675:              fatal ("Directory name missing after -I option");
        !          6676:            else
        !          6677:              dirtmp->fname = argv[++i];
        !          6678:            dirtmp->got_name_map = 0;
        !          6679:            append_include_chain (pfile, dirtmp, dirtmp);
        !          6680:          }
        !          6681:        }
        !          6682:        break;
        !          6683: 
        !          6684:       case 'n':
        !          6685:        if (!strcmp (argv[i], "-nostdinc"))
        !          6686:          /* -nostdinc causes no default include directories.
        !          6687:             You must specify all include-file directories with -I.  */
        !          6688:          opts->no_standard_includes = 1;
        !          6689:        else if (!strcmp (argv[i], "-nostdinc++"))
        !          6690:          /* -nostdinc++ causes no default C++-specific include directories. */
        !          6691:          opts->no_standard_cplusplus_includes = 1;
        !          6692: #if 0
        !          6693:        else if (!strcmp (argv[i], "-noprecomp"))
        !          6694:          no_precomp = 1;
        !          6695: #endif
        !          6696:        break;
        !          6697: 
        !          6698:       case 'u':
        !          6699:        /* Sun compiler passes undocumented switch "-undef".
        !          6700:           Let's assume it means to inhibit the predefined symbols.  */
        !          6701:        opts->inhibit_predefs = 1;
        !          6702:        break;
        !          6703: 
        !          6704:       case '\0': /* JF handle '-' as file name meaning stdin or stdout */
        !          6705:        if (opts->in_fname == NULL) {
        !          6706:          opts->in_fname = "";
        !          6707:          break;
        !          6708:        } else if (opts->out_fname == NULL) {
        !          6709:          opts->out_fname = "";
        !          6710:          break;
        !          6711:        }       /* else fall through into error */
        !          6712: 
        !          6713:       default:
        !          6714:        return i;
        !          6715:       }
        !          6716:     }
        !          6717:   }
        !          6718:   return i;
        !          6719: }
        !          6720: 
        !          6721: void
        !          6722: cpp_finish (pfile)
        !          6723:      cpp_reader *pfile;
        !          6724: {
        !          6725:   struct cpp_options *opts = CPP_OPTIONS (pfile);
        !          6726:   
        !          6727:   if (opts->print_deps)
        !          6728:     {
        !          6729:       /* Stream on which to print the dependency information.  */
        !          6730:       FILE *deps_stream;
        !          6731: 
        !          6732:       /* Don't actually write the deps file if compilation has failed.  */
        !          6733:       if (pfile->errors == 0)
        !          6734:        {
        !          6735:          char *deps_mode = opts->print_deps_append ? "a" : "w";
        !          6736:          if (opts->deps_file == 0)
        !          6737:            deps_stream = stdout;
        !          6738:          else if ((deps_stream = fopen (opts->deps_file, deps_mode)) == 0)
        !          6739:            cpp_pfatal_with_name (pfile, opts->deps_file);
        !          6740:          fputs (pfile->deps_buffer, deps_stream);
        !          6741:          putc ('\n', deps_stream);
        !          6742:          if (opts->deps_file)
        !          6743:            {
        !          6744:              if (ferror (deps_stream) || fclose (deps_stream) != 0)
        !          6745:                fatal ("I/O error on output");
        !          6746:            }
        !          6747:        }
        !          6748:     }
        !          6749: }
        !          6750: 
        !          6751: /* Free resources used by PFILE. */
        !          6752: 
        !          6753: void
        !          6754: cpp_cleanup (pfile)
        !          6755:      cpp_reader *pfile;
        !          6756: {
        !          6757:   int i;
        !          6758:   while ( CPP_BUFFER (pfile) != CPP_NULL_BUFFER (pfile))
        !          6759:     cpp_pop_buffer (pfile);
        !          6760: 
        !          6761:   if (pfile->token_buffer)
        !          6762:     {
        !          6763:       free (pfile->token_buffer);
        !          6764:       pfile->token_buffer = NULL;
        !          6765:     }
        !          6766: 
        !          6767:   if (pfile->deps_buffer)
        !          6768:     {
        !          6769:       free (pfile->deps_buffer);
        !          6770:       pfile->deps_buffer = NULL;
        !          6771:       pfile->deps_allocated_size = 0;
        !          6772:     }
        !          6773: 
        !          6774:   while (pfile->if_stack)
        !          6775:     {
        !          6776:       IF_STACK_FRAME *temp = pfile->if_stack;
        !          6777:       pfile->if_stack = temp->next;
        !          6778:       free (temp);
        !          6779:     }
        !          6780: 
        !          6781:   while (pfile->dont_repeat_files)
        !          6782:     {
        !          6783:       struct file_name_list *temp = pfile->dont_repeat_files;
        !          6784:       pfile->dont_repeat_files = temp->next;
        !          6785:       free (temp->fname);
        !          6786:       free (temp);
        !          6787:     }
        !          6788: 
        !          6789:   while (pfile->all_include_files)
        !          6790:     {
        !          6791:       struct file_name_list *temp = pfile->all_include_files;
        !          6792:       pfile->all_include_files = temp->next;
        !          6793:       free (temp->fname);
        !          6794:       free (temp);
        !          6795:     }
        !          6796: 
        !          6797:   for (i = IMPORT_HASH_SIZE; --i >= 0; )
        !          6798:     {
        !          6799:       register struct import_file *imp = pfile->import_hash_table[i];
        !          6800:       while (imp)
        !          6801:        {
        !          6802:          struct import_file *next = imp->next;
        !          6803:          free (imp->name);
        !          6804:          free (imp);
        !          6805:          imp = next;
        !          6806:        }
        !          6807:       pfile->import_hash_table[i] = 0;
        !          6808:     }
        !          6809: 
        !          6810:   for (i = ASSERTION_HASHSIZE; --i >= 0; )
        !          6811:     {
        !          6812:       while (pfile->assertion_hashtab[i])
        !          6813:        delete_assertion (pfile->assertion_hashtab[i]);
        !          6814:     }
        !          6815: 
        !          6816:   cpp_hash_cleanup (pfile);
        !          6817: }
        !          6818: 
        !          6819: static int
        !          6820: do_assert (pfile, keyword, buf, limit)
        !          6821:      cpp_reader *pfile;
        !          6822:      struct directive *keyword;
        !          6823:      U_CHAR *buf, *limit;
        !          6824: {
        !          6825:   long symstart;               /* remember where symbol name starts */
        !          6826:   int c;
        !          6827:   int sym_length;              /* and how long it is */
        !          6828:   struct arglist *tokens = NULL;
        !          6829: 
        !          6830:   if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing
        !          6831:       && !CPP_BUFFER (pfile)->system_header_p)
        !          6832:     cpp_pedwarn (pfile, "ANSI C does not allow `#assert'");
        !          6833: 
        !          6834:   cpp_skip_hspace (pfile);
        !          6835:   symstart = CPP_WRITTEN (pfile);      /* remember where it starts */
        !          6836:   parse_name (pfile, GETC());
        !          6837:   sym_length = check_macro_name (pfile, pfile->token_buffer + symstart,
        !          6838:                                 "assertion");
        !          6839: 
        !          6840:   cpp_skip_hspace (pfile);
        !          6841:   if (PEEKC() != '(') {
        !          6842:     cpp_error (pfile, "missing token-sequence in `#assert'");
        !          6843:     goto error;
        !          6844:   }
        !          6845: 
        !          6846:   {
        !          6847:     int error_flag = 0;
        !          6848:     tokens = read_token_list (pfile, &error_flag);
        !          6849:     if (error_flag)
        !          6850:       goto error;
        !          6851:     if (tokens == 0) {
        !          6852:       cpp_error (pfile, "empty token-sequence in `#assert'");
        !          6853:       goto error;
        !          6854:     }
        !          6855:   cpp_skip_hspace (pfile);
        !          6856:   c = PEEKC ();
        !          6857:   if (c != EOF && c != '\n')
        !          6858:       cpp_pedwarn (pfile, "junk at end of `#assert'");
        !          6859:   skip_rest_of_line (pfile);
        !          6860:   }
        !          6861: 
        !          6862:   /* If this name isn't already an assertion name, make it one.
        !          6863:      Error if it was already in use in some other way.  */
        !          6864: 
        !          6865:   {
        !          6866:     ASSERTION_HASHNODE *hp;
        !          6867:     U_CHAR *symname = pfile->token_buffer + symstart;
        !          6868:     int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
        !          6869:     struct tokenlist_list *value
        !          6870:       = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list));
        !          6871: 
        !          6872:     hp = assertion_lookup (pfile, symname, sym_length, hashcode);
        !          6873:     if (hp == NULL) {
        !          6874:       if (sym_length == 7 && ! strncmp (symname, "defined", sym_length))
        !          6875:        cpp_error (pfile, "`defined' redefined as assertion");
        !          6876:       hp = assertion_install (pfile, symname, sym_length, hashcode);
        !          6877:     }
        !          6878: 
        !          6879:     /* Add the spec'd token-sequence to the list of such.  */
        !          6880:     value->tokens = tokens;
        !          6881:     value->next = hp->value;
        !          6882:     hp->value = value;
        !          6883:   }
        !          6884:   CPP_SET_WRITTEN (pfile, symstart); /* Pop */
        !          6885:   return 0;
        !          6886:  error:
        !          6887:   CPP_SET_WRITTEN (pfile, symstart); /* Pop */
        !          6888:   skip_rest_of_line (pfile);
        !          6889:   return 1;
        !          6890: }
        !          6891: 
        !          6892: static int
        !          6893: do_unassert (pfile, keyword, buf, limit)
        !          6894:      cpp_reader *pfile;
        !          6895:      struct directive *keyword;
        !          6896:      U_CHAR *buf, *limit;
        !          6897: {
        !          6898:   long symstart;               /* remember where symbol name starts */
        !          6899:   int sym_length;      /* and how long it is */
        !          6900:   int c;
        !          6901: 
        !          6902:   struct arglist *tokens = NULL;
        !          6903:   int tokens_specified = 0;
        !          6904: 
        !          6905:   if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing
        !          6906:       && !CPP_BUFFER (pfile)->system_header_p)
        !          6907:     cpp_pedwarn (pfile, "ANSI C does not allow `#unassert'");
        !          6908: 
        !          6909:   cpp_skip_hspace (pfile);
        !          6910: 
        !          6911:   symstart = CPP_WRITTEN (pfile);      /* remember where it starts */
        !          6912:   parse_name (pfile, GETC());
        !          6913:   sym_length = check_macro_name (pfile, pfile->token_buffer + symstart,
        !          6914:                                 "assertion");
        !          6915: 
        !          6916:   cpp_skip_hspace (pfile);
        !          6917:   if (PEEKC() == '(') {
        !          6918:     int error_flag = 0;
        !          6919: 
        !          6920:     tokens = read_token_list (pfile, &error_flag);
        !          6921:     if (error_flag)
        !          6922:       goto error;
        !          6923:     if (tokens == 0) {
        !          6924:       cpp_error (pfile, "empty token list in `#unassert'");
        !          6925:       goto error;
        !          6926:     }
        !          6927: 
        !          6928:     tokens_specified = 1;
        !          6929:   }
        !          6930: 
        !          6931:   cpp_skip_hspace (pfile);
        !          6932:   c = PEEKC ();
        !          6933:   if (c != EOF && c != '\n')
        !          6934:       cpp_error (pfile, "junk at end of `#unassert'");
        !          6935:   skip_rest_of_line (pfile);
        !          6936: 
        !          6937:   {
        !          6938:     ASSERTION_HASHNODE *hp;
        !          6939:     U_CHAR *symname = pfile->token_buffer + symstart;
        !          6940:     int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
        !          6941:     struct tokenlist_list *tail, *prev;
        !          6942: 
        !          6943:     hp = assertion_lookup (pfile, symname, sym_length, hashcode);
        !          6944:     if (hp == NULL)
        !          6945:       return 1;
        !          6946: 
        !          6947:     /* If no token list was specified, then eliminate this assertion
        !          6948:        entirely.  */
        !          6949:     if (! tokens_specified)
        !          6950:       delete_assertion (hp);
        !          6951:     else {
        !          6952:       /* If a list of tokens was given, then delete any matching list.  */
        !          6953: 
        !          6954:       tail = hp->value;
        !          6955:       prev = 0;
        !          6956:       while (tail) {
        !          6957:        struct tokenlist_list *next = tail->next;
        !          6958:        if (compare_token_lists (tail->tokens, tokens)) {
        !          6959:          if (prev)
        !          6960:            prev->next = next;
        !          6961:          else
        !          6962:            hp->value = tail->next;
        !          6963:          free_token_list (tail->tokens);
        !          6964:          free (tail);
        !          6965:        } else {
        !          6966:          prev = tail;
        !          6967:        }
        !          6968:        tail = next;
        !          6969:       }
        !          6970:     }
        !          6971:   }
        !          6972: 
        !          6973:   CPP_SET_WRITTEN (pfile, symstart); /* Pop */
        !          6974:   return 0;
        !          6975:  error:
        !          6976:   CPP_SET_WRITTEN (pfile, symstart); /* Pop */
        !          6977:   skip_rest_of_line (pfile);
        !          6978:   return 1;
        !          6979: }
        !          6980: 
        !          6981: /* Test whether there is an assertion named NAME
        !          6982:    and optionally whether it has an asserted token list TOKENS.
        !          6983:    NAME is not null terminated; its length is SYM_LENGTH.
        !          6984:    If TOKENS_SPECIFIED is 0, then don't check for any token list.  */
        !          6985: 
        !          6986: int
        !          6987: check_assertion (pfile, name, sym_length, tokens_specified, tokens)
        !          6988:      cpp_reader *pfile;
        !          6989:      U_CHAR *name;
        !          6990:      int sym_length;
        !          6991:      int tokens_specified;
        !          6992:      struct arglist *tokens;
        !          6993: {
        !          6994:   ASSERTION_HASHNODE *hp;
        !          6995:   int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE);
        !          6996: 
        !          6997:   if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
        !          6998:     cpp_pedwarn (pfile, "ANSI C does not allow testing assertions");
        !          6999: 
        !          7000:   hp = assertion_lookup (pfile, name, sym_length, hashcode);
        !          7001:   if (hp == NULL)
        !          7002:     /* It is not an assertion; just return false.  */
        !          7003:     return 0;
        !          7004: 
        !          7005:   /* If no token list was specified, then value is 1.  */
        !          7006:   if (! tokens_specified)
        !          7007:     return 1;
        !          7008: 
        !          7009:   {
        !          7010:     struct tokenlist_list *tail;
        !          7011: 
        !          7012:     tail = hp->value;
        !          7013: 
        !          7014:     /* If a list of tokens was given,
        !          7015:        then succeed if the assertion records a matching list.  */
        !          7016: 
        !          7017:     while (tail) {
        !          7018:       if (compare_token_lists (tail->tokens, tokens))
        !          7019:        return 1;
        !          7020:       tail = tail->next;
        !          7021:     }
        !          7022: 
        !          7023:     /* Fail if the assertion has no matching list.  */
        !          7024:     return 0;
        !          7025:   }
        !          7026: }
        !          7027: 
        !          7028: /* Compare two lists of tokens for equality including order of tokens.  */
        !          7029: 
        !          7030: static int
        !          7031: compare_token_lists (l1, l2)
        !          7032:      struct arglist *l1, *l2;
        !          7033: {
        !          7034:   while (l1 && l2) {
        !          7035:     if (l1->length != l2->length)
        !          7036:       return 0;
        !          7037:     if (strncmp (l1->name, l2->name, l1->length))
        !          7038:       return 0;
        !          7039:     l1 = l1->next;
        !          7040:     l2 = l2->next;
        !          7041:   }
        !          7042: 
        !          7043:   /* Succeed if both lists end at the same time.  */
        !          7044:   return l1 == l2;
        !          7045: }
        !          7046: 
        !          7047: struct arglist *
        !          7048: reverse_token_list (tokens)
        !          7049:      struct arglist *tokens;
        !          7050: {
        !          7051:   register struct arglist *prev = 0, *this, *next;
        !          7052:   for (this = tokens; this; this = next)
        !          7053:     {
        !          7054:       next = this->next;
        !          7055:       this->next = prev;
        !          7056:       prev = this;
        !          7057:     }
        !          7058:   return prev;
        !          7059: }
        !          7060: 
        !          7061: /* Read a space-separated list of tokens ending in a close parenthesis.
        !          7062:    Return a list of strings, in the order they were written.
        !          7063:    (In case of error, return 0 and store -1 in *ERROR_FLAG.) */
        !          7064: 
        !          7065: static struct arglist *
        !          7066: read_token_list (pfile, error_flag)
        !          7067:      cpp_reader *pfile;
        !          7068:      int *error_flag;
        !          7069: {
        !          7070:   struct arglist *token_ptrs = 0;
        !          7071:   int depth = 1;
        !          7072:   int length;
        !          7073: 
        !          7074:   *error_flag = 0;
        !          7075:   FORWARD (1);  /* Skip '(' */
        !          7076: 
        !          7077:   /* Loop over the assertion value tokens.  */
        !          7078:   while (depth > 0)
        !          7079:     {
        !          7080:       struct arglist *temp;
        !          7081:       long name_written = CPP_WRITTEN (pfile);
        !          7082:       int eofp = 0;  int c;
        !          7083: 
        !          7084:       cpp_skip_hspace (pfile);
        !          7085: 
        !          7086:       c = GETC ();
        !          7087:          
        !          7088:       /* Find the end of the token.  */
        !          7089:       if (c == '(')
        !          7090:         {
        !          7091:          CPP_PUTC (pfile, c);
        !          7092:          depth++;
        !          7093:         }
        !          7094:       else if (c == ')')
        !          7095:         {
        !          7096:          depth--;
        !          7097:          if (depth == 0)
        !          7098:            break;
        !          7099:          CPP_PUTC (pfile, c);
        !          7100:         }
        !          7101:       else if (c == '"' || c == '\'')
        !          7102:         {
        !          7103:          FORWARD(-1);
        !          7104:          cpp_get_token (pfile);
        !          7105:         }
        !          7106:       else if (c == '\n')
        !          7107:        break;
        !          7108:       else
        !          7109:         {
        !          7110:          while (c != EOF && ! is_space[c] && c != '(' && c != ')'
        !          7111:                 && c != '"' && c != '\'')
        !          7112:            {
        !          7113:              CPP_PUTC (pfile, c);
        !          7114:              c = GETC();
        !          7115:            }
        !          7116:          if (c != EOF)  FORWARD(-1);
        !          7117:         }
        !          7118: 
        !          7119:       length = CPP_WRITTEN (pfile) - name_written;
        !          7120:       temp = (struct arglist *)
        !          7121:          xmalloc (sizeof (struct arglist) + length + 1);
        !          7122:       temp->name = (U_CHAR *) (temp + 1);
        !          7123:       bcopy ((char *) (pfile->token_buffer + name_written),
        !          7124:             (char *) temp->name, length);
        !          7125:       temp->name[length] = 0;
        !          7126:       temp->next = token_ptrs;
        !          7127:       token_ptrs = temp;
        !          7128:       temp->length = length;
        !          7129: 
        !          7130:       CPP_ADJUST_WRITTEN (pfile, -length); /* pop */
        !          7131: 
        !          7132:       if (c == EOF || c == '\n')
        !          7133:         { /* FIXME */
        !          7134:          cpp_error (pfile,
        !          7135:                     "unterminated token sequence following  `#' operator");
        !          7136:          return 0;
        !          7137:        }
        !          7138:     }
        !          7139: 
        !          7140:   /* We accumulated the names in reverse order.
        !          7141:      Now reverse them to get the proper order.  */
        !          7142:   return reverse_token_list (token_ptrs);
        !          7143: }
        !          7144: 
        !          7145: static void
        !          7146: free_token_list (tokens)
        !          7147:      struct arglist *tokens;
        !          7148: {
        !          7149:   while (tokens) {
        !          7150:     struct arglist *next = tokens->next;
        !          7151:     free (tokens->name);
        !          7152:     free (tokens);
        !          7153:     tokens = next;
        !          7154:   }
        !          7155: }
        !          7156: 
        !          7157: /* Get the file-mode and data size of the file open on FD
        !          7158:    and store them in *MODE_POINTER and *SIZE_POINTER.  */
        !          7159: 
        !          7160: static int
        !          7161: file_size_and_mode (fd, mode_pointer, size_pointer)
        !          7162:      int fd;
        !          7163:      int *mode_pointer;
        !          7164:      long int *size_pointer;
        !          7165: {
        !          7166:   struct stat sbuf;
        !          7167: 
        !          7168:   if (fstat (fd, &sbuf) < 0) return (-1);
        !          7169:   if (mode_pointer) *mode_pointer = sbuf.st_mode;
        !          7170:   if (size_pointer) *size_pointer = sbuf.st_size;
        !          7171:   return 0;
        !          7172: }
        !          7173: 
        !          7174: /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
        !          7175:    retrying if necessary.  Return a negative value if an error occurs,
        !          7176:    otherwise return the actual number of bytes read,
        !          7177:    which must be LEN unless end-of-file was reached.  */
        !          7178: 
        !          7179: static int
        !          7180: safe_read (desc, ptr, len)
        !          7181:      int desc;
        !          7182:      char *ptr;
        !          7183:      int len;
        !          7184: {
        !          7185:   int left = len;
        !          7186:   while (left > 0) {
        !          7187:     int nchars = read (desc, ptr, left);
        !          7188:     if (nchars < 0)
        !          7189:       {
        !          7190: #ifdef EINTR
        !          7191:        if (errno == EINTR)
        !          7192:          continue;
        !          7193: #endif
        !          7194:        return nchars;
        !          7195:       }
        !          7196:     if (nchars == 0)
        !          7197:       break;
        !          7198:     ptr += nchars;
        !          7199:     left -= nchars;
        !          7200:   }
        !          7201:   return len - left;
        !          7202: }
        !          7203: 
        !          7204: static char *
        !          7205: savestring (input)
        !          7206:      char *input;
        !          7207: {
        !          7208:   unsigned size = strlen (input);
        !          7209:   char *output = xmalloc (size + 1);
        !          7210:   strcpy (output, input);
        !          7211:   return output;
        !          7212: }
        !          7213: 
        !          7214: /* Initialize PMARK to remember the current position of PFILE. */
        !          7215: void
        !          7216: parse_set_mark (pmark, pfile)
        !          7217:      struct parse_marker *pmark;
        !          7218:      cpp_reader *pfile;
        !          7219: {
        !          7220:   cpp_buffer *pbuf = CPP_BUFFER (pfile);
        !          7221:   pmark->next = pbuf->marks;
        !          7222:   pbuf->marks = pmark;
        !          7223:   pmark->buf = pbuf;
        !          7224:   pmark->position = pbuf->cur - pbuf->buf;
        !          7225: }
        !          7226: 
        !          7227: /* Cleanup PMARK - we no longer need it. */
        !          7228: void
        !          7229: parse_clear_mark (pmark)
        !          7230:      struct parse_marker *pmark;
        !          7231: {
        !          7232:   struct parse_marker **pp = &pmark->buf->marks;
        !          7233:   for (; ; pp = &(*pp)->next) {
        !          7234:     if (*pp == NULL) fatal ("internal error", "in parse_set_mark");
        !          7235:     if (*pp == pmark) break;
        !          7236:   }
        !          7237:   *pp = pmark->next;
        !          7238: }
        !          7239: 
        !          7240: /* Backup the current position of PFILE to that saved in PMARK. */
        !          7241: 
        !          7242: void
        !          7243: parse_goto_mark (pmark, pfile)
        !          7244:      struct parse_marker *pmark;
        !          7245:      cpp_reader *pfile;
        !          7246: {
        !          7247:   cpp_buffer *pbuf = CPP_BUFFER (pfile);
        !          7248:   if (pbuf != pmark->buf)
        !          7249:     fatal ("internal error %s", "parse_goto_mark");
        !          7250:   pbuf->cur = pbuf->buf + pmark->position;
        !          7251: }
        !          7252: 
        !          7253: /* Reset PMARK to point to the current position of PFILE.  (Same
        !          7254:    as parse_clear_mark (PMARK), parse_set_mark (PMARK, PFILE) but faster. */
        !          7255: 
        !          7256: void
        !          7257: parse_move_mark (pmark, pfile)
        !          7258:      struct parse_marker *pmark;
        !          7259:      cpp_reader *pfile;
        !          7260: {
        !          7261:   cpp_buffer *pbuf = CPP_BUFFER (pfile);
        !          7262:   if (pbuf != pmark->buf)
        !          7263:     fatal ("internal error %s", "parse_move_mark");
        !          7264:   pmark->position = pbuf->cur - pbuf->buf;
        !          7265: }
        !          7266: 
        !          7267: int
        !          7268: cpp_read_check_assertion (pfile)
        !          7269:      cpp_reader *pfile;
        !          7270: {
        !          7271:   int name_start = CPP_WRITTEN (pfile);
        !          7272:   int name_length, name_written;
        !          7273:   int result;
        !          7274:   FORWARD (1);  /* Skip '#' */
        !          7275:   cpp_skip_hspace (pfile);
        !          7276:   parse_name (pfile, GETC ());
        !          7277:   name_written = CPP_WRITTEN (pfile);
        !          7278:   name_length = name_written - name_start;
        !          7279:   cpp_skip_hspace (pfile);
        !          7280:   if (CPP_BUF_PEEK (CPP_BUFFER (pfile)) == '(')
        !          7281:     {
        !          7282:       int error_flag;
        !          7283:       struct arglist *token_ptrs = read_token_list (pfile, &error_flag);
        !          7284:       result = check_assertion (pfile,
        !          7285:                                pfile->token_buffer + name_start, name_length,
        !          7286:                                1, token_ptrs);
        !          7287:     }
        !          7288:   else
        !          7289:     result = check_assertion (pfile,
        !          7290:                              pfile->token_buffer + name_start, name_length,
        !          7291:                              0, NULL_PTR);
        !          7292:   CPP_ADJUST_WRITTEN (pfile, - name_length);  /* pop */
        !          7293:   return result;
        !          7294: }
        !          7295: 
        !          7296: void
        !          7297: cpp_print_file_and_line (pfile)
        !          7298:      cpp_reader *pfile;
        !          7299: {
        !          7300:   cpp_buffer *ip = cpp_file_buffer (pfile);
        !          7301: 
        !          7302:   if (ip != NULL)
        !          7303:     {
        !          7304:       long line, col;
        !          7305:       cpp_buf_line_and_col (ip, &line, &col);
        !          7306:       cpp_file_line_for_message (pfile, ip->nominal_fname,
        !          7307:                                 line, pfile->show_column ? col : -1);
        !          7308:     }
        !          7309: }
        !          7310: 
        !          7311: void
        !          7312: cpp_error (pfile, msg, arg1, arg2, arg3)
        !          7313:      cpp_reader *pfile;
        !          7314:      char *msg;
        !          7315:      char *arg1, *arg2, *arg3;
        !          7316: {
        !          7317:   cpp_print_containing_files (pfile);
        !          7318:   cpp_print_file_and_line (pfile);
        !          7319:   cpp_message (pfile, 1, msg, arg1, arg2, arg3);
        !          7320: }
        !          7321: 
        !          7322: /* Print error message but don't count it.  */
        !          7323: 
        !          7324: void
        !          7325: cpp_warning (pfile, msg, arg1, arg2, arg3)
        !          7326:      cpp_reader *pfile;
        !          7327:      char *msg;
        !          7328:      char *arg1, *arg2, *arg3;
        !          7329: {
        !          7330:   if (CPP_OPTIONS (pfile)->inhibit_warnings)
        !          7331:     return;
        !          7332: 
        !          7333:   if (CPP_OPTIONS (pfile)->warnings_are_errors)
        !          7334:     pfile->errors++;
        !          7335: 
        !          7336:   cpp_print_containing_files (pfile);
        !          7337:   cpp_print_file_and_line (pfile);
        !          7338:   cpp_message (pfile, 0, msg, arg1, arg2, arg3);
        !          7339: }
        !          7340: 
        !          7341: /* Print an error message and maybe count it.  */
        !          7342: 
        !          7343: void
        !          7344: cpp_pedwarn (pfile, msg, arg1, arg2, arg3)
        !          7345:      cpp_reader *pfile;
        !          7346:      char *msg;
        !          7347:      char *arg1, *arg2, *arg3;
        !          7348: {
        !          7349:   if (CPP_OPTIONS (pfile)->pedantic_errors)
        !          7350:     cpp_error (pfile, msg, arg1, arg2, arg3);
        !          7351:   else
        !          7352:     cpp_warning (pfile, msg, arg1, arg2, arg3);
        !          7353: }
        !          7354: 
        !          7355: void
        !          7356: cpp_error_with_line (pfile, line, column, msg, arg1, arg2, arg3)
        !          7357:      cpp_reader *pfile;
        !          7358:      int line, column;
        !          7359:      char *msg;
        !          7360:      char *arg1, *arg2, *arg3;
        !          7361: {
        !          7362:   int i;
        !          7363:   cpp_buffer *ip = cpp_file_buffer (pfile);
        !          7364: 
        !          7365:   cpp_print_containing_files (pfile);
        !          7366: 
        !          7367:   if (ip != NULL)
        !          7368:     cpp_file_line_for_message (pfile, ip->nominal_fname, line, column);
        !          7369: 
        !          7370:   cpp_message (pfile, 1, msg, arg1, arg2, arg3);
        !          7371: }
        !          7372: 
        !          7373: static void
        !          7374: cpp_warning_with_line (pfile, line, column, msg, arg1, arg2, arg3)
        !          7375:      cpp_reader *pfile;
        !          7376:      int line, column;
        !          7377:      char *msg;
        !          7378:      char *arg1, *arg2, *arg3;
        !          7379: {
        !          7380:   int i;
        !          7381:   cpp_buffer *ip;
        !          7382: 
        !          7383:   if (CPP_OPTIONS (pfile)->inhibit_warnings)
        !          7384:     return;
        !          7385: 
        !          7386:   if (CPP_OPTIONS (pfile)->warnings_are_errors)
        !          7387:     pfile->errors++;
        !          7388: 
        !          7389:   cpp_print_containing_files (pfile);
        !          7390: 
        !          7391:   ip = cpp_file_buffer (pfile);
        !          7392: 
        !          7393:   if (ip != NULL)
        !          7394:     cpp_file_line_for_message (pfile, ip->nominal_fname, line, column);
        !          7395: 
        !          7396:   cpp_message (pfile, 0, msg, arg1, arg2, arg3);
        !          7397: }
        !          7398: 
        !          7399: void
        !          7400: cpp_pedwarn_with_line (pfile, line, column, msg, arg1, arg2, arg3)
        !          7401:      cpp_reader *pfile;
        !          7402:      int line;
        !          7403:      char *msg;
        !          7404:      char *arg1, *arg2, *arg3;
        !          7405: {
        !          7406:   if (CPP_OPTIONS (pfile)->pedantic_errors)
        !          7407:     cpp_error_with_line (pfile, column, line, msg, arg1, arg2, arg3);
        !          7408:   else
        !          7409:     cpp_warning_with_line (pfile, line, column, msg, arg1, arg2, arg3);
        !          7410: }
        !          7411: 
        !          7412: /* Report a warning (or an error if pedantic_errors)
        !          7413:    giving specified file name and line number, not current.  */
        !          7414: 
        !          7415: void
        !          7416: cpp_pedwarn_with_file_and_line (pfile, file, line, msg, arg1, arg2, arg3)
        !          7417:      cpp_reader *pfile;
        !          7418:      char *file;
        !          7419:      int line;
        !          7420:      char *msg;
        !          7421:      char *arg1, *arg2, *arg3;
        !          7422: {
        !          7423:   if (!CPP_OPTIONS (pfile)->pedantic_errors
        !          7424:       && CPP_OPTIONS (pfile)->inhibit_warnings)
        !          7425:     return;
        !          7426:   if (file != NULL)
        !          7427:     cpp_file_line_for_message (pfile, file, line, -1);
        !          7428:   cpp_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors,
        !          7429:               msg, arg1, arg2, arg3);
        !          7430: }
        !          7431: 
        !          7432: /* This defines "errno" properly for VMS, and gives us EACCES. */
        !          7433: #include <errno.h>
        !          7434: #ifndef errno
        !          7435: extern int errno;
        !          7436: #endif
        !          7437: 
        !          7438: #ifndef VMS
        !          7439: #ifndef HAVE_STRERROR
        !          7440: extern int sys_nerr;
        !          7441: #if defined(bsd4_4)
        !          7442: extern const char *const sys_errlist[];
        !          7443: #else
        !          7444: extern char *sys_errlist[];
        !          7445: #endif
        !          7446: #else  /* HAVE_STRERROR */
        !          7447: char *strerror ();
        !          7448: #endif
        !          7449: #else  /* VMS */
        !          7450: char *strerror (int,...);
        !          7451: #endif
        !          7452: 
        !          7453: /*
        !          7454:  * my_strerror - return the descriptive text associated with an `errno' code.
        !          7455:  */
        !          7456: 
        !          7457: char *
        !          7458: my_strerror (errnum)
        !          7459:      int errnum;
        !          7460: {
        !          7461:   char *result;
        !          7462: 
        !          7463: #ifndef VMS
        !          7464: #ifndef HAVE_STRERROR
        !          7465:   result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0);
        !          7466: #else
        !          7467:   result = strerror (errnum);
        !          7468: #endif
        !          7469: #else  /* VMS */
        !          7470:   /* VAXCRTL's strerror() takes an optional second argument, which only
        !          7471:      matters when the first argument is EVMSERR.  However, it's simplest
        !          7472:      just to pass it unconditionally.  `vaxc$errno' is declared in
        !          7473:      <errno.h>, and maintained by the library in parallel with `errno'.
        !          7474:      We assume that caller's `errnum' either matches the last setting of
        !          7475:      `errno' by the library or else does not have the value `EVMSERR'.  */
        !          7476: 
        !          7477:   result = strerror (errnum, vaxc$errno);
        !          7478: #endif
        !          7479: 
        !          7480:   if (!result)
        !          7481:     result = "undocumented I/O error";
        !          7482: 
        !          7483:   return result;
        !          7484: }
        !          7485: 
        !          7486: /* Error including a message from `errno'.  */
        !          7487: 
        !          7488: void
        !          7489: cpp_error_from_errno (pfile, name)
        !          7490:      cpp_reader *pfile;
        !          7491:      char *name;
        !          7492: {
        !          7493:   int i;
        !          7494:   cpp_buffer *ip = cpp_file_buffer (pfile);
        !          7495: 
        !          7496:   cpp_print_containing_files (pfile);
        !          7497: 
        !          7498:   if (ip != NULL)
        !          7499:     cpp_file_line_for_message (pfile, ip->nominal_fname, ip->lineno, -1);
        !          7500: 
        !          7501:   cpp_message (pfile, 1, "%s: %s", name, my_strerror (errno));
        !          7502: }
        !          7503: 
        !          7504: void
        !          7505: cpp_perror_with_name (pfile, name)
        !          7506:      cpp_reader *pfile;
        !          7507:      char *name;
        !          7508: {
        !          7509:   cpp_message (pfile, 1, "%s: %s: %s", progname, name, my_strerror (errno));
        !          7510: }
        !          7511: 
        !          7512: /* TODO:
        !          7513:  * No pre-compiled header file support.
        !          7514:  *
        !          7515:  * Possibly different enum token codes for each C/C++ token.
        !          7516:  *
        !          7517:  * Should clean up remaining directives to that do_XXX functions
        !          7518:  *   only take two arguments and all have command_reads_line.
        !          7519:  *
        !          7520:  * Find and cleanup remaining uses of static variables,
        !          7521:  *
        !          7522:  * Support for trigraphs.
        !          7523:  *
        !          7524:  * Support -dM flag (dump_all_macros).
        !          7525:  *
        !          7526:  * Support for_lint flag.
        !          7527:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.