OSDN Git Service

* configure.in (all_headers, all_lib2funcs): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / tradcpp.c
1 /* C Compatible Compiler Preprocessor (CCCP)
2 Copyright (C) 1986, 1987, 1989, 2000, 2001 Free Software Foundation, Inc.
3                     Written by Paul Rubin, June 1986
4                     Adapted to ANSI C, Richard Stallman, Jan 1987
5                     Dusted off, polished, and adapted for use as traditional
6                     preprocessor only, Zack Weinberg, Jul 2000
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "version.h"
25 #include "cppdefault.h"
26 #include "tradcpp.h"
27 #include "mkdeps.h"
28 #include "intl.h"
29
30 typedef unsigned char U_CHAR;
31
32 /* Name under which this program was invoked.  */
33
34 static const char *progname;
35
36 /* Current maximum length of directory names in the search path
37    for include files.  (Altered as we get more of them.)  */
38
39 size_t max_include_len;
40
41 /* Nonzero means copy comments into the output file.  */
42
43 int put_out_comments = 0;
44
45 /* mkdeps.h opaque structure that encapsulates dependency information.  */
46 struct deps *deps;
47
48 /* Nonzero means print the names of included files rather than
49    the preprocessed output.  1 means just the #include "...",
50    2 means #include <...> as well.  */
51
52 int print_deps = 0;
53
54 /* Nonzero means print dummy targets for each header file.  */
55
56 int print_deps_phony_targets = 0;
57
58 /* If true, fopen (deps_file, "a") else fopen (deps_file, "w").  */
59
60 int deps_append = 0;
61
62 /* File name which deps are being written to.  This is 0 if deps are
63    being written to stdout.  */
64
65 const char *deps_file = 0;
66
67 /* Nonzero if missing .h files in -M output are assumed to be
68    generated files and not errors.  */
69
70 int deps_missing_files = 0;
71        
72 /* Nonzero means don't output line number information.  */
73
74 int no_line_commands;
75
76 /* Nonzero means inhibit output of the preprocessed text
77    and instead output the definitions of all user-defined macros
78    in a form suitable for use as input to cccp.  */
79
80 int dump_macros;
81
82 /* Nonzero means don't print warning messages.  -w.  */
83
84 int inhibit_warnings = 0;
85
86 /* Non-0 means don't output the preprocessed program.  */
87 int inhibit_output = 0;
88
89 /* Nonzero means warn if slash-star appears in a comment.  */
90
91 int warn_comments;
92
93 /* Nonzero causes output not to be done,
94    but directives such as #define that have side effects
95    are still obeyed.  */
96
97 int no_output;
98
99 /* Value of __USER_LABEL_PREFIX__.  Target-dependent, also controlled
100    by -f(no-)leading-underscore.  */
101 static const char *user_label_prefix;
102
103 /* I/O buffer structure.
104    The `fname' field is nonzero for source files and #include files
105    and for the dummy text used for -D and -U.
106    It is zero for rescanning results of macro expansion
107    and for expanding macro arguments.  */
108 #define INPUT_STACK_MAX 200
109 struct file_name_list;
110 struct file_buf {
111   const char *fname;
112   int lineno;
113   int length;
114   U_CHAR *buf;
115   U_CHAR *bufp;
116   /* Macro that this level is the expansion of.
117      Included so that we can reenable the macro
118      at the end of this level.  */
119   struct hashnode *macro;
120   /* Value of if_stack at start of this file.
121      Used to prohibit unmatched #endif (etc) in an include file.  */
122   struct if_stack *if_stack;
123   /* Object to be freed at end of input at this level.  */
124   U_CHAR *free_ptr;
125   /* Position to start scanning for #include_next in this file.  */
126   struct file_name_list *next_header_dir;
127 } instack[INPUT_STACK_MAX];
128
129 typedef struct file_buf FILE_BUF;
130
131 /* Current nesting level of input sources.
132    `instack[indepth]' is the level currently being read.  */
133 int indepth = -1;
134 #define CHECK_DEPTH(code) \
135   if (indepth >= (INPUT_STACK_MAX - 1))                                 \
136     {                                                                   \
137       error_with_line (line_for_error (instack[indepth].lineno),        \
138                        "macro or #include recursion too deep");         \
139       code;                                                             \
140     }
141
142 /* Current depth in #include directives that use <...>.  */
143 int system_include_depth = 0;
144
145 /* The output buffer.  Its LENGTH field is the amount of room allocated
146    for the buffer, not the number of chars actually present.  To get
147    that, subtract outbuf.buf from outbuf.bufp. */
148
149 #define OUTBUF_SIZE 10  /* initial size of output buffer */
150 FILE_BUF outbuf;
151
152 /* Grow output buffer OBUF points at
153    so it can hold at least NEEDED more chars.  */
154
155 #define check_expand(OBUF, NEEDED) do { \
156   if ((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED)) \
157     grow_outbuf ((OBUF), (NEEDED)); \
158  } while (0)
159
160 struct file_name_list
161   {
162     struct file_name_list *next;
163     const char *fname;
164   };
165
166 struct file_name_list *include = 0;     /* First dir to search */
167         /* First dir to search for <file> */
168 struct file_name_list *first_bracket_include = 0;
169 struct file_name_list *last_include = 0;        /* Last in chain */
170
171 /* List of included files that contained #once.  */
172 struct file_name_list *dont_repeat_files = 0;
173
174 /* List of other included files.  */
175 struct file_name_list *all_include_files = 0;
176 \f
177 /* Structure allocated for every #define.  For a simple replacement
178    such as
179         #define foo bar ,
180    nargs = -1, the `pattern' list is null, and the expansion is just
181    the replacement text.  Nargs = 0 means a functionlike macro with no args,
182    e.g.,
183        #define getchar() getc (stdin) .
184    When there are args, the expansion is the replacement text with the
185    args squashed out, and the reflist is a list describing how to
186    build the output from the input: e.g., "3 chars, then the 1st arg,
187    then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
188    The chars here come from the expansion.  Whatever is left of the
189    expansion after the last arg-occurrence is copied after that arg.
190    Note that the reflist can be arbitrarily long---
191    its length depends on the number of times the arguments appear in
192    the replacement text, not how many args there are.  Example:
193    #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
194    pattern list
195      { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
196    where (x, y) means (nchars, argno). */
197
198 typedef struct definition DEFINITION;
199 struct definition {
200   int nargs;
201   int length;                   /* length of expansion string */
202   U_CHAR *expansion;
203   struct reflist {
204     struct reflist *next;
205     char stringify;             /* nonzero if this arg was preceded by a
206                                    # operator. */
207     char raw_before;            /* Nonzero if a ## operator before arg. */
208     char raw_after;             /* Nonzero if a ## operator after arg. */
209     int nchars;                 /* Number of literal chars to copy before
210                                    this arg occurrence.  */
211     int argno;                  /* Number of arg to substitute (origin-0) */
212   } *pattern;
213   /* Names of macro args, concatenated in reverse order
214      with comma-space between them.
215      The only use of this is that we warn on redefinition
216      if this differs between the old and new definitions.  */
217   const U_CHAR *argnames;
218 };
219
220 /* Chained list of answers to an assertion.  */
221 struct answer
222 {
223   struct answer *next;
224   const unsigned char *answer;
225   size_t len;
226 };
227
228 /* different kinds of things that can appear in the value field
229    of a hash node.  Actually, this may be useless now. */
230 union hashval {
231   const char *cpval;
232   DEFINITION *defn;
233   struct answer *answers;
234 };
235
236 /* The structure of a node in the hash table.  The hash table
237    has entries for all tokens defined by #define commands (type T_MACRO),
238    plus some special tokens like __LINE__ (these each have their own
239    type, and the appropriate code is run when that type of node is seen.
240    It does not contain control words like "#define", which are recognized
241    by a separate piece of code. */
242
243 /* different flavors of hash nodes --- also used in keyword table */
244 enum node_type {
245  T_DEFINE = 1,  /* `#define' */
246  T_INCLUDE,     /* `#include' */
247  T_INCLUDE_NEXT,/* `#include_next' */
248  T_IFDEF,       /* `#ifdef' */
249  T_IFNDEF,      /* `#ifndef' */
250  T_IF,          /* `#if' */
251  T_ELSE,        /* `#else' */
252  T_ELIF,        /* `#elif' */
253  T_UNDEF,       /* `#undef' */
254  T_LINE,        /* `#line' */
255  T_ENDIF,       /* `#endif' */
256  T_ERROR,       /* `#error' */
257  T_WARNING,     /* `#warning' */
258  T_ASSERT,      /* `#assert' */
259  T_UNASSERT,    /* `#unassert' */
260  T_SPECLINE,    /* special symbol `__LINE__' */
261  T_DATE,        /* `__DATE__' */
262  T_FILE,        /* `__FILE__' */
263  T_BASE_FILE,   /* `__BASE_FILE__' */
264  T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
265  T_VERSION,     /* `__VERSION__' */
266  T_TIME,        /* `__TIME__' */
267  T_CONST,       /* Constant value, used by `__STDC__' */
268  T_MACRO,       /* macro defined by `#define' */
269  T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
270  T_UNUSED       /* Used for something not defined.  */
271 };
272
273 struct hashnode {
274   struct hashnode *next;        /* double links for easy deletion */
275   struct hashnode *prev;
276   struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash
277                                    chain is kept, in case the node is the head
278                                    of the chain and gets deleted. */
279   enum node_type type;          /* type of special token */
280   int length;                   /* length of token, for quick comparison */
281   U_CHAR *name;                 /* the actual name */
282   union hashval value;          /* pointer to expansion, or whatever */
283 };
284
285 typedef struct hashnode HASHNODE;
286
287 static HASHNODE *parse_assertion PARAMS ((const unsigned char *,
288                                           const unsigned char *,
289                                           struct answer **, int));
290 static struct answer **find_answer PARAMS ((HASHNODE *,
291                                             const struct answer *));
292 static int parse_answer PARAMS ((const unsigned char *, const unsigned char *,
293                                  struct answer **, int));
294 static unsigned char *canonicalize_text PARAMS ((const unsigned char *,
295                                                  const unsigned char *,
296                                                  const unsigned char **));
297
298 /* Some definitions for the hash table.  The hash function MUST be
299    computed as shown in hashf () below.  That is because the rescan
300    loop computes the hash value `on the fly' for most tokens,
301    in order to avoid the overhead of a lot of procedure calls to
302    the hashf () function.  Hashf () only exists for the sake of
303    politeness, for use when speed isn't so important. */
304
305 #define HASHSIZE 1403
306 HASHNODE *hashtab[HASHSIZE];
307 #define HASHSTEP(old, c) ((old << 2) + c)
308 #define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
309
310 /* `struct directive' defines one #-directive, including how to handle it.  */
311
312 struct directive {
313   int length;                   /* Length of name */
314   void (*func) PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
315                                 /* Function to handle directive */
316   const char *name;             /* Name of directive */
317   enum node_type type;          /* Code which describes which directive. */
318 };
319
320 /* Last arg to output_line_command.  */
321 enum file_change_code {same_file, enter_file, leave_file};
322
323 /* This structure represents one parsed argument in a macro call.
324    `raw' points to the argument text as written (`raw_length' is its length).
325    `expanded' points to the argument's macro-expansion
326    (its length is `expand_length').
327    `stringified_length' is the length the argument would have
328    if stringified.
329    `free1' and `free2', if nonzero, point to blocks to be freed
330    when the macro argument data is no longer needed.  */
331
332 struct argdata {
333   U_CHAR *raw, *expanded;
334   int raw_length, expand_length;
335   int stringified_length;
336   U_CHAR *free1, *free2;
337   char newlines;
338   char comments;
339 };
340
341 /* The arglist structure is built by do_define to tell
342    collect_definition where the argument names begin.  That
343    is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
344    would contain pointers to the strings x, y, and z.
345    Collect_definition would then build a DEFINITION node,
346    with reflist nodes pointing to the places x, y, and z had
347    appeared.  So the arglist is just convenience data passed
348    between these two routines.  It is not kept around after
349    the current #define has been processed and entered into the
350    hash table. */
351
352 struct arglist {
353   struct arglist *next;
354   U_CHAR *name;
355   int length;
356   int argno;
357 };
358
359 /* Function prototypes.  */
360
361 static void do_define   PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
362 static void do_error    PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
363 static void do_warning  PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
364 static void do_line     PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
365 static void do_include  PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
366 static void do_include_next     PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
367 static void do_undef    PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
368 static void do_if       PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
369 static void do_ifdef    PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
370 static void do_ifndef   PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
371 static void do_else     PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
372 static void do_elif     PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
373 static void do_endif    PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
374 static void do_assert   PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
375 static void do_unassert PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
376 static void do_xifdef   PARAMS ((U_CHAR *, U_CHAR *, enum node_type));
377
378 static struct hashnode *install PARAMS ((const U_CHAR *, int, enum node_type, int));
379 static int hashf                 PARAMS ((const U_CHAR *, int, int));
380 static int compare_defs  PARAMS ((DEFINITION *, DEFINITION *));
381 static int comp_def_part         PARAMS ((int, const U_CHAR *, int,
382                                           const U_CHAR *, int, int));
383 static void delete_macro         PARAMS ((HASHNODE *));
384
385 /* First arg to v_message.  */
386 enum msgtype { MT_WARNING = 0, MT_ERROR, MT_FATAL };
387 static void v_message            PARAMS ((enum msgtype mtype, int line,
388                                           const char *msgid, va_list ap))
389      ATTRIBUTE_PRINTF (3, 0);
390
391 static int line_for_error        PARAMS ((int));
392
393 /* We know perfectly well which file this is, so we don't need to
394    use __FILE__.  */
395 #undef abort
396 #if (GCC_VERSION >= 2007)
397 #define abort() fancy_abort(__LINE__, __FUNCTION__)
398 #else
399 #define abort() fancy_abort(__LINE__, 0);
400 #endif
401
402 static void macroexpand         PARAMS ((HASHNODE *, FILE_BUF *));
403 static void special_symbol      PARAMS ((HASHNODE *, FILE_BUF *));
404 static void dump_all_macros     PARAMS ((void));
405 static void dump_defn_1         PARAMS ((const U_CHAR *, int, int));
406 static void dump_arg_n          PARAMS ((DEFINITION *, int));
407 static void conditional_skip    PARAMS ((FILE_BUF *, int, enum node_type));
408 static void skip_if_group       PARAMS ((FILE_BUF *, int));
409 static void output_line_command PARAMS ((FILE_BUF *, FILE_BUF *,
410                                          int, enum file_change_code));
411
412 static int eval_if_expression   PARAMS ((const U_CHAR *, int));
413
414 static void output_deps         PARAMS ((void));
415 static void initialize_builtins PARAMS ((void));
416 static void run_directive       PARAMS ((const char *, size_t,
417                                          enum node_type));
418 static void make_definition     PARAMS ((const char *));
419 static void make_undef          PARAMS ((const char *));
420 static void make_assertion      PARAMS ((const char *));
421
422 static void grow_outbuf         PARAMS ((FILE_BUF *, int));
423 static int handle_directive     PARAMS ((FILE_BUF *, FILE_BUF *));
424 static void process_include     PARAMS ((struct file_name_list *,
425                                          const U_CHAR *, int, int, FILE_BUF *));
426 static void finclude            PARAMS ((int, const char *,
427                                          struct file_name_list *, FILE_BUF *));
428 static void init_dependency_output PARAMS ((void));
429 static void rescan              PARAMS ((FILE_BUF *, int));
430 static void newline_fix         PARAMS ((U_CHAR *));
431 static void name_newline_fix    PARAMS ((U_CHAR *));
432 static U_CHAR *macarg1          PARAMS ((U_CHAR *, const U_CHAR *, int *,
433                                          int *, int *));
434 static const char *macarg       PARAMS ((struct argdata *));
435 static int discard_comments     PARAMS ((U_CHAR *, int, int));
436 static int file_size_and_mode   PARAMS ((int, int *, long *));
437
438 static U_CHAR *skip_to_end_of_comment PARAMS ((FILE_BUF *, int *));
439 static U_CHAR *skip_quoted_string     PARAMS ((const U_CHAR *, const U_CHAR *,
440                                                int, int *, int *, int *));
441
442 int main                PARAMS ((int, char **));
443
444 /* Convenience.  Write U"string" to get an unsigned string constant.  */
445 #define U (const unsigned char *)
446
447 /* Here is the actual list of #-directives, most-often-used first.  */
448
449 struct directive directive_table[] = {
450   {  6, do_define,  "define",  T_DEFINE  },
451   {  7, do_include, "include", T_INCLUDE },
452   {  5, do_endif,   "endif",   T_ENDIF   },
453   {  5, do_ifdef,   "ifdef",   T_IFDEF   },
454   {  2, do_if,      "if",      T_IF,     },
455   {  4, do_else,    "else",    T_ELSE    },
456   {  6, do_ifndef,  "ifndef",  T_IFNDEF  },
457   {  5, do_undef,   "undef",   T_UNDEF   },
458   {  4, do_line,    "line",    T_LINE    },
459   {  4, do_elif,    "elif",    T_ELIF    },
460   {  5, do_error,   "error",   T_ERROR   },
461   {  7, do_warning, "warning", T_WARNING },
462   { 12, do_include_next, "include_next", T_INCLUDE_NEXT },
463   {  6, do_assert,  "assert",  T_ASSERT  },
464   {  8, do_unassert,"unassert",T_UNASSERT},
465   {  -1, 0, "", T_UNUSED},
466 };
467
468 #define SKIP_WHITE_SPACE(p) do { while (is_nvspace(*p)) p++; } while (0)
469 #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space(*p)) p++; } while (0)
470   
471 int errors = 0;                 /* Error counter for exit code */
472
473 static FILE_BUF expand_to_temp_buffer PARAMS ((const U_CHAR *, const U_CHAR *, int));
474 static DEFINITION *collect_expansion  PARAMS ((U_CHAR *, U_CHAR *, int,
475                                                struct arglist *));
476
477 /* Stack of conditionals currently in progress
478    (including both successful and failing conditionals).  */
479
480 struct if_stack {
481   struct if_stack *next;        /* for chaining to the next stack frame */
482   const char *fname;            /* copied from input when frame is made */
483   int lineno;                   /* similarly */
484   int if_succeeded;             /* true if a leg of this if-group
485                                     has been passed through rescan */
486   enum node_type type;          /* type of last directive seen in this group */
487 };
488 typedef struct if_stack IF_STACK_FRAME;
489 IF_STACK_FRAME *if_stack = NULL;
490
491 /* Nonzero means -I- has been seen,
492    so don't look for #include "foo" the source-file directory.  */
493 int ignore_srcdir;
494
495 /* Pending directives.  */
496 enum pending_dir_t {PD_NONE = 0, PD_DEFINE, PD_UNDEF, PD_ASSERTION, PD_FILE};
497
498 typedef struct pending_dir pending_dir;
499 struct pending_dir
500 {
501   const char *arg;
502   enum pending_dir_t type;
503 };
504
505 int
506 main (argc, argv)
507      int argc;
508      char **argv;
509 {
510   int st_mode;
511   long st_size;
512   const char *in_fname, *out_fname;
513   int f, i;
514   FILE_BUF *fp;
515   pending_dir *pend = (pending_dir *) xcalloc (argc, sizeof (pending_dir));
516   int no_standard_includes = 0;
517
518   hex_init ();
519
520 #ifdef RLIMIT_STACK
521   /* Get rid of any avoidable limit on stack size.  */
522   {
523     struct rlimit rlim;
524
525     /* Set the stack limit huge so that alloca (particularly stringtab
526      * in dbxread.c) does not fail. */
527     getrlimit (RLIMIT_STACK, &rlim);
528     rlim.rlim_cur = rlim.rlim_max;
529     setrlimit (RLIMIT_STACK, &rlim);
530   }
531 #endif /* RLIMIT_STACK defined */
532
533   progname = argv[0];
534
535   in_fname = NULL;
536   out_fname = NULL;
537
538   no_line_commands = 0;
539   dump_macros = 0;
540   no_output = 0;
541
542   max_include_len = cpp_GCC_INCLUDE_DIR_len + 7;  /* ??? */
543
544   gcc_init_libintl ();
545
546   /* It's simplest to just create this struct whether or not it will
547      be needed.  */
548   deps = deps_init ();
549
550   /* Process switches and find input file name.  */
551
552   for (i = 1; i < argc; i++) {
553     if (argv[i][0] != '-') {
554       if (out_fname != NULL)
555         fatal ("usage: %s [switches] input output", argv[0]);
556       else if (in_fname != NULL)
557         out_fname = argv[i];
558       else
559         in_fname = argv[i];
560     } else {
561       int c = argv[i][1];
562
563       switch (c) {
564       case 'E':
565       case '$':
566         break;  /* Ignore for compatibility with ISO/extended cpp.  */
567
568       case 'l':
569         if (!strcmp (argv[i], "-lang-c++")
570             || !strcmp (argv[i], "-lang-objc++"))
571           fatal ("-traditional is not supported in C++");
572         else if (!strcmp (argv[i], "-lang-c89"))
573           fatal ("-traditional and -ansi are mutually exclusive");
574         else if (!strcmp (argv[i], "-lang-objc"))
575           pend[i].type = PD_DEFINE, pend[i].arg = "__OBJC__";
576         else if (!strcmp (argv[i], "-lang-asm"))
577           pend[i].type = PD_DEFINE, pend[i].arg = "__ASSEMBLER__";
578         else if (!strcmp (argv[i], "-lang-fortran"))
579           pend[i].type = PD_DEFINE, pend[i].arg = "_LANGUAGE_FORTRAN";
580         /* All other possibilities ignored.  */
581         break;
582
583       case 'i':
584         if (!strcmp (argv[i], "-include"))
585           {
586             if (i + 1 == argc)
587               fatal ("filename missing after -i option");
588             else
589               pend[i].type = PD_FILE, pend[i].arg = argv[i + 1], i++;
590           }
591         else if (!strcmp (argv[i], "-iprefix"))
592           i++; /* Ignore for compatibility */
593         else if (!strcmp (argv[i], "-isystem")
594                  || !strcmp (argv[i], "-iwithprefix")
595                  || !strcmp (argv[i], "-iwithprefixbefore")
596                  || !strcmp (argv[i], "-idirafter"))
597           goto add_include;  /* best we can do */
598           
599         break;
600
601       case 'o':
602         if (out_fname != NULL)
603           fatal ("output filename specified twice");
604         if (i + 1 == argc)
605           fatal ("filename missing after -o option");
606         out_fname = argv[++i];
607         if (!strcmp (out_fname, "-"))
608           out_fname = "";
609         break;
610
611       case 'w':
612         inhibit_warnings = 1;
613         break;
614
615       case 'W':
616         if (!strcmp (argv[i], "-Wcomments"))
617           warn_comments = 1;
618         else if (!strcmp (argv[i], "-Wcomment"))
619           warn_comments = 1;
620         else if (!strcmp (argv[i], "-Wall")) {
621           warn_comments = 1;
622         }
623         break;
624
625       case 'f':
626         if (!strcmp (argv[i], "-fleading-underscore"))
627           user_label_prefix = "_";
628         else if (!strcmp (argv[i], "-fno-leading-underscore"))
629           user_label_prefix = "";
630         break;
631
632       case 'M':
633         {
634           char *p = NULL;
635
636           /* -MD and -MMD for tradcpp are deprecated and undocumented
637              (use -M or -MM with -MF instead), and probably should be
638              removed with the next major GCC version.  For the moment
639              we allow these for the benefit of Automake 1.4, which
640              uses these when dependency tracking is enabled.  Automake
641              1.5 will fix this.  */
642           if (!strncmp (argv[i], "-MD", 3)) {
643             p = argv[i] + 3;
644             print_deps = 2;
645           } else if (!strncmp (argv[i], "-MMD", 4)) {
646             p = argv[i] + 4;
647             print_deps = 1;
648           } else if (!strcmp (argv[i], "-M")) {
649             print_deps = 2;
650           } else if (!strcmp (argv[i], "-MM")) {
651             print_deps = 1;
652           } else if (!strcmp (argv[i], "-MG")) {
653             deps_missing_files = 1;
654           } else if (!strcmp (argv[i], "-MF")) {
655             p = argv[i] + 3;
656           } else if (!strcmp (argv[i], "-MP")) {
657             print_deps_phony_targets = 1;
658           } else if (!strcmp (argv[i], "-MQ") || !strcmp (argv[i], "-MT")) {
659             /* Add a target.  -MQ quotes for Make.  */
660             const char *tgt = argv[i] + 3;
661             int quoted = argv[i][2] == 'Q';
662
663             if (*tgt == '\0' && i + 1 == argc)
664               fatal ("target missing after %s option", argv[i]);
665             else
666               {
667                 if (*tgt == '\0')
668                   tgt = argv[++i];
669               
670                 deps_add_target (deps, tgt, quoted);
671               }
672           }
673
674           if (p) {
675             if (*p)
676               deps_file = p;
677             else if (i + 1 == argc)
678               fatal ("filename missing after %s option", argv[i]);
679             else
680               deps_file = argv[++i];
681           }
682         }
683         break;
684
685       case 'd':
686         dump_macros = 1;
687         no_output = 1;
688         break;
689
690       case 'v':
691         fprintf (stderr, "GNU traditional CPP version %s\n", version_string);
692         break;
693
694       case 'D':
695       case 'U':
696       case 'A':
697         {
698           char *p;
699
700           if (argv[i][2] != 0)
701             p = argv[i] + 2;
702           else if (i + 1 == argc)
703             fatal ("macro name missing after -%c option", c);
704           else
705             p = argv[++i];
706
707           if (c == 'D')
708             pend[i].type = PD_DEFINE;
709           else if (c == 'U')
710             pend[i].type = PD_UNDEF;
711           else
712             pend[i].type = PD_ASSERTION;
713           pend[i].arg = p;
714         }
715         break;
716
717       case 'C':
718         put_out_comments = 1;
719         break;
720
721       case 'p':
722         if (!strcmp (argv[i], "-pedantic"))
723           fatal ("-pedantic and -traditional are mutually exclusive");
724         break;
725
726       case 't':
727         if (!strcmp (argv[i], "-trigraphs"))
728           fatal ("-trigraphs and -traditional are mutually exclusive");
729         break;
730
731       case 'P':
732         no_line_commands = 1;
733         break;
734
735       case 'I':                 /* Add directory to path for includes.  */
736       add_include:
737         {
738           struct file_name_list *dirtmp;
739
740           if (! ignore_srcdir && !strcmp (argv[i] + 2, "-"))
741             ignore_srcdir = 1;
742           else {
743             dirtmp = (struct file_name_list *)
744               xmalloc (sizeof (struct file_name_list));
745             dirtmp->next = 0;           /* New one goes on the end */
746             if (include == 0)
747               include = dirtmp;
748             else
749               last_include->next = dirtmp;
750             last_include = dirtmp;      /* Tail follows the last one */
751             if (argv[i][1] == 'I' && argv[i][2] != 0)
752               dirtmp->fname = argv[i] + 2;
753             else if (i + 1 == argc)
754               fatal ("directory name missing after -I option");
755             else
756               dirtmp->fname = argv[++i];
757             if (strlen (dirtmp->fname) > max_include_len)
758               max_include_len = strlen (dirtmp->fname);
759             if (ignore_srcdir && first_bracket_include == 0)
760               first_bracket_include = dirtmp;
761             }
762         }
763         break;
764
765       case 'n':
766         /* -nostdinc causes no default include directories.
767            You must specify all include-file directories with -I.  */
768         no_standard_includes = 1;
769         break;
770
771       case '\0': /* JF handle '-' as file name meaning stdin or stdout */
772         if (in_fname == NULL) {
773           in_fname = "";
774           break;
775         } else if (out_fname == NULL) {
776           out_fname = "";
777           break;
778         }       /* else fall through into error */
779
780       default:
781         fatal ("invalid option `%s'", argv[i]);
782       }
783     }
784   }
785
786   init_dependency_output ();
787
788   /* After checking the environment variables, check if -M or -MM has
789      not been specified, but other -M options have.  */
790   if (print_deps == 0
791       && (deps_missing_files || deps_file || print_deps_phony_targets))
792     fatal ("you must additionally specify either -M or -MM");
793
794   if (user_label_prefix == 0)
795     user_label_prefix = USER_LABEL_PREFIX;
796
797   if (print_deps)
798     {
799       /* Set the default target (if there is none already), and
800          the dependency on the main file.  */
801       deps_add_default_target (deps, in_fname);
802
803       deps_add_dep (deps, in_fname);
804     }
805
806   /* Install __LINE__, etc.  Must follow option processing.  */
807   initialize_builtins ();
808
809   /* Do defines specified with -D and undefines specified with -U.  */
810   for (i = 1; i < argc; i++)
811     if (pend[i].type == PD_DEFINE)
812       make_definition (pend[i].arg);
813     else if (pend[i].type == PD_UNDEF)
814       make_undef (pend[i].arg);
815     else if (pend[i].type == PD_ASSERTION)
816       make_assertion (pend[i].arg);
817
818   /* Unless -fnostdinc,
819      tack on the standard include file dirs to the specified list */
820   if (!no_standard_includes) {
821     const struct default_include *di;
822     struct file_name_list *old_last_include = last_include;
823     struct file_name_list *dirtmp;
824     for (di = cpp_include_defaults; di->fname; di++) {
825       if (di->cplusplus)
826         continue;
827       dirtmp = (struct file_name_list *)
828         xmalloc (sizeof (struct file_name_list));
829       dirtmp->next = 0;         /* New one goes on the end */
830       if (include == 0)
831         include = dirtmp;
832       else
833         last_include->next = dirtmp;
834       last_include = dirtmp;    /* Tail follows the last one */
835       dirtmp->fname = di->fname;
836       if (strlen (dirtmp->fname) > max_include_len)
837         max_include_len = strlen (dirtmp->fname);
838     }
839
840     if (ignore_srcdir && first_bracket_include == 0)
841       first_bracket_include = old_last_include->next;
842   }
843
844   /* Initialize output buffer */
845
846   outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);
847   outbuf.bufp = outbuf.buf;
848   outbuf.length = OUTBUF_SIZE;
849
850   /* Scan the -i files before the main input.
851      Much like #including them, but with no_output set
852      so that only their macro definitions matter.  */
853
854   no_output++;
855   indepth++;
856   for (i = 1; i < argc; i++)
857     if (pend[i].type == PD_FILE)
858       {
859         int fd = open (pend[i].arg, O_RDONLY, 0666);
860         if (fd < 0)
861           {
862             perror_with_name (pend[i].arg);
863             return FATAL_EXIT_CODE;
864           }
865
866         /* For -M, add this file to the dependencies.  */
867         if (print_deps)
868           deps_add_dep (deps, pend[i].arg);
869
870         finclude (fd, pend[i].arg, 0, &outbuf);
871       }
872   indepth--;
873   no_output--;
874
875   /* Pending directives no longer needed.  */
876   free ((PTR) pend);
877
878   /* Create an input stack level for the main input file
879      and copy the entire contents of the file into it.  */
880
881   fp = &instack[++indepth];
882
883   /* JF check for stdin */
884   if (in_fname == NULL || *in_fname == 0) {
885     in_fname = "";
886     f = 0;
887   } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0)
888     goto sys_error;
889
890   if (file_size_and_mode (f, &st_mode, &st_size))
891     goto sys_error;
892   fp->fname = in_fname;
893   fp->lineno = 1;
894   /* JF all this is mine about reading pipes and ttys */
895   if (!S_ISREG (st_mode)) {
896     /* Read input from a file that is not a normal disk file.
897        We cannot preallocate a buffer with the correct size,
898        so we must read in the file a piece at the time and make it bigger.  */
899     int size;
900     int bsize;
901     int cnt;
902     U_CHAR *bufp;
903
904     bsize = 2000;
905     size = 0;
906     fp->buf = (U_CHAR *) xmalloc (bsize + 2);
907     bufp = fp->buf;
908     for (;;) {
909       cnt = read (f, bufp, bsize - size);
910       if (cnt < 0) goto sys_error;      /* error! */
911       if (cnt == 0) break;              /* End of file */
912       size += cnt;
913       bufp += cnt;
914       if (bsize == size) {              /* Buffer is full! */
915         bsize *= 2;
916         fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
917         bufp = fp->buf + size;  /* May have moved */
918       }
919     }
920     fp->length = size;
921   } else {
922     /* Read a file whose size we can determine in advance.
923        For the sake of VMS, st_size is just an upper bound.  */
924     long i;
925     fp->length = 0;
926     fp->buf = (U_CHAR *) xmalloc (st_size + 2);
927
928     while (st_size > 0) {
929       i = read (f, fp->buf + fp->length, st_size);
930       if (i <= 0) {
931         if (i == 0) break;
932         goto sys_error;
933       }
934       fp->length += i;
935       st_size -= i;
936     }
937   }
938   fp->bufp = fp->buf;
939   fp->if_stack = if_stack;
940
941   /* Make sure data ends with a newline.  And put a null after it.  */
942
943   if (fp->length > 0 && fp->buf[fp->length-1] != '\n')
944     fp->buf[fp->length++] = '\n';
945   fp->buf[fp->length] = '\0';
946   
947   /* Now that we know the input file is valid, open the output.  */
948
949   if (!out_fname || !strcmp (out_fname, ""))
950     out_fname = "stdout";
951   else if (! freopen (out_fname, "w", stdout))
952     pfatal_with_name (out_fname);
953
954   output_line_command (fp, &outbuf, 0, same_file);
955
956   /* Scan the input, processing macros and directives.  */
957
958   rescan (&outbuf, 0);
959
960   /* Now we have processed the entire input
961      Write whichever kind of output has been requested.  */
962
963
964   if (dump_macros)
965     dump_all_macros ();
966   else if (! inhibit_output)
967     if (write (fileno (stdout), outbuf.buf, outbuf.bufp - outbuf.buf) < 0)
968       fatal ("I/O error on output");
969
970   /* Don't write the deps file if preprocessing has failed.  */
971   if (print_deps && errors == 0)
972     output_deps ();
973
974   /* Destruct the deps object.  */
975   deps_free (deps);
976
977   if (ferror (stdout))
978     fatal ("I/O error on output");
979
980   if (errors)
981     exit (FATAL_EXIT_CODE);
982   exit (SUCCESS_EXIT_CODE);
983
984  sys_error:
985   pfatal_with_name (in_fname);
986 }
987
988 /* Set up dependency-file output.  */
989 static void
990 init_dependency_output ()
991 {
992   char *spec, *s, *output_file;
993
994   /* Either of two environment variables can specify output of deps.
995      Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
996      where OUTPUT_FILE is the file to write deps info to
997      and DEPS_TARGET is the target to mention in the deps.  */
998
999   if (print_deps == 0)
1000     {
1001       spec = getenv ("DEPENDENCIES_OUTPUT");
1002       if (spec)
1003         print_deps = 1;
1004       else
1005         {
1006           spec = getenv ("SUNPRO_DEPENDENCIES");
1007           if (spec)
1008             print_deps = 2;
1009           else
1010             return;
1011         }
1012
1013       /* Find the space before the DEPS_TARGET, if there is one.  */
1014       s = strchr (spec, ' ');
1015       if (s)
1016         {
1017           /* Let the caller perform MAKE quoting.  */
1018           deps_add_target (deps, s + 1, 0);
1019           output_file = (char *) xmalloc (s - spec + 1);
1020           memcpy (output_file, spec, s - spec);
1021           output_file[s - spec] = 0;
1022         }
1023       else
1024         output_file = spec;
1025
1026       /* Command line overrides environment variables.  */
1027       if (deps_file == 0)
1028         deps_file = output_file;
1029       deps_append = 1;
1030     }
1031
1032   /* If dependencies go to standard output, or -MG is used, we should
1033      suppress output.  The user may be requesting other stuff to
1034      stdout, with -dM, -v etc.  We let them shoot themselves in the
1035      foot.  */
1036   if (deps_file == 0 || deps_missing_files)
1037     inhibit_output = 1;
1038 }
1039
1040 /* Use mkdeps.c to output dependency information.  */
1041 static void
1042 output_deps ()
1043 {
1044   /* Stream on which to print the dependency information.  */
1045   FILE *deps_stream = 0;
1046   const char *const deps_mode = deps_append ? "a" : "w";
1047
1048   if (deps_file == 0)
1049     deps_stream = stdout;
1050   else
1051     {
1052       deps_stream = fopen (deps_file, deps_mode);
1053       if (deps_stream == 0)
1054         {
1055           error_from_errno (deps_file);
1056           return;
1057         }
1058     }
1059
1060   deps_write (deps, deps_stream, 72);
1061
1062   if (print_deps_phony_targets)
1063     deps_phony_targets (deps, deps_stream);
1064
1065   /* Don't close stdout.  */
1066   if (deps_file)
1067     {
1068       if (ferror (deps_stream) || fclose (deps_stream) != 0)
1069         fatal ("I/O error on output");
1070     }
1071 }
1072
1073 /* Move all backslash-newline pairs out of embarrassing places.
1074    Exchange all such pairs following BP
1075    with any potentially-embarrasing characters that follow them.
1076    Potentially-embarrassing characters are / and *
1077    (because a backslash-newline inside a comment delimiter
1078    would cause it not to be recognized).  */
1079 static void
1080 newline_fix (bp)
1081      U_CHAR *bp;
1082 {
1083   U_CHAR *p = bp;
1084   int count = 0;
1085
1086   /* First count the backslash-newline pairs here.  */
1087
1088   while (*p++ == '\\' && *p++ == '\n')
1089     count++;
1090
1091   p = bp + count * 2;
1092
1093   /* Exit if what follows the backslash-newlines is not embarrassing.  */
1094
1095   if (count == 0 || (*p != '/' && *p != '*'))
1096     return;
1097
1098   /* Copy all potentially embarrassing characters
1099      that follow the backslash-newline pairs
1100      down to where the pairs originally started.  */
1101
1102   while (*p == '*' || *p == '/')
1103     *bp++ = *p++;
1104
1105   /* Now write the same number of pairs after the embarrassing chars.  */
1106   while (count-- > 0) {
1107     *bp++ = '\\';
1108     *bp++ = '\n';
1109   }
1110 }
1111
1112 /* Like newline_fix but for use within a directive-name.
1113    Move any backslash-newlines up past any following symbol constituents.  */
1114 static void
1115 name_newline_fix (bp)
1116      U_CHAR *bp;
1117 {
1118   U_CHAR *p = bp;
1119   int count = 0;
1120
1121   /* First count the backslash-newline pairs here.  */
1122
1123   while (*p++ == '\\' && *p++ == '\n')
1124     count++;
1125
1126   p = bp + count * 2;
1127
1128   /* What follows the backslash-newlines is not embarrassing.  */
1129
1130   if (count == 0 || !is_idchar (*p))
1131     return;
1132
1133   /* Copy all potentially embarrassing characters
1134      that follow the backslash-newline pairs
1135      down to where the pairs originally started.  */
1136
1137   while (is_idchar (*p))
1138     *bp++ = *p++;
1139
1140   /* Now write the same number of pairs after the embarrassing chars.  */
1141   while (count-- > 0) {
1142     *bp++ = '\\';
1143     *bp++ = '\n';
1144   }
1145 }
1146 \f
1147 /*
1148  * The main loop of the program.
1149  *
1150  * Read characters from the input stack, transferring them to the
1151  * output buffer OP.
1152  *
1153  * Macros are expanded and push levels on the input stack.
1154  * At the end of such a level it is popped off and we keep reading.
1155  * At the end of any other kind of level, we return.
1156  * #-directives are handled, except within macros.
1157  *
1158  * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input
1159  * and insert them when appropriate.  This is set while scanning macro
1160  * arguments before substitution.  It is zero when scanning for final output.
1161  *   There are three types of Newline markers:
1162  *   * Newline -  follows a macro name that was not expanded
1163  *     because it appeared inside an expansion of the same macro.
1164  *     This marker prevents future expansion of that identifier.
1165  *     When the input is rescanned into the final output, these are deleted.
1166  *     These are also deleted by ## concatenation.
1167  *   * Newline Space (or Newline and any other whitespace character)
1168  *     stands for a place that tokens must be separated or whitespace
1169  *     is otherwise desirable, but where the ANSI standard specifies there
1170  *     is no whitespace.  This marker turns into a Space (or whichever other
1171  *     whitespace char appears in the marker) in the final output,
1172  *     but it turns into nothing in an argument that is stringified with #.
1173  *     Such stringified arguments are the only place where the ANSI standard
1174  *     specifies with precision that whitespace may not appear.
1175  *
1176  * During this function, IP->bufp is kept cached in IBP for speed of access.
1177  * Likewise, OP->bufp is kept in OBP.  Before calling a subroutine
1178  * IBP, IP and OBP must be copied back to memory.  IP and IBP are
1179  * copied back with the RECACHE macro.  OBP must be copied back from OP->bufp
1180  * explicitly, and before RECACHE, since RECACHE uses OBP.
1181  */
1182
1183 static void
1184 rescan (op, output_marks)
1185      FILE_BUF *op;
1186      int output_marks;
1187 {
1188   /* Character being scanned in main loop.  */
1189   U_CHAR c;
1190
1191   /* Length of pending accumulated identifier.  */
1192   int ident_length = 0;
1193
1194   /* Hash code of pending accumulated identifier.  */
1195   int hash = 0;
1196
1197   /* Current input level (&instack[indepth]).  */
1198   FILE_BUF *ip;
1199
1200   /* Pointer for scanning input.  */
1201   U_CHAR *ibp;
1202
1203   /* Pointer to end of input.  End of scan is controlled by LIMIT.  */
1204   U_CHAR *limit;
1205
1206   /* Pointer for storing output.  */
1207   U_CHAR *obp;
1208
1209   /* REDO_CHAR is nonzero if we are processing an identifier
1210      after backing up over the terminating character.
1211      Sometimes we process an identifier without backing up over
1212      the terminating character, if the terminating character
1213      is not special.  Backing up is done so that the terminating character
1214      will be dispatched on again once the identifier is dealt with.  */
1215   int redo_char = 0;
1216
1217   /* 1 if within an identifier inside of which a concatenation
1218      marker (Newline -) has been seen.  */
1219   int concatenated = 0;
1220
1221   /* While scanning a comment or a string constant,
1222      this records the line it started on, for error messages.  */
1223   int start_line;
1224
1225   /* Record position of last `real' newline.  */
1226   U_CHAR *beg_of_line;
1227
1228   /* This has to be a global bacause of RECACHE.  */
1229   U_CHAR *obufp_before_macroname = NULL;
1230
1231 /* Pop the innermost input stack level, assuming it is a macro expansion.  */
1232
1233 #define POPMACRO \
1234 do { ip->macro->type = T_MACRO;         \
1235      if (ip->free_ptr) free (ip->free_ptr);     \
1236      --indepth; } while (0)
1237
1238 /* Reload `rescan's local variables that describe the current
1239    level of the input stack.  */
1240
1241 #define RECACHE  \
1242 do { ip = &instack[indepth];            \
1243      ibp = ip->bufp;                    \
1244      limit = ip->buf + ip->length;      \
1245      op->bufp = obp;                    \
1246      check_expand (op, limit - ibp);    \
1247      beg_of_line = 0;                   \
1248      obufp_before_macroname += op->bufp - obp;  \
1249      obp = op->bufp; } while (0)
1250
1251   if (no_output && instack[indepth].fname != 0)
1252     skip_if_group (&instack[indepth], 1);
1253
1254   obp = op->bufp;
1255   RECACHE;
1256   beg_of_line = ibp;
1257
1258   /* Our caller must always put a null after the end of
1259      the input at each input stack level.  */
1260   if (*limit != 0)
1261     abort ();
1262
1263   while (1) {
1264     c = *ibp++;
1265     *obp++ = c;
1266
1267     switch (c) {
1268     case '\\':
1269       if (ibp >= limit)
1270         break;
1271       if (*ibp == '\n') {
1272         /* Always merge lines ending with backslash-newline,
1273            even in middle of identifier.  */
1274         ++ibp;
1275         ++ip->lineno;
1276         --obp;          /* remove backslash from obuf */
1277         break;
1278       }
1279       /* Otherwise, backslash suppresses specialness of following char,
1280          so copy it here to prevent the switch from seeing it.
1281          But first get any pending identifier processed.  */
1282       if (ident_length > 0)
1283         goto specialchar;
1284       *obp++ = *ibp++;
1285       break;
1286
1287     case '#':
1288       /* If this is expanding a macro definition, don't recognize
1289          preprocessor directives.  */
1290       if (ip->macro != 0)
1291         goto randomchar;
1292       if (ident_length)
1293         goto specialchar;
1294
1295       /* # keyword: a # must be the first char on the line */
1296       if (beg_of_line == 0)
1297         goto randomchar;
1298       if (beg_of_line + 1 != ibp)
1299         goto randomchar;
1300
1301       /* This # can start a directive.  */
1302
1303       --obp;            /* Don't copy the '#' */
1304
1305       ip->bufp = ibp;
1306       op->bufp = obp;
1307       if (! handle_directive (ip, op)) {
1308 #ifdef USE_C_ALLOCA
1309         alloca (0);
1310 #endif
1311         /* Not a known directive: treat it as ordinary text.
1312            IP, OP, IBP, etc. have not been changed.  */
1313         if (no_output && instack[indepth].fname) {
1314           /* If not generating expanded output,
1315              what we do with ordinary text is skip it.
1316              Discard everything until next # directive.  */
1317           skip_if_group (&instack[indepth], 1);
1318           RECACHE;
1319           beg_of_line = ibp;
1320           break;
1321         }
1322         ++obp;          /* Copy the '#' after all */
1323         goto randomchar;
1324       }
1325 #ifdef USE_C_ALLOCA
1326       alloca (0);
1327 #endif
1328       /* A # directive has been successfully processed.  */
1329       /* If not generating expanded output, ignore everything until
1330          next # directive.  */
1331       if (no_output && instack[indepth].fname)
1332         skip_if_group (&instack[indepth], 1);
1333       obp = op->bufp;
1334       RECACHE;
1335       beg_of_line = ibp;
1336       break;
1337
1338     case '\"':                  /* skip quoted string */
1339     case '\'':
1340       /* A single quoted string is treated like a double -- some
1341          programs (e.g., troff) are perverse this way */
1342
1343       if (ident_length)
1344         goto specialchar;
1345
1346       start_line = ip->lineno;
1347
1348       /* Skip ahead to a matching quote.  */
1349
1350       while (1) {
1351         if (ibp >= limit) {
1352           if (ip->macro != 0) {
1353             /* try harder: this string crosses a macro expansion boundary */
1354             POPMACRO;
1355             RECACHE;
1356             continue;
1357           }
1358           break;
1359         }
1360         *obp++ = *ibp;
1361         switch (*ibp++) {
1362         case '\n':
1363           ++ip->lineno;
1364           ++op->lineno;
1365           /* Traditionally, end of line ends a string constant with no error.
1366              So exit the loop and record the new line.  */
1367           beg_of_line = ibp;
1368           goto while2end;
1369
1370         case '\\':
1371           if (ibp >= limit)
1372             break;
1373           if (*ibp == '\n') {
1374             /* Backslash newline is replaced by nothing at all,
1375                but keep the line counts correct.  */
1376             --obp;
1377             ++ibp;
1378             ++ip->lineno;
1379           } else {
1380             /* ANSI stupidly requires that in \\ the second \
1381                is *not* prevented from combining with a newline.  */
1382             while (*ibp == '\\' && ibp[1] == '\n') {
1383               ibp += 2;
1384               ++ip->lineno;
1385             }
1386             *obp++ = *ibp++;
1387           }
1388           break;
1389
1390         case '\"':
1391         case '\'':
1392           if (ibp[-1] == c)
1393             goto while2end;
1394           break;
1395         }
1396       }
1397     while2end:
1398       break;
1399
1400     case '/':
1401       if (*ibp == '\\' && ibp[1] == '\n')
1402         newline_fix (ibp);
1403       /* Don't look for comments inside a macro definition.  */
1404       if (ip->macro != 0)
1405         goto randomchar;
1406       /* A comment constitutes white space, so it can terminate an identifier.
1407          Process the identifier, if any.  */
1408       if (ident_length)
1409         goto specialchar;
1410
1411       if (*ibp != '*')
1412         goto randomchar;
1413
1414       /* We have a comment.  Skip it, optionally copying it to output.  */
1415
1416       start_line = ip->lineno;
1417
1418       ++ibp;                    /* Skip the star. */
1419
1420       /* In K+R C, a comment is equivalent to nothing.  Note that we
1421           already output the slash; we might not want it.  */
1422       if (! put_out_comments)
1423         obp--;
1424       else
1425         *obp++ = '*';
1426
1427       {
1428         U_CHAR *before_bp = ibp;
1429
1430         while (ibp < limit) {
1431           switch (*ibp++) {
1432           case '/':
1433             if (warn_comments && ibp < limit && *ibp == '*')
1434               warning("`/*' within comment");
1435             break;
1436           case '*':
1437             if (*ibp == '\\' && ibp[1] == '\n')
1438               newline_fix (ibp);
1439             if (ibp >= limit || *ibp == '/')
1440               goto comment_end;
1441             break;
1442           case '\n':
1443             ++ip->lineno;
1444             /* Copy the newline into the output buffer, in order to
1445                avoid the pain of a #line every time a multiline comment
1446                is seen.  */
1447             if (!put_out_comments)
1448               *obp++ = '\n';
1449             ++op->lineno;
1450           }
1451         }
1452       comment_end:
1453
1454         if (ibp >= limit)
1455           error_with_line (line_for_error (start_line),
1456                            "unterminated comment");
1457         else {
1458           ibp++;
1459           if (put_out_comments) {
1460             memcpy (obp, before_bp, ibp - before_bp);
1461             obp += ibp - before_bp;
1462           }
1463         }
1464       }
1465       break;
1466
1467     case '0': case '1': case '2': case '3': case '4':
1468     case '5': case '6': case '7': case '8': case '9':
1469       /* If digit is not part of identifier, it starts a number,
1470          which means that following letters are not an identifier.
1471          "0x5" does not refer to an identifier "x5".
1472          So copy all alphanumerics that follow without accumulating
1473          as an identifier.  Periods also, for sake of "3.e7".  */
1474
1475       if (ident_length == 0) {
1476         while (ibp < limit) {
1477           while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
1478             ++ip->lineno;
1479             ibp += 2;
1480           }
1481           c = *ibp++;
1482           if (! ISIDNUM (c) && c != '.') {
1483             --ibp;
1484             break;
1485           }
1486           *obp++ = c;
1487           /* A sign can be part of a preprocessing number
1488              if it follows an e.  */
1489           if (c == 'e' || c == 'E') {
1490             while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
1491               ++ip->lineno;
1492               ibp += 2;
1493             }
1494             if (ibp < limit && (*ibp == '+' || *ibp == '-')) {
1495               *obp++ = *ibp++;
1496               /* Traditional C does not let the token go past the sign.  */
1497               break;
1498             }
1499           }
1500         }
1501         break;
1502       }
1503       /* fall through */
1504
1505     case '_':
1506     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1507     case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
1508     case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
1509     case 's': case 't': case 'u': case 'v': case 'w': case 'x':
1510     case 'y': case 'z':
1511     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1512     case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
1513     case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
1514     case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
1515     case 'Y': case 'Z':
1516       ident_length++;
1517       /* Compute step of hash function, to avoid a proc call on every token */
1518       hash = HASHSTEP (hash, c);
1519       break;
1520
1521     case '\n':
1522       /* If reprocessing a macro expansion, newline is a special marker.  */
1523       if (ip->macro != 0) {
1524         /* Newline White is a "funny space" to separate tokens that are
1525            supposed to be separate but without space between.
1526            Here White means any horizontal whitespace character.
1527            Newline - marks a recursive macro use that is not
1528            supposed to be expandable.  */
1529
1530         if (*ibp == '-') {
1531           /* Newline - inhibits expansion of preceding token.
1532              If expanding a macro arg, we keep the newline -.
1533              In final output, it is deleted.  */
1534           if (! concatenated) {
1535             ident_length = 0;
1536             hash = 0;
1537           }
1538           ibp++;
1539           if (!output_marks) {
1540             obp--;
1541           } else {
1542             /* If expanding a macro arg, keep the newline -.  */
1543             *obp++ = '-';
1544           }
1545         } else if (is_space (*ibp)) {
1546           /* Newline Space does not prevent expansion of preceding token
1547              so expand the preceding token and then come back.  */
1548           if (ident_length > 0)
1549             goto specialchar;
1550
1551           /* If generating final output, newline space makes a space.  */
1552           if (!output_marks) {
1553             obp[-1] = *ibp++;
1554             /* And Newline Newline makes a newline, so count it.  */
1555             if (obp[-1] == '\n')
1556               op->lineno++;
1557           } else {
1558             /* If expanding a macro arg, keep the newline space.
1559                If the arg gets stringified, newline space makes nothing.  */
1560             *obp++ = *ibp++;
1561           }
1562         } else abort ();        /* Newline followed by something random?  */
1563         break;
1564       }
1565
1566       /* If there is a pending identifier, handle it and come back here.  */
1567       if (ident_length > 0)
1568         goto specialchar;
1569
1570       beg_of_line = ibp;
1571
1572       /* Update the line counts and output a #line if necessary.  */
1573       ++ip->lineno;
1574       ++op->lineno;
1575       if (ip->lineno != op->lineno) {
1576         op->bufp = obp;
1577         output_line_command (ip, op, 1, same_file);
1578         check_expand (op, ip->length - (ip->bufp - ip->buf));
1579         obp = op->bufp;
1580       }
1581       break;
1582
1583       /* Come here either after (1) a null character that is part of the input
1584          or (2) at the end of the input, because there is a null there.  */
1585     case 0:
1586       if (ibp <= limit)
1587         /* Our input really contains a null character.  */
1588         goto randomchar;
1589
1590       /* At end of a macro-expansion level, pop it and read next level.  */
1591       if (ip->macro != 0) {
1592         obp--;
1593         ibp--;
1594         /* If we have an identifier that ends here, process it now, so
1595            we get the right error for recursion.  */
1596         if (ident_length && ! is_idchar (*instack[indepth - 1].bufp)) {
1597           redo_char = 1;
1598           goto randomchar;
1599         }
1600         POPMACRO;
1601         RECACHE;
1602         break;
1603       }
1604
1605       /* If we don't have a pending identifier,
1606          return at end of input.  */
1607       if (ident_length == 0) {
1608         obp--;
1609         ibp--;
1610         op->bufp = obp;
1611         ip->bufp = ibp;
1612         goto ending;
1613       }
1614
1615       /* If we do have a pending identifier, just consider this null
1616          a special character and arrange to dispatch on it again.
1617          The second time, IDENT_LENGTH will be zero so we will return.  */
1618
1619       /* Fall through */
1620
1621 specialchar:
1622
1623       /* Handle the case of a character such as /, ', " or null
1624          seen following an identifier.  Back over it so that
1625          after the identifier is processed the special char
1626          will be dispatched on again.  */
1627
1628       ibp--;
1629       obp--;
1630       redo_char = 1;
1631
1632     default:
1633
1634 randomchar:
1635
1636       if (ident_length > 0) {
1637         HASHNODE *hp;
1638
1639         /* We have just seen an identifier end.  If it's a macro, expand it.
1640
1641            IDENT_LENGTH is the length of the identifier
1642            and HASH is its hash code.
1643
1644            The identifier has already been copied to the output,
1645            so if it is a macro we must remove it.
1646
1647            If REDO_CHAR is 0, the char that terminated the identifier
1648            has been skipped in the output and the input.
1649            OBP-IDENT_LENGTH-1 points to the identifier.
1650            If the identifier is a macro, we must back over the terminator.
1651
1652            If REDO_CHAR is 1, the terminating char has already been
1653            backed over.  OBP-IDENT_LENGTH points to the identifier.  */
1654
1655         for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL;
1656              hp = hp->next) {
1657
1658           if (hp->length == ident_length) {
1659             /* obufp_before_macroname is used only in this block,
1660                but it has to be global because of RECACHE.  */
1661             int op_lineno_before_macroname;
1662             int i = ident_length;
1663             U_CHAR *p = hp->name;
1664             U_CHAR *q = obp - i;
1665
1666             if (! redo_char)
1667               q--;
1668
1669             do {                /* All this to avoid a strncmp () */
1670               if (*p++ != *q++)
1671                 goto hashcollision;
1672             } while (--i);
1673
1674             /* We found a use of a macro name.
1675                see if the context shows it is a macro call.  */
1676
1677             /* Back up over terminating character if not already done.  */
1678             if (! redo_char) {
1679               ibp--;
1680               obp--;
1681             }
1682
1683             obufp_before_macroname = obp - ident_length;
1684             op_lineno_before_macroname = op->lineno;
1685
1686             /* If macro wants an arglist, verify that a '(' follows.
1687                first skip all whitespace, copying it to the output
1688                after the macro name.  Then, if there is no '(',
1689                decide this is not a macro call and leave things that way.  */
1690             if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
1691               {
1692                 while (1) {
1693                   /* Scan forward over whitespace, copying it to the output.  */
1694                   if (ibp == limit && ip->macro != 0) {
1695                     POPMACRO;
1696                     RECACHE;
1697                   }
1698                   /* A comment: copy it unchanged or discard it.  */
1699                   else if (*ibp == '/' && ibp+1 != limit && ibp[1] == '*') {
1700                     if (put_out_comments) {
1701                       *obp++ = '/';
1702                       *obp++ = '*';
1703                     }
1704                     ibp += 2;
1705                     while (ibp + 1 != limit
1706                            && !(ibp[0] == '*' && ibp[1] == '/')) {
1707                       /* We need not worry about newline-marks,
1708                          since they are never found in comments.  */
1709                       if (*ibp == '\n') {
1710                         /* Newline in a file.  Count it.  */
1711                         ++ip->lineno;
1712                         ++op->lineno;
1713                       }
1714                       if (put_out_comments)
1715                         *obp++ = *ibp++;
1716                       else
1717                         ibp++;
1718                     }
1719                     ibp += 2;
1720                     if (put_out_comments) {
1721                       *obp++ = '*';
1722                       *obp++ = '/';
1723                     }
1724                   }
1725                   else if (is_space (*ibp)) {
1726                     *obp++ = *ibp++;
1727                     if (ibp[-1] == '\n') {
1728                       if (ip->macro == 0) {
1729                         /* Newline in a file.  Count it.  */
1730                         ++ip->lineno;
1731                         ++op->lineno;
1732                       } else if (!output_marks) {
1733                         /* A newline mark, and we don't want marks
1734                            in the output.  If it is newline-hyphen,
1735                            discard it entirely.  Otherwise, it is
1736                            newline-whitechar, so keep the whitechar.  */
1737                         obp--;
1738                         if (*ibp == '-')
1739                           ibp++;
1740                         else {
1741                           if (*ibp == '\n')
1742                             ++op->lineno;
1743                           *obp++ = *ibp++;
1744                         }
1745                       } else {
1746                         /* A newline mark; copy both chars to the output.  */
1747                         *obp++ = *ibp++;
1748                       }
1749                     }
1750                   }
1751                   else break;
1752                 }
1753                 if (*ibp != '(')
1754                   break;
1755               }
1756
1757             /* This is now known to be a macro call.
1758                Discard the macro name from the output,
1759                along with any following whitespace just copied.  */
1760             obp = obufp_before_macroname;
1761             op->lineno = op_lineno_before_macroname;
1762
1763             /* Expand the macro, reading arguments as needed,
1764                and push the expansion on the input stack.  */
1765             ip->bufp = ibp;
1766             op->bufp = obp;
1767             macroexpand (hp, op);
1768
1769             /* Reexamine input stack, since macroexpand has pushed
1770                a new level on it.  */
1771             obp = op->bufp;
1772             RECACHE;
1773             break;
1774           }
1775 hashcollision:
1776                ;
1777         }                       /* End hash-table-search loop */
1778         ident_length = hash = 0; /* Stop collecting identifier */
1779         redo_char = 0;
1780         concatenated = 0;
1781       }                         /* End if (ident_length > 0) */
1782     }                           /* End switch */
1783   }                             /* End per-char loop */
1784
1785   /* Come here to return -- but first give an error message
1786      if there was an unterminated successful conditional.  */
1787  ending:
1788   if (if_stack != ip->if_stack) {
1789     const char *str;
1790     switch (if_stack->type) {
1791     case T_IF:
1792       str = "if";
1793       break;
1794     case T_IFDEF:
1795       str = "ifdef";
1796       break;
1797     case T_IFNDEF:
1798       str = "ifndef";
1799       break;
1800     case T_ELSE:
1801       str = "else";
1802       break;
1803     case T_ELIF:
1804       str = "elif";
1805       break;
1806     default:
1807       abort ();
1808     }
1809     error_with_line (line_for_error (if_stack->lineno),
1810                      "unterminated #%s conditional", str);
1811   }
1812   if_stack = ip->if_stack;
1813 }
1814 \f
1815 /*
1816  * Rescan a string into a temporary buffer and return the result
1817  * as a FILE_BUF.  Note this function returns a struct, not a pointer.
1818  *
1819  * OUTPUT_MARKS nonzero means keep Newline markers found in the input
1820  * and insert such markers when appropriate.  See `rescan' for details.
1821  * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately
1822  * before substitution; it is 0 for other uses.
1823  */
1824 static FILE_BUF
1825 expand_to_temp_buffer (buf, limit, output_marks)
1826      const U_CHAR *buf, *limit;
1827      int output_marks;
1828 {
1829   FILE_BUF *ip;
1830   FILE_BUF obuf;
1831   int length = limit - buf;
1832   U_CHAR *buf1;
1833   int odepth = indepth;
1834
1835   if (length < 0)
1836     abort ();
1837
1838   /* Set up the input on the input stack.  */
1839
1840   buf1 = (U_CHAR *) alloca (length + 1);
1841   {
1842     const U_CHAR *p1 = buf;
1843     U_CHAR *p2 = buf1;
1844
1845     while (p1 != limit)
1846       *p2++ = *p1++;
1847   }
1848   buf1[length] = 0;
1849
1850   /* Set up to receive the output.  */
1851
1852   obuf.length = length * 2 + 100; /* Usually enough.  Why be stingy?  */
1853   obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
1854   obuf.fname = 0;
1855   obuf.macro = 0;
1856   obuf.free_ptr = 0;
1857
1858   CHECK_DEPTH ({return obuf;});
1859
1860   ++indepth;
1861
1862   ip = &instack[indepth];
1863   ip->fname = 0;
1864   ip->macro = 0;
1865   ip->free_ptr = 0;
1866   ip->length = length;
1867   ip->buf = ip->bufp = buf1;
1868   ip->if_stack = if_stack;
1869
1870   ip->lineno = obuf.lineno = 1;
1871
1872   /* Scan the input, create the output.  */
1873
1874   rescan (&obuf, output_marks);
1875
1876   /* Pop input stack to original state.  */
1877   --indepth;
1878
1879   if (indepth != odepth)
1880     abort ();
1881
1882   /* Record the output.  */
1883   obuf.length = obuf.bufp - obuf.buf;
1884
1885   return obuf;
1886 }
1887 \f
1888 /*
1889  * Process a # directive.  Expects IP->bufp to point to the '#', as in
1890  * `#define foo bar'.  Passes to the command handler
1891  * (do_define, do_include, etc.): the addresses of the 1st and
1892  * last chars of the command (starting immediately after the #
1893  * keyword), plus op and the keyword table pointer.  If the command
1894  * contains comments it is copied into a temporary buffer sans comments
1895  * and the temporary buffer is passed to the command handler instead.
1896  * Likewise for backslash-newlines.
1897  *
1898  * Returns nonzero if this was a known # directive.
1899  * Otherwise, returns zero, without advancing the input pointer.
1900  */
1901
1902 static int
1903 handle_directive (ip, op)
1904      FILE_BUF *ip, *op;
1905 {
1906   U_CHAR *bp, *cp;
1907   struct directive *kt;
1908   int ident_length;
1909   U_CHAR *resume_p;
1910
1911   /* Nonzero means we must copy the entire command
1912      to get rid of comments or backslash-newlines.  */
1913   int copy_command = 0;
1914
1915   U_CHAR *ident, *after_ident;
1916
1917   bp = ip->bufp;
1918   /* Skip whitespace and \-newline.  */
1919   while (1) {
1920     if (is_nvspace (*bp))
1921       bp++;
1922     else if (*bp == '/' && (newline_fix (bp + 1), bp[1]) == '*') {
1923       ip->bufp = bp;
1924       skip_to_end_of_comment (ip, &ip->lineno);
1925       bp = ip->bufp;
1926     } else if (*bp == '\\' && bp[1] == '\n') {
1927       bp += 2; ip->lineno++;
1928     } else break;
1929   }
1930
1931   /* Now find end of directive name.
1932      If we encounter a backslash-newline, exchange it with any following
1933      symbol-constituents so that we end up with a contiguous name.  */
1934
1935   cp = bp;
1936   while (1) {
1937     if (is_idchar (*cp))
1938       cp++;
1939     else {
1940       if (*cp == '\\' && cp[1] == '\n')
1941         name_newline_fix (cp);
1942       if (is_idchar (*cp))
1943         cp++;
1944       else break;
1945     }
1946   }
1947   ident_length = cp - bp;
1948   ident = bp;
1949   after_ident = cp;
1950
1951   /* A line of just `#' becomes blank.  */
1952
1953   if (ident_length == 0 && *after_ident == '\n') {
1954     ip->bufp = after_ident;
1955     return 1;
1956   }
1957
1958   /*
1959    * Decode the keyword and call the appropriate expansion
1960    * routine, after moving the input pointer up to the next line.
1961    */
1962   for (kt = directive_table; kt->length > 0; kt++) {
1963     if (kt->length == ident_length
1964         && !strncmp (kt->name, (const char *)ident, ident_length)) {
1965       U_CHAR *buf;
1966       U_CHAR *limit = ip->buf + ip->length;
1967       int unterminated = 0;
1968
1969       /* Nonzero means do not delete comments within the directive.
1970          #define needs this to detect traditional token paste.  */
1971       int keep_comments = kt->type == T_DEFINE;
1972
1973       /* Find the end of this command (first newline not backslashed
1974          and not in a string or comment).
1975          Set COPY_COMMAND if the command must be copied
1976          (it contains a backslash-newline or a comment).  */
1977
1978       buf = bp = after_ident;
1979       while (bp < limit) {
1980         U_CHAR c = *bp++;
1981         switch (c) {
1982         case '\\':
1983           if (bp < limit) {
1984             if (*bp == '\n') {
1985               ip->lineno++;
1986               copy_command = 1;
1987             }
1988             bp++;
1989           }
1990           break;
1991
1992         case '\'':
1993         case '\"':
1994           bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, &copy_command, &unterminated);
1995           if (unterminated) {
1996             /* Traditional preprocessing permits unterminated strings.  */
1997             ip->bufp = bp;
1998             goto endloop1;
1999           }
2000           break;
2001
2002           /* <...> is special for #include.  */
2003         case '<':
2004           if (kt->type != T_INCLUDE)
2005             break;
2006           while (*bp && *bp != '>') bp++;
2007           break;
2008
2009         case '/':
2010           if (*bp == '\\' && bp[1] == '\n')
2011             newline_fix (bp);
2012           if (*bp == '*') {
2013             U_CHAR *obp = bp - 1;
2014             ip->bufp = bp + 1;
2015             skip_to_end_of_comment (ip, &ip->lineno);
2016             bp = ip->bufp;
2017             /* No need to copy the command because of a comment at the end;
2018                just don't include the comment in the directive.  */
2019             if (bp == limit || *bp == '\n') {
2020               bp = obp;
2021               goto endloop1;
2022             }
2023             /* Don't remove the comments if this is #define.  */
2024             if (! keep_comments)
2025               copy_command++;
2026           }
2027           break;
2028
2029         case '\n':
2030           --bp;         /* Point to the newline */
2031           ip->bufp = bp;
2032           goto endloop1;
2033         }
2034       }
2035       ip->bufp = bp;
2036
2037     endloop1:
2038       resume_p = ip->bufp;
2039       /* BP is the end of the directive.
2040          RESUME_P is the next interesting data after the directive.
2041          A comment may come between.  */
2042
2043       if (copy_command) {
2044         U_CHAR *xp = buf;
2045         /* Need to copy entire command into temp buffer before dispatching */
2046
2047         cp = (U_CHAR *) alloca (bp - buf + 5); /* room for cmd plus
2048                                                   some slop */
2049         buf = cp;
2050
2051         /* Copy to the new buffer, deleting comments
2052            and backslash-newlines (and whitespace surrounding the latter).  */
2053
2054         while (xp < bp) {
2055           U_CHAR c = *xp++;
2056           *cp++ = c;
2057
2058           switch (c) {
2059           case '\n':
2060             break;
2061
2062             /* <...> is special for #include.  */
2063           case '<':
2064             if (kt->type != T_INCLUDE)
2065               break;
2066             while (xp < bp && c != '>') {
2067               c = *xp++;
2068               if (c == '\\' && xp < bp && *xp == '\n')
2069                 xp++, ip->lineno++;
2070               else
2071                 *cp++ = c;
2072             }
2073             break;
2074
2075           case '\\':
2076             if (*xp == '\n') {
2077               xp++;
2078               cp--;
2079               if (cp != buf && is_space (cp[-1])) {
2080                 while (cp != buf && is_space(cp[-1])) cp--;
2081                 cp++;
2082                 SKIP_WHITE_SPACE (xp);
2083               } else if (is_nvspace (*xp)) {
2084                 *cp++ = *xp++;
2085                 SKIP_WHITE_SPACE (xp);
2086               }
2087             } else {
2088               *cp++ = *xp++;
2089             }
2090             break;
2091
2092           case '\'':
2093           case '\"':
2094             {
2095               const U_CHAR *bp1
2096                 = skip_quoted_string (xp - 1, limit, ip->lineno, 0, 0, 0);
2097               while (xp != bp1)
2098                 *cp++ = *xp++;
2099             }
2100             break;
2101
2102           case '/':
2103             if (*xp == '*') {
2104               ip->bufp = xp + 1;
2105               skip_to_end_of_comment (ip, 0);
2106               if (keep_comments)
2107                 while (xp != ip->bufp)
2108                   *cp++ = *xp++;
2109               /* Delete the slash.  */
2110               else
2111                 cp--;
2112               xp = ip->bufp;
2113             }
2114           }
2115         }
2116
2117         /* Null-terminate the copy.  */
2118
2119         *cp = 0;
2120       }
2121       else
2122         cp = bp;
2123
2124       ip->bufp = resume_p;
2125
2126       /* Call the appropriate command handler.  buf now points to
2127          either the appropriate place in the input buffer, or to
2128          the temp buffer if it was necessary to make one.  cp
2129          points to the first char after the contents of the (possibly
2130          copied) command, in either case. */
2131       (*kt->func) (buf, cp, op);
2132       check_expand (op, ip->length - (ip->bufp - ip->buf));
2133
2134       return 1;
2135     }
2136   }
2137
2138   return 0;
2139 }
2140 \f
2141 static const char *const
2142 monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
2143                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
2144
2145 /*
2146  * expand things like __FILE__.  Place the expansion into the output
2147  * buffer *without* rescanning.
2148  */
2149 static void
2150 special_symbol (hp, op)
2151      HASHNODE *hp;
2152      FILE_BUF *op;
2153 {
2154   const char *buf;
2155   time_t t;
2156   int i, len;
2157   int true_indepth;
2158   FILE_BUF *ip = NULL;
2159   static struct tm *timebuf = NULL;
2160
2161   int paren = 0;                /* For special `defined' keyword */
2162
2163   for (i = indepth; i >= 0; i--)
2164     if (instack[i].fname != NULL) {
2165       ip = &instack[i];
2166       break;
2167     }
2168   if (ip == NULL)
2169     fatal ("not in any file?!");
2170
2171   switch (hp->type) {
2172   case T_FILE:
2173   case T_BASE_FILE:
2174     {
2175       const char *string;
2176       if (hp->type == T_FILE)
2177         string = ip->fname;
2178       else
2179         string = instack[0].fname;
2180
2181       if (string)
2182         {
2183           char *tmp = (char *) alloca (3 + strlen (string));
2184           sprintf (tmp, "\"%s\"", string);
2185           buf = tmp;
2186         }
2187       else
2188         buf = "";
2189
2190       break;
2191     }
2192
2193   case T_INCLUDE_LEVEL:
2194     {
2195       char *tmp = (char *) alloca (8);  /* Eigth bytes ought to be more than enough */
2196       true_indepth = 0;
2197       for (i = indepth; i >= 0; i--)
2198         if (instack[i].fname != NULL)
2199           true_indepth++;
2200
2201     sprintf (tmp, "%d", true_indepth - 1);
2202     buf = tmp;
2203     break;
2204     }
2205
2206   case T_VERSION:
2207     {
2208       char *tmp = (char *) alloca (3 + strlen (version_string));
2209       sprintf (tmp, "\"%s\"", version_string);
2210       buf = tmp;
2211       break;
2212     }
2213
2214   case T_CONST:
2215     buf = hp->value.cpval;
2216     break;
2217
2218   case T_SPECLINE:
2219     {
2220       char *tmp = (char *) alloca (10);
2221       sprintf (tmp, "%d", ip->lineno);
2222       buf = tmp;
2223       break;
2224     }
2225
2226   case T_DATE:
2227   case T_TIME:
2228     {
2229       char *tmp = (char *) alloca (20);
2230
2231       if (timebuf == NULL) {
2232         t = time (0);
2233         timebuf = localtime (&t);
2234       }
2235       if (hp->type == T_DATE)
2236         sprintf (tmp, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
2237                  timebuf->tm_mday, timebuf->tm_year + 1900);
2238       else
2239         sprintf (tmp, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
2240                  timebuf->tm_sec);
2241       buf = tmp;
2242       break;
2243     }
2244
2245   case T_SPEC_DEFINED:
2246     buf = " 0 ";                        /* Assume symbol is not defined */
2247     ip = &instack[indepth];
2248     SKIP_WHITE_SPACE (ip->bufp);
2249     if (*ip->bufp == '(') {
2250       paren++;
2251       ip->bufp++;                       /* Skip over the paren */
2252       SKIP_WHITE_SPACE (ip->bufp);
2253     }
2254
2255     if (!is_idstart (*ip->bufp))
2256       goto oops;
2257     {
2258       HASHNODE *hp = lookup (ip->bufp, -1, -1);
2259
2260       if (hp && hp->type != T_UNUSED && hp->type != T_SPEC_DEFINED)
2261         buf = " 1 ";
2262     }
2263     while (is_idchar (*ip->bufp))
2264       ++ip->bufp;
2265     SKIP_WHITE_SPACE (ip->bufp);
2266     if (paren) {
2267       if (*ip->bufp != ')')
2268         goto oops;
2269       ++ip->bufp;
2270     }
2271     break;
2272
2273 oops:
2274
2275     error ("`defined' must be followed by ident or (ident)");
2276     break;
2277
2278   default:
2279     error ("cccp error: invalid special hash type"); /* time for gdb */
2280     abort ();
2281   }
2282   len = strlen (buf);
2283   check_expand (op, len);
2284   memcpy (op->bufp, buf, len);
2285   op->bufp += len;
2286 }
2287
2288 \f
2289 /* Routines to handle #directives */
2290
2291 /*
2292  * Process include file by reading it in and calling rescan.
2293  * Expects to see "fname" or <fname> on the input.
2294  */
2295 static void
2296 do_include (buf, limit, op)
2297      U_CHAR *buf, *limit;
2298      FILE_BUF *op;
2299 {
2300   U_CHAR *fbeg, *fend;          /* Beginning and end of fname */
2301
2302   struct file_name_list *stackp = include; /* Chain of dirs to search */
2303   struct file_name_list dsp[1]; /* First in chain, if #include "..." */
2304   int flen;
2305
2306   int retried = 0;              /* Have already tried macro
2307                                    expanding the include line*/
2308   FILE_BUF trybuf;              /* It got expanded into here */
2309   int system_header_p = 0;      /* 0 for "...", 1 for <...> */
2310
2311 get_filename:
2312
2313   fbeg = buf;
2314   SKIP_WHITE_SPACE (fbeg);
2315   /* Discard trailing whitespace so we can easily see
2316      if we have parsed all the significant chars we were given.  */
2317   while (limit != fbeg && is_nvspace (limit[-1])) limit--;
2318
2319   switch (*fbeg++) {
2320   case '\"':
2321     fend = fbeg;
2322     while (fend != limit && *fend != '\"')
2323       fend++;
2324     if (*fend == '\"' && fend + 1 == limit) {
2325       FILE_BUF *fp;
2326
2327       /* We have "filename".  Figure out directory this source
2328          file is coming from and put it on the front of the list. */
2329
2330       /* If -I- was specified, don't search current dir, only spec'd ones. */
2331       if (ignore_srcdir) break;
2332
2333       for (fp = &instack[indepth]; fp >= instack; fp--)
2334         {
2335           size_t n;
2336           const char *ep, *nam;
2337
2338           if ((nam = fp->fname) != NULL) {
2339             /* Found a named file.  Figure out dir of the file,
2340                and put it in front of the search list.  */
2341             dsp[0].next = stackp;
2342             stackp = dsp;
2343             ep = strrchr (nam, '/');
2344             if (ep != NULL) {
2345               char *f; 
2346               n = ep - nam;
2347               f = (char *) alloca (n + 1);
2348               strncpy (f, nam, n);
2349               f[n] = '\0';
2350               dsp[0].fname = f;
2351               if (n > max_include_len) max_include_len = n;
2352             } else {
2353               dsp[0].fname = 0; /* Current directory */
2354             }
2355             break;
2356           }
2357         }
2358       break;
2359     }
2360     goto fail;
2361
2362   case '<':
2363     fend = fbeg;
2364     while (fend != limit && *fend != '>') fend++;
2365     if (*fend == '>' && fend + 1 == limit) {
2366       system_header_p = 1;
2367       /* If -I-, start with the first -I dir after the -I-.  */
2368       if (first_bracket_include)
2369         stackp = first_bracket_include;
2370       break;
2371     }
2372     goto fail;
2373
2374   default:
2375   fail:
2376     if (retried) {
2377       error ("#include expects \"fname\" or <fname>");
2378       return;
2379     } else {
2380       trybuf = expand_to_temp_buffer (buf, limit, 0);
2381       buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
2382       memcpy (buf, trybuf.buf, trybuf.bufp - trybuf.buf);
2383       limit = buf + (trybuf.bufp - trybuf.buf);
2384       free (trybuf.buf);
2385       retried++;
2386       goto get_filename;
2387     }
2388   }
2389
2390   flen = fend - fbeg;
2391   process_include (stackp, fbeg, flen, system_header_p, op);
2392 }
2393
2394 static void
2395 do_include_next (buf, limit, op)
2396      U_CHAR *buf, *limit;
2397      FILE_BUF *op;
2398 {
2399   U_CHAR *fbeg, *fend;          /* Beginning and end of fname */
2400
2401   struct file_name_list *stackp; /* Chain of dirs to search */
2402   int flen;
2403
2404   int retried = 0;              /* Have already tried macro
2405                                    expanding the include line*/
2406   FILE_BUF trybuf;              /* It got expanded into here */
2407   int system_header_p = 0;      /* 0 for "...", 1 for <...> */
2408
2409   /* Treat as plain #include if we don't know where to start
2410      looking.  */
2411   stackp = instack[indepth].next_header_dir;
2412   if (stackp == 0)
2413     {
2414       do_include (buf, limit, op);
2415       return;
2416     }
2417
2418 get_filename:
2419
2420   fbeg = buf;
2421   SKIP_WHITE_SPACE (fbeg);
2422   /* Discard trailing whitespace so we can easily see
2423      if we have parsed all the significant chars we were given.  */
2424   while (limit != fbeg && is_nvspace (limit[-1])) limit--;
2425
2426   switch (*fbeg++) {
2427   case '\"':
2428     fend = fbeg;
2429     while (fend != limit && *fend != '\"')
2430       fend++;
2431     if (*fend == '\"' && fend + 1 == limit)
2432       break;
2433     goto fail;
2434
2435   case '<':
2436     fend = fbeg;
2437     while (fend != limit && *fend != '>') fend++;
2438     if (*fend == '>' && fend + 1 == limit) {
2439       system_header_p = 1;
2440       break;
2441     }
2442     goto fail;
2443
2444   default:
2445   fail:
2446     if (retried) {
2447       error ("#include expects \"fname\" or <fname>");
2448       return;
2449     } else {
2450       trybuf = expand_to_temp_buffer (buf, limit, 0);
2451       buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
2452       memcpy (buf, trybuf.buf, trybuf.bufp - trybuf.buf);
2453       limit = buf + (trybuf.bufp - trybuf.buf);
2454       free (trybuf.buf);
2455       retried++;
2456       goto get_filename;
2457     }
2458   }
2459
2460   flen = fend - fbeg;
2461   process_include (stackp, fbeg, flen, system_header_p, op);
2462 }
2463
2464 static void
2465 process_include (stackp, fbeg, flen, system_header_p, op)
2466      struct file_name_list *stackp;
2467      const U_CHAR *fbeg;
2468      int flen;
2469      int system_header_p;
2470      FILE_BUF *op;
2471 {
2472   char *fname;
2473   int f = -1;                   /* file number */
2474
2475   fname = (char *) alloca (max_include_len + flen + 2);
2476   /* + 2 above for slash and terminating null.  */
2477
2478   /* If specified file name is absolute, just open it.  */
2479
2480   if (IS_ABSOLUTE_PATHNAME (fbeg)) {
2481     strncpy (fname, (const char *)fbeg, flen);
2482     fname[flen] = 0;
2483     f = open (fname, O_RDONLY, 0666);
2484   } else {
2485     /* Search directory path, trying to open the file.
2486        Copy each filename tried into FNAME.  */
2487
2488     for (; stackp; stackp = stackp->next) {
2489       if (stackp->fname) {
2490         strcpy (fname, stackp->fname);
2491         strcat (fname, "/");
2492         fname[strlen (fname) + flen] = 0;
2493       } else {
2494         fname[0] = 0;
2495       }
2496       strncat (fname, (const char *)fbeg, flen);
2497       if ((f = open (fname, O_RDONLY, 0666)) >= 0)
2498         break;
2499     }
2500   }
2501
2502   if (f < 0) {
2503     strncpy (fname, (const char *)fbeg, flen);
2504     fname[flen] = 0;
2505     if (deps_missing_files
2506         && print_deps > (system_header_p || (system_include_depth > 0))) {
2507
2508       /* If requested as a system header, assume it belongs in
2509          the first system header directory. */
2510       if (first_bracket_include)
2511         stackp = first_bracket_include;
2512       else
2513         stackp = include;
2514
2515       if (!system_header_p || IS_ABSOLUTE_PATHNAME (fbeg) || !stackp->fname)
2516         deps_add_dep (deps, fname);
2517       else {
2518         char *p;
2519         int len = strlen(stackp->fname);
2520
2521         p = (char *) alloca (len + flen + 2);
2522         memcpy (p, stackp->fname, len);
2523         p[len++] = '/';
2524         memcpy (p + len, fbeg, flen);
2525         len += flen;
2526         p[len] = '\0';
2527         deps_add_dep (deps, p);
2528       }
2529     } else if (print_deps
2530                && print_deps <= (system_header_p
2531                                  || (system_include_depth > 0)))
2532       warning ("no include path in which to find %.*s", flen, fbeg);
2533     else
2534       error_from_errno (fname);
2535
2536   } else {
2537
2538     /* Check to see if this include file is a once-only include file.
2539        If so, give up.  */
2540
2541     struct file_name_list* ptr;
2542
2543     for (ptr = dont_repeat_files; ptr; ptr = ptr->next) {
2544       if (!strcmp (ptr->fname, fname)) {
2545         close (f);
2546         return;                         /* This file was once'd. */
2547       }
2548     }
2549
2550     for (ptr = all_include_files; ptr; ptr = ptr->next) {
2551       if (!strcmp (ptr->fname, fname))
2552         break;                          /* This file was included before. */
2553     }
2554
2555     if (ptr == 0) {
2556       /* This is the first time for this file.  */
2557       /* Add it to list of files included.  */
2558
2559       ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
2560       ptr->next = all_include_files;
2561       all_include_files = ptr;
2562       ptr->fname = xstrdup (fname);
2563
2564       /* For -M, add this file to the dependencies.  */
2565       if (print_deps > (system_header_p || (system_include_depth > 0)))
2566         deps_add_dep (deps, fname);
2567     }   
2568
2569     if (system_header_p)
2570       system_include_depth++;
2571
2572     /* Actually process the file.  */
2573     finclude (f, fname, stackp->next, op);
2574
2575     if (system_header_p)
2576       system_include_depth--;
2577
2578     close (f);
2579   }
2580 }
2581
2582 /* Process the contents of include file FNAME, already open on descriptor F,
2583    with output to OP.  */
2584
2585 static void
2586 finclude (f, fname, nhd, op)
2587      int f;
2588      const char *fname;
2589      struct file_name_list *nhd;
2590      FILE_BUF *op;
2591 {
2592   int st_mode;
2593   long st_size;
2594   long i;
2595   FILE_BUF *fp;                 /* For input stack frame */
2596
2597   CHECK_DEPTH (return;);
2598
2599   if (file_size_and_mode (f, &st_mode, &st_size))
2600     goto nope;
2601
2602   fp = &instack[indepth + 1];
2603   memset (fp, 0, sizeof (FILE_BUF));
2604   fp->fname = fname;
2605   fp->length = 0;
2606   fp->lineno = 1;
2607   fp->if_stack = if_stack;
2608   fp->next_header_dir = nhd;
2609
2610   if (S_ISREG (st_mode)) {
2611     fp->buf = (U_CHAR *) xmalloc (st_size + 2);
2612     fp->bufp = fp->buf;
2613
2614     /* Read the file contents, knowing that st_size is an upper bound
2615        on the number of bytes we can read.  */
2616     while (st_size > 0) {
2617       i = read (f, fp->buf + fp->length, st_size);
2618       if (i <= 0) {
2619         if (i == 0) break;
2620         goto nope;
2621       }
2622       fp->length += i;
2623       st_size -= i;
2624     }
2625   }
2626   else {
2627     /* Cannot count its file size before reading.  */
2628
2629     U_CHAR *bufp;
2630     U_CHAR *basep;
2631     int bsize = 2000;
2632
2633     st_size = 0;
2634     basep = (U_CHAR *) xmalloc (bsize + 2);
2635     bufp = basep;
2636
2637     for (;;) {
2638       i = read (f, bufp, bsize - st_size);
2639       if (i < 0)
2640         goto nope;      /* error! */
2641       if (i == 0)
2642         break;  /* End of file */
2643       st_size += i;
2644       bufp += i;
2645       if (bsize == st_size) {   /* Buffer is full! */
2646           bsize *= 2;
2647           basep = (U_CHAR *) xrealloc (basep, bsize + 2);
2648           bufp = basep + st_size;       /* May have moved */
2649         }
2650     }
2651     fp->buf = basep;
2652     fp->bufp = fp->buf;
2653     fp->length = st_size;
2654   }
2655   close (f);
2656
2657   /* Make sure data ends with a newline.  And put a null after it.  */
2658
2659   if (fp->length > 0 && fp->buf[fp->length-1] != '\n')
2660     fp->buf[fp->length++] = '\n';
2661   fp->buf[fp->length] = '\0';
2662
2663   indepth++;
2664   output_line_command (fp, op, 0, enter_file);
2665   rescan (op, 0);
2666   indepth--;
2667   instack[indepth].lineno++;
2668   instack[indepth].bufp++;      /* Skip the new line.  */
2669   output_line_command (&instack[indepth], op, 0, leave_file);
2670   free (fp->buf);
2671   return;
2672
2673 nope:
2674   perror_with_name (fname);
2675   close (f);
2676 }
2677 \f
2678
2679 /* Process a #define command.
2680 BUF points to the contents of the #define command, as a continguous string.
2681 LIMIT points to the first character past the end of the definition.
2682 KEYWORD is the keyword-table entry for #define.  */
2683
2684 static void
2685 do_define (buf, limit, op)
2686      U_CHAR *buf, *limit;
2687      FILE_BUF *op ATTRIBUTE_UNUSED;
2688 {
2689   U_CHAR *bp;                   /* temp ptr into input buffer */
2690   U_CHAR *symname;              /* remember where symbol name starts */
2691   int sym_length;               /* and how long it is */
2692
2693   DEFINITION *defn;
2694   int arglengths = 0;           /* Accumulate lengths of arg names
2695                                    plus number of args.  */
2696   int hashcode;
2697
2698   bp = buf;
2699
2700   while (is_nvspace (*bp))
2701     bp++;
2702
2703   symname = bp;                 /* remember where it starts */
2704   while (is_idchar (*bp) && bp < limit) {
2705     bp++;
2706   }
2707   sym_length = bp - symname;
2708   if (sym_length == 0)
2709     {
2710       error ("invalid macro name");
2711       return;
2712     }
2713   else if (!is_idstart (*symname)) {
2714     U_CHAR *msg;                        /* what pain... */
2715     msg = (U_CHAR *) alloca (sym_length + 1);
2716     memcpy (msg, symname, sym_length);
2717     msg[sym_length] = 0;
2718     error ("invalid macro name `%s'", msg);
2719     return;
2720   } else {
2721     if (! strncmp ((const char *)symname, "defined", 7) && sym_length == 7)
2722       {
2723         error ("\"defined\" cannot be used as a macro name");
2724         return;
2725       }
2726   }
2727
2728   /* lossage will occur if identifiers or control keywords are broken
2729      across lines using backslash.  This is not the right place to take
2730      care of that. */
2731
2732   if (*bp == '(') {
2733     struct arglist *arg_ptrs = NULL;
2734     int argno = 0;
2735
2736     bp++;                       /* skip '(' */
2737     SKIP_WHITE_SPACE (bp);
2738
2739     /* Loop over macro argument names.  */
2740     while (*bp != ')') {
2741       struct arglist *temp;
2742
2743       temp = (struct arglist *) alloca (sizeof (struct arglist));
2744       temp->name = bp;
2745       temp->next = arg_ptrs;
2746       temp->argno = argno++;
2747       arg_ptrs = temp;
2748
2749       if (!is_idstart (*bp))
2750         warning ("parameter name starts with a digit in #define");
2751
2752       /* Find the end of the arg name.  */
2753       while (is_idchar (*bp)) {
2754         bp++;
2755       }
2756       temp->length = bp - temp->name;
2757       arglengths += temp->length + 2;
2758       SKIP_WHITE_SPACE (bp);
2759       if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
2760         error ("badly punctuated parameter list in #define");
2761         return;
2762       }
2763       if (*bp == ',') {
2764         bp++;
2765         SKIP_WHITE_SPACE (bp);
2766       }
2767       if (bp >= limit) {
2768         error ("unterminated parameter list in #define");
2769         return;
2770       }
2771     }
2772
2773     ++bp;                                       /* skip paren */
2774     while (is_nvspace (*bp) && bp < limit)      /* and leading whitespace */
2775       ++bp;
2776     /* now everything from bp before limit is the definition. */
2777     defn = collect_expansion (bp, limit, argno, arg_ptrs);
2778
2779     /* Now set defn->argnames to the result of concatenating
2780        the argument names in reverse order
2781        with comma-space between them.  */
2782     {
2783       struct arglist *temp;
2784       int i = 0;
2785       U_CHAR *tmp = (U_CHAR *) xmalloc (arglengths + 1);
2786
2787       for (temp = arg_ptrs; temp; temp = temp->next) {
2788         memcpy (&tmp[i], temp->name, temp->length);
2789         i += temp->length;
2790         if (temp->next != 0) {
2791           tmp[i++] = ',';
2792           tmp[i++] = ' ';
2793         }
2794       }
2795       tmp[i] = 0;
2796       defn->argnames = tmp;
2797       
2798     }
2799   } else {
2800     /* simple expansion or empty definition; skip leading whitespace */
2801     while (is_nvspace (*bp) && bp < limit)
2802       ++bp;
2803     /* now everything from bp before limit is the definition. */
2804     defn = collect_expansion (bp, limit, -1, 0);
2805     defn->argnames = (const U_CHAR *) "";
2806   }
2807
2808   hashcode = hashf (symname, sym_length, HASHSIZE);
2809
2810   {
2811     HASHNODE *hp;
2812     if ((hp = lookup (symname, sym_length, hashcode)) == NULL)
2813       hp = install (symname, sym_length, T_MACRO, hashcode);
2814     else {
2815       if (hp->type != T_MACRO || compare_defs (defn, hp->value.defn))
2816         warning ("\"%.*s\" redefined", sym_length, symname);
2817
2818       /* Replace the old definition.  */
2819       hp->type = T_MACRO;
2820     }
2821
2822     hp->value.defn = defn;
2823   }
2824 }
2825
2826 /*
2827  * return zero if two DEFINITIONs are isomorphic
2828  */
2829 static int
2830 compare_defs (d1, d2)
2831      DEFINITION *d1, *d2;
2832 {
2833   struct reflist *a1, *a2;
2834   U_CHAR *p1 = d1->expansion;
2835   U_CHAR *p2 = d2->expansion;
2836   int first = 1;
2837
2838   if (d1->nargs != d2->nargs)
2839     return 1;
2840   if (strcmp ((const char *)d1->argnames, (const char *)d2->argnames))
2841     return 1;
2842   for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
2843        a1 = a1->next, a2 = a2->next) {
2844     if (!((a1->nchars == a2->nchars
2845            && ! strncmp ((const char *)p1, (const char *)p2, a1->nchars))
2846           || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
2847         || a1->argno != a2->argno
2848         || a1->stringify != a2->stringify
2849         || a1->raw_before != a2->raw_before
2850         || a1->raw_after != a2->raw_after)
2851       return 1;
2852     first = 0;
2853     p1 += a1->nchars;
2854     p2 += a2->nchars;
2855   }
2856   if (a1 != a2)
2857     return 1;
2858   if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
2859                      p2, d2->length - (p2 - d2->expansion), 1))
2860     return 1;
2861   return 0;
2862 }
2863
2864 /* Return 1 if two parts of two macro definitions are effectively different.
2865    One of the parts starts at BEG1 and has LEN1 chars;
2866    the other has LEN2 chars at BEG2.
2867    Any sequence of whitespace matches any other sequence of whitespace.
2868    FIRST means these parts are the first of a macro definition;
2869     so ignore leading whitespace entirely.
2870    LAST means these parts are the last of a macro definition;
2871     so ignore trailing whitespace entirely.  */
2872 static int
2873 comp_def_part (first, beg1, len1, beg2, len2, last)
2874      int first;
2875      const U_CHAR *beg1, *beg2;
2876      int len1, len2;
2877      int last;
2878 {
2879   const U_CHAR *end1 = beg1 + len1;
2880   const U_CHAR *end2 = beg2 + len2;
2881   if (first) {
2882     while (beg1 != end1 && is_space (*beg1)) beg1++;
2883     while (beg2 != end2 && is_space (*beg2)) beg2++;
2884   }
2885   if (last) {
2886     while (beg1 != end1 && is_space (end1[-1])) end1--;
2887     while (beg2 != end2 && is_space (end2[-1])) end2--;
2888   }
2889   while (beg1 != end1 && beg2 != end2) {
2890     if (is_space (*beg1) && is_space (*beg2)) {
2891       while (beg1 != end1 && is_space (*beg1)) beg1++;
2892       while (beg2 != end2 && is_space (*beg2)) beg2++;
2893     } else if (*beg1 == *beg2) {
2894       beg1++; beg2++;
2895     } else break;
2896   }
2897   return (beg1 != end1) || (beg2 != end2);
2898 }
2899
2900 /* Read a replacement list for a macro with parameters.
2901    Build the DEFINITION structure.
2902    Reads characters of text starting at BUF until LIMIT.
2903    ARGLIST specifies the formal parameters to look for
2904    in the text of the definition; NARGS is the number of args
2905    in that list, or -1 for a macro name that wants no argument list.
2906    MACRONAME is the macro name itself (so we can avoid recursive expansion)
2907    and NAMELEN is its length in characters.
2908    
2909 Note that comments and backslash-newlines have already been deleted
2910 from the argument.  */
2911
2912 /* Leading and trailing Space, Tab, etc. are converted to markers
2913    Newline Space, Newline Tab, etc.
2914    Newline Space makes a space in the final output
2915    but is discarded if stringified.  (Newline Tab is similar but
2916    makes a Tab instead.)
2917
2918    If there is no trailing whitespace, a Newline Space is added at the end
2919    to prevent concatenation that would be contrary to the standard.  */
2920
2921 static DEFINITION *
2922 collect_expansion (buf, end, nargs, arglist)
2923      U_CHAR *buf, *end;
2924      int nargs;
2925      struct arglist *arglist;
2926 {
2927   DEFINITION *defn;
2928   U_CHAR *p, *limit, *lastp, *exp_p;
2929   struct reflist *endpat = NULL;
2930   /* Pointer to first nonspace after last ## seen.  */
2931   U_CHAR *concat = 0;
2932   /* Pointer to first nonspace after last single-# seen.  */
2933   U_CHAR *stringify = 0;
2934   int maxsize;
2935   int expected_delimiter = '\0';
2936
2937   /* Scan thru the replacement list, ignoring comments and quoted
2938      strings, picking up on the macro calls.  It does a linear search
2939      thru the arg list on every potential symbol.  Profiling might say
2940      that something smarter should happen. */
2941
2942   if (end < buf)
2943     abort ();
2944
2945   /* Find the beginning of the trailing whitespace.  */
2946   /* Find end of leading whitespace.  */
2947   limit = end;
2948   p = buf;
2949   while (p < limit && is_space (limit[-1])) limit--;
2950   while (p < limit && is_space (*p)) p++;
2951
2952   /* Allocate space for the text in the macro definition.
2953      Leading and trailing whitespace chars need 2 bytes each.
2954      Each other input char may or may not need 1 byte,
2955      so this is an upper bound.
2956      The extra 2 are for invented trailing newline-marker and final null.  */
2957   maxsize = (sizeof (DEFINITION)
2958              + 2 * (end - limit) + 2 * (p - buf)
2959              + (limit - p) + 3);
2960   defn = (DEFINITION *) xcalloc (1, maxsize);
2961
2962   defn->nargs = nargs;
2963   exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
2964   lastp = exp_p;
2965
2966   p = buf;
2967
2968   /* Convert leading whitespace to Newline-markers.  */
2969   while (p < limit && is_space (*p)) {
2970     *exp_p++ = '\n';
2971     *exp_p++ = *p++;
2972   }
2973
2974   /* Process the main body of the definition.  */
2975   while (p < limit) {
2976     int skipped_arg = 0;
2977     U_CHAR c = *p++;
2978
2979     *exp_p++ = c;
2980
2981     /* In -traditional mode, recognize arguments inside strings and
2982        and character constants, and ignore special properties of #.
2983        Arguments inside strings are considered "stringified", but no
2984        extra quote marks are supplied.  */
2985     switch (c) {
2986     case '\'':
2987     case '\"':
2988       if (expected_delimiter != '\0') {
2989         if (c == expected_delimiter)
2990           expected_delimiter = '\0';
2991       } else
2992         expected_delimiter = c;
2993       break;
2994
2995     case '\\':
2996       /* Backslash quotes delimiters and itself, but not macro args.  */
2997       if (expected_delimiter != 0 && p < limit
2998           && (*p == expected_delimiter || *p == '\\')) {
2999         *exp_p++ = *p++;
3000         continue;
3001       }
3002       break;
3003
3004     case '/':
3005       if (expected_delimiter != '\0') /* No comments inside strings.  */
3006         break;
3007       if (*p == '*') {
3008         /* If we find a comment that wasn't removed by handle_directive,
3009            this must be -traditional.  So replace the comment with
3010            nothing at all.  */
3011         exp_p--;
3012         p += 1;
3013         while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
3014           p++;
3015       }
3016       break;
3017     }
3018
3019     if (is_idchar (c) && nargs > 0) {
3020       U_CHAR *id_beg = p - 1;
3021       int id_len;
3022
3023       --exp_p;
3024       while (p != limit && is_idchar (*p)) p++;
3025       id_len = p - id_beg;
3026
3027       if (is_idstart (c)) {
3028         struct arglist *arg;
3029
3030         for (arg = arglist; arg != NULL; arg = arg->next) {
3031           struct reflist *tpat;
3032
3033           if (arg->name[0] == c
3034               && arg->length == id_len
3035               && strncmp ((const char *)arg->name,
3036                           (const char *)id_beg, id_len) == 0) {
3037             /* make a pat node for this arg and append it to the end of
3038                the pat list */
3039             tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
3040             tpat->next = NULL;
3041             tpat->raw_before = concat == id_beg;
3042             tpat->raw_after = 0;
3043             tpat->stringify = expected_delimiter != '\0';
3044
3045             if (endpat == NULL)
3046               defn->pattern = tpat;
3047             else
3048               endpat->next = tpat;
3049             endpat = tpat;
3050
3051             tpat->argno = arg->argno;
3052             tpat->nchars = exp_p - lastp;
3053             {
3054               U_CHAR *p1 = p;
3055               SKIP_WHITE_SPACE (p1);
3056               if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
3057                 tpat->raw_after = 1;
3058             }
3059             lastp = exp_p;      /* place to start copying from next time */
3060             skipped_arg = 1;
3061             break;
3062           }
3063         }
3064       }
3065
3066       /* If this was not a macro arg, copy it into the expansion.  */
3067       if (! skipped_arg) {
3068         U_CHAR *lim1 = p;
3069         p = id_beg;
3070         while (p != lim1)
3071           *exp_p++ = *p++;
3072         if (stringify == id_beg)
3073           error ("# operator should be followed by a macro argument name");
3074       }
3075     }
3076   }
3077
3078   if (limit < end) {
3079     /* Convert trailing whitespace to Newline-markers.  */
3080     while (limit < end && is_space (*limit)) {
3081       *exp_p++ = '\n';
3082       *exp_p++ = *limit++;
3083     }
3084   }
3085   *exp_p = '\0';
3086
3087   defn->length = exp_p - defn->expansion;
3088
3089   /* Crash now if we overrun the allocated size.  */
3090   if (defn->length + 1 > maxsize)
3091     abort ();
3092
3093   return defn;
3094 }
3095 \f
3096 /*
3097  * interpret #line command.  Remembers previously seen fnames
3098  * in its very own hash table.
3099  */
3100 #define FNAME_HASHSIZE 37
3101 static void
3102 do_line (buf, limit, op)
3103      U_CHAR *buf, *limit;
3104      FILE_BUF *op;
3105 {
3106   U_CHAR *bp;
3107   FILE_BUF *ip = &instack[indepth];
3108   FILE_BUF tem;
3109   int new_lineno;
3110   enum file_change_code file_change = same_file;
3111
3112   /* Expand any macros.  */
3113   tem = expand_to_temp_buffer (buf, limit, 0);
3114
3115   /* Point to macroexpanded line, which is null-terminated now.  */
3116   bp = tem.buf;
3117   SKIP_WHITE_SPACE (bp);
3118
3119   if (!ISDIGIT (*bp)) {
3120     error ("invalid format #line command");
3121     return;
3122   }
3123
3124   /* The Newline at the end of this line remains to be processed.
3125      To put the next line at the specified line number,
3126      we must store a line number now that is one less.  */
3127   new_lineno = atoi ((const char *)bp);
3128
3129   /* skip over the line number.  */
3130   while (ISDIGIT (*bp))
3131     bp++;
3132
3133   SKIP_WHITE_SPACE (bp);
3134
3135   if (*bp == '\"') {
3136     static HASHNODE *fname_table[FNAME_HASHSIZE];
3137     HASHNODE *hp, **hash_bucket;
3138     U_CHAR *fname;
3139     int fname_length;
3140
3141     fname = ++bp;
3142
3143     while (*bp && *bp != '\"')
3144       bp++;
3145     if (*bp != '\"') {
3146       error ("invalid format #line command");
3147       return;
3148     }
3149
3150     fname_length = bp - fname;
3151
3152     bp++;
3153     SKIP_WHITE_SPACE (bp);
3154     if (*bp) {
3155       if (*bp == '1')
3156         file_change = enter_file;
3157       else if (*bp == '2')
3158         file_change = leave_file;
3159       else {
3160         error ("invalid format #line command");
3161         return;
3162       }
3163
3164       bp++;
3165       SKIP_WHITE_SPACE (bp);
3166       if (*bp) {
3167         error ("invalid format #line command");
3168         return;
3169       }
3170     }
3171
3172     hash_bucket =
3173       &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
3174     for (hp = *hash_bucket; hp != NULL; hp = hp->next)
3175       if (hp->length == fname_length &&
3176           strncmp (hp->value.cpval, (const char *)fname, fname_length) == 0) {
3177         ip->fname = hp->value.cpval;
3178         break;
3179       }
3180     if (hp == 0) {
3181       char *q;
3182       /* Didn't find it; cons up a new one.  */
3183       hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
3184       hp->next = *hash_bucket;
3185       *hash_bucket = hp;
3186
3187       hp->length = fname_length;
3188       ip->fname = hp->value.cpval = q = ((char *) hp) + sizeof (HASHNODE);
3189       memcpy (q, fname, fname_length);
3190     }
3191   } else if (*bp) {
3192     error ("invalid format #line command");
3193     return;
3194   }
3195
3196   ip->lineno = new_lineno;
3197   output_line_command (ip, op, 0, file_change);
3198   ip->bufp++;                   /* Skip the new line.  */
3199   check_expand (op, ip->length - (ip->bufp - ip->buf));
3200 }
3201
3202 /*
3203  * remove all definitions of symbol from symbol table.
3204  * according to un*x /lib/cpp, it is not an error to undef
3205  * something that has no definitions, so it isn't one here either.
3206  */
3207 static void
3208 do_undef (buf, limit, op)
3209      U_CHAR *buf;
3210      U_CHAR *limit ATTRIBUTE_UNUSED;
3211      FILE_BUF *op ATTRIBUTE_UNUSED;
3212 {
3213   HASHNODE *hp;
3214
3215   SKIP_WHITE_SPACE (buf);
3216
3217   if (! strncmp ((const char *)buf, "defined", 7) && ! is_idchar (buf[7]))
3218     warning ("undefining `defined'");
3219
3220   while ((hp = lookup (buf, -1, -1)) != NULL) {
3221     if (hp->type != T_MACRO)
3222       warning ("undefining `%s'", hp->name);
3223     delete_macro (hp);
3224   }
3225 }
3226
3227 /* Read the tokens of the answer into the macro pool.  Only commit the
3228    memory if we intend it as permanent storage, i.e. the #assert case.
3229    Returns 0 on success.  */
3230
3231 static int
3232 parse_answer (buf, limit, answerp, type)
3233      const unsigned char *buf, *limit;
3234      struct answer **answerp;
3235      int type;
3236 {
3237   const unsigned char *start;
3238
3239   /* Skip leading whitespace.  */
3240   if (buf < limit && *buf == ' ')
3241     buf++;
3242
3243   /* Parentheses are optional here.  */
3244   if (buf == limit && type == T_UNASSERT)
3245     return 0;
3246
3247   if (buf == limit || *buf++ != '(')
3248     {
3249       if (type == T_IF)
3250         return 0;
3251
3252       error ("missing '(' after predicate");
3253       return 1;
3254     }
3255
3256   /* Drop whitespace at start.  */
3257   while (buf < limit && *buf == ' ')
3258     buf++;
3259
3260   start = buf;
3261   while (buf < limit && *buf != ')')
3262     buf++;
3263
3264   if (buf == limit)
3265     {
3266       error ("missing ')' to complete answer");
3267       return 1;
3268     }
3269
3270   if (buf == start)
3271     {
3272       error ("predicate's answer is empty");
3273       return 1;
3274     }
3275
3276   if ((type == T_ASSERT || type == T_UNASSERT) && buf + 1 != limit)
3277     {
3278       error ("extra text at end of directive");
3279       return 1;
3280     }
3281
3282   /* Lose trailing whitespace.  */
3283   if (buf[-1] == ' ')
3284     buf--;
3285
3286   *answerp = (struct answer *) xmalloc (sizeof (struct answer));
3287   (*answerp)->answer = start;
3288   (*answerp)->len = buf - start;
3289
3290   return 0;
3291 }
3292
3293 /* Parses an assertion, returning a pointer to the hash node of the
3294    predicate, or 0 on error.  If an answer was supplied, it is placed
3295    in ANSWERP, otherwise it is set to 0.  */
3296 static HASHNODE *
3297 parse_assertion (buf, limit, answerp, type)
3298      const unsigned char *buf, *limit;
3299      struct answer **answerp;
3300      int type;
3301 {
3302   HASHNODE *result = 0;
3303   const unsigned char *climit;
3304   unsigned char *bp, *symname = canonicalize_text (buf, limit, &climit);
3305   unsigned int len;
3306
3307   bp = symname;
3308   if (bp < climit && is_idstart (*bp))
3309     {
3310       do
3311         bp++;
3312       while (bp < climit && is_idchar (*bp));
3313     }
3314   len = bp - symname;
3315
3316   *answerp = 0;
3317   if (len == 0)
3318     {
3319       if (symname == climit)
3320         error ("assertion without predicate");
3321       else
3322         error ("predicate must be an identifier");
3323     }
3324   /* Unfortunately, because of the way we handle #if, we don't avoid
3325      macro expansion in answers.  This is not easy to fix.  */
3326   else if (parse_answer (bp, climit, answerp, type) == 0)
3327     {
3328       unsigned char *sym = alloca (len + 1);
3329       int hashcode;
3330       
3331       /* Prefix '#' to get it out of macro namespace.  */
3332       sym[0] = '#';
3333       memcpy (sym + 1, symname, len);
3334
3335       hashcode = hashf (sym, len + 1, HASHSIZE);
3336       result = lookup (sym, len + 1, hashcode);
3337       if (result == 0)
3338         result = install (sym, len + 1, T_UNUSED, hashcode);
3339     }
3340
3341   return result;
3342 }
3343
3344 /* Test an assertion within a preprocessor conditional.  Returns zero
3345    on error or failure, one on success.  */
3346 int
3347 test_assertion (pbuf)
3348      unsigned char **pbuf;      /* NUL-terminated.  */
3349 {
3350   unsigned char *buf = *pbuf;
3351   unsigned char *limit = buf + strlen ((char *) buf);
3352   struct answer *answer;
3353   HASHNODE *node;
3354   int result = 0;
3355
3356   node = parse_assertion (buf, limit, &answer, T_IF);
3357   if (node)
3358     {
3359       result = (node->type == T_ASSERT &&
3360                 (answer == 0 || *find_answer (node, answer) != 0));
3361
3362       /* Yuk.  We update pbuf to point after the assertion test.
3363          First, move past the identifier.  */
3364       if (is_space (*buf))
3365         buf++;
3366       while (is_idchar (*buf))
3367         buf++;
3368       /* If we have an answer, we need to move past the parentheses.  */
3369       if (answer)
3370         while (*buf++ != ')')
3371           ;
3372       *pbuf = buf;
3373     }
3374
3375   return result;
3376 }
3377
3378 /* Handle a #error directive.  */
3379 static void
3380 do_error (buf, limit, op)
3381      U_CHAR *buf;
3382      U_CHAR *limit;
3383      FILE_BUF *op ATTRIBUTE_UNUSED;
3384 {
3385   error ("#error%.*s", (int) (limit - buf), buf);
3386 }
3387
3388 /* Handle a #warning directive.  */
3389 static void
3390 do_warning (buf, limit, op)
3391      U_CHAR *buf;
3392      U_CHAR *limit;
3393      FILE_BUF *op ATTRIBUTE_UNUSED;
3394 {
3395   warning ("#warning%.*s", (int) (limit - buf), buf);
3396 }
3397
3398 /* Handle a #assert directive.  */
3399 static void
3400 do_assert (buf, limit, op)
3401      U_CHAR *buf;
3402      U_CHAR *limit;
3403      FILE_BUF *op ATTRIBUTE_UNUSED;
3404 {
3405   struct answer *new_answer;
3406   HASHNODE *node;
3407   
3408   node = parse_assertion (buf, limit, &new_answer, T_ASSERT);
3409   if (node)
3410     {
3411       /* Place the new answer in the answer list.  First check there
3412          is not a duplicate.  */
3413       new_answer->next = 0;
3414       if (node->type == T_ASSERT)
3415         {
3416           if (*find_answer (node, new_answer))
3417             {
3418               free (new_answer);
3419               warning ("\"%s\" re-asserted", node->name + 1);
3420               return;
3421             }
3422           new_answer->next = node->value.answers;
3423         }
3424       node->type = T_ASSERT;
3425       node->value.answers = new_answer;
3426     }
3427 }
3428
3429 /* Function body to be provided later.  */
3430 static void
3431 do_unassert (buf, limit, op)
3432      U_CHAR *buf;
3433      U_CHAR *limit;
3434      FILE_BUF *op ATTRIBUTE_UNUSED;
3435 {
3436   HASHNODE *node;
3437   struct answer *answer;
3438   
3439   node = parse_assertion (buf, limit, &answer, T_UNASSERT);
3440   /* It isn't an error to #unassert something that isn't asserted.  */
3441   if (node)
3442     {
3443       if (node->type == T_ASSERT)
3444         {
3445           if (answer)
3446             {
3447               struct answer **p = find_answer (node, answer), *temp;
3448
3449               /* Remove the answer from the list.  */
3450               temp = *p;
3451               if (temp)
3452                 *p = temp->next;
3453
3454               /* Did we free the last answer?  */
3455               if (node->value.answers == 0)
3456                 delete_macro (node);
3457             }
3458           else
3459             delete_macro (node);
3460         }
3461
3462       free (answer);
3463     }
3464 }
3465
3466 /* Returns a pointer to the pointer to the answer in the answer chain,
3467    or a pointer to NULL if the answer is not in the chain.  */
3468 static struct answer **
3469 find_answer (node, candidate)
3470      HASHNODE *node;
3471      const struct answer *candidate;
3472 {
3473   struct answer **result;
3474
3475   for (result = &node->value.answers; *result; result = &(*result)->next)
3476     {
3477       struct answer *answer = *result;
3478
3479       if (answer->len == candidate->len
3480           && !memcmp (answer->answer, candidate->answer, answer->len))
3481         break;
3482     }
3483
3484   return result;
3485 }
3486
3487 /* Return a malloced buffer with leading and trailing whitespace
3488    removed, and all instances of internal whitespace reduced to a
3489    single space.  */
3490 static unsigned char *
3491 canonicalize_text (buf, limit, climit)
3492      const unsigned char *buf, *limit, **climit;
3493 {
3494   unsigned int len = limit - buf;
3495   unsigned char *result = (unsigned char *) xmalloc (len), *dest;
3496
3497   for (dest = result; buf < limit;)
3498     {
3499       if (! is_space (*buf))
3500         *dest++ = *buf++;
3501       else
3502         {
3503           while (++buf < limit && is_space (*buf))
3504             ;
3505           if (dest != result && buf != limit)
3506             *dest++ = ' ';
3507         }
3508     }
3509
3510   *climit = dest;
3511   return result;
3512 }
3513
3514 /*
3515  * handle #if command by
3516  *   1) inserting special `defined' keyword into the hash table
3517  *      that gets turned into 0 or 1 by special_symbol (thus,
3518  *      if the luser has a symbol called `defined' already, it won't
3519  *      work inside the #if command)
3520  *   2) rescan the input into a temporary output buffer
3521  *   3) pass the output buffer to the yacc parser and collect a value
3522  *   4) clean up the mess left from steps 1 and 2.
3523  *   5) call conditional_skip to skip til the next #endif (etc.),
3524  *      or not, depending on the value from step 3.
3525  */
3526 static void
3527 do_if (buf, limit, op)
3528      U_CHAR *buf, *limit;
3529      FILE_BUF *op ATTRIBUTE_UNUSED;
3530 {
3531   int value;
3532   FILE_BUF *ip = &instack[indepth];
3533
3534   value = eval_if_expression (buf, limit - buf);
3535   conditional_skip (ip, value == 0, T_IF);
3536 }
3537
3538 /*
3539  * handle a #elif directive by not changing  if_stack  either.
3540  * see the comment above do_else.
3541  */
3542 static void
3543 do_elif (buf, limit, op)
3544      U_CHAR *buf, *limit;
3545      FILE_BUF *op;
3546 {
3547   int value;
3548   FILE_BUF *ip = &instack[indepth];
3549
3550   if (if_stack == instack[indepth].if_stack) {
3551     error ("#elif not within a conditional");
3552     return;
3553   } else {
3554     if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
3555       error ("#elif after #else");
3556       fprintf (stderr, " (matches line %d", if_stack->lineno);
3557       if (if_stack->fname != NULL && ip->fname != NULL &&
3558           strcmp (if_stack->fname, ip->fname) != 0)
3559         fprintf (stderr, ", file %s", if_stack->fname);
3560       fprintf (stderr, ")\n");
3561     }
3562     if_stack->type = T_ELIF;
3563   }
3564
3565   if (if_stack->if_succeeded)
3566     skip_if_group (ip, 0);
3567   else {
3568     value = eval_if_expression (buf, limit - buf);
3569     if (value == 0)
3570       skip_if_group (ip, 0);
3571     else {
3572       ++if_stack->if_succeeded; /* continue processing input */
3573       output_line_command (ip, op, 1, same_file);
3574     }
3575   }
3576 }
3577
3578 /*
3579  * evaluate a #if expression in BUF, of length LENGTH,
3580  * then parse the result as a C expression and return the value as an int.
3581  */
3582 static int
3583 eval_if_expression (buf, length)
3584      const U_CHAR *buf;
3585      int length;
3586 {
3587   FILE_BUF temp_obuf;
3588   HASHNODE *save_defined;
3589   int value;
3590
3591   save_defined = install (U"defined", -1, T_SPEC_DEFINED, -1);
3592   temp_obuf = expand_to_temp_buffer (buf, buf + length, 0);
3593   delete_macro (save_defined);  /* clean up special symbol */
3594
3595   value = parse_c_expression ((const char *)temp_obuf.buf);
3596
3597   free (temp_obuf.buf);
3598
3599   return value;
3600 }
3601
3602 /*
3603  * routine to handle ifdef/ifndef.  Try to look up the symbol,
3604  * then do or don't skip to the #endif/#else/#elif depending
3605  * on what directive is actually being processed.
3606  */
3607 static void
3608 do_xifdef (buf, limit, type)
3609      U_CHAR *buf, *limit;
3610      enum node_type type;     
3611 {
3612   int skip;
3613   FILE_BUF *ip = &instack[indepth];
3614   U_CHAR *end; 
3615
3616   /* Discard leading and trailing whitespace.  */
3617   SKIP_WHITE_SPACE (buf);
3618   while (limit != buf && is_nvspace (limit[-1])) limit--;
3619
3620   /* Find the end of the identifier at the beginning.  */
3621   for (end = buf; is_idchar (*end); end++);
3622
3623   if (end == buf)
3624     skip = (type == T_IFDEF);
3625   else
3626     skip = (lookup (buf, end-buf, -1) == NULL) ^ (type == T_IFNDEF);
3627
3628   conditional_skip (ip, skip, T_IF);
3629 }
3630
3631 static void
3632 do_ifdef (buf, limit, op)
3633      U_CHAR *buf, *limit;
3634      FILE_BUF *op ATTRIBUTE_UNUSED;
3635 {
3636   do_xifdef (buf, limit, T_IFDEF);
3637 }
3638
3639 static void
3640 do_ifndef (buf, limit, op)
3641      U_CHAR *buf, *limit;
3642      FILE_BUF *op ATTRIBUTE_UNUSED;
3643 {
3644   do_xifdef (buf, limit, T_IFNDEF);
3645 }
3646
3647 /*
3648  * push TYPE on stack; then, if SKIP is nonzero, skip ahead.
3649  */
3650 static void
3651 conditional_skip (ip, skip, type)
3652      FILE_BUF *ip;
3653      int skip;
3654      enum node_type type;
3655 {
3656   IF_STACK_FRAME *temp;
3657
3658   temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
3659   temp->fname = ip->fname;
3660   temp->lineno = ip->lineno;
3661   temp->next = if_stack;
3662   if_stack = temp;
3663
3664   if_stack->type = type;
3665
3666   if (skip != 0) {
3667     skip_if_group (ip, 0);
3668     return;
3669   } else {
3670     ++if_stack->if_succeeded;
3671     output_line_command (ip, &outbuf, 1, same_file);
3672   }
3673 }
3674
3675 /*
3676  * skip to #endif, #else, or #elif.  adjust line numbers, etc.
3677  * leaves input ptr at the sharp sign found.
3678  * If ANY is nonzero, return at next directive of any sort.
3679  */
3680 static void
3681 skip_if_group (ip, any)
3682      FILE_BUF *ip;
3683      int any;
3684 {
3685   U_CHAR *bp = ip->bufp, *cp;
3686   U_CHAR *endb = ip->buf + ip->length;
3687   struct directive *kt;
3688   IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */
3689   U_CHAR *beg_of_line = bp;
3690
3691   while (bp < endb) {
3692     switch (*bp++) {
3693     case '/':                   /* possible comment */
3694       if (*bp == '\\' && bp[1] == '\n')
3695         newline_fix (bp);
3696       if (*bp == '*') {
3697         ip->bufp = ++bp;
3698         bp = skip_to_end_of_comment (ip, &ip->lineno);
3699       }
3700       break;
3701     case '\"':
3702     case '\'':
3703       bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno, 0, 0);
3704       break;
3705     case '\\':
3706       /* Char after backslash loses its special meaning.  */
3707       if (bp < endb) {
3708         if (*bp == '\n')
3709           ++ip->lineno;         /* But do update the line-count.  */
3710         bp++;
3711       }
3712       break;
3713     case '\n':
3714       ++ip->lineno;
3715       beg_of_line = bp;
3716       break;
3717     case '#':
3718       ip->bufp = bp - 1;
3719
3720       /* # keyword: a # must be first nonblank char on the line */
3721       if (beg_of_line == 0)
3722         break;
3723       /* Scan from start of line, skipping whitespace, comments
3724          and backslash-newlines, and see if we reach this #.
3725          If not, this # is not special.  */
3726       bp = beg_of_line;
3727       while (1) {
3728         if (is_nvspace (*bp))
3729           bp++;
3730         else if (*bp == '\\' && bp[1] == '\n')
3731           bp += 2;
3732         else if (*bp == '/' && bp[1] == '*') {
3733           bp += 2;
3734           while (!(*bp == '*' && bp[1] == '/')) {
3735             if (*bp == '\n')
3736               ip->lineno++;
3737             bp++;
3738           }
3739           bp += 2;
3740         }
3741         else break;
3742       }
3743       if (bp != ip->bufp) {
3744         bp = ip->bufp + 1;      /* Reset bp to after the #.  */
3745         break;
3746       }
3747
3748       bp = ip->bufp + 1;        /* Point after '#'.  */
3749
3750       /* Skip whitespace and \-newline.  */
3751       while (1) {
3752         if (is_nvspace (*bp))
3753           bp++;
3754         else if (*bp == '\\' && bp[1] == '\n')
3755           bp += 2;
3756         else if (*bp == '/' && bp[1] == '*') {
3757           bp += 2;
3758           while (!(*bp == '*' && bp[1] == '/'))
3759             bp++;
3760           bp += 2;
3761         }
3762         else break;
3763       }
3764
3765       cp = bp;
3766
3767       /* Now find end of directive name.
3768          If we encounter a backslash-newline, exchange it with any following
3769          symbol-constituents so that we end up with a contiguous name.  */
3770
3771       while (1) {
3772         if (is_idchar (*bp))
3773           bp++;
3774         else {
3775           if (*bp == '\\' && bp[1] == '\n')
3776             name_newline_fix (bp);
3777           if (is_idchar (*bp))
3778             bp++;
3779           else break;
3780         }
3781       }
3782
3783       for (kt = directive_table; kt->length >= 0; kt++) {
3784         IF_STACK_FRAME *temp;
3785         if (strncmp ((const char *)cp, kt->name, kt->length) == 0
3786             && !is_idchar (cp[kt->length])) {
3787
3788           /* If we are asked to return on next directive,
3789              do so now.  */
3790           if (any)
3791             return;
3792
3793           switch (kt->type) {
3794           case T_IF:
3795           case T_IFDEF:
3796           case T_IFNDEF:
3797             temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
3798             temp->next = if_stack;
3799             if_stack = temp;
3800             temp->lineno = ip->lineno;
3801             temp->fname = ip->fname;
3802             temp->type = kt->type;
3803             break;
3804           case T_ELSE:
3805           case T_ENDIF:
3806           case T_ELIF:
3807             if (if_stack == instack[indepth].if_stack) {
3808               error ("#%s not within a conditional", kt->name);
3809               break;
3810             }
3811             else if (if_stack == save_if_stack)
3812               return;           /* found what we came for */
3813
3814             if (kt->type != T_ENDIF) {
3815               if (if_stack->type == T_ELSE)
3816                 error ("#else or #elif after #else");
3817               if_stack->type = kt->type;
3818               break;
3819             }
3820
3821             temp = if_stack;
3822             if_stack = if_stack->next;
3823             free (temp);
3824             break;
3825
3826           default:
3827             /* Anything else is ignored.  */
3828             break;
3829           }
3830           break;
3831         }
3832       }
3833     }
3834   }
3835   ip->bufp = bp;
3836   /* after this returns, rescan will exit because ip->bufp
3837      now points to the end of the buffer.
3838      rescan is responsible for the error message also.  */
3839 }
3840
3841 /*
3842  * handle a #else directive.  Do this by just continuing processing
3843  * without changing  if_stack ;  this is so that the error message
3844  * for missing #endif's etc. will point to the original #if.  It
3845  * is possible that something different would be better.
3846  */
3847 static void
3848 do_else (buf, limit, op)
3849      U_CHAR *buf ATTRIBUTE_UNUSED;
3850      U_CHAR *limit ATTRIBUTE_UNUSED;
3851      FILE_BUF *op;
3852 {
3853   FILE_BUF *ip = &instack[indepth];
3854
3855   if (if_stack == instack[indepth].if_stack) {
3856     error ("#else not within a conditional");
3857     return;
3858   } else {
3859     if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
3860       error ("#else after #else");
3861       fprintf (stderr, " (matches line %d", if_stack->lineno);
3862       if (strcmp (if_stack->fname, ip->fname) != 0)
3863         fprintf (stderr, ", file %s", if_stack->fname);
3864       fprintf (stderr, ")\n");
3865     }
3866     if_stack->type = T_ELSE;
3867   }
3868
3869   if (if_stack->if_succeeded)
3870     skip_if_group (ip, 0);
3871   else {
3872     ++if_stack->if_succeeded;   /* continue processing input */
3873     output_line_command (ip, op, 1, same_file);
3874   }
3875 }
3876
3877 /*
3878  * unstack after #endif command
3879  */
3880 static void
3881 do_endif (buf, limit, op)
3882      U_CHAR *buf ATTRIBUTE_UNUSED;
3883      U_CHAR *limit ATTRIBUTE_UNUSED;
3884      FILE_BUF *op;
3885 {
3886   if (if_stack == instack[indepth].if_stack)
3887     error ("unbalanced #endif");
3888   else {
3889     IF_STACK_FRAME *temp = if_stack;
3890     if_stack = if_stack->next;
3891     free (temp);
3892     output_line_command (&instack[indepth], op, 1, same_file);
3893   }
3894 }
3895
3896 /*
3897  * Skip a comment, assuming the input ptr immediately follows the
3898  * initial slash-star.  Bump line counter as necessary.
3899  * (The canonical line counter is &ip->lineno).
3900  * Don't use this routine (or the next one) if bumping the line
3901  * counter is not sufficient to deal with newlines in the string.
3902  */
3903 static U_CHAR *
3904 skip_to_end_of_comment (ip, line_counter)
3905      FILE_BUF *ip;
3906      int *line_counter;         /* place to remember newlines, or NULL */
3907 {
3908   U_CHAR *limit = ip->buf + ip->length;
3909   U_CHAR *bp = ip->bufp;
3910   FILE_BUF *op = &outbuf;       /* JF */
3911   int output = put_out_comments && !line_counter;
3912
3913         /* JF this line_counter stuff is a crock to make sure the
3914            comment is only put out once, no matter how many times
3915            the comment is skipped.  It almost works */
3916   if (output) {
3917     *op->bufp++ = '/';
3918     *op->bufp++ = '*';
3919   }
3920   while (bp < limit) {
3921     if (output)
3922       *op->bufp++ = *bp;
3923     switch (*bp++) {
3924     case '/':
3925       if (warn_comments && bp < limit && *bp == '*')
3926         warning("`/*' within comment");
3927       break;
3928     case '\n':
3929       if (line_counter != NULL)
3930         ++*line_counter;
3931       if (output)
3932         ++op->lineno;
3933       break;
3934     case '*':
3935       if (*bp == '\\' && bp[1] == '\n')
3936         newline_fix (bp);
3937       if (*bp == '/') {
3938         if (output)
3939           *op->bufp++ = '/';
3940         ip->bufp = ++bp;
3941         return bp;
3942       }
3943       break;
3944     }
3945   }
3946   ip->bufp = bp;
3947   return bp;
3948 }
3949
3950 /*
3951  * Skip over a quoted string.  BP points to the opening quote.
3952  * Returns a pointer after the closing quote.  Don't go past LIMIT.
3953  * START_LINE is the line number of the starting point (but it need
3954  * not be valid if the starting point is inside a macro expansion).
3955  *
3956  * The input stack state is not changed.
3957  *
3958  * If COUNT_NEWLINES is nonzero, it points to an int to increment
3959  * for each newline passed.
3960  *
3961  * If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
3962  * if we pass a backslash-newline.
3963  *
3964  * If EOFP is nonzero, set *EOFP to 1 if the string is unterminated.
3965  */
3966 static U_CHAR *
3967 skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
3968      const U_CHAR *bp;
3969      const U_CHAR *limit;
3970      int start_line;
3971      int *count_newlines;
3972      int *backslash_newlines_p;
3973      int *eofp;
3974 {
3975   U_CHAR c, match;
3976
3977   match = *bp++;
3978   while (1) {
3979     if (bp >= limit) {
3980       error_with_line (line_for_error (start_line),
3981                        "unterminated string or character constant");
3982       if (eofp)
3983         *eofp = 1;
3984       break;
3985     }
3986     c = *bp++;
3987     if (c == '\\') {
3988       while (*bp == '\\' && bp[1] == '\n') {
3989         if (backslash_newlines_p)
3990           *backslash_newlines_p = 1;
3991         if (count_newlines)
3992           ++*count_newlines;
3993         bp += 2;
3994       }
3995       if (*bp == '\n' && count_newlines) {
3996         if (backslash_newlines_p)
3997           *backslash_newlines_p = 1;
3998         ++*count_newlines;
3999       }
4000       bp++;
4001     } else if (c == '\n') {
4002       /* Unterminated strings and character constants are 'legal'.  */
4003       bp--;     /* Don't consume the newline. */
4004       if (eofp)
4005         *eofp = 1;
4006       break;
4007     } else if (c == match)
4008       break;
4009   }
4010   return (U_CHAR *) bp;
4011 }
4012 \f
4013 /*
4014  * write out a #line command, for instance, after an #include file.
4015  * If CONDITIONAL is nonzero, we can omit the #line if it would
4016  * appear to be a no-op, and we can output a few newlines instead
4017  * if we want to increase the line number by a small amount.
4018  * FILE_CHANGE says whether we are entering a file, leaving, or neither.
4019  */
4020
4021 static void
4022 output_line_command (ip, op, conditional, file_change)
4023      FILE_BUF *ip, *op;
4024      int conditional;
4025      enum file_change_code file_change;
4026 {
4027   int len;
4028   char line_cmd_buf[500];
4029
4030   if (no_line_commands
4031       || ip->fname == NULL
4032       || no_output) {
4033     op->lineno = ip->lineno;
4034     return;
4035   }
4036
4037   if (conditional) {
4038     if (ip->lineno == op->lineno)
4039       return;
4040
4041     /* If the inherited line number is a little too small,
4042        output some newlines instead of a #line command.  */
4043     if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) {
4044       check_expand (op, 10);
4045       while (ip->lineno > op->lineno) {
4046         *op->bufp++ = '\n';
4047         op->lineno++;
4048       }
4049       return;
4050     }
4051   }
4052
4053   sprintf (line_cmd_buf, "# %d \"%s\"", ip->lineno, ip->fname);
4054   if (file_change != same_file)
4055     strcat (line_cmd_buf, file_change == enter_file ? " 1" : " 2");
4056   if (system_include_depth > 0)
4057     strcat (line_cmd_buf, " 3");
4058   len = strlen (line_cmd_buf);
4059   line_cmd_buf[len++] = '\n';
4060   check_expand (op, len + 1);
4061   if (op->bufp > op->buf && op->bufp[-1] != '\n')
4062     *op->bufp++ = '\n';
4063   memcpy (op->bufp, line_cmd_buf, len);
4064   op->bufp += len;
4065   op->lineno = ip->lineno;
4066 }
4067 \f
4068
4069 /* Expand a macro call.
4070    HP points to the symbol that is the macro being called.
4071    Put the result of expansion onto the input stack
4072    so that subsequent input by our caller will use it.
4073
4074    If macro wants arguments, caller has already verified that
4075    an argument list follows; arguments come from the input stack.  */
4076
4077 static void
4078 macroexpand (hp, op)
4079      HASHNODE *hp;
4080      FILE_BUF *op;
4081 {
4082   int nargs;
4083   DEFINITION *defn = hp->value.defn;
4084   U_CHAR *xbuf;
4085   int xbuf_len;
4086   int start_line = instack[indepth].lineno;
4087
4088   CHECK_DEPTH (return;);
4089
4090   /* it might not actually be a macro.  */
4091   if (hp->type != T_MACRO) {
4092     special_symbol (hp, op);
4093     return;
4094   }
4095
4096   nargs = defn->nargs;
4097
4098   if (nargs >= 0) {
4099     int i;
4100     struct argdata *args;
4101     const char *parse_error = 0;
4102
4103     args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
4104
4105     for (i = 0; i < nargs; i++) {
4106       args[i].raw = args[i].expanded = (U_CHAR *) "";
4107       args[i].raw_length = args[i].expand_length
4108         = args[i].stringified_length = 0;
4109       args[i].free1 = args[i].free2 = 0;
4110     }
4111
4112     /* Parse all the macro args that are supplied.  I counts them.
4113        The first NARGS args are stored in ARGS.
4114        The rest are discarded.  */
4115     i = 0;
4116     do {
4117       /* Discard the open-parenthesis or comma before the next arg.  */
4118       ++instack[indepth].bufp;
4119       parse_error
4120         = macarg ((i < nargs || (nargs == 0 && i == 0)) ? &args[i] : 0);
4121       if (parse_error)
4122         {
4123           error_with_line (line_for_error (start_line), "%s", parse_error);
4124           break;
4125         }
4126       i++;
4127     } while (*instack[indepth].bufp != ')');
4128
4129     /* If we got one arg but it was just whitespace, call that 0 args.  */
4130     if (i == 1) {
4131       const U_CHAR *bp = args[0].raw;
4132       const U_CHAR *lim = bp + args[0].raw_length;
4133       while (bp != lim && is_space (*bp)) bp++;
4134       if (bp == lim)
4135         i = 0;
4136     }
4137
4138     if (nargs == 0 && i > 0)
4139       error ("arguments given to macro `%s'", hp->name);
4140     else if (i < nargs) {
4141       /* traditional C allows foo() if foo wants one argument.  */
4142       if (nargs == 1 && i == 0)
4143         ;
4144       else if (i == 0)
4145         error ("no args to macro `%s'", hp->name);
4146       else if (i == 1)
4147         error ("only 1 arg to macro `%s'", hp->name);
4148       else
4149         error ("only %d args to macro `%s'", i, hp->name);
4150     } else if (i > nargs)
4151       error ("too many (%d) args to macro `%s'", i, hp->name);
4152
4153     /* Swallow the closeparen.  */
4154     ++instack[indepth].bufp;
4155
4156     /* If macro wants zero args, we parsed the arglist for checking only.
4157        Read directly from the macro definition.  */
4158     if (nargs == 0) {
4159       xbuf = defn->expansion;
4160       xbuf_len = defn->length;
4161     } else {
4162       U_CHAR *exp = defn->expansion;
4163       int offset;       /* offset in expansion,
4164                                    copied a piece at a time */
4165       int totlen;       /* total amount of exp buffer filled so far */
4166
4167       struct reflist *ap;
4168
4169       /* Macro really takes args.  Compute the expansion of this call.  */
4170
4171       /* Compute length in characters of the macro's expansion.  */
4172       xbuf_len = defn->length;
4173       for (ap = defn->pattern; ap != NULL; ap = ap->next) {
4174         if (ap->stringify)
4175           xbuf_len += args[ap->argno].stringified_length;
4176         else 
4177           xbuf_len += args[ap->argno].raw_length;
4178       }
4179
4180       xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
4181
4182       /* Generate in XBUF the complete expansion
4183          with arguments substituted in.
4184          TOTLEN is the total size generated so far.
4185          OFFSET is the index in the definition
4186          of where we are copying from.  */
4187       offset = totlen = 0;
4188       for (ap = defn->pattern; ap != NULL; ap = ap->next) {
4189         struct argdata *arg = &args[ap->argno];
4190
4191         for (i = 0; i < ap->nchars; i++)
4192           xbuf[totlen++] = exp[offset++];
4193
4194         if (ap->stringify != 0) {
4195           int arglen = arg->raw_length;
4196           int escaped = 0;
4197           int in_string = 0;
4198           int c;
4199           i = 0;
4200           while (i < arglen
4201                  && (c = arg->raw[i], is_space (c)))
4202             i++;
4203           while (i < arglen
4204                  && (c = arg->raw[arglen - 1], is_space (c)))
4205             arglen--;
4206           for (; i < arglen; i++) {
4207             c = arg->raw[i];
4208
4209             /* Special markers Newline Space
4210                generate nothing for a stringified argument.  */
4211             if (c == '\n' && arg->raw[i+1] != '\n') {
4212               i++;
4213               continue;
4214             }
4215
4216             /* Internal sequences of whitespace are replaced by one space
4217                except within an string or char token.  */
4218             if (! in_string
4219                 && (c == '\n' ? arg->raw[i+1] == '\n' : is_space (c))) {
4220               while (1) {
4221                 /* Note that Newline Space does occur within whitespace
4222                    sequences; consider it part of the sequence.  */
4223                 if (c == '\n' && is_space (arg->raw[i+1]))
4224                   i += 2;
4225                 else if (c != '\n' && is_space (c))
4226                   i++;
4227                 else break;
4228                 c = arg->raw[i];
4229               }
4230               i--;
4231               c = ' ';
4232             }
4233
4234             if (escaped)
4235               escaped = 0;
4236             else {
4237               if (c == '\\')
4238                 escaped = 1;
4239               if (in_string) {
4240                 if (c == in_string)
4241                   in_string = 0;
4242               } else if (c == '\"' || c == '\'')
4243                 in_string = c;
4244             }
4245
4246             /* Escape these chars */
4247             if (c == '\"' || (in_string && c == '\\'))
4248               xbuf[totlen++] = '\\';
4249             if (ISPRINT (c))
4250               xbuf[totlen++] = c;
4251             else {
4252               sprintf ((char *) &xbuf[totlen], "\\%03o", (unsigned int) c);
4253               totlen += 4;
4254             }
4255           }
4256         } else {
4257           const U_CHAR *p1 = arg->raw;
4258           const U_CHAR *l1 = p1 + arg->raw_length;
4259
4260           if (ap->raw_before) {
4261             while (p1 != l1 && is_space (*p1)) p1++;
4262             while (p1 != l1 && is_idchar (*p1))
4263               xbuf[totlen++] = *p1++;
4264             /* Delete any no-reexpansion marker that follows
4265                an identifier at the beginning of the argument
4266                if the argument is concatenated with what precedes it.  */
4267             if (p1[0] == '\n' && p1[1] == '-')
4268               p1 += 2;
4269           }
4270           if (ap->raw_after) {
4271             /* Arg is concatenated after: delete trailing whitespace,
4272                whitespace markers, and no-reexpansion markers.  */
4273             while (p1 != l1) {
4274               if (is_space (l1[-1])) l1--;
4275               else if (l1[-1] == '-') {
4276                 const U_CHAR *p2 = l1 - 1;
4277                 /* If a `-' is preceded by an odd number of newlines then it
4278                    and the last newline are a no-reexpansion marker.  */
4279                 while (p2 != p1 && p2[-1] == '\n') p2--;
4280                 if ((l1 - 1 - p2) & 1) {
4281                   l1 -= 2;
4282                 }
4283                 else break;
4284               }
4285               else break;
4286             }
4287           }
4288           memmove (xbuf + totlen, p1, l1 - p1);
4289           totlen += l1 - p1;
4290         }
4291
4292         if (totlen > xbuf_len)
4293           abort ();
4294       }
4295
4296       /* if there is anything left of the definition
4297          after handling the arg list, copy that in too. */
4298
4299       for (i = offset; i < defn->length; i++)
4300         xbuf[totlen++] = exp[i];
4301
4302       xbuf[totlen] = 0;
4303       xbuf_len = totlen;
4304
4305       for (i = 0; i < nargs; i++) {
4306         if (args[i].free1 != 0)
4307           free (args[i].free1);
4308         if (args[i].free2 != 0)
4309           free (args[i].free2);
4310       }
4311     }
4312   } else {
4313     xbuf = defn->expansion;
4314     xbuf_len = defn->length;
4315   }
4316
4317   /* Now put the expansion on the input stack
4318      so our caller will commence reading from it.  */
4319   {
4320     FILE_BUF *ip2;
4321
4322     ip2 = &instack[++indepth];
4323
4324     ip2->fname = 0;
4325     ip2->lineno = 0;
4326     ip2->buf = xbuf;
4327     ip2->length = xbuf_len;
4328     ip2->bufp = xbuf;
4329     ip2->free_ptr = (nargs > 0) ? xbuf : 0;
4330     ip2->macro = hp;
4331     ip2->if_stack = if_stack;
4332   }
4333 }
4334 \f
4335 /*
4336  * Parse a macro argument and store the info on it into *ARGPTR.
4337  * Return nonzero to indicate a syntax error.
4338  */
4339
4340 static const char *
4341 macarg (argptr)
4342      struct argdata *argptr;
4343 {
4344   FILE_BUF *ip = &instack[indepth];
4345   int paren = 0;
4346   int newlines = 0;
4347   int comments = 0;
4348
4349   /* Try to parse as much of the argument as exists at this
4350      input stack level.  */
4351   U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length,
4352                         &paren, &newlines, &comments);
4353
4354   /* If we find the end of the argument at this level,
4355      set up *ARGPTR to point at it in the input stack.  */
4356   if (!(ip->fname != 0 && (newlines != 0 || comments != 0))
4357       && bp != ip->buf + ip->length) {
4358     if (argptr != 0) {
4359       argptr->raw = ip->bufp;
4360       argptr->raw_length = bp - ip->bufp;
4361     }
4362     ip->bufp = bp;
4363   } else {
4364     /* This input stack level ends before the macro argument does.
4365        We must pop levels and keep parsing.
4366        Therefore, we must allocate a temporary buffer and copy
4367        the macro argument into it.  */
4368     int bufsize = bp - ip->bufp;
4369     int extra = newlines;
4370     U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1);
4371     int final_start = 0;
4372
4373     memcpy (buffer, ip->bufp, bufsize);
4374     ip->bufp = bp;
4375     ip->lineno += newlines;
4376
4377     while (bp == ip->buf + ip->length) {
4378       if (instack[indepth].macro == 0) {
4379         free (buffer);
4380         return "unterminated macro call";
4381       }
4382       ip->macro->type = T_MACRO;
4383       if (ip->free_ptr)
4384         free (ip->free_ptr);
4385       ip = &instack[--indepth];
4386       newlines = 0;
4387       comments = 0;
4388       bp = macarg1 (ip->bufp, ip->buf + ip->length, &paren,
4389                     &newlines, &comments);
4390       final_start = bufsize;
4391       bufsize += bp - ip->bufp;
4392       extra += newlines;
4393       buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1);
4394       memcpy (buffer + bufsize - (bp - ip->bufp), ip->bufp, bp - ip->bufp);
4395       ip->bufp = bp;
4396       ip->lineno += newlines;
4397     }
4398
4399     /* Now, if arg is actually wanted, record its raw form,
4400        discarding comments and duplicating newlines in whatever
4401        part of it did not come from a macro expansion.
4402        EXTRA space has been preallocated for duplicating the newlines.
4403        FINAL_START is the index of the start of that part.  */
4404     if (argptr != 0) {
4405       argptr->raw = buffer;
4406       argptr->raw_length = bufsize;
4407       argptr->free1 = buffer;
4408       argptr->newlines = newlines;
4409       argptr->comments = comments;
4410       if ((newlines || comments) && ip->fname != 0)
4411         argptr->raw_length
4412           = final_start +
4413             discard_comments (argptr->raw + final_start,
4414                               argptr->raw_length - final_start,
4415                               newlines);
4416       argptr->raw[argptr->raw_length] = 0;
4417       if (argptr->raw_length > bufsize + extra)
4418         abort ();
4419     }
4420   }
4421
4422   /* If we are not discarding this argument,
4423      macroexpand it and compute its length as stringified.
4424      All this info goes into *ARGPTR.  */
4425
4426   if (argptr != 0) {
4427     FILE_BUF obuf;
4428     const U_CHAR *buf, *lim;
4429     int totlen;
4430
4431     obuf = expand_to_temp_buffer (argptr->raw,
4432                                   argptr->raw + argptr->raw_length,
4433                                   1);
4434
4435     argptr->expanded = obuf.buf;
4436     argptr->expand_length = obuf.length;
4437     argptr->free2 = obuf.buf;
4438
4439     buf = argptr->raw;
4440     lim = buf + argptr->raw_length;
4441
4442     totlen = 0;
4443     while (buf != lim) {
4444       U_CHAR c = *buf++;
4445       totlen++;
4446       /* Internal sequences of whitespace are replaced by one space
4447          in most cases, but not always.  So count all the whitespace
4448          in case we need to keep it all.  */
4449       if (c == '\"' || c == '\\') /* escape these chars */
4450         totlen++;
4451       else if (!ISPRINT (c))
4452         totlen += 3;
4453     }
4454     argptr->stringified_length = totlen;
4455   }
4456   return 0;
4457 }
4458
4459 /* Scan text from START (inclusive) up to LIMIT (exclusive),
4460    counting parens in *DEPTHPTR,
4461    and return if reach LIMIT
4462    or before a `)' that would make *DEPTHPTR negative
4463    or before a comma when *DEPTHPTR is zero.
4464    Single and double quotes are matched and termination
4465    is inhibited within them.  Comments also inhibit it.
4466    Value returned is pointer to stopping place.
4467
4468    Increment *NEWLINES each time a newline is passed.
4469    Set *COMMENTS to 1 if a comment is seen.  */
4470
4471 static U_CHAR *
4472 macarg1 (start, limit, depthptr, newlines, comments)
4473      U_CHAR *start;
4474      const U_CHAR *limit;
4475      int *depthptr, *newlines, *comments;
4476 {
4477   U_CHAR *bp = start;
4478
4479   while (bp < limit) {
4480     switch (*bp) {
4481     case '(':
4482       (*depthptr)++;
4483       break;
4484     case ')':
4485       if (--(*depthptr) < 0)
4486         return bp;
4487       break;
4488     case '\\':
4489       /* Traditionally, backslash makes following char not special.  */
4490       if (bp + 1 < limit)
4491         {
4492           bp++;
4493           /* But count source lines anyway.  */
4494           if (*bp == '\n')
4495             ++*newlines;
4496         }
4497       break;
4498     case '\n':
4499       ++*newlines;
4500       break;
4501     case '/':
4502       if (bp[1] == '\\' && bp[2] == '\n')
4503         newline_fix (bp + 1);
4504       if (bp[1] != '*' || bp + 1 >= limit)
4505         break;
4506       *comments = 1;
4507       bp += 2;
4508       while (bp + 1 < limit) {
4509         if (bp[0] == '*'
4510             && bp[1] == '\\' && bp[2] == '\n')
4511           newline_fix (bp + 1);
4512         if (bp[0] == '*' && bp[1] == '/')
4513           break;
4514         if (*bp == '\n') ++*newlines;
4515         bp++;
4516       }
4517       bp += 1;
4518       break;
4519     case '\'':
4520     case '\"':
4521       {
4522         int quotec;
4523         for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) {
4524           if (*bp == '\\') {
4525             bp++;
4526             if (*bp == '\n')
4527               ++*newlines;
4528             while (*bp == '\\' && bp[1] == '\n') {
4529               bp += 2;
4530             }
4531           } else if (*bp == '\n') {
4532             ++*newlines;
4533             if (quotec == '\'')
4534               break;
4535           }
4536         }
4537       }
4538       break;
4539     case ',':
4540       if ((*depthptr) == 0)
4541         return bp;
4542       break;
4543     }
4544     bp++;
4545   }
4546
4547   return bp;
4548 }
4549
4550 /* Discard comments and duplicate newlines
4551    in the string of length LENGTH at START,
4552    except inside of string constants.
4553    The string is copied into itself with its beginning staying fixed.  
4554
4555    NEWLINES is the number of newlines that must be duplicated.
4556    We assume that that much extra space is available past the end
4557    of the string.  */
4558
4559 static int
4560 discard_comments (start, length, newlines)
4561      U_CHAR *start;
4562      int length;
4563      int newlines;
4564 {
4565   U_CHAR *ibp;
4566   U_CHAR *obp;
4567   const U_CHAR *limit;
4568   int c;
4569
4570   /* If we have newlines to duplicate, copy everything
4571      that many characters up.  Then, in the second part,
4572      we will have room to insert the newlines
4573      while copying down.
4574      NEWLINES may actually be too large, because it counts
4575      newlines in string constants, and we don't duplicate those.
4576      But that does no harm.  */
4577   if (newlines > 0) {
4578     ibp = start + length;
4579     obp = ibp + newlines;
4580     limit = start;
4581     while (limit != ibp)
4582       *--obp = *--ibp;
4583   }
4584
4585   ibp = start + newlines;
4586   limit = start + length + newlines;
4587   obp = start;
4588
4589   while (ibp < limit) {
4590     *obp++ = c = *ibp++;
4591     switch (c) {
4592     case '\n':
4593       /* Duplicate the newline.  */
4594       *obp++ = '\n';
4595       break;
4596
4597     case '\\':
4598       if (*ibp == '\n') {
4599         obp--;
4600         ibp++;
4601       }
4602       break;
4603
4604     case '/':
4605       if (*ibp == '\\' && ibp[1] == '\n')
4606         newline_fix (ibp);
4607       /* Delete any comment.  */
4608       if (ibp[0] != '*' || ibp + 1 >= limit)
4609         break;
4610       obp--;
4611       ibp++;
4612       while (ibp + 1 < limit) {
4613         if (ibp[0] == '*'
4614             && ibp[1] == '\\' && ibp[2] == '\n')
4615           newline_fix (ibp + 1);
4616         if (ibp[0] == '*' && ibp[1] == '/')
4617           break;
4618         ibp++;
4619       }
4620       ibp += 2;
4621       break;
4622
4623     case '\'':
4624     case '\"':
4625       /* Notice and skip strings, so that we don't
4626          think that comments start inside them,
4627          and so we don't duplicate newlines in them.  */
4628       {
4629         int quotec = c;
4630         while (ibp < limit) {
4631           *obp++ = c = *ibp++;
4632           if (c == quotec)
4633             break;
4634           if (c == '\n' && quotec == '\'')
4635             break;
4636           if (c == '\\' && ibp < limit) {
4637             while (*ibp == '\\' && ibp[1] == '\n')
4638               ibp += 2;
4639             *obp++ = *ibp++;
4640           }
4641         }
4642       }
4643       break;
4644     }
4645   }
4646
4647   return obp - start;
4648 }
4649 \f
4650
4651 /* Core error handling routine.  */
4652 static void
4653 v_message (mtype, line, msgid, ap)
4654      enum msgtype mtype;
4655      int line;
4656      const char *msgid;
4657      va_list ap;
4658 {
4659   const char *fname = 0;
4660   int i;
4661
4662   if (mtype == MT_WARNING && inhibit_warnings)
4663     return;
4664
4665   for (i = indepth; i >= 0; i--)
4666     if (instack[i].fname != NULL) {
4667       if (line == 0)
4668         line = instack[i].lineno;
4669       fname = instack[i].fname;
4670       break;
4671     }
4672
4673   if (fname)
4674     fprintf (stderr, "%s:%d: ", fname, line);
4675   else
4676     fprintf (stderr, "%s: ", progname);
4677
4678   if (mtype == MT_WARNING)
4679     fputs (_("warning: "), stderr);
4680
4681   vfprintf (stderr, _(msgid), ap);
4682   putc ('\n', stderr);
4683
4684   if (mtype == MT_ERROR)
4685     errors++;
4686 }
4687
4688 /*
4689  * error - print error message and increment count of errors.
4690  */
4691 void
4692 error VPARAMS ((const char *msgid, ...))
4693 {
4694   VA_OPEN(ap, msgid);
4695   VA_FIXEDARG (ap, const char *, msgid);
4696
4697   v_message (MT_ERROR, 0, msgid, ap);
4698   VA_CLOSE (ap);
4699 }
4700
4701 void
4702 error_with_line VPARAMS ((int line, const char *msgid, ...))
4703 {
4704   VA_OPEN(ap, msgid);
4705   VA_FIXEDARG (ap, int, line);
4706   VA_FIXEDARG (ap, const char *, msgid);
4707
4708   v_message (MT_ERROR, line, msgid, ap);
4709   VA_CLOSE (ap);
4710 }
4711
4712 /* Error including a message from `errno'.  */
4713 void
4714 error_from_errno (name)
4715      const char *name;
4716 {
4717   error ("%s: %s", name, strerror (errno));
4718 }
4719
4720 /* Print error message but don't count it.  */
4721 void
4722 warning VPARAMS ((const char *msgid, ...))
4723 {
4724   VA_OPEN(ap, msgid);
4725   VA_FIXEDARG (ap, const char *, msgid);
4726
4727   v_message (MT_WARNING, 0, msgid, ap);
4728   VA_CLOSE (ap);
4729 }
4730
4731 void
4732 fatal VPARAMS ((const char *msgid, ...))
4733 {
4734   VA_OPEN(ap, msgid);
4735   VA_FIXEDARG (ap, const char *, msgid);
4736
4737   v_message (MT_FATAL, 0, msgid, ap);
4738   VA_CLOSE (ap);
4739   exit (FATAL_EXIT_CODE);
4740 }
4741
4742 /* More 'friendly' abort that prints the location at which we died.  */
4743 void
4744 fancy_abort (line, func)
4745      int line;
4746      const char *func;
4747 {
4748   fatal ("internal error in %s, at tradcpp.c:%d\n\
4749 Please submit a full bug report.\n\
4750 See %s for instructions.", func, line, GCCBUGURL);
4751 }
4752
4753 void
4754 perror_with_name (name)
4755      const char *name;
4756 {
4757   fprintf (stderr, "%s: %s: %s\n", progname, name, strerror (errno));
4758   errors++;
4759 }
4760
4761 void
4762 pfatal_with_name (name)
4763      const char *name;
4764 {
4765   perror_with_name (name);
4766   exit (FATAL_EXIT_CODE);
4767 }
4768
4769 /* Return the line at which an error occurred.
4770    The error is not necessarily associated with the current spot
4771    in the input stack, so LINE says where.  LINE will have been
4772    copied from ip->lineno for the current input level.
4773    If the current level is for a file, we return LINE.
4774    But if the current level is not for a file, LINE is meaningless.
4775    In that case, we return the lineno of the innermost file.  */
4776 static int
4777 line_for_error (line)
4778      int line;
4779 {
4780   int i;
4781   int line1 = line;
4782
4783   for (i = indepth; i >= 0; ) {
4784     if (instack[i].fname != 0)
4785       return line1;
4786     i--;
4787     if (i < 0)
4788       return 0;
4789     line1 = instack[i].lineno;
4790   }
4791   return 0;
4792 }
4793
4794 /*
4795  * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger.
4796  *
4797  * As things stand, nothing is ever placed in the output buffer to be
4798  * removed again except when it's KNOWN to be part of an identifier,
4799  * so flushing and moving down everything left, instead of expanding,
4800  * should work ok.
4801  */
4802
4803 static void
4804 grow_outbuf (obuf, needed)
4805      FILE_BUF *obuf;
4806      int needed;
4807 {
4808   U_CHAR *p;
4809   int minsize;
4810
4811   if (obuf->length - (obuf->bufp - obuf->buf) > needed)
4812     return;
4813
4814   /* Make it at least twice as big as it is now.  */
4815   obuf->length *= 2;
4816   /* Make it have at least 150% of the free space we will need.  */
4817   minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf);
4818   if (minsize > obuf->length)
4819     obuf->length = minsize;
4820
4821   p = (U_CHAR *) xrealloc (obuf->buf, obuf->length);
4822   obuf->bufp = p + (obuf->bufp - obuf->buf);
4823   obuf->buf = p;
4824 }
4825 \f
4826 /* Symbol table for macro names and special symbols */
4827
4828 /*
4829  * install a name in the main hash table, even if it is already there.
4830  *   name stops with first non alphanumeric, except leading '#'.
4831  * caller must check against redefinition if that is desired.
4832  * delete_macro () removes things installed by install () in fifo order.
4833  * this is important because of the `defined' special symbol used
4834  * in #if, and also if pushdef/popdef directives are ever implemented.
4835  *
4836  * If LEN is >= 0, it is the length of the name.
4837  * Otherwise, compute the length by scanning the entire name.
4838  *
4839  * If HASH is >= 0, it is the precomputed hash code.
4840  * Otherwise, compute the hash code.
4841  *
4842  * caller must set the value, if any is desired.
4843  */
4844 static HASHNODE *
4845 install (name, len, type, hash)
4846      const U_CHAR *name;
4847      int len;
4848      enum node_type type;
4849      int hash;
4850         /* watch out here if sizeof (U_CHAR *) != sizeof (int) */
4851 {
4852   HASHNODE *hp;
4853   int bucket;
4854   const U_CHAR *p;
4855   U_CHAR *q;
4856
4857   if (len < 0) {
4858     p = name;
4859     while (is_idchar (*p))
4860       p++;
4861     len = p - name;
4862   }
4863
4864   if (hash < 0)
4865     hash = hashf (name, len, HASHSIZE);
4866
4867   hp = (HASHNODE *) xmalloc (sizeof (HASHNODE) + len + 1);
4868   bucket = hash;
4869   hp->bucket_hdr = &hashtab[bucket];
4870   hp->next = hashtab[bucket];
4871   hashtab[bucket] = hp;
4872   hp->prev = NULL;
4873   if (hp->next != NULL)
4874     hp->next->prev = hp;
4875   hp->type = type;
4876   hp->length = len;
4877   hp->name = q = ((U_CHAR *) hp) + sizeof (HASHNODE);
4878   memcpy (q, name, len);
4879   q[len] = 0;
4880   return hp;
4881 }
4882
4883 /*
4884  * find the most recent hash node for name name (ending with first
4885  * non-identifier char) installed by install
4886  *
4887  * If LEN is >= 0, it is the length of the name.
4888  * Otherwise, compute the length by scanning the entire name.
4889  *
4890  * If HASH is >= 0, it is the precomputed hash code.
4891  * Otherwise, compute the hash code.
4892  */
4893 HASHNODE *
4894 lookup (name, len, hash)
4895      const U_CHAR *name;
4896      int len;
4897      int hash;
4898 {
4899   const U_CHAR *bp;
4900   HASHNODE *bucket;
4901
4902   if (len < 0) {
4903     for (bp = name; is_idchar (*bp); bp++) ;
4904     len = bp - name;
4905   }
4906
4907   if (hash < 0)
4908     hash = hashf (name, len, HASHSIZE);
4909
4910   bucket = hashtab[hash];
4911   while (bucket) {
4912     if (bucket->length == len
4913         && strncmp ((const char *)bucket->name, (const char *)name, len) == 0)
4914       return bucket;
4915     bucket = bucket->next;
4916   }
4917   return NULL;
4918 }
4919
4920 /*
4921  * Delete a hash node.  Some weirdness to free junk from macros.
4922  * More such weirdness will have to be added if you define more hash
4923  * types that need it.
4924  */
4925
4926 /* Note that the DEFINITION of a macro is removed from the hash table
4927    but its storage is not freed.  This would be a storage leak
4928    except that it is not reasonable to keep undefining and redefining
4929    large numbers of macros many times.
4930    In any case, this is necessary, because a macro can be #undef'd
4931    in the middle of reading the arguments to a call to it.
4932    If #undef freed the DEFINITION, that would crash.  */
4933 static void
4934 delete_macro (hp)
4935      HASHNODE *hp;
4936 {
4937
4938   if (hp->prev != NULL)
4939     hp->prev->next = hp->next;
4940   if (hp->next != NULL)
4941     hp->next->prev = hp->prev;
4942
4943   /* make sure that the bucket chain header that
4944      the deleted guy was on points to the right thing afterwards. */
4945   if (hp == *hp->bucket_hdr)
4946     *hp->bucket_hdr = hp->next;
4947
4948   free (hp);
4949 }
4950
4951 /*
4952  * return hash function on name.  must be compatible with the one
4953  * computed a step at a time, elsewhere
4954  */
4955 static int
4956 hashf (name, len, hashsize)
4957      const U_CHAR *name;
4958      int len;
4959      int hashsize;
4960 {
4961   int r = 0;
4962
4963   while (len--)
4964     r = HASHSTEP (r, *name++);
4965
4966   return MAKE_POS (r) % hashsize;
4967 }
4968 \f
4969 /* Dump all macro definitions as #defines to stdout.  */
4970
4971 static void
4972 dump_all_macros ()
4973 {
4974   int bucket;
4975
4976   for (bucket = 0; bucket < HASHSIZE; bucket++) {
4977     HASHNODE *hp;
4978
4979     for (hp = hashtab[bucket]; hp; hp= hp->next) {
4980       if (hp->type == T_MACRO) {
4981         DEFINITION *defn = hp->value.defn;
4982         struct reflist *ap;
4983         int offset;
4984         int concat;
4985
4986
4987         /* Print the definition of the macro HP.  */
4988
4989         printf ("#define %s", hp->name);
4990         if (defn->nargs >= 0) {
4991           int i;
4992
4993           printf ("(");
4994           for (i = 0; i < defn->nargs; i++) {
4995             dump_arg_n (defn, i);
4996             if (i + 1 < defn->nargs)
4997               printf (", ");
4998           }
4999           printf (")");
5000         }
5001
5002         printf (" ");
5003
5004         offset = 0;
5005         concat = 0;
5006         for (ap = defn->pattern; ap != NULL; ap = ap->next) {
5007           dump_defn_1 (defn->expansion, offset, ap->nchars);
5008           if (ap->nchars != 0)
5009             concat = 0;
5010           offset += ap->nchars;
5011           if (ap->stringify)
5012             printf (" #");
5013           if (ap->raw_before && !concat)
5014             printf (" ## ");
5015           concat = 0;
5016           dump_arg_n (defn, ap->argno);
5017           if (ap->raw_after) {
5018             printf (" ## ");
5019             concat = 1;
5020           }
5021         }
5022         dump_defn_1 (defn->expansion, offset, defn->length - offset);
5023         printf ("\n");
5024       }
5025     }
5026   }
5027 }
5028
5029 /* Output to stdout a substring of a macro definition.
5030    BASE is the beginning of the definition.
5031    Output characters START thru LENGTH.
5032    Discard newlines outside of strings, thus
5033    converting funny-space markers to ordinary spaces.  */
5034 static void
5035 dump_defn_1 (base, start, length)
5036      const U_CHAR *base;
5037      int start;
5038      int length;
5039 {
5040   const U_CHAR *p = base + start;
5041   const U_CHAR *limit = base + start + length;
5042
5043   while (p < limit) {
5044     if (*p != '\n')
5045       putchar (*p);
5046     else if (*p == '\"' || *p =='\'') {
5047       const U_CHAR *p1 = skip_quoted_string (p, limit, 0, 0, 0, 0);
5048       fwrite (p, p1 - p, 1, stdout);
5049       p = p1 - 1;
5050     }
5051     p++;
5052   }
5053 }
5054
5055 /* Print the name of argument number ARGNUM of macro definition DEFN.
5056    Recall that DEFN->argnames contains all the arg names
5057    concatenated in reverse order with comma-space in between.  */
5058 static void
5059 dump_arg_n (defn, argnum)
5060      DEFINITION *defn;
5061      int argnum;
5062 {
5063   const U_CHAR *p = defn->argnames;
5064   while (argnum + 1 < defn->nargs) {
5065     p = (const U_CHAR *) strchr ((const char *)p, ' ') + 1;
5066     argnum++;
5067   }
5068
5069   while (*p && *p != ',') {
5070     putchar (*p);
5071     p++;
5072   }
5073 }
5074
5075 /* Initialize the built-in macros.  */
5076 #define DSC(x) U x, sizeof x - 1
5077 #define install_spec(name, type) \
5078  install(DSC(name), type, -1);
5079 #define install_value(name, val) \
5080  hp = install(DSC(name), T_CONST, -1); hp->value.cpval = val;
5081 static void
5082 initialize_builtins ()
5083 {
5084   HASHNODE *hp;
5085
5086   install_spec ("__BASE_FILE__",     T_BASE_FILE);
5087   install_spec ("__DATE__",          T_DATE);
5088   install_spec ("__FILE__",          T_FILE);
5089   install_spec ("__TIME__",          T_TIME);
5090   install_spec ("__VERSION__",       T_VERSION);
5091   install_spec ("__INCLUDE_LEVEL__", T_INCLUDE_LEVEL);
5092   install_spec ("__LINE__",          T_SPECLINE);
5093
5094 #ifndef NO_BUILTIN_SIZE_TYPE
5095   install_value ("__SIZE_TYPE__",         SIZE_TYPE);
5096 #endif
5097 #ifndef NO_BUILTIN_PTRDIFF_TYPE
5098   install_value ("__PTRDIFF_TYPE__",      PTRDIFF_TYPE);
5099 #endif
5100 #ifndef NO_BUILTIN_WCHAR_TYPE
5101   install_value ("__WCHAR_TYPE__",        WCHAR_TYPE);
5102 #endif
5103 #ifndef NO_BUILTIN_WINT_TYPE
5104   install_value ("__WINT_TYPE__",         WINT_TYPE);
5105 #endif
5106   install_value ("__REGISTER_PREFIX__",   REGISTER_PREFIX);
5107   install_value ("__USER_LABEL_PREFIX__", user_label_prefix);
5108 }
5109 #undef DSC
5110 #undef install_spec
5111 #undef install_value
5112 \f
5113 /* Common handler of command line directives -U, -D and -A.  */
5114 static void
5115 run_directive (str, len, type)
5116      const char *str;
5117      size_t len;
5118      enum node_type type;
5119 {
5120   struct directive *kt;
5121   FILE_BUF *ip = &instack[++indepth];
5122   ip->fname = "*command line*";
5123
5124   ip->buf = ip->bufp = (U_CHAR *) str;
5125   ip->length = len;
5126   ip->lineno = 1;
5127   ip->macro = 0;
5128   ip->free_ptr = 0;
5129   ip->if_stack = if_stack;
5130
5131   for (kt = directive_table; kt->type != type; kt++)
5132     ;
5133
5134   (*kt->func) ((U_CHAR *) str, (U_CHAR *) str + len, NULL);
5135   --indepth;
5136 }
5137
5138 /* Handle the -D option.  If STR is just an identifier, define it with
5139  * value 1.  If STR has anything after the identifier, then it should
5140  * be identifier-space-definition.  */
5141 static void
5142 make_definition (str)
5143      const char *str;
5144 {
5145   char *buf, *p;
5146   size_t count;
5147
5148   /* Copy the entire option so we can modify it. 
5149      Change the first "=" in the string to a space.  If there is none,
5150      tack " 1" on the end.  */
5151
5152   /* Length including the null.  */  
5153   count = strlen (str);
5154   buf = (char *) alloca (count + 2);
5155   memcpy (buf, str, count);
5156
5157   p = strchr (str, '=');
5158   if (p)
5159     buf[p - str] = ' ';
5160   else
5161     {
5162       buf[count++] = ' ';
5163       buf[count++] = '1';
5164     }
5165
5166   run_directive (buf, count, T_DEFINE);
5167 }
5168
5169 /* Handle the -U option.  */
5170 static void
5171 make_undef (str)
5172      const char *str;
5173 {
5174   run_directive (str, strlen (str), T_UNDEF);
5175 }
5176
5177 /* Handles the #assert (-A) and #unassert (-A-) command line options.  */
5178 static void
5179 make_assertion (str)
5180      const char *str;
5181 {
5182   enum node_type type = T_ASSERT;
5183   size_t count;
5184   const char *p;
5185
5186   if (*str == '-')
5187     {
5188       str++;
5189       type = T_UNASSERT;
5190     }
5191   
5192   count = strlen (str);
5193   p = strchr (str, '=');
5194   if (p)
5195     {
5196       /* Copy the entire option so we can modify it.  Change the first
5197          "=" in the string to a '(', and tack a ')' on the end.  */
5198       char *buf = (char *) alloca (count + 1);
5199
5200       memcpy (buf, str, count);
5201       buf[p - str] = '(';
5202       buf[count++] = ')';
5203       str = buf;
5204     }
5205
5206   run_directive (str, count, type);
5207 }
5208 \f
5209 /* Get the file-mode and data size of the file open on FD
5210    and store them in *MODE_POINTER and *SIZE_POINTER.  */
5211
5212 static int
5213 file_size_and_mode (fd, mode_pointer, size_pointer)
5214      int fd;
5215      int *mode_pointer;
5216      long *size_pointer;
5217 {
5218   struct stat sbuf;
5219
5220   if (fstat (fd, &sbuf) < 0) return -1;
5221   if (mode_pointer) *mode_pointer = sbuf.st_mode;
5222   if (size_pointer) *size_pointer = sbuf.st_size;
5223   return 0;
5224 }