Annotation of gcc/cccp.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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