Annotation of gcc/cccp.c, revision 1.1.1.7

1.1       root        1: /* C Compatible Compiler Preprocessor (CCCP)
1.1.1.7 ! root        2:    Copyright (C) 1986, 87, 89, 92, 93, 1994 Free Software Foundation, Inc.
        !             3:    Written by Paul Rubin, June 1986
        !             4:    Adapted to ANSI C, Richard Stallman, Jan 1987
1.1       root        5: 
                      6: This program is free software; you can redistribute it and/or modify it
                      7: under the terms of the GNU General Public License as published by the
                      8: Free Software Foundation; either version 2, or (at your option) any
                      9: later version.
                     10: 
                     11: This program is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with this program; if not, write to the Free Software
                     18: Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
                     19: 
                     20:  In other words, you are welcome to use, share and improve this program.
                     21:  You are forbidden to forbid anyone else to use, share and improve
                     22:  what you give them.   Help stamp out software-hoarding!  */
                     23: 
                     24: typedef unsigned char U_CHAR;
                     25: 
                     26: #ifdef EMACS
                     27: #define NO_SHORTNAMES
                     28: #include "../src/config.h"
                     29: #ifdef open
                     30: #undef open
                     31: #undef read
                     32: #undef write
                     33: #endif /* open */
                     34: #endif /* EMACS */
                     35: 
                     36: /* The macro EMACS is defined when cpp is distributed as part of Emacs,
                     37:    for the sake of machines with limited C compilers.  */
                     38: #ifndef EMACS
                     39: #include "config.h"
                     40: #endif /* not EMACS */
                     41: 
                     42: #ifndef STANDARD_INCLUDE_DIR
                     43: #define STANDARD_INCLUDE_DIR "/usr/include"
                     44: #endif
                     45: 
                     46: #ifndef LOCAL_INCLUDE_DIR
                     47: #define LOCAL_INCLUDE_DIR "/usr/local/include"
                     48: #endif
                     49: 
1.1.1.4   root       50: #if 0 /* We can't get ptrdiff_t, so I arranged not to need PTR_INT_TYPE.  */
                     51: #ifdef __STDC__
                     52: #define PTR_INT_TYPE ptrdiff_t
                     53: #else
                     54: #define PTR_INT_TYPE long
                     55: #endif
                     56: #endif /* 0 */
                     57: 
1.1       root       58: #include "pcp.h"
                     59: 
                     60: #ifndef STDC_VALUE
                     61: #define STDC_VALUE 1
                     62: #endif
                     63: 
1.1.1.3   root       64: /* By default, colon separates directories in a path.  */
                     65: #ifndef PATH_SEPARATOR
                     66: #define PATH_SEPARATOR ':'
                     67: #endif
                     68: 
1.1       root       69: /* In case config.h defines these.  */
                     70: #undef bcopy
                     71: #undef bzero
                     72: #undef bcmp
                     73: 
                     74: #include <sys/types.h>
                     75: #include <sys/stat.h>
                     76: #include <ctype.h>
                     77: #include <stdio.h>
1.1.1.5   root       78: #include <signal.h>
1.1       root       79: 
                     80: #ifndef VMS
                     81: #ifndef USG
                     82: #include <sys/time.h>          /* for __DATE__ and __TIME__ */
                     83: #include <sys/resource.h>
                     84: #else
                     85: #include <time.h>
                     86: #include <fcntl.h>
                     87: #endif /* USG */
                     88: #endif /* not VMS */
                     89: 
1.1.1.5   root       90: /* This defines "errno" properly for VMS, and gives us EACCES. */
                     91: #include <errno.h>
                     92: 
1.1       root       93: /* VMS-specific definitions */
                     94: #ifdef VMS
                     95: #include <time.h>
                     96: #include <descrip.h>
                     97: #define O_RDONLY       0       /* Open arg for Read/Only  */
                     98: #define O_WRONLY       1       /* Open arg for Write/Only */
1.1.1.5   root       99: #define read(fd,buf,size)      VMS_read (fd,buf,size)
                    100: #define write(fd,buf,size)     VMS_write (fd,buf,size)
                    101: #define open(fname,mode,prot)  VMS_open (fname,mode,prot)
                    102: #define fopen(fname,mode)      VMS_fopen (fname,mode)
                    103: #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
                    104: #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
1.1.1.4   root      105: static char * VMS_strncat ();
1.1       root      106: static int VMS_read ();
                    107: static int VMS_write ();
                    108: static int VMS_open ();
                    109: static FILE * VMS_fopen ();
                    110: static FILE * VMS_freopen ();
                    111: static void hack_vms_include_specification ();
                    112: typedef struct { unsigned :16, :16, :16; } vms_ino_t;
                    113: #define ino_t vms_ino_t
1.1.1.4   root      114: #define INCLUDE_LEN_FUDGE 10   /* leave room for VMS syntax conversion */
1.1       root      115: #ifdef __GNUC__
                    116: #define BSTRING                        /* VMS/GCC supplies the bstring routines */
                    117: #endif /* __GNUC__ */
                    118: #endif /* VMS */
1.1.1.4   root      119:   
                    120: extern char *index ();
                    121: extern char *rindex ();
1.1       root      122: 
                    123: #ifndef O_RDONLY
                    124: #define O_RDONLY 0
                    125: #endif
                    126: 
                    127: #undef MIN
                    128: #undef MAX
                    129: #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
                    130: #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
                    131: 
1.1.1.4   root      132: /* Find the largest host integer type and set its size and type.  */
                    133: 
                    134: #ifndef HOST_BITS_PER_WIDE_INT
                    135: 
                    136: #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
                    137: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
                    138: #define HOST_WIDE_INT long
                    139: #else
                    140: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
                    141: #define HOST_WIDE_INT int
                    142: #endif
                    143: 
                    144: #endif
                    145: 
1.1       root      146: #ifndef S_ISREG
                    147: #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
                    148: #endif
                    149: 
1.1.1.5   root      150: #ifndef S_ISDIR
                    151: #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
                    152: #endif
                    153: 
1.1.1.4   root      154: /* Define a generic NULL if one hasn't already been defined.  */
                    155: 
                    156: #ifndef NULL
                    157: #define NULL 0
                    158: #endif
                    159: 
                    160: #ifndef GENERIC_PTR
                    161: #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
                    162: #define GENERIC_PTR void *
                    163: #else
                    164: #define GENERIC_PTR char *
                    165: #endif
                    166: #endif
                    167: 
                    168: #ifndef NULL_PTR
                    169: #define NULL_PTR ((GENERIC_PTR)0)
                    170: #endif
                    171: 
                    172: #ifndef INCLUDE_LEN_FUDGE
                    173: #define INCLUDE_LEN_FUDGE 0
                    174: #endif
                    175: 
                    176: /* Forward declarations.  */
1.1       root      177: 
                    178: char *xmalloc ();
                    179: void error ();
                    180: void warning ();
                    181: 
                    182: /* External declarations.  */
                    183: 
                    184: extern char *getenv ();
                    185: extern FILE *fdopen ();
                    186: extern char *version_string;
                    187: extern struct tm *localtime ();
1.1.1.7 ! root      188: #ifndef VMS
        !           189: #ifndef HAVE_STRERROR
1.1       root      190: extern int sys_nerr;
1.1.1.7 ! root      191: #if defined(bsd4_4) || defined(__NetBSD__)
1.1.1.6   root      192: extern const char *const sys_errlist[];
                    193: #else
1.1       root      194: extern char *sys_errlist[];
1.1.1.6   root      195: #endif
1.1.1.7 ! root      196: #else  /* HAVE_STERRROR */
        !           197: char *strerror ();
        !           198: #endif
        !           199: #else  /* VMS */
        !           200: char *strerror (int,...);
        !           201: #endif
1.1.1.6   root      202: extern int parse_escape ();
1.1.1.7 ! root      203: extern HOST_WIDE_INT parse_c_expression ();
1.1       root      204: 
                    205: #ifndef errno
                    206: extern int errno;
                    207: #endif
                    208: 
                    209: /* Forward declarations.  */
                    210: 
                    211: struct directive;
                    212: struct file_buf;
                    213: struct arglist;
                    214: struct argdata;
                    215: 
                    216: #if defined(USG) || defined(VMS)
                    217: #ifndef BSTRING
                    218: void bcopy ();
                    219: void bzero ();
                    220: int bcmp ();
                    221: #endif
                    222: #endif
                    223: 
                    224: /* These functions are declared to return int instead of void since they
                    225:    are going to be placed in a table and some old compilers have trouble with
                    226:    pointers to functions returning void.  */
                    227: 
                    228: static int do_define ();
                    229: static int do_line ();
                    230: static int do_include ();
                    231: static int do_undef ();
                    232: static int do_error ();
                    233: static int do_pragma ();
                    234: static int do_ident ();
                    235: static int do_if ();
                    236: static int do_xifdef ();
                    237: static int do_else ();
                    238: static int do_elif ();
                    239: static int do_endif ();
                    240: static int do_sccs ();
                    241: static int do_once ();
                    242: static int do_assert ();
                    243: static int do_unassert ();
                    244: static int do_warning ();
                    245: 
                    246: static void add_import ();
1.1.1.4   root      247: static void append_include_chain ();
1.1       root      248: static void deps_output ();
                    249: static void make_undef ();
                    250: static void make_definition ();
                    251: static void make_assertion ();
                    252: static void path_include ();
                    253: static void initialize_builtins ();
                    254: static void initialize_char_syntax ();
                    255: static void dump_arg_n ();
                    256: static void dump_defn_1 ();
                    257: static void delete_macro ();
                    258: static void trigraph_pcp ();
                    259: static void rescan ();
                    260: static void finclude ();
                    261: static void validate_else ();
                    262: static int comp_def_part ();
                    263: static void error_from_errno ();
                    264: static void error_with_line ();
                    265: void pedwarn ();
1.1.1.5   root      266: void pedwarn_with_line ();
1.1       root      267: static void pedwarn_with_file_and_line ();
                    268: static void fatal ();
                    269: void fancy_abort ();
                    270: static void pfatal_with_name ();
                    271: static void perror_with_name ();
1.1.1.5   root      272: static void pipe_closed ();
1.1       root      273: static void print_containing_files ();
                    274: static int lookup_import ();
1.1.1.4   root      275: static int redundant_include_p ();
                    276: static is_system_include ();
1.1.1.7 ! root      277: static struct file_name_map *read_name_map ();
        !           278: static char *read_filename_string ();
        !           279: static int open_include_file ();
1.1       root      280: static int check_preconditions ();
                    281: static void pcfinclude ();
                    282: static void pcstring_used ();
                    283: static void write_output ();
                    284: static int check_macro_name ();
                    285: static int compare_defs ();
                    286: static int compare_token_lists ();
1.1.1.7 ! root      287: static HOST_WIDE_INT eval_if_expression ();
1.1       root      288: static int discard_comments ();
1.1.1.5   root      289: static int change_newlines ();
1.1       root      290: static int line_for_error ();
                    291: static int hashf ();
                    292: static int file_size_and_mode ();
                    293: 
                    294: static struct arglist *read_token_list ();
                    295: static void free_token_list ();
                    296: 
                    297: static struct hashnode *install ();
                    298: struct hashnode *lookup ();
                    299: 
                    300: static struct assertion_hashnode *assertion_install ();
                    301: static struct assertion_hashnode *assertion_lookup ();
                    302: 
                    303: static char *xrealloc ();
                    304: static char *xcalloc ();
                    305: static char *savestring ();
                    306: 
                    307: static void delete_assertion ();
                    308: static void macroexpand ();
                    309: static void dump_all_macros ();
                    310: static void conditional_skip ();
                    311: static void skip_if_group ();
                    312: static void output_line_command ();
                    313: 
                    314: /* Last arg to output_line_command.  */
                    315: enum file_change_code {same_file, enter_file, leave_file};
                    316: 
                    317: static int grow_outbuf ();
                    318: static int handle_directive ();
                    319: static void memory_full ();
                    320: 
                    321: static U_CHAR *macarg1 ();
                    322: static char *macarg ();
                    323: 
                    324: static U_CHAR *skip_to_end_of_comment ();
                    325: static U_CHAR *skip_quoted_string ();
                    326: static U_CHAR *skip_paren_group ();
1.1.1.6   root      327: static char *quote_string ();
1.1       root      328: 
                    329: static char *check_precompiled ();
1.1.1.4   root      330: /* static struct macrodef create_definition ();        [moved below] */
1.1       root      331: static void dump_single_macro ();
1.1.1.6   root      332: static void output_dots ();
1.1       root      333: 
                    334: #ifndef FAILURE_EXIT_CODE
                    335: #define FAILURE_EXIT_CODE 33   /* gnu cc command understands this */
                    336: #endif
                    337: 
                    338: #ifndef SUCCESS_EXIT_CODE
                    339: #define SUCCESS_EXIT_CODE 0    /* 0 means success on Unix.  */
                    340: #endif
                    341: 
                    342: /* Name under which this program was invoked.  */
                    343: 
                    344: static char *progname;
                    345: 
1.1.1.4   root      346: /* Nonzero means use extra default include directories for C++.  */
1.1       root      347: 
                    348: static int cplusplus;
                    349: 
1.1.1.4   root      350: /* Nonzero means handle cplusplus style comments */
                    351: 
                    352: static int cplusplus_comments;
                    353: 
1.1       root      354: /* Nonzero means handle #import, for objective C.  */
                    355: 
                    356: static int objc;
                    357: 
                    358: /* Nonzero means this is an assembly file, and allow
                    359:    unknown directives, which could be comments.  */
                    360: 
                    361: static int lang_asm;
                    362: 
                    363: /* Current maximum length of directory names in the search path
                    364:    for include files.  (Altered as we get more of them.)  */
                    365: 
                    366: static int max_include_len;
                    367: 
                    368: /* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */
                    369: 
1.1.1.7 ! root      370: static int for_lint = 0;
1.1       root      371: 
                    372: /* Nonzero means copy comments into the output file.  */
                    373: 
                    374: static int put_out_comments = 0;
                    375: 
                    376: /* Nonzero means don't process the ANSI trigraph sequences.  */
                    377: 
                    378: static int no_trigraphs = 0;
                    379: 
                    380: /* Nonzero means print the names of included files rather than
                    381:    the preprocessed output.  1 means just the #include "...",
                    382:    2 means #include <...> as well.  */
                    383: 
                    384: static int print_deps = 0;
                    385: 
1.1.1.7 ! root      386: /* Nonzero if missing .h files in -M output are assumed to be generated
        !           387:    files and not errors.  */
        !           388: 
        !           389: static int print_deps_missing_files = 0;
        !           390: 
1.1       root      391: /* Nonzero means print names of header files (-H).  */
                    392: 
                    393: static int print_include_names = 0;
                    394: 
                    395: /* Nonzero means don't output line number information.  */
                    396: 
                    397: static int no_line_commands;
                    398: 
1.1.1.7 ! root      399: /* Nonzero means output the text in failing conditionals,
        !           400:    inside #failed ... #endfailed.  */
        !           401: 
        !           402: static int output_conditionals;
        !           403: 
1.1       root      404: /* dump_only means inhibit output of the preprocessed text
                    405:              and instead output the definitions of all user-defined
                    406:              macros in a form suitable for use as input to cccp.
                    407:    dump_names means pass #define and the macro name through to output.
                    408:    dump_definitions means pass the whole definition (plus #define) through
                    409: */
                    410: 
                    411: static enum {dump_none, dump_only, dump_names, dump_definitions}
                    412:      dump_macros = dump_none;
                    413: 
                    414: /* Nonzero means pass all #define and #undef directives which we actually
                    415:    process through to the output stream.  This feature is used primarily
                    416:    to allow cc1 to record the #defines and #undefs for the sake of
                    417:    debuggers which understand about preprocessor macros, but it may
                    418:    also be useful with -E to figure out how symbols are defined, and
                    419:    where they are defined.  */
                    420: static int debug_output = 0;
                    421: 
                    422: /* Nonzero indicates special processing used by the pcp program.  The
                    423:    special effects of this mode are: 
                    424:      
                    425:      Inhibit all macro expansion, except those inside #if directives.
                    426: 
                    427:      Process #define directives normally, and output their contents 
                    428:      to the output file.
                    429: 
                    430:      Output preconditions to pcp_outfile indicating all the relevant
                    431:      preconditions for use of this file in a later cpp run.
                    432: */
                    433: static FILE *pcp_outfile;
                    434: 
                    435: /* Nonzero means we are inside an IF during a -pcp run.  In this mode
                    436:    macro expansion is done, and preconditions are output for all macro
                    437:    uses requiring them. */
                    438: static int pcp_inside_if;
                    439: 
1.1.1.5   root      440: /* Nonzero means never to include precompiled files.
                    441:    This is 1 since there's no way now to make precompiled files,
                    442:    so it's not worth testing for them.  */
                    443: static int no_precomp = 1;
1.1       root      444: 
                    445: /* Nonzero means give all the error messages the ANSI standard requires.  */
                    446: 
                    447: int pedantic;
                    448: 
                    449: /* Nonzero means try to make failure to fit ANSI C an error.  */
                    450: 
                    451: static int pedantic_errors;
                    452: 
                    453: /* Nonzero means don't print warning messages.  -w.  */
                    454: 
                    455: static int inhibit_warnings = 0;
                    456: 
                    457: /* Nonzero means warn if slash-star appears in a comment.  */
                    458: 
                    459: static int warn_comments;
                    460: 
                    461: /* Nonzero means warn if a macro argument is (or would be)
                    462:    stringified with -traditional.  */
                    463: 
                    464: static int warn_stringify;
                    465: 
                    466: /* Nonzero means warn if there are any trigraphs.  */
                    467: 
                    468: static int warn_trigraphs;
                    469: 
1.1.1.2   root      470: /* Nonzero means warn if #import is used.  */
                    471: 
                    472: static int warn_import = 1;
                    473: 
1.1       root      474: /* Nonzero means turn warnings into errors.  */
                    475: 
                    476: static int warnings_are_errors;
                    477: 
                    478: /* Nonzero means try to imitate old fashioned non-ANSI preprocessor.  */
                    479: 
                    480: int traditional;
                    481: 
                    482: /* Nonzero causes output not to be done,
                    483:    but directives such as #define that have side effects
                    484:    are still obeyed.  */
                    485: 
                    486: static int no_output;
                    487: 
1.1.1.7 ! root      488: /* Nonzero means this file was included with a -imacros or -include
        !           489:    command line and should not be recorded as an include file.  */
        !           490: 
        !           491: static int no_record_file;
        !           492: 
1.1       root      493: /* Nonzero means that we have finished processing the command line options.
                    494:    This flag is used to decide whether or not to issue certain errors
                    495:    and/or warnings.  */
                    496: 
                    497: static int done_initializing = 0;
1.1.1.5   root      498: 
                    499: /* Line where a newline was first seen in a string constant.  */
                    500: 
                    501: static int multiline_string_line = 0;
1.1       root      502: 
                    503: /* I/O buffer structure.
                    504:    The `fname' field is nonzero for source files and #include files
                    505:    and for the dummy text used for -D and -U.
                    506:    It is zero for rescanning results of macro expansion
                    507:    and for expanding macro arguments.  */
1.1.1.6   root      508: #define INPUT_STACK_MAX 400
1.1       root      509: static struct file_buf {
                    510:   char *fname;
                    511:   /* Filename specified with #line command.  */
                    512:   char *nominal_fname;
                    513:   /* Record where in the search path this file was found.
                    514:      For #include_next.  */
                    515:   struct file_name_list *dir;
                    516:   int lineno;
                    517:   int length;
                    518:   U_CHAR *buf;
                    519:   U_CHAR *bufp;
                    520:   /* Macro that this level is the expansion of.
                    521:      Included so that we can reenable the macro
                    522:      at the end of this level.  */
                    523:   struct hashnode *macro;
                    524:   /* Value of if_stack at start of this file.
                    525:      Used to prohibit unmatched #endif (etc) in an include file.  */
                    526:   struct if_stack *if_stack;
                    527:   /* Object to be freed at end of input at this level.  */
                    528:   U_CHAR *free_ptr;
                    529:   /* True if this is a header file included using <FILENAME>.  */
                    530:   char system_header_p;
                    531: } instack[INPUT_STACK_MAX];
                    532: 
                    533: static int last_error_tick;       /* Incremented each time we print it.  */
                    534: static int input_file_stack_tick;  /* Incremented when the status changes.  */
                    535: 
                    536: /* Current nesting level of input sources.
                    537:    `instack[indepth]' is the level currently being read.  */
                    538: static int indepth = -1;
                    539: #define CHECK_DEPTH(code) \
                    540:   if (indepth >= (INPUT_STACK_MAX - 1))                                        \
                    541:     {                                                                  \
                    542:       error_with_line (line_for_error (instack[indepth].lineno),       \
                    543:                       "macro or `#include' recursion too deep");       \
                    544:       code;                                                            \
                    545:     }
                    546: 
                    547: /* Current depth in #include directives that use <...>.  */
                    548: static int system_include_depth = 0;
                    549: 
                    550: typedef struct file_buf FILE_BUF;
                    551: 
                    552: /* The output buffer.  Its LENGTH field is the amount of room allocated
                    553:    for the buffer, not the number of chars actually present.  To get
                    554:    that, subtract outbuf.buf from outbuf.bufp. */
                    555: 
                    556: #define OUTBUF_SIZE 10 /* initial size of output buffer */
                    557: static FILE_BUF outbuf;
                    558: 
                    559: /* Grow output buffer OBUF points at
                    560:    so it can hold at least NEEDED more chars.  */
                    561: 
                    562: #define check_expand(OBUF, NEEDED)  \
                    563:   (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED))   \
                    564:    ? grow_outbuf ((OBUF), (NEEDED)) : 0)
                    565: 
                    566: struct file_name_list
                    567:   {
                    568:     struct file_name_list *next;
                    569:     char *fname;
                    570:     /* If the following is nonzero, it is a macro name.
                    571:        Don't include the file again if that macro is defined.  */
                    572:     U_CHAR *control_macro;
1.1.1.6   root      573:     /* If the following is nonzero, it is a C-language system include
                    574:        directory.  */
                    575:     int c_system_include_path;
1.1.1.7 ! root      576:     /* Mapping of file names for this directory.  */
        !           577:     struct file_name_map *name_map;
        !           578:     /* Non-zero if name_map is valid.  */
        !           579:     int got_name_map;
1.1       root      580:   };
                    581: 
                    582: /* #include "file" looks in source file dir, then stack. */
                    583: /* #include <file> just looks in the stack. */
                    584: /* -I directories are added to the end, then the defaults are added. */
1.1.1.7 ! root      585: /* The */
        !           586: static struct default_include {
        !           587:   char *fname;                 /* The name of the directory.  */
        !           588:   int cplusplus;               /* Only look here if we're compiling C++.  */
        !           589:   int cxx_aware;               /* Includes in this directory don't need to
        !           590:                                   be wrapped in extern "C" when compiling
        !           591:                                   C++.  */
        !           592: } include_defaults_array[]
1.1       root      593: #ifdef INCLUDE_DEFAULTS
                    594:   = INCLUDE_DEFAULTS;
                    595: #else
                    596:   = {
                    597:     /* Pick up GNU C++ specific include files.  */
1.1.1.7 ! root      598:     { GPLUSPLUS_INCLUDE_DIR, 1, 1 },
1.1       root      599: #ifdef CROSS_COMPILE
1.1.1.5   root      600:     /* This is the dir for fixincludes.  Put it just before
                    601:        the files that we fix.  */
1.1.1.7 ! root      602:     { GCC_INCLUDE_DIR, 0, 0 },
1.1       root      603:     /* For cross-compilation, this dir name is generated
                    604:        automatically in Makefile.in.  */
1.1.1.7 ! root      605:     { CROSS_INCLUDE_DIR, 0, 0 },
1.1.1.5   root      606:     /* This is another place that the target system's headers might be.  */
1.1.1.7 ! root      607:     { TOOL_INCLUDE_DIR, 0, 0 },
1.1       root      608: #else /* not CROSS_COMPILE */
1.1.1.7 ! root      609:     /* This should be /usr/local/include and should come before
1.1.1.5   root      610:        the fixincludes-fixed header files.  */
1.1.1.7 ! root      611:     { LOCAL_INCLUDE_DIR, 0, 1 },
1.1.1.5   root      612:     /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
                    613:        Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h.  */
1.1.1.7 ! root      614:     { TOOL_INCLUDE_DIR, 0, 0 },
1.1.1.5   root      615:     /* This is the dir for fixincludes.  Put it just before
                    616:        the files that we fix.  */
1.1.1.7 ! root      617:     { GCC_INCLUDE_DIR, 0, 0 },
1.1       root      618:     /* Some systems have an extra dir of include files.  */
                    619: #ifdef SYSTEM_INCLUDE_DIR
1.1.1.7 ! root      620:     { SYSTEM_INCLUDE_DIR, 0, 0 },
1.1       root      621: #endif
1.1.1.7 ! root      622:     { STANDARD_INCLUDE_DIR, 0, 0 },
1.1       root      623: #endif /* not CROSS_COMPILE */
1.1.1.7 ! root      624:     { 0, 0, 0 }
1.1       root      625:     };
                    626: #endif /* no INCLUDE_DEFAULTS */
                    627: 
                    628: /* The code looks at the defaults through this pointer, rather than through
                    629:    the constant structure above.  This pointer gets changed if an environment
                    630:    variable specifies other defaults.  */
                    631: static struct default_include *include_defaults = include_defaults_array;
                    632: 
                    633: static struct file_name_list *include = 0;     /* First dir to search */
                    634:        /* First dir to search for <file> */
1.1.1.4   root      635: /* This is the first element to use for #include <...>.
                    636:    If it is 0, use the entire chain for such includes.  */
1.1       root      637: static struct file_name_list *first_bracket_include = 0;
1.1.1.4   root      638: /* This is the first element in the chain that corresponds to
                    639:    a directory of system header files.  */
                    640: static struct file_name_list *first_system_include = 0;
1.1       root      641: static struct file_name_list *last_include = 0;        /* Last in chain */
                    642: 
                    643: /* Chain of include directories to put at the end of the other chain.  */
                    644: static struct file_name_list *after_include = 0;
                    645: static struct file_name_list *last_after_include = 0;  /* Last in chain */
                    646: 
1.1.1.7 ! root      647: /* Chain to put at the start of the system include files.  */
        !           648: static struct file_name_list *before_system = 0;
        !           649: static struct file_name_list *last_before_system = 0;  /* Last in chain */
        !           650: 
1.1       root      651: /* List of included files that contained #pragma once.  */
                    652: static struct file_name_list *dont_repeat_files = 0;
                    653: 
                    654: /* List of other included files.
                    655:    If ->control_macro if nonzero, the file had a #ifndef
                    656:    around the entire contents, and ->control_macro gives the macro name.  */
                    657: static struct file_name_list *all_include_files = 0;
                    658: 
1.1.1.3   root      659: /* Directory prefix that should replace `/usr' in the standard
                    660:    include file directories.  */
                    661: static char *include_prefix;
                    662: 
1.1       root      663: /* Global list of strings read in from precompiled files.  This list
                    664:    is kept in the order the strings are read in, with new strings being
                    665:    added at the end through stringlist_tailp.  We use this list to output
                    666:    the strings at the end of the run. 
                    667: */
                    668: static STRINGDEF *stringlist;
                    669: static STRINGDEF **stringlist_tailp = &stringlist;
                    670: 
                    671: 
                    672: /* Structure returned by create_definition */
                    673: typedef struct macrodef MACRODEF;
                    674: struct macrodef
                    675: {
                    676:   struct definition *defn;
                    677:   U_CHAR *symnam;
                    678:   int symlen;
                    679: };
                    680: 
1.1.1.4   root      681: static struct macrodef create_definition ();
                    682: 
1.1       root      683: 
                    684: /* Structure allocated for every #define.  For a simple replacement
                    685:    such as
                    686:        #define foo bar ,
                    687:    nargs = -1, the `pattern' list is null, and the expansion is just
                    688:    the replacement text.  Nargs = 0 means a functionlike macro with no args,
                    689:    e.g.,
                    690:        #define getchar() getc (stdin) .
                    691:    When there are args, the expansion is the replacement text with the
                    692:    args squashed out, and the reflist is a list describing how to
                    693:    build the output from the input: e.g., "3 chars, then the 1st arg,
                    694:    then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
                    695:    The chars here come from the expansion.  Whatever is left of the
                    696:    expansion after the last arg-occurrence is copied after that arg.
                    697:    Note that the reflist can be arbitrarily long---
                    698:    its length depends on the number of times the arguments appear in
                    699:    the replacement text, not how many args there are.  Example:
                    700:    #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
                    701:    pattern list
                    702:      { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
                    703:    where (x, y) means (nchars, argno). */
                    704: 
                    705: typedef struct definition DEFINITION;
                    706: struct definition {
                    707:   int nargs;
                    708:   int length;                  /* length of expansion string */
                    709:   int predefined;              /* True if the macro was builtin or */
                    710:                                /* came from the command line */
                    711:   U_CHAR *expansion;
                    712:   int line;                    /* Line number of definition */
                    713:   char *file;                  /* File of definition */
1.1.1.3   root      714:   char rest_args;              /* Nonzero if last arg. absorbs the rest */
1.1       root      715:   struct reflist {
                    716:     struct reflist *next;
                    717:     char stringify;            /* nonzero if this arg was preceded by a
                    718:                                   # operator. */
                    719:     char raw_before;           /* Nonzero if a ## operator before arg. */
                    720:     char raw_after;            /* Nonzero if a ## operator after arg. */
1.1.1.3   root      721:     char rest_args;            /* Nonzero if this arg. absorbs the rest */
1.1       root      722:     int nchars;                        /* Number of literal chars to copy before
                    723:                                   this arg occurrence.  */
                    724:     int argno;                 /* Number of arg to substitute (origin-0) */
                    725:   } *pattern;
                    726:   union {
                    727:     /* Names of macro args, concatenated in reverse order
                    728:        with comma-space between them.
                    729:        The only use of this is that we warn on redefinition
                    730:        if this differs between the old and new definitions.  */
                    731:     U_CHAR *argnames;
                    732:   } args;
                    733: };
                    734: 
                    735: /* different kinds of things that can appear in the value field
                    736:    of a hash node.  Actually, this may be useless now. */
                    737: union hashval {
                    738:   int ival;
                    739:   char *cpval;
                    740:   DEFINITION *defn;
                    741:   KEYDEF *keydef;
                    742: };
                    743: 
1.1.1.3   root      744: /*
                    745:  * special extension string that can be added to the last macro argument to 
                    746:  * allow it to absorb the "rest" of the arguments when expanded.  Ex:
1.1.1.5   root      747:  *             #define wow(a, b...)            process (b, a, b)
                    748:  *             { wow (1, 2, 3); }      ->      { process (2, 3, 1, 2, 3); }
                    749:  *             { wow (one, two); }     ->      { process (two, one, two); }
1.1.1.3   root      750:  * if this "rest_arg" is used with the concat token '##' and if it is not
1.1.1.4   root      751:  * supplied then the token attached to with ## will not be outputted.  Ex:
1.1.1.5   root      752:  *             #define wow (a, b...)           process (b ## , a, ## b)
                    753:  *             { wow (1, 2); }         ->      { process (2, 1, 2); }
                    754:  *             { wow (one); }          ->      { process (one); {
1.1.1.3   root      755:  */
                    756: static char rest_extension[] = "...";
                    757: #define REST_EXTENSION_LENGTH  (sizeof (rest_extension) - 1)
1.1       root      758: 
                    759: /* The structure of a node in the hash table.  The hash table
                    760:    has entries for all tokens defined by #define commands (type T_MACRO),
                    761:    plus some special tokens like __LINE__ (these each have their own
                    762:    type, and the appropriate code is run when that type of node is seen.
                    763:    It does not contain control words like "#define", which are recognized
                    764:    by a separate piece of code. */
                    765: 
                    766: /* different flavors of hash nodes --- also used in keyword table */
                    767: enum node_type {
                    768:  T_DEFINE = 1, /* the `#define' keyword */
                    769:  T_INCLUDE,    /* the `#include' keyword */
                    770:  T_INCLUDE_NEXT, /* the `#include_next' keyword */
                    771:  T_IMPORT,      /* the `#import' keyword */
                    772:  T_IFDEF,      /* the `#ifdef' keyword */
                    773:  T_IFNDEF,     /* the `#ifndef' keyword */
                    774:  T_IF,         /* the `#if' keyword */
                    775:  T_ELSE,       /* `#else' */
                    776:  T_PRAGMA,     /* `#pragma' */
                    777:  T_ELIF,       /* `#elif' */
                    778:  T_UNDEF,      /* `#undef' */
                    779:  T_LINE,       /* `#line' */
                    780:  T_ERROR,      /* `#error' */
                    781:  T_WARNING,    /* `#warning' */
                    782:  T_ENDIF,      /* `#endif' */
                    783:  T_SCCS,       /* `#sccs', used on system V.  */
                    784:  T_IDENT,      /* `#ident', used on system V.  */
                    785:  T_ASSERT,     /* `#assert', taken from system V.  */
                    786:  T_UNASSERT,   /* `#unassert', taken from system V.  */
                    787:  T_SPECLINE,   /* special symbol `__LINE__' */
                    788:  T_DATE,       /* `__DATE__' */
                    789:  T_FILE,       /* `__FILE__' */
                    790:  T_BASE_FILE,  /* `__BASE_FILE__' */
                    791:  T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
                    792:  T_VERSION,    /* `__VERSION__' */
                    793:  T_SIZE_TYPE,   /* `__SIZE_TYPE__' */
                    794:  T_PTRDIFF_TYPE,   /* `__PTRDIFF_TYPE__' */
                    795:  T_WCHAR_TYPE,   /* `__WCHAR_TYPE__' */
1.1.1.5   root      796:  T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */
                    797:  T_REGISTER_PREFIX_TYPE,   /* `__REGISTER_PREFIX__' */
1.1       root      798:  T_TIME,       /* `__TIME__' */
                    799:  T_CONST,      /* Constant value, used by `__STDC__' */
                    800:  T_MACRO,      /* macro defined by `#define' */
                    801:  T_DISABLED,   /* macro temporarily turned off for rescan */
                    802:  T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
                    803:  T_PCSTRING,   /* precompiled string (hashval is KEYDEF *) */
                    804:  T_UNUSED      /* Used for something not defined.  */
                    805:  };
                    806: 
                    807: struct hashnode {
                    808:   struct hashnode *next;       /* double links for easy deletion */
                    809:   struct hashnode *prev;
                    810:   struct hashnode **bucket_hdr;        /* also, a back pointer to this node's hash
                    811:                                   chain is kept, in case the node is the head
                    812:                                   of the chain and gets deleted. */
                    813:   enum node_type type;         /* type of special token */
                    814:   int length;                  /* length of token, for quick comparison */
                    815:   U_CHAR *name;                        /* the actual name */
                    816:   union hashval value;         /* pointer to expansion, or whatever */
                    817: };
                    818: 
                    819: typedef struct hashnode HASHNODE;
                    820: 
                    821: /* Some definitions for the hash table.  The hash function MUST be
                    822:    computed as shown in hashf () below.  That is because the rescan
                    823:    loop computes the hash value `on the fly' for most tokens,
                    824:    in order to avoid the overhead of a lot of procedure calls to
                    825:    the hashf () function.  Hashf () only exists for the sake of
                    826:    politeness, for use when speed isn't so important. */
                    827: 
                    828: #define HASHSIZE 1403
                    829: static HASHNODE *hashtab[HASHSIZE];
                    830: #define HASHSTEP(old, c) ((old << 2) + c)
                    831: #define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
                    832: 
                    833: /* Symbols to predefine.  */
                    834: 
                    835: #ifdef CPP_PREDEFINES
                    836: static char *predefs = CPP_PREDEFINES;
                    837: #else
                    838: static char *predefs = "";
                    839: #endif
                    840: 
                    841: /* We let tm.h override the types used here, to handle trivial differences
                    842:    such as the choice of unsigned int or long unsigned int for size_t.
                    843:    When machines start needing nontrivial differences in the size type,
                    844:    it would be best to do something here to figure out automatically
                    845:    from other information what type to use.  */
                    846: 
1.1.1.7 ! root      847: /* The string value for __SIZE_TYPE__.  */
1.1       root      848: 
                    849: #ifndef SIZE_TYPE
                    850: #define SIZE_TYPE "long unsigned int"
                    851: #endif
                    852: 
1.1.1.7 ! root      853: /* The string value for __PTRDIFF_TYPE__.  */
1.1       root      854: 
                    855: #ifndef PTRDIFF_TYPE
                    856: #define PTRDIFF_TYPE "long int"
                    857: #endif
                    858: 
1.1.1.7 ! root      859: /* The string value for __WCHAR_TYPE__.  */
1.1       root      860: 
                    861: #ifndef WCHAR_TYPE
                    862: #define WCHAR_TYPE "int"
                    863: #endif
1.1.1.7 ! root      864: char * wchar_type = WCHAR_TYPE;
        !           865: #undef WCHAR_TYPE
1.1.1.5   root      866: 
                    867: /* The string value for __USER_LABEL_PREFIX__ */
                    868: 
                    869: #ifndef USER_LABEL_PREFIX
                    870: #define USER_LABEL_PREFIX ""
                    871: #endif
                    872: 
                    873: /* The string value for __REGISTER_PREFIX__ */
                    874: 
                    875: #ifndef REGISTER_PREFIX
                    876: #define REGISTER_PREFIX ""
                    877: #endif
1.1       root      878: 
                    879: /* In the definition of a #assert name, this structure forms
                    880:    a list of the individual values asserted.
                    881:    Each value is itself a list of "tokens".
                    882:    These are strings that are compared by name.  */
                    883: 
                    884: struct tokenlist_list {
                    885:   struct tokenlist_list *next;
                    886:   struct arglist *tokens;
                    887: };
                    888: 
                    889: struct assertion_hashnode {
                    890:   struct assertion_hashnode *next;     /* double links for easy deletion */
                    891:   struct assertion_hashnode *prev;
                    892:   /* also, a back pointer to this node's hash
                    893:      chain is kept, in case the node is the head
                    894:      of the chain and gets deleted. */
                    895:   struct assertion_hashnode **bucket_hdr;
                    896:   int length;                  /* length of token, for quick comparison */
                    897:   U_CHAR *name;                        /* the actual name */
                    898:   /* List of token-sequences.  */
                    899:   struct tokenlist_list *value;
                    900: };
                    901: 
                    902: typedef struct assertion_hashnode ASSERTION_HASHNODE;
                    903: 
                    904: /* Some definitions for the hash table.  The hash function MUST be
1.1.1.4   root      905:    computed as shown in hashf below.  That is because the rescan
1.1       root      906:    loop computes the hash value `on the fly' for most tokens,
                    907:    in order to avoid the overhead of a lot of procedure calls to
1.1.1.4   root      908:    the hashf function.  hashf only exists for the sake of
1.1       root      909:    politeness, for use when speed isn't so important. */
                    910: 
                    911: #define ASSERTION_HASHSIZE 37
                    912: static ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE];
                    913: 
                    914: /* Nonzero means inhibit macroexpansion of what seem to be
                    915:    assertion tests, in rescan.  For #if.  */
                    916: static int assertions_flag;
                    917: 
                    918: /* `struct directive' defines one #-directive, including how to handle it.  */
                    919: 
                    920: struct directive {
                    921:   int length;                  /* Length of name */
                    922:   int (*func)();               /* Function to handle directive */
                    923:   char *name;                  /* Name of directive */
                    924:   enum node_type type;         /* Code which describes which directive. */
                    925:   char angle_brackets;         /* Nonzero => <...> is special.  */
                    926:   char traditional_comments;   /* Nonzero: keep comments if -traditional.  */
                    927:   char pass_thru;              /* Copy preprocessed directive to output file.  */
                    928: };
                    929: 
                    930: /* Here is the actual list of #-directives, most-often-used first.  */
                    931: 
                    932: static struct directive directive_table[] = {
                    933:   {  6, do_define, "define", T_DEFINE, 0, 1},
                    934:   {  2, do_if, "if", T_IF},
                    935:   {  5, do_xifdef, "ifdef", T_IFDEF},
                    936:   {  6, do_xifdef, "ifndef", T_IFNDEF},
                    937:   {  5, do_endif, "endif", T_ENDIF},
                    938:   {  4, do_else, "else", T_ELSE},
                    939:   {  4, do_elif, "elif", T_ELIF},
                    940:   {  4, do_line, "line", T_LINE},
                    941:   {  7, do_include, "include", T_INCLUDE, 1},
                    942:   { 12, do_include, "include_next", T_INCLUDE_NEXT, 1},
                    943:   {  6, do_include, "import", T_IMPORT, 1},
                    944:   {  5, do_undef, "undef", T_UNDEF},
                    945:   {  5, do_error, "error", T_ERROR},
                    946:   {  7, do_warning, "warning", T_WARNING},
                    947: #ifdef SCCS_DIRECTIVE
                    948:   {  4, do_sccs, "sccs", T_SCCS},
                    949: #endif
                    950:   {  6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1},
1.1.1.6   root      951:   {  5, do_ident, "ident", T_IDENT},
1.1       root      952:   {  6, do_assert, "assert", T_ASSERT},
                    953:   {  8, do_unassert, "unassert", T_UNASSERT},
                    954:   {  -1, 0, "", T_UNUSED},
                    955: };
                    956: 
                    957: /* When a directive handler is called,
                    958:    this points to the # that started the directive.  */
                    959: U_CHAR *directive_start;
                    960: 
                    961: /* table to tell if char can be part of a C identifier. */
                    962: U_CHAR is_idchar[256];
                    963: /* table to tell if char can be first char of a c identifier. */
                    964: U_CHAR is_idstart[256];
                    965: /* table to tell if c is horizontal space.  */
                    966: U_CHAR is_hor_space[256];
                    967: /* table to tell if c is horizontal or vertical space.  */
                    968: static U_CHAR is_space[256];
                    969: 
                    970: #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
                    971: #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
                    972:   
                    973: static int errors = 0;                 /* Error counter for exit code */
                    974: 
1.1.1.5   root      975: /* Name of output file, for error messages.  */
                    976: static char *out_fname;
                    977: 
1.1       root      978: /* Zero means dollar signs are punctuation.
                    979:    -$ stores 0; -traditional may store 1.  Default is 1 for VMS, 0 otherwise.
                    980:    This must be 0 for correct processing of this ANSI C program:
                    981:        #define foo(a) #a
1.1.1.5   root      982:        #define lose(b) foo (b)
1.1       root      983:        #define test$
1.1.1.5   root      984:        lose (test)     */
1.1       root      985: static int dollars_in_ident;
                    986: #ifndef DOLLARS_IN_IDENTIFIERS
                    987: #define DOLLARS_IN_IDENTIFIERS 1
                    988: #endif
                    989: 
                    990: static FILE_BUF expand_to_temp_buffer ();
                    991: 
                    992: static DEFINITION *collect_expansion ();
                    993: 
                    994: /* Stack of conditionals currently in progress
                    995:    (including both successful and failing conditionals).  */
                    996: 
                    997: struct if_stack {
                    998:   struct if_stack *next;       /* for chaining to the next stack frame */
                    999:   char *fname;         /* copied from input when frame is made */
                   1000:   int lineno;                  /* similarly */
                   1001:   int if_succeeded;            /* true if a leg of this if-group
                   1002:                                    has been passed through rescan */
                   1003:   U_CHAR *control_macro;       /* For #ifndef at start of file,
                   1004:                                   this is the macro name tested.  */
                   1005:   enum node_type type;         /* type of last directive seen in this group */
                   1006: };
                   1007: typedef struct if_stack IF_STACK_FRAME;
                   1008: static IF_STACK_FRAME *if_stack = NULL;
                   1009: 
                   1010: /* Buffer of -M output.  */
                   1011: static char *deps_buffer;
                   1012: 
                   1013: /* Number of bytes allocated in above.  */
                   1014: static int deps_allocated_size;
                   1015: 
                   1016: /* Number of bytes used.  */
                   1017: static int deps_size;
                   1018: 
                   1019: /* Number of bytes since the last newline.  */
                   1020: static int deps_column;
                   1021: 
                   1022: /* Nonzero means -I- has been seen,
                   1023:    so don't look for #include "foo" the source-file directory.  */
                   1024: static int ignore_srcdir;
                   1025: 
1.1.1.6   root     1026: /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
1.1.1.7 ! root     1027:    retrying if necessary.  Return a negative value if an error occurs,
        !          1028:    otherwise return the actual number of bytes read,
        !          1029:    which must be LEN unless end-of-file was reached.  */
1.1.1.6   root     1030: 
                   1031: static int
                   1032: safe_read (desc, ptr, len)
                   1033:      int desc;
                   1034:      char *ptr;
                   1035:      int len;
                   1036: {
                   1037:   int left = len;
                   1038:   while (left > 0) {
                   1039:     int nchars = read (desc, ptr, left);
                   1040:     if (nchars < 0)
                   1041:       {
                   1042: #ifdef EINTR
                   1043:        if (errno == EINTR)
                   1044:          continue;
                   1045: #endif
                   1046:        return nchars;
                   1047:       }
                   1048:     if (nchars == 0)
                   1049:       break;
                   1050:     ptr += nchars;
                   1051:     left -= nchars;
                   1052:   }
                   1053:   return len - left;
                   1054: }
                   1055: 
                   1056: /* Write LEN bytes at PTR to descriptor DESC,
                   1057:    retrying if necessary, and treating any real error as fatal.  */
                   1058: 
                   1059: static void
                   1060: safe_write (desc, ptr, len)
                   1061:      int desc;
                   1062:      char *ptr;
                   1063:      int len;
                   1064: {
                   1065:   while (len > 0) {
                   1066:     int written = write (desc, ptr, len);
                   1067:     if (written < 0)
                   1068:       {
                   1069: #ifdef EINTR
                   1070:        if (errno == EINTR)
                   1071:          continue;
                   1072: #endif
                   1073:        pfatal_with_name (out_fname);
                   1074:       }
                   1075:     ptr += written;
                   1076:     len -= written;
                   1077:   }
                   1078: }
                   1079: 
1.1       root     1080: int
                   1081: main (argc, argv)
                   1082:      int argc;
                   1083:      char **argv;
                   1084: {
                   1085:   int st_mode;
                   1086:   long st_size;
1.1.1.5   root     1087:   char *in_fname;
1.1       root     1088:   char *p;
                   1089:   int f, i;
                   1090:   FILE_BUF *fp;
                   1091:   char **pend_files = (char **) xmalloc (argc * sizeof (char *));
                   1092:   char **pend_defs = (char **) xmalloc (argc * sizeof (char *));
                   1093:   char **pend_undefs = (char **) xmalloc (argc * sizeof (char *));
                   1094:   char **pend_assertions = (char **) xmalloc (argc * sizeof (char *));
                   1095:   char **pend_includes = (char **) xmalloc (argc * sizeof (char *));
                   1096: 
                   1097:   /* Record the option used with each element of pend_assertions.
                   1098:      This is preparation for supporting more than one option for making
                   1099:      an assertion.  */
                   1100:   char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *));
                   1101:   int inhibit_predefs = 0;
                   1102:   int no_standard_includes = 0;
1.1.1.3   root     1103:   int no_standard_cplusplus_includes = 0;
1.1       root     1104:   int missing_newline = 0;
                   1105: 
                   1106:   /* Non-0 means don't output the preprocessed program.  */
                   1107:   int inhibit_output = 0;
1.1.1.6   root     1108:   /* Non-0 means -v, so print the full set of include dirs.  */
                   1109:   int verbose = 0;
1.1       root     1110: 
1.1.1.4   root     1111:   /* File name which deps are being written to.
                   1112:      This is 0 if deps are being written to stdout.  */
                   1113:   char *deps_file = 0;
1.1.1.5   root     1114:   /* Fopen file mode to open deps_file with.  */
                   1115:   char *deps_mode = "a";
1.1       root     1116:   /* Stream on which to print the dependency information.  */
                   1117:   FILE *deps_stream = 0;
                   1118:   /* Target-name to write with the dependency information.  */
                   1119:   char *deps_target = 0;
                   1120: 
                   1121: #ifdef RLIMIT_STACK
                   1122:   /* Get rid of any avoidable limit on stack size.  */
                   1123:   {
                   1124:     struct rlimit rlim;
                   1125: 
                   1126:     /* Set the stack limit huge so that alloca (particularly stringtab
                   1127:      * in dbxread.c) does not fail. */
                   1128:     getrlimit (RLIMIT_STACK, &rlim);
                   1129:     rlim.rlim_cur = rlim.rlim_max;
                   1130:     setrlimit (RLIMIT_STACK, &rlim);
                   1131:   }
                   1132: #endif /* RLIMIT_STACK defined */
                   1133: 
1.1.1.6   root     1134: #ifdef SIGPIPE
1.1.1.5   root     1135:   signal (SIGPIPE, pipe_closed);
1.1.1.6   root     1136: #endif
1.1.1.5   root     1137: 
                   1138:   p = argv[0] + strlen (argv[0]);
1.1.1.7 ! root     1139:   while (p != argv[0] && p[-1] != '/'
        !          1140: #ifdef DIR_SEPARATOR
        !          1141:         && p[-1] != DIR_SEPARATOR
        !          1142: #endif
        !          1143:         )
        !          1144:     --p;
1.1.1.5   root     1145:   progname = p;
                   1146: 
1.1       root     1147: #ifdef VMS
                   1148:   {
                   1149:     /* Remove directories from PROGNAME.  */
                   1150:     char *s;
                   1151: 
                   1152:     progname = savestring (argv[0]);
                   1153: 
                   1154:     if (!(s = rindex (progname, ']')))
                   1155:       s = rindex (progname, ':');
                   1156:     if (s)
                   1157:       strcpy (progname, s+1);
                   1158:     if (s = rindex (progname, '.'))
                   1159:       *s = '\0';
                   1160:   }
                   1161: #endif
                   1162: 
                   1163:   in_fname = NULL;
                   1164:   out_fname = NULL;
                   1165: 
                   1166:   /* Initialize is_idchar to allow $.  */
                   1167:   dollars_in_ident = 1;
                   1168:   initialize_char_syntax ();
                   1169:   dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0;
                   1170: 
                   1171:   no_line_commands = 0;
                   1172:   no_trigraphs = 1;
                   1173:   dump_macros = dump_none;
                   1174:   no_output = 0;
                   1175:   cplusplus = 0;
1.1.1.4   root     1176:   cplusplus_comments = 0;
1.1       root     1177: 
1.1.1.7 ! root     1178:   bzero ((char *) pend_files, argc * sizeof (char *));
        !          1179:   bzero ((char *) pend_defs, argc * sizeof (char *));
        !          1180:   bzero ((char *) pend_undefs, argc * sizeof (char *));
        !          1181:   bzero ((char *) pend_assertions, argc * sizeof (char *));
        !          1182:   bzero ((char *) pend_includes, argc * sizeof (char *));
1.1       root     1183: 
                   1184:   /* Process switches and find input file name.  */
                   1185: 
                   1186:   for (i = 1; i < argc; i++) {
                   1187:     if (argv[i][0] != '-') {
                   1188:       if (out_fname != NULL)
                   1189:        fatal ("Usage: %s [switches] input output", argv[0]);
                   1190:       else if (in_fname != NULL)
                   1191:        out_fname = argv[i];
                   1192:       else
                   1193:        in_fname = argv[i];
                   1194:     } else {
                   1195:       switch (argv[i][1]) {
                   1196: 
                   1197:       case 'i':
                   1198:        if (!strcmp (argv[i], "-include")) {
                   1199:          if (i + 1 == argc)
1.1.1.5   root     1200:            fatal ("Filename missing after `-include' option");
1.1       root     1201:          else
                   1202:            pend_includes[i] = argv[i+1], i++;
                   1203:        }
                   1204:        if (!strcmp (argv[i], "-imacros")) {
                   1205:          if (i + 1 == argc)
1.1.1.5   root     1206:            fatal ("Filename missing after `-imacros' option");
1.1       root     1207:          else
                   1208:            pend_files[i] = argv[i+1], i++;
                   1209:        }
1.1.1.3   root     1210:        if (!strcmp (argv[i], "-iprefix")) {
                   1211:          if (i + 1 == argc)
1.1.1.5   root     1212:            fatal ("Filename missing after `-iprefix' option");
1.1.1.3   root     1213:          else
                   1214:            include_prefix = argv[++i];
                   1215:        }
1.1.1.7 ! root     1216:        if (!strcmp (argv[i], "-ifoutput")) {
        !          1217:          output_conditionals = 1;
        !          1218:        }
        !          1219:        if (!strcmp (argv[i], "-isystem")) {
        !          1220:          struct file_name_list *dirtmp;
        !          1221: 
        !          1222:          if (i + 1 == argc)
        !          1223:            fatal ("Filename missing after `-isystem' option");
        !          1224: 
        !          1225:          dirtmp = (struct file_name_list *)
        !          1226:            xmalloc (sizeof (struct file_name_list));
        !          1227:          dirtmp->next = 0;
        !          1228:          dirtmp->control_macro = 0;
        !          1229:          dirtmp->c_system_include_path = 1;
        !          1230:          dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) + 1);
        !          1231:          strcpy (dirtmp->fname, argv[++i]);
        !          1232:          dirtmp->got_name_map = 0;
        !          1233: 
        !          1234:          if (before_system == 0)
        !          1235:            before_system = dirtmp;
        !          1236:          else
        !          1237:            last_before_system->next = dirtmp;
        !          1238:          last_before_system = dirtmp; /* Tail follows the last one */
        !          1239:        }
1.1.1.5   root     1240:        /* Add directory to end of path for includes,
                   1241:           with the default prefix at the front of its name.  */
                   1242:        if (!strcmp (argv[i], "-iwithprefix")) {
                   1243:          struct file_name_list *dirtmp;
1.1.1.6   root     1244:          char *prefix;
                   1245: 
                   1246:          if (include_prefix != 0)
                   1247:            prefix = include_prefix;
                   1248:          else {
                   1249:            prefix = savestring (GCC_INCLUDE_DIR);
                   1250:            /* Remove the `include' from /usr/local/lib/gcc.../include.  */
                   1251:            if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
                   1252:              prefix[strlen (prefix) - 7] = 0;
                   1253:          }
1.1.1.5   root     1254: 
                   1255:          dirtmp = (struct file_name_list *)
                   1256:            xmalloc (sizeof (struct file_name_list));
                   1257:          dirtmp->next = 0;     /* New one goes on the end */
                   1258:          dirtmp->control_macro = 0;
1.1.1.6   root     1259:          dirtmp->c_system_include_path = 0;
1.1.1.5   root     1260:          if (i + 1 == argc)
                   1261:            fatal ("Directory name missing after `-iwithprefix' option");
                   1262: 
                   1263:          dirtmp->fname = (char *) xmalloc (strlen (argv[i+1])
1.1.1.6   root     1264:                                            + strlen (prefix) + 1);
                   1265:          strcpy (dirtmp->fname, prefix);
1.1.1.5   root     1266:          strcat (dirtmp->fname, argv[++i]);
1.1.1.7 ! root     1267:          dirtmp->got_name_map = 0;
1.1.1.5   root     1268: 
                   1269:          if (after_include == 0)
                   1270:            after_include = dirtmp;
                   1271:          else
                   1272:            last_after_include->next = dirtmp;
                   1273:          last_after_include = dirtmp; /* Tail follows the last one */
                   1274:        }
1.1.1.6   root     1275:        /* Add directory to main path for includes,
                   1276:           with the default prefix at the front of its name.  */
                   1277:        if (!strcmp (argv[i], "-iwithprefixbefore")) {
                   1278:          struct file_name_list *dirtmp;
                   1279:          char *prefix;
                   1280: 
                   1281:          if (include_prefix != 0)
                   1282:            prefix = include_prefix;
                   1283:          else {
                   1284:            prefix = savestring (GCC_INCLUDE_DIR);
                   1285:            /* Remove the `include' from /usr/local/lib/gcc.../include.  */
                   1286:            if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
                   1287:              prefix[strlen (prefix) - 7] = 0;
                   1288:          }
                   1289: 
                   1290:          dirtmp = (struct file_name_list *)
                   1291:            xmalloc (sizeof (struct file_name_list));
                   1292:          dirtmp->next = 0;     /* New one goes on the end */
                   1293:          dirtmp->control_macro = 0;
                   1294:          dirtmp->c_system_include_path = 0;
                   1295:          if (i + 1 == argc)
                   1296:            fatal ("Directory name missing after `-iwithprefixbefore' option");
                   1297: 
                   1298:          dirtmp->fname = (char *) xmalloc (strlen (argv[i+1])
                   1299:                                            + strlen (prefix) + 1);
                   1300:          strcpy (dirtmp->fname, prefix);
                   1301:          strcat (dirtmp->fname, argv[++i]);
1.1.1.7 ! root     1302:          dirtmp->got_name_map = 0;
1.1.1.6   root     1303: 
                   1304:          append_include_chain (dirtmp, dirtmp);
                   1305:        }
1.1       root     1306:        /* Add directory to end of path for includes.  */
                   1307:        if (!strcmp (argv[i], "-idirafter")) {
                   1308:          struct file_name_list *dirtmp;
                   1309: 
                   1310:          dirtmp = (struct file_name_list *)
                   1311:            xmalloc (sizeof (struct file_name_list));
                   1312:          dirtmp->next = 0;     /* New one goes on the end */
                   1313:          dirtmp->control_macro = 0;
1.1.1.6   root     1314:          dirtmp->c_system_include_path = 0;
1.1       root     1315:          if (i + 1 == argc)
1.1.1.5   root     1316:            fatal ("Directory name missing after `-idirafter' option");
1.1       root     1317:          else
                   1318:            dirtmp->fname = argv[++i];
1.1.1.7 ! root     1319:          dirtmp->got_name_map = 0;
1.1       root     1320: 
1.1.1.4   root     1321:          if (after_include == 0)
                   1322:            after_include = dirtmp;
                   1323:          else
                   1324:            last_after_include->next = dirtmp;
                   1325:          last_after_include = dirtmp; /* Tail follows the last one */
1.1       root     1326:        }
                   1327:        break;
                   1328: 
                   1329:       case 'o':
                   1330:        if (out_fname != NULL)
                   1331:          fatal ("Output filename specified twice");
                   1332:        if (i + 1 == argc)
                   1333:          fatal ("Filename missing after -o option");
                   1334:        out_fname = argv[++i];
                   1335:        if (!strcmp (out_fname, "-"))
                   1336:          out_fname = "";
                   1337:        break;
                   1338: 
                   1339:       case 'p':
                   1340:        if (!strcmp (argv[i], "-pedantic"))
                   1341:          pedantic = 1;
                   1342:        else if (!strcmp (argv[i], "-pedantic-errors")) {
                   1343:          pedantic = 1;
                   1344:          pedantic_errors = 1;
                   1345:        } else if (!strcmp (argv[i], "-pcp")) {
1.1.1.7 ! root     1346:          char *pcp_fname;
        !          1347:          if (i + 1 == argc)
        !          1348:            fatal ("Filename missing after -pcp option");
        !          1349:          pcp_fname = argv[++i];
1.1       root     1350:          pcp_outfile = 
                   1351:            ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
                   1352:             ? fopen (pcp_fname, "w")
                   1353:             : fdopen (dup (fileno (stdout)), "w"));
                   1354:          if (pcp_outfile == 0)
                   1355:            pfatal_with_name (pcp_fname);
                   1356:          no_precomp = 1;
                   1357:        }
                   1358:        break;
                   1359: 
                   1360:       case 't':
                   1361:        if (!strcmp (argv[i], "-traditional")) {
                   1362:          traditional = 1;
                   1363:          if (dollars_in_ident > 0)
                   1364:            dollars_in_ident = 1;
                   1365:        } else if (!strcmp (argv[i], "-trigraphs")) {
                   1366:          no_trigraphs = 0;
                   1367:        }
                   1368:        break;
                   1369: 
                   1370:       case 'l':
                   1371:        if (! strcmp (argv[i], "-lang-c"))
1.1.1.4   root     1372:          cplusplus = 0, cplusplus_comments = 0, objc = 0;
1.1       root     1373:        if (! strcmp (argv[i], "-lang-c++"))
1.1.1.4   root     1374:          cplusplus = 1, cplusplus_comments = 1, objc = 0;
1.1.1.6   root     1375:        if (! strcmp (argv[i], "-lang-c-c++-comments"))
                   1376:          cplusplus = 0, cplusplus_comments = 1, objc = 0;
1.1       root     1377:        if (! strcmp (argv[i], "-lang-objc"))
1.1.1.4   root     1378:          objc = 1, cplusplus = 0, cplusplus_comments = 1;
1.1       root     1379:        if (! strcmp (argv[i], "-lang-objc++"))
1.1.1.4   root     1380:          objc = 1, cplusplus = 1, cplusplus_comments = 1;
1.1       root     1381:        if (! strcmp (argv[i], "-lang-asm"))
                   1382:          lang_asm = 1;
                   1383:        if (! strcmp (argv[i], "-lint"))
1.1.1.7 ! root     1384:          for_lint = 1;
1.1       root     1385:        break;
                   1386: 
                   1387:       case '+':
1.1.1.4   root     1388:        cplusplus = 1, cplusplus_comments = 1;
1.1       root     1389:        break;
                   1390: 
                   1391:       case 'w':
                   1392:        inhibit_warnings = 1;
                   1393:        break;
                   1394: 
                   1395:       case 'W':
                   1396:        if (!strcmp (argv[i], "-Wtrigraphs"))
                   1397:          warn_trigraphs = 1;
                   1398:        else if (!strcmp (argv[i], "-Wno-trigraphs"))
                   1399:          warn_trigraphs = 0;
                   1400:        else if (!strcmp (argv[i], "-Wcomment"))
                   1401:          warn_comments = 1;
                   1402:        else if (!strcmp (argv[i], "-Wno-comment"))
                   1403:          warn_comments = 0;
                   1404:        else if (!strcmp (argv[i], "-Wcomments"))
                   1405:          warn_comments = 1;
                   1406:        else if (!strcmp (argv[i], "-Wno-comments"))
                   1407:          warn_comments = 0;
                   1408:        else if (!strcmp (argv[i], "-Wtraditional"))
                   1409:          warn_stringify = 1;
                   1410:        else if (!strcmp (argv[i], "-Wno-traditional"))
                   1411:          warn_stringify = 0;
1.1.1.2   root     1412:        else if (!strcmp (argv[i], "-Wimport"))
                   1413:          warn_import = 1;
                   1414:        else if (!strcmp (argv[i], "-Wno-import"))
                   1415:          warn_import = 0;
1.1       root     1416:        else if (!strcmp (argv[i], "-Werror"))
                   1417:          warnings_are_errors = 1;
                   1418:        else if (!strcmp (argv[i], "-Wno-error"))
                   1419:          warnings_are_errors = 0;
                   1420:        else if (!strcmp (argv[i], "-Wall"))
                   1421:          {
                   1422:            warn_trigraphs = 1;
                   1423:            warn_comments = 1;
                   1424:          }
                   1425:        break;
                   1426: 
                   1427:       case 'M':
1.1.1.7 ! root     1428:        /* The style of the choices here is a bit mixed.
        !          1429:           The chosen scheme is a hybrid of keeping all options in one string
        !          1430:           and specifying each option in a separate argument:
        !          1431:           -M|-MM|-MD file|-MMD file [-MG].  An alternative is:
        !          1432:           -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely:
        !          1433:           -M[M][G][D file].  This is awkward to handle in specs, and is not
        !          1434:           as extensible.  */
        !          1435:        /* ??? -MG must be specified in addition to one of -M or -MM.
        !          1436:           This can be relaxed in the future without breaking anything.
        !          1437:           The converse isn't true.  */
        !          1438: 
        !          1439:        /* -MG isn't valid with -MD or -MMD.  This is checked for later.  */
        !          1440:        if (!strcmp (argv[i], "-MG"))
        !          1441:          {
        !          1442:            print_deps_missing_files = 1;
        !          1443:            break;
        !          1444:          }
1.1       root     1445:        if (!strcmp (argv[i], "-M"))
                   1446:          print_deps = 2;
                   1447:        else if (!strcmp (argv[i], "-MM"))
                   1448:          print_deps = 1;
                   1449:        else if (!strcmp (argv[i], "-MD"))
                   1450:          print_deps = 2;
                   1451:        else if (!strcmp (argv[i], "-MMD"))
                   1452:          print_deps = 1;
                   1453:        /* For -MD and -MMD options, write deps on file named by next arg.  */
                   1454:        if (!strcmp (argv[i], "-MD")
                   1455:            || !strcmp (argv[i], "-MMD")) {
1.1.1.7 ! root     1456:          if (i + 1 == argc)
        !          1457:            fatal ("Filename missing after %s option", argv[i]);
1.1       root     1458:          i++;
                   1459:          deps_file = argv[i];
1.1.1.5   root     1460:          deps_mode = "w";
1.1       root     1461:        } else {
                   1462:          /* For -M and -MM, write deps on standard output
                   1463:             and suppress the usual output.  */
                   1464:          deps_stream = stdout;
                   1465:          inhibit_output = 1;
                   1466:        }         
                   1467:        break;
                   1468: 
                   1469:       case 'd':
                   1470:        {
                   1471:          char *p = argv[i] + 2;
                   1472:          char c;
                   1473:          while (c = *p++) {
                   1474:            /* Arg to -d specifies what parts of macros to dump */
                   1475:            switch (c) {
                   1476:            case 'M':
                   1477:              dump_macros = dump_only;
                   1478:              no_output = 1;
                   1479:              break;
                   1480:            case 'N':
                   1481:              dump_macros = dump_names;
                   1482:              break;
                   1483:            case 'D':
                   1484:              dump_macros = dump_definitions;
                   1485:              break;
                   1486:            }
                   1487:          }
                   1488:        }
                   1489:        break;
                   1490: 
                   1491:       case 'g':
                   1492:        if (argv[i][2] == '3')
                   1493:          debug_output = 1;
                   1494:        break;
                   1495: 
                   1496:       case 'v':
                   1497:        fprintf (stderr, "GNU CPP version %s", version_string);
                   1498: #ifdef TARGET_VERSION
                   1499:        TARGET_VERSION;
                   1500: #endif
                   1501:        fprintf (stderr, "\n");
1.1.1.6   root     1502:        verbose = 1;
1.1       root     1503:        break;
                   1504: 
                   1505:       case 'H':
                   1506:        print_include_names = 1;
                   1507:        break;
                   1508: 
                   1509:       case 'D':
1.1.1.7 ! root     1510:        if (argv[i][2] != 0)
        !          1511:          pend_defs[i] = argv[i] + 2;
        !          1512:        else if (i + 1 == argc)
        !          1513:          fatal ("Macro name missing after -D option");
        !          1514:        else
        !          1515:          i++, pend_defs[i] = argv[i];
1.1       root     1516:        break;
                   1517: 
                   1518:       case 'A':
                   1519:        {
1.1.1.7 ! root     1520:          char *p;
1.1       root     1521: 
                   1522:          if (argv[i][2] != 0)
                   1523:            p = argv[i] + 2;
                   1524:          else if (i + 1 == argc)
                   1525:            fatal ("Assertion missing after -A option");
                   1526:          else
                   1527:            p = argv[++i];
                   1528: 
                   1529:          if (!strcmp (p, "-")) {
                   1530:            /* -A- eliminates all predefined macros and assertions.
                   1531:               Let's include also any that were specified earlier
                   1532:               on the command line.  That way we can get rid of any
                   1533:               that were passed automatically in from GCC.  */
                   1534:            int j;
                   1535:            inhibit_predefs = 1;
                   1536:            for (j = 0; j < i; j++)
                   1537:              pend_defs[j] = pend_assertions[j] = 0;
                   1538:          } else {
                   1539:            pend_assertions[i] = p;
                   1540:            pend_assertion_options[i] = "-A";
                   1541:          }
                   1542:        }
                   1543:        break;
                   1544: 
                   1545:       case 'U':                /* JF #undef something */
                   1546:        if (argv[i][2] != 0)
                   1547:          pend_undefs[i] = argv[i] + 2;
                   1548:        else if (i + 1 == argc)
                   1549:          fatal ("Macro name missing after -U option");
                   1550:        else
                   1551:          pend_undefs[i] = argv[i+1], i++;
                   1552:        break;
                   1553: 
                   1554:       case 'C':
                   1555:        put_out_comments = 1;
                   1556:        break;
                   1557: 
                   1558:       case 'E':                        /* -E comes from cc -E; ignore it.  */
                   1559:        break;
                   1560: 
                   1561:       case 'P':
                   1562:        no_line_commands = 1;
                   1563:        break;
                   1564: 
                   1565:       case '$':                        /* Don't include $ in identifiers.  */
                   1566:        dollars_in_ident = 0;
                   1567:        break;
                   1568: 
                   1569:       case 'I':                        /* Add directory to path for includes.  */
                   1570:        {
                   1571:          struct file_name_list *dirtmp;
                   1572: 
1.1.1.4   root     1573:          if (! ignore_srcdir && !strcmp (argv[i] + 2, "-")) {
1.1       root     1574:            ignore_srcdir = 1;
1.1.1.4   root     1575:            /* Don't use any preceding -I directories for #include <...>.  */
                   1576:            first_bracket_include = 0;
                   1577:          }
1.1       root     1578:          else {
                   1579:            dirtmp = (struct file_name_list *)
                   1580:              xmalloc (sizeof (struct file_name_list));
                   1581:            dirtmp->next = 0;           /* New one goes on the end */
                   1582:            dirtmp->control_macro = 0;
1.1.1.6   root     1583:            dirtmp->c_system_include_path = 0;
1.1       root     1584:            if (argv[i][2] != 0)
                   1585:              dirtmp->fname = argv[i] + 2;
                   1586:            else if (i + 1 == argc)
                   1587:              fatal ("Directory name missing after -I option");
                   1588:            else
                   1589:              dirtmp->fname = argv[++i];
1.1.1.7 ! root     1590:            dirtmp->got_name_map = 0;
1.1.1.4   root     1591:            append_include_chain (dirtmp, dirtmp);
                   1592:          }
1.1       root     1593:        }
                   1594:        break;
                   1595: 
                   1596:       case 'n':
                   1597:        if (!strcmp (argv[i], "-nostdinc"))
                   1598:          /* -nostdinc causes no default include directories.
                   1599:             You must specify all include-file directories with -I.  */
                   1600:          no_standard_includes = 1;
1.1.1.3   root     1601:        else if (!strcmp (argv[i], "-nostdinc++"))
                   1602:          /* -nostdinc++ causes no default C++-specific include directories. */
                   1603:          no_standard_cplusplus_includes = 1;
1.1       root     1604:        else if (!strcmp (argv[i], "-noprecomp"))
                   1605:          no_precomp = 1;
                   1606:        break;
                   1607: 
                   1608:       case 'u':
                   1609:        /* Sun compiler passes undocumented switch "-undef".
                   1610:           Let's assume it means to inhibit the predefined symbols.  */
                   1611:        inhibit_predefs = 1;
                   1612:        break;
                   1613: 
                   1614:       case '\0': /* JF handle '-' as file name meaning stdin or stdout */
                   1615:        if (in_fname == NULL) {
                   1616:          in_fname = "";
                   1617:          break;
                   1618:        } else if (out_fname == NULL) {
                   1619:          out_fname = "";
                   1620:          break;
                   1621:        }       /* else fall through into error */
                   1622: 
                   1623:       default:
                   1624:        fatal ("Invalid option `%s'", argv[i]);
                   1625:       }
                   1626:     }
                   1627:   }
                   1628: 
                   1629:   /* Add dirs from CPATH after dirs from -I.  */
                   1630:   /* There seems to be confusion about what CPATH should do,
                   1631:      so for the moment it is not documented.  */
                   1632:   /* Some people say that CPATH should replace the standard include dirs,
                   1633:      but that seems pointless: it comes before them, so it overrides them
                   1634:      anyway.  */
1.1.1.7 ! root     1635: #ifdef WINNT
        !          1636:   p = (char *) getenv ("Include");
        !          1637: #else
1.1       root     1638:   p = (char *) getenv ("CPATH");
1.1.1.7 ! root     1639: #endif
1.1       root     1640:   if (p != 0 && ! no_standard_includes)
                   1641:     path_include (p);
                   1642: 
                   1643:   /* Now that dollars_in_ident is known, initialize is_idchar.  */
                   1644:   initialize_char_syntax ();
                   1645: 
                   1646:   /* Initialize output buffer */
                   1647: 
                   1648:   outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);
                   1649:   outbuf.bufp = outbuf.buf;
                   1650:   outbuf.length = OUTBUF_SIZE;
                   1651: 
                   1652:   /* Do partial setup of input buffer for the sake of generating
                   1653:      early #line directives (when -g is in effect).  */
                   1654: 
                   1655:   fp = &instack[++indepth];
                   1656:   if (in_fname == NULL)
                   1657:     in_fname = "";
                   1658:   fp->nominal_fname = fp->fname = in_fname;
                   1659:   fp->lineno = 0;
                   1660: 
1.1.1.7 ! root     1661:   /* In C++, wchar_t is a distinct basic type, and we can expect
        !          1662:      __wchar_t to be defined by cc1plus.  */
        !          1663:   if (cplusplus)
        !          1664:     wchar_type = "__wchar_t";
        !          1665: 
1.1       root     1666:   /* Install __LINE__, etc.  Must follow initialize_char_syntax
                   1667:      and option processing.  */
                   1668:   initialize_builtins (fp, &outbuf);
                   1669: 
                   1670:   /* Do standard #defines and assertions
                   1671:      that identify system and machine type.  */
                   1672: 
                   1673:   if (!inhibit_predefs) {
                   1674:     char *p = (char *) alloca (strlen (predefs) + 1);
                   1675:     strcpy (p, predefs);
                   1676:     while (*p) {
                   1677:       char *q;
                   1678:       while (*p == ' ' || *p == '\t')
                   1679:        p++;
                   1680:       /* Handle -D options.  */ 
                   1681:       if (p[0] == '-' && p[1] == 'D') {
                   1682:        q = &p[2];
                   1683:        while (*p && *p != ' ' && *p != '\t')
                   1684:          p++;
                   1685:        if (*p != 0)
                   1686:          *p++= 0;
                   1687:        if (debug_output)
                   1688:          output_line_command (fp, &outbuf, 0, same_file);
                   1689:        make_definition (q, &outbuf);
                   1690:        while (*p == ' ' || *p == '\t')
                   1691:          p++;
                   1692:       } else if (p[0] == '-' && p[1] == 'A') {
                   1693:        /* Handle -A options (assertions).  */ 
                   1694:        char *assertion;
                   1695:        char *past_name;
                   1696:        char *value;
                   1697:        char *past_value;
                   1698:        char *termination;
                   1699:        int save_char;
                   1700: 
                   1701:        assertion = &p[2];
                   1702:        past_name = assertion;
                   1703:        /* Locate end of name.  */
                   1704:        while (*past_name && *past_name != ' '
                   1705:               && *past_name != '\t' && *past_name != '(')
                   1706:          past_name++;
                   1707:        /* Locate `(' at start of value.  */
                   1708:        value = past_name;
                   1709:        while (*value && (*value == ' ' || *value == '\t'))
                   1710:          value++;
                   1711:        if (*value++ != '(')
                   1712:          abort ();
                   1713:        while (*value && (*value == ' ' || *value == '\t'))
                   1714:          value++;
                   1715:        past_value = value;
                   1716:        /* Locate end of value.  */
                   1717:        while (*past_value && *past_value != ' '
                   1718:               && *past_value != '\t' && *past_value != ')')
                   1719:          past_value++;
                   1720:        termination = past_value;
                   1721:        while (*termination && (*termination == ' ' || *termination == '\t'))
                   1722:          termination++;
                   1723:        if (*termination++ != ')')
                   1724:          abort ();
                   1725:        if (*termination && *termination != ' ' && *termination != '\t')
                   1726:          abort ();
                   1727:        /* Temporarily null-terminate the value.  */
                   1728:        save_char = *termination;
                   1729:        *termination = '\0';
                   1730:        /* Install the assertion.  */
                   1731:        make_assertion ("-A", assertion);
                   1732:        *termination = (char) save_char;
                   1733:        p = termination;
                   1734:        while (*p == ' ' || *p == '\t')
                   1735:          p++;
                   1736:       } else {
                   1737:        abort ();
                   1738:       }
                   1739:     }
                   1740:   }
                   1741: 
                   1742:   /* Now handle the command line options.  */
                   1743: 
1.1.1.4   root     1744:   /* Do -U's, -D's and -A's in the order they were seen.  */
                   1745:   for (i = 1; i < argc; i++) {
                   1746:     if (pend_undefs[i]) {
1.1       root     1747:       if (debug_output)
                   1748:         output_line_command (fp, &outbuf, 0, same_file);
1.1.1.4   root     1749:       make_undef (pend_undefs[i], &outbuf);
1.1       root     1750:     }
1.1.1.4   root     1751:     if (pend_defs[i]) {
1.1       root     1752:       if (debug_output)
                   1753:         output_line_command (fp, &outbuf, 0, same_file);
1.1.1.4   root     1754:       make_definition (pend_defs[i], &outbuf);
1.1       root     1755:     }
1.1.1.4   root     1756:     if (pend_assertions[i])
                   1757:       make_assertion (pend_assertion_options[i], pend_assertions[i]);
                   1758:   }
1.1       root     1759: 
                   1760:   done_initializing = 1;
                   1761: 
                   1762:   { /* read the appropriate environment variable and if it exists
                   1763:        replace include_defaults with the listed path. */
                   1764:     char *epath = 0;
                   1765:     switch ((objc << 1) + cplusplus)
                   1766:       {
                   1767:       case 0:
                   1768:        epath = getenv ("C_INCLUDE_PATH");
                   1769:        break;
                   1770:       case 1:
1.1.1.2   root     1771:        epath = getenv ("CPLUS_INCLUDE_PATH");
1.1       root     1772:        break;
                   1773:       case 2:
                   1774:        epath = getenv ("OBJC_INCLUDE_PATH");
                   1775:        break;
                   1776:       case 3:
1.1.1.2   root     1777:        epath = getenv ("OBJCPLUS_INCLUDE_PATH");
1.1       root     1778:        break;
                   1779:       }
                   1780:     /* If the environment var for this language is set,
                   1781:        add to the default list of include directories.  */
                   1782:     if (epath) {
                   1783:       char *nstore = (char *) alloca (strlen (epath) + 2);
                   1784:       int num_dirs;
                   1785:       char *startp, *endp;
                   1786: 
                   1787:       for (num_dirs = 1, startp = epath; *startp; startp++)
1.1.1.3   root     1788:        if (*startp == PATH_SEPARATOR)
1.1       root     1789:          num_dirs++;
                   1790:       include_defaults
                   1791:        = (struct default_include *) xmalloc ((num_dirs
                   1792:                                               * sizeof (struct default_include))
                   1793:                                              + sizeof (include_defaults_array));
                   1794:       startp = endp = epath;
                   1795:       num_dirs = 0;
                   1796:       while (1) {
1.1.1.2   root     1797:         /* Handle cases like c:/usr/lib:d:/gcc/lib */
1.1.1.3   root     1798:         if ((*endp == PATH_SEPARATOR
                   1799: #if 0 /* Obsolete, now that we use semicolons as the path separator.  */
1.1.1.2   root     1800: #ifdef __MSDOS__
1.1.1.4   root     1801:             && (endp-startp != 1 || !isalpha (*startp))
1.1.1.2   root     1802: #endif
1.1.1.3   root     1803: #endif
1.1.1.2   root     1804:             )
1.1.1.3   root     1805:             || *endp == 0) {
1.1       root     1806:          strncpy (nstore, startp, endp-startp);
                   1807:          if (endp == startp)
                   1808:            strcpy (nstore, ".");
                   1809:          else
                   1810:            nstore[endp-startp] = '\0';
                   1811: 
                   1812:          include_defaults[num_dirs].fname = savestring (nstore);
                   1813:          include_defaults[num_dirs].cplusplus = cplusplus;
1.1.1.7 ! root     1814:          include_defaults[num_dirs].cxx_aware = 1;
1.1       root     1815:          num_dirs++;
                   1816:          if (*endp == '\0')
                   1817:            break;
                   1818:          endp = startp = endp + 1;
                   1819:        } else
                   1820:          endp++;
                   1821:       }
                   1822:       /* Put the usual defaults back in at the end.  */
1.1.1.7 ! root     1823:       bcopy ((char *) include_defaults_array,
        !          1824:             (char *) &include_defaults[num_dirs],
1.1       root     1825:             sizeof (include_defaults_array));
                   1826:     }
                   1827:   }
                   1828: 
1.1.1.7 ! root     1829:   append_include_chain (before_system, last_before_system);
        !          1830:   first_system_include = before_system;
        !          1831: 
1.1       root     1832:   /* Unless -fnostdinc,
                   1833:      tack on the standard include file dirs to the specified list */
                   1834:   if (!no_standard_includes) {
                   1835:     struct default_include *p = include_defaults;
1.1.1.3   root     1836:     char *specd_prefix = include_prefix;
1.1       root     1837:     char *default_prefix = savestring (GCC_INCLUDE_DIR);
                   1838:     int default_len = 0;
                   1839:     /* Remove the `include' from /usr/local/lib/gcc.../include.  */
                   1840:     if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
                   1841:       default_len = strlen (default_prefix) - 7;
                   1842:       default_prefix[default_len] = 0;
                   1843:     }
                   1844:     /* Search "translated" versions of GNU directories.
                   1845:        These have /usr/local/lib/gcc... replaced by specd_prefix.  */
                   1846:     if (specd_prefix != 0 && default_len != 0)
                   1847:       for (p = include_defaults; p->fname; p++) {
                   1848:        /* Some standard dirs are only for C++.  */
1.1.1.3   root     1849:        if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
1.1       root     1850:          /* Does this dir start with the prefix?  */
                   1851:          if (!strncmp (p->fname, default_prefix, default_len)) {
                   1852:            /* Yes; change prefix and add to search list.  */
                   1853:            struct file_name_list *new
                   1854:              = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
                   1855:            int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len;
                   1856:            char *str = (char *) xmalloc (this_len + 1);
                   1857:            strcpy (str, specd_prefix);
                   1858:            strcat (str, p->fname + default_len);
                   1859:            new->fname = str;
                   1860:            new->control_macro = 0;
1.1.1.7 ! root     1861:            new->c_system_include_path = !p->cxx_aware;
        !          1862:            new->got_name_map = 0;
1.1.1.4   root     1863:            append_include_chain (new, new);
                   1864:            if (first_system_include == 0)
                   1865:              first_system_include = new;
1.1       root     1866:          }
                   1867:        }
                   1868:       }
                   1869:     /* Search ordinary names for GNU include directories.  */
                   1870:     for (p = include_defaults; p->fname; p++) {
                   1871:       /* Some standard dirs are only for C++.  */
1.1.1.3   root     1872:       if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
1.1       root     1873:        struct file_name_list *new
                   1874:          = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
                   1875:        new->control_macro = 0;
1.1.1.7 ! root     1876:        new->c_system_include_path = !p->cxx_aware;
1.1       root     1877:        new->fname = p->fname;
1.1.1.7 ! root     1878:        new->got_name_map = 0;
1.1.1.4   root     1879:        append_include_chain (new, new);
                   1880:        if (first_system_include == 0)
                   1881:          first_system_include = new;
1.1       root     1882:       }
                   1883:     }
                   1884:   }
                   1885: 
                   1886:   /* Tack the after_include chain at the end of the include chain.  */
1.1.1.4   root     1887:   append_include_chain (after_include, last_after_include);
                   1888:   if (first_system_include == 0)
                   1889:     first_system_include = after_include;
1.1       root     1890: 
1.1.1.6   root     1891:   /* With -v, print the list of dirs to search.  */
                   1892:   if (verbose) {
                   1893:     struct file_name_list *p;
                   1894:     fprintf (stderr, "#include \"...\" search starts here:\n");
                   1895:     for (p = include; p; p = p->next) {
                   1896:       if (p == first_bracket_include)
                   1897:        fprintf (stderr, "#include <...> search starts here:\n");
                   1898:       fprintf (stderr, " %s\n", p->fname);
                   1899:     }
                   1900:     fprintf (stderr, "End of search list.\n");
                   1901:   }
                   1902: 
1.1       root     1903:   /* Scan the -imacros files before the main input.
                   1904:      Much like #including them, but with no_output set
                   1905:      so that only their macro definitions matter.  */
                   1906: 
1.1.1.7 ! root     1907:   no_output++; no_record_file++;
1.1       root     1908:   for (i = 1; i < argc; i++)
                   1909:     if (pend_files[i]) {
                   1910:       int fd = open (pend_files[i], O_RDONLY, 0666);
                   1911:       if (fd < 0) {
                   1912:        perror_with_name (pend_files[i]);
                   1913:        return FAILURE_EXIT_CODE;
                   1914:       }
1.1.1.4   root     1915:       finclude (fd, pend_files[i], &outbuf, 0, NULL_PTR);
1.1       root     1916:     }
1.1.1.7 ! root     1917:   no_output--; no_record_file--;
1.1       root     1918: 
                   1919:   /* Copy the entire contents of the main input file into
                   1920:      the stacked input buffer previously allocated for it.  */
                   1921: 
                   1922:   /* JF check for stdin */
                   1923:   if (in_fname == NULL || *in_fname == 0) {
                   1924:     in_fname = "";
                   1925:     f = 0;
                   1926:   } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0)
                   1927:     goto perror;
                   1928: 
1.1.1.7 ! root     1929:   /* -MG doesn't select the form of output and must be specified with one of
        !          1930:      -M or -MM.  -MG doesn't make sense with -MD or -MMD since they don't
        !          1931:      inhibit compilation.  */
        !          1932:   if (print_deps_missing_files && (print_deps == 0 || !inhibit_output))
        !          1933:     fatal ("-MG must be specified with one of -M or -MM");
        !          1934: 
1.1       root     1935:   /* Either of two environment variables can specify output of deps.
                   1936:      Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
                   1937:      where OUTPUT_FILE is the file to write deps info to
                   1938:      and DEPS_TARGET is the target to mention in the deps.  */
                   1939: 
                   1940:   if (print_deps == 0
                   1941:       && (getenv ("SUNPRO_DEPENDENCIES") != 0
                   1942:          || getenv ("DEPENDENCIES_OUTPUT") != 0)) {
                   1943:     char *spec = getenv ("DEPENDENCIES_OUTPUT");
                   1944:     char *s;
                   1945:     char *output_file;
                   1946: 
                   1947:     if (spec == 0) {
                   1948:       spec = getenv ("SUNPRO_DEPENDENCIES");
                   1949:       print_deps = 2;
                   1950:     }
                   1951:     else
                   1952:       print_deps = 1;
                   1953: 
                   1954:     s = spec;
                   1955:     /* Find the space before the DEPS_TARGET, if there is one.  */
1.1.1.4   root     1956:     /* This should use index.  (mrs) */
1.1       root     1957:     while (*s != 0 && *s != ' ') s++;
                   1958:     if (*s != 0) {
                   1959:       deps_target = s + 1;
                   1960:       output_file = (char *) xmalloc (s - spec + 1);
                   1961:       bcopy (spec, output_file, s - spec);
                   1962:       output_file[s - spec] = 0;
                   1963:     }
                   1964:     else {
                   1965:       deps_target = 0;
                   1966:       output_file = spec;
                   1967:     }
                   1968:       
                   1969:     deps_file = output_file;
1.1.1.5   root     1970:     deps_mode = "a";
1.1       root     1971:   }
                   1972: 
                   1973:   /* For -M, print the expected object file name
                   1974:      as the target of this Make-rule.  */
                   1975:   if (print_deps) {
                   1976:     deps_allocated_size = 200;
                   1977:     deps_buffer = (char *) xmalloc (deps_allocated_size);
                   1978:     deps_buffer[0] = 0;
                   1979:     deps_size = 0;
                   1980:     deps_column = 0;
                   1981: 
                   1982:     if (deps_target) {
1.1.1.7 ! root     1983:       deps_output (deps_target, ':');
        !          1984:     } else if (*in_fname == 0) {
        !          1985:       deps_output ("-", ':');
        !          1986:     } else {
        !          1987:       char *p, *q;
1.1       root     1988:       int len;
1.1.1.7 ! root     1989: 
        !          1990:       /* Discard all directory prefixes from filename.  */
        !          1991:       if ((q = rindex (in_fname, '/')) != NULL
        !          1992: #ifdef DIR_SEPARATOR
        !          1993:          && (q = rindex (in_fname, DIR_SEPARATOR)) != NULL
        !          1994: #endif
        !          1995:          )
        !          1996:        ++q;
        !          1997:       else
        !          1998:        q = in_fname;
        !          1999: 
        !          2000:       /* Copy remainder to mungable area.  */
        !          2001:       p = (char *) alloca (strlen(q) + 8);
        !          2002:       strcpy (p, q);
        !          2003: 
1.1       root     2004:       /* Output P, but remove known suffixes.  */
                   2005:       len = strlen (p);
1.1.1.7 ! root     2006:       q = p + len;
        !          2007:       if (len >= 2
        !          2008:          && p[len - 2] == '.'
        !          2009:          && index("cCsSm", p[len - 1]))
        !          2010:        q = p + (len - 2);
        !          2011:       else if (len >= 3
        !          2012:               && p[len - 3] == '.'
1.1       root     2013:               && p[len - 2] == 'c'
                   2014:               && p[len - 1] == 'c')
1.1.1.7 ! root     2015:        q = p + (len - 3);
        !          2016:       else if (len >= 4
        !          2017:               && p[len - 4] == '.'
1.1.1.5   root     2018:               && p[len - 3] == 'c'
                   2019:               && p[len - 2] == 'x'
                   2020:               && p[len - 1] == 'x')
1.1.1.7 ! root     2021:        q = p + (len - 4);
        !          2022:       else if (len >= 4
        !          2023:               && p[len - 4] == '.'
        !          2024:               && p[len - 3] == 'c'
        !          2025:               && p[len - 2] == 'p'
        !          2026:               && p[len - 1] == 'p')
        !          2027:        q = p + (len - 4);
        !          2028: 
1.1       root     2029:       /* Supply our own suffix.  */
1.1.1.4   root     2030: #ifndef VMS
1.1.1.7 ! root     2031:       strcpy (q, ".o");
1.1.1.4   root     2032: #else
1.1.1.7 ! root     2033:       strcpy (q, ".obj");
1.1.1.4   root     2034: #endif
1.1.1.7 ! root     2035: 
        !          2036:       deps_output (p, ':');
        !          2037:       deps_output (in_fname, ' ');
1.1       root     2038:     }
                   2039:   }
                   2040: 
                   2041:   file_size_and_mode (f, &st_mode, &st_size);
                   2042:   fp->nominal_fname = fp->fname = in_fname;
                   2043:   fp->lineno = 1;
                   2044:   fp->system_header_p = 0;
                   2045:   /* JF all this is mine about reading pipes and ttys */
                   2046:   if (! S_ISREG (st_mode)) {
                   2047:     /* Read input from a file that is not a normal disk file.
                   2048:        We cannot preallocate a buffer with the correct size,
                   2049:        so we must read in the file a piece at the time and make it bigger.  */
                   2050:     int size;
                   2051:     int bsize;
                   2052:     int cnt;
                   2053: 
                   2054:     bsize = 2000;
                   2055:     size = 0;
                   2056:     fp->buf = (U_CHAR *) xmalloc (bsize + 2);
                   2057:     for (;;) {
1.1.1.7 ! root     2058:       cnt = safe_read (f, fp->buf + size, bsize - size);
1.1       root     2059:       if (cnt < 0) goto perror;        /* error! */
                   2060:       size += cnt;
1.1.1.7 ! root     2061:       if (size != bsize) break;        /* End of file */
        !          2062:       bsize *= 2;
        !          2063:       fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
1.1       root     2064:     }
                   2065:     fp->length = size;
                   2066:   } else {
                   2067:     /* Read a file whose size we can determine in advance.
                   2068:        For the sake of VMS, st_size is just an upper bound.  */
                   2069:     fp->buf = (U_CHAR *) xmalloc (st_size + 2);
1.1.1.7 ! root     2070:     fp->length = safe_read (f, fp->buf, st_size);
        !          2071:     if (fp->length < 0) goto perror;
1.1       root     2072:   }
                   2073:   fp->bufp = fp->buf;
                   2074:   fp->if_stack = if_stack;
                   2075: 
                   2076:   /* Make sure data ends with a newline.  And put a null after it.  */
                   2077: 
                   2078:   if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
                   2079:       /* Backslash-newline at end is not good enough.  */
                   2080:       || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
                   2081:     fp->buf[fp->length++] = '\n';
                   2082:     missing_newline = 1;
                   2083:   }
                   2084:   fp->buf[fp->length] = '\0';
                   2085: 
                   2086:   /* Unless inhibited, convert trigraphs in the input.  */
                   2087: 
                   2088:   if (!no_trigraphs)
                   2089:     trigraph_pcp (fp);
                   2090: 
                   2091:   /* Now that we know the input file is valid, open the output.  */
                   2092: 
                   2093:   if (!out_fname || !strcmp (out_fname, ""))
                   2094:     out_fname = "stdout";
                   2095:   else if (! freopen (out_fname, "w", stdout))
                   2096:     pfatal_with_name (out_fname);
                   2097: 
                   2098:   output_line_command (fp, &outbuf, 0, same_file);
                   2099: 
                   2100:   /* Scan the -include files before the main input.  */
                   2101: 
1.1.1.7 ! root     2102:   no_record_file++;
1.1       root     2103:   for (i = 1; i < argc; i++)
                   2104:     if (pend_includes[i]) {
                   2105:       int fd = open (pend_includes[i], O_RDONLY, 0666);
                   2106:       if (fd < 0) {
                   2107:        perror_with_name (pend_includes[i]);
                   2108:        return FAILURE_EXIT_CODE;
                   2109:       }
1.1.1.4   root     2110:       finclude (fd, pend_includes[i], &outbuf, 0, NULL_PTR);
1.1       root     2111:     }
1.1.1.7 ! root     2112:   no_record_file--;
1.1       root     2113: 
                   2114:   /* Scan the input, processing macros and directives.  */
                   2115: 
                   2116:   rescan (&outbuf, 0);
                   2117: 
1.1.1.5   root     2118:   if (missing_newline)
                   2119:     fp->lineno--;
                   2120: 
1.1       root     2121:   if (pedantic && missing_newline)
                   2122:     pedwarn ("file does not end in newline");
                   2123: 
                   2124:   /* Now we have processed the entire input
                   2125:      Write whichever kind of output has been requested.  */
                   2126: 
                   2127:   if (dump_macros == dump_only)
                   2128:     dump_all_macros ();
                   2129:   else if (! inhibit_output) {
                   2130:     write_output ();
                   2131:   }
                   2132: 
                   2133:   if (print_deps) {
1.1.1.4   root     2134:     /* Don't actually write the deps file if compilation has failed.  */
                   2135:     if (errors == 0) {
1.1.1.5   root     2136:       if (deps_file && ! (deps_stream = fopen (deps_file, deps_mode)))
1.1.1.4   root     2137:        pfatal_with_name (deps_file);
1.1       root     2138:       fputs (deps_buffer, deps_stream);
                   2139:       putc ('\n', deps_stream);
1.1.1.4   root     2140:       if (deps_file) {
                   2141:        if (ferror (deps_stream) || fclose (deps_stream) != 0)
1.1       root     2142:          fatal ("I/O error on output");
                   2143:       }
                   2144:     }
                   2145:   }
                   2146: 
1.1.1.5   root     2147:   if (pcp_outfile && pcp_outfile != stdout
                   2148:       && (ferror (pcp_outfile) || fclose (pcp_outfile) != 0))
                   2149:     fatal ("I/O error on `-pcp' output");
                   2150: 
1.1.1.4   root     2151:   if (ferror (stdout) || fclose (stdout) != 0)
1.1       root     2152:     fatal ("I/O error on output");
                   2153: 
                   2154:   if (errors)
                   2155:     exit (FAILURE_EXIT_CODE);
                   2156:   exit (SUCCESS_EXIT_CODE);
                   2157: 
                   2158:  perror:
                   2159:   pfatal_with_name (in_fname);
                   2160:   return 0;
                   2161: }
                   2162: 
                   2163: /* Given a colon-separated list of file names PATH,
                   2164:    add all the names to the search path for include files.  */
                   2165: 
                   2166: static void
                   2167: path_include (path)
                   2168:      char *path;
                   2169: {
                   2170:   char *p;
                   2171: 
                   2172:   p = path;
                   2173: 
                   2174:   if (*p)
                   2175:     while (1) {
                   2176:       char *q = p;
                   2177:       char *name;
                   2178:       struct file_name_list *dirtmp;
                   2179: 
                   2180:       /* Find the end of this name.  */
1.1.1.3   root     2181:       while (*q != 0 && *q != PATH_SEPARATOR) q++;
1.1       root     2182:       if (p == q) {
                   2183:        /* An empty name in the path stands for the current directory.  */
                   2184:        name = (char *) xmalloc (2);
                   2185:        name[0] = '.';
                   2186:        name[1] = 0;
                   2187:       } else {
                   2188:        /* Otherwise use the directory that is named.  */
                   2189:        name = (char *) xmalloc (q - p + 1);
                   2190:        bcopy (p, name, q - p);
                   2191:        name[q - p] = 0;
                   2192:       }
                   2193: 
                   2194:       dirtmp = (struct file_name_list *)
                   2195:        xmalloc (sizeof (struct file_name_list));
                   2196:       dirtmp->next = 0;                /* New one goes on the end */
                   2197:       dirtmp->control_macro = 0;
1.1.1.6   root     2198:       dirtmp->c_system_include_path = 0;
1.1       root     2199:       dirtmp->fname = name;
1.1.1.7 ! root     2200:       dirtmp->got_name_map = 0;
1.1.1.4   root     2201:       append_include_chain (dirtmp, dirtmp);
1.1       root     2202: 
                   2203:       /* Advance past this name.  */
                   2204:       p = q;
                   2205:       if (*p == 0)
                   2206:        break;
                   2207:       /* Skip the colon.  */
                   2208:       p++;
                   2209:     }
                   2210: }
                   2211: 
1.1.1.7 ! root     2212: /* Return the address of the first character in S that equals C.
        !          2213:    S is an array of length N, possibly containing '\0's, and followed by '\0'.
        !          2214:    Return 0 if there is no such character.  Assume that C itself is not '\0'.
        !          2215:    If we knew we could use memchr, we could just invoke memchr (S, C, N),
        !          2216:    but unfortunately memchr isn't autoconfigured yet.  */
        !          2217: 
        !          2218: static U_CHAR *
        !          2219: index0 (s, c, n)
        !          2220:      U_CHAR *s;
        !          2221:      int c;
        !          2222:      int n;
        !          2223: {
        !          2224:   for (;;) {
        !          2225:     char *q = index (s, c);
        !          2226:     if (q)
        !          2227:       return (U_CHAR *) q;
        !          2228:     else {
        !          2229:       int l = strlen (s);
        !          2230:       if (l == n)
        !          2231:        return 0;
        !          2232:       l++;
        !          2233:       s += l;
        !          2234:       n -= l;
        !          2235:     }
        !          2236:   }
        !          2237: }
        !          2238: 
1.1       root     2239: /* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF
                   2240:    before main CCCP processing.  Name `pcp' is also in honor of the
                   2241:    drugs the trigraph designers must have been on.
                   2242: 
                   2243:    Using an extra pass through the buffer takes a little extra time,
                   2244:    but is infinitely less hairy than trying to handle trigraphs inside
                   2245:    strings, etc. everywhere, and also makes sure that trigraphs are
                   2246:    only translated in the top level of processing. */
                   2247: 
                   2248: static void
                   2249: trigraph_pcp (buf)
                   2250:      FILE_BUF *buf;
                   2251: {
1.1.1.7 ! root     2252:   register U_CHAR c, *fptr, *bptr, *sptr, *lptr;
1.1       root     2253:   int len;
                   2254: 
                   2255:   fptr = bptr = sptr = buf->buf;
1.1.1.7 ! root     2256:   lptr = fptr + buf->length;
        !          2257:   while ((sptr = (U_CHAR *) index0 (sptr, '?', lptr - sptr)) != NULL) {
1.1       root     2258:     if (*++sptr != '?')
                   2259:       continue;
                   2260:     switch (*++sptr) {
                   2261:       case '=':
                   2262:       c = '#';
                   2263:       break;
                   2264:     case '(':
                   2265:       c = '[';
                   2266:       break;
                   2267:     case '/':
                   2268:       c = '\\';
                   2269:       break;
                   2270:     case ')':
                   2271:       c = ']';
                   2272:       break;
                   2273:     case '\'':
                   2274:       c = '^';
                   2275:       break;
                   2276:     case '<':
                   2277:       c = '{';
                   2278:       break;
                   2279:     case '!':
                   2280:       c = '|';
                   2281:       break;
                   2282:     case '>':
                   2283:       c = '}';
                   2284:       break;
                   2285:     case '-':
                   2286:       c  = '~';
                   2287:       break;
                   2288:     case '?':
                   2289:       sptr--;
                   2290:       continue;
                   2291:     default:
                   2292:       continue;
                   2293:     }
                   2294:     len = sptr - fptr - 2;
1.1.1.7 ! root     2295: 
        !          2296:     /* BSD doc says bcopy () works right for overlapping strings.  In ANSI
        !          2297:        C, this will be memmove (). */
1.1       root     2298:     if (bptr != fptr && len > 0)
1.1.1.7 ! root     2299:       bcopy ((char *) fptr, (char *) bptr, len);
        !          2300: 
1.1       root     2301:     bptr += len;
                   2302:     *bptr++ = c;
                   2303:     fptr = ++sptr;
                   2304:   }
                   2305:   len = buf->length - (fptr - buf->buf);
                   2306:   if (bptr != fptr && len > 0)
1.1.1.7 ! root     2307:     bcopy ((char *) fptr, (char *) bptr, len);
1.1       root     2308:   buf->length -= fptr - bptr;
                   2309:   buf->buf[buf->length] = '\0';
                   2310:   if (warn_trigraphs && fptr != bptr)
                   2311:     warning ("%d trigraph(s) encountered", (fptr - bptr) / 2);
                   2312: }
                   2313: 
                   2314: /* Move all backslash-newline pairs out of embarrassing places.
                   2315:    Exchange all such pairs following BP
1.1.1.2   root     2316:    with any potentially-embarrassing characters that follow them.
1.1       root     2317:    Potentially-embarrassing characters are / and *
                   2318:    (because a backslash-newline inside a comment delimiter
                   2319:    would cause it not to be recognized).  */
                   2320: 
                   2321: static void
                   2322: newline_fix (bp)
                   2323:      U_CHAR *bp;
                   2324: {
                   2325:   register U_CHAR *p = bp;
                   2326: 
                   2327:   /* First count the backslash-newline pairs here.  */
                   2328: 
1.1.1.7 ! root     2329:   while (p[0] == '\\' && p[1] == '\n')
        !          2330:     p += 2;
1.1       root     2331: 
                   2332:   /* What follows the backslash-newlines is not embarrassing.  */
                   2333: 
1.1.1.7 ! root     2334:   if (*p != '/' && *p != '*')
1.1       root     2335:     return;
                   2336: 
                   2337:   /* Copy all potentially embarrassing characters
                   2338:      that follow the backslash-newline pairs
                   2339:      down to where the pairs originally started.  */
                   2340: 
                   2341:   while (*p == '*' || *p == '/')
                   2342:     *bp++ = *p++;
                   2343: 
                   2344:   /* Now write the same number of pairs after the embarrassing chars.  */
1.1.1.7 ! root     2345:   while (bp < p) {
1.1       root     2346:     *bp++ = '\\';
                   2347:     *bp++ = '\n';
                   2348:   }
                   2349: }
                   2350: 
                   2351: /* Like newline_fix but for use within a directive-name.
                   2352:    Move any backslash-newlines up past any following symbol constituents.  */
                   2353: 
                   2354: static void
                   2355: name_newline_fix (bp)
                   2356:      U_CHAR *bp;
                   2357: {
                   2358:   register U_CHAR *p = bp;
                   2359: 
                   2360:   /* First count the backslash-newline pairs here.  */
1.1.1.7 ! root     2361:   while (p[0] == '\\' && p[1] == '\n')
        !          2362:     p += 2;
1.1       root     2363: 
                   2364:   /* What follows the backslash-newlines is not embarrassing.  */
                   2365: 
1.1.1.7 ! root     2366:   if (!is_idchar[*p])
1.1       root     2367:     return;
                   2368: 
                   2369:   /* Copy all potentially embarrassing characters
                   2370:      that follow the backslash-newline pairs
                   2371:      down to where the pairs originally started.  */
                   2372: 
                   2373:   while (is_idchar[*p])
                   2374:     *bp++ = *p++;
                   2375: 
                   2376:   /* Now write the same number of pairs after the embarrassing chars.  */
1.1.1.7 ! root     2377:   while (bp < p) {
1.1       root     2378:     *bp++ = '\\';
                   2379:     *bp++ = '\n';
                   2380:   }
                   2381: }
                   2382: 
                   2383: /* Look for lint commands in comments.
                   2384: 
                   2385:    When we come in here, ibp points into a comment.  Limit is as one expects.
                   2386:    scan within the comment -- it should start, after lwsp, with a lint command.
                   2387:    If so that command is returned as a (constant) string.
                   2388: 
                   2389:    Upon return, any arg will be pointed to with argstart and will be
                   2390:    arglen long.  Note that we don't parse that arg since it will just
                   2391:    be printed out again.
                   2392: */
                   2393: 
                   2394: static char *
                   2395: get_lintcmd (ibp, limit, argstart, arglen, cmdlen)
                   2396:      register U_CHAR *ibp;
                   2397:      register U_CHAR *limit;
                   2398:      U_CHAR **argstart;                /* point to command arg */
                   2399:      int *arglen, *cmdlen;     /* how long they are */
                   2400: {
                   2401:   long linsize;
                   2402:   register U_CHAR *numptr;     /* temp for arg parsing */
                   2403: 
                   2404:   *arglen = 0;
                   2405: 
                   2406:   SKIP_WHITE_SPACE (ibp);
                   2407: 
                   2408:   if (ibp >= limit) return NULL;
                   2409: 
                   2410:   linsize = limit - ibp;
                   2411:   
                   2412:   /* Oh, I wish C had lexical functions... hell, I'll just open-code the set */
                   2413:   if ((linsize >= 10) && !strncmp (ibp, "NOTREACHED", 10)) {
                   2414:     *cmdlen = 10;
                   2415:     return "NOTREACHED";
                   2416:   }
                   2417:   if ((linsize >= 8) && !strncmp (ibp, "ARGSUSED", 8)) {
                   2418:     *cmdlen = 8;
                   2419:     return "ARGSUSED";
                   2420:   }
1.1.1.4   root     2421:   if ((linsize >= 11) && !strncmp (ibp, "LINTLIBRARY", 11)) {
                   2422:     *cmdlen = 11;
1.1       root     2423:     return "LINTLIBRARY";
                   2424:   }
                   2425:   if ((linsize >= 7) && !strncmp (ibp, "VARARGS", 7)) {
                   2426:     *cmdlen = 7;
                   2427:     ibp += 7; linsize -= 7;
                   2428:     if ((linsize == 0) || ! isdigit (*ibp)) return "VARARGS";
                   2429: 
                   2430:     /* OK, read a number */
                   2431:     for (numptr = *argstart = ibp; (numptr < limit) && isdigit (*numptr);
                   2432:         numptr++);
                   2433:     *arglen = numptr - *argstart;
                   2434:     return "VARARGS";
                   2435:   }
                   2436:   return NULL;
                   2437: }
                   2438: 
                   2439: /*
                   2440:  * The main loop of the program.
                   2441:  *
                   2442:  * Read characters from the input stack, transferring them to the
                   2443:  * output buffer OP.
                   2444:  *
                   2445:  * Macros are expanded and push levels on the input stack.
                   2446:  * At the end of such a level it is popped off and we keep reading.
                   2447:  * At the end of any other kind of level, we return.
                   2448:  * #-directives are handled, except within macros.
                   2449:  *
                   2450:  * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input
                   2451:  * and insert them when appropriate.  This is set while scanning macro
                   2452:  * arguments before substitution.  It is zero when scanning for final output.
                   2453:  *   There are three types of Newline markers:
                   2454:  *   * Newline -  follows a macro name that was not expanded
                   2455:  *     because it appeared inside an expansion of the same macro.
                   2456:  *     This marker prevents future expansion of that identifier.
                   2457:  *     When the input is rescanned into the final output, these are deleted.
                   2458:  *     These are also deleted by ## concatenation.
                   2459:  *   * Newline Space (or Newline and any other whitespace character)
                   2460:  *     stands for a place that tokens must be separated or whitespace
                   2461:  *     is otherwise desirable, but where the ANSI standard specifies there
                   2462:  *     is no whitespace.  This marker turns into a Space (or whichever other
                   2463:  *     whitespace char appears in the marker) in the final output,
                   2464:  *     but it turns into nothing in an argument that is stringified with #.
                   2465:  *     Such stringified arguments are the only place where the ANSI standard
                   2466:  *     specifies with precision that whitespace may not appear.
                   2467:  *
                   2468:  * During this function, IP->bufp is kept cached in IBP for speed of access.
                   2469:  * Likewise, OP->bufp is kept in OBP.  Before calling a subroutine
                   2470:  * IBP, IP and OBP must be copied back to memory.  IP and IBP are
                   2471:  * copied back with the RECACHE macro.  OBP must be copied back from OP->bufp
                   2472:  * explicitly, and before RECACHE, since RECACHE uses OBP.
                   2473:  */
                   2474: 
                   2475: static void
                   2476: rescan (op, output_marks)
                   2477:      FILE_BUF *op;
                   2478:      int output_marks;
                   2479: {
                   2480:   /* Character being scanned in main loop.  */
                   2481:   register U_CHAR c;
                   2482: 
                   2483:   /* Length of pending accumulated identifier.  */
                   2484:   register int ident_length = 0;
                   2485: 
                   2486:   /* Hash code of pending accumulated identifier.  */
                   2487:   register int hash = 0;
                   2488: 
                   2489:   /* Current input level (&instack[indepth]).  */
                   2490:   FILE_BUF *ip;
                   2491: 
                   2492:   /* Pointer for scanning input.  */
                   2493:   register U_CHAR *ibp;
                   2494: 
                   2495:   /* Pointer to end of input.  End of scan is controlled by LIMIT.  */
                   2496:   register U_CHAR *limit;
                   2497: 
                   2498:   /* Pointer for storing output.  */
                   2499:   register U_CHAR *obp;
                   2500: 
                   2501:   /* REDO_CHAR is nonzero if we are processing an identifier
                   2502:      after backing up over the terminating character.
                   2503:      Sometimes we process an identifier without backing up over
                   2504:      the terminating character, if the terminating character
                   2505:      is not special.  Backing up is done so that the terminating character
                   2506:      will be dispatched on again once the identifier is dealt with.  */
                   2507:   int redo_char = 0;
                   2508: 
                   2509:   /* 1 if within an identifier inside of which a concatenation
                   2510:      marker (Newline -) has been seen.  */
                   2511:   int concatenated = 0;
                   2512: 
                   2513:   /* While scanning a comment or a string constant,
                   2514:      this records the line it started on, for error messages.  */
                   2515:   int start_line;
                   2516: 
                   2517:   /* Record position of last `real' newline.  */
                   2518:   U_CHAR *beg_of_line;
                   2519: 
                   2520: /* Pop the innermost input stack level, assuming it is a macro expansion.  */
                   2521: 
                   2522: #define POPMACRO \
                   2523: do { ip->macro->type = T_MACRO;                \
                   2524:      if (ip->free_ptr) free (ip->free_ptr);    \
                   2525:      --indepth; } while (0)
                   2526: 
                   2527: /* Reload `rescan's local variables that describe the current
                   2528:    level of the input stack.  */
                   2529: 
                   2530: #define RECACHE  \
                   2531: do { ip = &instack[indepth];           \
                   2532:      ibp = ip->bufp;                   \
                   2533:      limit = ip->buf + ip->length;     \
                   2534:      op->bufp = obp;                   \
                   2535:      check_expand (op, limit - ibp);   \
                   2536:      beg_of_line = 0;                  \
                   2537:      obp = op->bufp; } while (0)
                   2538: 
                   2539:   if (no_output && instack[indepth].fname != 0)
1.1.1.7 ! root     2540:     skip_if_group (&instack[indepth], 1, NULL);
1.1       root     2541: 
                   2542:   obp = op->bufp;
                   2543:   RECACHE;
1.1.1.4   root     2544: 
1.1       root     2545:   beg_of_line = ibp;
                   2546: 
                   2547:   /* Our caller must always put a null after the end of
                   2548:      the input at each input stack level.  */
                   2549:   if (*limit != 0)
                   2550:     abort ();
                   2551: 
                   2552:   while (1) {
                   2553:     c = *ibp++;
                   2554:     *obp++ = c;
                   2555: 
                   2556:     switch (c) {
                   2557:     case '\\':
1.1.1.7 ! root     2558:       if (*ibp == '\n' && !ip->macro) {
        !          2559:        /* At the top level, always merge lines ending with backslash-newline,
        !          2560:           even in middle of identifier.  But do not merge lines in a macro,
        !          2561:           since backslash might be followed by a newline-space marker.  */
1.1       root     2562:        ++ibp;
                   2563:        ++ip->lineno;
                   2564:        --obp;          /* remove backslash from obuf */
                   2565:        break;
                   2566:       }
1.1.1.7 ! root     2567:       /* If ANSI, backslash is just another character outside a string.  */
        !          2568:       if (!traditional)
        !          2569:        goto randomchar;
1.1       root     2570:       /* Otherwise, backslash suppresses specialness of following char,
                   2571:         so copy it here to prevent the switch from seeing it.
                   2572:         But first get any pending identifier processed.  */
                   2573:       if (ident_length > 0)
                   2574:        goto specialchar;
1.1.1.7 ! root     2575:       if (ibp < limit)
        !          2576:        *obp++ = *ibp++;
1.1       root     2577:       break;
                   2578: 
                   2579:     case '#':
                   2580:       if (assertions_flag) {
                   2581:        /* Copy #foo (bar lose) without macro expansion.  */
                   2582:        SKIP_WHITE_SPACE (ibp);
                   2583:        while (is_idchar[*ibp])
                   2584:          *obp++ = *ibp++;
                   2585:        SKIP_WHITE_SPACE (ibp);
                   2586:        if (*ibp == '(') {
                   2587:          ip->bufp = ibp;
                   2588:          skip_paren_group (ip);
1.1.1.7 ! root     2589:          bcopy ((char *) ibp, (char *) obp, ip->bufp - ibp);
1.1       root     2590:          obp += ip->bufp - ibp;
                   2591:          ibp = ip->bufp;
                   2592:        }
                   2593:       }
                   2594: 
                   2595:       /* If this is expanding a macro definition, don't recognize
                   2596:         preprocessor directives.  */
                   2597:       if (ip->macro != 0)
                   2598:        goto randomchar;
1.1.1.4   root     2599:       /* If this is expand_into_temp_buffer, recognize them
                   2600:         only after an actual newline at this level,
                   2601:         not at the beginning of the input level.  */
                   2602:       if (ip->fname == 0 && beg_of_line == ip->buf)
                   2603:        goto randomchar;
1.1       root     2604:       if (ident_length)
                   2605:        goto specialchar;
                   2606: 
1.1.1.4   root     2607:       
1.1       root     2608:       /* # keyword: a # must be first nonblank char on the line */
                   2609:       if (beg_of_line == 0)
                   2610:        goto randomchar;
                   2611:       {
                   2612:        U_CHAR *bp;
                   2613: 
                   2614:        /* Scan from start of line, skipping whitespace, comments
                   2615:           and backslash-newlines, and see if we reach this #.
                   2616:           If not, this # is not special.  */
                   2617:        bp = beg_of_line;
1.1.1.4   root     2618:        /* If -traditional, require # to be at beginning of line.  */
                   2619:        if (!traditional)
                   2620:          while (1) {
                   2621:            if (is_hor_space[*bp])
1.1       root     2622:              bp++;
1.1.1.4   root     2623:            else if (*bp == '\\' && bp[1] == '\n')
                   2624:              bp += 2;
                   2625:            else if (*bp == '/' && bp[1] == '*') {
                   2626:              bp += 2;
                   2627:              while (!(*bp == '*' && bp[1] == '/'))
                   2628:                bp++;
                   2629:              bp += 2;
                   2630:            }
1.1.1.7 ! root     2631:            /* There is no point in trying to deal with C++ // comments here,
        !          2632:               because if there is one, then this # must be part of the
        !          2633:               comment and we would never reach here.  */
1.1.1.4   root     2634:            else break;
1.1       root     2635:          }
                   2636:        if (bp + 1 != ibp)
                   2637:          goto randomchar;
                   2638:       }
                   2639: 
                   2640:       /* This # can start a directive.  */
                   2641: 
                   2642:       --obp;           /* Don't copy the '#' */
                   2643: 
                   2644:       ip->bufp = ibp;
                   2645:       op->bufp = obp;
                   2646:       if (! handle_directive (ip, op)) {
                   2647: #ifdef USE_C_ALLOCA
                   2648:        alloca (0);
                   2649: #endif
                   2650:        /* Not a known directive: treat it as ordinary text.
                   2651:           IP, OP, IBP, etc. have not been changed.  */
                   2652:        if (no_output && instack[indepth].fname) {
                   2653:          /* If not generating expanded output,
                   2654:             what we do with ordinary text is skip it.
                   2655:             Discard everything until next # directive.  */
1.1.1.7 ! root     2656:          skip_if_group (&instack[indepth], 1, 0);
1.1       root     2657:          RECACHE;
                   2658:          beg_of_line = ibp;
                   2659:          break;
                   2660:        }
                   2661:        ++obp;          /* Copy the '#' after all */
1.1.1.6   root     2662:        /* Don't expand an identifier that could be a macro directive.
                   2663:           (Section 3.8.3 of the ANSI C standard)                       */
                   2664:        SKIP_WHITE_SPACE (ibp);
                   2665:        if (is_idstart[*ibp])
                   2666:          {
                   2667:            *obp++ = *ibp++;
                   2668:            while (is_idchar[*ibp])
                   2669:              *obp++ = *ibp++;
                   2670:          }
1.1       root     2671:        goto randomchar;
                   2672:       }
                   2673: #ifdef USE_C_ALLOCA
                   2674:       alloca (0);
                   2675: #endif
                   2676:       /* A # directive has been successfully processed.  */
                   2677:       /* If not generating expanded output, ignore everything until
                   2678:         next # directive.  */
                   2679:       if (no_output && instack[indepth].fname)
1.1.1.7 ! root     2680:        skip_if_group (&instack[indepth], 1, 0);
1.1       root     2681:       obp = op->bufp;
                   2682:       RECACHE;
                   2683:       beg_of_line = ibp;
                   2684:       break;
                   2685: 
                   2686:     case '\"':                 /* skip quoted string */
                   2687:     case '\'':
                   2688:       /* A single quoted string is treated like a double -- some
                   2689:         programs (e.g., troff) are perverse this way */
                   2690: 
                   2691:       if (ident_length)
                   2692:        goto specialchar;
                   2693: 
                   2694:       start_line = ip->lineno;
                   2695: 
                   2696:       /* Skip ahead to a matching quote.  */
                   2697: 
                   2698:       while (1) {
                   2699:        if (ibp >= limit) {
1.1.1.4   root     2700:          if (ip->macro != 0) {
                   2701:            /* try harder: this string crosses a macro expansion boundary.
                   2702:               This can happen naturally if -traditional.
                   2703:               Otherwise, only -D can make a macro with an unmatched quote.  */
                   2704:            POPMACRO;
                   2705:            RECACHE;
                   2706:            continue;
                   2707:          }
                   2708:          if (!traditional) {
1.1       root     2709:            error_with_line (line_for_error (start_line),
                   2710:                             "unterminated string or character constant");
                   2711:            error_with_line (multiline_string_line,
                   2712:                             "possible real start of unterminated constant");
                   2713:            multiline_string_line = 0;
                   2714:          }
                   2715:          break;
                   2716:        }
                   2717:        *obp++ = *ibp;
                   2718:        switch (*ibp++) {
                   2719:        case '\n':
                   2720:          ++ip->lineno;
                   2721:          ++op->lineno;
                   2722:          /* Traditionally, end of line ends a string constant with no error.
                   2723:             So exit the loop and record the new line.  */
                   2724:          if (traditional) {
                   2725:            beg_of_line = ibp;
                   2726:            goto while2end;
                   2727:          }
1.1.1.5   root     2728:          if (c == '\'') {
1.1       root     2729:            error_with_line (line_for_error (start_line),
1.1.1.5   root     2730:                             "unterminated character constant");
1.1       root     2731:            goto while2end;
                   2732:          }
1.1.1.5   root     2733:          if (pedantic && multiline_string_line == 0) {
                   2734:            pedwarn_with_line (line_for_error (start_line),
                   2735:                               "string constant runs past end of line");
                   2736:          }
1.1       root     2737:          if (multiline_string_line == 0)
                   2738:            multiline_string_line = ip->lineno - 1;
                   2739:          break;
                   2740: 
                   2741:        case '\\':
                   2742:          if (ibp >= limit)
                   2743:            break;
                   2744:          if (*ibp == '\n') {
                   2745:            /* Backslash newline is replaced by nothing at all,
                   2746:               but keep the line counts correct.  */
                   2747:            --obp;
                   2748:            ++ibp;
                   2749:            ++ip->lineno;
                   2750:          } else {
                   2751:            /* ANSI stupidly requires that in \\ the second \
                   2752:               is *not* prevented from combining with a newline.  */
                   2753:            while (*ibp == '\\' && ibp[1] == '\n') {
                   2754:              ibp += 2;
                   2755:              ++ip->lineno;
                   2756:            }
                   2757:            *obp++ = *ibp++;
                   2758:          }
                   2759:          break;
                   2760: 
                   2761:        case '\"':
                   2762:        case '\'':
                   2763:          if (ibp[-1] == c)
                   2764:            goto while2end;
                   2765:          break;
                   2766:        }
                   2767:       }
                   2768:     while2end:
                   2769:       break;
                   2770: 
                   2771:     case '/':
                   2772:       if (*ibp == '\\' && ibp[1] == '\n')
                   2773:        newline_fix (ibp);
                   2774: 
                   2775:       if (*ibp != '*'
1.1.1.4   root     2776:          && !(cplusplus_comments && *ibp == '/'))
1.1       root     2777:        goto randomchar;
                   2778:       if (ip->macro != 0)
                   2779:        goto randomchar;
                   2780:       if (ident_length)
                   2781:        goto specialchar;
                   2782: 
                   2783:       if (*ibp == '/') {
                   2784:        /* C++ style comment... */
                   2785:        start_line = ip->lineno;
                   2786: 
                   2787:        --ibp;                  /* Back over the slash */
                   2788:        --obp;
                   2789: 
                   2790:        /* Comments are equivalent to spaces. */
                   2791:        if (! put_out_comments)
                   2792:          *obp++ = ' ';
                   2793:        else {
                   2794:          /* must fake up a comment here */
                   2795:          *obp++ = '/';
                   2796:          *obp++ = '/';
                   2797:        }
                   2798:        {
                   2799:          U_CHAR *before_bp = ibp+2;
                   2800: 
                   2801:          while (ibp < limit) {
1.1.1.7 ! root     2802:            if (ibp[-1] != '\\' && *ibp == '\n') {
1.1       root     2803:              if (put_out_comments) {
1.1.1.7 ! root     2804:                bcopy ((char *) before_bp, (char *) obp, ibp - before_bp);
1.1       root     2805:                obp += ibp - before_bp;
                   2806:              }
                   2807:              break;
1.1.1.7 ! root     2808:            } else {
        !          2809:              if (*ibp == '\n') {
        !          2810:                ++ip->lineno;
        !          2811:                /* Copy the newline into the output buffer, in order to
        !          2812:                   avoid the pain of a #line every time a multiline comment
        !          2813:                   is seen.  */
        !          2814:                if (!put_out_comments)
        !          2815:                  *obp++ = '\n';
        !          2816:                ++op->lineno;
        !          2817:              }
        !          2818:              ibp++;
1.1       root     2819:            }
                   2820:          }
                   2821:          break;
                   2822:        }
                   2823:       }
                   2824: 
                   2825:       /* Ordinary C comment.  Skip it, optionally copying it to output.  */
                   2826: 
                   2827:       start_line = ip->lineno;
                   2828: 
                   2829:       ++ibp;                   /* Skip the star. */
                   2830: 
                   2831:       /* If this cpp is for lint, we peek inside the comments: */
1.1.1.7 ! root     2832:       if (for_lint) {
1.1       root     2833:        U_CHAR *argbp;
                   2834:        int cmdlen, arglen;
                   2835:        char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
                   2836: 
                   2837:        if (lintcmd != NULL) {
1.1.1.7 ! root     2838:          op->bufp = obp;
        !          2839:          check_expand (op, cmdlen + arglen + 14);
        !          2840:          obp = op->bufp;
1.1       root     2841:          /* I believe it is always safe to emit this newline: */
                   2842:          obp[-1] = '\n';
1.1.1.7 ! root     2843:          bcopy ("#pragma lint ", (char *) obp, 13);
1.1       root     2844:          obp += 13;
1.1.1.7 ! root     2845:          bcopy (lintcmd, (char *) obp, cmdlen);
1.1       root     2846:          obp += cmdlen;
                   2847: 
                   2848:          if (arglen != 0) {
                   2849:            *(obp++) = ' ';
1.1.1.7 ! root     2850:            bcopy (argbp, (char *) obp, arglen);
1.1       root     2851:            obp += arglen;
                   2852:          }
                   2853: 
                   2854:          /* OK, now bring us back to the state we were in before we entered
1.1.1.7 ! root     2855:             this branch.  We need #line because the #pragma's newline always
        !          2856:             messes up the line count.  */
        !          2857:          op->bufp = obp;
1.1       root     2858:          output_line_command (ip, op, 0, same_file);
1.1.1.7 ! root     2859:          check_expand (op, limit - ibp + 2);
        !          2860:          obp = op->bufp;
1.1       root     2861:          *(obp++) = '/';
                   2862:        }
                   2863:       }
                   2864: 
                   2865:       /* Comments are equivalent to spaces.
                   2866:         Note that we already output the slash; we might not want it.
                   2867:         For -traditional, a comment is equivalent to nothing.  */
                   2868:       if (! put_out_comments) {
                   2869:        if (traditional)
                   2870:          obp--;
                   2871:        else
                   2872:          obp[-1] = ' ';
                   2873:       }
                   2874:       else
                   2875:        *obp++ = '*';
                   2876: 
                   2877:       {
                   2878:        U_CHAR *before_bp = ibp;
                   2879: 
                   2880:        while (ibp < limit) {
                   2881:          switch (*ibp++) {
                   2882:          case '/':
                   2883:            if (warn_comments && ibp < limit && *ibp == '*')
1.1.1.5   root     2884:              warning ("`/*' within comment");
1.1       root     2885:            break;
                   2886:          case '*':
                   2887:            if (*ibp == '\\' && ibp[1] == '\n')
                   2888:              newline_fix (ibp);
                   2889:            if (ibp >= limit || *ibp == '/')
                   2890:              goto comment_end;
                   2891:            break;
                   2892:          case '\n':
                   2893:            ++ip->lineno;
                   2894:            /* Copy the newline into the output buffer, in order to
                   2895:               avoid the pain of a #line every time a multiline comment
                   2896:               is seen.  */
                   2897:            if (!put_out_comments)
                   2898:              *obp++ = '\n';
                   2899:            ++op->lineno;
                   2900:          }
                   2901:        }
                   2902:       comment_end:
                   2903: 
                   2904:        if (ibp >= limit)
                   2905:          error_with_line (line_for_error (start_line),
                   2906:                           "unterminated comment");
                   2907:        else {
                   2908:          ibp++;
                   2909:          if (put_out_comments) {
1.1.1.7 ! root     2910:            bcopy ((char *) before_bp, (char *) obp, ibp - before_bp);
1.1       root     2911:            obp += ibp - before_bp;
                   2912:          }
                   2913:        }
                   2914:       }
                   2915:       break;
                   2916: 
                   2917:     case '$':
                   2918:       if (!dollars_in_ident)
                   2919:        goto randomchar;
                   2920:       goto letter;
                   2921: 
                   2922:     case '0': case '1': case '2': case '3': case '4':
                   2923:     case '5': case '6': case '7': case '8': case '9':
                   2924:       /* If digit is not part of identifier, it starts a number,
                   2925:         which means that following letters are not an identifier.
                   2926:         "0x5" does not refer to an identifier "x5".
                   2927:         So copy all alphanumerics that follow without accumulating
                   2928:         as an identifier.  Periods also, for sake of "3.e7".  */
                   2929: 
                   2930:       if (ident_length == 0) {
                   2931:        while (ibp < limit) {
                   2932:          while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
                   2933:            ++ip->lineno;
                   2934:            ibp += 2;
                   2935:          }
                   2936:          c = *ibp++;
1.1.1.7 ! root     2937:          if (!is_idchar[c] && c != '.') {
1.1       root     2938:            --ibp;
                   2939:            break;
                   2940:          }
                   2941:          *obp++ = c;
                   2942:          /* A sign can be part of a preprocessing number
                   2943:             if it follows an e.  */
                   2944:          if (c == 'e' || c == 'E') {
                   2945:            while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
                   2946:              ++ip->lineno;
                   2947:              ibp += 2;
                   2948:            }
                   2949:            if (ibp < limit && (*ibp == '+' || *ibp == '-')) {
                   2950:              *obp++ = *ibp++;
                   2951:              /* But traditional C does not let the token go past the sign.  */
                   2952:              if (traditional)
                   2953:                break;
                   2954:            }
                   2955:          }
                   2956:        }
                   2957:        break;
                   2958:       }
                   2959:       /* fall through */
                   2960: 
                   2961:     case '_':
                   2962:     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                   2963:     case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
                   2964:     case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
                   2965:     case 's': case 't': case 'u': case 'v': case 'w': case 'x':
                   2966:     case 'y': case 'z':
                   2967:     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                   2968:     case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
                   2969:     case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
                   2970:     case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
                   2971:     case 'Y': case 'Z':
                   2972:     letter:
                   2973:       ident_length++;
                   2974:       /* Compute step of hash function, to avoid a proc call on every token */
                   2975:       hash = HASHSTEP (hash, c);
                   2976:       break;
                   2977: 
                   2978:     case '\n':
1.1.1.5   root     2979:       if (ip->fname == 0 && *ibp == '-') {
                   2980:        /* Newline - inhibits expansion of preceding token.
                   2981:           If expanding a macro arg, we keep the newline -.
                   2982:           In final output, it is deleted.
                   2983:           We recognize Newline - in macro bodies and macro args.  */
                   2984:        if (! concatenated) {
                   2985:          ident_length = 0;
                   2986:          hash = 0;
                   2987:        }
                   2988:        ibp++;
                   2989:        if (!output_marks) {
                   2990:          obp--;
                   2991:        } else {
                   2992:          /* If expanding a macro arg, keep the newline -.  */
                   2993:          *obp++ = '-';
                   2994:        }
                   2995:        break;
                   2996:       }
                   2997: 
1.1       root     2998:       /* If reprocessing a macro expansion, newline is a special marker.  */
1.1.1.5   root     2999:       else if (ip->macro != 0) {
1.1       root     3000:        /* Newline White is a "funny space" to separate tokens that are
                   3001:           supposed to be separate but without space between.
                   3002:           Here White means any whitespace character.
                   3003:           Newline - marks a recursive macro use that is not
                   3004:           supposed to be expandable.  */
                   3005: 
1.1.1.5   root     3006:        if (is_space[*ibp]) {
1.1       root     3007:          /* Newline Space does not prevent expansion of preceding token
                   3008:             so expand the preceding token and then come back.  */
                   3009:          if (ident_length > 0)
                   3010:            goto specialchar;
                   3011: 
                   3012:          /* If generating final output, newline space makes a space.  */
                   3013:          if (!output_marks) {
                   3014:            obp[-1] = *ibp++;
                   3015:            /* And Newline Newline makes a newline, so count it.  */
                   3016:            if (obp[-1] == '\n')
                   3017:              op->lineno++;
                   3018:          } else {
                   3019:            /* If expanding a macro arg, keep the newline space.
                   3020:               If the arg gets stringified, newline space makes nothing.  */
                   3021:            *obp++ = *ibp++;
                   3022:          }
                   3023:        } else abort ();        /* Newline followed by something random?  */
                   3024:        break;
                   3025:       }
                   3026: 
                   3027:       /* If there is a pending identifier, handle it and come back here.  */
                   3028:       if (ident_length > 0)
                   3029:        goto specialchar;
                   3030: 
                   3031:       beg_of_line = ibp;
                   3032: 
                   3033:       /* Update the line counts and output a #line if necessary.  */
                   3034:       ++ip->lineno;
                   3035:       ++op->lineno;
                   3036:       if (ip->lineno != op->lineno) {
                   3037:        op->bufp = obp;
                   3038:        output_line_command (ip, op, 1, same_file);
1.1.1.7 ! root     3039:        check_expand (op, limit - ibp);
1.1       root     3040:        obp = op->bufp;
                   3041:       }
                   3042:       break;
                   3043: 
                   3044:       /* Come here either after (1) a null character that is part of the input
                   3045:         or (2) at the end of the input, because there is a null there.  */
                   3046:     case 0:
                   3047:       if (ibp <= limit)
                   3048:        /* Our input really contains a null character.  */
                   3049:        goto randomchar;
                   3050: 
                   3051:       /* At end of a macro-expansion level, pop it and read next level.  */
                   3052:       if (ip->macro != 0) {
                   3053:        obp--;
                   3054:        ibp--;
                   3055:        /* If traditional, and we have an identifier that ends here,
                   3056:           process it now, so we get the right error for recursion.  */
                   3057:        if (traditional && ident_length
                   3058:            && ! is_idchar[*instack[indepth - 1].bufp]) {
                   3059:          redo_char = 1;
                   3060:          goto randomchar;
                   3061:        }
                   3062:        POPMACRO;
                   3063:        RECACHE;
                   3064:        break;
                   3065:       }
                   3066: 
                   3067:       /* If we don't have a pending identifier,
                   3068:         return at end of input.  */
                   3069:       if (ident_length == 0) {
                   3070:        obp--;
                   3071:        ibp--;
                   3072:        op->bufp = obp;
                   3073:        ip->bufp = ibp;
                   3074:        goto ending;
                   3075:       }
                   3076: 
                   3077:       /* If we do have a pending identifier, just consider this null
                   3078:         a special character and arrange to dispatch on it again.
                   3079:         The second time, IDENT_LENGTH will be zero so we will return.  */
                   3080: 
                   3081:       /* Fall through */
                   3082: 
                   3083: specialchar:
                   3084: 
                   3085:       /* Handle the case of a character such as /, ', " or null
                   3086:         seen following an identifier.  Back over it so that
                   3087:         after the identifier is processed the special char
                   3088:         will be dispatched on again.  */
                   3089: 
                   3090:       ibp--;
                   3091:       obp--;
                   3092:       redo_char = 1;
                   3093: 
                   3094:     default:
                   3095: 
                   3096: randomchar:
                   3097: 
                   3098:       if (ident_length > 0) {
                   3099:        register HASHNODE *hp;
                   3100: 
                   3101:        /* We have just seen an identifier end.  If it's a macro, expand it.
                   3102: 
                   3103:           IDENT_LENGTH is the length of the identifier
                   3104:           and HASH is its hash code.
                   3105: 
                   3106:           The identifier has already been copied to the output,
                   3107:           so if it is a macro we must remove it.
                   3108: 
                   3109:           If REDO_CHAR is 0, the char that terminated the identifier
                   3110:           has been skipped in the output and the input.
                   3111:           OBP-IDENT_LENGTH-1 points to the identifier.
                   3112:           If the identifier is a macro, we must back over the terminator.
                   3113: 
                   3114:           If REDO_CHAR is 1, the terminating char has already been
                   3115:           backed over.  OBP-IDENT_LENGTH points to the identifier.  */
                   3116: 
                   3117:        if (!pcp_outfile || pcp_inside_if) {
                   3118: startagain:
                   3119:          for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL;
                   3120:               hp = hp->next) {
                   3121:            
                   3122:            if (hp->length == ident_length) {
                   3123:              int obufp_before_macroname;
                   3124:              int op_lineno_before_macroname;
                   3125:              register int i = ident_length;
                   3126:              register U_CHAR *p = hp->name;
                   3127:              register U_CHAR *q = obp - i;
                   3128:              int disabled;
                   3129:              
                   3130:              if (! redo_char)
                   3131:                q--;
                   3132:              
                   3133:              do {              /* All this to avoid a strncmp () */
                   3134:                if (*p++ != *q++)
                   3135:                  goto hashcollision;
                   3136:              } while (--i);
                   3137:              
                   3138:              /* We found a use of a macro name.
                   3139:                 see if the context shows it is a macro call.  */
                   3140:              
                   3141:              /* Back up over terminating character if not already done.  */
                   3142:              if (! redo_char) {
                   3143:                ibp--;
                   3144:                obp--;
                   3145:              }
                   3146:              
                   3147:              /* Save this as a displacement from the beginning of the output
                   3148:                 buffer.  We can not save this as a position in the output
                   3149:                 buffer, because it may get realloc'ed by RECACHE.  */
                   3150:              obufp_before_macroname = (obp - op->buf) - ident_length;
                   3151:              op_lineno_before_macroname = op->lineno;
                   3152:              
                   3153:              if (hp->type == T_PCSTRING) {
                   3154:                pcstring_used (hp); /* Mark the definition of this key
                   3155:                                       as needed, ensuring that it
                   3156:                                       will be output.  */
                   3157:                break;          /* Exit loop, since the key cannot have a
                   3158:                                   definition any longer.  */
                   3159:              }
                   3160: 
                   3161:              /* Record whether the macro is disabled.  */
                   3162:              disabled = hp->type == T_DISABLED;
                   3163:              
                   3164:              /* This looks like a macro ref, but if the macro was disabled,
                   3165:                 just copy its name and put in a marker if requested.  */
                   3166:              
                   3167:              if (disabled) {
                   3168: #if 0
                   3169:                /* This error check caught useful cases such as
1.1.1.5   root     3170:                   #define foo(x,y) bar (x (y,0), y)
                   3171:                   foo (foo, baz)  */
1.1       root     3172:                if (traditional)
                   3173:                  error ("recursive use of macro `%s'", hp->name);
                   3174: #endif
                   3175:                
                   3176:                if (output_marks) {
                   3177:                  check_expand (op, limit - ibp + 2);
                   3178:                  *obp++ = '\n';
                   3179:                  *obp++ = '-';
                   3180:                }
                   3181:                break;
                   3182:              }
                   3183:              
                   3184:              /* If macro wants an arglist, verify that a '(' follows.
                   3185:                 first skip all whitespace, copying it to the output
                   3186:                 after the macro name.  Then, if there is no '(',
                   3187:                 decide this is not a macro call and leave things that way.  */
                   3188:              if ((hp->type == T_MACRO || hp->type == T_DISABLED)
                   3189:                  && hp->value.defn->nargs >= 0)
                   3190:                {
                   3191:                  U_CHAR *old_ibp = ibp;
                   3192:                  U_CHAR *old_obp = obp;
                   3193:                  int old_iln = ip->lineno;
                   3194:                  int old_oln = op->lineno;
                   3195:                  
                   3196:                  while (1) {
                   3197:                    /* Scan forward over whitespace, copying it to the output.  */
                   3198:                    if (ibp == limit && ip->macro != 0) {
                   3199:                      POPMACRO;
                   3200:                      RECACHE;
                   3201:                      old_ibp = ibp;
                   3202:                      old_obp = obp;
                   3203:                      old_iln = ip->lineno;
                   3204:                      old_oln = op->lineno;
                   3205:                    }
                   3206:                    /* A comment: copy it unchanged or discard it.  */
                   3207:                    else if (*ibp == '/' && ibp+1 != limit && ibp[1] == '*') {
                   3208:                      if (put_out_comments) {
                   3209:                        *obp++ = '/';
                   3210:                        *obp++ = '*';
                   3211:                      } else if (! traditional) {
                   3212:                        *obp++ = ' ';
                   3213:                      }
                   3214:                      ibp += 2;
                   3215:                      while (ibp + 1 != limit
                   3216:                             && !(ibp[0] == '*' && ibp[1] == '/')) {
                   3217:                        /* We need not worry about newline-marks,
                   3218:                           since they are never found in comments.  */
                   3219:                        if (*ibp == '\n') {
                   3220:                          /* Newline in a file.  Count it.  */
                   3221:                          ++ip->lineno;
                   3222:                          ++op->lineno;
                   3223:                        }
                   3224:                        if (put_out_comments)
                   3225:                          *obp++ = *ibp++;
                   3226:                        else
                   3227:                          ibp++;
                   3228:                      }
                   3229:                      ibp += 2;
                   3230:                      if (put_out_comments) {
                   3231:                        *obp++ = '*';
                   3232:                        *obp++ = '/';
                   3233:                      }
                   3234:                    }
                   3235:                    else if (is_space[*ibp]) {
                   3236:                      *obp++ = *ibp++;
                   3237:                      if (ibp[-1] == '\n') {
                   3238:                        if (ip->macro == 0) {
                   3239:                          /* Newline in a file.  Count it.  */
                   3240:                          ++ip->lineno;
                   3241:                          ++op->lineno;
                   3242:                        } else if (!output_marks) {
                   3243:                          /* A newline mark, and we don't want marks
                   3244:                             in the output.  If it is newline-hyphen,
                   3245:                             discard it entirely.  Otherwise, it is
                   3246:                             newline-whitechar, so keep the whitechar.  */
                   3247:                          obp--;
                   3248:                          if (*ibp == '-')
                   3249:                            ibp++;
                   3250:                          else {
                   3251:                            if (*ibp == '\n')
                   3252:                              ++op->lineno;
                   3253:                            *obp++ = *ibp++;
                   3254:                          }
                   3255:                        } else {
                   3256:                          /* A newline mark; copy both chars to the output.  */
                   3257:                          *obp++ = *ibp++;
                   3258:                        }
                   3259:                      }
                   3260:                    }
                   3261:                    else break;
                   3262:                  }
                   3263:                  if (*ibp != '(') {
                   3264:                    /* It isn't a macro call.
                   3265:                       Put back the space that we just skipped.  */
                   3266:                    ibp = old_ibp;
                   3267:                    obp = old_obp;
                   3268:                    ip->lineno = old_iln;
                   3269:                    op->lineno = old_oln;
                   3270:                    /* Exit the for loop.  */
                   3271:                    break;
                   3272:                  }
                   3273:                }
                   3274:              
                   3275:              /* This is now known to be a macro call.
                   3276:                 Discard the macro name from the output,
1.1.1.7 ! root     3277:                 along with any following whitespace just copied,
        !          3278:                 but preserve newlines if not outputting marks since this
        !          3279:                 is more likely to do the right thing with line numbers.  */
1.1       root     3280:              obp = op->buf + obufp_before_macroname;
1.1.1.7 ! root     3281:              if (output_marks)
        !          3282:                op->lineno = op_lineno_before_macroname;
        !          3283:              else {
        !          3284:                int newlines = op->lineno - op_lineno_before_macroname;
        !          3285:                while (0 < newlines--)
        !          3286:                  *obp++ = '\n';
        !          3287:              }
1.1.1.5   root     3288: 
                   3289:              /* Prevent accidental token-pasting with a character
                   3290:                 before the macro call.  */
                   3291:              if (!traditional && obp != op->buf
                   3292:                  && (obp[-1] == '-' || obp[1] == '+' || obp[1] == '&'
                   3293:                      || obp[-1] == '|' || obp[1] == '<' || obp[1] == '>')) {
                   3294:                /* If we are expanding a macro arg, make a newline marker
                   3295:                   to separate the tokens.  If we are making real output,
                   3296:                   a plain space will do.  */
                   3297:                if (output_marks)
                   3298:                  *obp++ = '\n';
                   3299:                *obp++ = ' ';
                   3300:              }
                   3301: 
1.1       root     3302:              /* Expand the macro, reading arguments as needed,
                   3303:                 and push the expansion on the input stack.  */
                   3304:              ip->bufp = ibp;
                   3305:              op->bufp = obp;
                   3306:              macroexpand (hp, op);
                   3307:              
                   3308:              /* Reexamine input stack, since macroexpand has pushed
                   3309:                 a new level on it.  */
                   3310:              obp = op->bufp;
                   3311:              RECACHE;
                   3312:              break;
                   3313:            }
                   3314: hashcollision:
                   3315:            ;
                   3316:          }                     /* End hash-table-search loop */
                   3317:        }
                   3318:        ident_length = hash = 0; /* Stop collecting identifier */
                   3319:        redo_char = 0;
                   3320:        concatenated = 0;
                   3321:       }                                /* End if (ident_length > 0) */
                   3322:     }                          /* End switch */
                   3323:   }                            /* End per-char loop */
                   3324: 
                   3325:   /* Come here to return -- but first give an error message
                   3326:      if there was an unterminated successful conditional.  */
                   3327:  ending:
1.1.1.7 ! root     3328:   if (if_stack != ip->if_stack)
        !          3329:     {
        !          3330:       char *str = "unknown";
        !          3331: 
        !          3332:       switch (if_stack->type)
        !          3333:        {
        !          3334:        case T_IF:
        !          3335:          str = "if";
        !          3336:          break;
        !          3337:        case T_IFDEF:
        !          3338:          str = "ifdef";
        !          3339:          break;
        !          3340:        case T_IFNDEF:
        !          3341:          str = "ifndef";
        !          3342:          break;
        !          3343:        case T_ELSE:
        !          3344:          str = "else";
        !          3345:          break;
        !          3346:        case T_ELIF:
        !          3347:          str = "elif";
        !          3348:          break;
        !          3349:        }
        !          3350: 
        !          3351:       error_with_line (line_for_error (if_stack->lineno),
        !          3352:                       "unterminated `#%s' conditional", str);
1.1       root     3353:   }
                   3354:   if_stack = ip->if_stack;
                   3355: }
                   3356: 
                   3357: /*
                   3358:  * Rescan a string into a temporary buffer and return the result
                   3359:  * as a FILE_BUF.  Note this function returns a struct, not a pointer.
                   3360:  *
                   3361:  * OUTPUT_MARKS nonzero means keep Newline markers found in the input
                   3362:  * and insert such markers when appropriate.  See `rescan' for details.
                   3363:  * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately
                   3364:  * before substitution; it is 0 for other uses.
                   3365:  */
                   3366: static FILE_BUF
                   3367: expand_to_temp_buffer (buf, limit, output_marks, assertions)
                   3368:      U_CHAR *buf, *limit;
                   3369:      int output_marks, assertions;
                   3370: {
                   3371:   register FILE_BUF *ip;
                   3372:   FILE_BUF obuf;
                   3373:   int length = limit - buf;
                   3374:   U_CHAR *buf1;
                   3375:   int odepth = indepth;
                   3376:   int save_assertions_flag = assertions_flag;
                   3377: 
                   3378:   assertions_flag = assertions;
                   3379: 
                   3380:   if (length < 0)
                   3381:     abort ();
                   3382: 
                   3383:   /* Set up the input on the input stack.  */
                   3384: 
                   3385:   buf1 = (U_CHAR *) alloca (length + 1);
                   3386:   {
                   3387:     register U_CHAR *p1 = buf;
                   3388:     register U_CHAR *p2 = buf1;
                   3389: 
                   3390:     while (p1 != limit)
                   3391:       *p2++ = *p1++;
                   3392:   }
                   3393:   buf1[length] = 0;
                   3394: 
                   3395:   /* Set up to receive the output.  */
                   3396: 
                   3397:   obuf.length = length * 2 + 100; /* Usually enough.  Why be stingy?  */
                   3398:   obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
                   3399:   obuf.fname = 0;
                   3400:   obuf.macro = 0;
                   3401:   obuf.free_ptr = 0;
                   3402: 
                   3403:   CHECK_DEPTH ({return obuf;});
                   3404: 
                   3405:   ++indepth;
                   3406: 
                   3407:   ip = &instack[indepth];
                   3408:   ip->fname = 0;
                   3409:   ip->nominal_fname = 0;
                   3410:   ip->system_header_p = 0;
                   3411:   ip->macro = 0;
                   3412:   ip->free_ptr = 0;
                   3413:   ip->length = length;
                   3414:   ip->buf = ip->bufp = buf1;
                   3415:   ip->if_stack = if_stack;
                   3416: 
                   3417:   ip->lineno = obuf.lineno = 1;
                   3418: 
                   3419:   /* Scan the input, create the output.  */
                   3420:   rescan (&obuf, output_marks);
                   3421: 
                   3422:   /* Pop input stack to original state.  */
                   3423:   --indepth;
                   3424: 
                   3425:   if (indepth != odepth)
                   3426:     abort ();
                   3427: 
                   3428:   /* Record the output.  */
                   3429:   obuf.length = obuf.bufp - obuf.buf;
                   3430: 
                   3431:   assertions_flag = save_assertions_flag;
                   3432:   return obuf;
                   3433: }
                   3434: 
                   3435: /*
                   3436:  * Process a # directive.  Expects IP->bufp to point after the '#', as in
                   3437:  * `#define foo bar'.  Passes to the command handler
                   3438:  * (do_define, do_include, etc.): the addresses of the 1st and
                   3439:  * last chars of the command (starting immediately after the #
                   3440:  * keyword), plus op and the keyword table pointer.  If the command
                   3441:  * contains comments it is copied into a temporary buffer sans comments
                   3442:  * and the temporary buffer is passed to the command handler instead.
                   3443:  * Likewise for backslash-newlines.
                   3444:  *
                   3445:  * Returns nonzero if this was a known # directive.
                   3446:  * Otherwise, returns zero, without advancing the input pointer.
                   3447:  */
                   3448: 
                   3449: static int
                   3450: handle_directive (ip, op)
                   3451:      FILE_BUF *ip, *op;
                   3452: {
                   3453:   register U_CHAR *bp, *cp;
                   3454:   register struct directive *kt;
                   3455:   register int ident_length;
                   3456:   U_CHAR *resume_p;
                   3457: 
                   3458:   /* Nonzero means we must copy the entire command
                   3459:      to get rid of comments or backslash-newlines.  */
                   3460:   int copy_command = 0;
                   3461: 
                   3462:   U_CHAR *ident, *after_ident;
                   3463: 
                   3464:   bp = ip->bufp;
                   3465: 
                   3466:   /* Record where the directive started.  do_xifdef needs this.  */
                   3467:   directive_start = bp - 1;
                   3468: 
                   3469:   /* Skip whitespace and \-newline.  */
                   3470:   while (1) {
                   3471:     if (is_hor_space[*bp]) {
                   3472:       if ((*bp == '\f' || *bp == '\v') && pedantic)
                   3473:        pedwarn ("%s in preprocessing directive",
                   3474:                 *bp == '\f' ? "formfeed" : "vertical tab");
                   3475:       bp++;
1.1.1.7 ! root     3476:     } else if (*bp == '/' && (bp[1] == '*'
        !          3477:                              || (cplusplus_comments && bp[1] == '/'))) {
        !          3478:       ip->bufp = bp + 2;
1.1.1.2   root     3479:       skip_to_end_of_comment (ip, &ip->lineno, 0);
1.1       root     3480:       bp = ip->bufp;
                   3481:     } else if (*bp == '\\' && bp[1] == '\n') {
                   3482:       bp += 2; ip->lineno++;
                   3483:     } else break;
                   3484:   }
                   3485: 
                   3486:   /* Now find end of directive name.
                   3487:      If we encounter a backslash-newline, exchange it with any following
                   3488:      symbol-constituents so that we end up with a contiguous name.  */
                   3489: 
                   3490:   cp = bp;
                   3491:   while (1) {
                   3492:     if (is_idchar[*cp])
                   3493:       cp++;
                   3494:     else {
                   3495:       if (*cp == '\\' && cp[1] == '\n')
                   3496:        name_newline_fix (cp);
                   3497:       if (is_idchar[*cp])
                   3498:        cp++;
                   3499:       else break;
                   3500:     }
                   3501:   }
                   3502:   ident_length = cp - bp;
                   3503:   ident = bp;
                   3504:   after_ident = cp;
                   3505: 
                   3506:   /* A line of just `#' becomes blank.  */
                   3507: 
                   3508:   if (ident_length == 0 && *after_ident == '\n') {
                   3509:     ip->bufp = after_ident;
                   3510:     return 1;
                   3511:   }
                   3512: 
                   3513:   if (ident_length == 0 || !is_idstart[*ident]) {
                   3514:     U_CHAR *p = ident;
                   3515:     while (is_idchar[*p]) {
                   3516:       if (*p < '0' || *p > '9')
                   3517:        break;
                   3518:       p++;
                   3519:     }
                   3520:     /* Handle # followed by a line number.  */
                   3521:     if (p != ident && !is_idchar[*p]) {
                   3522:       static struct directive line_directive_table[] = {
                   3523:        {  4, do_line, "line", T_LINE},
                   3524:       };
                   3525:       if (pedantic)
                   3526:        pedwarn ("`#' followed by integer");
                   3527:       after_ident = ident;
                   3528:       kt = line_directive_table;
                   3529:       goto old_linenum;
                   3530:     }
                   3531: 
                   3532:     /* Avoid error for `###' and similar cases unless -pedantic.  */
                   3533:     if (p == ident) {
                   3534:       while (*p == '#' || is_hor_space[*p]) p++;
                   3535:       if (*p == '\n') {
                   3536:        if (pedantic && !lang_asm)
                   3537:          warning ("invalid preprocessor directive");
                   3538:        return 0;
                   3539:       }
                   3540:     }
                   3541: 
                   3542:     if (!lang_asm)
                   3543:       error ("invalid preprocessor directive name");
                   3544: 
                   3545:     return 0;
                   3546:   }
                   3547: 
                   3548:   /*
                   3549:    * Decode the keyword and call the appropriate expansion
                   3550:    * routine, after moving the input pointer up to the next line.
                   3551:    */
                   3552:   for (kt = directive_table; kt->length > 0; kt++) {
                   3553:     if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length)) {
                   3554:       register U_CHAR *buf;
                   3555:       register U_CHAR *limit;
                   3556:       int unterminated;
                   3557:       int junk;
1.1.1.5   root     3558:       int *already_output;
1.1       root     3559: 
                   3560:       /* Nonzero means do not delete comments within the directive.
                   3561:         #define needs this when -traditional.  */
                   3562:       int keep_comments;
                   3563: 
                   3564:     old_linenum:
                   3565: 
                   3566:       limit = ip->buf + ip->length;
                   3567:       unterminated = 0;
1.1.1.5   root     3568:       already_output = 0;
1.1       root     3569:       keep_comments = traditional && kt->traditional_comments;
                   3570:       /* #import is defined only in Objective C, or when on the NeXT.  */
                   3571:       if (kt->type == T_IMPORT && !(objc || lookup ("__NeXT__", -1, -1)))
                   3572:        break;
                   3573: 
                   3574:       /* Find the end of this command (first newline not backslashed
                   3575:         and not in a string or comment).
                   3576:         Set COPY_COMMAND if the command must be copied
                   3577:         (it contains a backslash-newline or a comment).  */
                   3578: 
                   3579:       buf = bp = after_ident;
                   3580:       while (bp < limit) {
                   3581:        register U_CHAR c = *bp++;
                   3582:        switch (c) {
                   3583:        case '\\':
                   3584:          if (bp < limit) {
                   3585:            if (*bp == '\n') {
                   3586:              ip->lineno++;
                   3587:              copy_command = 1;
1.1.1.7 ! root     3588:              bp++;
        !          3589:            } else if (traditional)
        !          3590:              bp++;
1.1       root     3591:          }
                   3592:          break;
                   3593: 
                   3594:        case '\'':
                   3595:        case '\"':
                   3596:          bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, &copy_command, &unterminated);
                   3597:          /* Don't bother calling the directive if we already got an error
                   3598:             message due to unterminated string.  Skip everything and pretend
                   3599:             we called the directive.  */
                   3600:          if (unterminated) {
                   3601:            if (traditional) {
                   3602:              /* Traditional preprocessing permits unterminated strings.  */
                   3603:              ip->bufp = bp;
                   3604:              goto endloop1;
                   3605:            }
                   3606:            ip->bufp = bp;
                   3607:            return 1;
                   3608:          }
                   3609:          break;
                   3610: 
                   3611:          /* <...> is special for #include.  */
                   3612:        case '<':
                   3613:          if (!kt->angle_brackets)
                   3614:            break;
1.1.1.7 ! root     3615:          while (bp < limit && *bp != '>' && *bp != '\n') {
        !          3616:            if (*bp == '\\' && bp[1] == '\n') {
        !          3617:              ip->lineno++;
        !          3618:              copy_command = 1;
        !          3619:              bp++;
        !          3620:            }
        !          3621:            bp++;
        !          3622:          }
1.1       root     3623:          break;
                   3624: 
                   3625:        case '/':
                   3626:          if (*bp == '\\' && bp[1] == '\n')
                   3627:            newline_fix (bp);
                   3628:          if (*bp == '*'
1.1.1.4   root     3629:              || (cplusplus_comments && *bp == '/')) {
1.1       root     3630:            U_CHAR *obp = bp - 1;
                   3631:            ip->bufp = bp + 1;
1.1.1.2   root     3632:            skip_to_end_of_comment (ip, &ip->lineno, 0);
1.1       root     3633:            bp = ip->bufp;
                   3634:            /* No need to copy the command because of a comment at the end;
                   3635:               just don't include the comment in the directive.  */
                   3636:            if (bp == limit || *bp == '\n') {
                   3637:              bp = obp;
                   3638:              goto endloop1;
                   3639:            }
                   3640:            /* Don't remove the comments if -traditional.  */
                   3641:            if (! keep_comments)
                   3642:              copy_command++;
                   3643:          }
                   3644:          break;
                   3645: 
                   3646:        case '\f':
                   3647:        case '\v':
                   3648:          if (pedantic)
                   3649:            pedwarn ("%s in preprocessing directive",
                   3650:                     c == '\f' ? "formfeed" : "vertical tab");
                   3651:          break;
                   3652: 
                   3653:        case '\n':
                   3654:          --bp;         /* Point to the newline */
                   3655:          ip->bufp = bp;
                   3656:          goto endloop1;
                   3657:        }
                   3658:       }
                   3659:       ip->bufp = bp;
                   3660: 
                   3661:     endloop1:
                   3662:       resume_p = ip->bufp;
                   3663:       /* BP is the end of the directive.
                   3664:         RESUME_P is the next interesting data after the directive.
                   3665:         A comment may come between.  */
                   3666: 
                   3667:       /* If a directive should be copied through, and -E was given,
                   3668:         pass it through before removing comments.  */
                   3669:       if (!no_output && kt->pass_thru && put_out_comments) {
                   3670:         int len;
                   3671: 
                   3672:        /* Output directive name.  */
                   3673:         check_expand (op, kt->length + 2);
                   3674:        /* Make sure # is at the start of a line */
                   3675:        if (op->bufp > op->buf && op->bufp[-1] != '\n') {
                   3676:          op->lineno++;
                   3677:          *op->bufp++ = '\n';
                   3678:        }
                   3679:         *op->bufp++ = '#';
                   3680:         bcopy (kt->name, op->bufp, kt->length);
                   3681:         op->bufp += kt->length;
                   3682: 
                   3683:        /* Output arguments.  */
                   3684:        len = (bp - buf);
                   3685:        check_expand (op, len);
1.1.1.7 ! root     3686:        bcopy (buf, (char *) op->bufp, len);
1.1       root     3687:        op->bufp += len;
                   3688:        /* Take account of any (escaped) newlines just output.  */
                   3689:        while (--len >= 0)
                   3690:          if (buf[len] == '\n')
                   3691:            op->lineno++;
                   3692: 
                   3693:        already_output = &junk;
                   3694:       }                                /* Don't we need a newline or #line? */
                   3695: 
                   3696:       if (copy_command) {
                   3697:        register U_CHAR *xp = buf;
                   3698:        /* Need to copy entire command into temp buffer before dispatching */
                   3699: 
                   3700:        cp = (U_CHAR *) alloca (bp - buf + 5); /* room for cmd plus
                   3701:                                                  some slop */
                   3702:        buf = cp;
                   3703: 
                   3704:        /* Copy to the new buffer, deleting comments
                   3705:           and backslash-newlines (and whitespace surrounding the latter).  */
                   3706: 
                   3707:        while (xp < bp) {
                   3708:          register U_CHAR c = *xp++;
                   3709:          *cp++ = c;
                   3710: 
                   3711:          switch (c) {
                   3712:          case '\n':
                   3713:            abort ();  /* A bare newline should never part of the line.  */
                   3714:            break;
                   3715: 
                   3716:            /* <...> is special for #include.  */
                   3717:          case '<':
                   3718:            if (!kt->angle_brackets)
                   3719:              break;
                   3720:            while (xp < bp && c != '>') {
                   3721:              c = *xp++;
                   3722:              if (c == '\\' && xp < bp && *xp == '\n')
                   3723:                xp++;
                   3724:              else
                   3725:                *cp++ = c;
                   3726:            }
                   3727:            break;
                   3728: 
                   3729:          case '\\':
                   3730:            if (*xp == '\n') {
                   3731:              xp++;
                   3732:              cp--;
                   3733:              if (cp != buf && is_space[cp[-1]]) {
                   3734:                while (cp != buf && is_space[cp[-1]]) cp--;
                   3735:                cp++;
                   3736:                SKIP_WHITE_SPACE (xp);
                   3737:              } else if (is_space[*xp]) {
                   3738:                *cp++ = *xp++;
                   3739:                SKIP_WHITE_SPACE (xp);
                   3740:              }
1.1.1.3   root     3741:            } else {
                   3742:              *cp++ = *xp++;
1.1       root     3743:            }
                   3744:            break;
                   3745: 
                   3746:          case '\'':
                   3747:          case '\"':
                   3748:            {
                   3749:              register U_CHAR *bp1
1.1.1.4   root     3750:                = skip_quoted_string (xp - 1, bp, ip->lineno,
                   3751:                                      NULL_PTR, NULL_PTR, NULL_PTR);
1.1       root     3752:              while (xp != bp1)
                   3753:                if (*xp == '\\') {
                   3754:                  if (*++xp != '\n')
                   3755:                    *cp++ = '\\';
                   3756:                  else
                   3757:                    xp++;
                   3758:                } else
                   3759:                  *cp++ = *xp++;
                   3760:            }
                   3761:            break;
                   3762: 
                   3763:          case '/':
                   3764:            if (*xp == '*'
1.1.1.4   root     3765:                || (cplusplus_comments && *xp == '/')) {
1.1       root     3766:              ip->bufp = xp + 1;
                   3767:              /* If we already copied the command through,
                   3768:                 already_output != 0 prevents outputting comment now.  */
1.1.1.2   root     3769:              skip_to_end_of_comment (ip, already_output, 0);
1.1       root     3770:              if (keep_comments)
                   3771:                while (xp != ip->bufp)
                   3772:                  *cp++ = *xp++;
                   3773:              /* Delete or replace the slash.  */
                   3774:              else if (traditional)
                   3775:                cp--;
                   3776:              else
                   3777:                cp[-1] = ' ';
                   3778:              xp = ip->bufp;
                   3779:            }
                   3780:          }
                   3781:        }
                   3782: 
                   3783:        /* Null-terminate the copy.  */
                   3784: 
                   3785:        *cp = 0;
                   3786:       } else
                   3787:        cp = bp;
                   3788: 
                   3789:       ip->bufp = resume_p;
                   3790: 
                   3791:       /* Some directives should be written out for cc1 to process,
                   3792:         just as if they were not defined.  And sometimes we're copying
                   3793:         definitions through.  */
                   3794: 
                   3795:       if (!no_output && already_output == 0
                   3796:          && (kt->pass_thru
                   3797:              || (kt->type == T_DEFINE
                   3798:                  && (dump_macros == dump_names
                   3799:                      || dump_macros == dump_definitions)))) {
                   3800:         int len;
                   3801: 
                   3802:        /* Output directive name.  */
                   3803:         check_expand (op, kt->length + 1);
                   3804:         *op->bufp++ = '#';
1.1.1.7 ! root     3805:         bcopy (kt->name, (char *) op->bufp, kt->length);
1.1       root     3806:         op->bufp += kt->length;
                   3807: 
                   3808:        if (kt->pass_thru || dump_macros == dump_definitions) {
                   3809:          /* Output arguments.  */
                   3810:          len = (cp - buf);
                   3811:          check_expand (op, len);
1.1.1.7 ! root     3812:          bcopy (buf, (char *) op->bufp, len);
1.1       root     3813:          op->bufp += len;
1.1.1.4   root     3814:        } else if (kt->type == T_DEFINE && dump_macros == dump_names) {
                   3815:          U_CHAR *xp = buf;
                   3816:          U_CHAR *yp;
                   3817:          SKIP_WHITE_SPACE (xp);
                   3818:          yp = xp;
                   3819:          while (is_idchar[*xp]) xp++;
                   3820:          len = (xp - yp);
                   3821:          check_expand (op, len + 1);
                   3822:          *op->bufp++ = ' ';
                   3823:          bcopy (yp, op->bufp, len);
                   3824:          op->bufp += len;
1.1       root     3825:        }
                   3826:       }                                /* Don't we need a newline or #line? */
                   3827: 
                   3828:       /* Call the appropriate command handler.  buf now points to
                   3829:         either the appropriate place in the input buffer, or to
                   3830:         the temp buffer if it was necessary to make one.  cp
                   3831:         points to the first char after the contents of the (possibly
                   3832:         copied) command, in either case. */
                   3833:       (*kt->func) (buf, cp, op, kt);
                   3834:       check_expand (op, ip->length - (ip->bufp - ip->buf));
                   3835: 
                   3836:       return 1;
                   3837:     }
                   3838:   }
                   3839: 
                   3840:   /* It is deliberate that we don't warn about undefined directives.
                   3841:      That is the responsibility of cc1.  */
                   3842:   return 0;
                   3843: }
                   3844: 
1.1.1.3   root     3845: static struct tm *
                   3846: timestamp ()
                   3847: {
                   3848:   static struct tm *timebuf;
                   3849:   if (!timebuf) {
1.1.1.7 ! root     3850:     time_t t = time ((time_t *)0);
1.1.1.3   root     3851:     timebuf = localtime (&t);
                   3852:   }
                   3853:   return timebuf;
                   3854: }
                   3855: 
1.1       root     3856: static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                   3857:                             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
                   3858:                            };
                   3859: 
                   3860: /*
                   3861:  * expand things like __FILE__.  Place the expansion into the output
                   3862:  * buffer *without* rescanning.
                   3863:  */
                   3864: 
                   3865: static void
                   3866: special_symbol (hp, op)
                   3867:      HASHNODE *hp;
                   3868:      FILE_BUF *op;
                   3869: {
                   3870:   char *buf;
                   3871:   int i, len;
                   3872:   int true_indepth;
                   3873:   FILE_BUF *ip = NULL;
1.1.1.3   root     3874:   struct tm *timebuf;
1.1       root     3875: 
                   3876:   int paren = 0;               /* For special `defined' keyword */
                   3877: 
                   3878:   if (pcp_outfile && pcp_inside_if
                   3879:       && hp->type != T_SPEC_DEFINED && hp->type != T_CONST)
                   3880:     error ("Predefined macro `%s' used inside `#if' during precompilation",
                   3881:           hp->name);
                   3882:     
                   3883:   for (i = indepth; i >= 0; i--)
                   3884:     if (instack[i].fname != NULL) {
                   3885:       ip = &instack[i];
                   3886:       break;
                   3887:     }
                   3888:   if (ip == NULL) {
                   3889:     error ("cccp error: not in any file?!");
                   3890:     return;                    /* the show must go on */
                   3891:   }
                   3892: 
                   3893:   switch (hp->type) {
                   3894:   case T_FILE:
                   3895:   case T_BASE_FILE:
                   3896:     {
                   3897:       char *string;
                   3898:       if (hp->type == T_FILE)
                   3899:        string = ip->nominal_fname;
                   3900:       else
                   3901:        string = instack[0].nominal_fname;
                   3902: 
                   3903:       if (string)
                   3904:        {
1.1.1.6   root     3905:          buf = (char *) alloca (3 + 4 * strlen (string));
                   3906:          quote_string (buf, string);
1.1       root     3907:        }
                   3908:       else
                   3909:        buf = "\"\"";
                   3910: 
                   3911:       break;
                   3912:     }
                   3913: 
                   3914:   case T_INCLUDE_LEVEL:
                   3915:     true_indepth = 0;
                   3916:     for (i = indepth; i >= 0; i--)
                   3917:       if (instack[i].fname != NULL)
                   3918:         true_indepth++;
                   3919: 
                   3920:     buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */
                   3921:     sprintf (buf, "%d", true_indepth - 1);
                   3922:     break;
                   3923: 
                   3924:   case T_VERSION:
                   3925:     buf = (char *) alloca (3 + strlen (version_string));
                   3926:     sprintf (buf, "\"%s\"", version_string);
                   3927:     break;
                   3928: 
1.1.1.6   root     3929: #ifndef NO_BUILTIN_SIZE_TYPE
1.1       root     3930:   case T_SIZE_TYPE:
1.1.1.7 ! root     3931:     buf = SIZE_TYPE;
1.1       root     3932:     break;
1.1.1.6   root     3933: #endif
1.1       root     3934: 
1.1.1.6   root     3935: #ifndef NO_BUILTIN_PTRDIFF_TYPE
1.1       root     3936:   case T_PTRDIFF_TYPE:
1.1.1.7 ! root     3937:     buf = PTRDIFF_TYPE;
1.1       root     3938:     break;
1.1.1.6   root     3939: #endif
1.1       root     3940: 
                   3941:   case T_WCHAR_TYPE:
1.1.1.7 ! root     3942:     buf = wchar_type;
1.1       root     3943:     break;
                   3944: 
1.1.1.5   root     3945:   case T_USER_LABEL_PREFIX_TYPE:
1.1.1.7 ! root     3946:     buf = USER_LABEL_PREFIX;
1.1.1.5   root     3947:     break;
                   3948: 
                   3949:   case T_REGISTER_PREFIX_TYPE:
1.1.1.7 ! root     3950:     buf = REGISTER_PREFIX;
1.1.1.5   root     3951:     break;
                   3952: 
1.1       root     3953:   case T_CONST:
                   3954:     buf = (char *) alloca (4 * sizeof (int));
                   3955:     sprintf (buf, "%d", hp->value.ival);
                   3956:     if (pcp_inside_if && pcp_outfile)
                   3957:       /* Output a precondition for this macro use */
                   3958:       fprintf (pcp_outfile, "#define %s %d\n", hp->name, hp->value.ival);
                   3959:     break;
                   3960: 
                   3961:   case T_SPECLINE:
                   3962:     buf = (char *) alloca (10);
                   3963:     sprintf (buf, "%d", ip->lineno);
                   3964:     break;
                   3965: 
                   3966:   case T_DATE:
                   3967:   case T_TIME:
                   3968:     buf = (char *) alloca (20);
1.1.1.3   root     3969:     timebuf = timestamp ();
1.1       root     3970:     if (hp->type == T_DATE)
                   3971:       sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
                   3972:              timebuf->tm_mday, timebuf->tm_year + 1900);
                   3973:     else
                   3974:       sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
                   3975:              timebuf->tm_sec);
                   3976:     break;
                   3977: 
                   3978:   case T_SPEC_DEFINED:
                   3979:     buf = " 0 ";               /* Assume symbol is not defined */
                   3980:     ip = &instack[indepth];
                   3981:     SKIP_WHITE_SPACE (ip->bufp);
                   3982:     if (*ip->bufp == '(') {
                   3983:       paren++;
                   3984:       ip->bufp++;                      /* Skip over the paren */
                   3985:       SKIP_WHITE_SPACE (ip->bufp);
                   3986:     }
                   3987: 
                   3988:     if (!is_idstart[*ip->bufp])
                   3989:       goto oops;
                   3990:     if (hp = lookup (ip->bufp, -1, -1)) {
                   3991:       if (pcp_outfile && pcp_inside_if
1.1.1.7 ! root     3992:          && (hp->type == T_CONST
        !          3993:              || (hp->type == T_MACRO && hp->value.defn->predefined)))
1.1       root     3994:        /* Output a precondition for this macro use. */
                   3995:        fprintf (pcp_outfile, "#define %s\n", hp->name);
                   3996:       buf = " 1 ";
                   3997:     }
                   3998:     else
                   3999:       if (pcp_outfile && pcp_inside_if)        {
                   4000:        /* Output a precondition for this macro use */
                   4001:        U_CHAR *cp = ip->bufp;
                   4002:        fprintf (pcp_outfile, "#undef ");
                   4003:        while (is_idchar[*cp]) /* Ick! */
                   4004:          fputc (*cp++, pcp_outfile);
                   4005:        putc ('\n', pcp_outfile);
                   4006:       }
                   4007:     while (is_idchar[*ip->bufp])
                   4008:       ++ip->bufp;
                   4009:     SKIP_WHITE_SPACE (ip->bufp);
                   4010:     if (paren) {
                   4011:       if (*ip->bufp != ')')
                   4012:        goto oops;
                   4013:       ++ip->bufp;
                   4014:     }
                   4015:     break;
                   4016: 
                   4017: oops:
                   4018: 
                   4019:     error ("`defined' without an identifier");
                   4020:     break;
                   4021: 
                   4022:   default:
                   4023:     error ("cccp error: invalid special hash type"); /* time for gdb */
                   4024:     abort ();
                   4025:   }
                   4026:   len = strlen (buf);
                   4027:   check_expand (op, len);
1.1.1.7 ! root     4028:   bcopy (buf, (char *) op->bufp, len);
1.1       root     4029:   op->bufp += len;
                   4030: 
                   4031:   return;
                   4032: }
                   4033: 
                   4034: 
                   4035: /* Routines to handle #directives */
                   4036: 
                   4037: /* Handle #include and #import.
                   4038:    This function expects to see "fname" or <fname> on the input.  */
                   4039: 
                   4040: static int
                   4041: do_include (buf, limit, op, keyword)
                   4042:      U_CHAR *buf, *limit;
                   4043:      FILE_BUF *op;
                   4044:      struct directive *keyword;
                   4045: {
                   4046:   int importing = (keyword->type == T_IMPORT);
                   4047:   int skip_dirs = (keyword->type == T_INCLUDE_NEXT);
                   4048:   static int import_warning = 0;
                   4049:   char *fname;         /* Dynamically allocated fname buffer */
                   4050:   char *pcftry;
                   4051:   char *pcfname;
                   4052:   U_CHAR *fbeg, *fend;         /* Beginning and end of fname */
                   4053: 
                   4054:   struct file_name_list *search_start = include; /* Chain of dirs to search */
                   4055:   struct file_name_list dsp[1];        /* First in chain, if #include "..." */
1.1.1.4   root     4056:   struct file_name_list *searchptr = 0;
1.1       root     4057:   int flen;
                   4058: 
                   4059:   int f;                       /* file number */
                   4060: 
                   4061:   int retried = 0;             /* Have already tried macro
                   4062:                                   expanding the include line*/
                   4063:   FILE_BUF trybuf;             /* It got expanded into here */
1.1.1.4   root     4064:   int angle_brackets = 0;      /* 0 for "...", 1 for <...> */
1.1       root     4065:   int pcf = -1;
                   4066:   char *pcfbuf;
                   4067:   int pcfbuflimit;
                   4068:   int pcfnum;
                   4069:   f= -1;                       /* JF we iz paranoid! */
                   4070: 
1.1.1.4   root     4071:   if (importing && warn_import && !inhibit_warnings
1.1.1.2   root     4072:       && !instack[indepth].system_header_p && !import_warning) {
1.1       root     4073:     import_warning = 1;
                   4074:     warning ("using `#import' is not recommended");
                   4075:     fprintf (stderr, "The fact that a certain header file need not be processed more than once\n");
                   4076:     fprintf (stderr, "should be indicated in the header file, not where it is used.\n");
                   4077:     fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n");
                   4078:     fprintf (stderr, "  #ifndef _FOO_H_INCLUDED\n");
                   4079:     fprintf (stderr, "  #define _FOO_H_INCLUDED\n");
                   4080:     fprintf (stderr, "  ... <real contents of file> ...\n");
                   4081:     fprintf (stderr, "  #endif /* Not _FOO_H_INCLUDED */\n\n");
                   4082:     fprintf (stderr, "Then users can use `#include' any number of times.\n");
                   4083:     fprintf (stderr, "GNU C automatically avoids processing the file more than once\n");
                   4084:     fprintf (stderr, "when it is equipped with such a conditional.\n");
                   4085:   }
                   4086: 
                   4087: get_filename:
                   4088: 
                   4089:   fbeg = buf;
                   4090:   SKIP_WHITE_SPACE (fbeg);
                   4091:   /* Discard trailing whitespace so we can easily see
                   4092:      if we have parsed all the significant chars we were given.  */
                   4093:   while (limit != fbeg && is_hor_space[limit[-1]]) limit--;
                   4094: 
                   4095:   switch (*fbeg++) {
                   4096:   case '\"':
1.1.1.4   root     4097:     {
1.1       root     4098:       FILE_BUF *fp;
1.1.1.4   root     4099:       /* Copy the operand text, concatenating the strings.  */
                   4100:       {
                   4101:        U_CHAR *fin = fbeg;
                   4102:        fbeg = (U_CHAR *) alloca (limit - fbeg + 1);
                   4103:        fend = fbeg;
                   4104:        while (fin != limit) {
                   4105:          while (fin != limit && *fin != '\"')
                   4106:            *fend++ = *fin++;
                   4107:          fin++;
                   4108:          if (fin == limit)
                   4109:            break;
                   4110:          /* If not at the end, there had better be another string.  */
                   4111:          /* Skip just horiz space, and don't go past limit.  */
                   4112:          while (fin != limit && is_hor_space[*fin]) fin++;
                   4113:          if (fin != limit && *fin == '\"')
                   4114:            fin++;
                   4115:          else
                   4116:            goto fail;
                   4117:        }
                   4118:       }
1.1.1.5   root     4119:       *fend = 0;
1.1       root     4120: 
                   4121:       /* We have "filename".  Figure out directory this source
                   4122:         file is coming from and put it on the front of the list. */
                   4123: 
                   4124:       /* If -I- was specified, don't search current dir, only spec'd ones. */
                   4125:       if (ignore_srcdir) break;
                   4126: 
                   4127:       for (fp = &instack[indepth]; fp >= instack; fp--)
                   4128:        {
                   4129:          int n;
                   4130:          char *ep,*nam;
                   4131: 
                   4132:          if ((nam = fp->nominal_fname) != NULL) {
                   4133:            /* Found a named file.  Figure out dir of the file,
                   4134:               and put it in front of the search list.  */
                   4135:            dsp[0].next = search_start;
                   4136:            search_start = dsp;
                   4137: #ifndef VMS
                   4138:            ep = rindex (nam, '/');
                   4139: #else                          /* VMS */
                   4140:            ep = rindex (nam, ']');
                   4141:            if (ep == NULL) ep = rindex (nam, '>');
                   4142:            if (ep == NULL) ep = rindex (nam, ':');
                   4143:            if (ep != NULL) ep++;
                   4144: #endif                         /* VMS */
                   4145:            if (ep != NULL) {
                   4146:              n = ep - nam;
                   4147:              dsp[0].fname = (char *) alloca (n + 1);
                   4148:              strncpy (dsp[0].fname, nam, n);
                   4149:              dsp[0].fname[n] = '\0';
1.1.1.4   root     4150:              if (n + INCLUDE_LEN_FUDGE > max_include_len)
                   4151:                max_include_len = n + INCLUDE_LEN_FUDGE;
1.1       root     4152:            } else {
                   4153:              dsp[0].fname = 0; /* Current directory */
                   4154:            }
1.1.1.7 ! root     4155:            dsp[0].got_name_map = 0;
1.1       root     4156:            break;
                   4157:          }
                   4158:        }
                   4159:       break;
                   4160:     }
                   4161: 
                   4162:   case '<':
                   4163:     fend = fbeg;
                   4164:     while (fend != limit && *fend != '>') fend++;
                   4165:     if (*fend == '>' && fend + 1 == limit) {
1.1.1.4   root     4166:       angle_brackets = 1;
1.1       root     4167:       /* If -I-, start with the first -I dir after the -I-.  */
                   4168:       if (first_bracket_include)
                   4169:        search_start = first_bracket_include;
                   4170:       break;
                   4171:     }
                   4172:     goto fail;
                   4173: 
                   4174:   default:
1.1.1.7 ! root     4175: #ifdef VMS
        !          4176:     /*
        !          4177:      * Support '#include xyz' like VAX-C to allow for easy use of all the
        !          4178:      * decwindow include files. It defaults to '#include <xyz.h>' (so the
        !          4179:      * code from case '<' is repeated here) and generates a warning.
        !          4180:      */
        !          4181:     if (isalpha(*(--fbeg))) {
        !          4182:       fend = fbeg;
        !          4183:       while (fend != limit && (!isspace(*fend))) fend++;
        !          4184:       warning ("VAX-C-style include specification found, use '#include <filename.h>' !");
        !          4185:       if (fend  == limit) {
        !          4186:        angle_brackets = 1;
        !          4187:        /* If -I-, start with the first -I dir after the -I-.  */
        !          4188:        if (first_bracket_include)
        !          4189:          search_start = first_bracket_include;
        !          4190:        break;
        !          4191:       }
        !          4192:     }
        !          4193: #endif
        !          4194: 
1.1       root     4195:   fail:
                   4196:     if (retried) {
1.1.1.5   root     4197:       error ("`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name);
1.1       root     4198:       return 0;
                   4199:     } else {
                   4200:       trybuf = expand_to_temp_buffer (buf, limit, 0, 0);
                   4201:       buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
1.1.1.7 ! root     4202:       bcopy ((char *) trybuf.buf, (char *) buf, trybuf.bufp - trybuf.buf);
1.1       root     4203:       limit = buf + (trybuf.bufp - trybuf.buf);
                   4204:       free (trybuf.buf);
                   4205:       retried++;
                   4206:       goto get_filename;
                   4207:     }
                   4208:   }
                   4209: 
                   4210:   /* For #include_next, skip in the search path
                   4211:      past the dir in which the containing file was found.  */
                   4212:   if (skip_dirs) {
                   4213:     FILE_BUF *fp;
                   4214:     for (fp = &instack[indepth]; fp >= instack; fp--)
                   4215:       if (fp->fname != NULL) {
                   4216:        /* fp->dir is null if the containing file was specified
                   4217:           with an absolute file name.  In that case, don't skip anything.  */
                   4218:        if (fp->dir)
                   4219:          search_start = fp->dir->next;
                   4220:        break;
                   4221:       }
                   4222:   }
                   4223: 
                   4224:   flen = fend - fbeg;
1.1.1.5   root     4225: 
                   4226:   if (flen == 0)
                   4227:     {
                   4228:       error ("empty file name in `#%s'", keyword->name);
                   4229:       return 0;
                   4230:     }
                   4231: 
1.1       root     4232:   /* Allocate this permanently, because it gets stored in the definitions
                   4233:      of macros.  */
1.1.1.7 ! root     4234:   fname = (char *) xmalloc (max_include_len + flen + 4);
1.1       root     4235:   /* + 2 above for slash and terminating null.  */
1.1.1.7 ! root     4236:   /* + 2 added for '.h' on VMS (to support '#include filename') */
1.1       root     4237: 
                   4238:   /* If specified file name is absolute, just open it.  */
                   4239: 
                   4240:   if (*fbeg == '/') {
                   4241:     strncpy (fname, fbeg, flen);
                   4242:     fname[flen] = 0;
1.1.1.4   root     4243:     if (redundant_include_p (fname))
1.1.1.2   root     4244:       return 0;
1.1       root     4245:     if (importing)
1.1.1.7 ! root     4246:       f = lookup_import (fname, NULL_PTR);
1.1       root     4247:     else
1.1.1.7 ! root     4248:       f = open_include_file (fname, NULL_PTR);
1.1       root     4249:     if (f == -2)
                   4250:       return 0;                /* Already included this file */
                   4251:   } else {
                   4252:     /* Search directory path, trying to open the file.
                   4253:        Copy each filename tried into FNAME.  */
                   4254: 
                   4255:     for (searchptr = search_start; searchptr; searchptr = searchptr->next) {
                   4256:       if (searchptr->fname) {
                   4257:        /* The empty string in a search path is ignored.
                   4258:           This makes it possible to turn off entirely
                   4259:           a standard piece of the list.  */
                   4260:        if (searchptr->fname[0] == 0)
                   4261:          continue;
                   4262:        strcpy (fname, searchptr->fname);
                   4263:        strcat (fname, "/");
                   4264:        fname[strlen (fname) + flen] = 0;
                   4265:       } else {
                   4266:        fname[0] = 0;
                   4267:       }
                   4268:       strncat (fname, fbeg, flen);
                   4269: #ifdef VMS
                   4270:       /* Change this 1/2 Unix 1/2 VMS file specification into a
                   4271:          full VMS file specification */
                   4272:       if (searchptr->fname && (searchptr->fname[0] != 0)) {
                   4273:        /* Fix up the filename */
                   4274:        hack_vms_include_specification (fname);
                   4275:       } else {
                   4276:        /* This is a normal VMS filespec, so use it unchanged.  */
                   4277:        strncpy (fname, fbeg, flen);
                   4278:        fname[flen] = 0;
1.1.1.7 ! root     4279:        /* if it's '#include filename', add the missing .h */
        !          4280:        if (index(fname,'.')==NULL) {
        !          4281:          strcat (fname, ".h");
        !          4282:        }
1.1       root     4283:       }
                   4284: #endif /* VMS */
                   4285:       if (importing)
1.1.1.7 ! root     4286:        f = lookup_import (fname, searchptr);
1.1       root     4287:       else
1.1.1.7 ! root     4288:        f = open_include_file (fname, searchptr);
1.1       root     4289:       if (f == -2)
                   4290:        return 0;                       /* Already included this file */
1.1.1.5   root     4291: #ifdef EACCES
                   4292:       else if (f == -1 && errno == EACCES)
                   4293:        warning ("Header file %s exists, but is not readable", fname);
                   4294: #endif
1.1.1.4   root     4295:       if (redundant_include_p (fname)) {
1.1.1.2   root     4296:        close (f);
                   4297:        return 0;
                   4298:       }
1.1       root     4299:       if (f >= 0)
                   4300:        break;
                   4301:     }
                   4302:   }
                   4303: 
                   4304:   if (f < 0) {
                   4305:     /* A file that was not found.  */
                   4306: 
                   4307:     strncpy (fname, fbeg, flen);
                   4308:     fname[flen] = 0;
1.1.1.7 ! root     4309:     /* If generating dependencies and -MG was specified, we assume missing
        !          4310:        files are leaf files, living in the same directory as the source file
        !          4311:        or other similar place; these missing files may be generated from
        !          4312:        other files and may not exist yet (eg: y.tab.h).  */
        !          4313:     if (print_deps_missing_files
        !          4314:        && print_deps > (angle_brackets || (system_include_depth > 0)))
        !          4315:       {
        !          4316:        /* If it was requested as a system header file,
        !          4317:           then assume it belongs in the first place to look for such.  */
        !          4318:        if (angle_brackets)
        !          4319:          {
        !          4320:            for (searchptr = search_start; searchptr; searchptr = searchptr->next)
        !          4321:              {
        !          4322:                if (searchptr->fname)
        !          4323:                  {
        !          4324:                    char *p;
        !          4325: 
        !          4326:                    if (searchptr->fname[0] == 0)
        !          4327:                      continue;
        !          4328:                    p = xmalloc (strlen (searchptr->fname)
        !          4329:                                 + strlen (fname) + 2);
        !          4330:                    strcpy (p, searchptr->fname);
        !          4331:                    strcat (p, "/");
        !          4332:                    strcat (p, fname);
        !          4333:                    deps_output (p, ' ');
        !          4334:                    break;
        !          4335:                  }
        !          4336:              }
        !          4337:          }
        !          4338:        else
        !          4339:          {
        !          4340:            /* Otherwise, omit the directory, as if the file existed
        !          4341:               in the directory with the source.  */
        !          4342:            deps_output (fname, ' ');
        !          4343:          }
        !          4344:       }
1.1.1.5   root     4345:     /* If -M was specified, and this header file won't be added to the
                   4346:        dependency list, then don't count this as an error, because we can
                   4347:        still produce correct output.  Otherwise, we can't produce correct
                   4348:        output, because there may be dependencies we need inside the missing
                   4349:        file, and we don't know what directory this missing file exists in.  */
1.1.1.7 ! root     4350:     else if (print_deps
1.1.1.5   root     4351:        && (print_deps <= (angle_brackets || (system_include_depth > 0))))
                   4352:       warning ("No include path in which to find %s", fname);
                   4353:     else if (search_start)
1.1.1.4   root     4354:       error_from_errno (fname);
                   4355:     else
                   4356:       error ("No include path in which to find %s", fname);
1.1       root     4357:   } else {
                   4358:     struct stat stat_f;
                   4359: 
                   4360:     /* Check to see if this include file is a once-only include file.
                   4361:        If so, give up.  */
                   4362: 
                   4363:     struct file_name_list* ptr;
                   4364: 
                   4365:     for (ptr = dont_repeat_files; ptr; ptr = ptr->next) {
                   4366:       if (!strcmp (ptr->fname, fname)) {
                   4367:        close (f);
                   4368:         return 0;                              /* This file was once'd. */
                   4369:       }
                   4370:     }
                   4371: 
                   4372:     for (ptr = all_include_files; ptr; ptr = ptr->next) {
                   4373:       if (!strcmp (ptr->fname, fname))
                   4374:         break;                         /* This file was included before. */
                   4375:     }
                   4376: 
                   4377:     if (ptr == 0) {
                   4378:       /* This is the first time for this file.  */
                   4379:       /* Add it to list of files included.  */
                   4380: 
                   4381:       ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
                   4382:       ptr->control_macro = 0;
1.1.1.6   root     4383:       ptr->c_system_include_path = 0;
1.1       root     4384:       ptr->next = all_include_files;
                   4385:       all_include_files = ptr;
                   4386:       ptr->fname = savestring (fname);
1.1.1.7 ! root     4387:       ptr->got_name_map = 0;
1.1       root     4388: 
                   4389:       /* For -M, add this file to the dependencies.  */
1.1.1.7 ! root     4390:       if (print_deps > (angle_brackets || (system_include_depth > 0)))
        !          4391:        deps_output (fname, ' ');
1.1       root     4392:     }   
                   4393: 
                   4394:     /* Handle -H option.  */
1.1.1.6   root     4395:     if (print_include_names) {
                   4396:       output_dots (stderr, indepth);
1.1       root     4397:       fprintf (stderr, "%s\n", fname);
1.1.1.6   root     4398:     }
1.1       root     4399: 
1.1.1.4   root     4400:     if (angle_brackets)
1.1       root     4401:       system_include_depth++;
                   4402: 
                   4403:     /* Actually process the file.  */
                   4404:     add_import (f, fname);     /* Record file on "seen" list for #import. */
                   4405: 
                   4406:     pcftry = (char *) alloca (strlen (fname) + 30);
                   4407:     pcfbuf = 0;
                   4408:     pcfnum = 0;
                   4409: 
                   4410:     fstat (f, &stat_f);
                   4411: 
                   4412:     if (!no_precomp)
                   4413:       do {
                   4414:        sprintf (pcftry, "%s%d", fname, pcfnum++);
                   4415:        
                   4416:        pcf = open (pcftry, O_RDONLY, 0666);
                   4417:        if (pcf != -1)
                   4418:          {
                   4419:            struct stat s;
                   4420: 
                   4421:            fstat (pcf, &s);
1.1.1.7 ! root     4422:            if (bcmp ((char *) &stat_f.st_ino, (char *) &s.st_ino,
        !          4423:                      sizeof (s.st_ino))
1.1       root     4424:                || stat_f.st_dev != s.st_dev)
                   4425:              {
                   4426:                pcfbuf = check_precompiled (pcf, fname, &pcfbuflimit);
                   4427:                /* Don't need it any more.  */
                   4428:                close (pcf);
                   4429:              }
                   4430:            else
                   4431:              {
                   4432:                /* Don't need it at all.  */
                   4433:                close (pcf);
                   4434:                break;
                   4435:              }
                   4436:          }
                   4437:       } while (pcf != -1 && !pcfbuf);
                   4438:     
                   4439:     /* Actually process the file */
                   4440:     if (pcfbuf) {
                   4441:       pcfname = xmalloc (strlen (pcftry) + 1);
                   4442:       strcpy (pcfname, pcftry);
                   4443:       pcfinclude (pcfbuf, pcfbuflimit, fname, op);
                   4444:     }
                   4445:     else
1.1.1.4   root     4446:       finclude (f, fname, op, is_system_include (fname), searchptr);
1.1       root     4447: 
1.1.1.4   root     4448:     if (angle_brackets)
1.1       root     4449:       system_include_depth--;
                   4450:   }
                   4451:   return 0;
                   4452: }
                   4453: 
1.1.1.2   root     4454: /* Return nonzero if there is no need to include file NAME
                   4455:    because it has already been included and it contains a conditional
                   4456:    to make a repeated include do nothing.  */
                   4457: 
                   4458: static int
1.1.1.4   root     4459: redundant_include_p (name)
1.1.1.2   root     4460:      char *name;
                   4461: {
                   4462:   struct file_name_list *l = all_include_files;
                   4463:   for (; l; l = l->next)
                   4464:     if (! strcmp (name, l->fname)
                   4465:        && l->control_macro
                   4466:        && lookup (l->control_macro, -1, -1))
                   4467:       return 1;
                   4468:   return 0;
                   4469: }
                   4470: 
1.1.1.4   root     4471: /* Return nonzero if the given FILENAME is an absolute pathname which
                   4472:    designates a file within one of the known "system" include file
                   4473:    directories.  We assume here that if the given FILENAME looks like
                   4474:    it is the name of a file which resides either directly in a "system"
                   4475:    include file directory, or within any subdirectory thereof, then the
                   4476:    given file must be a "system" include file.  This function tells us
1.1.1.6   root     4477:    if we should suppress pedantic errors/warnings for the given FILENAME.
                   4478: 
                   4479:    The value is 2 if the file is a C-language system header file
                   4480:    for which C++ should (on most systems) assume `extern "C"'.  */
1.1.1.4   root     4481: 
                   4482: static int
                   4483: is_system_include (filename)
                   4484:     register char *filename;
                   4485: {
                   4486:   struct file_name_list *searchptr;
                   4487: 
                   4488:   for (searchptr = first_system_include; searchptr;
                   4489:        searchptr = searchptr->next)
                   4490:     if (searchptr->fname) {
                   4491:       register char *sys_dir = searchptr->fname;
                   4492:       register unsigned length = strlen (sys_dir);
                   4493: 
                   4494:       if (! strncmp (sys_dir, filename, length) && filename[length] == '/')
1.1.1.6   root     4495:        {
                   4496:          if (searchptr->c_system_include_path)
                   4497:            return 2;
                   4498:          else
                   4499:            return 1;
                   4500:        }
1.1.1.4   root     4501:     }
                   4502:   return 0;
                   4503: }
                   4504: 
1.1.1.7 ! root     4505: /* The file_name_map structure holds a mapping of file names for a
        !          4506:    particular directory.  This mapping is read from the file named
        !          4507:    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
        !          4508:    map filenames on a file system with severe filename restrictions,
        !          4509:    such as DOS.  The format of the file name map file is just a series
        !          4510:    of lines with two tokens on each line.  The first token is the name
        !          4511:    to map, and the second token is the actual name to use.  */
        !          4512: 
        !          4513: struct file_name_map
        !          4514: {
        !          4515:   struct file_name_map *map_next;
        !          4516:   char *map_from;
        !          4517:   char *map_to;
        !          4518: };
        !          4519: 
        !          4520: #define FILE_NAME_MAP_FILE "header.gcc"
        !          4521: 
        !          4522: /* Read a space delimited string of unlimited length from a stdio
        !          4523:    file.  */
        !          4524: 
        !          4525: static char *
        !          4526: read_filename_string (ch, f)
        !          4527:      int ch;
        !          4528:      FILE *f;
        !          4529: {
        !          4530:   char *alloc, *set;
        !          4531:   int len;
        !          4532: 
        !          4533:   len = 20;
        !          4534:   set = alloc = xmalloc (len + 1);
        !          4535:   if (! is_space[ch])
        !          4536:     {
        !          4537:       *set++ = ch;
        !          4538:       while ((ch = getc (f)) != EOF && ! is_space[ch])
        !          4539:        {
        !          4540:          if (set - alloc == len)
        !          4541:            {
        !          4542:              len *= 2;
        !          4543:              alloc = xrealloc (alloc, len + 1);
        !          4544:              set = alloc + len / 2;
        !          4545:            }
        !          4546:          *set++ = ch;
        !          4547:        }
        !          4548:     }
        !          4549:   *set = '\0';
        !          4550:   ungetc (ch, f);
        !          4551:   return alloc;
        !          4552: }
        !          4553: 
        !          4554: /* Read the file name map file for DIRNAME.  */
        !          4555: 
        !          4556: static struct file_name_map *
        !          4557: read_name_map (dirname)
        !          4558:      char *dirname;
        !          4559: {
        !          4560:   /* This structure holds a linked list of file name maps, one per
        !          4561:      directory.  */
        !          4562:   struct file_name_map_list
        !          4563:     {
        !          4564:       struct file_name_map_list *map_list_next;
        !          4565:       char *map_list_name;
        !          4566:       struct file_name_map *map_list_map;
        !          4567:     };
        !          4568:   static struct file_name_map_list *map_list;
        !          4569:   register struct file_name_map_list *map_list_ptr;
        !          4570:   char *name;
        !          4571:   FILE *f;
        !          4572: 
        !          4573:   for (map_list_ptr = map_list; map_list_ptr;
        !          4574:        map_list_ptr = map_list_ptr->map_list_next)
        !          4575:     if (! strcmp (map_list_ptr->map_list_name, dirname))
        !          4576:       return map_list_ptr->map_list_map;
        !          4577: 
        !          4578:   map_list_ptr = ((struct file_name_map_list *)
        !          4579:                  xmalloc (sizeof (struct file_name_map_list)));
        !          4580:   map_list_ptr->map_list_name = savestring (dirname);
        !          4581:   map_list_ptr->map_list_map = NULL;
        !          4582: 
        !          4583:   name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
        !          4584:   strcpy (name, dirname);
        !          4585:   if (*dirname)
        !          4586:     strcat (name, "/");
        !          4587:   strcat (name, FILE_NAME_MAP_FILE);
        !          4588:   f = fopen (name, "r");
        !          4589:   if (!f)
        !          4590:     map_list_ptr->map_list_map = NULL;
        !          4591:   else
        !          4592:     {
        !          4593:       int ch;
        !          4594:       int dirlen = strlen (dirname);
        !          4595: 
        !          4596:       while ((ch = getc (f)) != EOF)
        !          4597:        {
        !          4598:          char *from, *to;
        !          4599:          struct file_name_map *ptr;
        !          4600: 
        !          4601:          if (is_space[ch])
        !          4602:            continue;
        !          4603:          from = read_filename_string (ch, f);
        !          4604:          while ((ch = getc (f)) != EOF && is_hor_space[ch])
        !          4605:            ;
        !          4606:          to = read_filename_string (ch, f);
        !          4607: 
        !          4608:          ptr = ((struct file_name_map *)
        !          4609:                 xmalloc (sizeof (struct file_name_map)));
        !          4610:          ptr->map_from = from;
        !          4611: 
        !          4612:          /* Make the real filename absolute.  */
        !          4613:          if (*to == '/')
        !          4614:            ptr->map_to = to;
        !          4615:          else
        !          4616:            {
        !          4617:              ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
        !          4618:              strcpy (ptr->map_to, dirname);
        !          4619:              ptr->map_to[dirlen] = '/';
        !          4620:              strcpy (ptr->map_to + dirlen + 1, to);
        !          4621:              free (to);
        !          4622:            }         
        !          4623: 
        !          4624:          ptr->map_next = map_list_ptr->map_list_map;
        !          4625:          map_list_ptr->map_list_map = ptr;
        !          4626: 
        !          4627:          while ((ch = getc (f)) != '\n')
        !          4628:            if (ch == EOF)
        !          4629:              break;
        !          4630:        }
        !          4631:       fclose (f);
        !          4632:     }
        !          4633:   
        !          4634:   map_list_ptr->map_list_next = map_list;
        !          4635:   map_list = map_list_ptr;
        !          4636: 
        !          4637:   return map_list_ptr->map_list_map;
        !          4638: }  
        !          4639: 
        !          4640: /* Try to open include file FILENAME.  SEARCHPTR is the directory
        !          4641:    being tried from the include file search path.  This function maps
        !          4642:    filenames on file systems based on information read by
        !          4643:    read_name_map.  */
        !          4644: 
        !          4645: static int
        !          4646: open_include_file (filename, searchptr)
        !          4647:      char *filename;
        !          4648:      struct file_name_list *searchptr;
        !          4649: {
        !          4650:   register struct file_name_map *map;
        !          4651:   register char *from;
        !          4652:   char *p, *dir;
        !          4653: 
        !          4654:   if (searchptr && ! searchptr->got_name_map)
        !          4655:     {
        !          4656:       searchptr->name_map = read_name_map (searchptr->fname
        !          4657:                                           ? searchptr->fname : ".");
        !          4658:       searchptr->got_name_map = 1;
        !          4659:     }
        !          4660: 
        !          4661:   /* First check the mapping for the directory we are using.  */
        !          4662:   if (searchptr && searchptr->name_map)
        !          4663:     {
        !          4664:       from = filename;
        !          4665:       if (searchptr->fname)
        !          4666:        from += strlen (searchptr->fname) + 1;
        !          4667:       for (map = searchptr->name_map; map; map = map->map_next)
        !          4668:        {
        !          4669:          if (! strcmp (map->map_from, from))
        !          4670:            {
        !          4671:              /* Found a match.  */
        !          4672:              return open (map->map_to, O_RDONLY, 0666);
        !          4673:            }
        !          4674:        }
        !          4675:     }
        !          4676: 
        !          4677:   /* Try to find a mapping file for the particular directory we are
        !          4678:      looking in.  Thus #include <sys/types.h> will look up sys/types.h
        !          4679:      in /usr/include/header.gcc and look up types.h in
        !          4680:      /usr/include/sys/header.gcc.  */
        !          4681:   p = rindex (filename, '/');
        !          4682:   if (! p)
        !          4683:     p = filename;
        !          4684:   if (searchptr
        !          4685:       && searchptr->fname
        !          4686:       && strlen (searchptr->fname) == p - filename
        !          4687:       && ! strncmp (searchptr->fname, filename, p - filename))
        !          4688:     {
        !          4689:       /* FILENAME is in SEARCHPTR, which we've already checked.  */
        !          4690:       return open (filename, O_RDONLY, 0666);
        !          4691:     }
        !          4692: 
        !          4693:   if (p == filename)
        !          4694:     {
        !          4695:       dir = ".";
        !          4696:       from = filename;
        !          4697:     }
        !          4698:   else
        !          4699:     {
        !          4700:       dir = (char *) alloca (p - filename + 1);
        !          4701:       bcopy (filename, dir, p - filename);
        !          4702:       dir[p - filename] = '\0';
        !          4703:       from = p + 1;
        !          4704:     }
        !          4705:   for (map = read_name_map (dir); map; map = map->map_next)
        !          4706:     if (! strcmp (map->map_from, from))
        !          4707:       return open (map->map_to, O_RDONLY, 0666);
        !          4708: 
        !          4709:   return open (filename, O_RDONLY, 0666);
        !          4710: }
        !          4711: 
1.1       root     4712: /* Process the contents of include file FNAME, already open on descriptor F,
                   4713:    with output to OP.
1.1.1.5   root     4714:    SYSTEM_HEADER_P is 1 if this file resides in any one of the known
                   4715:    "system" include directories (as decided by the `is_system_include'
                   4716:    function above).
1.1       root     4717:    DIRPTR is the link in the dir path through which this file was found,
                   4718:    or 0 if the file name was absolute.  */
                   4719: 
                   4720: static void
                   4721: finclude (f, fname, op, system_header_p, dirptr)
                   4722:      int f;
                   4723:      char *fname;
                   4724:      FILE_BUF *op;
                   4725:      int system_header_p;
                   4726:      struct file_name_list *dirptr;
                   4727: {
                   4728:   int st_mode;
                   4729:   long st_size;
                   4730:   long i;
                   4731:   FILE_BUF *fp;                        /* For input stack frame */
                   4732:   int missing_newline = 0;
                   4733: 
                   4734:   CHECK_DEPTH (return;);
                   4735: 
                   4736:   if (file_size_and_mode (f, &st_mode, &st_size) < 0)
1.1.1.4   root     4737:     {
                   4738:       perror_with_name (fname);
                   4739:       close (f);
                   4740:       return;
                   4741:     }
1.1       root     4742: 
                   4743:   fp = &instack[indepth + 1];
1.1.1.7 ! root     4744:   bzero ((char *) fp, sizeof (FILE_BUF));
1.1       root     4745:   fp->nominal_fname = fp->fname = fname;
                   4746:   fp->length = 0;
                   4747:   fp->lineno = 1;
                   4748:   fp->if_stack = if_stack;
                   4749:   fp->system_header_p = system_header_p;
                   4750:   fp->dir = dirptr;
                   4751: 
                   4752:   if (S_ISREG (st_mode)) {
1.1.1.3   root     4753:     fp->buf = (U_CHAR *) xmalloc (st_size + 2);
1.1       root     4754:     fp->bufp = fp->buf;
                   4755: 
                   4756:     /* Read the file contents, knowing that st_size is an upper bound
                   4757:        on the number of bytes we can read.  */
1.1.1.7 ! root     4758:     fp->length = safe_read (f, fp->buf, st_size);
        !          4759:     if (fp->length < 0) goto nope;
1.1       root     4760:   }
1.1.1.5   root     4761:   else if (S_ISDIR (st_mode)) {
                   4762:     error ("directory `%s' specified in #include", fname);
                   4763:     close (f);
                   4764:     return;
                   4765:   } else {
1.1       root     4766:     /* Cannot count its file size before reading.
                   4767:        First read the entire file into heap and
                   4768:        copy them into buffer on stack. */
                   4769: 
                   4770:     int bsize = 2000;
                   4771: 
                   4772:     st_size = 0;
1.1.1.7 ! root     4773:     fp->buf = (U_CHAR *) xmalloc (bsize + 2);
1.1       root     4774: 
                   4775:     for (;;) {
1.1.1.7 ! root     4776:       i = safe_read (f, fp->buf + st_size, bsize - st_size);
1.1       root     4777:       if (i < 0)
                   4778:        goto nope;      /* error! */
                   4779:       st_size += i;
1.1.1.7 ! root     4780:       if (st_size != bsize)
        !          4781:        break;  /* End of file */
        !          4782:       bsize *= 2;
        !          4783:       fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
1.1       root     4784:     }
                   4785:     fp->bufp = fp->buf;
                   4786:     fp->length = st_size;
                   4787:   }
                   4788: 
1.1.1.5   root     4789:   if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
                   4790:       /* Backslash-newline at end is not good enough.  */
                   4791:       || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
                   4792:     fp->buf[fp->length++] = '\n';
                   4793:     missing_newline = 1;
                   4794:   }
                   4795:   fp->buf[fp->length] = '\0';
                   4796: 
1.1       root     4797:   /* Close descriptor now, so nesting does not use lots of descriptors.  */
                   4798:   close (f);
                   4799: 
1.1.1.4   root     4800:   /* Must do this before calling trigraph_pcp, so that the correct file name
                   4801:      will be printed in warning messages.  */
                   4802: 
                   4803:   indepth++;
                   4804:   input_file_stack_tick++;
                   4805: 
1.1       root     4806:   if (!no_trigraphs)
                   4807:     trigraph_pcp (fp);
                   4808: 
                   4809:   output_line_command (fp, op, 0, enter_file);
                   4810:   rescan (op, 0);
                   4811: 
1.1.1.5   root     4812:   if (missing_newline)
                   4813:     fp->lineno--;
                   4814: 
1.1       root     4815:   if (pedantic && missing_newline)
                   4816:     pedwarn ("file does not end in newline");
                   4817: 
                   4818:   indepth--;
                   4819:   input_file_stack_tick++;
                   4820:   output_line_command (&instack[indepth], op, 0, leave_file);
1.1.1.3   root     4821:   free (fp->buf);
1.1       root     4822:   return;
                   4823: 
                   4824:  nope:
                   4825: 
                   4826:   perror_with_name (fname);
                   4827:   close (f);
1.1.1.3   root     4828:   free (fp->buf);
1.1       root     4829: }
                   4830: 
                   4831: /* Record that inclusion of the file named FILE
                   4832:    should be controlled by the macro named MACRO_NAME.
                   4833:    This means that trying to include the file again
                   4834:    will do something if that macro is defined.  */
                   4835: 
                   4836: static void
                   4837: record_control_macro (file, macro_name)
                   4838:      char *file;
                   4839:      U_CHAR *macro_name;
                   4840: {
                   4841:   struct file_name_list *new;
                   4842: 
                   4843:   for (new = all_include_files; new; new = new->next) {
                   4844:     if (!strcmp (new->fname, file)) {
                   4845:       new->control_macro = macro_name;
                   4846:       return;
                   4847:     }
                   4848:   }
                   4849: 
                   4850:   /* If the file is not in all_include_files, something's wrong.  */
                   4851:   abort ();
                   4852: }
                   4853: 
                   4854: /* Maintain and search list of included files, for #import.  */
                   4855: 
                   4856: #define IMPORT_HASH_SIZE 31
                   4857: 
                   4858: struct import_file {
                   4859:   char *name;
                   4860:   ino_t inode;
                   4861:   dev_t dev;
                   4862:   struct import_file *next;
                   4863: };
                   4864: 
                   4865: /* Hash table of files already included with #include or #import.  */
                   4866: 
                   4867: static struct import_file *import_hash_table[IMPORT_HASH_SIZE];
                   4868: 
                   4869: /* Hash a file name for import_hash_table.  */
                   4870: 
                   4871: static int 
                   4872: import_hash (f)
                   4873:      char *f;
                   4874: {
                   4875:   int val = 0;
                   4876: 
                   4877:   while (*f) val += *f++;
                   4878:   return (val%IMPORT_HASH_SIZE);
                   4879: }
                   4880: 
                   4881: /* Search for file FILENAME in import_hash_table.
                   4882:    Return -2 if found, either a matching name or a matching inode.
                   4883:    Otherwise, open the file and return a file descriptor if successful
                   4884:    or -1 if unsuccessful.  */
                   4885: 
                   4886: static int
1.1.1.7 ! root     4887: lookup_import (filename, searchptr)
1.1       root     4888:      char *filename;
1.1.1.7 ! root     4889:      struct file_name_list *searchptr;
1.1       root     4890: {
                   4891:   struct import_file *i;
                   4892:   int h;
                   4893:   int hashval;
                   4894:   struct stat sb;
                   4895:   int fd;
                   4896: 
                   4897:   hashval = import_hash (filename);
                   4898: 
                   4899:   /* Attempt to find file in list of already included files */
                   4900:   i = import_hash_table[hashval];
                   4901: 
                   4902:   while (i) {
                   4903:     if (!strcmp (filename, i->name))
                   4904:       return -2;               /* return found */
                   4905:     i = i->next;
                   4906:   }
                   4907:   /* Open it and try a match on inode/dev */
1.1.1.7 ! root     4908:   fd = open_include_file (filename, searchptr);
1.1       root     4909:   if (fd < 0)
                   4910:     return fd;
                   4911:   fstat (fd, &sb);
                   4912:   for (h = 0; h < IMPORT_HASH_SIZE; h++) {
                   4913:     i = import_hash_table[h];
                   4914:     while (i) {
                   4915:       /* Compare the inode and the device.
                   4916:         Supposedly on some systems the inode is not a scalar.  */
1.1.1.7 ! root     4917:       if (!bcmp ((char *) &i->inode, (char *) &sb.st_ino, sizeof (sb.st_ino))
1.1       root     4918:          && i->dev == sb.st_dev) {
                   4919:         close (fd);
                   4920:         return -2;             /* return found */
                   4921:       }
                   4922:       i = i->next;
                   4923:     }
                   4924:   }
                   4925:   return fd;                   /* Not found, return open file */
                   4926: }
                   4927: 
                   4928: /* Add the file FNAME, open on descriptor FD, to import_hash_table.  */
                   4929: 
                   4930: static void
                   4931: add_import (fd, fname)
                   4932:      int fd;
                   4933:      char *fname;
                   4934: {
                   4935:   struct import_file *i;
                   4936:   int hashval;
                   4937:   struct stat sb;
                   4938: 
                   4939:   hashval = import_hash (fname);
                   4940:   fstat (fd, &sb);
                   4941:   i = (struct import_file *)xmalloc (sizeof (struct import_file));
                   4942:   i->name = (char *)xmalloc (strlen (fname)+1);
                   4943:   strcpy (i->name, fname);
1.1.1.7 ! root     4944:   bcopy ((char *) &sb.st_ino, (char *) &i->inode, sizeof (sb.st_ino));
1.1       root     4945:   i->dev = sb.st_dev;
                   4946:   i->next = import_hash_table[hashval];
                   4947:   import_hash_table[hashval] = i;
                   4948: }
                   4949: 
                   4950: /* Load the specified precompiled header into core, and verify its
                   4951:    preconditions.  PCF indicates the file descriptor to read, which must
                   4952:    be a regular file.  FNAME indicates the file name of the original 
                   4953:    header.  *LIMIT will be set to an address one past the end of the file.
                   4954:    If the preconditions of the file are not satisfied, the buffer is 
                   4955:    freed and we return 0.  If the preconditions are satisfied, return
                   4956:    the address of the buffer following the preconditions.  The buffer, in
                   4957:    this case, should never be freed because various pieces of it will
                   4958:    be referred to until all precompiled strings are output at the end of
                   4959:    the run.
                   4960: */
                   4961: static char *
                   4962: check_precompiled (pcf, fname, limit)
                   4963:      int pcf;
                   4964:      char *fname;
                   4965:      char **limit;
                   4966: {
                   4967:   int st_mode;
                   4968:   long st_size;
                   4969:   int length = 0;
                   4970:   char *buf;
                   4971:   char *cp;
                   4972: 
                   4973:   if (pcp_outfile)
                   4974:     return 0;
                   4975:   
                   4976:   if (file_size_and_mode (pcf, &st_mode, &st_size) < 0)
                   4977:     return 0;
                   4978: 
                   4979:   if (S_ISREG (st_mode))
                   4980:     {
                   4981:       buf = xmalloc (st_size + 2);
1.1.1.7 ! root     4982:       length = safe_read (pcf, buf, st_size);
        !          4983:       if (length < 0)
        !          4984:        goto nope;
1.1       root     4985:     }
                   4986:   else
                   4987:     abort ();
                   4988:     
                   4989:   if (length > 0 && buf[length-1] != '\n')
                   4990:     buf[length++] = '\n';
                   4991:   buf[length] = '\0';
                   4992:   
                   4993:   *limit = buf + length;
                   4994: 
                   4995:   /* File is in core.  Check the preconditions. */
                   4996:   if (!check_preconditions (buf))
                   4997:     goto nope;
                   4998:   for (cp = buf; *cp; cp++)
                   4999:     ;
                   5000: #ifdef DEBUG_PCP
                   5001:   fprintf (stderr, "Using preinclude %s\n", fname);
                   5002: #endif
                   5003:   return cp + 1;
                   5004: 
                   5005:  nope:
                   5006: #ifdef DEBUG_PCP
                   5007:   fprintf (stderr, "Cannot use preinclude %s\n", fname);
                   5008: #endif
                   5009:   free (buf);
                   5010:   return 0;
                   5011: }
                   5012: 
                   5013: /* PREC (null terminated) points to the preconditions of a
                   5014:    precompiled header.  These are a series of #define and #undef
                   5015:    lines which must match the current contents of the hash
                   5016:    table.  */
                   5017: static int 
                   5018: check_preconditions (prec)
                   5019:      char *prec;
                   5020: {
                   5021:   MACRODEF mdef;
                   5022:   char *lineend;
                   5023:   
                   5024:   while (*prec) {
                   5025:     lineend = (char *) index (prec, '\n');
                   5026:     
                   5027:     if (*prec++ != '#') {
                   5028:       error ("Bad format encountered while reading precompiled file");
                   5029:       return 0;
                   5030:     }
                   5031:     if (!strncmp (prec, "define", 6)) {
                   5032:       HASHNODE *hp;
                   5033:       
                   5034:       prec += 6;
1.1.1.4   root     5035:       mdef = create_definition (prec, lineend, NULL_PTR);
                   5036: 
1.1       root     5037:       if (mdef.defn == 0)
1.1.1.5   root     5038:        abort ();
1.1       root     5039:       
                   5040:       if ((hp = lookup (mdef.symnam, mdef.symlen, -1)) == NULL
                   5041:          || (hp->type != T_MACRO && hp->type != T_CONST)
                   5042:          || (hp->type == T_MACRO
                   5043:              && !compare_defs (mdef.defn, hp->value.defn)
                   5044:              && (mdef.defn->length != 2
                   5045:                  || mdef.defn->expansion[0] != '\n'
                   5046:                  || mdef.defn->expansion[1] != ' ')))
                   5047:        return 0;
                   5048:     } else if (!strncmp (prec, "undef", 5)) {
                   5049:       char *name;
                   5050:       int len;
                   5051:       
                   5052:       prec += 5;
1.1.1.5   root     5053:       while (is_hor_space[(U_CHAR) *prec])
1.1       root     5054:        prec++;
                   5055:       name = prec;
1.1.1.5   root     5056:       while (is_idchar[(U_CHAR) *prec])
1.1       root     5057:        prec++;
                   5058:       len = prec - name;
                   5059:       
                   5060:       if (lookup (name, len, -1))
                   5061:        return 0;
                   5062:     } else {
                   5063:       error ("Bad format encountered while reading precompiled file");
                   5064:       return 0;
                   5065:     }
                   5066:     prec = lineend + 1;
                   5067:   }
                   5068:   /* They all passed successfully */
                   5069:   return 1;
                   5070: }
                   5071: 
                   5072: /* Process the main body of a precompiled file.  BUF points to the
                   5073:    string section of the file, following the preconditions.  LIMIT is one
                   5074:    character past the end.  NAME is the name of the file being read
                   5075:    in.  OP is the main output buffer */
                   5076: static void
                   5077: pcfinclude (buf, limit, name, op)
                   5078:      U_CHAR *buf, *limit, *name;
                   5079:      FILE_BUF *op;
                   5080: {
                   5081:   FILE_BUF tmpbuf;
                   5082:   int nstrings;
                   5083:   U_CHAR *cp = buf;
                   5084: 
                   5085:   /* First in the file comes 4 bytes indicating the number of strings, */
                   5086:   /* in network byte order. (MSB first).  */
                   5087:   nstrings = *cp++;
                   5088:   nstrings = (nstrings << 8) | *cp++;
                   5089:   nstrings = (nstrings << 8) | *cp++;
                   5090:   nstrings = (nstrings << 8) | *cp++;
                   5091:   
                   5092:   /* Looping over each string... */
                   5093:   while (nstrings--) {
                   5094:     U_CHAR *string_start;
                   5095:     U_CHAR *endofthiskey;
                   5096:     STRINGDEF *str;
                   5097:     int nkeys;
                   5098:     
                   5099:     /* Each string starts with a STRINGDEF structure (str), followed */
                   5100:     /* by the text of the string (string_start) */
                   5101: 
                   5102:     /* First skip to a longword boundary */
1.1.1.4   root     5103:     /* ??? Why a 4-byte boundary?  On all machines? */
                   5104:     /* NOTE: This works correctly even if HOST_WIDE_INT
                   5105:        is narrower than a pointer.
                   5106:        Do not try risky measures here to get another type to use!
1.1.1.7 ! root     5107:        Do not include stddef.h--it will fail!  */
1.1.1.4   root     5108:     if ((HOST_WIDE_INT) cp & 3)
                   5109:       cp += 4 - ((HOST_WIDE_INT) cp & 3);
1.1       root     5110:     
                   5111:     /* Now get the string. */
                   5112:     str = (STRINGDEF *) cp;
                   5113:     string_start = cp += sizeof (STRINGDEF);
                   5114:     
                   5115:     for (; *cp; cp++)          /* skip the string */
                   5116:       ;
                   5117:     
                   5118:     /* We need to macro expand the string here to ensure that the
                   5119:        proper definition environment is in place.  If it were only
                   5120:        expanded when we find out it is needed, macros necessary for
                   5121:        its proper expansion might have had their definitions changed. */
                   5122:     tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0);
                   5123:     /* Lineno is already set in the precompiled file */
                   5124:     str->contents = tmpbuf.buf;
                   5125:     str->len = tmpbuf.length;
                   5126:     str->writeflag = 0;
                   5127:     str->filename = name;
                   5128:     str->output_mark = outbuf.bufp - outbuf.buf;
                   5129:     
                   5130:     str->chain = 0;
                   5131:     *stringlist_tailp = str;
                   5132:     stringlist_tailp = &str->chain;
                   5133:     
                   5134:     /* Next comes a fourbyte number indicating the number of keys */
                   5135:     /* for this string. */
                   5136:     nkeys = *cp++;
                   5137:     nkeys = (nkeys << 8) | *cp++;
                   5138:     nkeys = (nkeys << 8) | *cp++;
                   5139:     nkeys = (nkeys << 8) | *cp++;
                   5140: 
                   5141:     /* If this number is -1, then the string is mandatory. */
                   5142:     if (nkeys == -1)
                   5143:       str->writeflag = 1;
                   5144:     else
1.1.1.2   root     5145:       /* Otherwise, for each key, */
1.1       root     5146:       for (; nkeys--; free (tmpbuf.buf), cp = endofthiskey + 1) {
                   5147:        KEYDEF *kp = (KEYDEF *) cp;
                   5148:        HASHNODE *hp;
                   5149:        
                   5150:        /* It starts with a KEYDEF structure */
                   5151:        cp += sizeof (KEYDEF);
                   5152:        
                   5153:        /* Find the end of the key.  At the end of this for loop we
                   5154:           advance CP to the start of the next key using this variable. */
                   5155:        endofthiskey = cp + strlen (cp);
                   5156:        kp->str = str;
                   5157:        
                   5158:        /* Expand the key, and enter it into the hash table. */
                   5159:        tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0);
                   5160:        tmpbuf.bufp = tmpbuf.buf;
                   5161:        
                   5162:        while (is_hor_space[*tmpbuf.bufp])
                   5163:          tmpbuf.bufp++;
                   5164:        if (!is_idstart[*tmpbuf.bufp]
                   5165:            || tmpbuf.bufp == tmpbuf.buf + tmpbuf.length) {
                   5166:          str->writeflag = 1;
                   5167:          continue;
                   5168:        }
                   5169:            
                   5170:        hp = lookup (tmpbuf.bufp, -1, -1);
                   5171:        if (hp == NULL) {
                   5172:          kp->chain = 0;
1.1.1.4   root     5173:          install (tmpbuf.bufp, -1, T_PCSTRING, 0, (char *) kp, -1);
1.1       root     5174:        }
                   5175:        else if (hp->type == T_PCSTRING) {
                   5176:          kp->chain = hp->value.keydef;
                   5177:          hp->value.keydef = kp;
                   5178:        }
                   5179:        else
                   5180:          str->writeflag = 1;
                   5181:       }
                   5182:   }
                   5183:   /* This output_line_command serves to switch us back to the current
                   5184:      input file in case some of these strings get output (which will 
                   5185:      result in line commands for the header file being output). */
                   5186:   output_line_command (&instack[indepth], op, 0, enter_file);
                   5187: }
                   5188: 
                   5189: /* Called from rescan when it hits a key for strings.  Mark them all */
                   5190:  /* used and clean up. */
                   5191: static void
                   5192: pcstring_used (hp)
                   5193:      HASHNODE *hp;
                   5194: {
1.1.1.7 ! root     5195:   KEYDEF *kp;
1.1       root     5196:   
                   5197:   for (kp = hp->value.keydef; kp; kp = kp->chain)
                   5198:     kp->str->writeflag = 1;
                   5199:   delete_macro (hp);
                   5200: }
                   5201: 
                   5202: /* Write the output, interspersing precompiled strings in their */
                   5203:  /* appropriate places. */
                   5204: static void
                   5205: write_output ()
                   5206: {
                   5207:   STRINGDEF *next_string;
                   5208:   U_CHAR *cur_buf_loc;
                   5209:   int line_command_len = 80;
                   5210:   char *line_command = xmalloc (line_command_len);
                   5211:   int len;
                   5212: 
                   5213:   /* In each run through the loop, either cur_buf_loc == */
                   5214:   /* next_string_loc, in which case we print a series of strings, or */
                   5215:   /* it is less than next_string_loc, in which case we write some of */
                   5216:   /* the buffer. */
                   5217:   cur_buf_loc = outbuf.buf; 
                   5218:   next_string = stringlist;
                   5219:   
                   5220:   while (cur_buf_loc < outbuf.bufp || next_string) {
                   5221:     if (next_string
                   5222:        && cur_buf_loc - outbuf.buf == next_string->output_mark) {
                   5223:       if (next_string->writeflag) {
1.1.1.6   root     5224:        len = 4 * strlen (next_string->filename) + 32;
                   5225:        while (len > line_command_len)
1.1       root     5226:          line_command = xrealloc (line_command, 
                   5227:                                   line_command_len *= 2);
1.1.1.6   root     5228:        sprintf (line_command, "\n# %d ", next_string->lineno);
                   5229:        strcpy (quote_string (line_command + strlen (line_command),
                   5230:                              next_string->filename),
                   5231:                "\n");
                   5232:        safe_write (fileno (stdout), line_command, strlen (line_command));
                   5233:        safe_write (fileno (stdout), next_string->contents, next_string->len);
1.1       root     5234:       }              
                   5235:       next_string = next_string->chain;
                   5236:     }
                   5237:     else {
                   5238:       len = (next_string
                   5239:             ? (next_string->output_mark 
                   5240:                - (cur_buf_loc - outbuf.buf))
                   5241:             : outbuf.bufp - cur_buf_loc);
                   5242:       
1.1.1.6   root     5243:       safe_write (fileno (stdout), cur_buf_loc, len);
1.1       root     5244:       cur_buf_loc += len;
                   5245:     }
                   5246:   }
1.1.1.5   root     5247:   free (line_command);
1.1       root     5248: }
                   5249: 
                   5250: /* Pass a directive through to the output file.
1.1.1.2   root     5251:    BUF points to the contents of the directive, as a contiguous string.
1.1       root     5252:    LIMIT points to the first character past the end of the directive.
                   5253:    KEYWORD is the keyword-table entry for the directive.  */
                   5254: 
                   5255: static void
                   5256: pass_thru_directive (buf, limit, op, keyword)
                   5257:      U_CHAR *buf, *limit;
                   5258:      FILE_BUF *op;
                   5259:      struct directive *keyword;
                   5260: {
                   5261:   register unsigned keyword_length = keyword->length;
                   5262: 
                   5263:   check_expand (op, 1 + keyword_length + (limit - buf));
                   5264:   *op->bufp++ = '#';
1.1.1.7 ! root     5265:   bcopy (keyword->name, (char *) op->bufp, keyword_length);
1.1       root     5266:   op->bufp += keyword_length;
                   5267:   if (limit != buf && buf[0] != ' ')
                   5268:     *op->bufp++ = ' ';
1.1.1.7 ! root     5269:   bcopy ((char *) buf, (char *) op->bufp, limit - buf);
1.1       root     5270:   op->bufp += (limit - buf);
1.1.1.3   root     5271: #if 0
1.1       root     5272:   *op->bufp++ = '\n';
1.1.1.3   root     5273:   /* Count the line we have just made in the output,
                   5274:      to get in sync properly.  */
                   5275:   op->lineno++;
                   5276: #endif
1.1       root     5277: }
                   5278: 
                   5279: /* The arglist structure is built by do_define to tell
                   5280:    collect_definition where the argument names begin.  That
                   5281:    is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
                   5282:    would contain pointers to the strings x, y, and z.
                   5283:    Collect_definition would then build a DEFINITION node,
                   5284:    with reflist nodes pointing to the places x, y, and z had
                   5285:    appeared.  So the arglist is just convenience data passed
                   5286:    between these two routines.  It is not kept around after
                   5287:    the current #define has been processed and entered into the
                   5288:    hash table. */
                   5289: 
                   5290: struct arglist {
                   5291:   struct arglist *next;
                   5292:   U_CHAR *name;
                   5293:   int length;
                   5294:   int argno;
1.1.1.3   root     5295:   char rest_args;
1.1       root     5296: };
                   5297: 
                   5298: /* Create a DEFINITION node from a #define directive.  Arguments are 
                   5299:    as for do_define. */
                   5300: static MACRODEF
                   5301: create_definition (buf, limit, op)
                   5302:      U_CHAR *buf, *limit;
                   5303:      FILE_BUF *op;
                   5304: {
                   5305:   U_CHAR *bp;                  /* temp ptr into input buffer */
                   5306:   U_CHAR *symname;             /* remember where symbol name starts */
                   5307:   int sym_length;              /* and how long it is */
                   5308:   int line = instack[indepth].lineno;
                   5309:   char *file = instack[indepth].nominal_fname;
1.1.1.3   root     5310:   int rest_args = 0;
1.1       root     5311: 
                   5312:   DEFINITION *defn;
                   5313:   int arglengths = 0;          /* Accumulate lengths of arg names
                   5314:                                   plus number of args.  */
                   5315:   MACRODEF mdef;
                   5316: 
                   5317:   bp = buf;
                   5318: 
                   5319:   while (is_hor_space[*bp])
                   5320:     bp++;
                   5321: 
                   5322:   symname = bp;                        /* remember where it starts */
                   5323:   sym_length = check_macro_name (bp, "macro");
                   5324:   bp += sym_length;
                   5325: 
                   5326:   /* Lossage will occur if identifiers or control keywords are broken
                   5327:      across lines using backslash.  This is not the right place to take
                   5328:      care of that. */
                   5329: 
                   5330:   if (*bp == '(') {
                   5331:     struct arglist *arg_ptrs = NULL;
                   5332:     int argno = 0;
                   5333: 
                   5334:     bp++;                      /* skip '(' */
                   5335:     SKIP_WHITE_SPACE (bp);
                   5336: 
                   5337:     /* Loop over macro argument names.  */
                   5338:     while (*bp != ')') {
                   5339:       struct arglist *temp;
                   5340: 
                   5341:       temp = (struct arglist *) alloca (sizeof (struct arglist));
                   5342:       temp->name = bp;
                   5343:       temp->next = arg_ptrs;
                   5344:       temp->argno = argno++;
1.1.1.3   root     5345:       temp->rest_args = 0;
1.1       root     5346:       arg_ptrs = temp;
                   5347: 
1.1.1.3   root     5348:       if (rest_args)
                   5349:        pedwarn ("another parameter follows `%s'",
                   5350:                 rest_extension);
1.1       root     5351: 
1.1.1.3   root     5352:       if (!is_idstart[*bp])
                   5353:        pedwarn ("invalid character in macro parameter name");
                   5354:       
1.1       root     5355:       /* Find the end of the arg name.  */
                   5356:       while (is_idchar[*bp]) {
                   5357:        bp++;
1.1.1.3   root     5358:        /* do we have a "special" rest-args extension here? */
                   5359:        if (limit - bp > REST_EXTENSION_LENGTH &&
                   5360:            strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
                   5361:          rest_args = 1;
                   5362:          temp->rest_args = 1;
                   5363:          break;
                   5364:        }
1.1       root     5365:       }
                   5366:       temp->length = bp - temp->name;
1.1.1.3   root     5367:       if (rest_args == 1)
                   5368:        bp += REST_EXTENSION_LENGTH;
1.1       root     5369:       arglengths += temp->length + 2;
                   5370:       SKIP_WHITE_SPACE (bp);
                   5371:       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
                   5372:        error ("badly punctuated parameter list in `#define'");
                   5373:        goto nope;
                   5374:       }
                   5375:       if (*bp == ',') {
                   5376:        bp++;
                   5377:        SKIP_WHITE_SPACE (bp);
                   5378:       }
                   5379:       if (bp >= limit) {
                   5380:        error ("unterminated parameter list in `#define'");
                   5381:        goto nope;
                   5382:       }
                   5383:       {
                   5384:        struct arglist *otemp;
                   5385: 
                   5386:        for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
                   5387:          if (temp->length == otemp->length &&
1.1.1.5   root     5388:            strncmp (temp->name, otemp->name, temp->length) == 0) {
1.1       root     5389:              U_CHAR *name;
                   5390: 
1.1.1.5   root     5391:              name = (U_CHAR *) alloca (temp->length + 1);
                   5392:              (void) strncpy (name, temp->name, temp->length);
1.1       root     5393:              name[temp->length] = '\0';
                   5394:              error ("duplicate argument name `%s' in `#define'", name);
                   5395:              goto nope;
                   5396:          }
                   5397:       }
                   5398:     }
                   5399: 
                   5400:     ++bp;                      /* skip paren */
1.1.1.7 ! root     5401:     /* Skip spaces and tabs if any.  */
        !          5402:     while (bp < limit && (*bp == ' ' || *bp == '\t'))
        !          5403:       ++bp;
1.1       root     5404:     /* now everything from bp before limit is the definition. */
                   5405:     defn = collect_expansion (bp, limit, argno, arg_ptrs);
1.1.1.3   root     5406:     defn->rest_args = rest_args;
1.1       root     5407: 
                   5408:     /* Now set defn->args.argnames to the result of concatenating
                   5409:        the argument names in reverse order
                   5410:        with comma-space between them.  */
                   5411:     defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
                   5412:     {
                   5413:       struct arglist *temp;
                   5414:       int i = 0;
                   5415:       for (temp = arg_ptrs; temp; temp = temp->next) {
                   5416:        bcopy (temp->name, &defn->args.argnames[i], temp->length);
                   5417:        i += temp->length;
                   5418:        if (temp->next != 0) {
                   5419:          defn->args.argnames[i++] = ',';
                   5420:          defn->args.argnames[i++] = ' ';
                   5421:        }
                   5422:       }
                   5423:       defn->args.argnames[i] = 0;
                   5424:     }
                   5425:   } else {
1.1.1.7 ! root     5426:     /* Simple expansion or empty definition.  */
        !          5427: 
        !          5428:     if (bp < limit)
        !          5429:       {
        !          5430:        switch (*bp)
        !          5431:          {
        !          5432:            case '\t': case ' ': case '\r':
        !          5433:              /* Skip spaces and tabs.  */
        !          5434:              while (++bp < limit && (*bp == ' ' || *bp == '\t' || *bp == '\r'))
        !          5435:                continue;
        !          5436:              break;
        !          5437: 
        !          5438:            case '!':  case '"':  case '#':  case '%':  case '&':  case '\'':
        !          5439:            case ')':  case '*':  case '+':  case ',':  case '-':  case '.':
        !          5440:            case '/':  case ':':  case ';':  case '<':  case '=':  case '>':
        !          5441:            case '?':  case '[':  case '\\': case ']':  case '^':  case '{':
        !          5442:            case '|':  case '}':  case '~':
        !          5443:              warning ("missing white space after `#define %.*s'",
        !          5444:                       sym_length, symname);
        !          5445:              break;
        !          5446: 
        !          5447:            default:
        !          5448:              pedwarn ("missing white space after `#define %.*s'",
        !          5449:                       sym_length, symname);
        !          5450:              break;
        !          5451:          }
        !          5452:       }
        !          5453:     /* Now everything from bp before limit is the definition. */
1.1.1.4   root     5454:     defn = collect_expansion (bp, limit, -1, NULL_PTR);
1.1       root     5455:     defn->args.argnames = (U_CHAR *) "";
                   5456:   }
                   5457: 
                   5458:   defn->line = line;
                   5459:   defn->file = file;
                   5460: 
                   5461:   /* OP is null if this is a predefinition */
                   5462:   defn->predefined = !op;
                   5463:   mdef.defn = defn;
                   5464:   mdef.symnam = symname;
                   5465:   mdef.symlen = sym_length;
                   5466: 
                   5467:   return mdef;
                   5468: 
                   5469:  nope:
                   5470:   mdef.defn = 0;
                   5471:   return mdef;
                   5472: }
                   5473:  
                   5474: /* Process a #define command.
1.1.1.2   root     5475: BUF points to the contents of the #define command, as a contiguous string.
1.1       root     5476: LIMIT points to the first character past the end of the definition.
                   5477: KEYWORD is the keyword-table entry for #define.  */
                   5478: 
                   5479: static int
                   5480: do_define (buf, limit, op, keyword)
                   5481:      U_CHAR *buf, *limit;
                   5482:      FILE_BUF *op;
                   5483:      struct directive *keyword;
                   5484: {
                   5485:   int hashcode;
                   5486:   MACRODEF mdef;
                   5487: 
                   5488:   /* If this is a precompiler run (with -pcp) pass thru #define commands.  */
                   5489:   if (pcp_outfile && op)
                   5490:     pass_thru_directive (buf, limit, op, keyword);
                   5491: 
                   5492:   mdef = create_definition (buf, limit, op);
                   5493:   if (mdef.defn == 0)
                   5494:     goto nope;
                   5495: 
                   5496:   hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
                   5497: 
                   5498:   {
                   5499:     HASHNODE *hp;
                   5500:     if ((hp = lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) {
                   5501:       int ok = 0;
                   5502:       /* Redefining a precompiled key is ok.  */
                   5503:       if (hp->type == T_PCSTRING)
                   5504:        ok = 1;
                   5505:       /* Redefining a macro is ok if the definitions are the same.  */
                   5506:       else if (hp->type == T_MACRO)
                   5507:        ok = ! compare_defs (mdef.defn, hp->value.defn);
                   5508:       /* Redefining a constant is ok with -D.  */
                   5509:       else if (hp->type == T_CONST)
                   5510:         ok = ! done_initializing;
                   5511:       /* Print the warning if it's not ok.  */
                   5512:       if (!ok) {
                   5513:        U_CHAR *msg;            /* what pain... */
                   5514: 
                   5515:         /* If we are passing through #define and #undef directives, do
                   5516:           that for this re-definition now.  */
                   5517:         if (debug_output && op)
                   5518:          pass_thru_directive (buf, limit, op, keyword);
                   5519: 
                   5520:        msg = (U_CHAR *) alloca (mdef.symlen + 22);
                   5521:        *msg = '`';
1.1.1.7 ! root     5522:        bcopy ((char *) mdef.symnam, (char *) (msg + 1), mdef.symlen);
1.1       root     5523:        strcpy ((char *) (msg + mdef.symlen + 1), "' redefined");
                   5524:        pedwarn (msg);
                   5525:        if (hp->type == T_MACRO)
                   5526:          pedwarn_with_file_and_line (hp->value.defn->file, hp->value.defn->line,
                   5527:                                      "this is the location of the previous definition");
                   5528:       }
                   5529:       /* Replace the old definition.  */
                   5530:       hp->type = T_MACRO;
                   5531:       hp->value.defn = mdef.defn;
                   5532:     } else {
                   5533:       /* If we are passing through #define and #undef directives, do
                   5534:         that for this new definition now.  */
                   5535:       if (debug_output && op)
                   5536:        pass_thru_directive (buf, limit, op, keyword);
1.1.1.4   root     5537:       install (mdef.symnam, mdef.symlen, T_MACRO, 0,
                   5538:               (char *) mdef.defn, hashcode);
1.1       root     5539:     }
                   5540:   }
                   5541: 
                   5542:   return 0;
                   5543: 
                   5544: nope:
                   5545: 
                   5546:   return 1;
                   5547: }
                   5548: 
                   5549: /* Check a purported macro name SYMNAME, and yield its length.
                   5550:    USAGE is the kind of name this is intended for.  */
                   5551: 
                   5552: static int
                   5553: check_macro_name (symname, usage)
                   5554:      U_CHAR *symname;
                   5555:      char *usage;
                   5556: {
                   5557:   U_CHAR *p;
                   5558:   int sym_length;
                   5559: 
                   5560:   for (p = symname; is_idchar[*p]; p++)
                   5561:     ;
                   5562:   sym_length = p - symname;
                   5563:   if (sym_length == 0)
                   5564:     error ("invalid %s name", usage);
                   5565:   else if (!is_idstart[*symname]) {
                   5566:     U_CHAR *msg;                       /* what pain... */
                   5567:     msg = (U_CHAR *) alloca (sym_length + 1);
1.1.1.7 ! root     5568:     bcopy ((char *) symname, (char *) msg, sym_length);
1.1       root     5569:     msg[sym_length] = 0;
                   5570:     error ("invalid %s name `%s'", usage, msg);
                   5571:   } else {
                   5572:     if (! strncmp (symname, "defined", 7) && sym_length == 7)
                   5573:       error ("invalid %s name `defined'", usage);
                   5574:   }
                   5575:   return sym_length;
                   5576: }
                   5577: 
                   5578: /*
                   5579:  * return zero if two DEFINITIONs are isomorphic
                   5580:  */
                   5581: static int
                   5582: compare_defs (d1, d2)
                   5583:      DEFINITION *d1, *d2;
                   5584: {
                   5585:   register struct reflist *a1, *a2;
                   5586:   register U_CHAR *p1 = d1->expansion;
                   5587:   register U_CHAR *p2 = d2->expansion;
                   5588:   int first = 1;
                   5589: 
                   5590:   if (d1->nargs != d2->nargs)
                   5591:     return 1;
                   5592:   if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames))
                   5593:     return 1;
                   5594:   for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
                   5595:        a1 = a1->next, a2 = a2->next) {
                   5596:     if (!((a1->nchars == a2->nchars && ! strncmp (p1, p2, a1->nchars))
                   5597:          || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
                   5598:        || a1->argno != a2->argno
                   5599:        || a1->stringify != a2->stringify
                   5600:        || a1->raw_before != a2->raw_before
                   5601:        || a1->raw_after != a2->raw_after)
                   5602:       return 1;
                   5603:     first = 0;
                   5604:     p1 += a1->nchars;
                   5605:     p2 += a2->nchars;
                   5606:   }
                   5607:   if (a1 != a2)
                   5608:     return 1;
                   5609:   if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
                   5610:                     p2, d2->length - (p2 - d2->expansion), 1))
                   5611:     return 1;
                   5612:   return 0;
                   5613: }
                   5614: 
                   5615: /* Return 1 if two parts of two macro definitions are effectively different.
                   5616:    One of the parts starts at BEG1 and has LEN1 chars;
                   5617:    the other has LEN2 chars at BEG2.
                   5618:    Any sequence of whitespace matches any other sequence of whitespace.
                   5619:    FIRST means these parts are the first of a macro definition;
                   5620:     so ignore leading whitespace entirely.
                   5621:    LAST means these parts are the last of a macro definition;
                   5622:     so ignore trailing whitespace entirely.  */
                   5623: 
                   5624: static int
                   5625: comp_def_part (first, beg1, len1, beg2, len2, last)
                   5626:      int first;
                   5627:      U_CHAR *beg1, *beg2;
                   5628:      int len1, len2;
                   5629:      int last;
                   5630: {
                   5631:   register U_CHAR *end1 = beg1 + len1;
                   5632:   register U_CHAR *end2 = beg2 + len2;
                   5633:   if (first) {
                   5634:     while (beg1 != end1 && is_space[*beg1]) beg1++;
                   5635:     while (beg2 != end2 && is_space[*beg2]) beg2++;
                   5636:   }
                   5637:   if (last) {
                   5638:     while (beg1 != end1 && is_space[end1[-1]]) end1--;
                   5639:     while (beg2 != end2 && is_space[end2[-1]]) end2--;
                   5640:   }
                   5641:   while (beg1 != end1 && beg2 != end2) {
                   5642:     if (is_space[*beg1] && is_space[*beg2]) {
                   5643:       while (beg1 != end1 && is_space[*beg1]) beg1++;
                   5644:       while (beg2 != end2 && is_space[*beg2]) beg2++;
                   5645:     } else if (*beg1 == *beg2) {
                   5646:       beg1++; beg2++;
                   5647:     } else break;
                   5648:   }
                   5649:   return (beg1 != end1) || (beg2 != end2);
                   5650: }
                   5651: 
                   5652: /* Read a replacement list for a macro with parameters.
                   5653:    Build the DEFINITION structure.
                   5654:    Reads characters of text starting at BUF until END.
                   5655:    ARGLIST specifies the formal parameters to look for
                   5656:    in the text of the definition; NARGS is the number of args
                   5657:    in that list, or -1 for a macro name that wants no argument list.
                   5658:    MACRONAME is the macro name itself (so we can avoid recursive expansion)
                   5659:    and NAMELEN is its length in characters.
                   5660:    
                   5661: Note that comments and backslash-newlines have already been deleted
                   5662: from the argument.  */
                   5663: 
                   5664: /* Leading and trailing Space, Tab, etc. are converted to markers
                   5665:    Newline Space, Newline Tab, etc.
                   5666:    Newline Space makes a space in the final output
                   5667:    but is discarded if stringified.  (Newline Tab is similar but
                   5668:    makes a Tab instead.)
                   5669: 
                   5670:    If there is no trailing whitespace, a Newline Space is added at the end
                   5671:    to prevent concatenation that would be contrary to the standard.  */
                   5672: 
                   5673: static DEFINITION *
                   5674: collect_expansion (buf, end, nargs, arglist)
                   5675:      U_CHAR *buf, *end;
                   5676:      int nargs;
                   5677:      struct arglist *arglist;
                   5678: {
                   5679:   DEFINITION *defn;
                   5680:   register U_CHAR *p, *limit, *lastp, *exp_p;
                   5681:   struct reflist *endpat = NULL;
                   5682:   /* Pointer to first nonspace after last ## seen.  */
                   5683:   U_CHAR *concat = 0;
                   5684:   /* Pointer to first nonspace after last single-# seen.  */
                   5685:   U_CHAR *stringify = 0;
                   5686:   int maxsize;
                   5687:   int expected_delimiter = '\0';
                   5688: 
                   5689:   /* Scan thru the replacement list, ignoring comments and quoted
                   5690:      strings, picking up on the macro calls.  It does a linear search
                   5691:      thru the arg list on every potential symbol.  Profiling might say
                   5692:      that something smarter should happen. */
                   5693: 
                   5694:   if (end < buf)
                   5695:     abort ();
                   5696: 
                   5697:   /* Find the beginning of the trailing whitespace.  */
                   5698:   /* Find end of leading whitespace.  */
                   5699:   limit = end;
                   5700:   p = buf;
                   5701:   while (p < limit && is_space[limit[-1]]) limit--;
                   5702:   while (p < limit && is_space[*p]) p++;
                   5703: 
                   5704:   /* Allocate space for the text in the macro definition.
                   5705:      Leading and trailing whitespace chars need 2 bytes each.
                   5706:      Each other input char may or may not need 1 byte,
                   5707:      so this is an upper bound.
                   5708:      The extra 2 are for invented trailing newline-marker and final null.  */
                   5709:   maxsize = (sizeof (DEFINITION)
                   5710:             + 2 * (end - limit) + 2 * (p - buf)
                   5711:             + (limit - p) + 3);
                   5712:   defn = (DEFINITION *) xcalloc (1, maxsize);
                   5713: 
                   5714:   defn->nargs = nargs;
                   5715:   exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
                   5716:   lastp = exp_p;
                   5717: 
                   5718:   p = buf;
                   5719: 
                   5720:   /* Convert leading whitespace to Newline-markers.  */
                   5721:   while (p < limit && is_space[*p]) {
                   5722:     *exp_p++ = '\n';
                   5723:     *exp_p++ = *p++;
                   5724:   }
                   5725: 
                   5726:   if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
                   5727:     error ("`##' at start of macro definition");
                   5728:     p += 2;
                   5729:   }
                   5730: 
                   5731:   /* Process the main body of the definition.  */
                   5732:   while (p < limit) {
                   5733:     int skipped_arg = 0;
                   5734:     register U_CHAR c = *p++;
                   5735: 
                   5736:     *exp_p++ = c;
                   5737: 
                   5738:     if (!traditional) {
                   5739:       switch (c) {
                   5740:       case '\'':
                   5741:       case '\"':
                   5742:         if (expected_delimiter != '\0') {
                   5743:           if (c == expected_delimiter)
                   5744:             expected_delimiter = '\0';
                   5745:         } else
                   5746:           expected_delimiter = c;
                   5747:        break;
                   5748: 
                   5749:       case '\\':
1.1.1.7 ! root     5750:        if (p < limit && expected_delimiter) {
1.1       root     5751:          /* In a string, backslash goes through
                   5752:             and makes next char ordinary.  */
                   5753:          *exp_p++ = *p++;
                   5754:        }
                   5755:        break;
                   5756: 
                   5757:       case '#':
                   5758:        /* # is ordinary inside a string.  */
                   5759:        if (expected_delimiter)
                   5760:          break;
                   5761:        if (p < limit && *p == '#') {
                   5762:          /* ##: concatenate preceding and following tokens.  */
                   5763:          /* Take out the first #, discard preceding whitespace.  */
                   5764:          exp_p--;
                   5765:          while (exp_p > lastp && is_hor_space[exp_p[-1]])
                   5766:            --exp_p;
                   5767:          /* Skip the second #.  */
                   5768:          p++;
                   5769:          /* Discard following whitespace.  */
                   5770:          SKIP_WHITE_SPACE (p);
                   5771:          concat = p;
                   5772:          if (p == limit)
                   5773:            error ("`##' at end of macro definition");
1.1.1.5   root     5774:        } else if (nargs >= 0) {
1.1       root     5775:          /* Single #: stringify following argument ref.
                   5776:             Don't leave the # in the expansion.  */
                   5777:          exp_p--;
                   5778:          SKIP_WHITE_SPACE (p);
1.1.1.5   root     5779:          if (p == limit || ! is_idstart[*p])
1.1       root     5780:            error ("`#' operator is not followed by a macro argument name");
                   5781:          else
                   5782:            stringify = p;
                   5783:        }
                   5784:        break;
                   5785:       }
                   5786:     } else {
                   5787:       /* In -traditional mode, recognize arguments inside strings and
                   5788:         and character constants, and ignore special properties of #.
                   5789:         Arguments inside strings are considered "stringified", but no
                   5790:         extra quote marks are supplied.  */
                   5791:       switch (c) {
                   5792:       case '\'':
                   5793:       case '\"':
                   5794:        if (expected_delimiter != '\0') {
                   5795:          if (c == expected_delimiter)
                   5796:            expected_delimiter = '\0';
                   5797:        } else
                   5798:          expected_delimiter = c;
                   5799:        break;
                   5800: 
                   5801:       case '\\':
                   5802:        /* Backslash quotes delimiters and itself, but not macro args.  */
                   5803:        if (expected_delimiter != 0 && p < limit
                   5804:            && (*p == expected_delimiter || *p == '\\')) {
                   5805:          *exp_p++ = *p++;
                   5806:          continue;
                   5807:        }
                   5808:        break;
                   5809: 
                   5810:       case '/':
                   5811:        if (expected_delimiter != '\0') /* No comments inside strings.  */
                   5812:          break;
                   5813:        if (*p == '*') {
                   5814:          /* If we find a comment that wasn't removed by handle_directive,
                   5815:             this must be -traditional.  So replace the comment with
                   5816:             nothing at all.  */
                   5817:          exp_p--;
                   5818:          p += 1;
                   5819:          while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
                   5820:            p++;
                   5821: #if 0
                   5822:          /* Mark this as a concatenation-point, as if it had been ##.  */
                   5823:          concat = p;
                   5824: #endif
                   5825:        }
                   5826:        break;
                   5827:       }
                   5828:     }
                   5829: 
                   5830:     /* Handle the start of a symbol.  */
                   5831:     if (is_idchar[c] && nargs > 0) {
                   5832:       U_CHAR *id_beg = p - 1;
                   5833:       int id_len;
                   5834: 
                   5835:       --exp_p;
                   5836:       while (p != limit && is_idchar[*p]) p++;
                   5837:       id_len = p - id_beg;
                   5838: 
                   5839:       if (is_idstart[c]) {
                   5840:        register struct arglist *arg;
                   5841: 
                   5842:        for (arg = arglist; arg != NULL; arg = arg->next) {
                   5843:          struct reflist *tpat;
                   5844: 
                   5845:          if (arg->name[0] == c
                   5846:              && arg->length == id_len
                   5847:              && strncmp (arg->name, id_beg, id_len) == 0) {
                   5848:            if (expected_delimiter && warn_stringify) {
                   5849:              if (traditional) {
                   5850:                warning ("macro argument `%.*s' is stringified.",
                   5851:                         id_len, arg->name);
                   5852:              } else {
                   5853:                warning ("macro arg `%.*s' would be stringified with -traditional.",
                   5854:                         id_len, arg->name);
                   5855:              }
                   5856:            }
                   5857:            /* If ANSI, don't actually substitute inside a string.  */
                   5858:            if (!traditional && expected_delimiter)
                   5859:              break;
                   5860:            /* make a pat node for this arg and append it to the end of
                   5861:               the pat list */
                   5862:            tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
                   5863:            tpat->next = NULL;
                   5864:            tpat->raw_before = concat == id_beg;
                   5865:            tpat->raw_after = 0;
1.1.1.3   root     5866:            tpat->rest_args = arg->rest_args;
1.1       root     5867:            tpat->stringify = (traditional ? expected_delimiter != '\0'
                   5868:                               : stringify == id_beg);
                   5869: 
                   5870:            if (endpat == NULL)
                   5871:              defn->pattern = tpat;
                   5872:            else
                   5873:              endpat->next = tpat;
                   5874:            endpat = tpat;
                   5875: 
                   5876:            tpat->argno = arg->argno;
                   5877:            tpat->nchars = exp_p - lastp;
                   5878:            {
                   5879:              register U_CHAR *p1 = p;
                   5880:              SKIP_WHITE_SPACE (p1);
                   5881:              if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
                   5882:                tpat->raw_after = 1;
                   5883:            }
                   5884:            lastp = exp_p;      /* place to start copying from next time */
                   5885:            skipped_arg = 1;
                   5886:            break;
                   5887:          }
                   5888:        }
                   5889:       }
                   5890: 
                   5891:       /* If this was not a macro arg, copy it into the expansion.  */
                   5892:       if (! skipped_arg) {
                   5893:        register U_CHAR *lim1 = p;
                   5894:        p = id_beg;
                   5895:        while (p != lim1)
                   5896:          *exp_p++ = *p++;
                   5897:        if (stringify == id_beg)
                   5898:          error ("`#' operator should be followed by a macro argument name");
                   5899:       }
                   5900:     }
                   5901:   }
                   5902: 
1.1.1.7 ! root     5903:   if (!traditional && expected_delimiter == 0) {
1.1.1.4   root     5904:     /* There is no trailing whitespace, so invent some in ANSI mode.
                   5905:        But not if "inside a string" (which in ANSI mode
                   5906:        happens only for -D option).  */
1.1       root     5907:     *exp_p++ = '\n';
                   5908:     *exp_p++ = ' ';
                   5909:   }
                   5910: 
                   5911:   *exp_p = '\0';
                   5912: 
                   5913:   defn->length = exp_p - defn->expansion;
                   5914: 
                   5915:   /* Crash now if we overrun the allocated size.  */
                   5916:   if (defn->length + 1 > maxsize)
                   5917:     abort ();
                   5918: 
                   5919: #if 0
                   5920: /* This isn't worth the time it takes.  */
                   5921:   /* give back excess storage */
                   5922:   defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
                   5923: #endif
                   5924: 
                   5925:   return defn;
                   5926: }
                   5927: 
                   5928: static int
                   5929: do_assert (buf, limit, op, keyword)
                   5930:      U_CHAR *buf, *limit;
                   5931:      FILE_BUF *op;
                   5932:      struct directive *keyword;
                   5933: {
                   5934:   U_CHAR *bp;                  /* temp ptr into input buffer */
                   5935:   U_CHAR *symname;             /* remember where symbol name starts */
                   5936:   int sym_length;              /* and how long it is */
                   5937:   struct arglist *tokens = NULL;
                   5938: 
                   5939:   if (pedantic && done_initializing && !instack[indepth].system_header_p)
                   5940:     pedwarn ("ANSI C does not allow `#assert'");
                   5941: 
                   5942:   bp = buf;
                   5943: 
                   5944:   while (is_hor_space[*bp])
                   5945:     bp++;
                   5946: 
                   5947:   symname = bp;                        /* remember where it starts */
                   5948:   sym_length = check_macro_name (bp, "assertion");
                   5949:   bp += sym_length;
                   5950:   /* #define doesn't do this, but we should.  */
                   5951:   SKIP_WHITE_SPACE (bp);
                   5952: 
                   5953:   /* Lossage will occur if identifiers or control tokens are broken
                   5954:      across lines using backslash.  This is not the right place to take
                   5955:      care of that. */
                   5956: 
                   5957:   if (*bp != '(') {
                   5958:     error ("missing token-sequence in `#assert'");
                   5959:     return 1;
                   5960:   }
                   5961: 
                   5962:   {
                   5963:     int error_flag = 0;
                   5964: 
                   5965:     bp++;                      /* skip '(' */
                   5966:     SKIP_WHITE_SPACE (bp);
                   5967: 
                   5968:     tokens = read_token_list (&bp, limit, &error_flag);
                   5969:     if (error_flag)
                   5970:       return 1;
                   5971:     if (tokens == 0) {
                   5972:       error ("empty token-sequence in `#assert'");
                   5973:       return 1;
                   5974:     }
                   5975: 
                   5976:     ++bp;                      /* skip paren */
                   5977:     SKIP_WHITE_SPACE (bp);
                   5978:   }
                   5979: 
                   5980:   /* If this name isn't already an assertion name, make it one.
                   5981:      Error if it was already in use in some other way.  */
                   5982: 
                   5983:   {
                   5984:     ASSERTION_HASHNODE *hp;
                   5985:     int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
                   5986:     struct tokenlist_list *value
                   5987:       = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list));
                   5988: 
                   5989:     hp = assertion_lookup (symname, sym_length, hashcode);
                   5990:     if (hp == NULL) {
                   5991:       if (sym_length == 7 && ! strncmp (symname, "defined", sym_length))
                   5992:        error ("`defined' redefined as assertion");
                   5993:       hp = assertion_install (symname, sym_length, hashcode);
                   5994:     }
                   5995: 
                   5996:     /* Add the spec'd token-sequence to the list of such.  */
                   5997:     value->tokens = tokens;
                   5998:     value->next = hp->value;
                   5999:     hp->value = value;
                   6000:   }
                   6001: 
                   6002:   return 0;
                   6003: }
                   6004: 
                   6005: static int
                   6006: do_unassert (buf, limit, op, keyword)
                   6007:      U_CHAR *buf, *limit;
                   6008:      FILE_BUF *op;
                   6009:      struct directive *keyword;
                   6010: {
                   6011:   U_CHAR *bp;                  /* temp ptr into input buffer */
                   6012:   U_CHAR *symname;             /* remember where symbol name starts */
                   6013:   int sym_length;              /* and how long it is */
                   6014: 
                   6015:   struct arglist *tokens = NULL;
                   6016:   int tokens_specified = 0;
                   6017: 
                   6018:   if (pedantic && done_initializing && !instack[indepth].system_header_p)
                   6019:     pedwarn ("ANSI C does not allow `#unassert'");
                   6020: 
                   6021:   bp = buf;
                   6022: 
                   6023:   while (is_hor_space[*bp])
                   6024:     bp++;
                   6025: 
                   6026:   symname = bp;                        /* remember where it starts */
                   6027:   sym_length = check_macro_name (bp, "assertion");
                   6028:   bp += sym_length;
                   6029:   /* #define doesn't do this, but we should.  */
                   6030:   SKIP_WHITE_SPACE (bp);
                   6031: 
                   6032:   /* Lossage will occur if identifiers or control tokens are broken
                   6033:      across lines using backslash.  This is not the right place to take
                   6034:      care of that. */
                   6035: 
                   6036:   if (*bp == '(') {
                   6037:     int error_flag = 0;
                   6038: 
                   6039:     bp++;                      /* skip '(' */
                   6040:     SKIP_WHITE_SPACE (bp);
                   6041: 
                   6042:     tokens = read_token_list (&bp, limit, &error_flag);
                   6043:     if (error_flag)
                   6044:       return 1;
                   6045:     if (tokens == 0) {
                   6046:       error ("empty token list in `#unassert'");
                   6047:       return 1;
                   6048:     }
                   6049: 
                   6050:     tokens_specified = 1;
                   6051: 
                   6052:     ++bp;                      /* skip paren */
                   6053:     SKIP_WHITE_SPACE (bp);
                   6054:   }
                   6055: 
                   6056:   {
                   6057:     ASSERTION_HASHNODE *hp;
                   6058:     int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
                   6059:     struct tokenlist_list *tail, *prev;
                   6060: 
                   6061:     hp = assertion_lookup (symname, sym_length, hashcode);
                   6062:     if (hp == NULL)
                   6063:       return 1;
                   6064: 
                   6065:     /* If no token list was specified, then eliminate this assertion
                   6066:        entirely.  */
                   6067:     if (! tokens_specified) {
                   6068:       struct tokenlist_list *next;
                   6069:       for (tail = hp->value; tail; tail = next) {
                   6070:        next = tail->next;
                   6071:        free_token_list (tail->tokens);
                   6072:        free (tail);
                   6073:       }
                   6074:       delete_assertion (hp);
                   6075:     } else {
                   6076:       /* If a list of tokens was given, then delete any matching list.  */
                   6077: 
                   6078:       tail = hp->value;
                   6079:       prev = 0;
                   6080:       while (tail) {
                   6081:        struct tokenlist_list *next = tail->next;
                   6082:        if (compare_token_lists (tail->tokens, tokens)) {
                   6083:          if (prev)
                   6084:            prev->next = next;
                   6085:          else
                   6086:            hp->value = tail->next;
                   6087:          free_token_list (tail->tokens);
                   6088:          free (tail);
                   6089:        } else {
                   6090:          prev = tail;
                   6091:        }
                   6092:        tail = next;
                   6093:       }
                   6094:     }
                   6095:   }
                   6096: 
                   6097:   return 0;
                   6098: }
                   6099: 
                   6100: /* Test whether there is an assertion named NAME
                   6101:    and optionally whether it has an asserted token list TOKENS.
                   6102:    NAME is not null terminated; its length is SYM_LENGTH.
                   6103:    If TOKENS_SPECIFIED is 0, then don't check for any token list.  */
                   6104: 
                   6105: int
                   6106: check_assertion (name, sym_length, tokens_specified, tokens)
                   6107:      U_CHAR *name;
                   6108:      int sym_length;
                   6109:      int tokens_specified;
                   6110:      struct arglist *tokens;
                   6111: {
                   6112:   ASSERTION_HASHNODE *hp;
                   6113:   int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE);
                   6114: 
                   6115:   if (pedantic && !instack[indepth].system_header_p)
                   6116:     pedwarn ("ANSI C does not allow testing assertions");
                   6117: 
                   6118:   hp = assertion_lookup (name, sym_length, hashcode);
                   6119:   if (hp == NULL)
                   6120:     /* It is not an assertion; just return false.  */
                   6121:     return 0;
                   6122: 
                   6123:   /* If no token list was specified, then value is 1.  */
                   6124:   if (! tokens_specified)
                   6125:     return 1;
                   6126: 
                   6127:   {
                   6128:     struct tokenlist_list *tail;
                   6129: 
                   6130:     tail = hp->value;
                   6131: 
                   6132:     /* If a list of tokens was given,
                   6133:        then succeed if the assertion records a matching list.  */
                   6134: 
                   6135:     while (tail) {
                   6136:       if (compare_token_lists (tail->tokens, tokens))
                   6137:        return 1;
                   6138:       tail = tail->next;
                   6139:     }
                   6140: 
                   6141:     /* Fail if the assertion has no matching list.  */
                   6142:     return 0;
                   6143:   }
                   6144: }
                   6145: 
                   6146: /* Compare two lists of tokens for equality including order of tokens.  */
                   6147: 
                   6148: static int
                   6149: compare_token_lists (l1, l2)
                   6150:      struct arglist *l1, *l2;
                   6151: {
                   6152:   while (l1 && l2) {
                   6153:     if (l1->length != l2->length)
                   6154:       return 0;
                   6155:     if (strncmp (l1->name, l2->name, l1->length))
                   6156:       return 0;
                   6157:     l1 = l1->next;
                   6158:     l2 = l2->next;
                   6159:   }
                   6160: 
                   6161:   /* Succeed if both lists end at the same time.  */
                   6162:   return l1 == l2;
                   6163: }
                   6164: 
                   6165: /* Read a space-separated list of tokens ending in a close parenthesis.
                   6166:    Return a list of strings, in the order they were written.
                   6167:    (In case of error, return 0 and store -1 in *ERROR_FLAG.)
                   6168:    Parse the text starting at *BPP, and update *BPP.
                   6169:    Don't parse beyond LIMIT.  */
                   6170: 
                   6171: static struct arglist *
                   6172: read_token_list (bpp, limit, error_flag)
                   6173:      U_CHAR **bpp;
                   6174:      U_CHAR *limit;
                   6175:      int *error_flag;
                   6176: {
                   6177:   struct arglist *token_ptrs = 0;
                   6178:   U_CHAR *bp = *bpp;
                   6179:   int depth = 1;
                   6180: 
                   6181:   *error_flag = 0;
                   6182: 
                   6183:   /* Loop over the assertion value tokens.  */
                   6184:   while (depth > 0) {
                   6185:     struct arglist *temp;
                   6186:     int eofp = 0;
                   6187:     U_CHAR *beg = bp;
                   6188: 
                   6189:     /* Find the end of the token.  */
                   6190:     if (*bp == '(') {
                   6191:       bp++;
                   6192:       depth++;
                   6193:     } else if (*bp == ')') {
                   6194:       depth--;
                   6195:       if (depth == 0)
                   6196:        break;
                   6197:       bp++;
                   6198:     } else if (*bp == '"' || *bp == '\'')
1.1.1.4   root     6199:       bp = skip_quoted_string (bp, limit, 0, NULL_PTR, NULL_PTR, &eofp);
1.1       root     6200:     else
                   6201:       while (! is_hor_space[*bp] && *bp != '(' && *bp != ')'
                   6202:             && *bp != '"' && *bp != '\'' && bp != limit)
                   6203:        bp++;
                   6204: 
                   6205:     temp = (struct arglist *) xmalloc (sizeof (struct arglist));
                   6206:     temp->name = (U_CHAR *) xmalloc (bp - beg + 1);
1.1.1.7 ! root     6207:     bcopy ((char *) beg, (char *) temp->name, bp - beg);
1.1       root     6208:     temp->name[bp - beg] = 0;
                   6209:     temp->next = token_ptrs;
                   6210:     token_ptrs = temp;
                   6211:     temp->length = bp - beg;
                   6212: 
                   6213:     SKIP_WHITE_SPACE (bp);
                   6214: 
                   6215:     if (bp >= limit) {
                   6216:       error ("unterminated token sequence in `#assert' or `#unassert'");
                   6217:       *error_flag = -1;
                   6218:       return 0;
                   6219:     }
                   6220:   }
                   6221:   *bpp = bp;
                   6222: 
                   6223:   /* We accumulated the names in reverse order.
                   6224:      Now reverse them to get the proper order.  */
                   6225:   {
                   6226:     register struct arglist *prev = 0, *this, *next;
                   6227:     for (this = token_ptrs; this; this = next) {
                   6228:       next = this->next;
                   6229:       this->next = prev;
                   6230:       prev = this;
                   6231:     }
                   6232:     return prev;
                   6233:   }
                   6234: }
                   6235: 
                   6236: static void
                   6237: free_token_list (tokens)
                   6238:      struct arglist *tokens;
                   6239: {
                   6240:   while (tokens) {
                   6241:     struct arglist *next = tokens->next;
                   6242:     free (tokens->name);
                   6243:     free (tokens);
                   6244:     tokens = next;
                   6245:   }
                   6246: }
                   6247: 
                   6248: /*
                   6249:  * Install a name in the assertion hash table.
                   6250:  *
                   6251:  * If LEN is >= 0, it is the length of the name.
                   6252:  * Otherwise, compute the length by scanning the entire name.
                   6253:  *
                   6254:  * If HASH is >= 0, it is the precomputed hash code.
                   6255:  * Otherwise, compute the hash code.
                   6256:  */
                   6257: static ASSERTION_HASHNODE *
                   6258: assertion_install (name, len, hash)
                   6259:      U_CHAR *name;
                   6260:      int len;
                   6261:      int hash;
                   6262: {
                   6263:   register ASSERTION_HASHNODE *hp;
                   6264:   register int i, bucket;
                   6265:   register U_CHAR *p, *q;
                   6266: 
                   6267:   i = sizeof (ASSERTION_HASHNODE) + len + 1;
                   6268:   hp = (ASSERTION_HASHNODE *) xmalloc (i);
                   6269:   bucket = hash;
                   6270:   hp->bucket_hdr = &assertion_hashtab[bucket];
                   6271:   hp->next = assertion_hashtab[bucket];
                   6272:   assertion_hashtab[bucket] = hp;
                   6273:   hp->prev = NULL;
                   6274:   if (hp->next != NULL)
                   6275:     hp->next->prev = hp;
                   6276:   hp->length = len;
                   6277:   hp->value = 0;
                   6278:   hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE);
                   6279:   p = hp->name;
                   6280:   q = name;
                   6281:   for (i = 0; i < len; i++)
                   6282:     *p++ = *q++;
                   6283:   hp->name[len] = 0;
                   6284:   return hp;
                   6285: }
                   6286: 
                   6287: /*
                   6288:  * find the most recent hash node for name name (ending with first
                   6289:  * non-identifier char) installed by install
                   6290:  *
                   6291:  * If LEN is >= 0, it is the length of the name.
                   6292:  * Otherwise, compute the length by scanning the entire name.
                   6293:  *
                   6294:  * If HASH is >= 0, it is the precomputed hash code.
                   6295:  * Otherwise, compute the hash code.
                   6296:  */
                   6297: static ASSERTION_HASHNODE *
                   6298: assertion_lookup (name, len, hash)
                   6299:      U_CHAR *name;
                   6300:      int len;
                   6301:      int hash;
                   6302: {
                   6303:   register ASSERTION_HASHNODE *bucket;
                   6304: 
                   6305:   bucket = assertion_hashtab[hash];
                   6306:   while (bucket) {
                   6307:     if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
                   6308:       return bucket;
                   6309:     bucket = bucket->next;
                   6310:   }
                   6311:   return NULL;
                   6312: }
                   6313: 
                   6314: static void
                   6315: delete_assertion (hp)
                   6316:      ASSERTION_HASHNODE *hp;
                   6317: {
                   6318: 
                   6319:   if (hp->prev != NULL)
                   6320:     hp->prev->next = hp->next;
                   6321:   if (hp->next != NULL)
                   6322:     hp->next->prev = hp->prev;
                   6323: 
                   6324:   /* make sure that the bucket chain header that
                   6325:      the deleted guy was on points to the right thing afterwards. */
                   6326:   if (hp == *hp->bucket_hdr)
                   6327:     *hp->bucket_hdr = hp->next;
                   6328: 
                   6329:   free (hp);
                   6330: }
                   6331: 
                   6332: /*
                   6333:  * interpret #line command.  Remembers previously seen fnames
                   6334:  * in its very own hash table.
                   6335:  */
                   6336: #define FNAME_HASHSIZE 37
                   6337: 
                   6338: static int
                   6339: do_line (buf, limit, op, keyword)
                   6340:      U_CHAR *buf, *limit;
                   6341:      FILE_BUF *op;
                   6342:      struct directive *keyword;
                   6343: {
                   6344:   register U_CHAR *bp;
                   6345:   FILE_BUF *ip = &instack[indepth];
                   6346:   FILE_BUF tem;
                   6347:   int new_lineno;
                   6348:   enum file_change_code file_change = same_file;
                   6349: 
                   6350:   /* Expand any macros.  */
                   6351:   tem = expand_to_temp_buffer (buf, limit, 0, 0);
                   6352: 
                   6353:   /* Point to macroexpanded line, which is null-terminated now.  */
                   6354:   bp = tem.buf;
                   6355:   SKIP_WHITE_SPACE (bp);
                   6356: 
                   6357:   if (!isdigit (*bp)) {
                   6358:     error ("invalid format `#line' command");
                   6359:     return 0;
                   6360:   }
                   6361: 
                   6362:   /* The Newline at the end of this line remains to be processed.
                   6363:      To put the next line at the specified line number,
                   6364:      we must store a line number now that is one less.  */
                   6365:   new_lineno = atoi (bp) - 1;
                   6366: 
1.1.1.5   root     6367:   /* NEW_LINENO is one less than the actual line number here.  */
                   6368:   if (pedantic && new_lineno < 0)
                   6369:     pedwarn ("line number out of range in `#line' command");
                   6370: 
1.1       root     6371:   /* skip over the line number.  */
                   6372:   while (isdigit (*bp))
                   6373:     bp++;
                   6374: 
                   6375: #if 0 /* #line 10"foo.c" is supposed to be allowed.  */
                   6376:   if (*bp && !is_space[*bp]) {
                   6377:     error ("invalid format `#line' command");
                   6378:     return;
                   6379:   }
                   6380: #endif
                   6381: 
                   6382:   SKIP_WHITE_SPACE (bp);
                   6383: 
                   6384:   if (*bp == '\"') {
                   6385:     static HASHNODE *fname_table[FNAME_HASHSIZE];
                   6386:     HASHNODE *hp, **hash_bucket;
1.1.1.6   root     6387:     U_CHAR *fname, *p;
1.1       root     6388:     int fname_length;
                   6389: 
                   6390:     fname = ++bp;
                   6391: 
1.1.1.6   root     6392:     /* Turn the file name, which is a character string literal,
                   6393:        into a null-terminated string.  Do this in place.  */
                   6394:     p = bp;
                   6395:     for (;;)
                   6396:       switch ((*p++ = *bp++)) {
                   6397:       case '\0':
                   6398:        error ("invalid format `#line' command");
                   6399:        return 0;
1.1       root     6400: 
1.1.1.6   root     6401:       case '\\':
                   6402:        {
                   6403:          char *bpc = (char *) bp;
                   6404:          int c = parse_escape (&bpc);
                   6405:          bp = (U_CHAR *) bpc;
                   6406:          if (c < 0)
                   6407:            p--;
                   6408:          else
                   6409:            p[-1] = c;
                   6410:        }
                   6411:        break;
                   6412: 
                   6413:       case '\"':
                   6414:        p[-1] = 0;
                   6415:        goto fname_done;
                   6416:       }
                   6417:   fname_done:
                   6418:     fname_length = p - fname;
1.1       root     6419: 
                   6420:     SKIP_WHITE_SPACE (bp);
                   6421:     if (*bp) {
1.1.1.5   root     6422:       if (pedantic)
                   6423:        pedwarn ("garbage at end of `#line' command");
1.1       root     6424:       if (*bp == '1')
                   6425:        file_change = enter_file;
                   6426:       else if (*bp == '2')
                   6427:        file_change = leave_file;
1.1.1.2   root     6428:       else if (*bp == '3')
                   6429:        ip->system_header_p = 1;
1.1.1.6   root     6430:       else if (*bp == '4')
                   6431:        ip->system_header_p = 2;
1.1       root     6432:       else {
                   6433:        error ("invalid format `#line' command");
                   6434:        return 0;
                   6435:       }
                   6436: 
                   6437:       bp++;
                   6438:       SKIP_WHITE_SPACE (bp);
1.1.1.2   root     6439:       if (*bp == '3') {
                   6440:        ip->system_header_p = 1;
                   6441:        bp++;
                   6442:        SKIP_WHITE_SPACE (bp);
                   6443:       }
1.1.1.6   root     6444:       if (*bp == '4') {
                   6445:        ip->system_header_p = 2;
                   6446:        bp++;
                   6447:        SKIP_WHITE_SPACE (bp);
                   6448:       }
1.1       root     6449:       if (*bp) {
                   6450:        error ("invalid format `#line' command");
                   6451:        return 0;
                   6452:       }
                   6453:     }
                   6454: 
                   6455:     hash_bucket =
                   6456:       &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
                   6457:     for (hp = *hash_bucket; hp != NULL; hp = hp->next)
                   6458:       if (hp->length == fname_length &&
                   6459:          strncmp (hp->value.cpval, fname, fname_length) == 0) {
                   6460:        ip->nominal_fname = hp->value.cpval;
                   6461:        break;
                   6462:       }
                   6463:     if (hp == 0) {
                   6464:       /* Didn't find it; cons up a new one.  */
                   6465:       hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
                   6466:       hp->next = *hash_bucket;
                   6467:       *hash_bucket = hp;
                   6468: 
                   6469:       hp->length = fname_length;
                   6470:       ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
                   6471:       bcopy (fname, hp->value.cpval, fname_length);
                   6472:     }
                   6473:   } else if (*bp) {
                   6474:     error ("invalid format `#line' command");
                   6475:     return 0;
                   6476:   }
                   6477: 
                   6478:   ip->lineno = new_lineno;
                   6479:   output_line_command (ip, op, 0, file_change);
                   6480:   check_expand (op, ip->length - (ip->bufp - ip->buf));
                   6481:   return 0;
                   6482: }
                   6483: 
                   6484: /*
                   6485:  * remove the definition of a symbol from the symbol table.
                   6486:  * according to un*x /lib/cpp, it is not an error to undef
                   6487:  * something that has no definitions, so it isn't one here either.
                   6488:  */
                   6489: 
                   6490: static int
                   6491: do_undef (buf, limit, op, keyword)
                   6492:      U_CHAR *buf, *limit;
                   6493:      FILE_BUF *op;
                   6494:      struct directive *keyword;
                   6495: {
                   6496:   int sym_length;
                   6497:   HASHNODE *hp;
                   6498:   U_CHAR *orig_buf = buf;
                   6499: 
                   6500:   /* If this is a precompiler run (with -pcp) pass thru #undef commands.  */
                   6501:   if (pcp_outfile && op)
                   6502:     pass_thru_directive (buf, limit, op, keyword);
                   6503: 
                   6504:   SKIP_WHITE_SPACE (buf);
                   6505:   sym_length = check_macro_name (buf, "macro");
                   6506: 
                   6507:   while ((hp = lookup (buf, sym_length, -1)) != NULL) {
                   6508:     /* If we are generating additional info for debugging (with -g) we
                   6509:        need to pass through all effective #undef commands.  */
                   6510:     if (debug_output && op)
                   6511:       pass_thru_directive (orig_buf, limit, op, keyword);
                   6512:     if (hp->type != T_MACRO)
                   6513:       warning ("undefining `%s'", hp->name);
                   6514:     delete_macro (hp);
                   6515:   }
                   6516: 
                   6517:   if (pedantic) {
                   6518:     buf += sym_length;
                   6519:     SKIP_WHITE_SPACE (buf);
                   6520:     if (buf != limit)
                   6521:       pedwarn ("garbage after `#undef' directive");
                   6522:   }
                   6523:   return 0;
                   6524: }
                   6525: 
                   6526: /*
1.1.1.7 ! root     6527:  * Report an error detected by the program we are processing.
        !          6528:  * Use the text of the line in the error message.
1.1.1.5   root     6529:  * (We use error because it prints the filename & line#.)
1.1       root     6530:  */
                   6531: 
                   6532: static int
                   6533: do_error (buf, limit, op, keyword)
                   6534:      U_CHAR *buf, *limit;
                   6535:      FILE_BUF *op;
                   6536:      struct directive *keyword;
                   6537: {
                   6538:   int length = limit - buf;
1.1.1.5   root     6539:   U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
1.1.1.7 ! root     6540:   bcopy ((char *) buf, (char *) copy, length);
1.1       root     6541:   copy[length] = 0;
                   6542:   SKIP_WHITE_SPACE (copy);
                   6543:   error ("#error %s", copy);
                   6544:   return 0;
                   6545: }
                   6546: 
                   6547: /*
                   6548:  * Report a warning detected by the program we are processing.
                   6549:  * Use the text of the line in the warning message, then continue.
1.1.1.5   root     6550:  * (We use error because it prints the filename & line#.)
1.1       root     6551:  */
                   6552: 
                   6553: static int
                   6554: do_warning (buf, limit, op, keyword)
                   6555:      U_CHAR *buf, *limit;
                   6556:      FILE_BUF *op;
                   6557:      struct directive *keyword;
                   6558: {
                   6559:   int length = limit - buf;
1.1.1.5   root     6560:   U_CHAR *copy = (U_CHAR *) xmalloc (length + 1);
1.1.1.7 ! root     6561:   bcopy ((char *) buf, (char *) copy, length);
1.1       root     6562:   copy[length] = 0;
                   6563:   SKIP_WHITE_SPACE (copy);
1.1.1.3   root     6564:   warning ("#warning %s", copy);
1.1       root     6565:   return 0;
                   6566: }
                   6567: 
                   6568: /* Remember the name of the current file being read from so that we can
                   6569:    avoid ever including it again.  */
                   6570: 
                   6571: static int
                   6572: do_once ()
                   6573: {
                   6574:   int i;
                   6575:   FILE_BUF *ip = NULL;
                   6576: 
                   6577:   for (i = indepth; i >= 0; i--)
                   6578:     if (instack[i].fname != NULL) {
                   6579:       ip = &instack[i];
                   6580:       break;
                   6581:     }
                   6582: 
                   6583:   if (ip != NULL) {
                   6584:     struct file_name_list *new;
                   6585:     
                   6586:     new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
                   6587:     new->next = dont_repeat_files;
                   6588:     dont_repeat_files = new;
                   6589:     new->fname = savestring (ip->fname);
                   6590:     new->control_macro = 0;
1.1.1.7 ! root     6591:     new->got_name_map = 0;
1.1.1.6   root     6592:     new->c_system_include_path = 0;
1.1       root     6593:   }
                   6594:   return 0;
                   6595: }
                   6596: 
                   6597: /* #ident has already been copied to the output file, so just ignore it.  */
                   6598: 
                   6599: static int
                   6600: do_ident (buf, limit)
                   6601:      U_CHAR *buf, *limit;
                   6602: {
1.1.1.6   root     6603:   FILE_BUF trybuf;
                   6604:   int len;
                   6605:   FILE_BUF *op = &outbuf;
                   6606: 
1.1       root     6607:   /* Allow #ident in system headers, since that's not user's fault.  */
                   6608:   if (pedantic && !instack[indepth].system_header_p)
                   6609:     pedwarn ("ANSI C does not allow `#ident'");
1.1.1.6   root     6610: 
                   6611:   trybuf = expand_to_temp_buffer (buf, limit, 0, 0);
                   6612:   buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
1.1.1.7 ! root     6613:   bcopy ((char *) trybuf.buf, (char *) buf, trybuf.bufp - trybuf.buf);
1.1.1.6   root     6614:   limit = buf + (trybuf.bufp - trybuf.buf);
                   6615:   len = (limit - buf);
                   6616:   free (trybuf.buf);
                   6617: 
                   6618:   /* Output directive name.  */
1.1.1.7 ! root     6619:   check_expand (op, 7);
        !          6620:   bcopy ("#ident ", (char *) op->bufp, 7);
1.1.1.6   root     6621:   op->bufp += 7;
                   6622: 
                   6623:   /* Output the expanded argument line.  */
                   6624:   check_expand (op, len);
1.1.1.7 ! root     6625:   bcopy ((char *) buf, (char *) op->bufp, len);
1.1.1.6   root     6626:   op->bufp += len;
                   6627: 
1.1       root     6628:   return 0;
                   6629: }
                   6630: 
                   6631: /* #pragma and its argument line have already been copied to the output file.
1.1.1.4   root     6632:    Just check for some recognized pragmas that need validation here.  */
1.1       root     6633: 
                   6634: static int
                   6635: do_pragma (buf, limit)
                   6636:      U_CHAR *buf, *limit;
                   6637: {
                   6638:   while (*buf == ' ' || *buf == '\t')
                   6639:     buf++;
                   6640:   if (!strncmp (buf, "once", 4)) {
1.1.1.3   root     6641:     /* Allow #pragma once in system headers, since that's not the user's
                   6642:        fault.  */
                   6643:     if (!instack[indepth].system_header_p)
                   6644:       warning ("`#pragma once' is obsolete");
1.1       root     6645:     do_once ();
                   6646:   }
1.1.1.4   root     6647: 
                   6648:   if (!strncmp (buf, "implementation", 14)) {
                   6649:     /* Be quiet about `#pragma implementation' for a file only if it hasn't
                   6650:        been included yet.  */
                   6651:     struct file_name_list *ptr;
                   6652:     U_CHAR *p = buf + 14, *fname, *inc_fname;
                   6653:     SKIP_WHITE_SPACE (p);
                   6654:     if (*p == '\n' || *p != '\"')
                   6655:       return 0;
                   6656: 
                   6657:     fname = p + 1;
                   6658:     if (p = (U_CHAR *) index (fname, '\"'))
                   6659:       *p = '\0';
                   6660:     
                   6661:     for (ptr = all_include_files; ptr; ptr = ptr->next) {
                   6662:       inc_fname = (U_CHAR *) rindex (ptr->fname, '/');
                   6663:       inc_fname = inc_fname ? inc_fname + 1 : (U_CHAR *) ptr->fname;
                   6664:       if (inc_fname && !strcmp (inc_fname, fname))
                   6665:        warning ("`#pragma implementation' for `%s' appears after file is included",
                   6666:                 fname);
                   6667:     }
                   6668:   }
                   6669: 
1.1       root     6670:   return 0;
                   6671: }
                   6672: 
                   6673: #if 0
                   6674: /* This was a fun hack, but #pragma seems to start to be useful.
                   6675:    By failing to recognize it, we pass it through unchanged to cc1.  */
                   6676: 
                   6677: /*
                   6678:  * the behavior of the #pragma directive is implementation defined.
                   6679:  * this implementation defines it as follows.
                   6680:  */
                   6681: 
                   6682: static int
                   6683: do_pragma ()
                   6684: {
                   6685:   close (0);
                   6686:   if (open ("/dev/tty", O_RDONLY, 0666) != 0)
                   6687:     goto nope;
                   6688:   close (1);
                   6689:   if (open ("/dev/tty", O_WRONLY, 0666) != 1)
                   6690:     goto nope;
                   6691:   execl ("/usr/games/hack", "#pragma", 0);
                   6692:   execl ("/usr/games/rogue", "#pragma", 0);
                   6693:   execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
                   6694:   execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
                   6695: nope:
                   6696:   fatal ("You are in a maze of twisty compiler features, all different");
                   6697: }
                   6698: #endif
                   6699: 
                   6700: /* Just ignore #sccs, on systems where we define it at all.  */
                   6701: 
                   6702: static int
                   6703: do_sccs ()
                   6704: {
                   6705:   if (pedantic)
                   6706:     pedwarn ("ANSI C does not allow `#sccs'");
                   6707:   return 0;
                   6708: }
                   6709: 
                   6710: /*
                   6711:  * handle #if command by
                   6712:  *   1) inserting special `defined' keyword into the hash table
                   6713:  *     that gets turned into 0 or 1 by special_symbol (thus,
                   6714:  *     if the luser has a symbol called `defined' already, it won't
                   6715:  *      work inside the #if command)
                   6716:  *   2) rescan the input into a temporary output buffer
                   6717:  *   3) pass the output buffer to the yacc parser and collect a value
                   6718:  *   4) clean up the mess left from steps 1 and 2.
                   6719:  *   5) call conditional_skip to skip til the next #endif (etc.),
                   6720:  *      or not, depending on the value from step 3.
                   6721:  */
                   6722: 
                   6723: static int
                   6724: do_if (buf, limit, op, keyword)
                   6725:      U_CHAR *buf, *limit;
                   6726:      FILE_BUF *op;
                   6727:      struct directive *keyword;
                   6728: {
1.1.1.7 ! root     6729:   HOST_WIDE_INT value;
1.1       root     6730:   FILE_BUF *ip = &instack[indepth];
                   6731: 
                   6732:   value = eval_if_expression (buf, limit - buf);
1.1.1.7 ! root     6733:   conditional_skip (ip, value == 0, T_IF, NULL_PTR, op);
1.1       root     6734:   return 0;
                   6735: }
                   6736: 
                   6737: /*
                   6738:  * handle a #elif directive by not changing  if_stack  either.
                   6739:  * see the comment above do_else.
                   6740:  */
                   6741: 
                   6742: static int
                   6743: do_elif (buf, limit, op, keyword)
                   6744:      U_CHAR *buf, *limit;
                   6745:      FILE_BUF *op;
                   6746:      struct directive *keyword;
                   6747: {
1.1.1.7 ! root     6748:   HOST_WIDE_INT value;
1.1       root     6749:   FILE_BUF *ip = &instack[indepth];
                   6750: 
                   6751:   if (if_stack == instack[indepth].if_stack) {
                   6752:     error ("`#elif' not within a conditional");
                   6753:     return 0;
                   6754:   } else {
                   6755:     if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
                   6756:       error ("`#elif' after `#else'");
                   6757:       fprintf (stderr, " (matches line %d", if_stack->lineno);
                   6758:       if (if_stack->fname != NULL && ip->fname != NULL &&
                   6759:          strcmp (if_stack->fname, ip->nominal_fname) != 0)
                   6760:        fprintf (stderr, ", file %s", if_stack->fname);
                   6761:       fprintf (stderr, ")\n");
                   6762:     }
                   6763:     if_stack->type = T_ELIF;
                   6764:   }
                   6765: 
                   6766:   if (if_stack->if_succeeded)
1.1.1.7 ! root     6767:     skip_if_group (ip, 0, op);
1.1       root     6768:   else {
                   6769:     value = eval_if_expression (buf, limit - buf);
                   6770:     if (value == 0)
1.1.1.7 ! root     6771:       skip_if_group (ip, 0, op);
1.1       root     6772:     else {
                   6773:       ++if_stack->if_succeeded;        /* continue processing input */
                   6774:       output_line_command (ip, op, 1, same_file);
                   6775:     }
                   6776:   }
                   6777:   return 0;
                   6778: }
                   6779: 
                   6780: /*
                   6781:  * evaluate a #if expression in BUF, of length LENGTH,
                   6782:  * then parse the result as a C expression and return the value as an int.
                   6783:  */
1.1.1.7 ! root     6784: static HOST_WIDE_INT
1.1       root     6785: eval_if_expression (buf, length)
                   6786:      U_CHAR *buf;
                   6787:      int length;
                   6788: {
                   6789:   FILE_BUF temp_obuf;
                   6790:   HASHNODE *save_defined;
1.1.1.7 ! root     6791:   HOST_WIDE_INT value;
1.1       root     6792: 
1.1.1.7 ! root     6793:   save_defined = install ("defined", -1, T_SPEC_DEFINED, 0, NULL_PTR, -1);
1.1       root     6794:   pcp_inside_if = 1;
                   6795:   temp_obuf = expand_to_temp_buffer (buf, buf + length, 0, 1);
                   6796:   pcp_inside_if = 0;
                   6797:   delete_macro (save_defined); /* clean up special symbol */
                   6798: 
                   6799:   value = parse_c_expression (temp_obuf.buf);
                   6800: 
                   6801:   free (temp_obuf.buf);
                   6802: 
                   6803:   return value;
                   6804: }
                   6805: 
                   6806: /*
                   6807:  * routine to handle ifdef/ifndef.  Try to look up the symbol,
                   6808:  * then do or don't skip to the #endif/#else/#elif depending
                   6809:  * on what directive is actually being processed.
                   6810:  */
                   6811: 
                   6812: static int
                   6813: do_xifdef (buf, limit, op, keyword)
                   6814:      U_CHAR *buf, *limit;
                   6815:      FILE_BUF *op;
                   6816:      struct directive *keyword;
                   6817: {
                   6818:   int skip;
                   6819:   FILE_BUF *ip = &instack[indepth];
                   6820:   U_CHAR *end; 
                   6821:   int start_of_file = 0;
                   6822:   U_CHAR *control_macro = 0;
                   6823: 
                   6824:   /* Detect a #ifndef at start of file (not counting comments).  */
                   6825:   if (ip->fname != 0 && keyword->type == T_IFNDEF) {
                   6826:     U_CHAR *p = ip->buf;
                   6827:     while (p != directive_start) {
1.1.1.5   root     6828:       U_CHAR c = *p++;
1.1.1.4   root     6829:       if (is_space[c])
                   6830:        ;
                   6831:       else if (c == '/' && p != ip->bufp && *p == '*') {
                   6832:        /* Skip this comment.  */
1.1.1.7 ! root     6833:        int junk = 0;
1.1.1.4   root     6834:        U_CHAR *save_bufp = ip->bufp;
                   6835:        ip->bufp = p + 1;
                   6836:        p = skip_to_end_of_comment (ip, &junk, 1);
                   6837:        ip->bufp = save_bufp;
                   6838:       } else {
1.1       root     6839:        goto fail;
                   6840:       }
                   6841:     }
                   6842:     /* If we get here, this conditional is the beginning of the file.  */
                   6843:     start_of_file = 1;
                   6844:   fail: ;
                   6845:   }
                   6846: 
                   6847:   /* Discard leading and trailing whitespace.  */
                   6848:   SKIP_WHITE_SPACE (buf);
                   6849:   while (limit != buf && is_hor_space[limit[-1]]) limit--;
                   6850: 
                   6851:   /* Find the end of the identifier at the beginning.  */
                   6852:   for (end = buf; is_idchar[*end]; end++);
                   6853: 
                   6854:   if (end == buf) {
                   6855:     skip = (keyword->type == T_IFDEF);
                   6856:     if (! traditional)
                   6857:       pedwarn (end == limit ? "`#%s' with no argument"
                   6858:               : "`#%s' argument starts with punctuation",
                   6859:               keyword->name);
                   6860:   } else {
                   6861:     HASHNODE *hp;
                   6862: 
                   6863:     if (pedantic && buf[0] >= '0' && buf[0] <= '9')
                   6864:       pedwarn ("`#%s' argument starts with a digit", keyword->name);
                   6865:     else if (end != limit && !traditional)
                   6866:       pedwarn ("garbage at end of `#%s' argument", keyword->name);
                   6867: 
                   6868:     hp = lookup (buf, end-buf, -1);
                   6869: 
                   6870:     if (pcp_outfile) {
                   6871:       /* Output a precondition for this macro.  */
1.1.1.7 ! root     6872:       if (hp &&
        !          6873:          (hp->type == T_CONST
        !          6874:           || (hp->type == T_MACRO && hp->value.defn->predefined)))
1.1.1.5   root     6875:        fprintf (pcp_outfile, "#define %s\n", hp->name);
1.1       root     6876:       else {
                   6877:        U_CHAR *cp = buf;
1.1.1.5   root     6878:        fprintf (pcp_outfile, "#undef ");
1.1       root     6879:        while (is_idchar[*cp]) /* Ick! */
                   6880:          fputc (*cp++, pcp_outfile);
                   6881:        putc ('\n', pcp_outfile);
                   6882:       }
                   6883:     }
                   6884: 
                   6885:     skip = (hp == NULL) ^ (keyword->type == T_IFNDEF);
                   6886:     if (start_of_file && !skip) {
                   6887:       control_macro = (U_CHAR *) xmalloc (end - buf + 1);
1.1.1.7 ! root     6888:       bcopy ((char *) buf, (char *) control_macro, end - buf);
1.1       root     6889:       control_macro[end - buf] = 0;
                   6890:     }
                   6891:   }
                   6892:   
1.1.1.7 ! root     6893:   conditional_skip (ip, skip, T_IF, control_macro, op);
1.1       root     6894:   return 0;
                   6895: }
                   6896: 
                   6897: /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
                   6898:    If this is a #ifndef starting at the beginning of a file,
                   6899:    CONTROL_MACRO is the macro name tested by the #ifndef.
                   6900:    Otherwise, CONTROL_MACRO is 0.  */
                   6901: 
                   6902: static void
1.1.1.7 ! root     6903: conditional_skip (ip, skip, type, control_macro, op)
1.1       root     6904:      FILE_BUF *ip;
                   6905:      int skip;
                   6906:      enum node_type type;
                   6907:      U_CHAR *control_macro;
1.1.1.7 ! root     6908:      FILE_BUF *op;
1.1       root     6909: {
                   6910:   IF_STACK_FRAME *temp;
                   6911: 
                   6912:   temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
                   6913:   temp->fname = ip->nominal_fname;
                   6914:   temp->lineno = ip->lineno;
                   6915:   temp->next = if_stack;
                   6916:   temp->control_macro = control_macro;
                   6917:   if_stack = temp;
                   6918: 
                   6919:   if_stack->type = type;
                   6920: 
                   6921:   if (skip != 0) {
1.1.1.7 ! root     6922:     skip_if_group (ip, 0, op);
1.1       root     6923:     return;
                   6924:   } else {
                   6925:     ++if_stack->if_succeeded;
                   6926:     output_line_command (ip, &outbuf, 1, same_file);
                   6927:   }
                   6928: }
                   6929: 
                   6930: /*
                   6931:  * skip to #endif, #else, or #elif.  adjust line numbers, etc.
                   6932:  * leaves input ptr at the sharp sign found.
                   6933:  * If ANY is nonzero, return at next directive of any sort.
                   6934:  */
                   6935: static void
1.1.1.7 ! root     6936: skip_if_group (ip, any, op)
1.1       root     6937:      FILE_BUF *ip;
                   6938:      int any;
1.1.1.7 ! root     6939:      FILE_BUF *op;
1.1       root     6940: {
                   6941:   register U_CHAR *bp = ip->bufp, *cp;
                   6942:   register U_CHAR *endb = ip->buf + ip->length;
                   6943:   struct directive *kt;
                   6944:   IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */
                   6945:   U_CHAR *beg_of_line = bp;
                   6946:   register int ident_length;
                   6947:   U_CHAR *ident, *after_ident;
1.1.1.7 ! root     6948:   /* Save info about where the group starts.  */
        !          6949:   U_CHAR *beg_of_group = bp;
        !          6950:   int beg_lineno = ip->lineno;
        !          6951: 
        !          6952:   if (output_conditionals && op != 0) {
        !          6953:     char *ptr = "#failed\n";
        !          6954:     int len = strlen (ptr);
        !          6955: 
        !          6956:     if (op->bufp > op->buf && op->bufp[-1] != '\n')
        !          6957:       {
        !          6958:        *op->bufp++ = '\n';
        !          6959:        op->lineno++;
        !          6960:       }
        !          6961:     check_expand (op, len);
        !          6962:     bcopy (ptr, (char *) op->bufp, len);
        !          6963:     op->bufp += len;
        !          6964:     op->lineno++;
        !          6965:     output_line_command (ip, op, 1, 0);
        !          6966:   }
1.1       root     6967: 
                   6968:   while (bp < endb) {
                   6969:     switch (*bp++) {
                   6970:     case '/':                  /* possible comment */
                   6971:       if (*bp == '\\' && bp[1] == '\n')
                   6972:        newline_fix (bp);
                   6973:       if (*bp == '*'
1.1.1.4   root     6974:          || (cplusplus_comments && *bp == '/')) {
1.1       root     6975:        ip->bufp = ++bp;
1.1.1.2   root     6976:        bp = skip_to_end_of_comment (ip, &ip->lineno, 0);
1.1       root     6977:       }
                   6978:       break;
                   6979:     case '\"':
                   6980:     case '\'':
1.1.1.4   root     6981:       bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno,
                   6982:                               NULL_PTR, NULL_PTR);
1.1       root     6983:       break;
                   6984:     case '\\':
                   6985:       /* Char after backslash loses its special meaning.  */
                   6986:       if (bp < endb) {
                   6987:        if (*bp == '\n')
                   6988:          ++ip->lineno;         /* But do update the line-count.  */
                   6989:        bp++;
                   6990:       }
                   6991:       break;
                   6992:     case '\n':
                   6993:       ++ip->lineno;
                   6994:       beg_of_line = bp;
                   6995:       break;
                   6996:     case '#':
                   6997:       ip->bufp = bp - 1;
                   6998: 
                   6999:       /* # keyword: a # must be first nonblank char on the line */
                   7000:       if (beg_of_line == 0)
                   7001:        break;
                   7002:       /* Scan from start of line, skipping whitespace, comments
                   7003:         and backslash-newlines, and see if we reach this #.
                   7004:         If not, this # is not special.  */
                   7005:       bp = beg_of_line;
1.1.1.6   root     7006:       /* If -traditional, require # to be at beginning of line.  */
                   7007:       if (!traditional)
                   7008:        while (1) {
                   7009:          if (is_hor_space[*bp])
1.1       root     7010:            bp++;
1.1.1.6   root     7011:          else if (*bp == '\\' && bp[1] == '\n')
                   7012:            bp += 2;
                   7013:          else if (*bp == '/' && bp[1] == '*') {
                   7014:            bp += 2;
                   7015:            while (!(*bp == '*' && bp[1] == '/'))
                   7016:              bp++;
                   7017:            bp += 2;
                   7018:          }
1.1.1.7 ! root     7019:          /* There is no point in trying to deal with C++ // comments here,
        !          7020:             because if there is one, then this # must be part of the
        !          7021:             comment and we would never reach here.  */
1.1.1.6   root     7022:          else break;
                   7023:        }
1.1       root     7024:       if (bp != ip->bufp) {
                   7025:        bp = ip->bufp + 1;      /* Reset bp to after the #.  */
                   7026:        break;
                   7027:       }
                   7028: 
                   7029:       bp = ip->bufp + 1;       /* Point after the '#' */
                   7030: 
                   7031:       /* Skip whitespace and \-newline.  */
                   7032:       while (1) {
                   7033:        if (is_hor_space[*bp])
                   7034:          bp++;
                   7035:        else if (*bp == '\\' && bp[1] == '\n')
                   7036:          bp += 2;
                   7037:        else if (*bp == '/' && bp[1] == '*') {
                   7038:          bp += 2;
                   7039:          while (!(*bp == '*' && bp[1] == '/')) {
                   7040:            if (*bp == '\n')
                   7041:              ip->lineno++;
                   7042:            bp++;
                   7043:          }
                   7044:          bp += 2;
1.1.1.4   root     7045:        } else if (cplusplus_comments && *bp == '/' && bp[1] == '/') {
1.1       root     7046:          bp += 2;
1.1.1.7 ! root     7047:          while (bp[-1] == '\\' || *bp != '\n') {
        !          7048:            if (*bp == '\n')
        !          7049:              ip->lineno++;
        !          7050:            bp++;
        !          7051:          }
1.1       root     7052:         }
                   7053:        else break;
                   7054:       }
                   7055: 
                   7056:       cp = bp;
                   7057: 
                   7058:       /* Now find end of directive name.
                   7059:         If we encounter a backslash-newline, exchange it with any following
                   7060:         symbol-constituents so that we end up with a contiguous name.  */
                   7061: 
                   7062:       while (1) {
                   7063:        if (is_idchar[*bp])
                   7064:          bp++;
                   7065:        else {
                   7066:          if (*bp == '\\' && bp[1] == '\n')
                   7067:            name_newline_fix (bp);
                   7068:          if (is_idchar[*bp])
                   7069:            bp++;
                   7070:          else break;
                   7071:        }
                   7072:       }
                   7073:       ident_length = bp - cp;
                   7074:       ident = cp;
                   7075:       after_ident = bp;
                   7076: 
                   7077:       /* A line of just `#' becomes blank.  */
                   7078: 
                   7079:       if (ident_length == 0 && *after_ident == '\n') {
                   7080:        continue;
                   7081:       }
                   7082: 
                   7083:       if (ident_length == 0 || !is_idstart[*ident]) {
                   7084:        U_CHAR *p = ident;
                   7085:        while (is_idchar[*p]) {
                   7086:          if (*p < '0' || *p > '9')
                   7087:            break;
                   7088:          p++;
                   7089:        }
                   7090:        /* Handle # followed by a line number.  */
                   7091:        if (p != ident && !is_idchar[*p]) {
                   7092:          if (pedantic)
                   7093:            pedwarn ("`#' followed by integer");
                   7094:          continue;
                   7095:        }
                   7096: 
                   7097:        /* Avoid error for `###' and similar cases unless -pedantic.  */
                   7098:        if (p == ident) {
                   7099:          while (*p == '#' || is_hor_space[*p]) p++;
                   7100:          if (*p == '\n') {
                   7101:            if (pedantic && !lang_asm)
                   7102:              pedwarn ("invalid preprocessor directive");
                   7103:            continue;
                   7104:          }
                   7105:        }
                   7106: 
                   7107:        if (!lang_asm && pedantic)
                   7108:          pedwarn ("invalid preprocessor directive name");
                   7109:        continue;
                   7110:       }
                   7111: 
                   7112:       for (kt = directive_table; kt->length >= 0; kt++) {
                   7113:        IF_STACK_FRAME *temp;
                   7114:        if (ident_length == kt->length
                   7115:            && strncmp (cp, kt->name, kt->length) == 0) {
                   7116:          /* If we are asked to return on next directive, do so now.  */
                   7117:          if (any)
1.1.1.7 ! root     7118:            goto done;
1.1       root     7119: 
                   7120:          switch (kt->type) {
                   7121:          case T_IF:
                   7122:          case T_IFDEF:
                   7123:          case T_IFNDEF:
                   7124:            temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
                   7125:            temp->next = if_stack;
                   7126:            if_stack = temp;
                   7127:            temp->lineno = ip->lineno;
                   7128:            temp->fname = ip->nominal_fname;
                   7129:            temp->type = kt->type;
                   7130:            break;
                   7131:          case T_ELSE:
                   7132:          case T_ENDIF:
                   7133:            if (pedantic && if_stack != save_if_stack)
                   7134:              validate_else (bp);
                   7135:          case T_ELIF:
                   7136:            if (if_stack == instack[indepth].if_stack) {
                   7137:              error ("`#%s' not within a conditional", kt->name);
                   7138:              break;
                   7139:            }
                   7140:            else if (if_stack == save_if_stack)
1.1.1.7 ! root     7141:              goto done;                /* found what we came for */
1.1       root     7142: 
                   7143:            if (kt->type != T_ENDIF) {
                   7144:              if (if_stack->type == T_ELSE)
                   7145:                error ("`#else' or `#elif' after `#else'");
                   7146:              if_stack->type = kt->type;
                   7147:              break;
                   7148:            }
                   7149: 
                   7150:            temp = if_stack;
                   7151:            if_stack = if_stack->next;
                   7152:            free (temp);
                   7153:            break;
                   7154:          }
                   7155:          break;
                   7156:        }
                   7157:       }
                   7158:       /* Don't let erroneous code go by.  */
                   7159:       if (kt->length < 0 && !lang_asm && pedantic)
                   7160:        pedwarn ("invalid preprocessor directive name");
                   7161:     }
                   7162:   }
1.1.1.7 ! root     7163: 
1.1       root     7164:   ip->bufp = bp;
                   7165:   /* after this returns, rescan will exit because ip->bufp
                   7166:      now points to the end of the buffer.
                   7167:      rescan is responsible for the error message also.  */
1.1.1.7 ! root     7168: 
        !          7169:  done:
        !          7170:   if (output_conditionals && op != 0) {
        !          7171:     char *ptr = "#endfailed\n";
        !          7172:     int len = strlen (ptr);
        !          7173: 
        !          7174:     if (op->bufp > op->buf && op->bufp[-1] != '\n')
        !          7175:       {
        !          7176:        *op->bufp++ = '\n';
        !          7177:        op->lineno++;
        !          7178:       }
        !          7179:     check_expand (op, beg_of_line - beg_of_group);
        !          7180:     bcopy ((char *) beg_of_group, (char *) op->bufp,
        !          7181:           beg_of_line - beg_of_group);
        !          7182:     op->bufp += beg_of_line - beg_of_group;
        !          7183:     op->lineno += ip->lineno - beg_lineno;
        !          7184:     check_expand (op, len);
        !          7185:     bcopy (ptr, (char *) op->bufp, len);
        !          7186:     op->bufp += len;
        !          7187:     op->lineno++;
        !          7188:   }
1.1       root     7189: }
                   7190: 
                   7191: /*
                   7192:  * handle a #else directive.  Do this by just continuing processing
                   7193:  * without changing  if_stack ;  this is so that the error message
                   7194:  * for missing #endif's etc. will point to the original #if.  It
                   7195:  * is possible that something different would be better.
                   7196:  */
                   7197: 
                   7198: static int
                   7199: do_else (buf, limit, op, keyword)
                   7200:      U_CHAR *buf, *limit;
                   7201:      FILE_BUF *op;
                   7202:      struct directive *keyword;
                   7203: {
                   7204:   FILE_BUF *ip = &instack[indepth];
                   7205: 
                   7206:   if (pedantic) {
                   7207:     SKIP_WHITE_SPACE (buf);
                   7208:     if (buf != limit)
                   7209:       pedwarn ("text following `#else' violates ANSI standard");
                   7210:   }
                   7211: 
                   7212:   if (if_stack == instack[indepth].if_stack) {
                   7213:     error ("`#else' not within a conditional");
                   7214:     return 0;
                   7215:   } else {
                   7216:     /* #ifndef can't have its special treatment for containing the whole file
                   7217:        if it has a #else clause.  */
                   7218:     if_stack->control_macro = 0;
                   7219: 
                   7220:     if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
                   7221:       error ("`#else' after `#else'");
                   7222:       fprintf (stderr, " (matches line %d", if_stack->lineno);
                   7223:       if (strcmp (if_stack->fname, ip->nominal_fname) != 0)
                   7224:        fprintf (stderr, ", file %s", if_stack->fname);
                   7225:       fprintf (stderr, ")\n");
                   7226:     }
                   7227:     if_stack->type = T_ELSE;
                   7228:   }
                   7229: 
                   7230:   if (if_stack->if_succeeded)
1.1.1.7 ! root     7231:     skip_if_group (ip, 0, op);
1.1       root     7232:   else {
                   7233:     ++if_stack->if_succeeded;  /* continue processing input */
                   7234:     output_line_command (ip, op, 1, same_file);
                   7235:   }
                   7236:   return 0;
                   7237: }
                   7238: 
                   7239: /*
                   7240:  * unstack after #endif command
                   7241:  */
                   7242: 
                   7243: static int
                   7244: do_endif (buf, limit, op, keyword)
                   7245:      U_CHAR *buf, *limit;
                   7246:      FILE_BUF *op;
                   7247:      struct directive *keyword;
                   7248: {
                   7249:   if (pedantic) {
                   7250:     SKIP_WHITE_SPACE (buf);
                   7251:     if (buf != limit)
                   7252:       pedwarn ("text following `#endif' violates ANSI standard");
                   7253:   }
                   7254: 
                   7255:   if (if_stack == instack[indepth].if_stack)
                   7256:     error ("unbalanced `#endif'");
                   7257:   else {
                   7258:     IF_STACK_FRAME *temp = if_stack;
                   7259:     if_stack = if_stack->next;
                   7260:     if (temp->control_macro != 0) {
                   7261:       /* This #endif matched a #ifndef at the start of the file.
                   7262:         See if it is at the end of the file.  */
                   7263:       FILE_BUF *ip = &instack[indepth];
                   7264:       U_CHAR *p = ip->bufp;
                   7265:       U_CHAR *ep = ip->buf + ip->length;
                   7266: 
                   7267:       while (p != ep) {
                   7268:        U_CHAR c = *p++;
                   7269:        switch (c) {
                   7270:        case ' ':
                   7271:        case '\t':
                   7272:        case '\n':
                   7273:          break;
                   7274:        case '/':
                   7275:          if (p != ep && *p == '*') {
                   7276:            /* Skip this comment.  */
1.1.1.7 ! root     7277:            int junk = 0;
1.1       root     7278:            U_CHAR *save_bufp = ip->bufp;
                   7279:            ip->bufp = p + 1;
1.1.1.2   root     7280:            p = skip_to_end_of_comment (ip, &junk, 1);
1.1       root     7281:            ip->bufp = save_bufp;
                   7282:          }
                   7283:          break;
                   7284:        default:
                   7285:          goto fail;
                   7286:        }
                   7287:       }
                   7288:       /* If we get here, this #endif ends a #ifndef
                   7289:         that contains all of the file (aside from whitespace).
                   7290:         Arrange not to include the file again
1.1.1.7 ! root     7291:         if the macro that was tested is defined.
        !          7292: 
        !          7293:         Do not do this for the top-level file in a -include or any
        !          7294:         file in a -imacros.  */
        !          7295:       if (indepth != 0
        !          7296:          && ! (indepth == 1 && no_record_file)
        !          7297:          && ! (no_record_file && no_output))
1.1       root     7298:        record_control_macro (ip->fname, temp->control_macro);
                   7299:     fail: ;
                   7300:     }
                   7301:     free (temp);
                   7302:     output_line_command (&instack[indepth], op, 1, same_file);
                   7303:   }
                   7304:   return 0;
                   7305: }
                   7306: 
                   7307: /* When an #else or #endif is found while skipping failed conditional,
                   7308:    if -pedantic was specified, this is called to warn about text after
                   7309:    the command name.  P points to the first char after the command name.  */
                   7310: 
                   7311: static void
                   7312: validate_else (p)
                   7313:      register U_CHAR *p;
                   7314: {
                   7315:   /* Advance P over whitespace and comments.  */
                   7316:   while (1) {
                   7317:     if (*p == '\\' && p[1] == '\n')
                   7318:       p += 2;
                   7319:     if (is_hor_space[*p])
                   7320:       p++;
                   7321:     else if (*p == '/') {
                   7322:       if (p[1] == '\\' && p[2] == '\n')
                   7323:        newline_fix (p + 1);
                   7324:       if (p[1] == '*') {
                   7325:        p += 2;
                   7326:        /* Don't bother warning about unterminated comments
                   7327:           since that will happen later.  Just be sure to exit.  */
                   7328:        while (*p) {
                   7329:          if (p[1] == '\\' && p[2] == '\n')
                   7330:            newline_fix (p + 1);
                   7331:          if (*p == '*' && p[1] == '/') {
                   7332:            p += 2;
                   7333:            break;
                   7334:          }
                   7335:          p++;
                   7336:        }
                   7337:       }
1.1.1.4   root     7338:       else if (cplusplus_comments && p[1] == '/') {
1.1       root     7339:        p += 2;
1.1.1.7 ! root     7340:        while (*p && (*p != '\n' || p[-1] == '\\'))
        !          7341:          p++;
1.1       root     7342:       }
                   7343:     } else break;
                   7344:   }
                   7345:   if (*p && *p != '\n')
                   7346:     pedwarn ("text following `#else' or `#endif' violates ANSI standard");
                   7347: }
                   7348: 
1.1.1.2   root     7349: /* Skip a comment, assuming the input ptr immediately follows the
                   7350:    initial slash-star.  Bump *LINE_COUNTER for each newline.
                   7351:    (The canonical line counter is &ip->lineno.)
                   7352:    Don't use this routine (or the next one) if bumping the line
                   7353:    counter is not sufficient to deal with newlines in the string.
                   7354: 
                   7355:    If NOWARN is nonzero, don't warn about slash-star inside a comment.
                   7356:    This feature is useful when processing a comment that is going to be
                   7357:    processed or was processed at another point in the preprocessor,
1.1.1.7 ! root     7358:    to avoid a duplicate warning.  Likewise for unterminated comment errors.  */
        !          7359: 
1.1       root     7360: static U_CHAR *
1.1.1.2   root     7361: skip_to_end_of_comment (ip, line_counter, nowarn)
1.1       root     7362:      register FILE_BUF *ip;
                   7363:      int *line_counter;                /* place to remember newlines, or NULL */
1.1.1.2   root     7364:      int nowarn;
1.1       root     7365: {
                   7366:   register U_CHAR *limit = ip->buf + ip->length;
                   7367:   register U_CHAR *bp = ip->bufp;
                   7368:   FILE_BUF *op = &outbuf;      /* JF */
                   7369:   int output = put_out_comments && !line_counter;
1.1.1.7 ! root     7370:   int start_line = line_counter ? *line_counter : 0;
1.1       root     7371: 
                   7372:        /* JF this line_counter stuff is a crock to make sure the
                   7373:           comment is only put out once, no matter how many times
                   7374:           the comment is skipped.  It almost works */
                   7375:   if (output) {
                   7376:     *op->bufp++ = '/';
                   7377:     *op->bufp++ = '*';
                   7378:   }
1.1.1.4   root     7379:   if (cplusplus_comments && bp[-1] == '/') {
1.1       root     7380:     if (output) {
1.1.1.7 ! root     7381:       while (bp < limit) {
        !          7382:        *op->bufp++ = *bp;
        !          7383:        if (*bp == '\n' && bp[-1] != '\\')
1.1       root     7384:          break;
1.1.1.7 ! root     7385:        if (*bp == '\n') {
        !          7386:          ++*line_counter;
        !          7387:          ++op->lineno;
1.1       root     7388:        }
1.1.1.7 ! root     7389:        bp++;
        !          7390:       }
1.1       root     7391:       op->bufp[-1] = '*';
                   7392:       *op->bufp++ = '/';
                   7393:       *op->bufp++ = '\n';
                   7394:     } else {
                   7395:       while (bp < limit) {
1.1.1.7 ! root     7396:        if (bp[-1] != '\\' && *bp == '\n') {
1.1       root     7397:          break;
1.1.1.7 ! root     7398:        } else {
        !          7399:          if (*bp == '\n' && line_counter)
        !          7400:            ++*line_counter;
        !          7401:          bp++;
1.1       root     7402:        }
                   7403:       }
                   7404:     }
                   7405:     ip->bufp = bp;
                   7406:     return bp;
                   7407:   }
                   7408:   while (bp < limit) {
                   7409:     if (output)
                   7410:       *op->bufp++ = *bp;
                   7411:     switch (*bp++) {
                   7412:     case '/':
1.1.1.2   root     7413:       if (warn_comments && !nowarn && bp < limit && *bp == '*')
1.1       root     7414:        warning ("`/*' within comment");
                   7415:       break;
                   7416:     case '\n':
1.1.1.7 ! root     7417:       /* If this is the end of the file, we have an unterminated comment.
        !          7418:         Don't swallow the newline.  We are guaranteed that there will be a
        !          7419:         trailing newline and various pieces assume it's there.  */
        !          7420:       if (bp == limit)
        !          7421:        {
        !          7422:          --bp;
        !          7423:          --limit;
        !          7424:          break;
        !          7425:        }
1.1       root     7426:       if (line_counter != NULL)
                   7427:        ++*line_counter;
                   7428:       if (output)
                   7429:        ++op->lineno;
                   7430:       break;
                   7431:     case '*':
                   7432:       if (*bp == '\\' && bp[1] == '\n')
                   7433:        newline_fix (bp);
                   7434:       if (*bp == '/') {
                   7435:         if (output)
                   7436:          *op->bufp++ = '/';
                   7437:        ip->bufp = ++bp;
                   7438:        return bp;
                   7439:       }
                   7440:       break;
                   7441:     }
                   7442:   }
1.1.1.7 ! root     7443: 
        !          7444:   if (!nowarn)
        !          7445:     error_with_line (line_for_error (start_line), "unterminated comment");
1.1       root     7446:   ip->bufp = bp;
                   7447:   return bp;
                   7448: }
                   7449: 
                   7450: /*
                   7451:  * Skip over a quoted string.  BP points to the opening quote.
                   7452:  * Returns a pointer after the closing quote.  Don't go past LIMIT.
                   7453:  * START_LINE is the line number of the starting point (but it need
                   7454:  * not be valid if the starting point is inside a macro expansion).
                   7455:  *
                   7456:  * The input stack state is not changed.
                   7457:  *
                   7458:  * If COUNT_NEWLINES is nonzero, it points to an int to increment
                   7459:  * for each newline passed.
                   7460:  *
                   7461:  * If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
                   7462:  * if we pass a backslash-newline.
                   7463:  *
                   7464:  * If EOFP is nonzero, set *EOFP to 1 if the string is unterminated.
                   7465:  */
                   7466: static U_CHAR *
                   7467: skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
                   7468:      register U_CHAR *bp;
                   7469:      register U_CHAR *limit;
                   7470:      int start_line;
                   7471:      int *count_newlines;
                   7472:      int *backslash_newlines_p;
                   7473:      int *eofp;
                   7474: {
                   7475:   register U_CHAR c, match;
                   7476: 
                   7477:   match = *bp++;
                   7478:   while (1) {
                   7479:     if (bp >= limit) {
                   7480:       error_with_line (line_for_error (start_line),
                   7481:                       "unterminated string or character constant");
1.1.1.5   root     7482:       error_with_line (multiline_string_line,
                   7483:                       "possible real start of unterminated constant");
                   7484:       multiline_string_line = 0;
1.1       root     7485:       if (eofp)
                   7486:        *eofp = 1;
                   7487:       break;
                   7488:     }
                   7489:     c = *bp++;
                   7490:     if (c == '\\') {
                   7491:       while (*bp == '\\' && bp[1] == '\n') {
                   7492:        if (backslash_newlines_p)
                   7493:          *backslash_newlines_p = 1;
                   7494:        if (count_newlines)
                   7495:          ++*count_newlines;
                   7496:        bp += 2;
                   7497:       }
                   7498:       if (*bp == '\n' && count_newlines) {
                   7499:        if (backslash_newlines_p)
                   7500:          *backslash_newlines_p = 1;
                   7501:        ++*count_newlines;
                   7502:       }
                   7503:       bp++;
                   7504:     } else if (c == '\n') {
                   7505:       if (traditional) {
                   7506:        /* Unterminated strings and character constants are 'legal'.  */
                   7507:        bp--;   /* Don't consume the newline. */
                   7508:        if (eofp)
                   7509:          *eofp = 1;
                   7510:        break;
                   7511:       }
1.1.1.5   root     7512:       if (pedantic || match == '\'') {
1.1       root     7513:        error_with_line (line_for_error (start_line),
1.1.1.5   root     7514:                         "unterminated string or character constant");
1.1       root     7515:        bp--;
                   7516:        if (eofp)
                   7517:          *eofp = 1;
                   7518:        break;
                   7519:       }
                   7520:       /* If not traditional, then allow newlines inside strings.  */
                   7521:       if (count_newlines)
                   7522:        ++*count_newlines;
1.1.1.5   root     7523:       if (multiline_string_line == 0)
                   7524:        multiline_string_line = start_line;
1.1       root     7525:     } else if (c == match)
                   7526:       break;
                   7527:   }
                   7528:   return bp;
                   7529: }
                   7530: 
1.1.1.6   root     7531: /* Place into DST a quoted string representing the string SRC.
                   7532:    Return the address of DST's terminating null.  */
                   7533: static char *
                   7534: quote_string (dst, src)
                   7535:      char *dst, *src;
                   7536: {
                   7537:   U_CHAR c;
                   7538: 
                   7539:   *dst++ = '\"';
                   7540:   for (;;)
                   7541:     switch ((c = *src++))
                   7542:       {
                   7543:       default:
                   7544:         if (isprint (c))
                   7545:          *dst++ = c;
                   7546:        else
                   7547:          {
                   7548:            sprintf (dst, "\\%03o", c);
                   7549:            dst += 4;
                   7550:          }
                   7551:        break;
                   7552: 
                   7553:       case '\"':
                   7554:       case '\\':
                   7555:        *dst++ = '\\';
                   7556:        *dst++ = c;
                   7557:        break;
                   7558:       
                   7559:       case '\0':
                   7560:        *dst++ = '\"';
                   7561:        *dst = '\0';
                   7562:        return dst;
                   7563:       }
                   7564: }
                   7565: 
1.1       root     7566: /* Skip across a group of balanced parens, starting from IP->bufp.
                   7567:    IP->bufp is updated.  Use this with IP->bufp pointing at an open-paren.
                   7568: 
                   7569:    This does not handle newlines, because it's used for the arg of #if,
1.1.1.2   root     7570:    where there aren't any newlines.  Also, backslash-newline can't appear.  */
1.1       root     7571: 
                   7572: static U_CHAR *
                   7573: skip_paren_group (ip)
                   7574:      register FILE_BUF *ip;
                   7575: {
                   7576:   U_CHAR *limit = ip->buf + ip->length;
                   7577:   U_CHAR *p = ip->bufp;
                   7578:   int depth = 0;
                   7579:   int lines_dummy = 0;
                   7580: 
                   7581:   while (p != limit) {
                   7582:     int c = *p++;
                   7583:     switch (c) {
                   7584:     case '(':
                   7585:       depth++;
                   7586:       break;
                   7587: 
                   7588:     case ')':
                   7589:       depth--;
                   7590:       if (depth == 0)
                   7591:        return ip->bufp = p;
                   7592:       break;
                   7593: 
                   7594:     case '/':
                   7595:       if (*p == '*') {
                   7596:        ip->bufp = p;
1.1.1.2   root     7597:        p = skip_to_end_of_comment (ip, &lines_dummy, 0);
1.1       root     7598:        p = ip->bufp;
                   7599:       }
                   7600: 
                   7601:     case '"':
                   7602:     case '\'':
                   7603:       {
                   7604:        int eofp = 0;
1.1.1.4   root     7605:        p = skip_quoted_string (p - 1, limit, 0, NULL_PTR, NULL_PTR, &eofp);
1.1       root     7606:        if (eofp)
                   7607:          return ip->bufp = p;
                   7608:       }
                   7609:       break;
                   7610:     }
                   7611:   }
                   7612: 
                   7613:   ip->bufp = p;
                   7614:   return p;
                   7615: }
                   7616: 
                   7617: /*
                   7618:  * write out a #line command, for instance, after an #include file.
                   7619:  * If CONDITIONAL is nonzero, we can omit the #line if it would
                   7620:  * appear to be a no-op, and we can output a few newlines instead
                   7621:  * if we want to increase the line number by a small amount.
                   7622:  * FILE_CHANGE says whether we are entering a file, leaving, or neither.
                   7623:  */
                   7624: 
                   7625: static void
                   7626: output_line_command (ip, op, conditional, file_change)
                   7627:      FILE_BUF *ip, *op;
                   7628:      int conditional;
                   7629:      enum file_change_code file_change;
                   7630: {
                   7631:   int len;
1.1.1.6   root     7632:   char *line_cmd_buf, *line_end;
1.1       root     7633: 
                   7634:   if (no_line_commands
                   7635:       || ip->fname == NULL
                   7636:       || no_output) {
                   7637:     op->lineno = ip->lineno;
                   7638:     return;
                   7639:   }
                   7640: 
                   7641:   if (conditional) {
                   7642:     if (ip->lineno == op->lineno)
                   7643:       return;
                   7644: 
                   7645:     /* If the inherited line number is a little too small,
                   7646:        output some newlines instead of a #line command.  */
                   7647:     if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) {
                   7648:       check_expand (op, 10);
                   7649:       while (ip->lineno > op->lineno) {
                   7650:        *op->bufp++ = '\n';
                   7651:        op->lineno++;
                   7652:       }
                   7653:       return;
                   7654:     }
                   7655:   }
                   7656: 
1.1.1.2   root     7657:   /* Don't output a line number of 0 if we can help it.  */
                   7658:   if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length
                   7659:       && *ip->bufp == '\n') {
                   7660:     ip->lineno++;
                   7661:     ip->bufp++;
                   7662:   }
                   7663: 
1.1.1.6   root     7664:   line_cmd_buf = (char *) alloca (4 * strlen (ip->nominal_fname) + 100);
1.1       root     7665: #ifdef OUTPUT_LINE_COMMANDS
1.1.1.6   root     7666:   sprintf (line_cmd_buf, "#line %d ", ip->lineno);
1.1       root     7667: #else
1.1.1.6   root     7668:   sprintf (line_cmd_buf, "# %d ", ip->lineno);
1.1       root     7669: #endif
1.1.1.6   root     7670:   line_end = quote_string (line_cmd_buf + strlen (line_cmd_buf),
                   7671:                           ip->nominal_fname);
                   7672:   if (file_change != same_file) {
                   7673:     *line_end++ = ' ';
                   7674:     *line_end++ = file_change == enter_file ? '1' : '2';
                   7675:   }
1.1       root     7676:   /* Tell cc1 if following text comes from a system header file.  */
1.1.1.6   root     7677:   if (ip->system_header_p) {
                   7678:     *line_end++ = ' ';
                   7679:     *line_end++ = '3';
                   7680:   }
                   7681: #ifndef NO_IMPLICIT_EXTERN_C
                   7682:   /* Tell cc1plus if following text should be treated as C.  */
                   7683:   if (ip->system_header_p == 2 && cplusplus) {
                   7684:     *line_end++ = ' ';
                   7685:     *line_end++ = '4';
                   7686:   }
                   7687: #endif
                   7688:   *line_end++ = '\n';
                   7689:   len = line_end - line_cmd_buf;
1.1       root     7690:   check_expand (op, len + 1);
                   7691:   if (op->bufp > op->buf && op->bufp[-1] != '\n')
                   7692:     *op->bufp++ = '\n';
1.1.1.7 ! root     7693:   bcopy ((char *) line_cmd_buf, (char *) op->bufp, len);
1.1       root     7694:   op->bufp += len;
                   7695:   op->lineno = ip->lineno;
                   7696: }
                   7697: 
                   7698: /* This structure represents one parsed argument in a macro call.
                   7699:    `raw' points to the argument text as written (`raw_length' is its length).
                   7700:    `expanded' points to the argument's macro-expansion
                   7701:    (its length is `expand_length').
                   7702:    `stringified_length' is the length the argument would have
                   7703:    if stringified.
                   7704:    `use_count' is the number of times this macro arg is substituted
                   7705:    into the macro.  If the actual use count exceeds 10, 
                   7706:    the value stored is 10.
                   7707:    `free1' and `free2', if nonzero, point to blocks to be freed
                   7708:    when the macro argument data is no longer needed.  */
                   7709: 
                   7710: struct argdata {
                   7711:   U_CHAR *raw, *expanded;
                   7712:   int raw_length, expand_length;
                   7713:   int stringified_length;
                   7714:   U_CHAR *free1, *free2;
                   7715:   char newlines;
                   7716:   char comments;
                   7717:   char use_count;
                   7718: };
                   7719: 
                   7720: /* Expand a macro call.
                   7721:    HP points to the symbol that is the macro being called.
                   7722:    Put the result of expansion onto the input stack
                   7723:    so that subsequent input by our caller will use it.
                   7724: 
                   7725:    If macro wants arguments, caller has already verified that
                   7726:    an argument list follows; arguments come from the input stack.  */
                   7727: 
                   7728: static void
                   7729: macroexpand (hp, op)
                   7730:      HASHNODE *hp;
                   7731:      FILE_BUF *op;
                   7732: {
                   7733:   int nargs;
                   7734:   DEFINITION *defn = hp->value.defn;
                   7735:   register U_CHAR *xbuf;
                   7736:   int xbuf_len;
                   7737:   int start_line = instack[indepth].lineno;
1.1.1.3   root     7738:   int rest_args, rest_zero;
1.1       root     7739: 
                   7740:   CHECK_DEPTH (return;);
                   7741: 
                   7742:   /* it might not actually be a macro.  */
                   7743:   if (hp->type != T_MACRO) {
                   7744:     special_symbol (hp, op);
                   7745:     return;
                   7746:   }
                   7747: 
                   7748:   /* This macro is being used inside a #if, which means it must be */
                   7749:   /* recorded as a precondition.  */
                   7750:   if (pcp_inside_if && pcp_outfile && defn->predefined)
                   7751:     dump_single_macro (hp, pcp_outfile);
                   7752:   
                   7753:   nargs = defn->nargs;
                   7754: 
                   7755:   if (nargs >= 0) {
                   7756:     register int i;
                   7757:     struct argdata *args;
                   7758:     char *parse_error = 0;
                   7759: 
                   7760:     args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
                   7761: 
                   7762:     for (i = 0; i < nargs; i++) {
1.1.1.5   root     7763:       args[i].raw = (U_CHAR *) "";
                   7764:       args[i].expanded = 0;
1.1       root     7765:       args[i].raw_length = args[i].expand_length
                   7766:        = args[i].stringified_length = 0;
                   7767:       args[i].free1 = args[i].free2 = 0;
                   7768:       args[i].use_count = 0;
                   7769:     }
                   7770: 
                   7771:     /* Parse all the macro args that are supplied.  I counts them.
                   7772:        The first NARGS args are stored in ARGS.
1.1.1.3   root     7773:        The rest are discarded.
                   7774:        If rest_args is set then we assume macarg absorbed the rest of the args.
                   7775:        */
1.1       root     7776:     i = 0;
1.1.1.3   root     7777:     rest_args = 0;
1.1       root     7778:     do {
                   7779:       /* Discard the open-parenthesis or comma before the next arg.  */
                   7780:       ++instack[indepth].bufp;
1.1.1.3   root     7781:       if (rest_args)
                   7782:        continue;
                   7783:       if (i < nargs || (nargs == 0 && i == 0)) {
1.1.1.4   root     7784:        /* if we are working on last arg which absorbs rest of args... */
1.1.1.3   root     7785:        if (i == nargs - 1 && defn->rest_args)
                   7786:          rest_args = 1;
                   7787:        parse_error = macarg (&args[i], rest_args);
                   7788:       }
                   7789:       else
1.1.1.4   root     7790:        parse_error = macarg (NULL_PTR, 0);
1.1       root     7791:       if (parse_error) {
                   7792:        error_with_line (line_for_error (start_line), parse_error);
                   7793:        break;
                   7794:       }
                   7795:       i++;
                   7796:     } while (*instack[indepth].bufp != ')');
                   7797: 
                   7798:     /* If we got one arg but it was just whitespace, call that 0 args.  */
                   7799:     if (i == 1) {
                   7800:       register U_CHAR *bp = args[0].raw;
                   7801:       register U_CHAR *lim = bp + args[0].raw_length;
1.1.1.5   root     7802:       /* cpp.texi says for foo ( ) we provide one argument.
                   7803:         However, if foo wants just 0 arguments, treat this as 0.  */
                   7804:       if (nargs == 0)
                   7805:        while (bp != lim && is_space[*bp]) bp++;
1.1       root     7806:       if (bp == lim)
                   7807:        i = 0;
                   7808:     }
                   7809: 
1.1.1.4   root     7810:     /* Don't output an error message if we have already output one for
                   7811:        a parse error above.  */
1.1.1.3   root     7812:     rest_zero = 0;
1.1.1.4   root     7813:     if (nargs == 0 && i > 0) {
                   7814:       if (! parse_error)
                   7815:        error ("arguments given to macro `%s'", hp->name);
                   7816:     } else if (i < nargs) {
1.1       root     7817:       /* traditional C allows foo() if foo wants one argument.  */
                   7818:       if (nargs == 1 && i == 0 && traditional)
                   7819:        ;
1.1.1.3   root     7820:       /* the rest args token is allowed to absorb 0 tokens */
                   7821:       else if (i == nargs - 1 && defn->rest_args)
                   7822:        rest_zero = 1;
1.1.1.4   root     7823:       else if (parse_error)
                   7824:        ;
1.1       root     7825:       else if (i == 0)
                   7826:        error ("macro `%s' used without args", hp->name);
                   7827:       else if (i == 1)
                   7828:        error ("macro `%s' used with just one arg", hp->name);
                   7829:       else
                   7830:        error ("macro `%s' used with only %d args", hp->name, i);
1.1.1.4   root     7831:     } else if (i > nargs) {
                   7832:       if (! parse_error)
                   7833:        error ("macro `%s' used with too many (%d) args", hp->name, i);
                   7834:     }
1.1       root     7835: 
                   7836:     /* Swallow the closeparen.  */
                   7837:     ++instack[indepth].bufp;
                   7838: 
                   7839:     /* If macro wants zero args, we parsed the arglist for checking only.
                   7840:        Read directly from the macro definition.  */
                   7841:     if (nargs == 0) {
                   7842:       xbuf = defn->expansion;
                   7843:       xbuf_len = defn->length;
                   7844:     } else {
                   7845:       register U_CHAR *exp = defn->expansion;
                   7846:       register int offset;     /* offset in expansion,
                   7847:                                   copied a piece at a time */
                   7848:       register int totlen;     /* total amount of exp buffer filled so far */
                   7849: 
1.1.1.3   root     7850:       register struct reflist *ap, *last_ap;
1.1       root     7851: 
                   7852:       /* Macro really takes args.  Compute the expansion of this call.  */
                   7853: 
                   7854:       /* Compute length in characters of the macro's expansion.
                   7855:         Also count number of times each arg is used.  */
                   7856:       xbuf_len = defn->length;
                   7857:       for (ap = defn->pattern; ap != NULL; ap = ap->next) {
                   7858:        if (ap->stringify)
                   7859:          xbuf_len += args[ap->argno].stringified_length;
                   7860:        else if (ap->raw_before || ap->raw_after || traditional)
1.1.1.5   root     7861:          /* Add 4 for two newline-space markers to prevent
                   7862:             token concatenation.  */
                   7863:          xbuf_len += args[ap->argno].raw_length + 4;
                   7864:        else {
                   7865:          /* We have an ordinary (expanded) occurrence of the arg.
                   7866:             So compute its expansion, if we have not already.  */
                   7867:          if (args[ap->argno].expanded == 0) {
                   7868:            FILE_BUF obuf;
                   7869:            obuf = expand_to_temp_buffer (args[ap->argno].raw,
                   7870:                                          args[ap->argno].raw + args[ap->argno].raw_length,
                   7871:                                          1, 0);
                   7872: 
                   7873:            args[ap->argno].expanded = obuf.buf;
                   7874:            args[ap->argno].expand_length = obuf.length;
                   7875:            args[ap->argno].free2 = obuf.buf;
                   7876:          }
                   7877: 
                   7878:          /* Add 4 for two newline-space markers to prevent
                   7879:             token concatenation.  */
                   7880:          xbuf_len += args[ap->argno].expand_length + 4;
                   7881:        }
1.1       root     7882:        if (args[ap->argno].use_count < 10)
                   7883:          args[ap->argno].use_count++;
                   7884:       }
                   7885: 
                   7886:       xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
                   7887: 
                   7888:       /* Generate in XBUF the complete expansion
                   7889:         with arguments substituted in.
                   7890:         TOTLEN is the total size generated so far.
                   7891:         OFFSET is the index in the definition
                   7892:         of where we are copying from.  */
                   7893:       offset = totlen = 0;
1.1.1.3   root     7894:       for (last_ap = NULL, ap = defn->pattern; ap != NULL;
                   7895:           last_ap = ap, ap = ap->next) {
1.1       root     7896:        register struct argdata *arg = &args[ap->argno];
1.1.1.5   root     7897:        int count_before = totlen;
1.1       root     7898: 
1.1.1.5   root     7899:        /* Add chars to XBUF.  */
1.1.1.3   root     7900:        for (i = 0; i < ap->nchars; i++, offset++)
1.1.1.5   root     7901:          xbuf[totlen++] = exp[offset];
                   7902: 
                   7903:        /* If followed by an empty rest arg with concatenation,
                   7904:           delete the last run of nonwhite chars.  */
                   7905:        if (rest_zero && totlen > count_before
                   7906:            && ((ap->rest_args && ap->raw_before)
                   7907:                || (last_ap != NULL && last_ap->rest_args
                   7908:                    && last_ap->raw_after))) {
                   7909:          /* Delete final whitespace.  */
                   7910:          while (totlen > count_before && is_space[xbuf[totlen - 1]]) {
                   7911:            totlen--;
                   7912:          }
                   7913: 
                   7914:          /* Delete the nonwhites before them.  */
                   7915:          while (totlen > count_before && ! is_space[xbuf[totlen - 1]]) {
                   7916:            totlen--;
                   7917:          }
                   7918:        }
1.1       root     7919: 
                   7920:        if (ap->stringify != 0) {
                   7921:          int arglen = arg->raw_length;
                   7922:          int escaped = 0;
                   7923:          int in_string = 0;
                   7924:          int c;
                   7925:          i = 0;
                   7926:          while (i < arglen
                   7927:                 && (c = arg->raw[i], is_space[c]))
                   7928:            i++;
                   7929:          while (i < arglen
                   7930:                 && (c = arg->raw[arglen - 1], is_space[c]))
                   7931:            arglen--;
                   7932:          if (!traditional)
                   7933:            xbuf[totlen++] = '\"'; /* insert beginning quote */
                   7934:          for (; i < arglen; i++) {
                   7935:            c = arg->raw[i];
                   7936: 
                   7937:            /* Special markers Newline Space
                   7938:               generate nothing for a stringified argument.  */
                   7939:            if (c == '\n' && arg->raw[i+1] != '\n') {
                   7940:              i++;
                   7941:              continue;
                   7942:            }
                   7943: 
                   7944:            /* Internal sequences of whitespace are replaced by one space
                   7945:               except within an string or char token.  */
                   7946:            if (! in_string
                   7947:                && (c == '\n' ? arg->raw[i+1] == '\n' : is_space[c])) {
                   7948:              while (1) {
                   7949:                /* Note that Newline Space does occur within whitespace
                   7950:                   sequences; consider it part of the sequence.  */
                   7951:                if (c == '\n' && is_space[arg->raw[i+1]])
                   7952:                  i += 2;
                   7953:                else if (c != '\n' && is_space[c])
                   7954:                  i++;
                   7955:                else break;
                   7956:                c = arg->raw[i];
                   7957:              }
                   7958:              i--;
                   7959:              c = ' ';
                   7960:            }
                   7961: 
                   7962:            if (escaped)
                   7963:              escaped = 0;
                   7964:            else {
                   7965:              if (c == '\\')
                   7966:                escaped = 1;
                   7967:              if (in_string) {
                   7968:                if (c == in_string)
                   7969:                  in_string = 0;
                   7970:              } else if (c == '\"' || c == '\'')
                   7971:                in_string = c;
                   7972:            }
                   7973: 
                   7974:            /* Escape these chars */
                   7975:            if (c == '\"' || (in_string && c == '\\'))
                   7976:              xbuf[totlen++] = '\\';
                   7977:            if (isprint (c))
                   7978:              xbuf[totlen++] = c;
                   7979:            else {
                   7980:              sprintf ((char *) &xbuf[totlen], "\\%03o", (unsigned int) c);
                   7981:              totlen += 4;
                   7982:            }
                   7983:          }
                   7984:          if (!traditional)
                   7985:            xbuf[totlen++] = '\"'; /* insert ending quote */
                   7986:        } else if (ap->raw_before || ap->raw_after || traditional) {
                   7987:          U_CHAR *p1 = arg->raw;
                   7988:          U_CHAR *l1 = p1 + arg->raw_length;
                   7989:          if (ap->raw_before) {
                   7990:            while (p1 != l1 && is_space[*p1]) p1++;
                   7991:            while (p1 != l1 && is_idchar[*p1])
                   7992:              xbuf[totlen++] = *p1++;
                   7993:            /* Delete any no-reexpansion marker that follows
                   7994:               an identifier at the beginning of the argument
                   7995:               if the argument is concatenated with what precedes it.  */
                   7996:            if (p1[0] == '\n' && p1[1] == '-')
                   7997:              p1 += 2;
1.1.1.5   root     7998:          } else if (!traditional) {
                   7999:          /* Ordinary expanded use of the argument.
                   8000:             Put in newline-space markers to prevent token pasting.  */
                   8001:            xbuf[totlen++] = '\n';
                   8002:            xbuf[totlen++] = ' ';
1.1       root     8003:          }
                   8004:          if (ap->raw_after) {
                   8005:            /* Arg is concatenated after: delete trailing whitespace,
                   8006:               whitespace markers, and no-reexpansion markers.  */
                   8007:            while (p1 != l1) {
                   8008:              if (is_space[l1[-1]]) l1--;
                   8009:              else if (l1[-1] == '-') {
                   8010:                U_CHAR *p2 = l1 - 1;
                   8011:                /* If a `-' is preceded by an odd number of newlines then it
                   8012:                   and the last newline are a no-reexpansion marker.  */
                   8013:                while (p2 != p1 && p2[-1] == '\n') p2--;
                   8014:                if ((l1 - 1 - p2) & 1) {
                   8015:                  l1 -= 2;
                   8016:                }
                   8017:                else break;
                   8018:              }
                   8019:              else break;
                   8020:            }
                   8021:          }
1.1.1.5   root     8022: 
1.1.1.7 ! root     8023:          bcopy ((char *) p1, (char *) (xbuf + totlen), l1 - p1);
1.1       root     8024:          totlen += l1 - p1;
1.1.1.5   root     8025:          if (!traditional && !ap->raw_after) {
                   8026:            /* Ordinary expanded use of the argument.
                   8027:               Put in newline-space markers to prevent token pasting.  */
                   8028:            xbuf[totlen++] = '\n';
                   8029:            xbuf[totlen++] = ' ';
                   8030:          }
1.1       root     8031:        } else {
1.1.1.5   root     8032:          /* Ordinary expanded use of the argument.
                   8033:             Put in newline-space markers to prevent token pasting.  */
                   8034:          if (!traditional) {
                   8035:            xbuf[totlen++] = '\n';
                   8036:            xbuf[totlen++] = ' ';
                   8037:          }
1.1.1.7 ! root     8038:          bcopy ((char *) arg->expanded, (char *) (xbuf + totlen),
        !          8039:                 arg->expand_length);
1.1       root     8040:          totlen += arg->expand_length;
1.1.1.5   root     8041:          if (!traditional) {
                   8042:            xbuf[totlen++] = '\n';
                   8043:            xbuf[totlen++] = ' ';
                   8044:          }
1.1       root     8045:          /* If a macro argument with newlines is used multiple times,
                   8046:             then only expand the newlines once.  This avoids creating output
                   8047:             lines which don't correspond to any input line, which confuses
                   8048:             gdb and gcov.  */
                   8049:          if (arg->use_count > 1 && arg->newlines > 0) {
1.1.1.5   root     8050:            /* Don't bother doing change_newlines for subsequent
1.1       root     8051:               uses of arg.  */
                   8052:            arg->use_count = 1;
                   8053:            arg->expand_length
1.1.1.5   root     8054:              = change_newlines (arg->expanded, arg->expand_length);
1.1       root     8055:          }
                   8056:        }
                   8057: 
                   8058:        if (totlen > xbuf_len)
                   8059:          abort ();
                   8060:       }
                   8061: 
                   8062:       /* if there is anything left of the definition
                   8063:         after handling the arg list, copy that in too. */
                   8064: 
1.1.1.3   root     8065:       for (i = offset; i < defn->length; i++) {
                   8066:        /* if we've reached the end of the macro */
                   8067:        if (exp[i] == ')')
                   8068:          rest_zero = 0;
                   8069:        if (! (rest_zero && last_ap != NULL && last_ap->rest_args
                   8070:               && last_ap->raw_after))
                   8071:          xbuf[totlen++] = exp[i];
                   8072:       }
1.1       root     8073: 
                   8074:       xbuf[totlen] = 0;
                   8075:       xbuf_len = totlen;
                   8076: 
                   8077:       for (i = 0; i < nargs; i++) {
                   8078:        if (args[i].free1 != 0)
                   8079:          free (args[i].free1);
                   8080:        if (args[i].free2 != 0)
                   8081:          free (args[i].free2);
                   8082:       }
                   8083:     }
                   8084:   } else {
                   8085:     xbuf = defn->expansion;
                   8086:     xbuf_len = defn->length;
                   8087:   }
                   8088: 
                   8089:   /* Now put the expansion on the input stack
                   8090:      so our caller will commence reading from it.  */
                   8091:   {
                   8092:     register FILE_BUF *ip2;
                   8093: 
                   8094:     ip2 = &instack[++indepth];
                   8095: 
                   8096:     ip2->fname = 0;
                   8097:     ip2->nominal_fname = 0;
1.1.1.7 ! root     8098:     /* This may not be exactly correct, but will give much better error
        !          8099:        messages for nested macro calls than using a line number of zero.  */
        !          8100:     ip2->lineno = start_line;
1.1       root     8101:     ip2->buf = xbuf;
                   8102:     ip2->length = xbuf_len;
                   8103:     ip2->bufp = xbuf;
                   8104:     ip2->free_ptr = (nargs > 0) ? xbuf : 0;
                   8105:     ip2->macro = hp;
                   8106:     ip2->if_stack = if_stack;
                   8107:     ip2->system_header_p = 0;
                   8108: 
                   8109:     /* Recursive macro use sometimes works traditionally.
1.1.1.5   root     8110:        #define foo(x,y) bar (x (y,0), y)
                   8111:        foo (foo, baz)  */
1.1       root     8112: 
                   8113:     if (!traditional)
                   8114:       hp->type = T_DISABLED;
                   8115:   }
                   8116: }
                   8117: 
                   8118: /*
                   8119:  * Parse a macro argument and store the info on it into *ARGPTR.
1.1.1.3   root     8120:  * REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
1.1       root     8121:  * Return nonzero to indicate a syntax error.
                   8122:  */
                   8123: 
                   8124: static char *
1.1.1.3   root     8125: macarg (argptr, rest_args)
1.1       root     8126:      register struct argdata *argptr;
1.1.1.3   root     8127:      int rest_args;
1.1       root     8128: {
                   8129:   FILE_BUF *ip = &instack[indepth];
                   8130:   int paren = 0;
                   8131:   int newlines = 0;
                   8132:   int comments = 0;
                   8133: 
                   8134:   /* Try to parse as much of the argument as exists at this
                   8135:      input stack level.  */
                   8136:   U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length,
1.1.1.3   root     8137:                        &paren, &newlines, &comments, rest_args);
1.1       root     8138: 
                   8139:   /* If we find the end of the argument at this level,
                   8140:      set up *ARGPTR to point at it in the input stack.  */
                   8141:   if (!(ip->fname != 0 && (newlines != 0 || comments != 0))
                   8142:       && bp != ip->buf + ip->length) {
                   8143:     if (argptr != 0) {
                   8144:       argptr->raw = ip->bufp;
                   8145:       argptr->raw_length = bp - ip->bufp;
                   8146:       argptr->newlines = newlines;
                   8147:     }
                   8148:     ip->bufp = bp;
                   8149:   } else {
                   8150:     /* This input stack level ends before the macro argument does.
                   8151:        We must pop levels and keep parsing.
                   8152:        Therefore, we must allocate a temporary buffer and copy
                   8153:        the macro argument into it.  */
                   8154:     int bufsize = bp - ip->bufp;
                   8155:     int extra = newlines;
                   8156:     U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1);
                   8157:     int final_start = 0;
                   8158: 
1.1.1.7 ! root     8159:     bcopy ((char *) ip->bufp, (char *) buffer, bufsize);
1.1       root     8160:     ip->bufp = bp;
                   8161:     ip->lineno += newlines;
                   8162: 
                   8163:     while (bp == ip->buf + ip->length) {
                   8164:       if (instack[indepth].macro == 0) {
                   8165:        free (buffer);
                   8166:        return "unterminated macro call";
                   8167:       }
                   8168:       ip->macro->type = T_MACRO;
                   8169:       if (ip->free_ptr)
                   8170:        free (ip->free_ptr);
                   8171:       ip = &instack[--indepth];
                   8172:       newlines = 0;
                   8173:       comments = 0;
                   8174:       bp = macarg1 (ip->bufp, ip->buf + ip->length, &paren,
1.1.1.3   root     8175:                    &newlines, &comments, rest_args);
1.1       root     8176:       final_start = bufsize;
                   8177:       bufsize += bp - ip->bufp;
                   8178:       extra += newlines;
                   8179:       buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1);
1.1.1.7 ! root     8180:       bcopy ((char *) ip->bufp, (char *) (buffer + bufsize - (bp - ip->bufp)),
        !          8181:             bp - ip->bufp);
1.1       root     8182:       ip->bufp = bp;
                   8183:       ip->lineno += newlines;
                   8184:     }
                   8185: 
                   8186:     /* Now, if arg is actually wanted, record its raw form,
                   8187:        discarding comments and duplicating newlines in whatever
                   8188:        part of it did not come from a macro expansion.
                   8189:        EXTRA space has been preallocated for duplicating the newlines.
                   8190:        FINAL_START is the index of the start of that part.  */
                   8191:     if (argptr != 0) {
                   8192:       argptr->raw = buffer;
                   8193:       argptr->raw_length = bufsize;
                   8194:       argptr->free1 = buffer;
                   8195:       argptr->newlines = newlines;
                   8196:       argptr->comments = comments;
                   8197:       if ((newlines || comments) && ip->fname != 0)
                   8198:        argptr->raw_length
                   8199:          = final_start +
                   8200:            discard_comments (argptr->raw + final_start,
                   8201:                              argptr->raw_length - final_start,
                   8202:                              newlines);
                   8203:       argptr->raw[argptr->raw_length] = 0;
                   8204:       if (argptr->raw_length > bufsize + extra)
                   8205:        abort ();
                   8206:     }
                   8207:   }
                   8208: 
                   8209:   /* If we are not discarding this argument,
                   8210:      macroexpand it and compute its length as stringified.
                   8211:      All this info goes into *ARGPTR.  */
                   8212: 
                   8213:   if (argptr != 0) {
                   8214:     register U_CHAR *buf, *lim;
                   8215:     register int totlen;
                   8216: 
                   8217:     buf = argptr->raw;
                   8218:     lim = buf + argptr->raw_length;
                   8219: 
                   8220:     while (buf != lim && is_space[*buf])
                   8221:       buf++;
                   8222:     while (buf != lim && is_space[lim[-1]])
                   8223:       lim--;
                   8224:     totlen = traditional ? 0 : 2;      /* Count opening and closing quote.  */
                   8225:     while (buf != lim) {
                   8226:       register U_CHAR c = *buf++;
                   8227:       totlen++;
                   8228:       /* Internal sequences of whitespace are replaced by one space
                   8229:         in most cases, but not always.  So count all the whitespace
                   8230:         in case we need to keep it all.  */
                   8231: #if 0
                   8232:       if (is_space[c])
                   8233:        SKIP_ALL_WHITE_SPACE (buf);
                   8234:       else
                   8235: #endif
                   8236:       if (c == '\"' || c == '\\') /* escape these chars */
                   8237:        totlen++;
                   8238:       else if (!isprint (c))
                   8239:        totlen += 3;
                   8240:     }
                   8241:     argptr->stringified_length = totlen;
                   8242:   }
                   8243:   return 0;
                   8244: }
                   8245: 
                   8246: /* Scan text from START (inclusive) up to LIMIT (exclusive),
                   8247:    counting parens in *DEPTHPTR,
                   8248:    and return if reach LIMIT
                   8249:    or before a `)' that would make *DEPTHPTR negative
                   8250:    or before a comma when *DEPTHPTR is zero.
                   8251:    Single and double quotes are matched and termination
                   8252:    is inhibited within them.  Comments also inhibit it.
                   8253:    Value returned is pointer to stopping place.
                   8254: 
                   8255:    Increment *NEWLINES each time a newline is passed.
1.1.1.3   root     8256:    REST_ARGS notifies macarg1 that it should absorb the rest of the args.
1.1       root     8257:    Set *COMMENTS to 1 if a comment is seen.  */
                   8258: 
                   8259: static U_CHAR *
1.1.1.3   root     8260: macarg1 (start, limit, depthptr, newlines, comments, rest_args)
1.1       root     8261:      U_CHAR *start;
                   8262:      register U_CHAR *limit;
                   8263:      int *depthptr, *newlines, *comments;
1.1.1.3   root     8264:      int rest_args;
1.1       root     8265: {
                   8266:   register U_CHAR *bp = start;
                   8267: 
                   8268:   while (bp < limit) {
                   8269:     switch (*bp) {
                   8270:     case '(':
                   8271:       (*depthptr)++;
                   8272:       break;
                   8273:     case ')':
                   8274:       if (--(*depthptr) < 0)
                   8275:        return bp;
                   8276:       break;
                   8277:     case '\\':
                   8278:       /* Traditionally, backslash makes following char not special.  */
                   8279:       if (bp + 1 < limit && traditional)
                   8280:        {
                   8281:          bp++;
                   8282:          /* But count source lines anyway.  */
                   8283:          if (*bp == '\n')
                   8284:            ++*newlines;
                   8285:        }
                   8286:       break;
                   8287:     case '\n':
                   8288:       ++*newlines;
                   8289:       break;
                   8290:     case '/':
                   8291:       if (bp[1] == '\\' && bp[2] == '\n')
                   8292:        newline_fix (bp + 1);
1.1.1.4   root     8293:       if (cplusplus_comments && bp[1] == '/') {
1.1       root     8294:        *comments = 1;
                   8295:        bp += 2;
1.1.1.7 ! root     8296:        while (bp < limit && (*bp != '\n' || bp[-1] == '\\')) {
        !          8297:          if (*bp == '\n') ++*newlines;
        !          8298:          bp++;
        !          8299:        }
1.1       root     8300:        break;
                   8301:       }
                   8302:       if (bp[1] != '*' || bp + 1 >= limit)
                   8303:        break;
                   8304:       *comments = 1;
                   8305:       bp += 2;
                   8306:       while (bp + 1 < limit) {
                   8307:        if (bp[0] == '*'
                   8308:            && bp[1] == '\\' && bp[2] == '\n')
                   8309:          newline_fix (bp + 1);
                   8310:        if (bp[0] == '*' && bp[1] == '/')
                   8311:          break;
                   8312:        if (*bp == '\n') ++*newlines;
                   8313:        bp++;
                   8314:       }
                   8315:       break;
                   8316:     case '\'':
                   8317:     case '\"':
                   8318:       {
                   8319:        int quotec;
                   8320:        for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) {
                   8321:          if (*bp == '\\') {
                   8322:            bp++;
                   8323:            if (*bp == '\n')
                   8324:              ++*newlines;
                   8325:            while (*bp == '\\' && bp[1] == '\n') {
                   8326:              bp += 2;
                   8327:            }
                   8328:          } else if (*bp == '\n') {
                   8329:            ++*newlines;
                   8330:            if (quotec == '\'')
                   8331:              break;
                   8332:          }
                   8333:        }
                   8334:       }
                   8335:       break;
                   8336:     case ',':
1.1.1.3   root     8337:       /* if we've returned to lowest level and we aren't absorbing all args */
                   8338:       if ((*depthptr) == 0 && rest_args == 0)
1.1       root     8339:        return bp;
                   8340:       break;
                   8341:     }
                   8342:     bp++;
                   8343:   }
                   8344: 
                   8345:   return bp;
                   8346: }
                   8347: 
                   8348: /* Discard comments and duplicate newlines
                   8349:    in the string of length LENGTH at START,
                   8350:    except inside of string constants.
                   8351:    The string is copied into itself with its beginning staying fixed.  
                   8352: 
                   8353:    NEWLINES is the number of newlines that must be duplicated.
                   8354:    We assume that that much extra space is available past the end
                   8355:    of the string.  */
                   8356: 
                   8357: static int
                   8358: discard_comments (start, length, newlines)
                   8359:      U_CHAR *start;
                   8360:      int length;
                   8361:      int newlines;
                   8362: {
                   8363:   register U_CHAR *ibp;
                   8364:   register U_CHAR *obp;
                   8365:   register U_CHAR *limit;
                   8366:   register int c;
                   8367: 
                   8368:   /* If we have newlines to duplicate, copy everything
                   8369:      that many characters up.  Then, in the second part,
                   8370:      we will have room to insert the newlines
                   8371:      while copying down.
                   8372:      NEWLINES may actually be too large, because it counts
                   8373:      newlines in string constants, and we don't duplicate those.
                   8374:      But that does no harm.  */
                   8375:   if (newlines > 0) {
                   8376:     ibp = start + length;
                   8377:     obp = ibp + newlines;
                   8378:     limit = start;
                   8379:     while (limit != ibp)
                   8380:       *--obp = *--ibp;
                   8381:   }
                   8382: 
                   8383:   ibp = start + newlines;
                   8384:   limit = start + length + newlines;
                   8385:   obp = start;
                   8386: 
                   8387:   while (ibp < limit) {
                   8388:     *obp++ = c = *ibp++;
                   8389:     switch (c) {
                   8390:     case '\n':
                   8391:       /* Duplicate the newline.  */
                   8392:       *obp++ = '\n';
                   8393:       break;
                   8394: 
                   8395:     case '\\':
                   8396:       if (*ibp == '\n') {
                   8397:        obp--;
                   8398:        ibp++;
                   8399:       }
                   8400:       break;
                   8401: 
                   8402:     case '/':
                   8403:       if (*ibp == '\\' && ibp[1] == '\n')
                   8404:        newline_fix (ibp);
                   8405:       /* Delete any comment.  */
1.1.1.4   root     8406:       if (cplusplus_comments && ibp[0] == '/') {
1.1.1.7 ! root     8407:        /* Comments are equivalent to spaces.  */
        !          8408:        obp[-1] = ' ';
1.1       root     8409:        ibp++;
1.1.1.7 ! root     8410:        while (ibp < limit && (*ibp != '\n' || ibp[-1] == '\\'))
        !          8411:          ibp++;
1.1       root     8412:        break;
                   8413:       }
                   8414:       if (ibp[0] != '*' || ibp + 1 >= limit)
                   8415:        break;
1.1.1.7 ! root     8416:       /* Comments are equivalent to spaces.  */
        !          8417:       obp[-1] = ' ';
1.1       root     8418:       ibp++;
                   8419:       while (ibp + 1 < limit) {
                   8420:        if (ibp[0] == '*'
                   8421:            && ibp[1] == '\\' && ibp[2] == '\n')
                   8422:          newline_fix (ibp + 1);
                   8423:        if (ibp[0] == '*' && ibp[1] == '/')
                   8424:          break;
                   8425:        ibp++;
                   8426:       }
                   8427:       ibp += 2;
                   8428:       break;
                   8429: 
                   8430:     case '\'':
                   8431:     case '\"':
                   8432:       /* Notice and skip strings, so that we don't
                   8433:         think that comments start inside them,
                   8434:         and so we don't duplicate newlines in them.  */
                   8435:       {
                   8436:        int quotec = c;
                   8437:        while (ibp < limit) {
                   8438:          *obp++ = c = *ibp++;
                   8439:          if (c == quotec)
                   8440:            break;
                   8441:          if (c == '\n' && quotec == '\'')
                   8442:            break;
                   8443:          if (c == '\\' && ibp < limit) {
                   8444:            while (*ibp == '\\' && ibp[1] == '\n')
                   8445:              ibp += 2;
                   8446:            *obp++ = *ibp++;
                   8447:          }
                   8448:        }
                   8449:       }
                   8450:       break;
                   8451:     }
                   8452:   }
                   8453: 
                   8454:   return obp - start;
                   8455: }
                   8456: 
1.1.1.5   root     8457: /* Turn newlines to spaces in the string of length LENGTH at START,
                   8458:    except inside of string constants.
                   8459:    The string is copied into itself with its beginning staying fixed.  */
1.1       root     8460: 
                   8461: static int
1.1.1.5   root     8462: change_newlines (start, length)
1.1       root     8463:      U_CHAR *start;
                   8464:      int length;
                   8465: {
                   8466:   register U_CHAR *ibp;
                   8467:   register U_CHAR *obp;
                   8468:   register U_CHAR *limit;
                   8469:   register int c;
                   8470: 
                   8471:   ibp = start;
                   8472:   limit = start + length;
                   8473:   obp = start;
                   8474: 
                   8475:   while (ibp < limit) {
                   8476:     *obp++ = c = *ibp++;
                   8477:     switch (c) {
                   8478:     case '\n':
                   8479:       /* If this is a NEWLINE NEWLINE, then this is a real newline in the
1.1.1.5   root     8480:         string.  Skip past the newline and its duplicate.
                   8481:         Put a space in the output.  */
1.1       root     8482:       if (*ibp == '\n')
                   8483:        {
                   8484:          ibp++;
                   8485:          obp--;
1.1.1.5   root     8486:          *obp++ = ' ';
1.1       root     8487:        }
                   8488:       break;
                   8489: 
                   8490:     case '\'':
                   8491:     case '\"':
                   8492:       /* Notice and skip strings, so that we don't delete newlines in them.  */
                   8493:       {
                   8494:        int quotec = c;
                   8495:        while (ibp < limit) {
                   8496:          *obp++ = c = *ibp++;
                   8497:          if (c == quotec)
                   8498:            break;
                   8499:          if (c == '\n' && quotec == '\'')
                   8500:            break;
                   8501:        }
                   8502:       }
                   8503:       break;
                   8504:     }
                   8505:   }
                   8506: 
                   8507:   return obp - start;
                   8508: }
                   8509: 
                   8510: /*
1.1.1.7 ! root     8511:  * my_strerror - return the descriptive text associated with an `errno' code.
        !          8512:  */
        !          8513: 
        !          8514: char *
        !          8515: my_strerror (errnum)
        !          8516:      int errnum;
        !          8517: {
        !          8518:   char *result;
        !          8519: 
        !          8520: #ifndef VMS
        !          8521: #ifndef HAVE_STRERROR
        !          8522:   result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0);
        !          8523: #else
        !          8524:   result = strerror (errnum);
        !          8525: #endif
        !          8526: #else  /* VMS */
        !          8527:   /* VAXCRTL's strerror() takes an optional second argument, which only
        !          8528:      matters when the first argument is EVMSERR.  However, it's simplest
        !          8529:      just to pass it unconditionally.  `vaxc$errno' is declared in
        !          8530:      <errno.h>, and maintained by the library in parallel with `errno'.
        !          8531:      We assume that caller's `errnum' either matches the last setting of
        !          8532:      `errno' by the library or else does not have the value `EVMSERR'.  */
        !          8533: 
        !          8534:   result = strerror (errnum, vaxc$errno);
        !          8535: #endif
        !          8536: 
        !          8537:   if (!result)
        !          8538:     result = "undocumented I/O error";
        !          8539: 
        !          8540:   return result;
        !          8541: }
        !          8542: 
        !          8543: /*
1.1       root     8544:  * error - print error message and increment count of errors.
                   8545:  */
                   8546: 
                   8547: void
                   8548: error (msg, arg1, arg2, arg3)
                   8549:      char *msg;
1.1.1.4   root     8550:      char *arg1, *arg2, *arg3;
1.1       root     8551: {
                   8552:   int i;
                   8553:   FILE_BUF *ip = NULL;
                   8554: 
                   8555:   print_containing_files ();
                   8556: 
                   8557:   for (i = indepth; i >= 0; i--)
                   8558:     if (instack[i].fname != NULL) {
                   8559:       ip = &instack[i];
                   8560:       break;
                   8561:     }
                   8562: 
                   8563:   if (ip != NULL)
                   8564:     fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno);
                   8565:   fprintf (stderr, msg, arg1, arg2, arg3);
                   8566:   fprintf (stderr, "\n");
                   8567:   errors++;
                   8568: }
                   8569: 
                   8570: /* Error including a message from `errno'.  */
                   8571: 
                   8572: static void
                   8573: error_from_errno (name)
                   8574:      char *name;
                   8575: {
                   8576:   int i;
                   8577:   FILE_BUF *ip = NULL;
                   8578: 
                   8579:   print_containing_files ();
                   8580: 
                   8581:   for (i = indepth; i >= 0; i--)
                   8582:     if (instack[i].fname != NULL) {
                   8583:       ip = &instack[i];
                   8584:       break;
                   8585:     }
                   8586: 
                   8587:   if (ip != NULL)
                   8588:     fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno);
                   8589: 
1.1.1.7 ! root     8590:   fprintf (stderr, "%s: %s\n", name, my_strerror (errno));
1.1       root     8591: 
                   8592:   errors++;
                   8593: }
                   8594: 
                   8595: /* Print error message but don't count it.  */
                   8596: 
                   8597: void
                   8598: warning (msg, arg1, arg2, arg3)
                   8599:      char *msg;
1.1.1.4   root     8600:      char *arg1, *arg2, *arg3;
1.1       root     8601: {
                   8602:   int i;
                   8603:   FILE_BUF *ip = NULL;
                   8604: 
                   8605:   if (inhibit_warnings)
                   8606:     return;
                   8607: 
                   8608:   if (warnings_are_errors)
                   8609:     errors++;
                   8610: 
                   8611:   print_containing_files ();
                   8612: 
                   8613:   for (i = indepth; i >= 0; i--)
                   8614:     if (instack[i].fname != NULL) {
                   8615:       ip = &instack[i];
                   8616:       break;
                   8617:     }
                   8618: 
                   8619:   if (ip != NULL)
                   8620:     fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno);
                   8621:   fprintf (stderr, "warning: ");
                   8622:   fprintf (stderr, msg, arg1, arg2, arg3);
                   8623:   fprintf (stderr, "\n");
                   8624: }
                   8625: 
                   8626: static void
                   8627: error_with_line (line, msg, arg1, arg2, arg3)
                   8628:      int line;
                   8629:      char *msg;
1.1.1.4   root     8630:      char *arg1, *arg2, *arg3;
1.1       root     8631: {
                   8632:   int i;
                   8633:   FILE_BUF *ip = NULL;
                   8634: 
                   8635:   print_containing_files ();
                   8636: 
                   8637:   for (i = indepth; i >= 0; i--)
                   8638:     if (instack[i].fname != NULL) {
                   8639:       ip = &instack[i];
                   8640:       break;
                   8641:     }
                   8642: 
                   8643:   if (ip != NULL)
                   8644:     fprintf (stderr, "%s:%d: ", ip->nominal_fname, line);
                   8645:   fprintf (stderr, msg, arg1, arg2, arg3);
                   8646:   fprintf (stderr, "\n");
                   8647:   errors++;
                   8648: }
                   8649: 
1.1.1.5   root     8650: static void
                   8651: warning_with_line (line, msg, arg1, arg2, arg3)
                   8652:      int line;
                   8653:      char *msg;
                   8654:      char *arg1, *arg2, *arg3;
                   8655: {
                   8656:   int i;
                   8657:   FILE_BUF *ip = NULL;
                   8658: 
                   8659:   if (inhibit_warnings)
                   8660:     return;
                   8661: 
                   8662:   if (warnings_are_errors)
                   8663:     errors++;
                   8664: 
                   8665:   print_containing_files ();
                   8666: 
                   8667:   for (i = indepth; i >= 0; i--)
                   8668:     if (instack[i].fname != NULL) {
                   8669:       ip = &instack[i];
                   8670:       break;
                   8671:     }
                   8672: 
                   8673:   if (ip != NULL)
                   8674:     fprintf (stderr, "%s:%d: ", ip->nominal_fname, line);
                   8675:   fprintf (stderr, "warning: ");
                   8676:   fprintf (stderr, msg, arg1, arg2, arg3);
                   8677:   fprintf (stderr, "\n");
                   8678: }
                   8679: 
1.1       root     8680: /* print an error message and maybe count it.  */
                   8681: 
                   8682: void
                   8683: pedwarn (msg, arg1, arg2, arg3)
                   8684:      char *msg;
1.1.1.4   root     8685:      char *arg1, *arg2, *arg3;
1.1       root     8686: {
                   8687:   if (pedantic_errors)
                   8688:     error (msg, arg1, arg2, arg3);
                   8689:   else
                   8690:     warning (msg, arg1, arg2, arg3);
                   8691: }
                   8692: 
1.1.1.5   root     8693: void
                   8694: pedwarn_with_line (line, msg, arg1, arg2, arg3)
                   8695:      int line;
                   8696:      char *msg;
                   8697:      char *arg1, *arg2, *arg3;
                   8698: {
                   8699:   if (pedantic_errors)
                   8700:     error_with_line (line, msg, arg1, arg2, arg3);
                   8701:   else
                   8702:     warning_with_line (line, msg, arg1, arg2, arg3);
                   8703: }
                   8704: 
1.1       root     8705: /* Report a warning (or an error if pedantic_errors)
                   8706:    giving specified file name and line number, not current.  */
                   8707: 
                   8708: static void
                   8709: pedwarn_with_file_and_line (file, line, msg, arg1, arg2, arg3)
                   8710:      char *file;
                   8711:      int line;
                   8712:      char *msg;
1.1.1.4   root     8713:      char *arg1, *arg2, *arg3;
1.1       root     8714: {
                   8715:   if (!pedantic_errors && inhibit_warnings)
                   8716:     return;
                   8717:   if (file != NULL)
                   8718:     fprintf (stderr, "%s:%d: ", file, line);
1.1.1.5   root     8719:   if (pedantic_errors)
1.1       root     8720:     errors++;
                   8721:   if (!pedantic_errors)
                   8722:     fprintf (stderr, "warning: ");
                   8723:   fprintf (stderr, msg, arg1, arg2, arg3);
                   8724:   fprintf (stderr, "\n");
                   8725: }
                   8726: 
                   8727: /* Print the file names and line numbers of the #include
                   8728:    commands which led to the current file.  */
                   8729: 
                   8730: static void
                   8731: print_containing_files ()
                   8732: {
                   8733:   FILE_BUF *ip = NULL;
                   8734:   int i;
                   8735:   int first = 1;
                   8736: 
                   8737:   /* If stack of files hasn't changed since we last printed
                   8738:      this info, don't repeat it.  */
                   8739:   if (last_error_tick == input_file_stack_tick)
                   8740:     return;
                   8741: 
                   8742:   for (i = indepth; i >= 0; i--)
                   8743:     if (instack[i].fname != NULL) {
                   8744:       ip = &instack[i];
                   8745:       break;
                   8746:     }
                   8747: 
                   8748:   /* Give up if we don't find a source file.  */
                   8749:   if (ip == NULL)
                   8750:     return;
                   8751: 
                   8752:   /* Find the other, outer source files.  */
                   8753:   for (i--; i >= 0; i--)
                   8754:     if (instack[i].fname != NULL) {
                   8755:       ip = &instack[i];
                   8756:       if (first) {
                   8757:        first = 0;
                   8758:        fprintf (stderr, "In file included");
                   8759:       } else {
1.1.1.6   root     8760:        fprintf (stderr, ",\n                ");
1.1       root     8761:       }
                   8762: 
                   8763:       fprintf (stderr, " from %s:%d", ip->nominal_fname, ip->lineno);
                   8764:     }
                   8765:   if (! first)
                   8766:     fprintf (stderr, ":\n");
                   8767: 
                   8768:   /* Record we have printed the status as of this time.  */
                   8769:   last_error_tick = input_file_stack_tick;
                   8770: }
                   8771: 
                   8772: /* Return the line at which an error occurred.
                   8773:    The error is not necessarily associated with the current spot
                   8774:    in the input stack, so LINE says where.  LINE will have been
                   8775:    copied from ip->lineno for the current input level.
                   8776:    If the current level is for a file, we return LINE.
                   8777:    But if the current level is not for a file, LINE is meaningless.
                   8778:    In that case, we return the lineno of the innermost file.  */
                   8779: 
                   8780: static int
                   8781: line_for_error (line)
                   8782:      int line;
                   8783: {
                   8784:   int i;
                   8785:   int line1 = line;
                   8786: 
                   8787:   for (i = indepth; i >= 0; ) {
                   8788:     if (instack[i].fname != 0)
                   8789:       return line1;
                   8790:     i--;
                   8791:     if (i < 0)
                   8792:       return 0;
                   8793:     line1 = instack[i].lineno;
                   8794:   }
                   8795:   abort ();
                   8796:   /*NOTREACHED*/
                   8797:   return 0;
                   8798: }
                   8799: 
                   8800: /*
                   8801:  * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger.
                   8802:  *
                   8803:  * As things stand, nothing is ever placed in the output buffer to be
                   8804:  * removed again except when it's KNOWN to be part of an identifier,
                   8805:  * so flushing and moving down everything left, instead of expanding,
                   8806:  * should work ok.
                   8807:  */
                   8808: 
                   8809: /* You might think void was cleaner for the return type,
                   8810:    but that would get type mismatch in check_expand in strict ANSI.  */
                   8811: static int
                   8812: grow_outbuf (obuf, needed)
                   8813:      register FILE_BUF *obuf;
                   8814:      register int needed;
                   8815: {
                   8816:   register U_CHAR *p;
                   8817:   int minsize;
                   8818: 
                   8819:   if (obuf->length - (obuf->bufp - obuf->buf) > needed)
                   8820:     return 0;
                   8821: 
                   8822:   /* Make it at least twice as big as it is now.  */
                   8823:   obuf->length *= 2;
                   8824:   /* Make it have at least 150% of the free space we will need.  */
                   8825:   minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf);
                   8826:   if (minsize > obuf->length)
                   8827:     obuf->length = minsize;
                   8828: 
                   8829:   if ((p = (U_CHAR *) xrealloc (obuf->buf, obuf->length)) == NULL)
                   8830:     memory_full ();
                   8831: 
                   8832:   obuf->bufp = p + (obuf->bufp - obuf->buf);
                   8833:   obuf->buf = p;
                   8834: 
                   8835:   return 0;
                   8836: }
                   8837: 
                   8838: /* Symbol table for macro names and special symbols */
                   8839: 
                   8840: /*
                   8841:  * install a name in the main hash table, even if it is already there.
                   8842:  *   name stops with first non alphanumeric, except leading '#'.
                   8843:  * caller must check against redefinition if that is desired.
                   8844:  * delete_macro () removes things installed by install () in fifo order.
                   8845:  * this is important because of the `defined' special symbol used
                   8846:  * in #if, and also if pushdef/popdef directives are ever implemented.
                   8847:  *
                   8848:  * If LEN is >= 0, it is the length of the name.
                   8849:  * Otherwise, compute the length by scanning the entire name.
                   8850:  *
                   8851:  * If HASH is >= 0, it is the precomputed hash code.
                   8852:  * Otherwise, compute the hash code.
                   8853:  */
                   8854: static HASHNODE *
1.1.1.4   root     8855: install (name, len, type, ivalue, value, hash)
1.1       root     8856:      U_CHAR *name;
                   8857:      int len;
                   8858:      enum node_type type;
1.1.1.4   root     8859:      int ivalue;
                   8860:      char *value;
1.1       root     8861:      int hash;
                   8862: {
                   8863:   register HASHNODE *hp;
                   8864:   register int i, bucket;
                   8865:   register U_CHAR *p, *q;
                   8866: 
                   8867:   if (len < 0) {
                   8868:     p = name;
                   8869:     while (is_idchar[*p])
                   8870:       p++;
                   8871:     len = p - name;
                   8872:   }
                   8873: 
                   8874:   if (hash < 0)
                   8875:     hash = hashf (name, len, HASHSIZE);
                   8876: 
                   8877:   i = sizeof (HASHNODE) + len + 1;
                   8878:   hp = (HASHNODE *) xmalloc (i);
                   8879:   bucket = hash;
                   8880:   hp->bucket_hdr = &hashtab[bucket];
                   8881:   hp->next = hashtab[bucket];
                   8882:   hashtab[bucket] = hp;
                   8883:   hp->prev = NULL;
                   8884:   if (hp->next != NULL)
                   8885:     hp->next->prev = hp;
                   8886:   hp->type = type;
                   8887:   hp->length = len;
1.1.1.4   root     8888:   if (hp->type == T_CONST)
                   8889:     hp->value.ival = ivalue;
                   8890:   else
                   8891:     hp->value.cpval = value;
1.1       root     8892:   hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
                   8893:   p = hp->name;
                   8894:   q = name;
                   8895:   for (i = 0; i < len; i++)
                   8896:     *p++ = *q++;
                   8897:   hp->name[len] = 0;
                   8898:   return hp;
                   8899: }
                   8900: 
                   8901: /*
                   8902:  * find the most recent hash node for name name (ending with first
                   8903:  * non-identifier char) installed by install
                   8904:  *
                   8905:  * If LEN is >= 0, it is the length of the name.
                   8906:  * Otherwise, compute the length by scanning the entire name.
                   8907:  *
                   8908:  * If HASH is >= 0, it is the precomputed hash code.
                   8909:  * Otherwise, compute the hash code.
                   8910:  */
                   8911: HASHNODE *
                   8912: lookup (name, len, hash)
                   8913:      U_CHAR *name;
                   8914:      int len;
                   8915:      int hash;
                   8916: {
                   8917:   register U_CHAR *bp;
                   8918:   register HASHNODE *bucket;
                   8919: 
                   8920:   if (len < 0) {
                   8921:     for (bp = name; is_idchar[*bp]; bp++) ;
                   8922:     len = bp - name;
                   8923:   }
                   8924: 
                   8925:   if (hash < 0)
                   8926:     hash = hashf (name, len, HASHSIZE);
                   8927: 
                   8928:   bucket = hashtab[hash];
                   8929:   while (bucket) {
                   8930:     if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
                   8931:       return bucket;
                   8932:     bucket = bucket->next;
                   8933:   }
                   8934:   return NULL;
                   8935: }
                   8936: 
                   8937: /*
                   8938:  * Delete a hash node.  Some weirdness to free junk from macros.
                   8939:  * More such weirdness will have to be added if you define more hash
                   8940:  * types that need it.
                   8941:  */
                   8942: 
                   8943: /* Note that the DEFINITION of a macro is removed from the hash table
                   8944:    but its storage is not freed.  This would be a storage leak
                   8945:    except that it is not reasonable to keep undefining and redefining
                   8946:    large numbers of macros many times.
                   8947:    In any case, this is necessary, because a macro can be #undef'd
                   8948:    in the middle of reading the arguments to a call to it.
                   8949:    If #undef freed the DEFINITION, that would crash.  */
                   8950: 
                   8951: static void
                   8952: delete_macro (hp)
                   8953:      HASHNODE *hp;
                   8954: {
                   8955: 
                   8956:   if (hp->prev != NULL)
                   8957:     hp->prev->next = hp->next;
                   8958:   if (hp->next != NULL)
                   8959:     hp->next->prev = hp->prev;
                   8960: 
                   8961:   /* make sure that the bucket chain header that
                   8962:      the deleted guy was on points to the right thing afterwards. */
                   8963:   if (hp == *hp->bucket_hdr)
                   8964:     *hp->bucket_hdr = hp->next;
                   8965: 
                   8966: #if 0
                   8967:   if (hp->type == T_MACRO) {
                   8968:     DEFINITION *d = hp->value.defn;
                   8969:     struct reflist *ap, *nextap;
                   8970: 
                   8971:     for (ap = d->pattern; ap != NULL; ap = nextap) {
                   8972:       nextap = ap->next;
                   8973:       free (ap);
                   8974:     }
                   8975:     free (d);
                   8976:   }
                   8977: #endif
                   8978:   free (hp);
                   8979: }
                   8980: 
                   8981: /*
                   8982:  * return hash function on name.  must be compatible with the one
                   8983:  * computed a step at a time, elsewhere
                   8984:  */
                   8985: static int
                   8986: hashf (name, len, hashsize)
                   8987:      register U_CHAR *name;
                   8988:      register int len;
                   8989:      int hashsize;
                   8990: {
                   8991:   register int r = 0;
                   8992: 
                   8993:   while (len--)
                   8994:     r = HASHSTEP (r, *name++);
                   8995: 
                   8996:   return MAKE_POS (r) % hashsize;
                   8997: }
                   8998: 
                   8999: 
                   9000: /* Dump the definition of a single macro HP to OF.  */
                   9001: static void
                   9002: dump_single_macro (hp, of)
                   9003:      register HASHNODE *hp;
                   9004:      FILE *of;
                   9005: {
                   9006:   register DEFINITION *defn = hp->value.defn;
                   9007:   struct reflist *ap;
                   9008:   int offset;
                   9009:   int concat;
                   9010: 
                   9011: 
                   9012:   /* Print the definition of the macro HP.  */
                   9013: 
                   9014:   fprintf (of, "#define %s", hp->name);
                   9015: 
                   9016:   if (defn->nargs >= 0) {
                   9017:     int i;
                   9018: 
                   9019:     fprintf (of, "(");
                   9020:     for (i = 0; i < defn->nargs; i++) {
                   9021:       dump_arg_n (defn, i, of);
                   9022:       if (i + 1 < defn->nargs)
                   9023:        fprintf (of, ", ");
                   9024:     }
                   9025:     fprintf (of, ")");
                   9026:   }
                   9027: 
                   9028:   fprintf (of, " ");
                   9029: 
                   9030:   offset = 0;
                   9031:   concat = 0;
                   9032:   for (ap = defn->pattern; ap != NULL; ap = ap->next) {
                   9033:     dump_defn_1 (defn->expansion, offset, ap->nchars, of);
                   9034:     offset += ap->nchars;
1.1.1.7 ! root     9035:     if (!traditional) {
        !          9036:       if (ap->nchars != 0)
        !          9037:        concat = 0;
        !          9038:       if (ap->stringify)
        !          9039:        fprintf (of, " #");
        !          9040:       if (ap->raw_before && !concat)
        !          9041:        fprintf (of, " ## ");
        !          9042:       concat = 0;
        !          9043:     }
1.1       root     9044:     dump_arg_n (defn, ap->argno, of);
1.1.1.7 ! root     9045:     if (!traditional && ap->raw_after) {
1.1       root     9046:       fprintf (of, " ## ");
                   9047:       concat = 1;
                   9048:     }
                   9049:   }
                   9050:   dump_defn_1 (defn->expansion, offset, defn->length - offset, of);
                   9051:   fprintf (of, "\n");
                   9052: }
                   9053: 
                   9054: /* Dump all macro definitions as #defines to stdout.  */
                   9055: 
                   9056: static void
                   9057: dump_all_macros ()
                   9058: {
                   9059:   int bucket;
                   9060: 
                   9061:   for (bucket = 0; bucket < HASHSIZE; bucket++) {
                   9062:     register HASHNODE *hp;
                   9063: 
                   9064:     for (hp = hashtab[bucket]; hp; hp= hp->next) {
                   9065:       if (hp->type == T_MACRO)
                   9066:        dump_single_macro (hp, stdout);
                   9067:     }
                   9068:   }
                   9069: }
                   9070: 
                   9071: /* Output to OF a substring of a macro definition.
                   9072:    BASE is the beginning of the definition.
                   9073:    Output characters START thru LENGTH.
1.1.1.7 ! root     9074:    Unless traditional, discard newlines outside of strings, thus
1.1       root     9075:    converting funny-space markers to ordinary spaces.  */
                   9076: 
                   9077: static void
                   9078: dump_defn_1 (base, start, length, of)
                   9079:      U_CHAR *base;
                   9080:      int start;
                   9081:      int length;
                   9082:      FILE *of;
                   9083: {
                   9084:   U_CHAR *p = base + start;
                   9085:   U_CHAR *limit = base + start + length;
                   9086: 
1.1.1.7 ! root     9087:   if (traditional)
        !          9088:     fwrite (p, sizeof (*p), length, of);
        !          9089:   else {
        !          9090:     while (p < limit) {
        !          9091:       if (*p == '\"' || *p =='\'') {
        !          9092:        U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR,
        !          9093:                                         NULL_PTR, NULL_PTR);
        !          9094:        fwrite (p, sizeof (*p), p1 - p, of);
        !          9095:        p = p1;
        !          9096:       } else {
        !          9097:        if (*p != '\n')
        !          9098:          putc (*p, of);
        !          9099:        p++;
        !          9100:       }
1.1       root     9101:     }
                   9102:   }
                   9103: }
                   9104: 
                   9105: /* Print the name of argument number ARGNUM of macro definition DEFN
                   9106:    to OF.
                   9107:    Recall that DEFN->args.argnames contains all the arg names
                   9108:    concatenated in reverse order with comma-space in between.  */
                   9109: 
                   9110: static void
                   9111: dump_arg_n (defn, argnum, of)
                   9112:      DEFINITION *defn;
                   9113:      int argnum;
                   9114:      FILE *of;
                   9115: {
                   9116:   register U_CHAR *p = defn->args.argnames;
                   9117:   while (argnum + 1 < defn->nargs) {
                   9118:     p = (U_CHAR *) index (p, ' ') + 1;
                   9119:     argnum++;
                   9120:   }
                   9121: 
                   9122:   while (*p && *p != ',') {
                   9123:     putc (*p, of);
                   9124:     p++;
                   9125:   }
                   9126: }
                   9127: 
                   9128: /* Initialize syntactic classifications of characters.  */
                   9129: 
                   9130: static void
                   9131: initialize_char_syntax ()
                   9132: {
                   9133:   register int i;
                   9134: 
                   9135:   /*
                   9136:    * Set up is_idchar and is_idstart tables.  These should be
                   9137:    * faster than saying (is_alpha (c) || c == '_'), etc.
                   9138:    * Set up these things before calling any routines tthat
                   9139:    * refer to them.
                   9140:    */
                   9141:   for (i = 'a'; i <= 'z'; i++) {
                   9142:     is_idchar[i - 'a' + 'A'] = 1;
                   9143:     is_idchar[i] = 1;
                   9144:     is_idstart[i - 'a' + 'A'] = 1;
                   9145:     is_idstart[i] = 1;
                   9146:   }
                   9147:   for (i = '0'; i <= '9'; i++)
                   9148:     is_idchar[i] = 1;
                   9149:   is_idchar['_'] = 1;
                   9150:   is_idstart['_'] = 1;
                   9151:   is_idchar['$'] = dollars_in_ident;
                   9152:   is_idstart['$'] = dollars_in_ident;
                   9153: 
                   9154:   /* horizontal space table */
                   9155:   is_hor_space[' '] = 1;
                   9156:   is_hor_space['\t'] = 1;
                   9157:   is_hor_space['\v'] = 1;
                   9158:   is_hor_space['\f'] = 1;
                   9159:   is_hor_space['\r'] = 1;
                   9160: 
                   9161:   is_space[' '] = 1;
                   9162:   is_space['\t'] = 1;
                   9163:   is_space['\v'] = 1;
                   9164:   is_space['\f'] = 1;
                   9165:   is_space['\n'] = 1;
                   9166:   is_space['\r'] = 1;
                   9167: }
                   9168: 
                   9169: /* Initialize the built-in macros.  */
                   9170: 
                   9171: static void
                   9172: initialize_builtins (inp, outp)
                   9173:      FILE_BUF *inp;
                   9174:      FILE_BUF *outp;
                   9175: {
1.1.1.7 ! root     9176:   install ("__LINE__", -1, T_SPECLINE, 0, NULL_PTR, -1);
        !          9177:   install ("__DATE__", -1, T_DATE, 0, NULL_PTR, -1);
        !          9178:   install ("__FILE__", -1, T_FILE, 0, NULL_PTR, -1);
        !          9179:   install ("__BASE_FILE__", -1, T_BASE_FILE, 0, NULL_PTR, -1);
        !          9180:   install ("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, NULL_PTR, -1);
        !          9181:   install ("__VERSION__", -1, T_VERSION, 0, NULL_PTR, -1);
1.1.1.5   root     9182: #ifndef NO_BUILTIN_SIZE_TYPE
1.1.1.7 ! root     9183:   install ("__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, NULL_PTR, -1);
1.1.1.5   root     9184: #endif
                   9185: #ifndef NO_BUILTIN_PTRDIFF_TYPE
1.1.1.7 ! root     9186:   install ("__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0, NULL_PTR, -1);
1.1.1.5   root     9187: #endif
1.1.1.7 ! root     9188:   install ("__WCHAR_TYPE__", -1, T_WCHAR_TYPE, 0, NULL_PTR, -1);
        !          9189:   install ("__USER_LABEL_PREFIX__",-1,T_USER_LABEL_PREFIX_TYPE,0,NULL_PTR, -1);
        !          9190:   install ("__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE, 0, NULL_PTR, -1);
        !          9191:   install ("__TIME__", -1, T_TIME, 0, NULL_PTR, -1);
1.1       root     9192:   if (!traditional)
1.1.1.7 ! root     9193:     install ("__STDC__", -1, T_CONST, STDC_VALUE, NULL_PTR, -1);
1.1       root     9194:   if (objc)
1.1.1.7 ! root     9195:     install ("__OBJC__", -1, T_CONST, 1, NULL_PTR, -1);
1.1       root     9196: /*  This is supplied using a -D by the compiler driver
                   9197:     so that it is present only when truly compiling with GNU C.  */
1.1.1.7 ! root     9198: /*  install ("__GNUC__", -1, T_CONST, 2, NULL_PTR, -1);  */
1.1       root     9199: 
                   9200:   if (debug_output)
                   9201:     {
                   9202:       char directive[2048];
                   9203:       register struct directive *dp = &directive_table[0];
1.1.1.3   root     9204:       struct tm *timebuf = timestamp ();
1.1       root     9205: 
1.1.1.3   root     9206:       sprintf (directive, " __BASE_FILE__ \"%s\"\n",
1.1       root     9207:               instack[0].nominal_fname);
                   9208:       output_line_command (inp, outp, 0, same_file);
                   9209:       pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
                   9210: 
1.1.1.3   root     9211:       sprintf (directive, " __VERSION__ \"%s\"\n", version_string);
1.1       root     9212:       output_line_command (inp, outp, 0, same_file);
                   9213:       pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
                   9214: 
1.1.1.6   root     9215: #ifndef NO_BUILTIN_SIZE_TYPE
1.1.1.3   root     9216:       sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE);
1.1       root     9217:       output_line_command (inp, outp, 0, same_file);
                   9218:       pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
1.1.1.6   root     9219: #endif
1.1       root     9220: 
1.1.1.6   root     9221: #ifndef NO_BUILTIN_PTRDIFF_TYPE
1.1.1.3   root     9222:       sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE);
1.1       root     9223:       output_line_command (inp, outp, 0, same_file);
                   9224:       pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
1.1.1.6   root     9225: #endif
1.1       root     9226: 
1.1.1.7 ! root     9227:       sprintf (directive, " __WCHAR_TYPE__ %s\n", wchar_type);
1.1       root     9228:       output_line_command (inp, outp, 0, same_file);
                   9229:       pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
                   9230: 
1.1.1.3   root     9231:       sprintf (directive, " __DATE__ \"%s %2d %4d\"\n",
1.1       root     9232:               monthnames[timebuf->tm_mon],
                   9233:               timebuf->tm_mday, timebuf->tm_year + 1900);
                   9234:       output_line_command (inp, outp, 0, same_file);
                   9235:       pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
                   9236: 
1.1.1.3   root     9237:       sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n",
1.1       root     9238:               timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec);
                   9239:       output_line_command (inp, outp, 0, same_file);
                   9240:       pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
                   9241: 
                   9242:       if (!traditional)
                   9243:        {
                   9244:           sprintf (directive, " __STDC__ 1");
                   9245:           output_line_command (inp, outp, 0, same_file);
                   9246:           pass_thru_directive (directive, &directive[strlen (directive)],
                   9247:                               outp, dp);
                   9248:        }
                   9249:       if (objc)
                   9250:        {
                   9251:           sprintf (directive, " __OBJC__ 1");
                   9252:           output_line_command (inp, outp, 0, same_file);
                   9253:           pass_thru_directive (directive, &directive[strlen (directive)],
                   9254:                               outp, dp);
                   9255:        }
                   9256:     }
                   9257: }
                   9258: 
                   9259: /*
                   9260:  * process a given definition string, for initialization
                   9261:  * If STR is just an identifier, define it with value 1.
                   9262:  * If STR has anything after the identifier, then it should
                   9263:  * be identifier=definition.
                   9264:  */
                   9265: 
                   9266: static void
                   9267: make_definition (str, op)
                   9268:      U_CHAR *str;
                   9269:      FILE_BUF *op;
                   9270: {
                   9271:   FILE_BUF *ip;
                   9272:   struct directive *kt;
                   9273:   U_CHAR *buf, *p;
                   9274: 
                   9275:   buf = str;
                   9276:   p = str;
                   9277:   if (!is_idstart[*p]) {
                   9278:     error ("malformed option `-D %s'", str);
                   9279:     return;
                   9280:   }
                   9281:   while (is_idchar[*++p])
                   9282:     ;
1.1.1.7 ! root     9283:   if (*p == '(') {
        !          9284:     while (is_idchar[*++p] || *p == ',' || is_hor_space[*p])
        !          9285:       ;
        !          9286:     if (*p++ != ')')
        !          9287:       p = str;                 /* Error */
        !          9288:   }
1.1       root     9289:   if (*p == 0) {
                   9290:     buf = (U_CHAR *) alloca (p - buf + 4);
                   9291:     strcpy ((char *)buf, str);
                   9292:     strcat ((char *)buf, " 1");
                   9293:   } else if (*p != '=') {
                   9294:     error ("malformed option `-D %s'", str);
                   9295:     return;
                   9296:   } else {
                   9297:     U_CHAR *q;
                   9298:     /* Copy the entire option so we can modify it.  */
                   9299:     buf = (U_CHAR *) alloca (2 * strlen (str) + 1);
                   9300:     strncpy (buf, str, p - str);
                   9301:     /* Change the = to a space.  */
                   9302:     buf[p - str] = ' ';
                   9303:     /* Scan for any backslash-newline and remove it.  */
                   9304:     p++;
                   9305:     q = &buf[p - str];
                   9306:     while (*p) {
1.1.1.7 ! root     9307:       if (*p == '\"' || *p == '\'') {
        !          9308:        int unterminated = 0;
        !          9309:        U_CHAR *p1 = skip_quoted_string (p, p + strlen (p), 0,
        !          9310:                                         NULL_PTR, NULL_PTR, &unterminated);
        !          9311:        if (unterminated)
        !          9312:          return;
        !          9313:        while (p != p1)
        !          9314:          if (*p == '\\' && p[1] == '\n')
        !          9315:            p += 2;
        !          9316:          else
        !          9317:            *q++ = *p++;
        !          9318:       } else if (*p == '\\' && p[1] == '\n')
1.1       root     9319:        p += 2;
                   9320:       /* Change newline chars into newline-markers.  */
                   9321:       else if (*p == '\n')
                   9322:        {
                   9323:          *q++ = '\n';
                   9324:          *q++ = '\n';
                   9325:          p++;
                   9326:        }
                   9327:       else
                   9328:        *q++ = *p++;
                   9329:     }
                   9330:     *q = 0;
                   9331:   }
                   9332:   
                   9333:   ip = &instack[++indepth];
                   9334:   ip->nominal_fname = ip->fname = "*Initialization*";
                   9335: 
                   9336:   ip->buf = ip->bufp = buf;
                   9337:   ip->length = strlen (buf);
                   9338:   ip->lineno = 1;
                   9339:   ip->macro = 0;
                   9340:   ip->free_ptr = 0;
                   9341:   ip->if_stack = if_stack;
                   9342:   ip->system_header_p = 0;
                   9343: 
                   9344:   for (kt = directive_table; kt->type != T_DEFINE; kt++)
                   9345:     ;
                   9346: 
1.1.1.5   root     9347:   /* Pass NULL instead of OP, since this is a "predefined" macro.  */
1.1.1.7 ! root     9348:   do_define (buf, buf + strlen (buf), NULL_PTR, kt);
1.1       root     9349:   --indepth;
                   9350: }
                   9351: 
                   9352: /* JF, this does the work for the -U option */
                   9353: 
                   9354: static void
                   9355: make_undef (str, op)
                   9356:      U_CHAR *str;
                   9357:      FILE_BUF *op;
                   9358: {
                   9359:   FILE_BUF *ip;
                   9360:   struct directive *kt;
                   9361: 
                   9362:   ip = &instack[++indepth];
                   9363:   ip->nominal_fname = ip->fname = "*undef*";
                   9364: 
                   9365:   ip->buf = ip->bufp = str;
                   9366:   ip->length = strlen (str);
                   9367:   ip->lineno = 1;
                   9368:   ip->macro = 0;
                   9369:   ip->free_ptr = 0;
                   9370:   ip->if_stack = if_stack;
                   9371:   ip->system_header_p = 0;
                   9372: 
                   9373:   for (kt = directive_table; kt->type != T_UNDEF; kt++)
                   9374:     ;
                   9375: 
                   9376:   do_undef (str, str + strlen (str), op, kt);
                   9377:   --indepth;
                   9378: }
                   9379: 
                   9380: /* Process the string STR as if it appeared as the body of a #assert.
                   9381:    OPTION is the option name for which STR was the argument.  */
                   9382: 
                   9383: static void
                   9384: make_assertion (option, str)
                   9385:      char *option;
                   9386:      U_CHAR *str;
                   9387: {
                   9388:   FILE_BUF *ip;
                   9389:   struct directive *kt;
                   9390:   U_CHAR *buf, *p, *q;
                   9391: 
                   9392:   /* Copy the entire option so we can modify it.  */
                   9393:   buf = (U_CHAR *) alloca (strlen (str) + 1);
                   9394:   strcpy ((char *) buf, str);
                   9395:   /* Scan for any backslash-newline and remove it.  */
                   9396:   p = q = buf;
                   9397:   while (*p) {
                   9398:     if (*p == '\\' && p[1] == '\n')
                   9399:       p += 2;
                   9400:     else
                   9401:       *q++ = *p++;
                   9402:   }
                   9403:   *q = 0;
                   9404: 
                   9405:   p = buf;
                   9406:   if (!is_idstart[*p]) {
                   9407:     error ("malformed option `%s %s'", option, str);
                   9408:     return;
                   9409:   }
                   9410:   while (is_idchar[*++p])
                   9411:     ;
                   9412:   while (*p == ' ' || *p == '\t') p++;
                   9413:   if (! (*p == 0 || *p == '(')) {
                   9414:     error ("malformed option `%s %s'", option, str);
                   9415:     return;
                   9416:   }
                   9417:   
                   9418:   ip = &instack[++indepth];
                   9419:   ip->nominal_fname = ip->fname = "*Initialization*";
                   9420: 
                   9421:   ip->buf = ip->bufp = buf;
                   9422:   ip->length = strlen (buf);
                   9423:   ip->lineno = 1;
                   9424:   ip->macro = 0;
                   9425:   ip->free_ptr = 0;
                   9426:   ip->if_stack = if_stack;
                   9427:   ip->system_header_p = 0;
                   9428: 
                   9429:   for (kt = directive_table; kt->type != T_ASSERT; kt++)
                   9430:     ;
                   9431: 
                   9432:   /* pass NULL as output ptr to do_define since we KNOW it never
                   9433:      does any output.... */
1.1.1.4   root     9434:   do_assert (buf, buf + strlen (buf) , NULL_PTR, kt);
1.1       root     9435:   --indepth;
                   9436: }
                   9437: 
1.1.1.4   root     9438: /* Append a chain of `struct file_name_list's
                   9439:    to the end of the main include chain.
                   9440:    FIRST is the beginning of the chain to append, and LAST is the end.  */
                   9441: 
                   9442: static void
                   9443: append_include_chain (first, last)
                   9444:      struct file_name_list *first, *last;
                   9445: {
                   9446:   struct file_name_list *dir;
                   9447: 
                   9448:   if (!first || !last)
                   9449:     return;
                   9450: 
                   9451:   if (include == 0)
                   9452:     include = first;
                   9453:   else
                   9454:     last_include->next = first;
                   9455: 
                   9456:   if (first_bracket_include == 0)
                   9457:     first_bracket_include = first;
                   9458: 
                   9459:   for (dir = first; ; dir = dir->next) {
                   9460:     int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
                   9461:     if (len > max_include_len)
                   9462:       max_include_len = len;
                   9463:     if (dir == last)
                   9464:       break;
                   9465:   }
                   9466: 
                   9467:   last->next = NULL;
                   9468:   last_include = last;
                   9469: }
                   9470: 
1.1       root     9471: /* Add output to `deps_buffer' for the -M switch.
                   9472:    STRING points to the text to be output.
1.1.1.7 ! root     9473:    SPACER is ':' for targets, ' ' for dependencies, zero for text
        !          9474:    to be inserted literally.  */
1.1       root     9475: 
                   9476: static void
1.1.1.7 ! root     9477: deps_output (string, spacer)
1.1       root     9478:      char *string;
1.1.1.7 ! root     9479:      int spacer;
1.1       root     9480: {
1.1.1.7 ! root     9481:   int size = strlen (string);
        !          9482: 
1.1       root     9483:   if (size == 0)
1.1.1.7 ! root     9484:     return;
1.1       root     9485: 
                   9486: #ifndef MAX_OUTPUT_COLUMNS
1.1.1.7 ! root     9487: #define MAX_OUTPUT_COLUMNS 72
1.1       root     9488: #endif
1.1.1.7 ! root     9489:   if (spacer
        !          9490:       && deps_column > 0
        !          9491:       && (deps_column + size) > MAX_OUTPUT_COLUMNS)
        !          9492:   {
        !          9493:     deps_output (" \\\n  ", 0);
1.1       root     9494:     deps_column = 0;
                   9495:   }
                   9496: 
1.1.1.7 ! root     9497:   if (deps_size + size + 8 > deps_allocated_size) {
        !          9498:     deps_allocated_size = (deps_size + size + 50) * 2;
1.1       root     9499:     deps_buffer = (char *) xrealloc (deps_buffer, deps_allocated_size);
                   9500:   }
1.1.1.7 ! root     9501:   if (spacer == ' ' && deps_column > 0)
        !          9502:     deps_buffer[deps_size++] = ' ';
1.1       root     9503:   bcopy (string, &deps_buffer[deps_size], size);
                   9504:   deps_size += size;
                   9505:   deps_column += size;
1.1.1.7 ! root     9506:   if (spacer == ':')
        !          9507:     deps_buffer[deps_size++] = ':';
1.1       root     9508:   deps_buffer[deps_size] = 0;
                   9509: }
                   9510: 
                   9511: #if defined(USG) || defined(VMS)
                   9512: #ifndef BSTRING
                   9513: 
                   9514: void
                   9515: bzero (b, length)
                   9516:      register char *b;
                   9517:      register unsigned length;
                   9518: {
                   9519:   while (length-- > 0)
                   9520:     *b++ = 0;
                   9521: }
                   9522: 
                   9523: void
                   9524: bcopy (b1, b2, length)
                   9525:      register char *b1;
                   9526:      register char *b2;
                   9527:      register unsigned length;
                   9528: {
                   9529:   while (length-- > 0)
                   9530:     *b2++ = *b1++;
                   9531: }
                   9532: 
                   9533: int
                   9534: bcmp (b1, b2, length)  /* This could be a macro! */
                   9535:      register char *b1;
                   9536:      register char *b2;
                   9537:      register unsigned length;
                   9538: {
                   9539:    while (length-- > 0)
                   9540:      if (*b1++ != *b2++)
                   9541:        return 1;
                   9542: 
                   9543:    return 0;
                   9544: }
                   9545: #endif /* not BSTRING */
                   9546: #endif /* USG or VMS */
                   9547: 
                   9548: 
                   9549: static void
                   9550: fatal (str, arg)
                   9551:      char *str, *arg;
                   9552: {
                   9553:   fprintf (stderr, "%s: ", progname);
                   9554:   fprintf (stderr, str, arg);
                   9555:   fprintf (stderr, "\n");
                   9556:   exit (FAILURE_EXIT_CODE);
                   9557: }
                   9558: 
                   9559: /* More 'friendly' abort that prints the line and file.
                   9560:    config.h can #define abort fancy_abort if you like that sort of thing.  */
                   9561: 
                   9562: void
                   9563: fancy_abort ()
                   9564: {
                   9565:   fatal ("Internal gcc abort.");
                   9566: }
                   9567: 
                   9568: static void
                   9569: perror_with_name (name)
                   9570:      char *name;
                   9571: {
                   9572:   fprintf (stderr, "%s: ", progname);
1.1.1.7 ! root     9573:   fprintf (stderr, "%s: %s\n", name, my_strerror (errno));
1.1       root     9574:   errors++;
                   9575: }
                   9576: 
                   9577: static void
                   9578: pfatal_with_name (name)
                   9579:      char *name;
                   9580: {
                   9581:   perror_with_name (name);
                   9582: #ifdef VMS
                   9583:   exit (vaxc$errno);
                   9584: #else
                   9585:   exit (FAILURE_EXIT_CODE);
                   9586: #endif
                   9587: }
                   9588: 
1.1.1.5   root     9589: /* Handler for SIGPIPE.  */
                   9590: 
                   9591: static void
                   9592: pipe_closed (signo)
                   9593:      /* If this is missing, some compilers complain.  */
                   9594:      int signo;
                   9595: {
                   9596:   fatal ("output pipe has been closed");
                   9597: }
1.1       root     9598: 
                   9599: static void
                   9600: memory_full ()
                   9601: {
                   9602:   fatal ("Memory exhausted.");
                   9603: }
                   9604: 
                   9605: 
                   9606: char *
                   9607: xmalloc (size)
                   9608:      unsigned size;
                   9609: {
                   9610:   register char *ptr = (char *) malloc (size);
                   9611:   if (ptr != 0) return (ptr);
                   9612:   memory_full ();
                   9613:   /*NOTREACHED*/
                   9614:   return 0;
                   9615: }
                   9616: 
                   9617: static char *
                   9618: xrealloc (old, size)
                   9619:      char *old;
                   9620:      unsigned size;
                   9621: {
                   9622:   register char *ptr = (char *) realloc (old, size);
                   9623:   if (ptr != 0) return (ptr);
                   9624:   memory_full ();
                   9625:   /*NOTREACHED*/
                   9626:   return 0;
                   9627: }
                   9628: 
                   9629: static char *
                   9630: xcalloc (number, size)
                   9631:      unsigned number, size;
                   9632: {
                   9633:   register unsigned total = number * size;
                   9634:   register char *ptr = (char *) malloc (total);
                   9635:   if (ptr != 0) {
                   9636:     if (total > 100)
                   9637:       bzero (ptr, total);
                   9638:     else {
                   9639:       /* It's not too long, so loop, zeroing by longs.
                   9640:         It must be safe because malloc values are always well aligned.  */
                   9641:       register long *zp = (long *) ptr;
                   9642:       register long *zl = (long *) (ptr + total - 4);
                   9643:       register int i = total - 4;
                   9644:       while (zp < zl)
                   9645:        *zp++ = 0;
                   9646:       if (i < 0)
                   9647:        i = 0;
                   9648:       while (i < total)
                   9649:        ptr[i++] = 0;
                   9650:     }
                   9651:     return ptr;
                   9652:   }
                   9653:   memory_full ();
                   9654:   /*NOTREACHED*/
                   9655:   return 0;
                   9656: }
                   9657: 
                   9658: static char *
                   9659: savestring (input)
                   9660:      char *input;
                   9661: {
                   9662:   unsigned size = strlen (input);
                   9663:   char *output = xmalloc (size + 1);
                   9664:   strcpy (output, input);
                   9665:   return output;
                   9666: }
                   9667: 
                   9668: /* Get the file-mode and data size of the file open on FD
                   9669:    and store them in *MODE_POINTER and *SIZE_POINTER.  */
                   9670: 
                   9671: static int
                   9672: file_size_and_mode (fd, mode_pointer, size_pointer)
                   9673:      int fd;
                   9674:      int *mode_pointer;
                   9675:      long int *size_pointer;
                   9676: {
                   9677:   struct stat sbuf;
                   9678: 
                   9679:   if (fstat (fd, &sbuf) < 0) return (-1);
                   9680:   if (mode_pointer) *mode_pointer = sbuf.st_mode;
                   9681:   if (size_pointer) *size_pointer = sbuf.st_size;
                   9682:   return 0;
                   9683: }
1.1.1.6   root     9684: 
                   9685: static void
                   9686: output_dots (fd, depth)
                   9687:      FILE* fd;
                   9688:      int depth;
                   9689: {
                   9690:   while (depth > 0) {
                   9691:     putc ('.', fd);
                   9692:     depth--;
                   9693:   }
                   9694: }
                   9695:   
1.1       root     9696: 
                   9697: #ifdef VMS
                   9698: 
                   9699: /* Under VMS we need to fix up the "include" specification
                   9700:    filename so that everything following the 1st slash is
                   9701:    changed into its correct VMS file specification. */
                   9702: 
                   9703: static void
                   9704: hack_vms_include_specification (fname)
                   9705:      char *fname;
                   9706: {
                   9707:   register char *cp, *cp1, *cp2;
                   9708:   int f, check_filename_before_returning, no_prefix_seen;
                   9709:   char Local[512];
                   9710: 
                   9711:   check_filename_before_returning = 0;
                   9712:   no_prefix_seen = 0;
                   9713: 
                   9714:   /* Ignore leading "./"s */
                   9715:   while (fname[0] == '.' && fname[1] == '/') {
                   9716:     strcpy (fname, fname+2);
                   9717:     no_prefix_seen = 1;                /* mark this for later */
                   9718:   }
                   9719:   /* Look for the boundary between the VMS and UNIX filespecs */
                   9720:   cp = rindex (fname, ']');    /* Look for end of dirspec. */
                   9721:   if (cp == 0) cp = rindex (fname, '>'); /* ... Ditto              */
                   9722:   if (cp == 0) cp = rindex (fname, ':'); /* Look for end of devspec. */
                   9723:   if (cp) {
                   9724:     cp++;
                   9725:   } else {
                   9726:     cp = index (fname, '/');   /* Look for the "/" */
                   9727:   }
                   9728: 
1.1.1.7 ! root     9729:   /*
        !          9730:    * Check if we have a vax-c style '#include filename'
        !          9731:    * and add the missing .h
        !          9732:    */
        !          9733:   if (cp == 0) {
        !          9734:     if (index(fname,'.') == 0)
        !          9735:       strcat(fname, ".h");
        !          9736:   } else {
        !          9737:     if (index(cp,'.') == 0)
        !          9738:       strcat(cp, ".h");
        !          9739:   }
        !          9740: 
1.1       root     9741:   cp2 = Local;                 /* initialize */
                   9742: 
                   9743:   /* We are trying to do a number of things here.  First of all, we are
                   9744:      trying to hammer the filenames into a standard format, such that later
                   9745:      processing can handle them.
                   9746:      
                   9747:      If the file name contains something like [dir.], then it recognizes this
                   9748:      as a root, and strips the ".]".  Later processing will add whatever is
                   9749:      needed to get things working properly.
                   9750:      
                   9751:      If no device is specified, then the first directory name is taken to be
                   9752:      a device name (or a rooted logical). */
                   9753: 
                   9754:   /* See if we found that 1st slash */
                   9755:   if (cp == 0) return;         /* Nothing to do!!! */
                   9756:   if (*cp != '/') return;      /* Nothing to do!!! */
                   9757:   /* Point to the UNIX filename part (which needs to be fixed!) */
                   9758:   cp1 = cp+1;
                   9759:   /* If the directory spec is not rooted, we can just copy
                   9760:      the UNIX filename part and we are done */
                   9761:   if (((cp - fname) > 1) && ((cp[-1] == ']') || (cp[-1] == '>'))) {
                   9762:     if (cp[-2] != '.') {
                   9763:       /*
1.1.1.2   root     9764:        * The VMS part ends in a `]', and the preceding character is not a `.'.
1.1       root     9765:        * We strip the `]', and then splice the two parts of the name in the
                   9766:        * usual way.  Given the default locations for include files in cccp.c,
                   9767:        * we will only use this code if the user specifies alternate locations
                   9768:        * with the /include (-I) switch on the command line.  */
                   9769:       cp -= 1;                 /* Strip "]" */
                   9770:       cp1--;                   /* backspace */
                   9771:     } else {
                   9772:       /*
                   9773:        * The VMS part has a ".]" at the end, and this will not do.  Later
                   9774:        * processing will add a second directory spec, and this would be a syntax
                   9775:        * error.  Thus we strip the ".]", and thus merge the directory specs.
                   9776:        * We also backspace cp1, so that it points to a '/'.  This inhibits the
                   9777:        * generation of the 000000 root directory spec (which does not belong here
                   9778:        * in this case).
                   9779:        */
                   9780:       cp -= 2;                 /* Strip ".]" */
                   9781:       cp1--; };                        /* backspace */
                   9782:   } else {
                   9783: 
                   9784:     /* We drop in here if there is no VMS style directory specification yet.
                   9785:      * If there is no device specification either, we make the first dir a
                   9786:      * device and try that.  If we do not do this, then we will be essentially
                   9787:      * searching the users default directory (as if they did a #include "asdf.h").
                   9788:      *
                   9789:      * Then all we need to do is to push a '[' into the output string. Later
                   9790:      * processing will fill this in, and close the bracket.
                   9791:      */
1.1.1.5   root     9792:     if (cp[-1] != ':') *cp2++ = ':'; /* dev not in spec.  take first dir */
1.1       root     9793:     *cp2++ = '[';              /* Open the directory specification */
                   9794:   }
                   9795: 
                   9796:   /* at this point we assume that we have the device spec, and (at least
                   9797:      the opening "[" for a directory specification.  We may have directories
                   9798:      specified already */
                   9799: 
                   9800:   /* If there are no other slashes then the filename will be
                   9801:      in the "root" directory.  Otherwise, we need to add
                   9802:      directory specifications. */
                   9803:   if (index (cp1, '/') == 0) {
                   9804:     /* Just add "000000]" as the directory string */
                   9805:     strcpy (cp2, "000000]");
                   9806:     cp2 += strlen (cp2);
                   9807:     check_filename_before_returning = 1; /* we might need to fool with this later */
                   9808:   } else {
                   9809:     /* As long as there are still subdirectories to add, do them. */
                   9810:     while (index (cp1, '/') != 0) {
                   9811:       /* If this token is "." we can ignore it */
                   9812:       if ((cp1[0] == '.') && (cp1[1] == '/')) {
                   9813:        cp1 += 2;
                   9814:        continue;
                   9815:       }
                   9816:       /* Add a subdirectory spec. Do not duplicate "." */
                   9817:       if (cp2[-1] != '.' && cp2[-1] != '[' && cp2[-1] != '<')
                   9818:        *cp2++ = '.';
                   9819:       /* If this is ".." then the spec becomes "-" */
                   9820:       if ((cp1[0] == '.') && (cp1[1] == '.') && (cp[2] == '/')) {
                   9821:        /* Add "-" and skip the ".." */
                   9822:        *cp2++ = '-';
                   9823:        cp1 += 3;
                   9824:        continue;
                   9825:       }
                   9826:       /* Copy the subdirectory */
                   9827:       while (*cp1 != '/') *cp2++= *cp1++;
                   9828:       cp1++;                   /* Skip the "/" */
                   9829:     }
                   9830:     /* Close the directory specification */
1.1.1.5   root     9831:     if (cp2[-1] == '.')                /* no trailing periods */
1.1       root     9832:       cp2--;
                   9833:     *cp2++ = ']';
                   9834:   }
                   9835:   /* Now add the filename */
                   9836:   while (*cp1) *cp2++ = *cp1++;
                   9837:   *cp2 = 0;
                   9838:   /* Now append it to the original VMS spec. */
                   9839:   strcpy (cp, Local);
                   9840: 
                   9841:   /* If we put a [000000] in the filename, try to open it first. If this fails,
                   9842:      remove the [000000], and return that name.  This provides flexibility
                   9843:      to the user in that they can use both rooted and non-rooted logical names
                   9844:      to point to the location of the file.  */
                   9845: 
                   9846:   if (check_filename_before_returning && no_prefix_seen) {
                   9847:     f = open (fname, O_RDONLY, 0666);
                   9848:     if (f >= 0) {
                   9849:       /* The file name is OK as it is, so return it as is.  */
                   9850:       close (f);
                   9851:       return;
                   9852:     }
                   9853:     /* The filename did not work.  Try to remove the [000000] from the name,
                   9854:        and return it.  */
                   9855:     cp = index (fname, '[');
                   9856:     cp2 = index (fname, ']') + 1;
                   9857:     strcpy (cp, cp2);          /* this gets rid of it */
                   9858:   }
                   9859:   return;
                   9860: }
                   9861: #endif /* VMS */
                   9862: 
                   9863: #ifdef VMS
                   9864: 
                   9865: /* These are the read/write replacement routines for
                   9866:    VAX-11 "C".  They make read/write behave enough
                   9867:    like their UNIX counterparts that CCCP will work */
                   9868: 
                   9869: static int
                   9870: read (fd, buf, size)
                   9871:      int fd;
                   9872:      char *buf;
                   9873:      int size;
                   9874: {
                   9875: #undef read    /* Get back the REAL read routine */
                   9876:   register int i;
                   9877:   register int total = 0;
                   9878: 
                   9879:   /* Read until the buffer is exhausted */
                   9880:   while (size > 0) {
                   9881:     /* Limit each read to 32KB */
                   9882:     i = (size > (32*1024)) ? (32*1024) : size;
                   9883:     i = read (fd, buf, i);
                   9884:     if (i <= 0) {
                   9885:       if (i == 0) return (total);
1.1.1.5   root     9886:       return (i);
1.1       root     9887:     }
                   9888:     /* Account for this read */
                   9889:     total += i;
                   9890:     buf += i;
                   9891:     size -= i;
                   9892:   }
                   9893:   return (total);
                   9894: }
                   9895: 
                   9896: static int
                   9897: write (fd, buf, size)
                   9898:      int fd;
                   9899:      char *buf;
                   9900:      int size;
                   9901: {
                   9902: #undef write   /* Get back the REAL write routine */
                   9903:   int i;
                   9904:   int j;
                   9905: 
                   9906:   /* Limit individual writes to 32Kb */
                   9907:   i = size;
                   9908:   while (i > 0) {
                   9909:     j = (i > (32*1024)) ? (32*1024) : i;
                   9910:     if (write (fd, buf, j) < 0) return (-1);
                   9911:     /* Account for the data written */
                   9912:     buf += j;
                   9913:     i -= j;
                   9914:   }
                   9915:   return (size);
                   9916: }
                   9917: 
                   9918: /* The following wrapper functions supply additional arguments to the VMS
                   9919:    I/O routines to optimize performance with file handling.  The arguments
                   9920:    are:
                   9921:      "mbc=16" - Set multi-block count to 16 (use a 8192 byte buffer).
                   9922:      "deq=64" - When extending the file, extend it in chunks of 32Kbytes.
                   9923:      "fop=tef"- Truncate unused portions of file when closing file.
                   9924:      "shr=nil"- Disallow file sharing while file is open.
                   9925:  */
                   9926: 
                   9927: static FILE *
                   9928: freopen (fname, type, oldfile)
                   9929:      char *fname;
                   9930:      char *type;
                   9931:      FILE *oldfile;
                   9932: {
                   9933: #undef freopen /* Get back the REAL fopen routine */
                   9934:   if (strcmp (type, "w") == 0)
                   9935:     return freopen (fname, type, oldfile, "mbc=16", "deq=64", "fop=tef", "shr=nil");
                   9936:   return freopen (fname, type, oldfile, "mbc=16");
                   9937: }
                   9938: 
                   9939: static FILE *
                   9940: fopen (fname, type)
                   9941:      char *fname;
                   9942:      char *type;
                   9943: {
                   9944: #undef fopen   /* Get back the REAL fopen routine */
                   9945:   if (strcmp (type, "w") == 0)
                   9946:     return fopen (fname, type, "mbc=16", "deq=64", "fop=tef", "shr=nil");
                   9947:   return fopen (fname, type, "mbc=16");
                   9948: }
                   9949: 
                   9950: static int 
                   9951: open (fname, flags, prot)
                   9952:      char *fname;
                   9953:      int flags;
                   9954:      int prot;
                   9955: {
                   9956: #undef open    /* Get back the REAL open routine */
                   9957:   return open (fname, flags, prot, "mbc=16", "deq=64", "fop=tef");
                   9958: }
                   9959: 
1.1.1.4   root     9960: /* Avoid run-time library bug, where copying M out of N+M characters with
                   9961:    N >= 65535 results in VAXCRTL's strncat falling into an infinite loop.
                   9962:    gcc-cpp exercises this particular bug.  */
                   9963: 
                   9964: static char *
                   9965: strncat (dst, src, cnt)
                   9966:      char *dst;
                   9967:      const char *src;
                   9968:      unsigned cnt;
                   9969: {
                   9970:   register char *d = dst, *s = (char *) src;
                   9971:   register int n = cnt;        /* convert to _signed_ type */
                   9972: 
                   9973:   while (*d) d++;      /* advance to end */
                   9974:   while (--n >= 0)
                   9975:     if (!(*d++ = *s++)) break;
                   9976:   if (n < 0) *d = '\0';
                   9977:   return dst;
                   9978: }
1.1       root     9979: #endif /* VMS */

unix.superglobalmegacorp.com

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