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