OSDN Git Service

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