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