00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 # include <ctype.h>
00058 # include <stdio.h>
00059 # include <signal.h>
00060 # ifdef __STDC__
00061 # include <stdlib.h>
00062 # endif
00063
00064 # include <string.h>
00065
00066 # if !(defined (WIN32) || defined (OS2) && defined (__IBMC__))
00067 # include <unistd.h>
00068 # endif
00069
00070 # include <sys/types.h>
00071 # include <sys/stat.h>
00072 # include <fcntl.h>
00073
00074 # if defined (WIN32) || defined (OS2) && defined (__IBMC__)
00075 # include <io.h>
00076 # include <sys/utime.h>
00077 # include <time.h>
00078 # else
00079 # ifndef VMS
00080 # ifndef USG
00081 # include <sys/time.h>
00082 # include <sys/resource.h>
00083 # else
00084 # include <sys/times.h>
00085 # include <time.h>
00086 # include <fcntl.h>
00087 # endif
00088 # endif
00089 # endif
00090
00091
00092 # include <errno.h>
00093
00094 # include "lclintMacros.nf"
00095 # include "llbasic.h"
00096 # include "lcllib.h"
00097 # include "cpp.h"
00098 # include "cpplib.h"
00099 # include "cpperror.h"
00100 # include "cpphash.h"
00101 # include "cppexp.h"
00102 # include "version.h"
00103 # include "portab.h"
00104 # include "osd.h"
00105
00106
00107
00108
00109
00110
00111
00112
00113 #define NO_SHORTNAMES
00114
00115 # ifdef open
00116 # undef open
00117 # undef read
00118 # undef write
00119 # endif
00120
00121
00122 # define IMPORT_FOUND -2
00123
00124
00125 # define SKIP_INCLUDE IMPORT_FOUND
00126
00127
00128 # define IMPORT_NOT_FOUND -1
00129
00130 #ifndef STDC_VALUE
00131
00132 #define STDC_VALUE 1
00133 #endif
00134
00135
00136 #ifndef PATH_SEPARATOR
00137
00138 #define PATH_SEPARATOR ':'
00139 #endif
00140
00141 static void parse_name (cppReader *, int);
00142
00143 static int cpp_openIncludeFile (char *p_filename)
00144 ;
00145
00146 static void cpp_setLocation (cppReader *p_pfile)
00147 ;
00148
00149 static enum cpp_token cpp_handleComment (cppReader *p_pfile,
00150 struct parse_marker *p_smark)
00151 ;
00152
00153 static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) ;
00154
00155 static bool cpp_skipIncludeFile (cstring p_fname) ;
00156
00157 #ifndef O_RDONLY
00158 #define O_RDONLY 0
00159 #endif
00160
00161
00162
00163 #ifdef CPP_PREDEFINES
00164 static char *predefs = CPP_PREDEFINES;
00165 #else
00166 static char *predefs = "";
00167 #endif
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 #ifndef SIZE_TYPE
00178
00179 #define SIZE_TYPE "long unsigned int"
00180 #endif
00181
00182
00183
00184 #ifndef PTRDIFF_TYPE
00185
00186 #define PTRDIFF_TYPE "long int"
00187 #endif
00188
00189
00190
00191 #ifndef WCHAR_TYPE
00192
00193 #define WCHAR_TYPE "int"
00194 #endif
00195
00196
00197
00198 #ifndef USER_LABEL_PREFIX
00199
00200 #define USER_LABEL_PREFIX ""
00201 #endif
00202
00203
00204
00205 #ifndef REGISTER_PREFIX
00206
00207 #define REGISTER_PREFIX ""
00208 #endif
00209
00210
00211 static bool is_idchar[256];
00212
00213 static bool is_idstart[256];
00214
00215 static bool is_hor_space[256];
00216
00217 static bool is_space[256];
00218
00219 static cppBuffer *
00220 cppReader_getBuffer ( cppReader *p_pfile)
00221
00222 ;
00223
00224
00225 # define SKIP_WHITE_SPACE(p) do { while (is_hor_space[(int) *(p)]) { (p)++; } } while (0)
00226
00227
00228 # define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*(p)]) { (p)++; } } while (0)
00229
00230 static int cpp_peekN (cppReader *p_pfile, int p_n) ;
00231
00232
00233 # define cppBuffer_get(BUFFER) \
00234 ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
00235
00236
00237
00238
00239 # define cppReader_puts(PFILE, STR, N) \
00240 cppReader_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)
00241
00242
00243
00244
00245
00246 # define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH))
00247
00248
00249
00250
00251
00252 #define cppReader_putChar(PFILE, CH) (cppReader_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))
00253
00254
00255
00256
00257
00258 #define cppReader_nullTerminateQ(PFILE) (*(PFILE)->limit = 0)
00259
00260
00261
00262 # define cppReader_nullTerminate(PFILE) \
00263 (cppReader_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0)
00264
00265
00266
00267 #define cppReader_adjustWritten(PFILE,DELTA) ((PFILE)->limit += (DELTA))
00268
00269
00270 #define cppReader_isC89(PFILE) (CPPOPTIONS(PFILE)->c89)
00271
00272
00273
00274
00275 # define cppReader_wcharType(PFILE) \
00276 (CPPOPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE)
00277
00278 static void cppBuffer_forward (cppBuffer *p_buf, int p_n) ;
00279
00280
00281 # define cppReader_forward(pfile, N) \
00282 (cppBuffer_forward (cppReader_getBufferSafe (pfile), (N)))
00283
00284
00285 # define cppReader_getC(pfile) (cppBuffer_get (cppReader_getBufferSafe (pfile)))
00286
00287
00288 # define cppReader_peekC(pfile) (cppBufPeek (cppReader_getBufferSafe (pfile)))
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 # define NEWLINE_FIX \
00299 do { while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n') { cppReader_forward (pfile, 2); } } while(FALSE)
00300
00301
00302
00303 # define NEWLINE_FIX1(C) do { \
00304 while ((C) == '\\' && cppReader_peekC (pfile) == '\n') { cppReader_forward (pfile, 1); (C) = cppReader_getC (pfile); }\
00305 } while(0)
00306
00307 static void parseSetMark ( struct parse_marker *,
00308 cppReader *);
00309 static void parseClearMark (struct parse_marker *);
00310 static void parseGotoMark (struct parse_marker *, cppReader *);
00311 static void parseMoveMark (struct parse_marker *, cppReader *);
00312
00313
00314 static char *cppLineBase ( cppBuffer *);
00315
00316 static cppBuffer *
00317 cppReader_pushBuffer (cppReader *p_pfile,
00318 char *, size_t)
00319 ;
00320
00321 static void cppReader_appendIncludeChain
00322 (cppReader *p_pfile,
00323 struct file_name_list *p_first,
00324 struct file_name_list *p_last);
00325
00326 static void cppReader_macroCleanup (cppBuffer *p_pbuf, cppReader *p_pfile);
00327 static enum cpp_token cppReader_nullUnderflow ( cppReader *p_pfile);
00328
00329 static void cppReader_nullCleanup ( cppBuffer *p_pbuf,
00330 cppReader *p_pfile);
00331
00332 static void cppReader_fileCleanup (cppBuffer *p_pbuf,
00333 cppReader *p_pfile);
00334
00335 static int cppReader_handleDirective (cppReader *p_pfile);
00336
00337 static void cppReader_scanBuffer (cppReader *p_pfile);
00338
00339 # if defined (WIN32) || defined (OS2) && defined (__IBMC__)
00340
00341
00342
00343
00344
00345
00346 typedef unsigned int mode_t;
00347
00348
00349 # endif
00350
00351 static int file_size_and_mode (int p_fd, mode_t *p_mode_pointer,
00352 size_t *p_size_pointer);
00353 static int safe_read (int p_desc, char *p_ptr, int p_len);
00354
00355
00356
00357
00358
00359
00360
00361 static bool cppBuffer_isMacro ( cppBuffer *) ;
00362
00363 static void path_include (cppReader *p_pfile, char *p_path)
00364 ;
00365
00366 static void initialize_builtins (cppReader *p_pfile)
00367 ;
00368
00369 static void initialize_char_syntax (struct cppOptions *p_opts) ;
00370
00371 static int finclude (cppReader *p_pfile, int p_f,
00372 cstring p_fname,
00373 bool p_system_header_p,
00374 struct file_name_list *p_dirptr);
00375
00376 static void validate_else (cppReader *p_pfile, cstring p_directive);
00377
00378 static void conditional_skip (cppReader *p_pfile, int p_skip,
00379 enum node_type p_type,
00380 char *p_control_macro);
00381
00382 static HOST_WIDE_INT eval_if_expression (cppReader *p_pfile,
00383 char *p_buf,
00384 int p_length);
00385
00386 static void skip_if_group (cppReader *p_pfile, int p_any);
00387
00388 static bool comp_def_part (bool p_first, char *p_beg1, int p_len1,
00389 char *p_beg2, int p_len2, bool p_last);
00390
00391 #ifdef abort
00392 extern void fancy_abort ();
00393 #endif
00394
00395 static bool redundant_include_p (cppReader *p_pfile, cstring p_name);
00396 static bool is_system_include (cppReader *p_pfile, cstring p_filename);
00397
00398 static struct file_name_map *
00399 read_name_map (cppReader *p_pfile, cstring p_dirname);
00400
00401 static cstring read_filename_string (int p_ch, FILE *p_f);
00402
00403 static int open_include_file (cppReader *p_pfile,
00404 cstring p_fname,
00405 struct file_name_list *p_searchptr);
00406
00407 static void push_macro_expansion (cppReader *,
00408 char *, size_t,
00409 HASHNODE *);
00410
00411
00412 enum file_change_code {
00413 same_file, enter_file, leave_file
00414 };
00415
00416
00417
00418 struct directive {
00419 int length;
00420 int (*func)();
00421 cstring name;
00422 enum node_type type;
00423 bool command_reads_line;
00424 bool traditional_comments;
00425 bool pass_thru;
00426 };
00427
00428
00429
00430
00431
00432 static int do_define (cppReader *, struct directive *,
00433 char *, char *);
00434 static int do_defineAux (cppReader *, struct directive *,
00435 char *, char *, bool);
00436
00437 static int do_line (cppReader *, struct directive *);
00438 static int do_include (cppReader *, struct directive *, char *, char *);
00439 static int do_undef (cppReader *, struct directive *, char *, char *);
00440 static int do_error (cppReader *, struct directive *, char *, char *);
00441 static int do_pragma (cppReader *, struct directive *, char *, char *);
00442 static int do_ident (cppReader *, struct directive *, char *, char *);
00443 static int do_if (cppReader *, struct directive *, char *, char *);
00444 static int do_xifdef (cppReader *, struct directive *, char *, char *);
00445 static int do_else (cppReader *, struct directive *, char *, char *);
00446 static int do_elif (cppReader *, struct directive *, char *, char *);
00447 static int do_endif (cppReader *, struct directive *, char *, char *);
00448 static int do_warning (cppReader *, struct directive *, char *, char *);
00449
00450
00451
00452
00453
00454 #define SELF_DIR_DUMMY ((struct file_name_list *) (~0))
00455
00456
00457
00458
00459
00460
00461
00462 static struct default_include {
00463 cstring fname;
00464 int cplusplus;
00465 int cxx_aware;
00466
00467
00468 } include_defaults_array[]
00469 = {
00470
00471
00472 { GCC_INCLUDE_DIR, 0, 0 },
00473 { GCC_INCLUDE_DIR2, 0, 0 },
00474 { cstring_undefined, 0, 0 }
00475 };
00476
00477
00478
00479
00480
00481
00482
00483
00484 static struct directive directive_table[] = {
00485 { 6, do_define, "define", T_DEFINE, FALSE, TRUE, FALSE },
00486 { 5, do_xifdef, "ifdef", T_IFDEF, TRUE, FALSE, FALSE },
00487 { 6, do_xifdef, "ifndef", T_IFNDEF, TRUE, FALSE, FALSE },
00488 { 7, do_include, "include", T_INCLUDE, TRUE, FALSE, FALSE },
00489 { 5, do_endif, "endif", T_ENDIF, TRUE, FALSE, FALSE },
00490 { 4, do_else, "else", T_ELSE, TRUE, FALSE, FALSE },
00491 { 2, do_if, "if", T_IF, TRUE, FALSE, FALSE },
00492 { 4, do_elif, "elif", T_ELIF, TRUE, FALSE, FALSE },
00493 { 5, do_undef, "undef", T_UNDEF, FALSE, FALSE, FALSE },
00494 { 5, do_error, "error", T_ERROR, FALSE, FALSE, FALSE },
00495 { 7, do_warning, "warning", T_WARNING, FALSE, FALSE, FALSE },
00496 { 6, do_pragma, "pragma", T_PRAGMA, FALSE, FALSE, TRUE},
00497 { 4, do_line, "line", T_LINE, TRUE, FALSE, FALSE },
00498 { 5, do_ident, "ident", T_IDENT, TRUE, FALSE, TRUE },
00499
00500 { -1, 0, "", T_UNUSED, FALSE, FALSE, FALSE },
00501 };
00502
00503
00504
00505
00506 static void
00507 initialize_char_syntax (struct cppOptions *opts)
00508 {
00509 char i;
00510
00511
00512
00513
00514
00515
00516
00517
00518 for (i = 'a'; i <= 'z'; i++) {
00519 is_idchar[i - 'a' + 'A'] = TRUE;
00520 is_idchar[(int) i] = TRUE;
00521 is_idstart[i - 'a' + 'A'] = TRUE;
00522 is_idstart[(int) i] = TRUE;
00523 }
00524
00525 for (i = '0'; i <= '9'; i++)
00526 {
00527 is_idchar[(int) i] = TRUE;
00528 }
00529
00530 is_idchar['_'] = TRUE;
00531 is_idstart['_'] = TRUE;
00532 is_idchar['$'] = opts->dollars_in_ident;
00533 is_idstart['$'] = opts->dollars_in_ident;
00534
00535
00536 is_hor_space[' '] = TRUE;
00537 is_hor_space['\t'] = TRUE;
00538 is_hor_space['\v'] = TRUE;
00539 is_hor_space['\f'] = TRUE;
00540 is_hor_space['\r'] = TRUE;
00541
00542 is_space[' '] = TRUE;
00543 is_space['\t'] = TRUE;
00544 is_space['\v'] = TRUE;
00545 is_space['\f'] = TRUE;
00546 is_space['\n'] = TRUE;
00547 is_space['\r'] = TRUE;
00548 }
00549
00550 bool isIdentifierChar (char c)
00551 {
00552 return is_idchar[(int) c];
00553 }
00554
00555
00556
00557
00558 static void
00559 quote_string (cppReader *pfile, char *src)
00560 {
00561 char c;
00562
00563 cppReader_putCharQ (pfile, '\"');
00564 for (;;)
00565 {
00566 switch ((c = *src++))
00567 {
00568 default:
00569 if (isprint (c))
00570 cppReader_putCharQ (pfile, c);
00571 else
00572 {
00573 sprintf (cppReader_getPWritten (pfile), "\\%03o",
00574 (unsigned int) c);
00575 cppReader_adjustWritten (pfile, (size_t) 4);
00576 }
00577 break;
00578
00579 case '\"':
00580 case '\\':
00581 cppReader_putCharQ (pfile, '\\');
00582 cppReader_putCharQ (pfile, c);
00583 break;
00584
00585 case '\0':
00586 cppReader_putCharQ (pfile, '\"');
00587 cppReader_nullTerminateQ (pfile);
00588 return;
00589 }
00590 }
00591 }
00592
00593
00594
00595 void
00596 cppReader_growBuffer (cppReader *pfile, size_t n)
00597 {
00598 size_t old_written = cppReader_getWritten (pfile);
00599 pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;
00600 pfile->token_buffer = (char *)
00601 drealloc (pfile->token_buffer, pfile->token_buffer_size);
00602 cppReader_setWritten (pfile, old_written);
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612 void
00613 cppReader_define (cppReader *pfile, char *str)
00614 {
00615 char *buf = NULL;
00616 char *p = str;
00617
00618 DPRINTF (("Cpp reader define: %s", str));
00619
00620 if (!is_idstart[(int) *p])
00621 {
00622 DPRINTF (("ERROR 1"));
00623 cppReader_error (pfile,
00624 message ("Malformed option `-D%s'",
00625 cstring_fromChars (str)));
00626
00627 return;
00628 }
00629
00630 p++;
00631
00632 DPRINTF (("Here 2"));
00633
00634 while (is_idchar[(int) *p])
00635 {
00636 p++;
00637 }
00638
00639 if (*p == '(') {
00640 p++;
00641 while (*p != ')' && *p != '\0') {
00642 p++;
00643 }
00644
00645 if (*p == ')') {
00646 p++;
00647 } else {
00648 cppReader_error
00649 (pfile,
00650 message ("Malformed option: -D%s (no closing parenthesis)",
00651 cstring_fromChars (str)));
00652 }
00653 }
00654
00655 DPRINTF (("Here 2"));
00656
00657 if (*p == '\0')
00658 {
00659 buf = (char *) dmalloc (size_fromInt (p - str + 4));
00660 strcpy ((char *) buf, str);
00661 strcat ((char *) buf, " 1");
00662 }
00663 else if (*p != '=')
00664 {
00665 DPRINTF (("ERROR 2"));
00666 cppReader_error (pfile,
00667 message ("Malformed option: -D%s (expected '=', found '%c')",
00668 cstring_fromChars (str),
00669 *p));
00670 return;
00671 }
00672 else
00673 {
00674 char *q;
00675
00676 DPRINTF (("Copying..."));
00677 buf = (char *) dmalloc (2 * strlen (str) + 1);
00678 strncpy (buf, str, size_fromInt (p - str));
00679
00680
00681 buf[p - str] = ' ';
00682
00683 p++;
00684 q = &buf[p - str];
00685
00686 while (*p != '\0')
00687 {
00688 if (*p == '\\' && p[1] == '\n')
00689 p += 2;
00690 else
00691 *q++ = *p++;
00692 }
00693
00694 DPRINTF (("Here we are..."));
00695 *q = '\0';
00696 }
00697
00698 llassert (buf != NULL);
00699 DPRINTF (("Do define: %s / %ld", buf, size_toLong (strlen (buf))));
00700 (void) do_define (pfile, NULL, buf, buf + strlen (buf));
00701 sfree (buf);
00702 }
00703
00704
00705
00706
00707
00708 void
00709 cppReader_appendIncludeChain (cppReader *pfile,
00710 struct file_name_list *first,
00711 struct file_name_list *last)
00712 {
00713 struct cppOptions *opts = CPPOPTIONS (pfile);
00714 struct file_name_list *dir;
00715
00716 if (first == NULL || last == NULL)
00717 {
00718 return;
00719 }
00720
00721 if (opts->include == 0)
00722 {
00723 opts->include = first;
00724 }
00725 else
00726 {
00727 llassert (opts->last_include->next == NULL);
00728 opts->last_include->next = first;
00729 }
00730
00731 if (opts->first_bracket_include == 0)
00732 {
00733 opts->first_bracket_include = first;
00734
00735 for (dir = first; ; dir = dir->next) {
00736 int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
00737 if (len > pfile->max_include_len)
00738 pfile->max_include_len = len;
00739 if (dir == last)
00740 break;
00741 }
00742 }
00743
00744 llassert (last->next == NULL);
00745
00746 opts->last_include = last;
00747 }
00748
00749 static void
00750 cppReader_showIncludeChain (cppReader *pfile)
00751 {
00752 struct file_name_list *dirs = CPPOPTIONS (pfile)->include;
00753
00754 if (dirs != NULL)
00755 {
00756 while (dirs != NULL)
00757 {
00758 fprintf (stderr, "*%s*:", cstring_toCharsSafe (dirs->fname));
00759 dirs = dirs->next;
00760 }
00761
00762 fprintf (stderr, "\n");
00763 }
00764 else
00765 {
00766 fprintf (stderr, "No includes\n");
00767 }
00768 }
00769
00770 void
00771 cppReader_addIncludeChain (cppReader *pfile, struct file_name_list *dir)
00772 {
00773 struct cppOptions *opts = CPPOPTIONS (pfile);
00774
00775 if (dir == 0)
00776 {
00777 return;
00778 }
00779
00780 if (opts->include == 0)
00781 {
00782 opts->include = dir;
00783 }
00784 else
00785 {
00786 llassert (opts->last_include->next == NULL);
00787 opts->last_include->next = dir;
00788 }
00789
00790 if (opts->first_bracket_include == 0)
00791 {
00792 int len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
00793 opts->first_bracket_include = dir;
00794 if (len > pfile->max_include_len)
00795 {
00796 pfile->max_include_len = len;
00797 }
00798 }
00799
00800 dir->next = NULL;
00801 opts->last_include = dir;
00802
00803 }
00804
00805
00806
00807
00808 static void
00809 path_include (cppReader *pfile, char *path)
00810 {
00811 char *p;
00812
00813 #ifdef __CYGWIN32__
00814 char *win32temp;
00815
00816
00817 win32temp = (char *) dmalloc
00818 (cygwin32_posix_to_win32_path_list_buf_size (path));
00819 cygwin32_posix_to_win32_path_list (path, win32temp);
00820 path = win32temp;
00821 #endif
00822
00823 p = path;
00824
00825 if (*p != '\0')
00826 while (1) {
00827 char *q = p;
00828 char *name;
00829 struct file_name_list *dirtmp;
00830
00831
00832 while (*q != '\0' && *q != PATH_SEPARATOR)
00833 {
00834 q++;
00835 }
00836
00837 if (p == q)
00838 {
00839
00840 name = (char *) dmalloc ((size_t) 2);
00841 name[0] = '.';
00842 name[1] = '\0';
00843 }
00844 else
00845 {
00846
00847 name = (char *) dmalloc (size_fromInt (q - p + 1));
00848 memcpy (name, p, size_fromInt (q - p));
00849 name[q - p] = '\0';
00850 }
00851
00852 dirtmp = (struct file_name_list *) dmalloc (sizeof (*dirtmp));
00853 dirtmp->next = 0;
00854 dirtmp->control_macro = 0;
00855 dirtmp->c_system_include_path = 0;
00856 dirtmp->fname = cstring_fromChars (name);
00857 dirtmp->got_name_map = 0;
00858 cppReader_addIncludeChain (pfile, dirtmp);
00859
00860
00861 p = q;
00862 if (*p == '\0')
00863 break;
00864
00865 p++;
00866 }
00867 }
00868
00869 void
00870 cppOptions_init (cppOptions *opts)
00871 {
00872 memset ((char *) opts, 0, sizeof *opts);
00873 assertSet (opts);
00874
00875 opts->in_fname = NULL;
00876 opts->out_fname = NULL;
00877
00878
00879 opts->dollars_in_ident = TRUE;
00880
00881 opts->no_line_commands = 0;
00882 opts->no_trigraphs = TRUE;
00883 opts->put_out_comments = 1;
00884 opts->print_include_names = 0;
00885 opts->dump_macros = DUMP_DEFINITIONS;
00886 opts->no_output = 0;
00887 opts->cplusplus = 0;
00888
00889 opts->cplusplus_comments = 1;
00890 opts->verbose = 0;
00891 opts->lang_asm = 0;
00892 opts->for_lint = 0;
00893 opts->chill = 0;
00894 opts->pedantic_errors = 0;
00895 opts->inhibit_warnings = 0;
00896 opts->warn_comments = 0;
00897 opts->warnings_are_errors = 0;
00898
00899 initialize_char_syntax (opts);
00900 }
00901
00902 enum cpp_token
00903 cppReader_nullUnderflow ( cppReader *pfile)
00904 {
00905 return CPP_EOF;
00906 }
00907
00908 void
00909 cppReader_nullCleanup ( cppBuffer *pbuf,
00910 cppReader *pfile)
00911 {
00912 ;
00913 }
00914
00915 void
00916 cppReader_macroCleanup (cppBuffer *pbuf, cppReader *pfile)
00917 {
00918 HASHNODE *macro = pbuf->hnode;
00919
00920 if (macro->type == T_DISABLED)
00921 {
00922 macro->type = T_MACRO;
00923 }
00924
00925 if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
00926 {
00927 sfree (pbuf->buf);
00928 pbuf->buf = NULL;
00929 }
00930 }
00931
00932 void
00933 cppReader_fileCleanup (cppBuffer *pbuf, cppReader *pfile)
00934 {
00935 if (pbuf->buf != NULL)
00936 {
00937 sfree (pbuf->buf);
00938 pbuf->buf = NULL;
00939 }
00940 }
00941
00942
00943
00944
00945
00946
00947
00948 static int
00949 skip_comment (cppReader *pfile, long *linep)
00950 {
00951 int c = 0;
00952
00953 llassert (pfile->buffer != NULL);
00954 llassert (pfile->buffer->cur != NULL);
00955
00956 while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n')
00957 {
00958 if (linep != NULL)
00959 {
00960 (*linep)++;
00961 }
00962
00963 cppReader_forward (pfile, 2);
00964 }
00965
00966 if (cppReader_peekC (pfile) == '*')
00967 {
00968 cppReader_forward (pfile, 1);
00969
00970 for (;;)
00971 {
00972 int prev_c = c;
00973 c = cppReader_getC (pfile);
00974
00975 if (c == EOF)
00976 {
00977 return EOF;
00978 }
00979
00980 while (c == (int) '\\' && cppReader_peekC (pfile) == (int) '\n')
00981 {
00982 if (linep != NULL )
00983 {
00984 (*linep)++;
00985 }
00986
00987 cppReader_forward (pfile, 1), c = cppReader_getC (pfile);
00988 }
00989
00990 if (prev_c == (int) '*' && c == (int) '/')
00991 {
00992 return (int) ' ';
00993 }
00994
00995 if (c == (int) '\n' && (linep != NULL))
00996 {
00997 (*linep)++;
00998 }
00999 }
01000 }
01001 else if (cppReader_peekC (pfile) == '/'
01002 && CPPOPTIONS (pfile)->cplusplus_comments)
01003 {
01004 cppReader_forward (pfile, 1);
01005
01006 for (;;)
01007 {
01008 c = cppReader_getC (pfile);
01009
01010 if (c == EOF)
01011 {
01012
01013 return (int) ' ';
01014 }
01015
01016 while (c == (int) '\\' && cppReader_peekC (pfile) == '\n')
01017 {
01018 cppReader_forward (pfile, 1);
01019 c = cppReader_getC (pfile);
01020
01021 if (linep != NULL)
01022 {
01023 (*linep)++;
01024 }
01025 }
01026
01027 if (c == (int) '\n')
01028 {
01029
01030 cppReader_forward (pfile, -1);
01031 return (int) ' ';
01032 }
01033 }
01034 }
01035 else
01036 {
01037 return (int) '/';
01038 }
01039 }
01040
01041
01042 int
01043 cppSkipHspace (cppReader *pfile)
01044 {
01045 int nspaces = 0;
01046
01047 while (TRUE)
01048 {
01049 int c;
01050
01051 llassert (pfile->buffer != NULL);
01052
01053 c = cppReader_peekC (pfile);
01054
01055 if (c == EOF)
01056 {
01057 return 0;
01058 }
01059
01060 if (is_hor_space[c])
01061 {
01062 if ((c == '\f' || c == '\v') && cppReader_isPedantic (pfile))
01063 cppReader_pedwarn (pfile,
01064 message ("%s in preprocessing directive",
01065 c == '\f'
01066 ? cstring_makeLiteralTemp ("formfeed")
01067 : cstring_makeLiteralTemp ("vertical tab")));
01068
01069 nspaces++;
01070 cppReader_forward (pfile, 1);
01071 }
01072 else if (c == '/')
01073 {
01074 cppReader_forward (pfile, 1);
01075 c = skip_comment (pfile, NULL);
01076
01077 if (c == '/')
01078 {
01079 cppReader_forward (pfile, -1);
01080 }
01081
01082 if (c == EOF || c == '/')
01083 {
01084 return nspaces;
01085 }
01086 }
01087 else if (c == '\\' && cpp_peekN (pfile, 1) == '\n')
01088 {
01089 cppReader_forward (pfile, 2);
01090 }
01091 else if (c == '@' && CPPBUFFER (pfile)->has_escapes
01092 && is_hor_space [cpp_peekN (pfile, 1)])
01093 {
01094 cppReader_forward (pfile, 2);
01095 }
01096 else
01097 {
01098 return nspaces;
01099 }
01100 }
01101 }
01102
01103
01104
01105
01106 static void
01107 copy_rest_of_line (cppReader *pfile)
01108 {
01109 struct cppOptions *opts = CPPOPTIONS (pfile);
01110
01111 for (;;)
01112 {
01113 int c;
01114 int nextc;
01115
01116 llassert (pfile->buffer != NULL);
01117
01118 c = cppReader_getC (pfile);
01119 switch (c)
01120 {
01121 case EOF:
01122 goto end_directive;
01123 case '\\':
01124 if (cppReader_peekC (pfile) == '\n')
01125 {
01126 cppReader_forward (pfile, 1);
01127 continue;
01128 }
01129
01130 case '\'': case '\"':
01131 goto scan_directive_token;
01132
01133 case '/':
01134 nextc = cppReader_peekC (pfile);
01135
01136
01137
01138
01139
01140
01141 if (nextc == '*'
01142 || (opts->cplusplus_comments && nextc == '/'))
01143 {
01144 goto scan_directive_token;
01145 }
01146 break;
01147 case '\f':
01148 case '\v':
01149 if (cppReader_isPedantic (pfile))
01150 cppReader_pedwarn (pfile,
01151 message ("%s in preprocessing directive",
01152 c == '\f'
01153 ? cstring_makeLiteralTemp ("formfeed")
01154 : cstring_makeLiteralTemp ("vertical tab")));
01155 break;
01156
01157 case '\n':
01158 cppReader_forward (pfile, -1);
01159 goto end_directive;
01160 scan_directive_token:
01161 cppReader_forward (pfile, -1);
01162 (void) cppGetToken (pfile);
01163 continue;
01164 }
01165 cppReader_putChar (pfile, c);
01166 }
01167 end_directive: ;
01168 cppReader_nullTerminate (pfile);
01169 }
01170
01171 void
01172 cppReader_skipRestOfLine (cppReader *pfile)
01173 {
01174 size_t old = cppReader_getWritten (pfile);
01175 copy_rest_of_line (pfile);
01176 cppReader_setWritten (pfile, old);
01177 }
01178
01179
01180
01181
01182 int
01183 cppReader_handleDirective (cppReader *pfile)
01184 {
01185 int c;
01186 struct directive *kt = NULL;
01187 int ident_length;
01188 size_t after_ident = 0;
01189 char *ident, *line_end = NULL;
01190 size_t old_written = cppReader_getWritten (pfile);
01191 int nspaces = cppSkipHspace (pfile);
01192
01193 c = cppReader_peekC (pfile);
01194
01195 if (c >= '0' && c <= '9')
01196 {
01197
01198 if (cppReader_isPedantic (pfile))
01199 {
01200 cppReader_pedwarnLit
01201 (pfile,
01202 cstring_makeLiteralTemp ("`#' followed by integer"));
01203 }
01204
01205 (void) do_line (pfile, NULL);
01206 goto done_a_directive;
01207 }
01208
01209
01210
01211
01212 cppReader_putChar (pfile, '#');
01213
01214 parse_name (pfile, cppReader_getC (pfile));
01215
01216 llassert (pfile->token_buffer != NULL);
01217 ident = pfile->token_buffer + old_written + 1;
01218
01219 ident_length = cppReader_getPWritten (pfile) - ident;
01220
01221 if (ident_length == 0 && cppReader_peekC (pfile) == '\n')
01222 {
01223
01224 return 1;
01225 }
01226
01227 for (kt = directive_table; ; kt++)
01228 {
01229 if (kt->length <= 0)
01230 {
01231 return 0;
01232 }
01233
01234 if (kt->length == ident_length
01235 && (cstring_equalPrefix (kt->name, ident)))
01236 {
01237 break;
01238 }
01239 }
01240
01241 if (kt->command_reads_line)
01242 {
01243 after_ident = 0;
01244 }
01245 else
01246 {
01247
01248
01249 bool comments = 1;
01250 int save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
01251 CPPOPTIONS (pfile)->put_out_comments = comments;
01252 after_ident = cppReader_getWritten (pfile);
01253 copy_rest_of_line (pfile);
01254 CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
01255 }
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 line_end = cppReader_getPWritten (pfile);
01268
01269
01270 if (!kt->pass_thru && kt->type != T_DEFINE)
01271 {
01272 cppReader_setWritten (pfile, old_written);
01273 }
01274
01275 llassert (pfile->token_buffer != NULL);
01276
01277
01278
01279 if (kt->type == T_DEFINE
01280 && cpp_shouldCheckMacro (pfile, pfile->token_buffer + old_written))
01281 {
01282 char *p = pfile->token_buffer + old_written;
01283
01284
01285
01286
01287
01288
01289 (void) do_defineAux (pfile, kt,
01290 pfile->token_buffer + after_ident,
01291 line_end,
01292 TRUE);
01293
01294 if (*p == '#')
01295 {
01296 *p = ' ';
01297 }
01298
01299 SKIP_WHITE_SPACE (p);
01300
01301 llassert (*p == 'd');
01302 *p++ = LLMRCODE[0];
01303
01304 llassert (*p == 'e');
01305 *p++ = LLMRCODE[1];
01306
01307 llassert (*p == 'f');
01308 *p++ = LLMRCODE[2];
01309
01310 llassert (*p == 'i');
01311 *p++ = LLMRCODE[3];
01312
01313 llassert (*p == 'n');
01314 *p++ = LLMRCODE[4];
01315
01316 llassert (*p == 'e');
01317
01318
01319
01320
01321
01322
01323 if (nspaces > 9) nspaces = 9;
01324
01325 *p++ = '0' + nspaces;
01326
01327 return 0;
01328 }
01329 else if (kt->pass_thru)
01330 {
01331
01332 return 0;
01333
01334 }
01335 else if (kt->type == T_DEFINE
01336 && CPPOPTIONS (pfile)->dump_macros == DUMP_NAMES)
01337 {
01338 char *p = pfile->token_buffer + old_written + 7;
01339 SKIP_WHITE_SPACE (p);
01340
01341 while (is_idchar[(int) *p])
01342 {
01343 p++;
01344 }
01345
01346 pfile->limit = p;
01347 cppReader_putChar (pfile, '\n');
01348 }
01349 else if (kt->type == T_DEFINE)
01350 {
01351 cppReader_setWritten (pfile, old_written);
01352 }
01353 else
01354 {
01355 ;
01356 }
01357
01358 done_a_directive:
01359 if (kt == NULL) {
01360 return 1;
01361 } else {
01362 llassert (kt->func != NULL);
01363 (void) (kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end);
01364 return 1;
01365 }
01366 }
01367
01368
01369
01370
01371
01372
01373 static void
01374 pass_thru_directive (char *buf, char *limit,
01375 cppReader *pfile,
01376 struct directive *keyword)
01377 {
01378 int keyword_length = keyword->length;
01379
01380 cppReader_reserve (pfile,
01381 size_fromInt (2 + keyword_length + (limit - buf)));
01382 cppReader_putCharQ (pfile, '#');
01383
01384 cppReader_putStrN (pfile, cstring_toCharsSafe (keyword->name),
01385 size_fromInt (keyword_length));
01386
01387
01388 if (limit != buf && buf[0] != ' ')
01389 {
01390
01391 cppReader_putCharQ (pfile, ' ');
01392 }
01393
01394 cppReader_putStrN (pfile, buf, size_fromInt (limit - buf));
01395 }
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 static DEFINITION *
01410 collect_expansion (cppReader *pfile, char *buf, char *limit,
01411 int nargs, struct arglist *arglist)
01412 {
01413 DEFINITION *defn;
01414 char *p, *lastp, *exp_p;
01415 struct reflist *endpat = NULL;
01416
01417 char *concat = 0;
01418
01419 char *stringify = 0;
01420 size_t maxsize;
01421 char expected_delimiter = '\0';
01422
01423
01424
01425
01426
01427
01428
01429 if (limit < buf)
01430 abort ();
01431
01432
01433 p = buf;
01434
01435 while (p < limit && is_space[(int) limit[-1]])
01436 {
01437 limit--;
01438 }
01439
01440
01441
01442
01443
01444
01445 maxsize = (sizeof (*defn) + (limit - p) + 5);
01446
01447
01448 while (p < limit)
01449 {
01450 if (*p++ == '@')
01451 {
01452 maxsize++;
01453 }
01454 }
01455
01456 defn = (DEFINITION *) dmalloc (maxsize);
01457 defn->noExpand = FALSE;
01458 defn->file = NULL;
01459 defn->pattern = NULL;
01460 defn->nargs = nargs;
01461 defn->predefined = NULL;
01462
01463 exp_p = defn->expansion = (char *) defn + sizeof (*defn);
01464
01465 defn->line = 0;
01466 defn->rest_args = NULL;
01467 defn->args.argnames = NULL;
01468
01469 lastp = exp_p;
01470
01471 p = buf;
01472
01473
01474
01475 *exp_p++ = '@';
01476 *exp_p++ = ' ';
01477
01478 if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
01479 cppReader_errorLit (pfile,
01480 cstring_makeLiteralTemp ("`##' at start of macro definition"));
01481 p += 2;
01482 }
01483
01484
01485 while (p < limit) {
01486 int skipped_arg = 0;
01487 register char c = *p++;
01488
01489 *exp_p++ = c;
01490
01491 if (!cppReader_isTraditional (pfile)) {
01492 switch (c) {
01493 case '\'':
01494 case '\"':
01495 if (expected_delimiter != '\0')
01496 {
01497 if (c == expected_delimiter)
01498 expected_delimiter = '\0';
01499 }
01500 else
01501 {
01502 expected_delimiter = c;
01503 }
01504 break;
01505
01506 case '\\':
01507 if (p < limit && (expected_delimiter != '\0'))
01508 {
01509
01510
01511 *exp_p++ = *p++;
01512 }
01513 break;
01514
01515 case '@':
01516
01517
01518 if (expected_delimiter == '\0')
01519 {
01520 *exp_p++ = c;
01521 }
01522
01523 break;
01524
01525 case '#':
01526
01527 if (expected_delimiter != '\0')
01528 {
01529 break;
01530 }
01531
01532 if (p < limit && *p == '#') {
01533
01534
01535 exp_p--;
01536
01537
01538 while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
01539 {
01540 --exp_p;
01541 }
01542
01543
01544
01545 p++;
01546
01547 SKIP_WHITE_SPACE (p);
01548 concat = p;
01549 if (p == limit)
01550 {
01551 cppReader_errorLit (pfile,
01552 cstring_makeLiteralTemp ("`##' at end of macro definition"));
01553 }
01554 } else if (nargs >= 0) {
01555
01556
01557 exp_p--;
01558 SKIP_WHITE_SPACE (p);
01559 if (p == limit || ! is_idstart[(int) *p]
01560 || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '"')))
01561 cppReader_errorLit (pfile,
01562 cstring_makeLiteralTemp ("`#' operator is not followed by a macro argument name"));
01563 else
01564 stringify = p;
01565 } else {
01566 ;
01567 }
01568
01569 break;
01570 }
01571 } else {
01572
01573
01574
01575
01576 switch (c) {
01577 case '\'':
01578 case '\"':
01579 if (expected_delimiter != '\0') {
01580 if (c == expected_delimiter)
01581 expected_delimiter = '\0';
01582 } else
01583 expected_delimiter = c;
01584 break;
01585
01586 case '\\':
01587
01588 if (expected_delimiter != '\0' && p < limit
01589 && (*p == expected_delimiter || *p == '\\')) {
01590 *exp_p++ = *p++;
01591 continue;
01592 }
01593 break;
01594
01595 case '/':
01596 if (expected_delimiter != '\0')
01597 break;
01598 if (*p == '*') {
01599
01600
01601
01602 exp_p--;
01603 p += 1;
01604 while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
01605 {
01606 p++;
01607 }
01608 }
01609 break;
01610 }
01611 }
01612
01613
01614 if (is_idchar[(int) c] && nargs > 0) {
01615 char *id_beg = p - 1;
01616 int id_len;
01617
01618 --exp_p;
01619 while (p != limit && is_idchar[(int) *p])
01620 {
01621 p++;
01622 }
01623
01624 id_len = p - id_beg;
01625
01626 if (is_idstart[(int) c]
01627 && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
01628 register struct arglist *arg;
01629
01630 for (arg = arglist; arg != NULL; arg = arg->next) {
01631 struct reflist *tpat;
01632
01633 if (arg->name[0] == c
01634 && arg->length == id_len
01635 && strncmp (arg->name, id_beg, size_fromInt (id_len)) == 0) {
01636 char *p1;
01637
01638 if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) {
01639 if (cppReader_isTraditional (pfile)) {
01640 cppReader_warning (pfile,
01641 message ("macro argument `%x' is stringified.",
01642 cstring_prefix (cstring_fromChars (arg->name), id_len)));
01643 } else {
01644 cppReader_warning (pfile,
01645 message ("macro arg `%x' would be stringified with -traditional.",
01646 cstring_prefix (cstring_fromChars (arg->name), id_len)));
01647 }
01648 }
01649
01650 if (!cppReader_isTraditional (pfile) && expected_delimiter)
01651 break;
01652
01653
01654 tpat = (struct reflist *) dmalloc (sizeof (*tpat));
01655 tpat->next = NULL;
01656 tpat->raw_before = (concat == id_beg);
01657 tpat->raw_after = 0;
01658 tpat->rest_args = arg->rest_args;
01659 tpat->stringify = (cppReader_isTraditional (pfile)
01660 ? expected_delimiter != '\0'
01661 : stringify == id_beg);
01662
01663 if (endpat == NULL)
01664 {
01665 defn->pattern = tpat;
01666 }
01667 else
01668 {
01669 endpat->next = tpat;
01670
01671 }
01672
01673 endpat = tpat;
01674
01675 tpat->argno = arg->argno;
01676 tpat->nchars = exp_p - lastp;
01677
01678 p1 = p;
01679
01680 SKIP_WHITE_SPACE (p1);
01681
01682 if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
01683 {
01684 tpat->raw_after = 1;
01685 }
01686
01687 lastp = exp_p;
01688 skipped_arg = 1;
01689
01690 break;
01691 }
01692 }
01693 }
01694
01695
01696 if (skipped_arg == 0) {
01697 register char *lim1 = p;
01698 p = id_beg;
01699
01700 while (p != lim1)
01701 {
01702 *exp_p++ = *p++;
01703 }
01704
01705 if (stringify == id_beg)
01706 cppReader_errorLit (pfile,
01707 cstring_makeLiteralTemp ("`#' operator should be followed by a macro argument name"));
01708 }
01709 }
01710 }
01711
01712 if (!cppReader_isTraditional (pfile) && expected_delimiter == '\0')
01713 {
01714
01715
01716
01717 *exp_p++ = '@';
01718 *exp_p++ = ' ';
01719 }
01720
01721 *exp_p = '\0';
01722
01723 defn->length = size_fromInt (exp_p - defn->expansion);
01724
01725
01726 if (defn->length + 1 > maxsize)
01727 {
01728 llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
01729 }
01730
01731 return defn;
01732 }
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748 static char rest_extension[] = "...";
01749
01750
01751
01752 #define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
01753
01754
01755
01756
01757 static MACRODEF
01758 create_definition (char *buf, char *limit,
01759 cppReader *pfile, bool predefinition,
01760 bool noExpand)
01761 {
01762 char *bp;
01763 char *symname;
01764 int sym_length;
01765 int rest_args = 0;
01766 int line;
01767 int col;
01768 cstring file = (CPPBUFFER (pfile) != NULL)
01769 ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");
01770 DEFINITION *defn;
01771 int arglengths = 0;
01772
01773 MACRODEF mdef;
01774
01775 cppBuffer_lineAndColumn (CPPBUFFER (pfile), &line, &col);
01776
01777 bp = buf;
01778
01779 while (is_hor_space[(int) *bp])
01780 {
01781 bp++;
01782 }
01783
01784 symname = bp;
01785
01786 sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));
01787
01788 bp += sym_length;
01789
01790
01791
01792
01793
01794 if (*bp == '(') {
01795 struct arglist *arg_ptrs = NULL;
01796 int argno = 0;
01797
01798 bp++;
01799 SKIP_WHITE_SPACE (bp);
01800
01801
01802 while (*bp != ')')
01803 {
01804 struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
01805 temp->name = bp;
01806 temp->next = arg_ptrs;
01807 temp->argno = argno++;
01808 temp->rest_args = 0;
01809
01810 arg_ptrs = temp;
01811
01812 if (rest_args != 0)
01813 {
01814 cppReader_pedwarn (pfile,
01815 message ("another parameter follows `%s'",
01816 cstring_fromChars (rest_extension)));
01817 }
01818
01819 if (!is_idstart[(int) *bp])
01820 {
01821 cppReader_pedwarnLit (pfile,
01822 cstring_makeLiteralTemp ("invalid character in macro parameter name"));
01823 }
01824
01825
01826 while (is_idchar[(int) *bp])
01827 {
01828 bp++;
01829
01830 if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
01831 && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
01832 {
01833 rest_args = 1;
01834 temp->rest_args = 1;
01835 break;
01836 }
01837 }
01838
01839 temp->length = bp - temp->name;
01840
01841 if (rest_args != 0)
01842 {
01843 bp += REST_EXTENSION_LENGTH;
01844 }
01845
01846 arglengths += temp->length + 2;
01847 SKIP_WHITE_SPACE (bp);
01848
01849 if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
01850 cppReader_errorLit (pfile,
01851 cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
01852 goto nope;
01853 }
01854
01855 if (*bp == ',') {
01856 bp++;
01857 SKIP_WHITE_SPACE (bp);
01858 }
01859 if (bp >= limit) {
01860 cppReader_errorLit (pfile,
01861 cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));
01862 goto nope;
01863 }
01864 {
01865 struct arglist *otemp;
01866
01867 for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
01868 {
01869 if (temp->length == otemp->length &&
01870 strncmp (temp->name, otemp->name, size_fromInt (temp->length)) == 0) {
01871 cstring name = cstring_copyLength (temp->name, temp->length);
01872 cppReader_error (pfile,
01873 message ("duplicate argument name `%x' in `#define'", name));
01874 goto nope;
01875 }
01876 }
01877 }
01878 }
01879
01880 ++bp;
01881 SKIP_WHITE_SPACE (bp);
01882
01883 defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
01884 defn->rest_args = rest_args;
01885
01886
01887
01888
01889 defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
01890
01891 {
01892 struct arglist *temp;
01893 int i = 0;
01894 for (temp = arg_ptrs; temp != NULL; temp = temp->next) {
01895 memcpy (&defn->args.argnames[i], temp->name, size_fromInt (temp->length));
01896 i += temp->length;
01897 if (temp->next != 0) {
01898 defn->args.argnames[i++] = ',';
01899 defn->args.argnames[i++] = ' ';
01900 }
01901 }
01902
01903 defn->args.argnames[i] = '\0';
01904 }
01905
01906 sfree (arg_ptrs);
01907 } else {
01908
01909
01910 if (bp < limit)
01911 {
01912 if (is_hor_space[(int) *bp]) {
01913 bp++;
01914 SKIP_WHITE_SPACE (bp);
01915 } else {
01916 switch (*bp) {
01917 case '!': case '"': case '#': case '%': case '&': case '\'':
01918 case ')': case '*': case '+': case ',': case '-': case '.':
01919 case '/': case ':': case ';': case '<': case '=': case '>':
01920 case '?': case '[': case '\\': case ']': case '^': case '{':
01921 case '|': case '}': case '~':
01922 cppReader_warning (pfile,
01923 message ("Missing white space after #define %x",
01924 cstring_prefix (cstring_fromChars (symname),
01925 sym_length)));
01926 break;
01927
01928 default:
01929 cppReader_pedwarn (pfile,
01930 message ("Missing white space after #define %x",
01931 cstring_prefix (cstring_fromChars (symname),
01932 sym_length)));
01933 break;
01934 }
01935 }
01936 }
01937
01938 defn = collect_expansion (pfile, bp, limit, -1, NULL);
01939 defn->args.argnames = mstring_createEmpty ();
01940 }
01941
01942 defn->noExpand = noExpand;
01943 DPRINTF (("No expand: %d", noExpand));
01944
01945 defn->line = line;
01946
01947
01948 defn->file = file;
01949
01950
01951 defn->predefined = predefinition;
01952 mdef.defn = defn;
01953 mdef.symnam = symname;
01954 mdef.symlen = sym_length;
01955
01956 return mdef;
01957
01958 nope:
01959 mdef.defn = NULL;
01960 mdef.symnam = NULL;
01961 return mdef;
01962 }
01963
01964
01965
01966
01967 int cppReader_checkMacroName (cppReader *pfile,
01968 char *symname,
01969 cstring usage)
01970 {
01971 char *p;
01972 size_t sym_length;
01973
01974 for (p = symname; is_idchar[(int) *p]; p++)
01975 {
01976 ;
01977 }
01978
01979 sym_length = size_fromInt (p - symname);
01980
01981 if (sym_length == 0
01982 || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
01983 cppReader_error (pfile, message ("invalid %s name", usage));
01984 else if (!is_idstart[(int) *symname])
01985 {
01986 char *msg = (char *) dmalloc (sym_length + 1);
01987 memcpy (msg, symname, sym_length);
01988 msg[sym_length] = '\0';
01989 cppReader_error (pfile, message ("invalid %s name `%s'", usage,
01990 cstring_fromChars (msg)));
01991 sfree (msg);
01992 }
01993 else
01994 {
01995 if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7)
01996 {
01997 cppReader_error (pfile, message ("invalid %s name `defined'", usage));
01998 }
01999 }
02000
02001 return size_toInt (sym_length);
02002 }
02003
02004
02005
02006 static bool
02007 compare_defs (DEFINITION *d1, DEFINITION *d2)
02008 {
02009 register struct reflist *a1, *a2;
02010 register char *p1 = d1->expansion;
02011 register char *p2 = d2->expansion;
02012 bool first = TRUE;
02013
02014 if (d1->nargs != d2->nargs)
02015 {
02016 return TRUE;
02017 }
02018
02019 llassert (d1->args.argnames != NULL);
02020 llassert (d2->args.argnames != NULL);
02021
02022 if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames) != 0)
02023 {
02024 return TRUE;
02025 }
02026
02027 for (a1 = d1->pattern, a2 = d2->pattern;
02028 (a1 != NULL) && (a2 != NULL);
02029 a1 = a1->next, a2 = a2->next) {
02030 if (!((a1->nchars == a2->nchars
02031 && (strncmp (p1, p2, size_fromInt (a1->nchars)) == 0))
02032 || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
02033 || a1->argno != a2->argno
02034 || a1->stringify != a2->stringify
02035 || a1->raw_before != a2->raw_before
02036 || a1->raw_after != a2->raw_after)
02037 return TRUE;
02038 first = 0;
02039 p1 += a1->nchars;
02040 p2 += a2->nchars;
02041 }
02042 if (a1 != a2)
02043 return TRUE;
02044
02045 if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
02046 p2, d2->length - (p2 - d2->expansion), 1))
02047 return TRUE;
02048
02049 return FALSE;
02050 }
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061 static bool
02062 comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last)
02063 {
02064 char *end1 = beg1 + len1;
02065 char *end2 = beg2 + len2;
02066
02067 if (first) {
02068 while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
02069 while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
02070 }
02071 if (last) {
02072 while (beg1 != end1 && is_space[(int) end1[-1]]) { end1--; }
02073 while (beg2 != end2 && is_space[(int) end2[-1]]) { end2--; }
02074 }
02075 while (beg1 != end1 && beg2 != end2) {
02076 if (is_space[(int) *beg1] && is_space[(int) *beg2]) {
02077 while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
02078 while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
02079 } else if (*beg1 == *beg2) {
02080 beg1++; beg2++;
02081 } else break;
02082 }
02083 return (beg1 != end1) || (beg2 != end2);
02084 }
02085
02086
02087
02088
02089
02090
02091
02092 static int
02093 do_defineAux (cppReader *pfile, struct directive *keyword,
02094 char *buf, char *limit, bool noExpand)
02095 {
02096 int hashcode;
02097 MACRODEF mdef;
02098 HASHNODE *hp;
02099
02100 DPRINTF (("Define aux: %d", noExpand));
02101
02102 mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand);
02103
02104 if (mdef.defn == 0)
02105 goto nope;
02106
02107 hashcode = hashf (mdef.symnam, mdef.symlen, CPP_HASHSIZE);
02108
02109 DPRINTF (("Macro: %s / %s",
02110 cstring_copyLength (mdef.symnam, mdef.symlen),
02111 bool_unparse (noExpand)));
02112
02113 if ((hp = cppReader_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL)
02114 {
02115 bool ok = FALSE;
02116
02117
02118 if (hp->type == T_PCSTRING)
02119 ok = TRUE;
02120
02121 else if (hp->type == T_MACRO)
02122 ok = !compare_defs (mdef.defn, hp->value.defn);
02123
02124 else if (hp->type == T_CONST)
02125 ok = !CPPOPTIONS (pfile)->done_initializing;
02126 else {
02127 BADBRANCH;
02128 }
02129
02130
02131 if (!ok)
02132 {
02133
02134
02135
02136
02137
02138 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
02139 {
02140
02141 pass_thru_directive (buf, limit, pfile, keyword);
02142 }
02143
02144 cpp_setLocation (pfile);
02145
02146 if (hp->type == T_MACRO)
02147 {
02148 if (hp->value.defn->noExpand)
02149 {
02150 ;
02151 }
02152 else
02153 {
02154 genppllerrorhint
02155 (FLG_MACROREDEF,
02156 message ("Macro %q already defined",
02157 cstring_copyLength (mdef.symnam, mdef.symlen)),
02158 message ("%q: Previous definition of %q",
02159 fileloc_unparseRaw (hp->value.defn->file,
02160 (int) hp->value.defn->line),
02161 cstring_copyLength (mdef.symnam, mdef.symlen)));
02162 }
02163 }
02164 else
02165 {
02166 genppllerror (FLG_MACROREDEF,
02167 message ("Macro %q already defined",
02168 cstring_copyLength (mdef.symnam,
02169 mdef.symlen)));
02170
02171 }
02172 }
02173
02174
02175 hp->type = T_MACRO;
02176 hp->value.defn = mdef.defn;
02177 }
02178 else
02179 {
02180
02181
02182
02183
02184
02185 HASHNODE *hn;
02186
02187 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
02188 {
02189 pass_thru_directive (buf, limit, pfile, keyword);
02190 }
02191
02192 DPRINTF (("Define macro: %s / %d",
02193 mdef.symnam, mdef.defn->noExpand));
02194
02195 hn = cppReader_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
02196
02197 }
02198
02199 return 0;
02200
02201 nope:
02202
02203 return 1;
02204 }
02205
02206 static int
02207 do_define (cppReader *pfile, struct directive *keyword,
02208 char *buf, char *limit)
02209 {
02210 DPRINTF (("Regular do define"));
02211 return do_defineAux (pfile, keyword, buf, limit, FALSE);
02212 }
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226 #define ARG_BASE ((pfile)->token_buffer)
02227
02228 struct argdata {
02229
02230 long raw;
02231 size_t expanded;
02232 size_t stringified;
02233 int raw_length;
02234 int expand_length;
02235 int stringified_length;
02236 bool newlines;
02237 int use_count;
02238 };
02239
02240
02241
02242
02243
02244
02245 cppBuffer *
02246 cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)
02247 {
02248 cppBuffer *buf = cppReader_getBuffer (pfile);
02249
02250 if (buf == pfile->buffer_stack)
02251 {
02252 cppReader_fatalError
02253 (pfile,
02254 message ("%s: macro or `#include' recursion too deep",
02255 (buf->fname != NULL)
02256 ? buf->fname
02257 : cstring_makeLiteral ("<no name>")));
02258 sfreeEventually (buffer);
02259 return NULL;
02260 }
02261
02262 llassert (buf != NULL);
02263
02264 buf--;
02265 memset ((char *) buf, 0, sizeof (*buf));
02266 CPPBUFFER (pfile) = buf;
02267
02268 buf->if_stack = pfile->if_stack;
02269 buf->cleanup = cppReader_nullCleanup;
02270 buf->underflow = cppReader_nullUnderflow;
02271 buf->buf = buffer;
02272 buf->cur = buf->buf;
02273
02274 if (buffer != NULL)
02275 {
02276 buf->alimit = buf->rlimit = buffer + length;
02277 }
02278 else
02279 {
02280 buf->alimit = buf->rlimit = NULL;
02281 }
02282
02283 return buf;
02284 }
02285
02286 cppBuffer *
02287 cppReader_popBuffer (cppReader *pfile)
02288 {
02289 cppBuffer *buf = CPPBUFFER (pfile);
02290
02291 llassert (buf != NULL);
02292
02293 (void) (*buf->cleanup) (buf, pfile);
02294 return ++CPPBUFFER (pfile);
02295 }
02296
02297
02298
02299
02300 void
02301 cppReader_scanBuffer (cppReader *pfile)
02302 {
02303 cppBuffer *buffer = CPPBUFFER (pfile);
02304 for (;;)
02305 {
02306 enum cpp_token token;
02307
02308 token = cppGetToken (pfile);
02309
02310 if (token == CPP_EOF)
02311 {
02312 break;
02313 }
02314
02315 if (token == CPP_POP && CPPBUFFER (pfile) == buffer)
02316 {
02317 (void) cppReader_popBuffer (pfile);
02318 break;
02319 }
02320 }
02321 }
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332 static void
02333 cpp_expand_to_buffer (cppReader *pfile, char *buf, size_t length)
02334 {
02335 register cppBuffer *ip;
02336 char *limit = buf + length;
02337 char *buf1, *p1, *p2;
02338
02339 if (length < 0)
02340 abort ();
02341
02342
02343
02344 buf1 = (char *) dmalloc (length + 1);
02345
02346 p1 = buf;
02347 p2 = buf1;
02348
02349 while (p1 != limit)
02350 {
02351 *p2++ = *p1++;
02352 }
02353
02354 buf1[length] = '\0';
02355
02356 ip = cppReader_pushBuffer (pfile, buf1, length);
02357
02358 if (ip == NULL)
02359 return;
02360
02361 ip->has_escapes = TRUE;
02362
02363
02364 cppReader_scanBuffer (pfile);
02365
02366 cppReader_nullTerminate (pfile);
02367 }
02368
02369 static void
02370 adjust_position (char *buf, char *limit, int *linep, int *colp)
02371 {
02372 while (buf < limit)
02373 {
02374 char ch = *buf++;
02375 if (ch == '\n')
02376 (*linep)++, (*colp) = 1;
02377 else
02378 (*colp)++;
02379 }
02380 }
02381
02382
02383
02384 static void
02385 update_position (cppBuffer *pbuf)
02386 {
02387 char *old_pos;
02388 char *new_pos = pbuf->cur;
02389 register struct parse_marker *mark;
02390
02391 llassert (pbuf->buf != NULL);
02392 old_pos = pbuf->buf + pbuf->line_base;
02393
02394 for (mark = pbuf->marks; mark != NULL; mark = mark->next)
02395 {
02396 if (pbuf->buf + mark->position < new_pos)
02397 new_pos = pbuf->buf + mark->position;
02398 }
02399 pbuf->line_base += new_pos - old_pos;
02400
02401 llassert (old_pos != NULL);
02402 llassert (new_pos != NULL);
02403
02404 adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);
02405 }
02406
02407 void
02408 cppBuffer_lineAndColumn ( cppBuffer *pbuf, int *linep,
02409 int *colp)
02410 {
02411 int dummy;
02412
02413 if (colp == NULL)
02414 {
02415 colp = &dummy;
02416
02417 }
02418
02419 if (pbuf != NULL)
02420 {
02421 *linep = pbuf->lineno;
02422 *colp = pbuf->colno;
02423
02424 llassert (pbuf->buf != NULL);
02425 llassert (pbuf->cur != NULL);
02426
02427 adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp);
02428 }
02429 else
02430 {
02431 *linep = 0;
02432 *colp = 0;
02433 }
02434 }
02435
02436
02437
02438 cppBuffer *cppReader_fileBuffer (cppReader *pfile)
02439 {
02440 cppBuffer *ip = cppReader_getBuffer (pfile);
02441
02442 for ( ;
02443 ip != NULL && ip != cppReader_nullBuffer (pfile);
02444 ip = cppBuffer_prevBuffer (ip))
02445 {
02446 if (ip->fname != NULL)
02447 {
02448 return ip;
02449 }
02450 }
02451
02452 return NULL;
02453 }
02454
02455 static long
02456 count_newlines (char *buf, char *limit)
02457 {
02458 register long count = 0;
02459
02460 while (buf < limit)
02461 {
02462 char ch = *buf++;
02463 if (ch == '\n')
02464 count++;
02465 }
02466 return count;
02467 }
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477 static void
02478 output_line_command (cppReader *pfile, bool conditional,
02479 enum file_change_code file_change)
02480 {
02481 int line, col;
02482 cppBuffer *ip = CPPBUFFER (pfile);
02483 cppBuffer *buf;
02484
02485 llassert (ip != NULL);
02486
02487 if (ip->fname == NULL)
02488 return;
02489
02490 update_position (ip);
02491
02492 if (CPPOPTIONS (pfile)->no_line_commands
02493 || CPPOPTIONS (pfile)->no_output)
02494 return;
02495
02496 buf = CPPBUFFER (pfile);
02497
02498 llassert (buf != NULL);
02499
02500 line = buf->lineno;
02501 col = buf->colno;
02502
02503 llassert (ip->cur != NULL);
02504
02505 adjust_position (cppLineBase (ip), ip->cur, &line, &col);
02506
02507 if (CPPOPTIONS (pfile)->no_line_commands)
02508 return;
02509
02510 if (conditional) {
02511 if (line == pfile->lineno)
02512 return;
02513
02514
02515
02516
02517 if (line > pfile->lineno && line < pfile->lineno + 8)
02518 {
02519 cppReader_reserve (pfile, 20);
02520 while (line > pfile->lineno)
02521 {
02522 cppReader_putCharQ (pfile, '\n');
02523 pfile->lineno++;
02524 }
02525
02526 return;
02527 }
02528 }
02529
02530 cppReader_reserve (pfile,
02531 size_fromInt (4 * cstring_length (ip->nominal_fname) + 50));
02532
02533 {
02534 #ifdef OUTPUT_LINE_COMMANDS
02535 static char sharp_line[] = "#line ";
02536 #else
02537 static char sharp_line[] = "# ";
02538 #endif
02539 cppReader_putStrN (pfile, sharp_line, sizeof(sharp_line)-1);
02540 }
02541
02542 sprintf (cppReader_getPWritten (pfile), "%d ", line);
02543 cppReader_adjustWritten (pfile, strlen (cppReader_getPWritten (pfile)));
02544
02545 quote_string (pfile, cstring_toCharsSafe (ip->nominal_fname));
02546
02547 if (file_change != same_file) {
02548 cppReader_putCharQ (pfile, ' ');
02549 cppReader_putCharQ (pfile, file_change == enter_file ? '1' : '2');
02550 }
02551
02552 if (ip->system_header_p != '\0') {
02553 cppReader_putCharQ (pfile, ' ');
02554 cppReader_putCharQ (pfile, '3');
02555 }
02556 #ifndef NO_IMPLICIT_EXTERN_C
02557
02558 if (ip->system_header_p == (char) 2 && CPPOPTIONS (pfile)->cplusplus) {
02559 cppReader_putCharQ (pfile, ' ');
02560 cppReader_putCharQ (pfile, '4');
02561 }
02562 #endif
02563 cppReader_putCharQ (pfile, '\n');
02564 pfile->lineno = line;
02565 }
02566
02567
02568
02569
02570
02571
02572
02573
02574 static enum cpp_token
02575 macarg (cppReader *pfile, int rest_args)
02576 {
02577 int paren = 0;
02578 enum cpp_token token;
02579 char save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
02580 bool oldexpand = pfile->no_macro_expand;
02581 CPPOPTIONS (pfile)->put_out_comments = 1;
02582
02583
02584
02585
02586 pfile->no_macro_expand = TRUE;
02587
02588 for (;;)
02589 {
02590 token = cppGetToken (pfile);
02591
02592 switch (token)
02593 {
02594 case CPP_EOF:
02595 goto done;
02596 case CPP_POP:
02597
02598
02599
02600 if (!cppBuffer_isMacro (CPPBUFFER (pfile)))
02601 goto done;
02602 break;
02603 case CPP_LPAREN:
02604 paren++;
02605 break;
02606 case CPP_RPAREN:
02607 if (--paren < 0)
02608 goto found;
02609 break;
02610 case CPP_COMMA:
02611
02612
02613 if (paren == 0 && rest_args == 0)
02614 goto found;
02615 break;
02616 found:
02617
02618 cppReader_adjustWritten (pfile, -1);
02619 goto done;
02620 default:
02621 ;
02622 }
02623 }
02624
02625 done:
02626 CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
02627 pfile->no_macro_expand = oldexpand;
02628
02629 return token;
02630 }
02631
02632
02633
02634
02635
02636
02637 static int
02638 change_newlines (char *start, int length)
02639 {
02640 register char *ibp;
02641 register char *obp;
02642 register char *limit;
02643 char c;
02644
02645 ibp = start;
02646 limit = start + length;
02647 obp = start;
02648
02649 while (ibp < limit) {
02650 *obp++ = c = *ibp++;
02651 switch (c) {
02652
02653 case '\'':
02654 case '\"':
02655
02656 {
02657 char quotec = c;
02658 while (ibp < limit) {
02659 *obp++ = c = *ibp++;
02660 if (c == quotec)
02661 break;
02662 if (c == '\n' && quotec == '\'')
02663 break;
02664 }
02665 }
02666 break;
02667 }
02668 }
02669
02670 return obp - start;
02671 }
02672
02673 static struct tm *
02674 timestamp ( cppReader *pfile)
02675 {
02676 if (pfile->timebuf == NULL)
02677 {
02678 time_t t = time ((time_t *) 0);
02679 pfile->timebuf = localtime (&t);
02680 }
02681
02682 llassert (pfile->timebuf != NULL);
02683
02684 return pfile->timebuf;
02685 }
02686
02687 static ob_mstring monthnames[] = {
02688 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
02689 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
02690 } ;
02691
02692
02693
02694
02695
02696
02697 static void
02698 special_symbol (HASHNODE *hp, cppReader *pfile)
02699 {
02700 cstring buf = cstring_undefined;
02701 size_t len;
02702 int true_indepth;
02703 cppBuffer *ip;
02704 struct tm *timebuf;
02705
02706 int paren = 0;
02707
02708 for (ip = cppReader_getBuffer (pfile); ip != NULL; ip = cppBuffer_prevBuffer (ip))
02709 {
02710 if (ip == cppReader_nullBuffer (pfile))
02711 {
02712 cppReader_errorLit (pfile,
02713 cstring_makeLiteralTemp ("cccp error: not in any file?!"));
02714 return;
02715 }
02716
02717 if (ip != NULL && ip->fname != NULL)
02718 {
02719 break;
02720 }
02721 }
02722
02723 switch (hp->type)
02724 {
02725 case T_FILE:
02726 case T_BASE_FILE:
02727 {
02728 char *string;
02729 if (hp->type == T_BASE_FILE)
02730 {
02731 while (cppBuffer_prevBuffer (ip) != cppReader_nullBuffer (pfile))
02732 {
02733 ip = cppBuffer_prevBuffer (ip);
02734 }
02735 }
02736
02737 llassert (ip != NULL);
02738 string = cstring_toCharsSafe (ip->nominal_fname);
02739
02740 if (string == NULL)
02741 {
02742 string = "";
02743 }
02744
02745 cppReader_reserve (pfile, 3 + 4 * strlen (string));
02746 quote_string (pfile, string);
02747 return;
02748 }
02749
02750 case T_INCLUDE_LEVEL:
02751 true_indepth = 0;
02752 ip = cppReader_getBuffer (pfile);
02753
02754 for (; ip != cppReader_nullBuffer (pfile) && ip != NULL;
02755 ip = cppBuffer_prevBuffer (ip))
02756 {
02757 if (ip != NULL && ip->fname != NULL)
02758 {
02759 true_indepth++;
02760 }
02761 }
02762
02763 buf = message ("%d", true_indepth - 1);
02764 break;
02765
02766 case T_VERSION:
02767 buf = message ("\"%s\"", cstring_makeLiteralTemp (CPP_VERSION));
02768 break;
02769
02770 #ifndef NO_BUILTIN_SIZE_TYPE
02771 case T_SIZE_TYPE:
02772 buf = cstring_makeLiteral (SIZE_TYPE);
02773 break;
02774 #endif
02775
02776 #ifndef NO_BUILTIN_PTRDIFF_TYPE
02777 case T_PTRDIFF_TYPE:
02778 buf = cstring_makeLiteral (PTRDIFF_TYPE);
02779 break;
02780 #endif
02781
02782 case T_WCHAR_TYPE:
02783 buf = cstring_makeLiteral (cppReader_wcharType (pfile));
02784 break;
02785
02786 case T_USER_LABEL_PREFIX_TYPE:
02787 buf = cstring_makeLiteral (USER_LABEL_PREFIX);
02788 break;
02789
02790 case T_REGISTER_PREFIX_TYPE:
02791 buf = cstring_makeLiteral (REGISTER_PREFIX);
02792 break;
02793
02794 case T_CONST:
02795 buf = message ("%d", hp->value.ival);
02796 break;
02797
02798 case T_SPECLINE:
02799 {
02800 if (ip != NULL)
02801 {
02802 int line = ip->lineno;
02803 int col = ip->colno;
02804
02805 llassert (ip->cur != NULL);
02806 adjust_position (cppLineBase (ip), ip->cur, &line, &col);
02807
02808 buf = message ("%d", (int) line);
02809 }
02810 else
02811 {
02812 BADBRANCH;
02813 }
02814 }
02815 break;
02816
02817 case T_DATE:
02818 case T_TIME:
02819 {
02820 char *sbuf = (char *) dmalloc (20);
02821 timebuf = timestamp (pfile);
02822 if (hp->type == T_DATE)
02823 {
02824 sprintf (sbuf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
02825 timebuf->tm_mday, timebuf->tm_year + 1900);
02826 }
02827 else
02828 {
02829 sprintf (sbuf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
02830 timebuf->tm_sec);
02831 }
02832
02833 buf = cstring_fromCharsNew (sbuf);
02834 sfree (sbuf);
02835 break;
02836 }
02837
02838 case T_SPEC_DEFINED:
02839 buf = cstring_makeLiteral (" 0 ");
02840 ip = cppReader_getBuffer (pfile);
02841
02842 llassert (ip->cur != NULL);
02843 SKIP_WHITE_SPACE (ip->cur);
02844
02845 if (*ip->cur == '(')
02846 {
02847 paren++;
02848 ip->cur++;
02849 SKIP_WHITE_SPACE (ip->cur);
02850 }
02851
02852 if (!is_idstart[(int) *ip->cur])
02853 goto oops;
02854 if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
02855 goto oops;
02856
02857 if ((hp = cppReader_lookup (ip->cur, -1, -1)) != 0)
02858 {
02859 cstring_free (buf);
02860 buf = cstring_makeLiteral (" 1 ");
02861 }
02862
02863 while (is_idchar[(int) *ip->cur])
02864 {
02865 ++ip->cur;
02866 }
02867
02868 SKIP_WHITE_SPACE (ip->cur);
02869
02870 if (paren != 0)
02871 {
02872 if (*ip->cur != ')')
02873 goto oops;
02874 ++ip->cur;
02875 }
02876 break;
02877
02878 oops:
02879
02880 cppReader_errorLit (pfile,
02881 cstring_makeLiteralTemp ("`defined' without an identifier"));
02882 break;
02883
02884 default:
02885 cpp_setLocation (pfile);
02886 llfatalerror (message ("Pre-processing error: invalid special hash type"));
02887 }
02888
02889 len = size_fromInt (cstring_length (buf));
02890
02891 cppReader_reserve (pfile, len + 1);
02892 cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len);
02893 cppReader_nullTerminateQ (pfile);
02894
02895 cstring_free (buf);
02896 return;
02897 }
02898
02899
02900
02901
02902 static void
02903 dump_special_to_buffer (cppReader *pfile, char *macro_name)
02904 {
02905 static char define_directive[] = "#define ";
02906 size_t macro_name_length = strlen (macro_name);
02907 output_line_command (pfile, 0, same_file);
02908 cppReader_reserve (pfile, sizeof(define_directive) + macro_name_length);
02909 cppReader_putStrN (pfile, define_directive, sizeof(define_directive)-1);
02910 cppReader_putStrN (pfile, macro_name, macro_name_length);
02911 cppReader_putCharQ (pfile, ' ');
02912 cpp_expand_to_buffer (pfile, macro_name, macro_name_length);
02913 cppReader_putChar (pfile, '\n');
02914 }
02915
02916
02917
02918 static void
02919 cppReader_installBuiltin ( char *name, ctype ctyp,
02920 int len, enum node_type type,
02921 int ivalue, char *value,
02922 int hash)
02923 {
02924 cstring sname = cstring_fromCharsNew (name);
02925
02926 llassert (usymtab_inGlobalScope ());
02927
02928
02929
02930
02931
02932
02933 if (!usymtab_exists (sname))
02934 {
02935 uentry ue = uentry_makeConstant (sname, ctyp, fileloc_createBuiltin ());
02936
02937 if (ctype_equal (ctyp, ctype_string))
02938 {
02939 qualList ql = qualList_new ();
02940 ql = qualList_add (ql, QU_OBSERVER);
02941 uentry_reflectQualifiers (ue, ql);
02942 qualList_free (ql);
02943 }
02944
02945 usymtab_addGlobalEntry (ue);
02946 }
02947 else
02948 {
02949 ;
02950 }
02951
02952 (void) cppReader_install (name, len, type, ivalue, value, hash);
02953 cstring_free (sname);
02954 }
02955
02956 static void
02957 cppReader_installBuiltinType ( char *name, ctype ctyp,
02958 int len, enum node_type type,
02959 int ivalue,
02960 char *value, int hash)
02961 {
02962 cstring sname = cstring_fromChars (name);
02963
02964
02965 llassert (usymtab_inGlobalScope ());
02966
02967 if (!usymtab_exists (sname))
02968 {
02969 uentry ue = uentry_makeDatatype (sname, ctyp,
02970 NO, NO,
02971 fileloc_createBuiltin ());
02972 usymtab_addGlobalEntry (ue);
02973 }
02974
02975 (void) cppReader_install (name, len, type, ivalue, value, hash);
02976 }
02977
02978 static void
02979 initialize_builtins (cppReader *pfile)
02980 {
02981 cppReader_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);
02982 cppReader_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);
02983 cppReader_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);
02984 cppReader_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);
02985 cppReader_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);
02986 cppReader_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);
02987 #ifndef NO_BUILTIN_SIZE_TYPE
02988 cppReader_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);
02989 #endif
02990 #ifndef NO_BUILTIN_PTRDIFF_TYPE
02991 cppReader_installBuiltinType ("__PTRDIFF_TYPE__ ", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);
02992 #endif
02993 cppReader_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1);
02994 cppReader_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);
02995 cppReader_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);
02996 cppReader_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1);
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010 # ifdef WIN32
03011 cppReader_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
03012 # endif
03013
03014
03015
03016
03017
03018
03019
03020
03021 cppReader_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1);
03022
03023 if (CPPOPTIONS (pfile)->debug_output)
03024 {
03025 dump_special_to_buffer (pfile, "__BASE_FILE__");
03026 dump_special_to_buffer (pfile, "__VERSION__");
03027 #ifndef NO_BUILTIN_SIZE_TYPE
03028 dump_special_to_buffer (pfile, "__SIZE_TYPE__");
03029 #endif
03030 #ifndef NO_BUILTIN_PTRDIFF_TYPE
03031 dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
03032 #endif
03033 dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
03034 dump_special_to_buffer (pfile, "__DATE__");
03035 dump_special_to_buffer (pfile, "__TIME__");
03036 if (!cppReader_isTraditional (pfile))
03037 dump_special_to_buffer (pfile, "__STDC__");
03038 }
03039 }
03040
03041
03042
03043
03044
03045 static bool
03046 unsafe_chars (char c1, char c2)
03047 {
03048 switch (c1)
03049 {
03050 case '+': case '-':
03051 if (c2 == c1 || c2 == '=')
03052 return 1;
03053 goto letter;
03054 case '.':
03055 case '0': case '1': case '2': case '3': case '4':
03056 case '5': case '6': case '7': case '8': case '9':
03057 case 'e': case 'E': case 'p': case 'P':
03058 if (c2 == '-' || c2 == '+')
03059 return 1;
03060 goto letter;
03061 case 'L':
03062 if (c2 == '\'' || c2 == '\"')
03063 return 1;
03064 goto letter;
03065 letter:
03066 case '_':
03067 case 'a': case 'b': case 'c': case 'd': case 'f':
03068 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
03069 case 'm': case 'n': case 'o': case 'q': case 'r':
03070 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
03071 case 'y': case 'z':
03072 case 'A': case 'B': case 'C': case 'D': case 'F':
03073 case 'G': case 'H': case 'I': case 'J': case 'K':
03074 case 'M': case 'N': case 'O': case 'Q': case 'R':
03075 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
03076 case 'Y': case 'Z':
03077
03078 return (is_idchar[(int) c2] || c2 == '.');
03079 case '<': case '>': case '!': case '%': case '#': case ':':
03080 case '^': case '&': case '|': case '*': case '/': case '=':
03081 return (c2 == c1 || c2 == '=');
03082 }
03083 return 0;
03084 }
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094 static void
03095 macroexpand (cppReader *pfile, HASHNODE *hp)
03096 {
03097 int nargs;
03098 DEFINITION *defn = hp->value.defn;
03099 char *xbuf;
03100 char *oxbuf = NULL;
03101 int start_line;
03102 int start_column;
03103 size_t xbuf_len;
03104 size_t old_written = cppReader_getWritten (pfile);
03105 int rest_args;
03106 int rest_zero = 0;
03107 int i;
03108 struct argdata *args = NULL;
03109
03110 pfile->output_escapes++;
03111
03112 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
03113
03114 nargs = defn->nargs;
03115
03116 if (nargs >= 0)
03117 {
03118 enum cpp_token token = CPP_EOF;
03119
03120 args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));
03121
03122 for (i = 0; i < nargs; i++)
03123 {
03124 args[i].expanded = 0;
03125 args[i].raw = 0;
03126 args[i].raw_length = 0;
03127 args[i].expand_length = args[i].stringified_length = -1;
03128 args[i].use_count = 0;
03129 }
03130
03131
03132
03133
03134
03135
03136
03137
03138 i = 0;
03139 rest_args = 0;
03140
03141 cppReader_forward (pfile, 1);
03142 do
03143 {
03144 if (rest_args != 0)
03145 {
03146 continue;
03147 }
03148
03149 if (i < nargs || (nargs == 0 && i == 0))
03150 {
03151
03152 if (i == nargs - 1 && defn->rest_args)
03153 {
03154 rest_args = 1;
03155 }
03156
03157 args[i].raw = size_toLong (cppReader_getWritten (pfile));
03158 token = macarg (pfile, rest_args);
03159 args[i].raw_length = cppReader_getWritten (pfile) - args[i].raw;
03160 args[i].newlines = FALSE;
03161 }
03162 else
03163 {
03164 token = macarg (pfile, 0);
03165 }
03166
03167 if (token == CPP_EOF || token == CPP_POP)
03168 {
03169 cppReader_errorWithLine (pfile, start_line, start_column,
03170 cstring_fromCharsNew ("unterminated macro call"));
03171 sfree (args);
03172 return;
03173 }
03174 i++;
03175 } while (token == CPP_COMMA);
03176
03177
03178 if (i == 1)
03179 {
03180 char *bp;
03181 char *lim;
03182
03183 assertSet (args);
03184
03185 bp = ARG_BASE + args[0].raw;
03186 lim = bp + args[0].raw_length;
03187
03188
03189
03190
03191 if (nargs == 0)
03192 {
03193 while (bp != lim && is_space[(int) *bp])
03194 {
03195 bp++;
03196 }
03197 }
03198
03199 if (bp == lim)
03200 i = 0;
03201 }
03202
03203
03204
03205 rest_zero = 0;
03206
03207 if (nargs == 0 && i > 0)
03208 {
03209 cppReader_error (pfile,
03210 message ("arguments given to macro `%s'", hp->name));
03211 }
03212 else if (i < nargs)
03213 {
03214
03215 if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))
03216 {
03217 ;
03218 }
03219
03220 else if (i == nargs - 1 && defn->rest_args)
03221 rest_zero = 1;
03222 else if (i == 0)
03223 cppReader_error (pfile,
03224 message ("macro `%s' used without args", hp->name));
03225 else if (i == 1)
03226 cppReader_error (pfile,
03227 message ("macro `%s' used with just one arg", hp->name));
03228 else
03229 {
03230 cppReader_error (pfile,
03231 message ("macro `%s' used with only %d args",
03232 hp->name, i));
03233 }
03234 }
03235 else if (i > nargs)
03236 {
03237 cppReader_error (pfile,
03238 message ("macro `%s' used with too many (%d) args", hp->name, i));
03239 }
03240 else
03241 {
03242 ;
03243 }
03244 }
03245
03246
03247
03248
03249 if (nargs <= 0)
03250 {
03251 xbuf = defn->expansion;
03252 xbuf_len = defn->length;
03253 }
03254 else
03255 {
03256 char *exp = defn->expansion;
03257 int offset;
03258
03259 size_t totlen;
03260
03261 register struct reflist *ap, *last_ap;
03262
03263
03264
03265
03266
03267 xbuf_len = defn->length;
03268
03269 llassert (args != NULL);
03270
03271 for (ap = defn->pattern; ap != NULL; ap = ap->next)
03272 {
03273 if (ap->stringify)
03274 {
03275 struct argdata *arg = &args[ap->argno];
03276
03277
03278 assertSet (arg);
03279
03280 if (arg->stringified_length < 0)
03281 {
03282 int arglen = arg->raw_length;
03283 bool escaped = FALSE;
03284 char in_string = '\0';
03285 char c;
03286
03287
03288
03289
03290 int need_space = -1;
03291
03292 i = 0;
03293 arg->stringified = cppReader_getWritten (pfile);
03294 if (!cppReader_isTraditional (pfile))
03295 cppReader_putChar (pfile, '\"');
03296 for (; i < arglen; i++)
03297 {
03298 c = (ARG_BASE + arg->raw)[i];
03299
03300 if (in_string == '\0')
03301 {
03302
03303
03304 if (is_space[(int) c])
03305 {
03306 if (cppReader_getWritten (pfile) > arg->stringified
03307 && (cppReader_getPWritten (pfile))[-1] == '@')
03308 {
03309
03310 cppReader_adjustWritten (pfile, -1);
03311 continue;
03312 }
03313 if (need_space == 0)
03314 need_space = 1;
03315 continue;
03316 }
03317 else if (need_space > 0)
03318 cppReader_putChar (pfile, ' ');
03319 else
03320 {
03321 ;
03322 }
03323
03324 need_space = 0;
03325 }
03326
03327 if (escaped)
03328 escaped = 0;
03329 else
03330 {
03331 if (c == '\\')
03332 escaped = 1;
03333
03334 if (in_string != '\0')
03335 {
03336 if (c == in_string)
03337 in_string = '\0';
03338 }
03339 else if (c == '\"' || c == '\'')
03340 {
03341 in_string = c;
03342 }
03343 else
03344 {
03345 ;
03346 }
03347 }
03348
03349
03350 if (c == '\"' || (in_string != '\0' && c == '\\'))
03351 cppReader_putChar (pfile, '\\');
03352 if (isprint (c))
03353 cppReader_putChar (pfile, c);
03354 else
03355 {
03356 cppReader_reserve (pfile, 4);
03357 sprintf (cppReader_getPWritten (pfile), "\\%03o",
03358 (unsigned int) c);
03359 cppReader_adjustWritten (pfile, 4);
03360 }
03361 }
03362 if (!cppReader_isTraditional (pfile))
03363 cppReader_putChar (pfile, '\"');
03364 arg->stringified_length
03365 = size_toInt (cppReader_getWritten (pfile) - arg->stringified);
03366 }
03367
03368 xbuf_len += args[ap->argno].stringified_length;
03369 }
03370 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
03371 {
03372
03373
03374 xbuf_len += args[ap->argno].raw_length + 4;
03375 }
03376 else
03377 {
03378
03379
03380
03381 if (args[ap->argno].expand_length < 0)
03382 {
03383 args[ap->argno].expanded = cppReader_getWritten (pfile);
03384 cpp_expand_to_buffer (pfile,
03385 ARG_BASE + args[ap->argno].raw,
03386 size_fromInt (args[ap->argno].raw_length));
03387
03388 args[ap->argno].expand_length
03389 = size_toInt (cppReader_getWritten (pfile) - args[ap->argno].expanded);
03390 }
03391
03392
03393
03394 xbuf_len += args[ap->argno].expand_length + 4;
03395 }
03396 if (args[ap->argno].use_count < 10)
03397 args[ap->argno].use_count++;
03398 }
03399
03400 xbuf = (char *) dmalloc (xbuf_len + 1);
03401 oxbuf = xbuf;
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411 offset = 0;
03412 totlen = 0;
03413
03414 for (last_ap = NULL, ap = defn->pattern; ap != NULL;
03415 last_ap = ap, ap = ap->next)
03416 {
03417 register struct argdata *arg = &args[ap->argno];
03418 size_t count_before = totlen;
03419
03420
03421 for (i = 0; i < ap->nchars; i++, offset++)
03422 {
03423 xbuf[totlen++] = exp[offset];
03424 }
03425
03426
03427
03428 if (rest_zero && totlen > count_before
03429 && ((ap->rest_args && ap->raw_before)
03430 || (last_ap != NULL && last_ap->rest_args
03431 && last_ap->raw_after)))
03432 {
03433
03434 while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])
03435 {
03436 totlen--;
03437 }
03438
03439
03440 while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])
03441 {
03442 totlen--;
03443 }
03444 }
03445
03446 if (ap->stringify != 0)
03447 {
03448 assertSet(arg);
03449 memcpy (xbuf + totlen,
03450 ARG_BASE + arg->stringified,
03451 size_fromInt (arg->stringified_length));
03452 totlen += arg->stringified_length;
03453 }
03454 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
03455 {
03456 char *p1;
03457 char *l1;
03458
03459 assertSet (arg);
03460
03461 p1 = ARG_BASE + arg->raw;
03462 l1 = p1 + arg->raw_length;
03463
03464 if (ap->raw_before)
03465 {
03466 while (p1 != l1 && is_space[(int) *p1])
03467 {
03468 p1++;
03469 }
03470
03471 while (p1 != l1 && is_idchar[(int) *p1])
03472 {
03473 xbuf[totlen++] = *p1++;
03474 }
03475
03476
03477
03478
03479 if (p1[0] == '@' && p1[1] == '-')
03480 p1 += 2;
03481 }
03482 if (ap->raw_after)
03483 {
03484
03485
03486 while (p1 != l1)
03487 {
03488 if (is_space[(int) l1[-1]]) l1--;
03489 else if (l1[-1] == '-')
03490 {
03491 char *p2 = l1 - 1;
03492
03493
03494 while (p2 != p1 && p2[-1] == '\n')
03495 {
03496 p2--;
03497 }
03498
03499 if (((l1 - 1 - p2) & 1) != 0)
03500 {
03501 l1 -= 2;
03502 }
03503 else
03504 {
03505 break;
03506 }
03507 }
03508 else
03509 {
03510 break;
03511 }
03512 }
03513 }
03514
03515 memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));
03516 totlen += l1 - p1;
03517 }
03518 else
03519 {
03520 char *expanded;
03521
03522 assertSet (arg);
03523 expanded = ARG_BASE + arg->expanded;
03524
03525 if (!ap->raw_before && totlen > 0
03526 && (arg->expand_length != 0)
03527 && !cppReader_isTraditional(pfile)
03528 && unsafe_chars (xbuf[totlen-1], expanded[0]))
03529 {
03530 xbuf[totlen++] = '@';
03531 xbuf[totlen++] = ' ';
03532 }
03533
03534 memcpy (xbuf + totlen, expanded,
03535 size_fromInt (arg->expand_length));
03536 totlen += arg->expand_length;
03537
03538 if (!ap->raw_after && totlen > 0
03539 && offset < size_toInt (defn->length)
03540 && !cppReader_isTraditional(pfile)
03541 && unsafe_chars (xbuf[totlen-1], exp[offset]))
03542 {
03543 xbuf[totlen++] = '@';
03544 xbuf[totlen++] = ' ';
03545 }
03546
03547
03548
03549
03550
03551 if (arg->use_count > 1 && arg->newlines > 0)
03552 {
03553
03554
03555 arg->use_count = 1;
03556 arg->expand_length
03557 = change_newlines (expanded, arg->expand_length);
03558 }
03559 }
03560
03561 if (totlen > xbuf_len)
03562 abort ();
03563 }
03564
03565
03566
03567
03568 for (i = offset; i < size_toInt (defn->length); i++)
03569 {
03570
03571 if (exp[i] == ')')
03572 rest_zero = 0;
03573 if (! (rest_zero && last_ap != NULL && last_ap->rest_args
03574 && last_ap->raw_after))
03575 xbuf[totlen++] = exp[i];
03576 }
03577
03578 xbuf[totlen] = '\0';
03579 xbuf_len = totlen;
03580 }
03581
03582 pfile->output_escapes--;
03583
03584
03585
03586 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
03587 cppReader_getBuffer (pfile)->has_escapes = 1;
03588
03589
03590 cppReader_setWritten (pfile, old_written);
03591
03592
03593
03594
03595
03596 if (!cppReader_isTraditional (pfile))
03597 hp->type = T_DISABLED;
03598
03599 sfree (args);
03600 }
03601
03602 static void
03603 push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
03604 HASHNODE *hp)
03605 {
03606 cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);
03607
03608 if (mbuf == NULL)
03609 {
03610 return;
03611 }
03612
03613 mbuf->cleanup = cppReader_macroCleanup;
03614
03615 llassert (mbuf->hnode == NULL);
03616 mbuf->hnode = hp;
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636 if (xbuf[0] == '@' && xbuf[1] == ' '
03637 && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
03638 || xbuf[2] == '\"'))
03639 {
03640 llassert (mbuf->cur != NULL);
03641 mbuf->cur += 2;
03642 }
03643 }
03644
03645
03646
03647
03648
03649 static enum cpp_token
03650 get_directive_token (cppReader *pfile)
03651 {
03652 for (;;)
03653 {
03654 size_t old_written = cppReader_getWritten (pfile);
03655 enum cpp_token token;
03656 cppSkipHspace (pfile);
03657 if (cppReader_peekC (pfile) == '\n')
03658 {
03659 return CPP_VSPACE;
03660 }
03661
03662 token = cppGetToken (pfile);
03663
03664 switch (token)
03665 {
03666 case CPP_POP:
03667 if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))
03668 return token;
03669
03670 case CPP_HSPACE:
03671 case CPP_COMMENT:
03672 cppReader_setWritten (pfile, old_written);
03673 break;
03674 default:
03675 return token;
03676 }
03677 }
03678 }
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689 static int
03690 do_include (cppReader *pfile, struct directive *keyword,
03691 char *unused1, char *unused2)
03692 {
03693 bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);
03694 cstring fname;
03695 char *fbeg, *fend;
03696 enum cpp_token token;
03697
03698
03699 struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
03700 struct file_name_list dsp[1];
03701 struct file_name_list *searchptr = NULL;
03702 size_t old_written = cppReader_getWritten (pfile);
03703
03704 int flen;
03705
03706 int f;
03707 int angle_brackets = 0;
03708 f= -1;
03709
03710 pfile->parsing_include_directive++;
03711 token = get_directive_token (pfile);
03712 pfile->parsing_include_directive--;
03713
03714 if (token == CPP_STRING)
03715 {
03716
03717 fbeg = pfile->token_buffer + old_written + 1;
03718 fend = cppReader_getPWritten (pfile) - 1;
03719 if (fbeg[-1] == '<')
03720 {
03721 angle_brackets = 1;
03722
03723 if (CPPOPTIONS (pfile)->first_bracket_include != NULL)
03724 search_start = CPPOPTIONS (pfile)->first_bracket_include;
03725 }
03726
03727 else if (!CPPOPTIONS (pfile)->ignore_srcdir)
03728 {
03729 cppBuffer *fp = CPPBUFFER (pfile);
03730
03731
03732
03733 for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
03734 {
03735 int n;
03736 char *ep,*nam;
03737
03738 llassert (fp != NULL);
03739
03740 nam = NULL;
03741
03742 if (cstring_isDefined (fp->nominal_fname))
03743 {
03744 nam = cstring_toCharsSafe (fp->nominal_fname);
03745
03746
03747
03748 dsp[0].next = search_start;
03749 search_start = dsp;
03750
03751 #ifndef VMS
03752 ep = strrchr (nam, CONNECTCHAR);
03753 #else
03754 ep = strrchr (nam, ']');
03755 if (ep == NULL) ep = strrchr (nam, '>');
03756 if (ep == NULL) ep = strrchr (nam, ':');
03757 if (ep != NULL) ep++;
03758 #endif
03759 if (ep != NULL)
03760 {
03761 char save;
03762
03763 n = ep - nam;
03764 save = nam[n];
03765 nam[n] = '\0';
03766
03767
03768 dsp[0].fname = cstring_fromCharsNew (nam);
03769
03770 nam[n] = save;
03771
03772 if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len)
03773 pfile->max_include_len = n + INCLUDE_LEN_FUDGE;
03774 }
03775 else
03776 {
03777 dsp[0].fname = cstring_undefined;
03778 }
03779
03780 dsp[0].got_name_map = 0;
03781 break;
03782 }
03783 }
03784 }
03785 else
03786 {
03787 ;
03788 }
03789 }
03790 #ifdef VMS
03791 else if (token == CPP_NAME)
03792 {
03793
03794
03795
03796
03797
03798 cppReader_warning (pfile,
03799 "VAX-C-style include specification found, use '#include <filename.h>' !");
03800 angle_brackets = 1;
03801
03802 if (CPPOPTIONS (pfile)->first_bracket_include)
03803 search_start = CPPOPTIONS (pfile)->first_bracket_include;
03804 fbeg = pfile->token_buffer + old_written;
03805 fend = cppReader_getPWritten (pfile);
03806 }
03807 #endif
03808 else
03809 {
03810 cppReader_error (pfile,
03811 message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",
03812 keyword->name));
03813
03814 cppReader_setWritten (pfile, old_written);
03815 cppReader_skipRestOfLine (pfile);
03816 return 0;
03817 }
03818
03819 *fend = 0;
03820
03821 token = get_directive_token (pfile);
03822 if (token != CPP_VSPACE)
03823 {
03824 cppReader_errorLit (pfile,
03825 cstring_makeLiteralTemp ("Junk at end of #include"));
03826
03827 while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
03828 {
03829 token = get_directive_token (pfile);
03830 }
03831 }
03832
03833
03834
03835
03836
03837
03838 if (skip_dirs)
03839 {
03840 cppBuffer *fp = CPPBUFFER (pfile);
03841
03842 for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
03843 {
03844 llassert (fp != NULL);
03845
03846 if (fp->fname != NULL)
03847 {
03848
03849
03850 if (fp->dir == SELF_DIR_DUMMY)
03851 {
03852 search_start = CPPOPTIONS (pfile)->include;
03853 }
03854 else if (fp->dir != NULL)
03855 {
03856 search_start = fp->dir->next;
03857 }
03858 else
03859 {
03860 ;
03861 }
03862
03863 break;
03864 }
03865 }
03866 }
03867
03868 cppReader_setWritten (pfile, old_written);
03869
03870 flen = fend - fbeg;
03871
03872 DPRINTF (("fbeg: %s", fbeg));
03873
03874 if (flen == 0)
03875 {
03876 cppReader_error (pfile,
03877 message ("Empty file name in #%s", keyword->name));
03878 return 0;
03879 }
03880
03881
03882
03883
03884
03885
03886 fname = cstring_undefined;
03887
03888
03889
03890
03891
03892
03893 if (osd_isConnectChar (*fbeg)
03894 # if defined (WIN32) || defined (OS2)
03895 || (*(fbeg + 1) == ':')
03896 # endif
03897 )
03898 {
03899 fname = cstring_copyLength (fbeg, flen);
03900
03901 if (redundant_include_p (pfile, fname))
03902 {
03903 cstring_free (fname);
03904 return 0;
03905 }
03906
03907 f = open_include_file (pfile, fname, NULL);
03908
03909 if (f == IMPORT_FOUND)
03910 {
03911 return 0;
03912 }
03913 }
03914 else
03915 {
03916
03917
03918
03919 for (searchptr = search_start; searchptr != NULL;
03920 searchptr = searchptr->next)
03921 {
03922 if (!cstring_isEmpty (searchptr->fname))
03923 {
03924
03925
03926
03927 if (cstring_isEmpty (searchptr->fname))
03928 continue;
03929
03930 fname = cstring_copy (searchptr->fname);
03931 fname = cstring_appendChar (fname, CONNECTCHAR);
03932 DPRINTF (("Here: %s", fname));
03933 }
03934 else
03935 {
03936 ;
03937 }
03938
03939 fname = cstring_concatLength (fname, fbeg, flen);
03940
03941 DPRINTF (("fname: %s", fname));
03942
03943 #ifdef VMS
03944
03945
03946 if (searchptr->fname && (searchptr->fname[0] != 0)) {
03947
03948 hack_vms_include_specification (fname);
03949 } else {
03950
03951 strncpy (fname, fbeg, flen);
03952 fname[flen] = 0;
03953
03954 if (strchr (fname,'.') == NULL) {
03955 strcat (fname, ".h");
03956 }
03957 }
03958 #endif
03959
03960
03961
03962
03963 if (redundant_include_p (pfile, fname))
03964 {
03965 cstring_free (fname);
03966 return 0;
03967 }
03968
03969 DPRINTF (("Trying: %s", fname));
03970
03971 f = open_include_file (pfile, fname, searchptr);
03972
03973 if (f == IMPORT_FOUND)
03974 {
03975 return 0;
03976 }
03977 #ifdef EACCES
03978 else if (f == IMPORT_NOT_FOUND && errno == EACCES)
03979 {
03980 cppReader_warning (pfile,
03981 message ("Header file %s exists, but is not readable", fname));
03982 }
03983 #endif
03984
03985 if (f >= 0)
03986 {
03987 break;
03988 }
03989 }
03990 }
03991
03992 if (f < 0)
03993 {
03994
03995 fname = cstring_copyLength (fbeg, flen);
03996
03997 if (search_start != NULL)
03998 {
03999 cppReader_error (pfile,
04000 message ("Cannot find include file %s", fname));
04001 }
04002 else
04003 {
04004 cppReader_error (pfile,
04005 message ("No include path in which to find %s", fname));
04006 }
04007 }
04008 else {
04009
04010
04011
04012
04013
04014 struct file_name_list *ptr;
04015
04016 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
04017 {
04018 if (cstring_equal (ptr->fname, fname))
04019 {
04020
04021 break;
04022 }
04023 }
04024
04025 if (ptr == NULL)
04026 {
04027
04028
04029
04030 ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));
04031 ptr->control_macro = NULL;
04032 ptr->c_system_include_path = NULL;
04033 ptr->next = pfile->all_include_files;
04034 ptr->fname = fname;
04035 ptr->got_name_map = NULL;
04036
04037 pfile->all_include_files = ptr;
04038 assertSet (pfile->all_include_files);
04039 }
04040
04041 if (angle_brackets != 0)
04042 {
04043 pfile->system_include_depth++;
04044 }
04045
04046
04047 if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)
04048 {
04049 cstring_free (fname);
04050 return 0;
04051 }
04052
04053 if (finclude (pfile, f, fname, is_system_include (pfile, fname),
04054 searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
04055 {
04056 output_line_command (pfile, 0, enter_file);
04057 pfile->only_seen_white = 2;
04058 }
04059
04060 if (angle_brackets)
04061 {
04062 pfile->system_include_depth--;
04063 }
04064
04065 }
04066
04067 return 0;
04068 }
04069
04070
04071
04072
04073
04074 static bool
04075 redundant_include_p (cppReader *pfile, cstring name)
04076 {
04077 struct file_name_list *l = pfile->all_include_files;
04078
04079 for (; l != NULL; l = l->next)
04080 {
04081 if (cstring_equal (name, l->fname)
04082 && (l->control_macro != NULL)
04083 && (cppReader_lookup (l->control_macro, -1, -1) != NULL))
04084 {
04085 return TRUE;
04086 }
04087 }
04088
04089 return FALSE;
04090 }
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103 static bool
04104 is_system_include (cppReader *pfile, cstring filename)
04105 {
04106 struct file_name_list *searchptr;
04107
04108 for (searchptr = CPPOPTIONS (pfile)->first_system_include;
04109 searchptr != NULL;
04110 searchptr = searchptr->next)
04111 {
04112 if (!cstring_isEmpty (searchptr->fname)) {
04113 cstring sys_dir = searchptr->fname;
04114 int length = cstring_length (sys_dir);
04115
04116 if (cstring_equalLen (sys_dir, filename, length)
04117 && osd_isConnectChar (cstring_getChar (filename, length)))
04118 {
04119 if (searchptr->c_system_include_path)
04120 return 2;
04121 else
04122 return 1;
04123 }
04124 }
04125 }
04126
04127 return 0;
04128 }
04129
04130
04131
04132
04133
04134
04135
04136 static char *
04137 convert_string (cppReader *pfile, char *result,
04138 char *in, char *limit, int handle_escapes)
04139 {
04140 char c;
04141 c = *in++;
04142
04143 if (c != '\"')
04144 {
04145 return NULL;
04146 }
04147
04148 while (in < limit)
04149 {
04150 c = *in++;
04151
04152 switch (c)
04153 {
04154 case '\0':
04155 return NULL;
04156 case '\"':
04157 limit = in;
04158 break;
04159 case '\\':
04160 if (handle_escapes)
04161 {
04162 char *bpc = (char *) in;
04163 int i = (char) cppReader_parseEscape (pfile, &bpc);
04164 in = (char *) bpc;
04165 if (i >= 0)
04166 *result++ = (char) c;
04167 break;
04168 }
04169
04170
04171 default:
04172 *result++ = c;
04173 }
04174 }
04175
04176 *result = 0;
04177 return result;
04178 }
04179
04180
04181
04182
04183
04184
04185
04186 #define FNAME_HASHSIZE 37
04187
04188 static int
04189 do_line (cppReader *pfile, struct directive *keyword)
04190 {
04191 cppBuffer *ip = cppReader_getBuffer (pfile);
04192 int new_lineno;
04193 size_t old_written = cppReader_getWritten (pfile);
04194 enum file_change_code file_change = same_file;
04195 enum cpp_token token;
04196
04197 token = get_directive_token (pfile);
04198
04199 if (token != CPP_NUMBER
04200 || !isdigit(pfile->token_buffer[old_written]))
04201 {
04202 cppReader_errorLit (pfile,
04203 cstring_makeLiteralTemp ("invalid format `#line' command"));
04204
04205 goto bad_line_directive;
04206 }
04207
04208
04209
04210
04211 new_lineno = atoi (pfile->token_buffer + old_written) - 1;
04212 cppReader_setWritten (pfile, old_written);
04213
04214
04215 if (cppReader_isPedantic (pfile) && new_lineno < 0)
04216 cppReader_pedwarnLit (pfile,
04217 cstring_makeLiteralTemp ("line number out of range in `#line' command"));
04218
04219 token = get_directive_token (pfile);
04220
04221 if (token == CPP_STRING) {
04222 char *fname = pfile->token_buffer + old_written;
04223 char *end_name;
04224 static HASHNODE *fname_table[FNAME_HASHSIZE];
04225 HASHNODE *hp, **hash_bucket;
04226 char *p;
04227 size_t num_start;
04228 int fname_length;
04229
04230
04231
04232 end_name = convert_string (pfile, fname, fname, cppReader_getPWritten (pfile), 1);
04233 if (end_name == NULL)
04234 {
04235 cppReader_errorLit (pfile,
04236 cstring_makeLiteralTemp ("invalid format `#line' command"));
04237 goto bad_line_directive;
04238 }
04239
04240 fname_length = end_name - fname;
04241 num_start = cppReader_getWritten (pfile);
04242
04243 token = get_directive_token (pfile);
04244 if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
04245 p = pfile->token_buffer + num_start;
04246 if (cppReader_isPedantic (pfile))
04247 cppReader_pedwarnLit (pfile,
04248 cstring_makeLiteralTemp ("garbage at end of `#line' command"));
04249
04250 if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
04251 {
04252 cppReader_errorLit (pfile,
04253 cstring_makeLiteralTemp ("invalid format `#line' command"));
04254 goto bad_line_directive;
04255 }
04256 if (*p == '1')
04257 file_change = enter_file;
04258 else if (*p == 2)
04259 file_change = leave_file;
04260 else if (*p == 3)
04261 ip->system_header_p = 1;
04262 else
04263 ip->system_header_p = 2;
04264
04265 cppReader_setWritten (pfile, num_start);
04266 token = get_directive_token (pfile);
04267 p = pfile->token_buffer + num_start;
04268 if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
04269 ip->system_header_p = *p == 3 ? 1 : 2;
04270 token = get_directive_token (pfile);
04271 }
04272 if (token != CPP_VSPACE) {
04273 cppReader_errorLit (pfile,
04274 cstring_makeLiteralTemp ("invalid format `#line' command"));
04275
04276 goto bad_line_directive;
04277 }
04278 }
04279
04280 hash_bucket =
04281 &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
04282 for (hp = *hash_bucket; hp != NULL; hp = hp->next)
04283 {
04284 if (hp->length == fname_length &&
04285 strncmp (hp->value.cpval, fname, size_fromInt (fname_length)) == 0) {
04286 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
04287 break;
04288 }
04289 }
04290
04291 if (hp == 0) {
04292
04293 hp = (HASHNODE *) dmalloc (sizeof (*hp) + fname_length + 1);
04294
04295 hp->prev = NULL;
04296 hp->bucket_hdr = NULL;
04297 hp->type = T_NONE;
04298 hp->name = cstring_undefined;
04299 hp->next = *hash_bucket;
04300
04301 *hash_bucket = hp;
04302
04303 hp->length = fname_length;
04304 hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
04305 memcpy (hp->value.cpval, fname, size_fromInt (fname_length));
04306 hp->value.cpval[fname_length] = '\0';
04307 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
04308 }
04309 }
04310 else if (token != CPP_VSPACE && token != CPP_EOF)
04311 {
04312 cppReader_errorLit (pfile,
04313 cstring_makeLiteralTemp ("invalid format `#line' command"));
04314 goto bad_line_directive;
04315 }
04316 else
04317 {
04318 ;
04319 }
04320
04321 ip->lineno = new_lineno;
04322 bad_line_directive:
04323 cppReader_skipRestOfLine (pfile);
04324 cppReader_setWritten (pfile, old_written);
04325 output_line_command (pfile, 0, file_change);
04326 return 0;
04327 }
04328
04329
04330
04331
04332
04333
04334
04335 static int
04336 do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
04337 {
04338
04339 int sym_length;
04340 HASHNODE *hp;
04341 char *orig_buf = buf;
04342
04343 SKIP_WHITE_SPACE (buf);
04344
04345 sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
04346
04347 while ((hp = cppReader_lookup (buf, sym_length, -1)) != NULL)
04348 {
04349
04350
04351 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
04352 {
04353 pass_thru_directive (orig_buf, limit, pfile, keyword);
04354 }
04355
04356 if (hp->type != T_MACRO)
04357 {
04358 cppReader_warning (pfile,
04359 message ("Undefining preprocessor builtin: %s",
04360 hp->name));
04361 }
04362
04363 cppReader_deleteMacro (hp);
04364 }
04365
04366 if (cppReader_isPedantic (pfile)) {
04367 buf += sym_length;
04368 SKIP_WHITE_SPACE (buf);
04369 if (buf != limit)
04370 {
04371 cppReader_pedwarnLit (pfile,
04372 cstring_makeLiteralTemp ("garbage after `#undef' directive"));
04373 }
04374 }
04375
04376 return 0;
04377 }
04378
04379
04380
04381
04382
04383
04384
04385
04386 static int
04387 do_error (cppReader *pfile, struct directive *keyword,
04388 char *buf, char *limit)
04389 {
04390 int length = limit - buf;
04391 cstring copy = cstring_copyLength (buf, length);
04392 cstring adv = cstring_advanceWhiteSpace (copy);
04393
04394 cppReader_error (pfile, message ("#error %s", adv));
04395 cstring_free (copy);
04396 return 0;
04397 }
04398
04399
04400
04401
04402
04403
04404
04405 static int
04406 do_warning (cppReader *pfile, struct directive *keyword,
04407 char *buf, char *limit)
04408 {
04409 int length = limit - buf;
04410 cstring copy = cstring_copyLength (buf, length);
04411 cstring adv = cstring_advanceWhiteSpace (copy);
04412 cppReader_warning (pfile, message ("#warning %s", adv));
04413 cstring_free (copy);
04414 return 0;
04415 }
04416
04417
04418
04419
04420 static int
04421 do_ident (cppReader *pfile, struct directive *keyword,
04422 char *buf, char *limit)
04423 {
04424
04425 if (cppReader_isPedantic (pfile) && !cppReader_getBuffer (pfile)->system_header_p)
04426 cppReader_pedwarnLit (pfile,
04427 cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
04428
04429
04430
04431 return 0;
04432 }
04433
04434
04435
04436
04437 static int
04438 do_pragma (cppReader *pfile, struct directive *keyword,
04439 char *buf, char *limit)
04440 {
04441 while (*buf == ' ' || *buf == '\t')
04442 {
04443 buf++;
04444 }
04445
04446 if (!strncmp (buf, "implementation", 14)) {
04447
04448
04449 struct file_name_list *ptr;
04450 char *p = buf + 14, *fname, *inc_fname;
04451 int fname_len;
04452 SKIP_WHITE_SPACE (p);
04453 if (*p == '\n' || *p != '\"')
04454 return 0;
04455
04456 fname = p + 1;
04457 p = (char *) strchr (fname, '\"');
04458 fname_len = p != NULL ? p - fname : mstring_length (fname);
04459
04460 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
04461 {
04462 inc_fname = (char *) strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);
04463 inc_fname = (inc_fname != NULL)
04464 ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
04465
04466 if ((inc_fname != NULL)
04467 && (strncmp (inc_fname, fname, size_fromInt (fname_len)) == 0))
04468 {
04469 cpp_setLocation (pfile);
04470
04471 ppllerror (message ("`#pragma implementation' for `%s' appears "
04472 "after file is included",
04473 cstring_fromChars (fname)));
04474 }
04475 }
04476 }
04477
04478 return 0;
04479 }
04480
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494 static int
04495 do_if (cppReader *pfile, struct directive *keyword,
04496 char *buf, char *limit)
04497 {
04498 HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
04499 conditional_skip (pfile, value == 0, T_IF, NULL);
04500 return 0;
04501 }
04502
04503
04504
04505
04506
04507
04508 static int do_elif (cppReader *pfile, struct directive *keyword,
04509 char *buf, char *limit)
04510 {
04511 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
04512 {
04513 cppReader_errorLit (pfile,
04514 cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
04515 return 0;
04516 }
04517 else
04518 {
04519 llassert (pfile->if_stack != NULL);
04520
04521 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
04522 {
04523 cppReader_errorLit (pfile,
04524 cstring_makeLiteralTemp ("`#elif' after `#else'"));
04525
04526 if (pfile->if_stack->fname != NULL
04527 && cppReader_getBuffer (pfile)->fname != NULL
04528 && !cstring_equal (pfile->if_stack->fname,
04529 cppReader_getBuffer (pfile)->nominal_fname))
04530 fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
04531 fprintf (stderr, ")\n");
04532 }
04533 pfile->if_stack->type = T_ELIF;
04534 }
04535
04536 if (pfile->if_stack->if_succeeded)
04537 {
04538 skip_if_group (pfile, 0);
04539 }
04540 else
04541 {
04542 HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
04543 if (value == 0)
04544 skip_if_group (pfile, 0);
04545 else
04546 {
04547 ++pfile->if_stack->if_succeeded;
04548 output_line_command (pfile, 1, same_file);
04549 }
04550 }
04551
04552 return 0;
04553 }
04554
04555
04556
04557
04558
04559
04560 static HOST_WIDE_INT
04561 eval_if_expression (cppReader *pfile,
04562 char *buf,
04563 int length)
04564 {
04565 HASHNODE *save_defined;
04566 HOST_WIDE_INT value;
04567 size_t old_written = cppReader_getWritten (pfile);
04568
04569 save_defined = cppReader_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
04570 pfile->pcp_inside_if = 1;
04571
04572 value = cppReader_parseExpression (pfile);
04573 pfile->pcp_inside_if = 0;
04574
04575
04576 cppReader_deleteMacro (save_defined);
04577
04578 cppReader_setWritten (pfile, old_written);
04579
04580 return value;
04581 }
04582
04583
04584
04585
04586
04587
04588
04589 static int
04590 do_xifdef (cppReader *pfile, struct directive *keyword,
04591 char *unused1, char *unused2)
04592 {
04593 int skip;
04594 cppBuffer *ip = cppReader_getBuffer (pfile);
04595 char *ident;
04596 int ident_length;
04597 enum cpp_token token;
04598 int start_of_file = 0;
04599 char *control_macro = 0;
04600 size_t old_written = cppReader_getWritten (pfile);
04601
04602 DPRINTF (("do xifdef: %d",
04603 keyword->type == T_IFNDEF));
04604
04605
04606 if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)
04607 {
04608 start_of_file = pfile->only_seen_white == 2;
04609 }
04610
04611 pfile->no_macro_expand++;
04612 token = get_directive_token (pfile);
04613 pfile->no_macro_expand--;
04614
04615 ident = pfile->token_buffer + old_written;
04616 ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);
04617 cppReader_setWritten (pfile, old_written);
04618
04619 if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
04620 {
04621 skip = (keyword->type == T_IFDEF);
04622 if (! cppReader_isTraditional (pfile))
04623 {
04624 cppReader_pedwarn (pfile,
04625 message ("`#%s' with no argument", keyword->name));
04626 }
04627 }
04628 else if (token == CPP_NAME)
04629 {
04630 HASHNODE *hp = cppReader_lookup (ident, ident_length, -1);
04631 skip = (keyword->type == T_IFDEF)
04632 ? (hp == NULL) : (hp != NULL);
04633
04634 DPRINTF (("hp null: %d / %d / %d",
04635 (hp == NULL),
04636 (keyword->type == T_IFNDEF),
04637 skip));
04638
04639 if (start_of_file && !skip)
04640 {
04641 DPRINTF (("Not skipping!"));
04642 control_macro = (char *) dmalloc (size_fromInt (ident_length + 1));
04643 memcpy (control_macro, ident, size_fromInt (ident_length + 1));
04644 }
04645 }
04646 else
04647 {
04648 skip = (keyword->type == T_IFDEF);
04649 if (! cppReader_isTraditional (pfile))
04650 {
04651 cppReader_error (pfile,
04652 message ("`#%s' with invalid argument", keyword->name));
04653 }
04654 }
04655
04656 if (!cppReader_isTraditional (pfile))
04657 {
04658 int c;
04659 cppSkipHspace (pfile);
04660 c = cppReader_peekC (pfile);
04661 if (c != EOF && c != '\n')
04662 {
04663 cppReader_pedwarn (pfile,
04664 message ("garbage at end of `#%s' argument", keyword->name));
04665 }
04666 }
04667
04668 cppReader_skipRestOfLine (pfile);
04669
04670 DPRINTF (("Conditional skip: %d", skip));
04671 conditional_skip (pfile, skip, T_IF, control_macro);
04672 return 0;
04673 }
04674
04675
04676
04677
04678
04679
04680 static void
04681 conditional_skip (cppReader *pfile, int skip,
04682 enum node_type type,
04683 char *control_macro)
04684 {
04685 cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
04686
04687 temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
04688 temp->next = pfile->if_stack;
04689 temp->control_macro = control_macro;
04690 temp->lineno = 0;
04691 temp->if_succeeded = 0;
04692
04693 pfile->if_stack = temp;
04694 pfile->if_stack->type = type;
04695
04696 if (skip != 0)
04697 {
04698 skip_if_group (pfile, 0);
04699 return;
04700 }
04701 else
04702 {
04703 ++pfile->if_stack->if_succeeded;
04704 output_line_command (pfile, 1, same_file);
04705 }
04706 }
04707
04708
04709
04710
04711
04712
04713
04714 static void
04715 skip_if_group (cppReader *pfile, int any)
04716 {
04717 int c;
04718 struct directive *kt;
04719 cppIfStackFrame *save_if_stack = pfile->if_stack;
04720 register int ident_length;
04721 char *ident;
04722 struct parse_marker line_start_mark;
04723
04724 parseSetMark (&line_start_mark, pfile);
04725
04726 if (CPPOPTIONS (pfile)->output_conditionals) {
04727 static char failed[] = "#failed\n";
04728 cppReader_puts (pfile, failed, sizeof(failed)-1);
04729 pfile->lineno++;
04730 output_line_command (pfile, 1, same_file);
04731 }
04732
04733 beg_of_line:
04734 if (CPPOPTIONS (pfile)->output_conditionals)
04735 {
04736 cppBuffer *pbuf = cppReader_getBuffer (pfile);
04737 char *start_line;
04738
04739 llassert (pbuf->buf != NULL);
04740
04741 start_line = pbuf->buf + line_start_mark.position;
04742 cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));
04743 }
04744
04745 parseMoveMark (&line_start_mark, pfile);
04746
04747 if (!cppReader_isTraditional (pfile))
04748 {
04749 cppSkipHspace (pfile);
04750 }
04751
04752 c = cppReader_getC (pfile);
04753 if (c == '#')
04754 {
04755 size_t old_written = cppReader_getWritten (pfile);
04756 cppSkipHspace (pfile);
04757
04758 parse_name (pfile, cppReader_getC (pfile));
04759 ident_length = size_toInt (cppReader_getWritten (pfile) - old_written);
04760 ident = pfile->token_buffer + old_written;
04761 pfile->limit = ident;
04762
04763 for (kt = directive_table; kt->length >= 0; kt++)
04764 {
04765 cppIfStackFrame *temp;
04766 if (ident_length == kt->length
04767 && cstring_equalPrefix (kt->name, ident))
04768 {
04769
04770 if (any)
04771 {
04772 goto done;
04773 }
04774
04775 switch (kt->type)
04776 {
04777 case T_IF:
04778 case T_IFDEF:
04779 case T_IFNDEF:
04780 temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
04781 temp->next = pfile->if_stack;
04782 temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
04783 temp->type = kt->type;
04784 temp->lineno = 0;
04785 temp->if_succeeded = 0;
04786 temp->control_macro = NULL;
04787
04788 pfile->if_stack = temp;
04789 break;
04790 case T_ELSE:
04791 case T_ENDIF:
04792 if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)
04793 validate_else (pfile,
04794 cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
04795
04796 case T_ELIF:
04797 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
04798 {
04799 cppReader_error (pfile,
04800 message ("Preprocessor command #%s is not within a conditional", kt->name));
04801 break;
04802 }
04803 else if (pfile->if_stack == save_if_stack)
04804 {
04805 goto done;
04806 }
04807 else
04808 {
04809 ;
04810 }
04811
04812 if (kt->type != T_ENDIF)
04813 {
04814 llassert (pfile->if_stack != NULL);
04815
04816 if (pfile->if_stack->type == T_ELSE)
04817 {
04818 cppReader_errorLit (pfile,
04819 cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));
04820 }
04821
04822 pfile->if_stack->type = kt->type;
04823 break;
04824 }
04825
04826 temp = pfile->if_stack;
04827 llassert (temp != NULL);
04828 pfile->if_stack = temp->next;
04829 sfree (temp);
04830 break;
04831 default: ;
04832
04833 }
04834
04835 break;
04836 }
04837
04838
04839
04840 if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
04841 && cppReader_isPedantic (pfile))
04842 {
04843 cppReader_pedwarnLit (pfile,
04844 cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
04845 }
04846 }
04847
04848 c = cppReader_getC (pfile);
04849 }
04850
04851 for (;;) {
04852 switch (c)
04853 {
04854 size_t old;
04855 case EOF:
04856 goto done;
04857 case '/':
04858 c = skip_comment (pfile, NULL);
04859 if (c == EOF)
04860 goto done;
04861 break;
04862 case '\"':
04863 case '\'':
04864 cppReader_forward (pfile, -1);
04865 old = cppReader_getWritten (pfile);
04866 (void) cppGetToken (pfile);
04867 cppReader_setWritten (pfile, old);
04868 break;
04869 case '\\':
04870
04871 if (cppReader_peekC (pfile) == '\n')
04872 {
04873 cppReader_forward (pfile, 1);
04874 }
04875
04876 break;
04877 case '\n':
04878 goto beg_of_line;
04879 }
04880 c = cppReader_getC (pfile);
04881 }
04882 done:
04883 if (CPPOPTIONS (pfile)->output_conditionals) {
04884 static char end_failed[] = "#endfailed\n";
04885 cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);
04886 pfile->lineno++;
04887 }
04888 pfile->only_seen_white = 1;
04889
04890 parseGotoMark (&line_start_mark, pfile);
04891 parseClearMark (&line_start_mark);
04892 }
04893
04894
04895
04896
04897
04898
04899
04900
04901 static int
04902 do_else (cppReader *pfile, struct directive *keyword,
04903 char *buf, char *limit)
04904 {
04905 if (cppReader_isPedantic (pfile))
04906 {
04907 validate_else (pfile, cstring_makeLiteralTemp ("#else"));
04908 }
04909
04910 cppReader_skipRestOfLine (pfile);
04911
04912 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) {
04913 cppReader_errorLit (pfile,
04914 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
04915 return 0;
04916 } else {
04917
04918
04919
04920 llassert (pfile->if_stack != NULL);
04921
04922 pfile->if_stack->control_macro = 0;
04923
04924 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
04925 {
04926 cpp_setLocation (pfile);
04927 genppllerrorhint (FLG_PREPROC,
04928 message ("Pre-processor directive #else after #else"),
04929 message ("%q: Location of match",
04930 fileloc_unparseRaw (pfile->if_stack->fname,
04931 pfile->if_stack->lineno)));
04932 }
04933
04934 pfile->if_stack->type = T_ELSE;
04935 }
04936
04937 if (pfile->if_stack->if_succeeded)
04938 skip_if_group (pfile, 0);
04939 else {
04940 ++pfile->if_stack->if_succeeded;
04941 output_line_command (pfile, 1, same_file);
04942 }
04943
04944 return 0;
04945 }
04946
04947
04948
04949
04950
04951 static int
04952 do_endif (cppReader *pfile, struct directive *keyword,
04953 char *buf, char *limit)
04954 {
04955 if (cppReader_isPedantic (pfile))
04956 {
04957 validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
04958 }
04959
04960 cppReader_skipRestOfLine (pfile);
04961
04962 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
04963 {
04964 cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
04965 }
04966 else
04967 {
04968 cppIfStackFrame *temp = pfile->if_stack;
04969
04970 llassert (temp != NULL);
04971
04972 pfile->if_stack = temp->next;
04973 if (temp->control_macro != 0)
04974 {
04975
04976
04977 struct parse_marker start_mark;
04978 int c;
04979
04980 parseSetMark (&start_mark, pfile);
04981
04982 for (;;)
04983 {
04984 cppSkipHspace (pfile);
04985 c = cppReader_getC (pfile);
04986
04987 if (c != '\n')
04988 break;
04989 }
04990
04991 parseGotoMark (&start_mark, pfile);
04992 parseClearMark (&start_mark);
04993
04994 if (c == EOF)
04995 {
04996
04997
04998
04999
05000
05001
05002
05003 struct file_name_list *ifile = pfile->all_include_files;
05004
05005 for ( ; ifile != NULL; ifile = ifile->next)
05006 {
05007 if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname))
05008 {
05009 ifile->control_macro = temp->control_macro;
05010 break;
05011 }
05012 }
05013 }
05014 }
05015
05016 sfree (temp);
05017 output_line_command (pfile, 1, same_file);
05018 }
05019 return 0;
05020 }
05021
05022
05023
05024
05025
05026 static void
05027 validate_else (cppReader *pfile, cstring directive)
05028 {
05029 int c;
05030 cppSkipHspace (pfile);
05031 c = cppReader_peekC (pfile);
05032 if (c != EOF && c != '\n')
05033 {
05034 cppReader_pedwarn (pfile,
05035 message ("text following `%s' violates ANSI standard", directive));
05036 }
05037 }
05038
05039
05040
05041
05042
05043
05044 enum cpp_token
05045 cppGetToken (cppReader *pfile)
05046 {
05047 int c, c2, c3;
05048 size_t old_written = 0;
05049 int start_line, start_column;
05050 enum cpp_token token;
05051 struct cppOptions *opts = CPPOPTIONS (pfile);
05052 cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur;
05053
05054 get_next:
05055 c = cppReader_getC (pfile);
05056
05057 if (c == EOF)
05058 {
05059 handle_eof:
05060 if (cppReader_getBuffer (pfile)->seen_eof)
05061 {
05062 cppBuffer *buf = cppReader_popBuffer (pfile);
05063
05064 if (buf != cppReader_nullBuffer (pfile))
05065 {
05066 goto get_next;
05067 }
05068 else
05069 {
05070 return CPP_EOF;
05071 }
05072 }
05073 else
05074 {
05075 cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
05076 cppReader_getBuffer (pfile)->seen_eof = 1;
05077
05078 if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)
05079 && next_buf != cppReader_nullBuffer (pfile))
05080 {
05081
05082
05083
05084 cppBuffer *cur_buffer = CPPBUFFER (pfile);
05085 CPPBUFFER (pfile) = next_buf;
05086 pfile->input_stack_listing_current = 0;
05087 output_line_command (pfile, 0, leave_file);
05088 CPPBUFFER (pfile) = cur_buffer;
05089 }
05090 return CPP_POP;
05091 }
05092 }
05093 else
05094 {
05095 long newlines;
05096 struct parse_marker start_mark;
05097
05098 switch (c)
05099 {
05100 case '/':
05101 if (cppReader_peekC (pfile) == '=')
05102 {
05103 goto op2;
05104 }
05105
05106 if (opts->put_out_comments)
05107 {
05108 parseSetMark (&start_mark, pfile);
05109 }
05110
05111 newlines = 0;
05112 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
05113 &start_line, &start_column);
05114 c = skip_comment (pfile, &newlines);
05115
05116 if (opts->put_out_comments && (c == '/' || c == EOF))
05117 {
05118 assertSet (&start_mark);
05119 parseClearMark (&start_mark);
05120 }
05121
05122 if (c == '/')
05123 goto randomchar;
05124 if (c == EOF)
05125 {
05126 cppReader_errorWithLine (pfile, start_line, start_column,
05127 cstring_makeLiteral ("Unterminated comment"));
05128 goto handle_eof;
05129 }
05130 c = '/';
05131 return_comment:
05132
05133
05134
05135 if (opts->put_out_comments)
05136 {
05137 enum cpp_token res;
05138
05139 assertSet (&start_mark);
05140 res = cpp_handleComment (pfile, &start_mark);
05141 pfile->lineno += newlines;
05142 return res;
05143 }
05144 else if (cppReader_isTraditional (pfile))
05145 {
05146 return CPP_COMMENT;
05147 }
05148 else
05149 {
05150 cppReader_reserve(pfile, 1);
05151 cppReader_putCharQ (pfile, ' ');
05152 return CPP_HSPACE;
05153 }
05154
05155 case '#':
05156 if (!pfile->only_seen_white)
05157 {
05158 goto randomchar;
05159 }
05160
05161 if (cppReader_handleDirective (pfile))
05162 {
05163 return CPP_DIRECTIVE;
05164 }
05165
05166 pfile->only_seen_white = 0;
05167 return CPP_OTHER;
05168
05169 case '\"':
05170 case '\'':
05171
05172
05173 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
05174 &start_line, &start_column);
05175 old_written = cppReader_getWritten (pfile);
05176 string:
05177 cppReader_putChar (pfile, c);
05178 while (TRUE)
05179 {
05180 int cc = cppReader_getC (pfile);
05181 if (cc == EOF)
05182 {
05183 if (cppBuffer_isMacro (CPPBUFFER (pfile)))
05184 {
05185
05186
05187
05188
05189 cppBuffer *next_buf
05190 = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
05191 (*cppReader_getBuffer (pfile)->cleanup)
05192 (cppReader_getBuffer (pfile), pfile);
05193 CPPBUFFER (pfile) = next_buf;
05194 continue;
05195 }
05196 if (!cppReader_isTraditional (pfile))
05197 {
05198 cpp_setLocation (pfile);
05199
05200 setLine (long_toInt (start_line));
05201 setColumn (long_toInt (start_column));
05202
05203 if (pfile->multiline_string_line != long_toInt (start_line)
05204 && pfile->multiline_string_line != 0)
05205 {
05206 genppllerrorhint
05207 (FLG_PREPROC,
05208 message ("Unterminated string or character constant"),
05209 message ("%q: Possible real start of unterminated constant",
05210 fileloc_unparseRaw
05211 (fileloc_filename (g_currentloc),
05212 pfile->multiline_string_line)));
05213 pfile->multiline_string_line = 0;
05214 }
05215 else
05216 {
05217 genppllerror
05218 (FLG_PREPROC,
05219 message ("Unterminated string or character constant"));
05220 }
05221 }
05222 break;
05223 }
05224 cppReader_putChar (pfile, cc);
05225 switch (cc)
05226 {
05227 case '\n':
05228
05229
05230 if (cppReader_isTraditional (pfile))
05231 goto while2end;
05232 if (c == '\'')
05233 {
05234 goto while2end;
05235 }
05236 if (cppReader_isPedantic (pfile)
05237 && pfile->multiline_string_line == 0)
05238 {
05239 cppReader_pedwarnWithLine
05240 (pfile, long_toInt (start_line),
05241 long_toInt (start_column),
05242 cstring_makeLiteral ("String constant runs past end of line"));
05243 }
05244 if (pfile->multiline_string_line == 0)
05245 {
05246 pfile->multiline_string_line = start_line;
05247 }
05248
05249 break;
05250
05251 case '\\':
05252 cc = cppReader_getC (pfile);
05253 if (cc == '\n')
05254 {
05255
05256 cppReader_adjustWritten (pfile, -1);
05257 pfile->lineno++;
05258 }
05259 else
05260 {
05261
05262
05263 NEWLINE_FIX1(cc);
05264 if (cc != EOF)
05265 cppReader_putChar (pfile, cc);
05266 }
05267 break;
05268
05269 case '\"':
05270 case '\'':
05271 if (cc == c)
05272 goto while2end;
05273 break;
05274 }
05275 }
05276 while2end:
05277 pfile->lineno += count_newlines (pfile->token_buffer + old_written,
05278 cppReader_getPWritten (pfile));
05279 pfile->only_seen_white = 0;
05280 return c == '\'' ? CPP_CHAR : CPP_STRING;
05281
05282 case '$':
05283 if (!opts->dollars_in_ident)
05284 goto randomchar;
05285 goto letter;
05286
05287 case ':':
05288 if (opts->cplusplus && cppReader_peekC (pfile) == ':')
05289 goto op2;
05290 goto randomchar;
05291
05292 case '&':
05293 case '+':
05294 case '|':
05295 NEWLINE_FIX;
05296 c2 = cppReader_peekC (pfile);
05297 if (c2 == c || c2 == '=')
05298 goto op2;
05299 goto randomchar;
05300
05301 case '*':
05302 case '!':
05303 case '%':
05304 case '=':
05305 case '^':
05306 NEWLINE_FIX;
05307 if (cppReader_peekC (pfile) == '=')
05308 goto op2;
05309 goto randomchar;
05310
05311 case '-':
05312 NEWLINE_FIX;
05313 c2 = cppReader_peekC (pfile);
05314 if (c2 == '-' && opts->chill)
05315 {
05316
05317 if (opts->put_out_comments)
05318 {
05319 parseSetMark (&start_mark, pfile);
05320 }
05321
05322 cppReader_forward (pfile, 1);
05323
05324 for (;;)
05325 {
05326 c = cppReader_getC (pfile);
05327 if (c == EOF)
05328 break;
05329 if (c == '\n')
05330 {
05331
05332 cppReader_forward (pfile, -1);
05333 break;
05334 }
05335 }
05336 c = '-';
05337 goto return_comment;
05338 }
05339 if (c2 == '-' || c2 == '=' || c2 == '>')
05340 goto op2;
05341 goto randomchar;
05342
05343 case '<':
05344 if (pfile->parsing_include_directive)
05345 {
05346 for (;;)
05347 {
05348 cppReader_putChar (pfile, c);
05349 if (c == '>')
05350 break;
05351 c = cppReader_getC (pfile);
05352 NEWLINE_FIX1 (c);
05353 if (c == '\n' || c == EOF)
05354 {
05355 cppReader_errorLit (pfile,
05356 cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
05357 break;
05358 }
05359 }
05360 return CPP_STRING;
05361 }
05362
05363 case '>':
05364 NEWLINE_FIX;
05365 c2 = cppReader_peekC (pfile);
05366 if (c2 == '=')
05367 goto op2;
05368 if (c2 != c)
05369 goto randomchar;
05370 cppReader_forward (pfile, 1);
05371 cppReader_reserve (pfile, 4);
05372 cppReader_putChar (pfile, c);
05373 cppReader_putChar (pfile, c2);
05374 NEWLINE_FIX;
05375 c3 = cppReader_peekC (pfile);
05376 if (c3 == '=')
05377 cppReader_putCharQ (pfile, cppReader_getC (pfile));
05378 cppReader_nullTerminateQ (pfile);
05379 pfile->only_seen_white = 0;
05380 return CPP_OTHER;
05381
05382 case '@':
05383 if (cppReader_getBuffer (pfile)->has_escapes)
05384 {
05385 c = cppReader_getC (pfile);
05386 if (c == '-')
05387 {
05388 if (pfile->output_escapes)
05389 cppReader_puts (pfile, "@-", 2);
05390 parse_name (pfile, cppReader_getC (pfile));
05391 return CPP_NAME;
05392 }
05393 else if (is_space [c])
05394 {
05395 cppReader_reserve (pfile, 2);
05396 if (pfile->output_escapes)
05397 cppReader_putCharQ (pfile, '@');
05398 cppReader_putCharQ (pfile, c);
05399 return CPP_HSPACE;
05400 }
05401 else
05402 {
05403 ;
05404 }
05405 }
05406 if (pfile->output_escapes)
05407 {
05408 cppReader_puts (pfile, "@@", 2);
05409 return CPP_OTHER;
05410 }
05411 goto randomchar;
05412 case '.':
05413 NEWLINE_FIX;
05414 c2 = cppReader_peekC (pfile);
05415 if (isdigit(c2))
05416 {
05417 cppReader_reserve(pfile, 2);
05418 cppReader_putCharQ (pfile, '.');
05419 c = cppReader_getC (pfile);
05420 goto number;
05421 }
05422
05423
05424 if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
05425 {
05426 cppReader_reserve(pfile, 4);
05427 cppReader_putCharQ (pfile, '.');
05428 cppReader_putCharQ (pfile, '.');
05429 cppReader_putCharQ (pfile, '.');
05430 cppReader_forward (pfile, 2);
05431 cppReader_nullTerminateQ (pfile);
05432 pfile->only_seen_white = 0;
05433 return CPP_3DOTS;
05434 }
05435 goto randomchar;
05436 op2:
05437 token = CPP_OTHER;
05438 pfile->only_seen_white = 0;
05439 op2any:
05440 cppReader_reserve(pfile, 3);
05441 cppReader_putCharQ (pfile, c);
05442 cppReader_putCharQ (pfile, cppReader_getC (pfile));
05443 cppReader_nullTerminateQ (pfile);
05444 return token;
05445
05446 case 'L':
05447 NEWLINE_FIX;
05448 c2 = cppReader_peekC (pfile);
05449 if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
05450 {
05451 cppReader_putChar (pfile, c);
05452 c = cppReader_getC (pfile);
05453 goto string;
05454 }
05455 goto letter;
05456
05457 case '0': case '1': case '2': case '3': case '4':
05458 case '5': case '6': case '7': case '8': case '9':
05459 number:
05460 c2 = '.';
05461 for (;;)
05462 {
05463 cppReader_reserve (pfile, 2);
05464 cppReader_putCharQ (pfile, c);
05465 NEWLINE_FIX;
05466 c = cppReader_peekC (pfile);
05467 if (c == EOF)
05468 break;
05469 if (!is_idchar[c] && c != '.'
05470 && ((c2 != 'e' && c2 != 'E'
05471 && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
05472 || (c != '+' && c != '-')))
05473 break;
05474 cppReader_forward (pfile, 1);
05475 c2= c;
05476 }
05477
05478 cppReader_nullTerminateQ (pfile);
05479 pfile->only_seen_white = 0;
05480 return CPP_NUMBER;
05481
05482 case 'b': case 'c': case 'd': case 'h': case 'o':
05483 case 'B': case 'C': case 'D': case 'H': case 'O':
05484 if (opts->chill && cppReader_peekC (pfile) == '\'')
05485 {
05486 pfile->only_seen_white = 0;
05487 cppReader_reserve (pfile, 2);
05488 cppReader_putCharQ (pfile, c);
05489 cppReader_putCharQ (pfile, '\'');
05490 cppReader_forward (pfile, 1);
05491 for (;;)
05492 {
05493 c = cppReader_getC (pfile);
05494 if (c == EOF)
05495 goto chill_number_eof;
05496 if (!is_idchar[c])
05497 {
05498 if (c == '\\' && cppReader_peekC (pfile) == '\n')
05499 {
05500 cppReader_forward (pfile, 2);
05501 continue;
05502 }
05503 break;
05504 }
05505 cppReader_putChar (pfile, c);
05506 }
05507 if (c == '\'')
05508 {
05509 cppReader_reserve (pfile, 2);
05510 cppReader_putCharQ (pfile, c);
05511 cppReader_nullTerminateQ (pfile);
05512 return CPP_STRING;
05513 }
05514 else
05515 {
05516 cppReader_forward (pfile, -1);
05517 chill_number_eof:
05518 cppReader_nullTerminate (pfile);
05519 return CPP_NUMBER;
05520 }
05521 }
05522 else
05523 goto letter;
05524 case '_':
05525 case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
05526 case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
05527 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
05528 case 'x': case 'y': case 'z':
05529 case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
05530 case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
05531 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
05532 case 'Y': case 'Z':
05533 letter:
05534 {
05535 HASHNODE *hp;
05536 char *ident;
05537 size_t before_name_written = cppReader_getWritten (pfile);
05538 int ident_len;
05539 parse_name (pfile, c);
05540 pfile->only_seen_white = 0;
05541 if (pfile->no_macro_expand)
05542 {
05543 return CPP_NAME;
05544 }
05545
05546 ident = pfile->token_buffer + before_name_written;
05547 ident_len = (cppReader_getPWritten (pfile)) - ident;
05548
05549 hp = cppReader_lookupExpand (ident, ident_len, -1);
05550
05551 if (hp == NULL)
05552 {
05553 return CPP_NAME;
05554 }
05555
05556 if (hp->type == T_DISABLED)
05557 {
05558 if (pfile->output_escapes)
05559 {
05560 int i;
05561 cppReader_reserve (pfile, 3);
05562 ident = pfile->token_buffer + before_name_written;
05563 cppReader_adjustWritten (pfile, 2);
05564
05565 for (i = ident_len; i >= 0; i--)
05566 {
05567 ident[i+2] = ident[i];
05568 }
05569
05570 ident[0] = '@';
05571 ident[1] = '-';
05572 }
05573 return CPP_NAME;
05574 }
05575
05576
05577
05578
05579
05580
05581 if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
05582 {
05583 struct parse_marker macro_mark;
05584 int is_macro_call;
05585
05586 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
05587 {
05588 cppBuffer *next_buf;
05589 cppSkipHspace (pfile);
05590 if (cppReader_peekC (pfile) != EOF)
05591 {
05592 break;
05593 }
05594
05595 next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
05596 (*cppReader_getBuffer (pfile)->cleanup) (cppReader_getBuffer (pfile), pfile);
05597 CPPBUFFER (pfile) = next_buf;
05598 }
05599
05600 parseSetMark (¯o_mark, pfile);
05601
05602 for (;;)
05603 {
05604 cppSkipHspace (pfile);
05605 c = cppReader_peekC (pfile);
05606 is_macro_call = c == '(';
05607 if (c != '\n')
05608 break;
05609 cppReader_forward (pfile, 1);
05610 }
05611
05612 if (!is_macro_call)
05613 {
05614 parseGotoMark (¯o_mark, pfile);
05615 }
05616
05617 parseClearMark (¯o_mark);
05618
05619 if (!is_macro_call)
05620 {
05621 return CPP_NAME;
05622 }
05623 }
05624
05625
05626
05627 if (hp->type != T_MACRO)
05628 {
05629 size_t xbuf_len;
05630 char *xbuf;
05631
05632 cppReader_setWritten (pfile, before_name_written);
05633 special_symbol (hp, pfile);
05634 xbuf_len = cppReader_getWritten (pfile) - before_name_written;
05635 xbuf = (char *) dmalloc (xbuf_len + 1);
05636 cppReader_setWritten (pfile, before_name_written);
05637 memcpy (xbuf, cppReader_getPWritten (pfile), xbuf_len + 1);
05638 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
05639 }
05640 else
05641 {
05642
05643
05644 macroexpand (pfile, hp);
05645 cppReader_setWritten (pfile, before_name_written);
05646 }
05647
05648
05649
05650
05651
05652
05653 llassert (pfile->buffer->rlimit != NULL);
05654
05655 if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
05656 && pfile->buffer->rlimit[-2] == '@'
05657 && pfile->buffer->rlimit[-1] == ' ')
05658 {
05659 int c1 = pfile->buffer->rlimit[-3];
05660 int cl2 = cppBufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
05661
05662 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
05663 pfile->buffer->rlimit -= 2;
05664 }
05665 }
05666 goto get_next;
05667
05668 case ' ': case '\t': case '\v': case '\r':
05669 for (;;)
05670 {
05671 cppReader_putChar (pfile, c);
05672 c = cppReader_peekC (pfile);
05673 if (c == EOF || !is_hor_space[c])
05674 break;
05675 cppReader_forward (pfile, 1);
05676 }
05677 return CPP_HSPACE;
05678
05679 case '\\':
05680 c2 = cppReader_peekC (pfile);
05681 if (c2 != '\n')
05682 goto randomchar;
05683 token = CPP_HSPACE;
05684 goto op2any;
05685
05686 case '\n':
05687 cppReader_putChar (pfile, c);
05688 if (pfile->only_seen_white == 0)
05689 pfile->only_seen_white = 1;
05690 pfile->lineno++;
05691 output_line_command (pfile, 1, same_file);
05692 return CPP_VSPACE;
05693
05694 case '(': token = CPP_LPAREN; goto char1;
05695 case ')': token = CPP_RPAREN; goto char1;
05696 case '{': token = CPP_LBRACE; goto char1;
05697 case '}': token = CPP_RBRACE; goto char1;
05698 case ',': token = CPP_COMMA; goto char1;
05699 case ';': token = CPP_SEMICOLON; goto char1;
05700
05701 randomchar:
05702 default:
05703 token = CPP_OTHER;
05704 char1:
05705 pfile->only_seen_white = 0;
05706 cppReader_putChar (pfile, c);
05707 return token;
05708 }
05709 }
05710
05711 BADBRANCH;
05712
05713 }
05714
05715
05716
05717 void
05718 parse_name (cppReader *pfile, int c)
05719 {
05720 for (;;)
05721 {
05722 if (!is_idchar[c])
05723 {
05724 if (c == '\\' && cppReader_peekC (pfile) == '\n')
05725 {
05726 cppReader_forward (pfile, 2);
05727 continue;
05728 }
05729
05730 cppReader_forward (pfile, -1);
05731 break;
05732 }
05733
05734 if (c == '$' && cppReader_isPedantic (pfile))
05735 {
05736 cppReader_pedwarnLit (pfile,
05737 cstring_makeLiteralTemp ("`$' in identifier"));
05738 }
05739
05740 cppReader_reserve(pfile, 2);
05741 cppReader_putCharQ (pfile, c);
05742 c = cppReader_getC (pfile);
05743
05744 if (c == EOF)
05745 break;
05746 }
05747
05748 cppReader_nullTerminateQ (pfile);
05749 }
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759 struct file_name_map
05760 {
05761 struct file_name_map *map_next;
05762 cstring map_from;
05763 cstring map_to;
05764 };
05765
05766
05767 #define FILE_NAME_MAP_FILE "header.gcc"
05768
05769
05770
05771
05772 static cstring read_filename_string (int ch, FILE *f)
05773 {
05774 char *alloc, *set;
05775 size_t len;
05776
05777 len = 20;
05778 set = alloc = dmalloc (len + 1);
05779
05780 if (!is_space[ch])
05781 {
05782 *set++ = ch;
05783 while ((ch = getc (f)) != EOF && ! is_space[ch])
05784 {
05785 if (set - alloc == size_toInt (len))
05786 {
05787 len *= 2;
05788 alloc = drealloc (alloc, len + 1);
05789 set = alloc + len / 2;
05790 }
05791
05792 *set++ = ch;
05793 }
05794 }
05795 *set = '\0';
05796 check (ungetc (ch, f) != EOF);
05797
05798 return cstring_fromChars (alloc);
05799 }
05800
05801
05802
05803 struct file_name_map_list
05804 {
05805 struct file_name_map_list *map_list_next;
05806 cstring map_list_name;
05807 struct file_name_map *map_list_map;
05808 };
05809
05810
05811
05812 static struct file_name_map *
05813 read_name_map (cppReader *pfile, cstring dirname)
05814 {
05815 struct file_name_map_list *map_list_ptr;
05816 cstring name;
05817 FILE *f;
05818
05819 for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
05820 map_list_ptr != NULL;
05821 map_list_ptr = map_list_ptr->map_list_next)
05822 {
05823 if (cstring_equal (map_list_ptr->map_list_name, dirname))
05824 {
05825 return map_list_ptr->map_list_map;
05826 }
05827 }
05828
05829 map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
05830 map_list_ptr->map_list_name = cstring_copy (dirname);
05831 map_list_ptr->map_list_map = NULL;
05832
05833 name = cstring_copy (dirname);
05834
05835 if (cstring_length (dirname) > 0)
05836 {
05837 name = cstring_appendChar (name, CONNECTCHAR);
05838 }
05839
05840 name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
05841
05842 f = fopen (cstring_toCharsSafe (name), "r");
05843 cstring_free (name);
05844
05845 if (f == NULL)
05846 {
05847 map_list_ptr->map_list_map = NULL;
05848 }
05849 else
05850 {
05851 int ch;
05852
05853 while ((ch = getc (f)) != EOF)
05854 {
05855 cstring from, to;
05856 struct file_name_map *ptr;
05857
05858 if (is_space[ch])
05859 {
05860 continue;
05861 }
05862
05863 from = read_filename_string (ch, f);
05864 while ((ch = getc (f)) != EOF && is_hor_space[ch])
05865 {
05866 ;
05867 }
05868
05869 to = read_filename_string (ch, f);
05870
05871 ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
05872 ptr->map_from = from;
05873
05874
05875 if (cstring_length (to) > 1
05876 && osd_isConnectChar (cstring_firstChar (to)))
05877 {
05878 ptr->map_to = to;
05879 }
05880 else
05881 {
05882 ptr->map_to = cstring_copy (dirname);
05883 ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
05884 ptr->map_to = cstring_concatFree (ptr->map_to, to);
05885 }
05886
05887 ptr->map_next = map_list_ptr->map_list_map;
05888 map_list_ptr->map_list_map = ptr;
05889
05890 while ((ch = getc (f)) != '\n')
05891 {
05892 if (ch == EOF)
05893 {
05894 break;
05895 }
05896 }
05897 }
05898
05899 assertSet (map_list_ptr->map_list_map);
05900 check (fclose (f) == 0);
05901 }
05902
05903 map_list_ptr->map_list_next = pfile->opts->map_list;
05904 pfile->opts->map_list = map_list_ptr;
05905
05906 return map_list_ptr->map_list_map;
05907 }
05908
05909
05910
05911
05912
05913
05914 static int
05915 open_include_file (cppReader *pfile,
05916 cstring fname,
05917 struct file_name_list *searchptr)
05918 {
05919 char *filename = cstring_toCharsSafe (fname);
05920 struct file_name_map *map;
05921 char *from;
05922 char *p, *dir;
05923
05924 cstring_markOwned (fname);
05925
05926 cpp_setLocation (pfile);
05927
05928 if (context_getFlag (FLG_NEVERINCLUDE))
05929 {
05930 if (isHeaderFile (fname))
05931 {
05932 return SKIP_INCLUDE;
05933 }
05934 }
05935
05936 if ((searchptr != NULL) && ! searchptr->got_name_map)
05937 {
05938 searchptr->name_map = read_name_map (pfile,
05939 !cstring_isEmpty (searchptr->fname)
05940 ? searchptr->fname :
05941 cstring_makeLiteralTemp ("."));
05942 searchptr->got_name_map = 1;
05943 }
05944
05945
05946
05947 if ((searchptr != NULL)
05948 && (searchptr->name_map != NULL))
05949 {
05950 from = filename;
05951
05952 if (!cstring_isEmpty (searchptr->fname))
05953 {
05954 from += cstring_length (searchptr->fname) + 1;
05955 }
05956
05957 for (map = searchptr->name_map;
05958 map != NULL;
05959 map = map->map_next)
05960 {
05961 if (cstring_equal (map->map_from, cstring_fromChars (from)))
05962 {
05963
05964
05965
05966
05967 if (cpp_skipIncludeFile (map->map_to))
05968 {
05969 return SKIP_INCLUDE;
05970 }
05971 else
05972 {
05973 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
05974 }
05975 }
05976 }
05977 }
05978
05979
05980
05981
05982
05983
05984
05985
05986 p = strrchr (filename, CONNECTCHAR);
05987
05988 if (p == NULL)
05989 {
05990 p = filename;
05991 }
05992
05993 if ((searchptr != NULL)
05994 && (cstring_isDefined (searchptr->fname))
05995 && (cstring_length (searchptr->fname) == p - filename)
05996 && !strncmp (cstring_toCharsSafe (searchptr->fname),
05997 filename,
05998 size_fromInt (p - filename)))
05999 {
06000
06001
06002 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
06003 {
06004 return SKIP_INCLUDE;
06005 }
06006 else
06007 {
06008 return cpp_openIncludeFile (filename);
06009 }
06010 }
06011
06012 if (p == filename)
06013 {
06014 dir = mstring_copy (".");
06015 from = filename;
06016 }
06017 else
06018 {
06019 dir = (char *) dmalloc (size_fromInt (p - filename + 1));
06020 memcpy (dir, filename, size_fromInt (p - filename));
06021 dir[p - filename] = '\0';
06022 from = p + 1;
06023 }
06024
06025 for (map = read_name_map (pfile, cstring_fromChars (dir));
06026 map != NULL;
06027 map = map->map_next)
06028 {
06029 if (cstring_equal (map->map_from, cstring_fromChars (from)))
06030 {
06031 sfree (dir);
06032
06033 if (cpp_skipIncludeFile (map->map_to))
06034 {
06035 return SKIP_INCLUDE;
06036 }
06037 else
06038 {
06039 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
06040 }
06041 }
06042 }
06043
06044 sfree (dir);
06045
06046 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
06047 {
06048 return SKIP_INCLUDE;
06049 }
06050 else
06051 {
06052 return cpp_openIncludeFile (filename);
06053 }
06054 }
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067 static int
06068 finclude (cppReader *pfile, int f,
06069 cstring fname,
06070 bool system_header_p,
06071 struct file_name_list *dirptr)
06072 {
06073 mode_t st_mode;
06074 size_t st_size;
06075 long i;
06076 int length = 0;
06077 cppBuffer *fp;
06078
06079 if (file_size_and_mode (f, &st_mode, &st_size) < 0)
06080 {
06081 cppReader_perrorWithName (pfile, fname);
06082 check (close (f) == 0);
06083 (void) cppReader_popBuffer (pfile);
06084
06085 return 0;
06086
06087 }
06088
06089 fp = cppReader_getBuffer (pfile);
06090
06091
06092 fp->nominal_fname = fp->fname = fname;
06093
06094
06095 fp->dir = dirptr;
06096 fp->system_header_p = system_header_p;
06097 fp->lineno = 1;
06098 fp->colno = 1;
06099 fp->cleanup = cppReader_fileCleanup;
06100
06101 if (S_ISREG (st_mode))
06102 {
06103 sfree (fp->buf);
06104 fp->buf = (char *) dmalloc (st_size + 2);
06105 fp->alimit = fp->buf + st_size + 2;
06106 fp->cur = fp->buf;
06107
06108
06109
06110 length = safe_read (f, fp->buf, size_toInt (st_size));
06111 fp->rlimit = fp->buf + length;
06112 if (length < 0) goto nope;
06113 }
06114 else if (S_ISDIR (st_mode))
06115 {
06116 cppReader_error (pfile,
06117 message ("directory `%s' specified in #include", fname));
06118 check (close (f) == 0);
06119 return 0;
06120 }
06121 else
06122 {
06123
06124
06125
06126
06127
06128
06129 size_t bsize = 2000;
06130
06131 st_size = 0;
06132
06133 sfree (fp->buf);
06134 fp->buf = (char *) dmalloc (bsize + 2);
06135
06136 for (;;) {
06137 i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
06138
06139 if (i < 0)
06140 goto nope;
06141 st_size += i;
06142
06143 if (st_size != bsize)
06144 {
06145 break;
06146 }
06147
06148 bsize *= 2;
06149 fp->buf = (char *) drealloc (fp->buf, bsize + 2);
06150 }
06151
06152 fp->cur = fp->buf;
06153 length = size_toInt (st_size);
06154 }
06155
06156 if ((length > 0 && fp->buf[length - 1] != '\n')
06157
06158 || (length > 1 && fp->buf[length - 2] == '\\')) {
06159 fp->buf[length++] = '\n';
06160 }
06161
06162 fp->buf[length] = '\0';
06163 fp->rlimit = fp->buf + length;
06164
06165
06166
06167 check (close (f) == 0);
06168
06169
06170
06171
06172 pfile->input_stack_listing_current = 0;
06173 return 1;
06174
06175 nope:
06176
06177 cppReader_perrorWithName (pfile, fname);
06178 check (close (f) == 0);
06179 sfree (fp->buf);
06180 return 1;
06181 }
06182
06183 void
06184 cppReader_init (cppReader *pfile)
06185 {
06186 memset ((char *) pfile, 0, sizeof (*pfile));
06187
06188 pfile->get_token = cppGetToken;
06189 pfile->token_buffer_size = 200;
06190 pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
06191 pfile->all_include_files = NULL;
06192
06193 assertSet (pfile);
06194
06195 cppReader_setWritten (pfile, 0);
06196
06197 pfile->system_include_depth = 0;
06198 pfile->max_include_len = 0;
06199 pfile->timebuf = NULL;
06200 pfile->only_seen_white = 1;
06201
06202 pfile->buffer = cppReader_nullBuffer (pfile);
06203 }
06204
06205 void
06206 cppReader_finish ( cppReader *pfile)
06207 {
06208 ;
06209 }
06210
06211
06212
06213
06214 void
06215 cppCleanup (cppReader *pfile)
06216 {
06217 while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
06218 {
06219 (void) cppReader_popBuffer (pfile);
06220 }
06221
06222 if (pfile->token_buffer != NULL)
06223 {
06224 sfree (pfile->token_buffer);
06225 pfile->token_buffer = NULL;
06226 }
06227
06228 while (pfile->if_stack != NULL)
06229 {
06230 cppIfStackFrame *temp = pfile->if_stack;
06231 pfile->if_stack = temp->next;
06232 sfree (temp);
06233 }
06234
06235 while (pfile->all_include_files != NULL)
06236 {
06237 struct file_name_list *temp = pfile->all_include_files;
06238 pfile->all_include_files = temp->next;
06239
06240 cstring_free (temp->fname);
06241
06242 sfree (temp);
06243 }
06244
06245 cppReader_hashCleanup ();
06246 }
06247
06248
06249
06250
06251
06252
06253 static int
06254 file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
06255 {
06256 struct stat sbuf;
06257
06258 if (fstat (fd, &sbuf) < 0) {
06259 return (-1);
06260 }
06261
06262 if (mode_pointer != NULL)
06263 {
06264 *mode_pointer = sbuf.st_mode;
06265 }
06266
06267 if (size_pointer != NULL)
06268 {
06269 *size_pointer = (size_t) sbuf.st_size;
06270 }
06271
06272 return 0;
06273 }
06274
06275
06276
06277
06278
06279
06280 static int safe_read (int desc, char *ptr, int len)
06281 {
06282 int left = len;
06283
06284 while (left > 0)
06285 {
06286 # if defined (WIN32) || defined (OS2) && defined (__IBMC__)
06287
06288 int nchars = _read (desc, ptr, (unsigned) left);
06289
06290 # else
06291 ssize_t nchars = read (desc, ptr, size_fromInt (left));
06292 # endif
06293
06294 if (nchars < 0)
06295 {
06296 #ifdef EINTR
06297 if (errno == EINTR)
06298 continue;
06299 #endif
06300 return (int) nchars;
06301 }
06302
06303 if (nchars == 0) {
06304 break;
06305 }
06306
06307 ptr += nchars;
06308 left -= nchars;
06309 }
06310
06311 return len - left;
06312 }
06313
06314
06315
06316 void
06317 parseSetMark (struct parse_marker *pmark, cppReader *pfile)
06318 {
06319 cppBuffer *pbuf = cppReader_getBuffer (pfile);
06320
06321 pmark->next = pbuf->marks;
06322
06323 pbuf->marks = pmark;
06324
06325
06326 pmark->buf = pbuf;
06327 pmark->position = pbuf->cur - pbuf->buf;
06328 }
06329
06330
06331
06332 void parseClearMark (struct parse_marker *pmark)
06333 {
06334 struct parse_marker **pp = &pmark->buf->marks;
06335
06336 for (; ; pp = &(*pp)->next)
06337 {
06338 llassert (*pp != NULL);
06339 if (*pp == pmark) break;
06340 }
06341
06342 *pp = pmark->next;
06343 }
06344
06345
06346
06347 void
06348 parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
06349 {
06350 cppBuffer *pbuf = cppReader_getBuffer (pfile);
06351
06352 if (pbuf != pmark->buf)
06353 {
06354 cpp_setLocation (pfile);
06355 llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
06356 }
06357
06358 llassert (pbuf->buf != NULL);
06359 pbuf->cur = pbuf->buf + pmark->position;
06360 }
06361
06362
06363
06364
06365 void
06366 parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
06367 {
06368 cppBuffer *pbuf = cppReader_getBuffer (pfile);
06369
06370 if (pbuf != pmark->buf)
06371 {
06372 cpp_setLocation (pfile);
06373 llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
06374 }
06375
06376 pmark->position = pbuf->cur - pbuf->buf;
06377 }
06378
06379 void cppReader_initializeReader (cppReader *pfile)
06380 {
06381 struct cppOptions *opts = CPPOPTIONS (pfile);
06382 char *xp;
06383
06384
06385
06386
06387
06388 struct default_include *include_defaults = include_defaults_array;
06389
06390
06391
06392
06393
06394
06395
06396
06397 xp = (char *) getenv ("CPATH");
06398
06399 if (xp != 0 && ! opts->no_standard_includes)
06400 {
06401 path_include (pfile, xp);
06402 }
06403
06404
06405 initialize_char_syntax (opts);
06406
06407
06408
06409
06410 initialize_builtins (pfile);
06411
06412
06413
06414
06415 if (!opts->inhibit_predefs) {
06416 char *p = (char *) dmalloc (strlen (predefs) + 1);
06417 strcpy (p, predefs);
06418
06419 while (*p)
06420 {
06421 char *q;
06422
06423 while (*p == ' ' || *p == '\t')
06424 {
06425 p++;
06426 }
06427
06428
06429 if (p[0] == '-' && p[1] == 'D')
06430 {
06431 q = &p[2];
06432
06433 while (*p && *p != ' ' && *p != '\t')
06434 {
06435 p++;
06436 }
06437
06438 if (*p != 0)
06439 {
06440 *p++= 0;
06441 }
06442
06443 if (opts->debug_output)
06444 {
06445 output_line_command (pfile, 0, same_file);
06446 }
06447
06448 cppReader_define (pfile, q);
06449
06450 while (*p == ' ' || *p == '\t')
06451 {
06452 p++;
06453 }
06454 }
06455 else
06456 {
06457 abort ();
06458 }
06459 }
06460
06461 sfree (p);
06462 }
06463
06464 opts->done_initializing = 1;
06465
06466 {
06467
06468 char *epath = 0;
06469 #ifdef __CYGWIN32__
06470 char *win32epath;
06471 int win32_buf_size = 0;
06472 #endif
06473
06474 if (opts->cplusplus)
06475 {
06476 epath = getenv ("CPLUS_INCLUDE_PATH");
06477 }
06478 else
06479 {
06480 epath = getenv ("C_INCLUDE_PATH");
06481 }
06482
06483
06484
06485
06486
06487
06488 if (epath != NULL) {
06489 char *nstore = (char *) dmalloc (strlen (epath) + 2);
06490 int num_dirs;
06491 char *startp, *endp;
06492
06493 #ifdef __CYGWIN32__
06494
06495 if (cygwin32_posix_path_list_p (epath))
06496 {
06497 win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
06498 win32epath = (char *) dmalloc (win32_buf_size);
06499 cygwin32_posix_to_win32_path_list (epath, win32epath);
06500 epath = win32epath;
06501 }
06502 #endif
06503 for (num_dirs = 1, startp = epath; *startp; startp++)
06504 {
06505 if (*startp == PATH_SEPARATOR)
06506 num_dirs++;
06507 }
06508
06509
06510 include_defaults
06511 = (struct default_include *) dmalloc ((num_dirs
06512 * sizeof (struct default_include))
06513 + sizeof (include_defaults_array));
06514
06515
06516 startp = endp = epath;
06517 num_dirs = 0;
06518 while (1) {
06519
06520 if ((*endp == PATH_SEPARATOR) || *endp == 0)
06521 {
06522 strncpy (nstore, startp, size_fromInt (endp - startp));
06523 if (endp == startp)
06524 {
06525 strcpy (nstore, ".");
06526 }
06527 else
06528 {
06529 nstore[endp-startp] = '\0';
06530 }
06531
06532 include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
06533 include_defaults[num_dirs].cplusplus = opts->cplusplus;
06534 include_defaults[num_dirs].cxx_aware = 1;
06535 num_dirs++;
06536
06537 if (*endp == '\0')
06538 {
06539 break;
06540 }
06541 endp = startp = endp + 1;
06542 }
06543 else
06544 {
06545 endp++;
06546 }
06547 }
06548
06549 memcpy ((char *) &include_defaults[num_dirs],
06550 (char *) include_defaults_array,
06551 sizeof (include_defaults_array));
06552
06553 sfree (nstore);
06554 }
06555 }
06556
06557 cppReader_appendIncludeChain (pfile, opts->before_system,
06558 opts->last_before_system);
06559 opts->first_system_include = opts->before_system;
06560
06561
06562
06563 if (!opts->no_standard_includes) {
06564 struct default_include *p = include_defaults;
06565 char *specd_prefix = opts->include_prefix;
06566 char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
06567 int default_len = 0;
06568
06569
06570 if (default_prefix != NULL) {
06571 if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
06572 default_len = strlen (default_prefix) - 7;
06573 default_prefix[default_len] = 0;
06574 }
06575 }
06576
06577
06578
06579 if (specd_prefix != 0 && default_len != 0)
06580 for (p = include_defaults; p->fname != NULL; p++) {
06581
06582 if (!p->cplusplus
06583 || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
06584
06585 if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix,
06586 size_fromInt (default_len)))
06587 {
06588
06589 struct file_name_list *nlist
06590 = (struct file_name_list *) dmalloc (sizeof (*nlist));
06591 size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
06592 char *str = (char *) dmalloc (this_len + 1);
06593 strcpy (str, specd_prefix);
06594 strcat (str, cstring_toCharsSafe (p->fname) + default_len);
06595
06596 nlist->next = NULL;
06597 nlist->fname = cstring_fromChars (str);
06598 nlist->control_macro = 0;
06599 nlist->c_system_include_path = !p->cxx_aware;
06600 nlist->got_name_map = 0;
06601
06602 cppReader_addIncludeChain (pfile, nlist);
06603 if (opts->first_system_include == 0)
06604 {
06605 opts->first_system_include = nlist;
06606 }
06607 }
06608 }
06609 }
06610
06611
06612
06613 for (p = include_defaults; p->fname != NULL; p++)
06614 {
06615
06616 if (!p->cplusplus
06617 || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
06618 {
06619 struct file_name_list *nlist
06620 = (struct file_name_list *) dmalloc (sizeof (*nlist));
06621 nlist->control_macro = 0;
06622 nlist->c_system_include_path = !p->cxx_aware;
06623 nlist->fname = p->fname;
06624 nlist->got_name_map = 0;
06625 nlist->next = NULL;
06626
06627 cppReader_addIncludeChain (pfile, nlist);
06628
06629 if (opts->first_system_include == 0)
06630 {
06631 opts->first_system_include = nlist;
06632 }
06633 }
06634 }
06635 sfree (default_prefix);
06636 }
06637
06638
06639 cppReader_appendIncludeChain (pfile, opts->after_include,
06640 opts->last_after_include);
06641
06642 if (opts->first_system_include == 0)
06643 {
06644 opts->first_system_include = opts->after_include;
06645 }
06646
06647
06648 if (opts->verbose) {
06649 struct file_name_list *p;
06650 fprintf (stderr, "#include \"...\" search starts here:\n");
06651
06652 for (p = opts->include; p != NULL; p = p->next) {
06653 if (p == opts->first_bracket_include)
06654 fprintf (stderr, "#include <...> search starts here:\n");
06655
06656 fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
06657 }
06658 fprintf (stderr, "End of search list.\n");
06659 }
06660 }
06661
06662 int cppReader_startProcess (cppReader *pfile, cstring fname)
06663 {
06664 cppBuffer *fp;
06665 int f;
06666 struct cppOptions *opts = CPPOPTIONS (pfile);
06667
06668 fp = cppReader_pushBuffer (pfile, NULL, 0);
06669
06670 if (fp == NULL)
06671 {
06672 return 0;
06673 }
06674
06675 if (opts->in_fname == NULL)
06676 {
06677 opts->in_fname = cstring_makeLiteralTemp ("");
06678 }
06679
06680 fp->fname = opts->in_fname;
06681 fp->nominal_fname = fp->fname;
06682 fp->lineno = 0;
06683
06684
06685
06686
06687 if (cstring_isEmpty (fname))
06688 {
06689 fname = cstring_makeLiteralTemp ("");
06690 f = 0;
06691 }
06692 else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
06693 {
06694 cppReader_pfatalWithName (pfile, fname);
06695 }
06696 else
06697 {
06698 ;
06699 }
06700
06701 if (finclude (pfile, f, fname, 0, NULL))
06702 {
06703 output_line_command (pfile, 0, same_file);
06704 }
06705
06706 return 1;
06707 }
06708
06709 static cppBuffer *cppReader_getBuffer (cppReader *pfile)
06710 {
06711 return pfile->buffer;
06712 }
06713
06714 cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
06715 {
06716 llassert (pfile->buffer != NULL);
06717 return pfile->buffer;
06718 }
06719
06720 char *cppLineBase (cppBuffer *buf)
06721 {
06722 llassert (buf->buf != NULL);
06723 return (buf->buf + buf->line_base);
06724 }
06725
06726 int cppBufPeek (cppBuffer *buf)
06727 {
06728 if (buf->cur == NULL || buf->rlimit == NULL) {
06729 return EOF;
06730 }
06731
06732 if (buf->cur < buf->rlimit) {
06733 return *(buf->cur);
06734 }
06735
06736 return EOF;
06737 }
06738
06739 bool cppBuffer_isMacro (cppBuffer *buf)
06740 {
06741 if (buf != NULL)
06742 {
06743 return (buf->cleanup == cppReader_macroCleanup);
06744 }
06745
06746 return FALSE;
06747 }
06748
06749
06750
06751
06752
06753
06754 static bool notparseable = FALSE;
06755 static bool notfunction = FALSE;
06756 static bool expectiter = FALSE;
06757 static bool expectenditer = FALSE;
06758 static bool expectfunction = FALSE;
06759 static bool expectconstant = FALSE;
06760 static bool expectmacro = FALSE;
06761
06762 static void cpp_setLocation (cppReader *pfile)
06763 {
06764 fileId fid;
06765 int line;
06766
06767 if (pfile->buffer != NULL)
06768 {
06769 if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname))
06770 {
06771 cstring fname = cppReader_getBuffer (pfile)->nominal_fname;
06772
06773 if (fileTable_exists (context_fileTable (), fname))
06774 {
06775 fid = fileTable_lookup (context_fileTable (), fname);
06776 }
06777 else
06778 {
06779 fid = fileTable_lookup (context_fileTable (),
06780 cppReader_getBuffer (pfile)->fname);
06781 }
06782 }
06783 else
06784 {
06785 fid = fileTable_lookup (context_fileTable (),
06786 cppReader_getBuffer (pfile)->fname);
06787 }
06788
06789 line = cppReader_getBuffer (pfile)->lineno;
06790 fileloc_free (g_currentloc);
06791 g_currentloc = fileloc_create (fid, line, 1);
06792 }
06793 else
06794 {
06795 fileloc_free (g_currentloc);
06796 g_currentloc = fileloc_createBuiltin ();
06797 }
06798 }
06799
06800 static bool cpp_shouldCheckMacro (cppReader *pfile, char *p)
06801 {
06802 bool checkmacro = FALSE;
06803 bool hasParams = FALSE;
06804 bool noexpand = FALSE;
06805 cstring sname;
06806 char c;
06807
06808 cpp_setLocation (pfile);
06809
06810 DPRINTF (("Should check macro? %s", p));
06811
06812 if (expectiter || expectconstant || expectenditer)
06813 {
06814 if (expectiter)
06815 {
06816 expectiter = FALSE;
06817 expectenditer = TRUE;
06818 }
06819 else
06820 {
06821 expectiter = FALSE;
06822 expectconstant = FALSE;
06823 expectenditer = FALSE;
06824 }
06825
06826 if (notfunction || notparseable)
06827 {
06828 notfunction = FALSE;
06829 notparseable = FALSE;
06830 return FALSE;
06831 }
06832 else
06833 {
06834 return TRUE;
06835 }
06836 }
06837
06838 llassert (*p == '#');
06839 p++;
06840
06841 while (*p == ' ' || *p == '\t')
06842 {
06843 p++;
06844 }
06845
06846 llassert (*p == 'd');
06847
06848 p += 6;
06849
06850 while (*p == ' ' || *p == '\t')
06851 {
06852 p++;
06853 }
06854
06855 sname = cstring_fromChars (p);
06856 DPRINTF (("Check macro: %s", sname));
06857
06858 while (((c = *p) != ' ')
06859 && c != '\0' && c != '('
06860 && c != '\t' && c != '\\' && c != '\n'
06861 && !iscntrl (c))
06862 {
06863 p++;
06864 }
06865
06866 hasParams = (c == '(');
06867 *p = '\0';
06868
06869
06870 if (notparseable)
06871 {
06872 notparseable = FALSE;
06873 }
06874 else if (notfunction || fileloc_isStandardLib (g_currentloc))
06875 {
06876 DPRINTF (("Clear notfunction"));
06877 notfunction = FALSE;
06878 }
06879 else
06880 {
06881 if (noexpand)
06882 {
06883 checkmacro = TRUE;
06884
06885 if (!expectenditer)
06886 {
06887 noexpand = FALSE;
06888 }
06889 }
06890 else
06891 {
06892 if (usymtab_existsReal (sname))
06893 {
06894 uentry ue = usymtab_lookup (sname);
06895
06896 DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
06897
06898 if (fileloc_isPreproc (uentry_whereLast (ue)))
06899 {
06900 goto macroDne;
06901 }
06902 else
06903 {
06904 if (uentry_isSpecified (ue))
06905 {
06906 checkmacro = context_getFlag (FLG_SPECMACROS);
06907 }
06908 else
06909 {
06910 if (hasParams)
06911 {
06912 checkmacro = context_getFlag (FLG_LIBMACROS)
06913 || context_getFlag (FLG_FCNMACROS);
06914 }
06915 }
06916 }
06917 }
06918 else
06919 {
06920 macroDne:
06921 DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
06922
06923 if (fileloc_isSystemFile (g_currentloc)
06924 && context_getFlag (FLG_SYSTEMDIREXPAND))
06925 {
06926 ;
06927 DPRINTF (("Don't check 1"));
06928 }
06929 else
06930 {
06931 uentry le;
06932
06933 if (hasParams)
06934 {
06935 DPRINTF (("Has params..."));
06936
06937 if (context_getFlag (FLG_FCNMACROS))
06938 {
06939 if (usymtab_exists (sname))
06940 {
06941
06942
06943
06944
06945
06946 DPRINTF (("It exists!"));
06947 }
06948 else
06949 {
06950
06951
06952
06953
06954
06955
06956 fileloc loc = fileloc_makePreproc (g_currentloc);
06957
06958
06959 decLine ();
06960
06961 if (expectfunction)
06962 {
06963 expectfunction = FALSE;
06964 }
06965
06966 le = uentry_makeForwardFunction (sname,
06967 typeId_invalid, loc);
06968
06969 fileloc_free (loc);
06970
06971 incLine ();
06972
06973
06974
06975 (void) usymtab_addEntry (le);
06976 }
06977
06978 checkmacro = TRUE;
06979 DPRINTF (("Check: TRUE"));
06980 }
06981 else
06982 {
06983 DPRINTF (("Flag FCN_MACROS not set!"));
06984 }
06985 }
06986 else
06987 {
06988 DPRINTF (("No params"));
06989
06990 if (context_getFlag (FLG_CONSTMACROS))
06991 {
06992 bool nocontent = FALSE;
06993
06994 if (c == '\0')
06995 {
06996 nocontent = TRUE;
06997 }
06998 else
06999 {
07000 if (isspace (c))
07001 {
07002 char *rest = p + 1;
07003
07004
07005
07006
07007
07008 while ((*rest) != '\0' && isspace (*rest))
07009 {
07010 rest++;
07011 }
07012
07013 if (*rest == '\0')
07014 {
07015 nocontent = TRUE;
07016 }
07017 }
07018 }
07019
07020 if (usymtab_exists (sname))
07021 {
07022 ;
07023 }
07024 else
07025 {
07026 fileloc loc = fileloc_makePreproc (g_currentloc);
07027 DPRINTF (("Make constant: %s", sname));
07028 le = uentry_makeConstant (sname,
07029 ctype_unknown, loc);
07030 (void) usymtab_addEntry (le);
07031 }
07032
07033 checkmacro = !nocontent;
07034 }
07035 }
07036 }
07037
07038 if (checkmacro && usymtab_existsType (sname))
07039 {
07040 DPRINTF (("Making false..."));
07041 decLine ();
07042 ppllerror (message ("Specified type implemented as macro: %s", sname));
07043 checkmacro = FALSE;
07044 incLine ();
07045 }
07046 }
07047 }
07048 }
07049
07050 if (!checkmacro)
07051 {
07052 if (usymtab_exists (sname))
07053 {
07054 uentry ue = usymtab_lookupExpose (sname);
07055 fileloc tloc = fileloc_makePreproc (g_currentloc);
07056
07057 uentry_setDefined (ue, tloc);
07058 fileloc_free (tloc);
07059 uentry_setUsed (ue, fileloc_undefined);
07060 }
07061 else
07062 {
07063 fileloc tloc = fileloc_makePreproc (g_currentloc);
07064 uentry ue = uentry_makeExpandedMacro (sname, tloc);
07065 DPRINTF (("Make expanded macro: %s", sname));
07066 DPRINTF (("Not in symbol table: %s", sname));
07067
07068 (void) usymtab_addGlobalEntry (ue);
07069 fileloc_free (tloc);
07070 }
07071 }
07072
07073 *p = c;
07074 DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
07075 return checkmacro;
07076 }
07077
07078 static enum cpp_token
07079 cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
07080 {
07081 cppBuffer *pbuf = cppReader_getBuffer (pfile);
07082 char *start;
07083 int len;
07084 bool eliminateComment = FALSE;
07085
07086 llassert (pbuf->buf != NULL);
07087
07088 start = pbuf->buf + smark->position;
07089
07090 llassert (pbuf->cur != NULL);
07091 len = pbuf->cur - start;
07092
07093 if (start[0] == '*'
07094 && start[1] == context_getCommentMarkerChar ())
07095 {
07096 int i;
07097 char c = ' ';
07098 char *scomment = start + 2;
07099
07100 start[0] = BEFORE_COMMENT_MARKER[0];
07101 start[1] = BEFORE_COMMENT_MARKER[1];
07102
07103 llassert (start[len - 2] == '*');
07104 start[len - 2] = AFTER_COMMENT_MARKER[0];
07105
07106 llassert (start[len - 1] == '/');
07107 start[len - 1] = AFTER_COMMENT_MARKER[1];
07108
07109 cppReader_reserve(pfile, size_fromInt (1 + len));
07110 cppReader_putCharQ (pfile, c);
07111
07112 cpp_setLocation (pfile);
07113
07114 if (mstring_equalPrefix (scomment, "ignore"))
07115 {
07116 if (!context_getFlag (FLG_NOCOMMENTS))
07117 {
07118 context_enterSuppressRegion ();
07119 }
07120 }
07121 else if (mstring_equalPrefix (scomment, "end"))
07122 {
07123 if (!context_getFlag (FLG_NOCOMMENTS))
07124 {
07125 context_exitSuppressRegion ();
07126 }
07127 }
07128 else if (mstring_equalPrefix (scomment, "notparseable"))
07129 {
07130 notparseable = TRUE;
07131 expectmacro = TRUE;
07132 eliminateComment = TRUE;
07133 }
07134 else if (mstring_equalPrefix (scomment, "notfunction"))
07135 {
07136 notfunction = TRUE;
07137 expectmacro = TRUE;
07138 eliminateComment = TRUE;
07139 }
07140 else if (mstring_equalPrefix (scomment, "iter"))
07141 {
07142 expectiter = TRUE;
07143 }
07144 else if (mstring_equalPrefix (scomment, "function"))
07145 {
07146 expectfunction = TRUE;
07147 }
07148 else if (mstring_equalPrefix (scomment, "constant"))
07149 {
07150 expectconstant = TRUE;
07151 }
07152 else
07153 {
07154 char sChar = *scomment;
07155
07156 if (sChar == '='
07157 || sChar == '-'
07158 || sChar == '+')
07159 {
07160 char *rest = scomment + 1;
07161
07162 if (mstring_equalPrefix (rest, "commentchar"))
07163 {
07164 eliminateComment = TRUE;
07165
07166 if (sChar == '=')
07167 {
07168 ppllerror (cstring_makeLiteral
07169 ("Cannot restore commentchar"));
07170 }
07171 else
07172 {
07173 char *next = scomment + 12;
07174
07175 if (*next != ' ' && *next != '\t' && *next != '\n')
07176 {
07177 ppllerror
07178 (message
07179 ("Syntactic commentchar comment is not followed by a "
07180 "whitespace character: %c",
07181 *next));
07182 }
07183 else
07184 {
07185 char cchar = *(next + 1);
07186
07187 if (cchar == '\0')
07188 {
07189 ppllerror
07190 (cstring_makeLiteral
07191 ("Cannot set commentchar to NUL"));
07192 }
07193 else
07194 {
07195 context_setCommentMarkerChar (cchar);
07196
07197 }
07198 }
07199 }
07200 }
07201 else if (mstring_equalPrefix (rest, "namechecks"))
07202 {
07203 context_fileSetFlag (FLG_NAMECHECKS,
07204 ynm_fromCodeChar (sChar));
07205 }
07206 else if (mstring_equalPrefix (rest, "macroredef"))
07207 {
07208 context_fileSetFlag (FLG_MACROREDEF,
07209 ynm_fromCodeChar (sChar));
07210 }
07211 else if (mstring_equalPrefix (rest, "usevarargs"))
07212 {
07213 context_fileSetFlag (FLG_USEVARARGS,
07214 ynm_fromCodeChar (sChar));
07215 }
07216 else if (mstring_equalPrefix (rest, "nextlinemacros"))
07217 {
07218 context_fileSetFlag (FLG_MACRONEXTLINE,
07219 ynm_fromCodeChar (sChar));
07220 }
07221 else if (mstring_equalPrefix (rest, "allmacros")
07222 || mstring_equalPrefix (rest, "fcnmacros")
07223 || mstring_equalPrefix (rest, "constmacros"))
07224 {
07225 flagcode fl;
07226
07227 if (mstring_equalPrefix (rest, "allmacros"))
07228 {
07229 fl = FLG_ALLMACROS;
07230 }
07231 else if (mstring_equalPrefix (rest, "fcnmacros"))
07232 {
07233 fl = FLG_FCNMACROS;
07234 }
07235 else
07236 {
07237 llassert (mstring_equalPrefix (rest, "constmacros"));
07238 fl = FLG_CONSTMACROS;
07239 }
07240
07241
07242 context_fileSetFlag (fl, ynm_fromCodeChar (sChar));
07243 notfunction = FALSE;
07244 }
07245 else
07246 {
07247 ;
07248 }
07249 }
07250 else
07251 {
07252 ;
07253 }
07254 }
07255
07256 if (eliminateComment)
07257 {
07258 goto removeComment;
07259 }
07260
07261
07262
07263 for (i = 2; i < len - 2; i++)
07264 {
07265 if (start[i] == BEFORE_COMMENT_MARKER[0]
07266 || start[i] == BEFORE_COMMENT_MARKER[1]
07267 || start[i] == context_getCommentMarkerChar ())
07268 {
07269 start[i] = ' ';
07270 }
07271 }
07272
07273 cppReader_putStrN (pfile, start, size_fromInt (len));
07274 parseClearMark (smark);
07275 return CPP_COMMENT;
07276 }
07277 else
07278 {
07279 removeComment:
07280 {
07281 int i;
07282
07283
07284
07285
07286
07287
07288 char c = ' ';
07289 cstring lintcomment = cstring_undefined;
07290
07291 if (context_getFlag (FLG_LINTCOMMENTS))
07292 {
07293 if (mstring_equalPrefix (start, "*NOTREACHED*/"))
07294 {
07295 lintcomment = cstring_makeLiteralTemp ("l_notreach");
07296 }
07297 else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
07298 {
07299 lintcomment = cstring_makeLiteralTemp ("l_printfli");
07300 }
07301 else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
07302 {
07303 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
07304 }
07305 else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
07306 {
07307 lintcomment = cstring_makeLiteralTemp ("l_argsus");
07308 }
07309 else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
07310 {
07311 lintcomment = cstring_makeLiteralTemp ("l_fallth");
07312 }
07313 else
07314 {
07315 lintcomment = cstring_undefined;
07316 }
07317 }
07318 else
07319 {
07320 lintcomment = cstring_undefined;
07321 }
07322
07323 if (cstring_isDefined (lintcomment))
07324 {
07325 c = BEFORE_COMMENT_MARKER[0];
07326 start[0] = BEFORE_COMMENT_MARKER[1];
07327
07328 llassert (cstring_length (lintcomment) == len - 3);
07329
07330 for (i = 1; i < len - 2; i++)
07331 {
07332 start[i] = cstring_getChar (lintcomment, i);
07333 }
07334
07335 start[len - 2] = AFTER_COMMENT_MARKER[0];
07336 start[len - 1] = AFTER_COMMENT_MARKER[1];
07337 }
07338 else
07339 {
07340
07341 for (i = 0; i < len; i++)
07342 {
07343 if (start[i] == '/'
07344 && i < len - 1
07345 && start[i + 1] == '*') {
07346 cppReader_warning
07347 (pfile,
07348 message ("Start comment inside comment"));
07349 }
07350
07351 if (start[i] != '\n')
07352 {
07353 start[i] = ' ';
07354 }
07355 }
07356 }
07357
07358 cppReader_reserve (pfile, size_fromInt (1 + len));
07359 cppReader_putCharQ (pfile, c);
07360 cppReader_putStrN (pfile, start, size_fromInt (len));
07361 parseClearMark (smark);
07362 return CPP_COMMENT;
07363 }
07364 }
07365 }
07366
07367 static int cpp_openIncludeFile (char *filename)
07368 {
07369 int res = open (filename, O_RDONLY, 0666);
07370
07371 if (res
07372 && !fileTable_exists (context_fileTable (),
07373 cstring_fromChars (filename)))
07374 {
07375 DPRINTF (("Add header: %s", filename));
07376 (void) fileTable_addHeaderFile (context_fileTable (),
07377 cstring_fromChars (filename));
07378 }
07379
07380 return res;
07381 }
07382
07383 static bool cpp_skipIncludeFile (cstring fname)
07384 {
07385 if (context_isSystemDir (fname))
07386 {
07387 DPRINTF (("System dir: %s", fname));
07388
07389 if (lcllib_isSkipHeader (fname))
07390 {
07391 DPRINTF (("Skip include TRUE: %s", fname));
07392 return TRUE;
07393 }
07394
07395 if (context_getFlag (FLG_SKIPSYSHEADERS))
07396 {
07397 DPRINTF (("Skip include TRUE: %s", fname));
07398 return TRUE;
07399 }
07400 }
07401
07402 if (context_getFlag (FLG_SINGLEINCLUDE))
07403 {
07404 fname = cstring_fromChars (removePreDirs (cstring_toCharsSafe (fname)));
07405
07406 # if defined (WIN32) || defined (OS2)
07407 cstring_replaceAll (fname, '\\', '/');
07408 # endif
07409
07410 if (fileTable_exists (context_fileTable (), fname))
07411 {
07412 DPRINTF (("Skip include TRUE: %s", fname));
07413 return TRUE;
07414 }
07415 }
07416
07417 DPRINTF (("Skip include FALSE: %s", fname));
07418 return FALSE;
07419 }
07420
07421 static int cpp_peekN (cppReader *pfile, int n)
07422 {
07423 cppBuffer *buf = cppReader_getBuffer (pfile);
07424
07425 llassert (buf->cur != NULL);
07426
07427 return (buf->rlimit - buf->cur >= (n)
07428 ? buf->cur[n]
07429 : EOF);
07430 }
07431
07432 cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
07433 {
07434 return buf + 1;
07435 }
07436
07437 void cppBuffer_forward (cppBuffer *buf, int n)
07438 {
07439 llassert (buf->cur != NULL);
07440 buf->cur += n;
07441 }