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