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