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