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