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