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