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