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