|
|
1.1 root 1: /* C Compatible Compiler Preprocessor (CCCP) 1.1.1.7 ! root 2: Copyright (C) 1986, 87, 89, 92, 93, 1994 Free Software Foundation, Inc. ! 3: Written by Paul Rubin, June 1986 ! 4: Adapted to ANSI C, Richard Stallman, Jan 1987 1.1 root 5: 6: This program is free software; you can redistribute it and/or modify it 7: under the terms of the GNU General Public License as published by the 8: Free Software Foundation; either version 2, or (at your option) any 9: later version. 10: 11: This program is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with this program; if not, write to the Free Software 18: Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19: 20: In other words, you are welcome to use, share and improve this program. 21: You are forbidden to forbid anyone else to use, share and improve 22: what you give them. Help stamp out software-hoarding! */ 23: 24: typedef unsigned char U_CHAR; 25: 26: #ifdef EMACS 27: #define NO_SHORTNAMES 28: #include "../src/config.h" 29: #ifdef open 30: #undef open 31: #undef read 32: #undef write 33: #endif /* open */ 34: #endif /* EMACS */ 35: 36: /* The macro EMACS is defined when cpp is distributed as part of Emacs, 37: for the sake of machines with limited C compilers. */ 38: #ifndef EMACS 39: #include "config.h" 40: #endif /* not EMACS */ 41: 42: #ifndef STANDARD_INCLUDE_DIR 43: #define STANDARD_INCLUDE_DIR "/usr/include" 44: #endif 45: 46: #ifndef LOCAL_INCLUDE_DIR 47: #define LOCAL_INCLUDE_DIR "/usr/local/include" 48: #endif 49: 1.1.1.4 root 50: #if 0 /* We can't get ptrdiff_t, so I arranged not to need PTR_INT_TYPE. */ 51: #ifdef __STDC__ 52: #define PTR_INT_TYPE ptrdiff_t 53: #else 54: #define PTR_INT_TYPE long 55: #endif 56: #endif /* 0 */ 57: 1.1 root 58: #include "pcp.h" 59: 60: #ifndef STDC_VALUE 61: #define STDC_VALUE 1 62: #endif 63: 1.1.1.3 root 64: /* By default, colon separates directories in a path. */ 65: #ifndef PATH_SEPARATOR 66: #define PATH_SEPARATOR ':' 67: #endif 68: 1.1 root 69: /* In case config.h defines these. */ 70: #undef bcopy 71: #undef bzero 72: #undef bcmp 73: 74: #include <sys/types.h> 75: #include <sys/stat.h> 76: #include <ctype.h> 77: #include <stdio.h> 1.1.1.5 root 78: #include <signal.h> 1.1 root 79: 80: #ifndef VMS 81: #ifndef USG 82: #include <sys/time.h> /* for __DATE__ and __TIME__ */ 83: #include <sys/resource.h> 84: #else 85: #include <time.h> 86: #include <fcntl.h> 87: #endif /* USG */ 88: #endif /* not VMS */ 89: 1.1.1.5 root 90: /* This defines "errno" properly for VMS, and gives us EACCES. */ 91: #include <errno.h> 92: 1.1 root 93: /* VMS-specific definitions */ 94: #ifdef VMS 95: #include <time.h> 96: #include <descrip.h> 97: #define O_RDONLY 0 /* Open arg for Read/Only */ 98: #define O_WRONLY 1 /* Open arg for Write/Only */ 1.1.1.5 root 99: #define read(fd,buf,size) VMS_read (fd,buf,size) 100: #define write(fd,buf,size) VMS_write (fd,buf,size) 101: #define open(fname,mode,prot) VMS_open (fname,mode,prot) 102: #define fopen(fname,mode) VMS_fopen (fname,mode) 103: #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile) 104: #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt) 1.1.1.4 root 105: static char * VMS_strncat (); 1.1 root 106: static int VMS_read (); 107: static int VMS_write (); 108: static int VMS_open (); 109: static FILE * VMS_fopen (); 110: static FILE * VMS_freopen (); 111: static void hack_vms_include_specification (); 112: typedef struct { unsigned :16, :16, :16; } vms_ino_t; 113: #define ino_t vms_ino_t 1.1.1.4 root 114: #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */ 1.1 root 115: #ifdef __GNUC__ 116: #define BSTRING /* VMS/GCC supplies the bstring routines */ 117: #endif /* __GNUC__ */ 118: #endif /* VMS */ 1.1.1.4 root 119: 120: extern char *index (); 121: extern char *rindex (); 1.1 root 122: 123: #ifndef O_RDONLY 124: #define O_RDONLY 0 125: #endif 126: 127: #undef MIN 128: #undef MAX 129: #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) 130: #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) 131: 1.1.1.4 root 132: /* Find the largest host integer type and set its size and type. */ 133: 134: #ifndef HOST_BITS_PER_WIDE_INT 135: 136: #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT 137: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG 138: #define HOST_WIDE_INT long 139: #else 140: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT 141: #define HOST_WIDE_INT int 142: #endif 143: 144: #endif 145: 1.1 root 146: #ifndef S_ISREG 147: #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 148: #endif 149: 1.1.1.5 root 150: #ifndef S_ISDIR 151: #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 152: #endif 153: 1.1.1.4 root 154: /* Define a generic NULL if one hasn't already been defined. */ 155: 156: #ifndef NULL 157: #define NULL 0 158: #endif 159: 160: #ifndef GENERIC_PTR 161: #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) 162: #define GENERIC_PTR void * 163: #else 164: #define GENERIC_PTR char * 165: #endif 166: #endif 167: 168: #ifndef NULL_PTR 169: #define NULL_PTR ((GENERIC_PTR)0) 170: #endif 171: 172: #ifndef INCLUDE_LEN_FUDGE 173: #define INCLUDE_LEN_FUDGE 0 174: #endif 175: 176: /* Forward declarations. */ 1.1 root 177: 178: char *xmalloc (); 179: void error (); 180: void warning (); 181: 182: /* External declarations. */ 183: 184: extern char *getenv (); 185: extern FILE *fdopen (); 186: extern char *version_string; 187: extern struct tm *localtime (); 1.1.1.7 ! root 188: #ifndef VMS ! 189: #ifndef HAVE_STRERROR 1.1 root 190: extern int sys_nerr; 1.1.1.7 ! root 191: #if defined(bsd4_4) || defined(__NetBSD__) 1.1.1.6 root 192: extern const char *const sys_errlist[]; 193: #else 1.1 root 194: extern char *sys_errlist[]; 1.1.1.6 root 195: #endif 1.1.1.7 ! root 196: #else /* HAVE_STERRROR */ ! 197: char *strerror (); ! 198: #endif ! 199: #else /* VMS */ ! 200: char *strerror (int,...); ! 201: #endif 1.1.1.6 root 202: extern int parse_escape (); 1.1.1.7 ! root 203: extern HOST_WIDE_INT parse_c_expression (); 1.1 root 204: 205: #ifndef errno 206: extern int errno; 207: #endif 208: 209: /* Forward declarations. */ 210: 211: struct directive; 212: struct file_buf; 213: struct arglist; 214: struct argdata; 215: 216: #if defined(USG) || defined(VMS) 217: #ifndef BSTRING 218: void bcopy (); 219: void bzero (); 220: int bcmp (); 221: #endif 222: #endif 223: 224: /* These functions are declared to return int instead of void since they 225: are going to be placed in a table and some old compilers have trouble with 226: pointers to functions returning void. */ 227: 228: static int do_define (); 229: static int do_line (); 230: static int do_include (); 231: static int do_undef (); 232: static int do_error (); 233: static int do_pragma (); 234: static int do_ident (); 235: static int do_if (); 236: static int do_xifdef (); 237: static int do_else (); 238: static int do_elif (); 239: static int do_endif (); 240: static int do_sccs (); 241: static int do_once (); 242: static int do_assert (); 243: static int do_unassert (); 244: static int do_warning (); 245: 246: static void add_import (); 1.1.1.4 root 247: static void append_include_chain (); 1.1 root 248: static void deps_output (); 249: static void make_undef (); 250: static void make_definition (); 251: static void make_assertion (); 252: static void path_include (); 253: static void initialize_builtins (); 254: static void initialize_char_syntax (); 255: static void dump_arg_n (); 256: static void dump_defn_1 (); 257: static void delete_macro (); 258: static void trigraph_pcp (); 259: static void rescan (); 260: static void finclude (); 261: static void validate_else (); 262: static int comp_def_part (); 263: static void error_from_errno (); 264: static void error_with_line (); 265: void pedwarn (); 1.1.1.5 root 266: void pedwarn_with_line (); 1.1 root 267: static void pedwarn_with_file_and_line (); 268: static void fatal (); 269: void fancy_abort (); 270: static void pfatal_with_name (); 271: static void perror_with_name (); 1.1.1.5 root 272: static void pipe_closed (); 1.1 root 273: static void print_containing_files (); 274: static int lookup_import (); 1.1.1.4 root 275: static int redundant_include_p (); 276: static is_system_include (); 1.1.1.7 ! root 277: static struct file_name_map *read_name_map (); ! 278: static char *read_filename_string (); ! 279: static int open_include_file (); 1.1 root 280: static int check_preconditions (); 281: static void pcfinclude (); 282: static void pcstring_used (); 283: static void write_output (); 284: static int check_macro_name (); 285: static int compare_defs (); 286: static int compare_token_lists (); 1.1.1.7 ! root 287: static HOST_WIDE_INT eval_if_expression (); 1.1 root 288: static int discard_comments (); 1.1.1.5 root 289: static int change_newlines (); 1.1 root 290: static int line_for_error (); 291: static int hashf (); 292: static int file_size_and_mode (); 293: 294: static struct arglist *read_token_list (); 295: static void free_token_list (); 296: 297: static struct hashnode *install (); 298: struct hashnode *lookup (); 299: 300: static struct assertion_hashnode *assertion_install (); 301: static struct assertion_hashnode *assertion_lookup (); 302: 303: static char *xrealloc (); 304: static char *xcalloc (); 305: static char *savestring (); 306: 307: static void delete_assertion (); 308: static void macroexpand (); 309: static void dump_all_macros (); 310: static void conditional_skip (); 311: static void skip_if_group (); 312: static void output_line_command (); 313: 314: /* Last arg to output_line_command. */ 315: enum file_change_code {same_file, enter_file, leave_file}; 316: 317: static int grow_outbuf (); 318: static int handle_directive (); 319: static void memory_full (); 320: 321: static U_CHAR *macarg1 (); 322: static char *macarg (); 323: 324: static U_CHAR *skip_to_end_of_comment (); 325: static U_CHAR *skip_quoted_string (); 326: static U_CHAR *skip_paren_group (); 1.1.1.6 root 327: static char *quote_string (); 1.1 root 328: 329: static char *check_precompiled (); 1.1.1.4 root 330: /* static struct macrodef create_definition (); [moved below] */ 1.1 root 331: static void dump_single_macro (); 1.1.1.6 root 332: static void output_dots (); 1.1 root 333: 334: #ifndef FAILURE_EXIT_CODE 335: #define FAILURE_EXIT_CODE 33 /* gnu cc command understands this */ 336: #endif 337: 338: #ifndef SUCCESS_EXIT_CODE 339: #define SUCCESS_EXIT_CODE 0 /* 0 means success on Unix. */ 340: #endif 341: 342: /* Name under which this program was invoked. */ 343: 344: static char *progname; 345: 1.1.1.4 root 346: /* Nonzero means use extra default include directories for C++. */ 1.1 root 347: 348: static int cplusplus; 349: 1.1.1.4 root 350: /* Nonzero means handle cplusplus style comments */ 351: 352: static int cplusplus_comments; 353: 1.1 root 354: /* Nonzero means handle #import, for objective C. */ 355: 356: static int objc; 357: 358: /* Nonzero means this is an assembly file, and allow 359: unknown directives, which could be comments. */ 360: 361: static int lang_asm; 362: 363: /* Current maximum length of directory names in the search path 364: for include files. (Altered as we get more of them.) */ 365: 366: static int max_include_len; 367: 368: /* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */ 369: 1.1.1.7 ! root 370: static int for_lint = 0; 1.1 root 371: 372: /* Nonzero means copy comments into the output file. */ 373: 374: static int put_out_comments = 0; 375: 376: /* Nonzero means don't process the ANSI trigraph sequences. */ 377: 378: static int no_trigraphs = 0; 379: 380: /* Nonzero means print the names of included files rather than 381: the preprocessed output. 1 means just the #include "...", 382: 2 means #include <...> as well. */ 383: 384: static int print_deps = 0; 385: 1.1.1.7 ! root 386: /* Nonzero if missing .h files in -M output are assumed to be generated ! 387: files and not errors. */ ! 388: ! 389: static int print_deps_missing_files = 0; ! 390: 1.1 root 391: /* Nonzero means print names of header files (-H). */ 392: 393: static int print_include_names = 0; 394: 395: /* Nonzero means don't output line number information. */ 396: 397: static int no_line_commands; 398: 1.1.1.7 ! root 399: /* Nonzero means output the text in failing conditionals, ! 400: inside #failed ... #endfailed. */ ! 401: ! 402: static int output_conditionals; ! 403: 1.1 root 404: /* dump_only means inhibit output of the preprocessed text 405: and instead output the definitions of all user-defined 406: macros in a form suitable for use as input to cccp. 407: dump_names means pass #define and the macro name through to output. 408: dump_definitions means pass the whole definition (plus #define) through 409: */ 410: 411: static enum {dump_none, dump_only, dump_names, dump_definitions} 412: dump_macros = dump_none; 413: 414: /* Nonzero means pass all #define and #undef directives which we actually 415: process through to the output stream. This feature is used primarily 416: to allow cc1 to record the #defines and #undefs for the sake of 417: debuggers which understand about preprocessor macros, but it may 418: also be useful with -E to figure out how symbols are defined, and 419: where they are defined. */ 420: static int debug_output = 0; 421: 422: /* Nonzero indicates special processing used by the pcp program. The 423: special effects of this mode are: 424: 425: Inhibit all macro expansion, except those inside #if directives. 426: 427: Process #define directives normally, and output their contents 428: to the output file. 429: 430: Output preconditions to pcp_outfile indicating all the relevant 431: preconditions for use of this file in a later cpp run. 432: */ 433: static FILE *pcp_outfile; 434: 435: /* Nonzero means we are inside an IF during a -pcp run. In this mode 436: macro expansion is done, and preconditions are output for all macro 437: uses requiring them. */ 438: static int pcp_inside_if; 439: 1.1.1.5 root 440: /* Nonzero means never to include precompiled files. 441: This is 1 since there's no way now to make precompiled files, 442: so it's not worth testing for them. */ 443: static int no_precomp = 1; 1.1 root 444: 445: /* Nonzero means give all the error messages the ANSI standard requires. */ 446: 447: int pedantic; 448: 449: /* Nonzero means try to make failure to fit ANSI C an error. */ 450: 451: static int pedantic_errors; 452: 453: /* Nonzero means don't print warning messages. -w. */ 454: 455: static int inhibit_warnings = 0; 456: 457: /* Nonzero means warn if slash-star appears in a comment. */ 458: 459: static int warn_comments; 460: 461: /* Nonzero means warn if a macro argument is (or would be) 462: stringified with -traditional. */ 463: 464: static int warn_stringify; 465: 466: /* Nonzero means warn if there are any trigraphs. */ 467: 468: static int warn_trigraphs; 469: 1.1.1.2 root 470: /* Nonzero means warn if #import is used. */ 471: 472: static int warn_import = 1; 473: 1.1 root 474: /* Nonzero means turn warnings into errors. */ 475: 476: static int warnings_are_errors; 477: 478: /* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */ 479: 480: int traditional; 481: 482: /* Nonzero causes output not to be done, 483: but directives such as #define that have side effects 484: are still obeyed. */ 485: 486: static int no_output; 487: 1.1.1.7 ! root 488: /* Nonzero means this file was included with a -imacros or -include ! 489: command line and should not be recorded as an include file. */ ! 490: ! 491: static int no_record_file; ! 492: 1.1 root 493: /* Nonzero means that we have finished processing the command line options. 494: This flag is used to decide whether or not to issue certain errors 495: and/or warnings. */ 496: 497: static int done_initializing = 0; 1.1.1.5 root 498: 499: /* Line where a newline was first seen in a string constant. */ 500: 501: static int multiline_string_line = 0; 1.1 root 502: 503: /* I/O buffer structure. 504: The `fname' field is nonzero for source files and #include files 505: and for the dummy text used for -D and -U. 506: It is zero for rescanning results of macro expansion 507: and for expanding macro arguments. */ 1.1.1.6 root 508: #define INPUT_STACK_MAX 400 1.1 root 509: static struct file_buf { 510: char *fname; 511: /* Filename specified with #line command. */ 512: char *nominal_fname; 513: /* Record where in the search path this file was found. 514: For #include_next. */ 515: struct file_name_list *dir; 516: int lineno; 517: int length; 518: U_CHAR *buf; 519: U_CHAR *bufp; 520: /* Macro that this level is the expansion of. 521: Included so that we can reenable the macro 522: at the end of this level. */ 523: struct hashnode *macro; 524: /* Value of if_stack at start of this file. 525: Used to prohibit unmatched #endif (etc) in an include file. */ 526: struct if_stack *if_stack; 527: /* Object to be freed at end of input at this level. */ 528: U_CHAR *free_ptr; 529: /* True if this is a header file included using <FILENAME>. */ 530: char system_header_p; 531: } instack[INPUT_STACK_MAX]; 532: 533: static int last_error_tick; /* Incremented each time we print it. */ 534: static int input_file_stack_tick; /* Incremented when the status changes. */ 535: 536: /* Current nesting level of input sources. 537: `instack[indepth]' is the level currently being read. */ 538: static int indepth = -1; 539: #define CHECK_DEPTH(code) \ 540: if (indepth >= (INPUT_STACK_MAX - 1)) \ 541: { \ 542: error_with_line (line_for_error (instack[indepth].lineno), \ 543: "macro or `#include' recursion too deep"); \ 544: code; \ 545: } 546: 547: /* Current depth in #include directives that use <...>. */ 548: static int system_include_depth = 0; 549: 550: typedef struct file_buf FILE_BUF; 551: 552: /* The output buffer. Its LENGTH field is the amount of room allocated 553: for the buffer, not the number of chars actually present. To get 554: that, subtract outbuf.buf from outbuf.bufp. */ 555: 556: #define OUTBUF_SIZE 10 /* initial size of output buffer */ 557: static FILE_BUF outbuf; 558: 559: /* Grow output buffer OBUF points at 560: so it can hold at least NEEDED more chars. */ 561: 562: #define check_expand(OBUF, NEEDED) \ 563: (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED)) \ 564: ? grow_outbuf ((OBUF), (NEEDED)) : 0) 565: 566: struct file_name_list 567: { 568: struct file_name_list *next; 569: char *fname; 570: /* If the following is nonzero, it is a macro name. 571: Don't include the file again if that macro is defined. */ 572: U_CHAR *control_macro; 1.1.1.6 root 573: /* If the following is nonzero, it is a C-language system include 574: directory. */ 575: int c_system_include_path; 1.1.1.7 ! root 576: /* Mapping of file names for this directory. */ ! 577: struct file_name_map *name_map; ! 578: /* Non-zero if name_map is valid. */ ! 579: int got_name_map; 1.1 root 580: }; 581: 582: /* #include "file" looks in source file dir, then stack. */ 583: /* #include <file> just looks in the stack. */ 584: /* -I directories are added to the end, then the defaults are added. */ 1.1.1.7 ! root 585: /* The */ ! 586: static struct default_include { ! 587: char *fname; /* The name of the directory. */ ! 588: int cplusplus; /* Only look here if we're compiling C++. */ ! 589: int cxx_aware; /* Includes in this directory don't need to ! 590: be wrapped in extern "C" when compiling ! 591: C++. */ ! 592: } include_defaults_array[] 1.1 root 593: #ifdef INCLUDE_DEFAULTS 594: = INCLUDE_DEFAULTS; 595: #else 596: = { 597: /* Pick up GNU C++ specific include files. */ 1.1.1.7 ! root 598: { GPLUSPLUS_INCLUDE_DIR, 1, 1 }, 1.1 root 599: #ifdef CROSS_COMPILE 1.1.1.5 root 600: /* This is the dir for fixincludes. Put it just before 601: the files that we fix. */ 1.1.1.7 ! root 602: { GCC_INCLUDE_DIR, 0, 0 }, 1.1 root 603: /* For cross-compilation, this dir name is generated 604: automatically in Makefile.in. */ 1.1.1.7 ! root 605: { CROSS_INCLUDE_DIR, 0, 0 }, 1.1.1.5 root 606: /* This is another place that the target system's headers might be. */ 1.1.1.7 ! root 607: { TOOL_INCLUDE_DIR, 0, 0 }, 1.1 root 608: #else /* not CROSS_COMPILE */ 1.1.1.7 ! root 609: /* This should be /usr/local/include and should come before 1.1.1.5 root 610: the fixincludes-fixed header files. */ 1.1.1.7 ! root 611: { LOCAL_INCLUDE_DIR, 0, 1 }, 1.1.1.5 root 612: /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here. 613: Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */ 1.1.1.7 ! root 614: { TOOL_INCLUDE_DIR, 0, 0 }, 1.1.1.5 root 615: /* This is the dir for fixincludes. Put it just before 616: the files that we fix. */ 1.1.1.7 ! root 617: { GCC_INCLUDE_DIR, 0, 0 }, 1.1 root 618: /* Some systems have an extra dir of include files. */ 619: #ifdef SYSTEM_INCLUDE_DIR 1.1.1.7 ! root 620: { SYSTEM_INCLUDE_DIR, 0, 0 }, 1.1 root 621: #endif 1.1.1.7 ! root 622: { STANDARD_INCLUDE_DIR, 0, 0 }, 1.1 root 623: #endif /* not CROSS_COMPILE */ 1.1.1.7 ! root 624: { 0, 0, 0 } 1.1 root 625: }; 626: #endif /* no INCLUDE_DEFAULTS */ 627: 628: /* The code looks at the defaults through this pointer, rather than through 629: the constant structure above. This pointer gets changed if an environment 630: variable specifies other defaults. */ 631: static struct default_include *include_defaults = include_defaults_array; 632: 633: static struct file_name_list *include = 0; /* First dir to search */ 634: /* First dir to search for <file> */ 1.1.1.4 root 635: /* This is the first element to use for #include <...>. 636: If it is 0, use the entire chain for such includes. */ 1.1 root 637: static struct file_name_list *first_bracket_include = 0; 1.1.1.4 root 638: /* This is the first element in the chain that corresponds to 639: a directory of system header files. */ 640: static struct file_name_list *first_system_include = 0; 1.1 root 641: static struct file_name_list *last_include = 0; /* Last in chain */ 642: 643: /* Chain of include directories to put at the end of the other chain. */ 644: static struct file_name_list *after_include = 0; 645: static struct file_name_list *last_after_include = 0; /* Last in chain */ 646: 1.1.1.7 ! root 647: /* Chain to put at the start of the system include files. */ ! 648: static struct file_name_list *before_system = 0; ! 649: static struct file_name_list *last_before_system = 0; /* Last in chain */ ! 650: 1.1 root 651: /* List of included files that contained #pragma once. */ 652: static struct file_name_list *dont_repeat_files = 0; 653: 654: /* List of other included files. 655: If ->control_macro if nonzero, the file had a #ifndef 656: around the entire contents, and ->control_macro gives the macro name. */ 657: static struct file_name_list *all_include_files = 0; 658: 1.1.1.3 root 659: /* Directory prefix that should replace `/usr' in the standard 660: include file directories. */ 661: static char *include_prefix; 662: 1.1 root 663: /* Global list of strings read in from precompiled files. This list 664: is kept in the order the strings are read in, with new strings being 665: added at the end through stringlist_tailp. We use this list to output 666: the strings at the end of the run. 667: */ 668: static STRINGDEF *stringlist; 669: static STRINGDEF **stringlist_tailp = &stringlist; 670: 671: 672: /* Structure returned by create_definition */ 673: typedef struct macrodef MACRODEF; 674: struct macrodef 675: { 676: struct definition *defn; 677: U_CHAR *symnam; 678: int symlen; 679: }; 680: 1.1.1.4 root 681: static struct macrodef create_definition (); 682: 1.1 root 683: 684: /* Structure allocated for every #define. For a simple replacement 685: such as 686: #define foo bar , 687: nargs = -1, the `pattern' list is null, and the expansion is just 688: the replacement text. Nargs = 0 means a functionlike macro with no args, 689: e.g., 690: #define getchar() getc (stdin) . 691: When there are args, the expansion is the replacement text with the 692: args squashed out, and the reflist is a list describing how to 693: build the output from the input: e.g., "3 chars, then the 1st arg, 694: then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg". 695: The chars here come from the expansion. Whatever is left of the 696: expansion after the last arg-occurrence is copied after that arg. 697: Note that the reflist can be arbitrarily long--- 698: its length depends on the number of times the arguments appear in 699: the replacement text, not how many args there are. Example: 700: #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and 701: pattern list 702: { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL } 703: where (x, y) means (nchars, argno). */ 704: 705: typedef struct definition DEFINITION; 706: struct definition { 707: int nargs; 708: int length; /* length of expansion string */ 709: int predefined; /* True if the macro was builtin or */ 710: /* came from the command line */ 711: U_CHAR *expansion; 712: int line; /* Line number of definition */ 713: char *file; /* File of definition */ 1.1.1.3 root 714: char rest_args; /* Nonzero if last arg. absorbs the rest */ 1.1 root 715: struct reflist { 716: struct reflist *next; 717: char stringify; /* nonzero if this arg was preceded by a 718: # operator. */ 719: char raw_before; /* Nonzero if a ## operator before arg. */ 720: char raw_after; /* Nonzero if a ## operator after arg. */ 1.1.1.3 root 721: char rest_args; /* Nonzero if this arg. absorbs the rest */ 1.1 root 722: int nchars; /* Number of literal chars to copy before 723: this arg occurrence. */ 724: int argno; /* Number of arg to substitute (origin-0) */ 725: } *pattern; 726: union { 727: /* Names of macro args, concatenated in reverse order 728: with comma-space between them. 729: The only use of this is that we warn on redefinition 730: if this differs between the old and new definitions. */ 731: U_CHAR *argnames; 732: } args; 733: }; 734: 735: /* different kinds of things that can appear in the value field 736: of a hash node. Actually, this may be useless now. */ 737: union hashval { 738: int ival; 739: char *cpval; 740: DEFINITION *defn; 741: KEYDEF *keydef; 742: }; 743: 1.1.1.3 root 744: /* 745: * special extension string that can be added to the last macro argument to 746: * allow it to absorb the "rest" of the arguments when expanded. Ex: 1.1.1.5 root 747: * #define wow(a, b...) process (b, a, b) 748: * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); } 749: * { wow (one, two); } -> { process (two, one, two); } 1.1.1.3 root 750: * if this "rest_arg" is used with the concat token '##' and if it is not 1.1.1.4 root 751: * supplied then the token attached to with ## will not be outputted. Ex: 1.1.1.5 root 752: * #define wow (a, b...) process (b ## , a, ## b) 753: * { wow (1, 2); } -> { process (2, 1, 2); } 754: * { wow (one); } -> { process (one); { 1.1.1.3 root 755: */ 756: static char rest_extension[] = "..."; 757: #define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) 1.1 root 758: 759: /* The structure of a node in the hash table. The hash table 760: has entries for all tokens defined by #define commands (type T_MACRO), 761: plus some special tokens like __LINE__ (these each have their own 762: type, and the appropriate code is run when that type of node is seen. 763: It does not contain control words like "#define", which are recognized 764: by a separate piece of code. */ 765: 766: /* different flavors of hash nodes --- also used in keyword table */ 767: enum node_type { 768: T_DEFINE = 1, /* the `#define' keyword */ 769: T_INCLUDE, /* the `#include' keyword */ 770: T_INCLUDE_NEXT, /* the `#include_next' keyword */ 771: T_IMPORT, /* the `#import' keyword */ 772: T_IFDEF, /* the `#ifdef' keyword */ 773: T_IFNDEF, /* the `#ifndef' keyword */ 774: T_IF, /* the `#if' keyword */ 775: T_ELSE, /* `#else' */ 776: T_PRAGMA, /* `#pragma' */ 777: T_ELIF, /* `#elif' */ 778: T_UNDEF, /* `#undef' */ 779: T_LINE, /* `#line' */ 780: T_ERROR, /* `#error' */ 781: T_WARNING, /* `#warning' */ 782: T_ENDIF, /* `#endif' */ 783: T_SCCS, /* `#sccs', used on system V. */ 784: T_IDENT, /* `#ident', used on system V. */ 785: T_ASSERT, /* `#assert', taken from system V. */ 786: T_UNASSERT, /* `#unassert', taken from system V. */ 787: T_SPECLINE, /* special symbol `__LINE__' */ 788: T_DATE, /* `__DATE__' */ 789: T_FILE, /* `__FILE__' */ 790: T_BASE_FILE, /* `__BASE_FILE__' */ 791: T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ 792: T_VERSION, /* `__VERSION__' */ 793: T_SIZE_TYPE, /* `__SIZE_TYPE__' */ 794: T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */ 795: T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */ 1.1.1.5 root 796: T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */ 797: T_REGISTER_PREFIX_TYPE, /* `__REGISTER_PREFIX__' */ 1.1 root 798: T_TIME, /* `__TIME__' */ 799: T_CONST, /* Constant value, used by `__STDC__' */ 800: T_MACRO, /* macro defined by `#define' */ 801: T_DISABLED, /* macro temporarily turned off for rescan */ 802: T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */ 803: T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */ 804: T_UNUSED /* Used for something not defined. */ 805: }; 806: 807: struct hashnode { 808: struct hashnode *next; /* double links for easy deletion */ 809: struct hashnode *prev; 810: struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash 811: chain is kept, in case the node is the head 812: of the chain and gets deleted. */ 813: enum node_type type; /* type of special token */ 814: int length; /* length of token, for quick comparison */ 815: U_CHAR *name; /* the actual name */ 816: union hashval value; /* pointer to expansion, or whatever */ 817: }; 818: 819: typedef struct hashnode HASHNODE; 820: 821: /* Some definitions for the hash table. The hash function MUST be 822: computed as shown in hashf () below. That is because the rescan 823: loop computes the hash value `on the fly' for most tokens, 824: in order to avoid the overhead of a lot of procedure calls to 825: the hashf () function. Hashf () only exists for the sake of 826: politeness, for use when speed isn't so important. */ 827: 828: #define HASHSIZE 1403 829: static HASHNODE *hashtab[HASHSIZE]; 830: #define HASHSTEP(old, c) ((old << 2) + c) 831: #define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */ 832: 833: /* Symbols to predefine. */ 834: 835: #ifdef CPP_PREDEFINES 836: static char *predefs = CPP_PREDEFINES; 837: #else 838: static char *predefs = ""; 839: #endif 840: 841: /* We let tm.h override the types used here, to handle trivial differences 842: such as the choice of unsigned int or long unsigned int for size_t. 843: When machines start needing nontrivial differences in the size type, 844: it would be best to do something here to figure out automatically 845: from other information what type to use. */ 846: 1.1.1.7 ! root 847: /* The string value for __SIZE_TYPE__. */ 1.1 root 848: 849: #ifndef SIZE_TYPE 850: #define SIZE_TYPE "long unsigned int" 851: #endif 852: 1.1.1.7 ! root 853: /* The string value for __PTRDIFF_TYPE__. */ 1.1 root 854: 855: #ifndef PTRDIFF_TYPE 856: #define PTRDIFF_TYPE "long int" 857: #endif 858: 1.1.1.7 ! root 859: /* The string value for __WCHAR_TYPE__. */ 1.1 root 860: 861: #ifndef WCHAR_TYPE 862: #define WCHAR_TYPE "int" 863: #endif 1.1.1.7 ! root 864: char * wchar_type = WCHAR_TYPE; ! 865: #undef WCHAR_TYPE 1.1.1.5 root 866: 867: /* The string value for __USER_LABEL_PREFIX__ */ 868: 869: #ifndef USER_LABEL_PREFIX 870: #define USER_LABEL_PREFIX "" 871: #endif 872: 873: /* The string value for __REGISTER_PREFIX__ */ 874: 875: #ifndef REGISTER_PREFIX 876: #define REGISTER_PREFIX "" 877: #endif 1.1 root 878: 879: /* In the definition of a #assert name, this structure forms 880: a list of the individual values asserted. 881: Each value is itself a list of "tokens". 882: These are strings that are compared by name. */ 883: 884: struct tokenlist_list { 885: struct tokenlist_list *next; 886: struct arglist *tokens; 887: }; 888: 889: struct assertion_hashnode { 890: struct assertion_hashnode *next; /* double links for easy deletion */ 891: struct assertion_hashnode *prev; 892: /* also, a back pointer to this node's hash 893: chain is kept, in case the node is the head 894: of the chain and gets deleted. */ 895: struct assertion_hashnode **bucket_hdr; 896: int length; /* length of token, for quick comparison */ 897: U_CHAR *name; /* the actual name */ 898: /* List of token-sequences. */ 899: struct tokenlist_list *value; 900: }; 901: 902: typedef struct assertion_hashnode ASSERTION_HASHNODE; 903: 904: /* Some definitions for the hash table. The hash function MUST be 1.1.1.4 root 905: computed as shown in hashf below. That is because the rescan 1.1 root 906: loop computes the hash value `on the fly' for most tokens, 907: in order to avoid the overhead of a lot of procedure calls to 1.1.1.4 root 908: the hashf function. hashf only exists for the sake of 1.1 root 909: politeness, for use when speed isn't so important. */ 910: 911: #define ASSERTION_HASHSIZE 37 912: static ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE]; 913: 914: /* Nonzero means inhibit macroexpansion of what seem to be 915: assertion tests, in rescan. For #if. */ 916: static int assertions_flag; 917: 918: /* `struct directive' defines one #-directive, including how to handle it. */ 919: 920: struct directive { 921: int length; /* Length of name */ 922: int (*func)(); /* Function to handle directive */ 923: char *name; /* Name of directive */ 924: enum node_type type; /* Code which describes which directive. */ 925: char angle_brackets; /* Nonzero => <...> is special. */ 926: char traditional_comments; /* Nonzero: keep comments if -traditional. */ 927: char pass_thru; /* Copy preprocessed directive to output file. */ 928: }; 929: 930: /* Here is the actual list of #-directives, most-often-used first. */ 931: 932: static struct directive directive_table[] = { 933: { 6, do_define, "define", T_DEFINE, 0, 1}, 934: { 2, do_if, "if", T_IF}, 935: { 5, do_xifdef, "ifdef", T_IFDEF}, 936: { 6, do_xifdef, "ifndef", T_IFNDEF}, 937: { 5, do_endif, "endif", T_ENDIF}, 938: { 4, do_else, "else", T_ELSE}, 939: { 4, do_elif, "elif", T_ELIF}, 940: { 4, do_line, "line", T_LINE}, 941: { 7, do_include, "include", T_INCLUDE, 1}, 942: { 12, do_include, "include_next", T_INCLUDE_NEXT, 1}, 943: { 6, do_include, "import", T_IMPORT, 1}, 944: { 5, do_undef, "undef", T_UNDEF}, 945: { 5, do_error, "error", T_ERROR}, 946: { 7, do_warning, "warning", T_WARNING}, 947: #ifdef SCCS_DIRECTIVE 948: { 4, do_sccs, "sccs", T_SCCS}, 949: #endif 950: { 6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1}, 1.1.1.6 root 951: { 5, do_ident, "ident", T_IDENT}, 1.1 root 952: { 6, do_assert, "assert", T_ASSERT}, 953: { 8, do_unassert, "unassert", T_UNASSERT}, 954: { -1, 0, "", T_UNUSED}, 955: }; 956: 957: /* When a directive handler is called, 958: this points to the # that started the directive. */ 959: U_CHAR *directive_start; 960: 961: /* table to tell if char can be part of a C identifier. */ 962: U_CHAR is_idchar[256]; 963: /* table to tell if char can be first char of a c identifier. */ 964: U_CHAR is_idstart[256]; 965: /* table to tell if c is horizontal space. */ 966: U_CHAR is_hor_space[256]; 967: /* table to tell if c is horizontal or vertical space. */ 968: static U_CHAR is_space[256]; 969: 970: #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0) 971: #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0) 972: 973: static int errors = 0; /* Error counter for exit code */ 974: 1.1.1.5 root 975: /* Name of output file, for error messages. */ 976: static char *out_fname; 977: 1.1 root 978: /* Zero means dollar signs are punctuation. 979: -$ stores 0; -traditional may store 1. Default is 1 for VMS, 0 otherwise. 980: This must be 0 for correct processing of this ANSI C program: 981: #define foo(a) #a 1.1.1.5 root 982: #define lose(b) foo (b) 1.1 root 983: #define test$ 1.1.1.5 root 984: lose (test) */ 1.1 root 985: static int dollars_in_ident; 986: #ifndef DOLLARS_IN_IDENTIFIERS 987: #define DOLLARS_IN_IDENTIFIERS 1 988: #endif 989: 990: static FILE_BUF expand_to_temp_buffer (); 991: 992: static DEFINITION *collect_expansion (); 993: 994: /* Stack of conditionals currently in progress 995: (including both successful and failing conditionals). */ 996: 997: struct if_stack { 998: struct if_stack *next; /* for chaining to the next stack frame */ 999: char *fname; /* copied from input when frame is made */ 1000: int lineno; /* similarly */ 1001: int if_succeeded; /* true if a leg of this if-group 1002: has been passed through rescan */ 1003: U_CHAR *control_macro; /* For #ifndef at start of file, 1004: this is the macro name tested. */ 1005: enum node_type type; /* type of last directive seen in this group */ 1006: }; 1007: typedef struct if_stack IF_STACK_FRAME; 1008: static IF_STACK_FRAME *if_stack = NULL; 1009: 1010: /* Buffer of -M output. */ 1011: static char *deps_buffer; 1012: 1013: /* Number of bytes allocated in above. */ 1014: static int deps_allocated_size; 1015: 1016: /* Number of bytes used. */ 1017: static int deps_size; 1018: 1019: /* Number of bytes since the last newline. */ 1020: static int deps_column; 1021: 1022: /* Nonzero means -I- has been seen, 1023: so don't look for #include "foo" the source-file directory. */ 1024: static int ignore_srcdir; 1025: 1.1.1.6 root 1026: /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME, 1.1.1.7 ! root 1027: retrying if necessary. Return a negative value if an error occurs, ! 1028: otherwise return the actual number of bytes read, ! 1029: which must be LEN unless end-of-file was reached. */ 1.1.1.6 root 1030: 1031: static int 1032: safe_read (desc, ptr, len) 1033: int desc; 1034: char *ptr; 1035: int len; 1036: { 1037: int left = len; 1038: while (left > 0) { 1039: int nchars = read (desc, ptr, left); 1040: if (nchars < 0) 1041: { 1042: #ifdef EINTR 1043: if (errno == EINTR) 1044: continue; 1045: #endif 1046: return nchars; 1047: } 1048: if (nchars == 0) 1049: break; 1050: ptr += nchars; 1051: left -= nchars; 1052: } 1053: return len - left; 1054: } 1055: 1056: /* Write LEN bytes at PTR to descriptor DESC, 1057: retrying if necessary, and treating any real error as fatal. */ 1058: 1059: static void 1060: safe_write (desc, ptr, len) 1061: int desc; 1062: char *ptr; 1063: int len; 1064: { 1065: while (len > 0) { 1066: int written = write (desc, ptr, len); 1067: if (written < 0) 1068: { 1069: #ifdef EINTR 1070: if (errno == EINTR) 1071: continue; 1072: #endif 1073: pfatal_with_name (out_fname); 1074: } 1075: ptr += written; 1076: len -= written; 1077: } 1078: } 1079: 1.1 root 1080: int 1081: main (argc, argv) 1082: int argc; 1083: char **argv; 1084: { 1085: int st_mode; 1086: long st_size; 1.1.1.5 root 1087: char *in_fname; 1.1 root 1088: char *p; 1089: int f, i; 1090: FILE_BUF *fp; 1091: char **pend_files = (char **) xmalloc (argc * sizeof (char *)); 1092: char **pend_defs = (char **) xmalloc (argc * sizeof (char *)); 1093: char **pend_undefs = (char **) xmalloc (argc * sizeof (char *)); 1094: char **pend_assertions = (char **) xmalloc (argc * sizeof (char *)); 1095: char **pend_includes = (char **) xmalloc (argc * sizeof (char *)); 1096: 1097: /* Record the option used with each element of pend_assertions. 1098: This is preparation for supporting more than one option for making 1099: an assertion. */ 1100: char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *)); 1101: int inhibit_predefs = 0; 1102: int no_standard_includes = 0; 1.1.1.3 root 1103: int no_standard_cplusplus_includes = 0; 1.1 root 1104: int missing_newline = 0; 1105: 1106: /* Non-0 means don't output the preprocessed program. */ 1107: int inhibit_output = 0; 1.1.1.6 root 1108: /* Non-0 means -v, so print the full set of include dirs. */ 1109: int verbose = 0; 1.1 root 1110: 1.1.1.4 root 1111: /* File name which deps are being written to. 1112: This is 0 if deps are being written to stdout. */ 1113: char *deps_file = 0; 1.1.1.5 root 1114: /* Fopen file mode to open deps_file with. */ 1115: char *deps_mode = "a"; 1.1 root 1116: /* Stream on which to print the dependency information. */ 1117: FILE *deps_stream = 0; 1118: /* Target-name to write with the dependency information. */ 1119: char *deps_target = 0; 1120: 1121: #ifdef RLIMIT_STACK 1122: /* Get rid of any avoidable limit on stack size. */ 1123: { 1124: struct rlimit rlim; 1125: 1126: /* Set the stack limit huge so that alloca (particularly stringtab 1127: * in dbxread.c) does not fail. */ 1128: getrlimit (RLIMIT_STACK, &rlim); 1129: rlim.rlim_cur = rlim.rlim_max; 1130: setrlimit (RLIMIT_STACK, &rlim); 1131: } 1132: #endif /* RLIMIT_STACK defined */ 1133: 1.1.1.6 root 1134: #ifdef SIGPIPE 1.1.1.5 root 1135: signal (SIGPIPE, pipe_closed); 1.1.1.6 root 1136: #endif 1.1.1.5 root 1137: 1138: p = argv[0] + strlen (argv[0]); 1.1.1.7 ! root 1139: while (p != argv[0] && p[-1] != '/' ! 1140: #ifdef DIR_SEPARATOR ! 1141: && p[-1] != DIR_SEPARATOR ! 1142: #endif ! 1143: ) ! 1144: --p; 1.1.1.5 root 1145: progname = p; 1146: 1.1 root 1147: #ifdef VMS 1148: { 1149: /* Remove directories from PROGNAME. */ 1150: char *s; 1151: 1152: progname = savestring (argv[0]); 1153: 1154: if (!(s = rindex (progname, ']'))) 1155: s = rindex (progname, ':'); 1156: if (s) 1157: strcpy (progname, s+1); 1158: if (s = rindex (progname, '.')) 1159: *s = '\0'; 1160: } 1161: #endif 1162: 1163: in_fname = NULL; 1164: out_fname = NULL; 1165: 1166: /* Initialize is_idchar to allow $. */ 1167: dollars_in_ident = 1; 1168: initialize_char_syntax (); 1169: dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0; 1170: 1171: no_line_commands = 0; 1172: no_trigraphs = 1; 1173: dump_macros = dump_none; 1174: no_output = 0; 1175: cplusplus = 0; 1.1.1.4 root 1176: cplusplus_comments = 0; 1.1 root 1177: 1.1.1.7 ! root 1178: bzero ((char *) pend_files, argc * sizeof (char *)); ! 1179: bzero ((char *) pend_defs, argc * sizeof (char *)); ! 1180: bzero ((char *) pend_undefs, argc * sizeof (char *)); ! 1181: bzero ((char *) pend_assertions, argc * sizeof (char *)); ! 1182: bzero ((char *) pend_includes, argc * sizeof (char *)); 1.1 root 1183: 1184: /* Process switches and find input file name. */ 1185: 1186: for (i = 1; i < argc; i++) { 1187: if (argv[i][0] != '-') { 1188: if (out_fname != NULL) 1189: fatal ("Usage: %s [switches] input output", argv[0]); 1190: else if (in_fname != NULL) 1191: out_fname = argv[i]; 1192: else 1193: in_fname = argv[i]; 1194: } else { 1195: switch (argv[i][1]) { 1196: 1197: case 'i': 1198: if (!strcmp (argv[i], "-include")) { 1199: if (i + 1 == argc) 1.1.1.5 root 1200: fatal ("Filename missing after `-include' option"); 1.1 root 1201: else 1202: pend_includes[i] = argv[i+1], i++; 1203: } 1204: if (!strcmp (argv[i], "-imacros")) { 1205: if (i + 1 == argc) 1.1.1.5 root 1206: fatal ("Filename missing after `-imacros' option"); 1.1 root 1207: else 1208: pend_files[i] = argv[i+1], i++; 1209: } 1.1.1.3 root 1210: if (!strcmp (argv[i], "-iprefix")) { 1211: if (i + 1 == argc) 1.1.1.5 root 1212: fatal ("Filename missing after `-iprefix' option"); 1.1.1.3 root 1213: else 1214: include_prefix = argv[++i]; 1215: } 1.1.1.7 ! root 1216: if (!strcmp (argv[i], "-ifoutput")) { ! 1217: output_conditionals = 1; ! 1218: } ! 1219: if (!strcmp (argv[i], "-isystem")) { ! 1220: struct file_name_list *dirtmp; ! 1221: ! 1222: if (i + 1 == argc) ! 1223: fatal ("Filename missing after `-isystem' option"); ! 1224: ! 1225: dirtmp = (struct file_name_list *) ! 1226: xmalloc (sizeof (struct file_name_list)); ! 1227: dirtmp->next = 0; ! 1228: dirtmp->control_macro = 0; ! 1229: dirtmp->c_system_include_path = 1; ! 1230: dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) + 1); ! 1231: strcpy (dirtmp->fname, argv[++i]); ! 1232: dirtmp->got_name_map = 0; ! 1233: ! 1234: if (before_system == 0) ! 1235: before_system = dirtmp; ! 1236: else ! 1237: last_before_system->next = dirtmp; ! 1238: last_before_system = dirtmp; /* Tail follows the last one */ ! 1239: } 1.1.1.5 root 1240: /* Add directory to end of path for includes, 1241: with the default prefix at the front of its name. */ 1242: if (!strcmp (argv[i], "-iwithprefix")) { 1243: struct file_name_list *dirtmp; 1.1.1.6 root 1244: char *prefix; 1245: 1246: if (include_prefix != 0) 1247: prefix = include_prefix; 1248: else { 1249: prefix = savestring (GCC_INCLUDE_DIR); 1250: /* Remove the `include' from /usr/local/lib/gcc.../include. */ 1251: if (!strcmp (prefix + strlen (prefix) - 8, "/include")) 1252: prefix[strlen (prefix) - 7] = 0; 1253: } 1.1.1.5 root 1254: 1255: dirtmp = (struct file_name_list *) 1256: xmalloc (sizeof (struct file_name_list)); 1257: dirtmp->next = 0; /* New one goes on the end */ 1258: dirtmp->control_macro = 0; 1.1.1.6 root 1259: dirtmp->c_system_include_path = 0; 1.1.1.5 root 1260: if (i + 1 == argc) 1261: fatal ("Directory name missing after `-iwithprefix' option"); 1262: 1263: dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) 1.1.1.6 root 1264: + strlen (prefix) + 1); 1265: strcpy (dirtmp->fname, prefix); 1.1.1.5 root 1266: strcat (dirtmp->fname, argv[++i]); 1.1.1.7 ! root 1267: dirtmp->got_name_map = 0; 1.1.1.5 root 1268: 1269: if (after_include == 0) 1270: after_include = dirtmp; 1271: else 1272: last_after_include->next = dirtmp; 1273: last_after_include = dirtmp; /* Tail follows the last one */ 1274: } 1.1.1.6 root 1275: /* Add directory to main path for includes, 1276: with the default prefix at the front of its name. */ 1277: if (!strcmp (argv[i], "-iwithprefixbefore")) { 1278: struct file_name_list *dirtmp; 1279: char *prefix; 1280: 1281: if (include_prefix != 0) 1282: prefix = include_prefix; 1283: else { 1284: prefix = savestring (GCC_INCLUDE_DIR); 1285: /* Remove the `include' from /usr/local/lib/gcc.../include. */ 1286: if (!strcmp (prefix + strlen (prefix) - 8, "/include")) 1287: prefix[strlen (prefix) - 7] = 0; 1288: } 1289: 1290: dirtmp = (struct file_name_list *) 1291: xmalloc (sizeof (struct file_name_list)); 1292: dirtmp->next = 0; /* New one goes on the end */ 1293: dirtmp->control_macro = 0; 1294: dirtmp->c_system_include_path = 0; 1295: if (i + 1 == argc) 1296: fatal ("Directory name missing after `-iwithprefixbefore' option"); 1297: 1298: dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) 1299: + strlen (prefix) + 1); 1300: strcpy (dirtmp->fname, prefix); 1301: strcat (dirtmp->fname, argv[++i]); 1.1.1.7 ! root 1302: dirtmp->got_name_map = 0; 1.1.1.6 root 1303: 1304: append_include_chain (dirtmp, dirtmp); 1305: } 1.1 root 1306: /* Add directory to end of path for includes. */ 1307: if (!strcmp (argv[i], "-idirafter")) { 1308: struct file_name_list *dirtmp; 1309: 1310: dirtmp = (struct file_name_list *) 1311: xmalloc (sizeof (struct file_name_list)); 1312: dirtmp->next = 0; /* New one goes on the end */ 1313: dirtmp->control_macro = 0; 1.1.1.6 root 1314: dirtmp->c_system_include_path = 0; 1.1 root 1315: if (i + 1 == argc) 1.1.1.5 root 1316: fatal ("Directory name missing after `-idirafter' option"); 1.1 root 1317: else 1318: dirtmp->fname = argv[++i]; 1.1.1.7 ! root 1319: dirtmp->got_name_map = 0; 1.1 root 1320: 1.1.1.4 root 1321: if (after_include == 0) 1322: after_include = dirtmp; 1323: else 1324: last_after_include->next = dirtmp; 1325: last_after_include = dirtmp; /* Tail follows the last one */ 1.1 root 1326: } 1327: break; 1328: 1329: case 'o': 1330: if (out_fname != NULL) 1331: fatal ("Output filename specified twice"); 1332: if (i + 1 == argc) 1333: fatal ("Filename missing after -o option"); 1334: out_fname = argv[++i]; 1335: if (!strcmp (out_fname, "-")) 1336: out_fname = ""; 1337: break; 1338: 1339: case 'p': 1340: if (!strcmp (argv[i], "-pedantic")) 1341: pedantic = 1; 1342: else if (!strcmp (argv[i], "-pedantic-errors")) { 1343: pedantic = 1; 1344: pedantic_errors = 1; 1345: } else if (!strcmp (argv[i], "-pcp")) { 1.1.1.7 ! root 1346: char *pcp_fname; ! 1347: if (i + 1 == argc) ! 1348: fatal ("Filename missing after -pcp option"); ! 1349: pcp_fname = argv[++i]; 1.1 root 1350: pcp_outfile = 1351: ((pcp_fname[0] != '-' || pcp_fname[1] != '\0') 1352: ? fopen (pcp_fname, "w") 1353: : fdopen (dup (fileno (stdout)), "w")); 1354: if (pcp_outfile == 0) 1355: pfatal_with_name (pcp_fname); 1356: no_precomp = 1; 1357: } 1358: break; 1359: 1360: case 't': 1361: if (!strcmp (argv[i], "-traditional")) { 1362: traditional = 1; 1363: if (dollars_in_ident > 0) 1364: dollars_in_ident = 1; 1365: } else if (!strcmp (argv[i], "-trigraphs")) { 1366: no_trigraphs = 0; 1367: } 1368: break; 1369: 1370: case 'l': 1371: if (! strcmp (argv[i], "-lang-c")) 1.1.1.4 root 1372: cplusplus = 0, cplusplus_comments = 0, objc = 0; 1.1 root 1373: if (! strcmp (argv[i], "-lang-c++")) 1.1.1.4 root 1374: cplusplus = 1, cplusplus_comments = 1, objc = 0; 1.1.1.6 root 1375: if (! strcmp (argv[i], "-lang-c-c++-comments")) 1376: cplusplus = 0, cplusplus_comments = 1, objc = 0; 1.1 root 1377: if (! strcmp (argv[i], "-lang-objc")) 1.1.1.4 root 1378: objc = 1, cplusplus = 0, cplusplus_comments = 1; 1.1 root 1379: if (! strcmp (argv[i], "-lang-objc++")) 1.1.1.4 root 1380: objc = 1, cplusplus = 1, cplusplus_comments = 1; 1.1 root 1381: if (! strcmp (argv[i], "-lang-asm")) 1382: lang_asm = 1; 1383: if (! strcmp (argv[i], "-lint")) 1.1.1.7 ! root 1384: for_lint = 1; 1.1 root 1385: break; 1386: 1387: case '+': 1.1.1.4 root 1388: cplusplus = 1, cplusplus_comments = 1; 1.1 root 1389: break; 1390: 1391: case 'w': 1392: inhibit_warnings = 1; 1393: break; 1394: 1395: case 'W': 1396: if (!strcmp (argv[i], "-Wtrigraphs")) 1397: warn_trigraphs = 1; 1398: else if (!strcmp (argv[i], "-Wno-trigraphs")) 1399: warn_trigraphs = 0; 1400: else if (!strcmp (argv[i], "-Wcomment")) 1401: warn_comments = 1; 1402: else if (!strcmp (argv[i], "-Wno-comment")) 1403: warn_comments = 0; 1404: else if (!strcmp (argv[i], "-Wcomments")) 1405: warn_comments = 1; 1406: else if (!strcmp (argv[i], "-Wno-comments")) 1407: warn_comments = 0; 1408: else if (!strcmp (argv[i], "-Wtraditional")) 1409: warn_stringify = 1; 1410: else if (!strcmp (argv[i], "-Wno-traditional")) 1411: warn_stringify = 0; 1.1.1.2 root 1412: else if (!strcmp (argv[i], "-Wimport")) 1413: warn_import = 1; 1414: else if (!strcmp (argv[i], "-Wno-import")) 1415: warn_import = 0; 1.1 root 1416: else if (!strcmp (argv[i], "-Werror")) 1417: warnings_are_errors = 1; 1418: else if (!strcmp (argv[i], "-Wno-error")) 1419: warnings_are_errors = 0; 1420: else if (!strcmp (argv[i], "-Wall")) 1421: { 1422: warn_trigraphs = 1; 1423: warn_comments = 1; 1424: } 1425: break; 1426: 1427: case 'M': 1.1.1.7 ! root 1428: /* The style of the choices here is a bit mixed. ! 1429: The chosen scheme is a hybrid of keeping all options in one string ! 1430: and specifying each option in a separate argument: ! 1431: -M|-MM|-MD file|-MMD file [-MG]. An alternative is: ! 1432: -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: ! 1433: -M[M][G][D file]. This is awkward to handle in specs, and is not ! 1434: as extensible. */ ! 1435: /* ??? -MG must be specified in addition to one of -M or -MM. ! 1436: This can be relaxed in the future without breaking anything. ! 1437: The converse isn't true. */ ! 1438: ! 1439: /* -MG isn't valid with -MD or -MMD. This is checked for later. */ ! 1440: if (!strcmp (argv[i], "-MG")) ! 1441: { ! 1442: print_deps_missing_files = 1; ! 1443: break; ! 1444: } 1.1 root 1445: if (!strcmp (argv[i], "-M")) 1446: print_deps = 2; 1447: else if (!strcmp (argv[i], "-MM")) 1448: print_deps = 1; 1449: else if (!strcmp (argv[i], "-MD")) 1450: print_deps = 2; 1451: else if (!strcmp (argv[i], "-MMD")) 1452: print_deps = 1; 1453: /* For -MD and -MMD options, write deps on file named by next arg. */ 1454: if (!strcmp (argv[i], "-MD") 1455: || !strcmp (argv[i], "-MMD")) { 1.1.1.7 ! root 1456: if (i + 1 == argc) ! 1457: fatal ("Filename missing after %s option", argv[i]); 1.1 root 1458: i++; 1459: deps_file = argv[i]; 1.1.1.5 root 1460: deps_mode = "w"; 1.1 root 1461: } else { 1462: /* For -M and -MM, write deps on standard output 1463: and suppress the usual output. */ 1464: deps_stream = stdout; 1465: inhibit_output = 1; 1466: } 1467: break; 1468: 1469: case 'd': 1470: { 1471: char *p = argv[i] + 2; 1472: char c; 1473: while (c = *p++) { 1474: /* Arg to -d specifies what parts of macros to dump */ 1475: switch (c) { 1476: case 'M': 1477: dump_macros = dump_only; 1478: no_output = 1; 1479: break; 1480: case 'N': 1481: dump_macros = dump_names; 1482: break; 1483: case 'D': 1484: dump_macros = dump_definitions; 1485: break; 1486: } 1487: } 1488: } 1489: break; 1490: 1491: case 'g': 1492: if (argv[i][2] == '3') 1493: debug_output = 1; 1494: break; 1495: 1496: case 'v': 1497: fprintf (stderr, "GNU CPP version %s", version_string); 1498: #ifdef TARGET_VERSION 1499: TARGET_VERSION; 1500: #endif 1501: fprintf (stderr, "\n"); 1.1.1.6 root 1502: verbose = 1; 1.1 root 1503: break; 1504: 1505: case 'H': 1506: print_include_names = 1; 1507: break; 1508: 1509: case 'D': 1.1.1.7 ! root 1510: if (argv[i][2] != 0) ! 1511: pend_defs[i] = argv[i] + 2; ! 1512: else if (i + 1 == argc) ! 1513: fatal ("Macro name missing after -D option"); ! 1514: else ! 1515: i++, pend_defs[i] = argv[i]; 1.1 root 1516: break; 1517: 1518: case 'A': 1519: { 1.1.1.7 ! root 1520: char *p; 1.1 root 1521: 1522: if (argv[i][2] != 0) 1523: p = argv[i] + 2; 1524: else if (i + 1 == argc) 1525: fatal ("Assertion missing after -A option"); 1526: else 1527: p = argv[++i]; 1528: 1529: if (!strcmp (p, "-")) { 1530: /* -A- eliminates all predefined macros and assertions. 1531: Let's include also any that were specified earlier 1532: on the command line. That way we can get rid of any 1533: that were passed automatically in from GCC. */ 1534: int j; 1535: inhibit_predefs = 1; 1536: for (j = 0; j < i; j++) 1537: pend_defs[j] = pend_assertions[j] = 0; 1538: } else { 1539: pend_assertions[i] = p; 1540: pend_assertion_options[i] = "-A"; 1541: } 1542: } 1543: break; 1544: 1545: case 'U': /* JF #undef something */ 1546: if (argv[i][2] != 0) 1547: pend_undefs[i] = argv[i] + 2; 1548: else if (i + 1 == argc) 1549: fatal ("Macro name missing after -U option"); 1550: else 1551: pend_undefs[i] = argv[i+1], i++; 1552: break; 1553: 1554: case 'C': 1555: put_out_comments = 1; 1556: break; 1557: 1558: case 'E': /* -E comes from cc -E; ignore it. */ 1559: break; 1560: 1561: case 'P': 1562: no_line_commands = 1; 1563: break; 1564: 1565: case '$': /* Don't include $ in identifiers. */ 1566: dollars_in_ident = 0; 1567: break; 1568: 1569: case 'I': /* Add directory to path for includes. */ 1570: { 1571: struct file_name_list *dirtmp; 1572: 1.1.1.4 root 1573: if (! ignore_srcdir && !strcmp (argv[i] + 2, "-")) { 1.1 root 1574: ignore_srcdir = 1; 1.1.1.4 root 1575: /* Don't use any preceding -I directories for #include <...>. */ 1576: first_bracket_include = 0; 1577: } 1.1 root 1578: else { 1579: dirtmp = (struct file_name_list *) 1580: xmalloc (sizeof (struct file_name_list)); 1581: dirtmp->next = 0; /* New one goes on the end */ 1582: dirtmp->control_macro = 0; 1.1.1.6 root 1583: dirtmp->c_system_include_path = 0; 1.1 root 1584: if (argv[i][2] != 0) 1585: dirtmp->fname = argv[i] + 2; 1586: else if (i + 1 == argc) 1587: fatal ("Directory name missing after -I option"); 1588: else 1589: dirtmp->fname = argv[++i]; 1.1.1.7 ! root 1590: dirtmp->got_name_map = 0; 1.1.1.4 root 1591: append_include_chain (dirtmp, dirtmp); 1592: } 1.1 root 1593: } 1594: break; 1595: 1596: case 'n': 1597: if (!strcmp (argv[i], "-nostdinc")) 1598: /* -nostdinc causes no default include directories. 1599: You must specify all include-file directories with -I. */ 1600: no_standard_includes = 1; 1.1.1.3 root 1601: else if (!strcmp (argv[i], "-nostdinc++")) 1602: /* -nostdinc++ causes no default C++-specific include directories. */ 1603: no_standard_cplusplus_includes = 1; 1.1 root 1604: else if (!strcmp (argv[i], "-noprecomp")) 1605: no_precomp = 1; 1606: break; 1607: 1608: case 'u': 1609: /* Sun compiler passes undocumented switch "-undef". 1610: Let's assume it means to inhibit the predefined symbols. */ 1611: inhibit_predefs = 1; 1612: break; 1613: 1614: case '\0': /* JF handle '-' as file name meaning stdin or stdout */ 1615: if (in_fname == NULL) { 1616: in_fname = ""; 1617: break; 1618: } else if (out_fname == NULL) { 1619: out_fname = ""; 1620: break; 1621: } /* else fall through into error */ 1622: 1623: default: 1624: fatal ("Invalid option `%s'", argv[i]); 1625: } 1626: } 1627: } 1628: 1629: /* Add dirs from CPATH after dirs from -I. */ 1630: /* There seems to be confusion about what CPATH should do, 1631: so for the moment it is not documented. */ 1632: /* Some people say that CPATH should replace the standard include dirs, 1633: but that seems pointless: it comes before them, so it overrides them 1634: anyway. */ 1.1.1.7 ! root 1635: #ifdef WINNT ! 1636: p = (char *) getenv ("Include"); ! 1637: #else 1.1 root 1638: p = (char *) getenv ("CPATH"); 1.1.1.7 ! root 1639: #endif 1.1 root 1640: if (p != 0 && ! no_standard_includes) 1641: path_include (p); 1642: 1643: /* Now that dollars_in_ident is known, initialize is_idchar. */ 1644: initialize_char_syntax (); 1645: 1646: /* Initialize output buffer */ 1647: 1648: outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE); 1649: outbuf.bufp = outbuf.buf; 1650: outbuf.length = OUTBUF_SIZE; 1651: 1652: /* Do partial setup of input buffer for the sake of generating 1653: early #line directives (when -g is in effect). */ 1654: 1655: fp = &instack[++indepth]; 1656: if (in_fname == NULL) 1657: in_fname = ""; 1658: fp->nominal_fname = fp->fname = in_fname; 1659: fp->lineno = 0; 1660: 1.1.1.7 ! root 1661: /* In C++, wchar_t is a distinct basic type, and we can expect ! 1662: __wchar_t to be defined by cc1plus. */ ! 1663: if (cplusplus) ! 1664: wchar_type = "__wchar_t"; ! 1665: 1.1 root 1666: /* Install __LINE__, etc. Must follow initialize_char_syntax 1667: and option processing. */ 1668: initialize_builtins (fp, &outbuf); 1669: 1670: /* Do standard #defines and assertions 1671: that identify system and machine type. */ 1672: 1673: if (!inhibit_predefs) { 1674: char *p = (char *) alloca (strlen (predefs) + 1); 1675: strcpy (p, predefs); 1676: while (*p) { 1677: char *q; 1678: while (*p == ' ' || *p == '\t') 1679: p++; 1680: /* Handle -D options. */ 1681: if (p[0] == '-' && p[1] == 'D') { 1682: q = &p[2]; 1683: while (*p && *p != ' ' && *p != '\t') 1684: p++; 1685: if (*p != 0) 1686: *p++= 0; 1687: if (debug_output) 1688: output_line_command (fp, &outbuf, 0, same_file); 1689: make_definition (q, &outbuf); 1690: while (*p == ' ' || *p == '\t') 1691: p++; 1692: } else if (p[0] == '-' && p[1] == 'A') { 1693: /* Handle -A options (assertions). */ 1694: char *assertion; 1695: char *past_name; 1696: char *value; 1697: char *past_value; 1698: char *termination; 1699: int save_char; 1700: 1701: assertion = &p[2]; 1702: past_name = assertion; 1703: /* Locate end of name. */ 1704: while (*past_name && *past_name != ' ' 1705: && *past_name != '\t' && *past_name != '(') 1706: past_name++; 1707: /* Locate `(' at start of value. */ 1708: value = past_name; 1709: while (*value && (*value == ' ' || *value == '\t')) 1710: value++; 1711: if (*value++ != '(') 1712: abort (); 1713: while (*value && (*value == ' ' || *value == '\t')) 1714: value++; 1715: past_value = value; 1716: /* Locate end of value. */ 1717: while (*past_value && *past_value != ' ' 1718: && *past_value != '\t' && *past_value != ')') 1719: past_value++; 1720: termination = past_value; 1721: while (*termination && (*termination == ' ' || *termination == '\t')) 1722: termination++; 1723: if (*termination++ != ')') 1724: abort (); 1725: if (*termination && *termination != ' ' && *termination != '\t') 1726: abort (); 1727: /* Temporarily null-terminate the value. */ 1728: save_char = *termination; 1729: *termination = '\0'; 1730: /* Install the assertion. */ 1731: make_assertion ("-A", assertion); 1732: *termination = (char) save_char; 1733: p = termination; 1734: while (*p == ' ' || *p == '\t') 1735: p++; 1736: } else { 1737: abort (); 1738: } 1739: } 1740: } 1741: 1742: /* Now handle the command line options. */ 1743: 1.1.1.4 root 1744: /* Do -U's, -D's and -A's in the order they were seen. */ 1745: for (i = 1; i < argc; i++) { 1746: if (pend_undefs[i]) { 1.1 root 1747: if (debug_output) 1748: output_line_command (fp, &outbuf, 0, same_file); 1.1.1.4 root 1749: make_undef (pend_undefs[i], &outbuf); 1.1 root 1750: } 1.1.1.4 root 1751: if (pend_defs[i]) { 1.1 root 1752: if (debug_output) 1753: output_line_command (fp, &outbuf, 0, same_file); 1.1.1.4 root 1754: make_definition (pend_defs[i], &outbuf); 1.1 root 1755: } 1.1.1.4 root 1756: if (pend_assertions[i]) 1757: make_assertion (pend_assertion_options[i], pend_assertions[i]); 1758: } 1.1 root 1759: 1760: done_initializing = 1; 1761: 1762: { /* read the appropriate environment variable and if it exists 1763: replace include_defaults with the listed path. */ 1764: char *epath = 0; 1765: switch ((objc << 1) + cplusplus) 1766: { 1767: case 0: 1768: epath = getenv ("C_INCLUDE_PATH"); 1769: break; 1770: case 1: 1.1.1.2 root 1771: epath = getenv ("CPLUS_INCLUDE_PATH"); 1.1 root 1772: break; 1773: case 2: 1774: epath = getenv ("OBJC_INCLUDE_PATH"); 1775: break; 1776: case 3: 1.1.1.2 root 1777: epath = getenv ("OBJCPLUS_INCLUDE_PATH"); 1.1 root 1778: break; 1779: } 1780: /* If the environment var for this language is set, 1781: add to the default list of include directories. */ 1782: if (epath) { 1783: char *nstore = (char *) alloca (strlen (epath) + 2); 1784: int num_dirs; 1785: char *startp, *endp; 1786: 1787: for (num_dirs = 1, startp = epath; *startp; startp++) 1.1.1.3 root 1788: if (*startp == PATH_SEPARATOR) 1.1 root 1789: num_dirs++; 1790: include_defaults 1791: = (struct default_include *) xmalloc ((num_dirs 1792: * sizeof (struct default_include)) 1793: + sizeof (include_defaults_array)); 1794: startp = endp = epath; 1795: num_dirs = 0; 1796: while (1) { 1.1.1.2 root 1797: /* Handle cases like c:/usr/lib:d:/gcc/lib */ 1.1.1.3 root 1798: if ((*endp == PATH_SEPARATOR 1799: #if 0 /* Obsolete, now that we use semicolons as the path separator. */ 1.1.1.2 root 1800: #ifdef __MSDOS__ 1.1.1.4 root 1801: && (endp-startp != 1 || !isalpha (*startp)) 1.1.1.2 root 1802: #endif 1.1.1.3 root 1803: #endif 1.1.1.2 root 1804: ) 1.1.1.3 root 1805: || *endp == 0) { 1.1 root 1806: strncpy (nstore, startp, endp-startp); 1807: if (endp == startp) 1808: strcpy (nstore, "."); 1809: else 1810: nstore[endp-startp] = '\0'; 1811: 1812: include_defaults[num_dirs].fname = savestring (nstore); 1813: include_defaults[num_dirs].cplusplus = cplusplus; 1.1.1.7 ! root 1814: include_defaults[num_dirs].cxx_aware = 1; 1.1 root 1815: num_dirs++; 1816: if (*endp == '\0') 1817: break; 1818: endp = startp = endp + 1; 1819: } else 1820: endp++; 1821: } 1822: /* Put the usual defaults back in at the end. */ 1.1.1.7 ! root 1823: bcopy ((char *) include_defaults_array, ! 1824: (char *) &include_defaults[num_dirs], 1.1 root 1825: sizeof (include_defaults_array)); 1826: } 1827: } 1828: 1.1.1.7 ! root 1829: append_include_chain (before_system, last_before_system); ! 1830: first_system_include = before_system; ! 1831: 1.1 root 1832: /* Unless -fnostdinc, 1833: tack on the standard include file dirs to the specified list */ 1834: if (!no_standard_includes) { 1835: struct default_include *p = include_defaults; 1.1.1.3 root 1836: char *specd_prefix = include_prefix; 1.1 root 1837: char *default_prefix = savestring (GCC_INCLUDE_DIR); 1838: int default_len = 0; 1839: /* Remove the `include' from /usr/local/lib/gcc.../include. */ 1840: if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) { 1841: default_len = strlen (default_prefix) - 7; 1842: default_prefix[default_len] = 0; 1843: } 1844: /* Search "translated" versions of GNU directories. 1845: These have /usr/local/lib/gcc... replaced by specd_prefix. */ 1846: if (specd_prefix != 0 && default_len != 0) 1847: for (p = include_defaults; p->fname; p++) { 1848: /* Some standard dirs are only for C++. */ 1.1.1.3 root 1849: if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) { 1.1 root 1850: /* Does this dir start with the prefix? */ 1851: if (!strncmp (p->fname, default_prefix, default_len)) { 1852: /* Yes; change prefix and add to search list. */ 1853: struct file_name_list *new 1854: = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 1855: int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len; 1856: char *str = (char *) xmalloc (this_len + 1); 1857: strcpy (str, specd_prefix); 1858: strcat (str, p->fname + default_len); 1859: new->fname = str; 1860: new->control_macro = 0; 1.1.1.7 ! root 1861: new->c_system_include_path = !p->cxx_aware; ! 1862: new->got_name_map = 0; 1.1.1.4 root 1863: append_include_chain (new, new); 1864: if (first_system_include == 0) 1865: first_system_include = new; 1.1 root 1866: } 1867: } 1868: } 1869: /* Search ordinary names for GNU include directories. */ 1870: for (p = include_defaults; p->fname; p++) { 1871: /* Some standard dirs are only for C++. */ 1.1.1.3 root 1872: if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) { 1.1 root 1873: struct file_name_list *new 1874: = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 1875: new->control_macro = 0; 1.1.1.7 ! root 1876: new->c_system_include_path = !p->cxx_aware; 1.1 root 1877: new->fname = p->fname; 1.1.1.7 ! root 1878: new->got_name_map = 0; 1.1.1.4 root 1879: append_include_chain (new, new); 1880: if (first_system_include == 0) 1881: first_system_include = new; 1.1 root 1882: } 1883: } 1884: } 1885: 1886: /* Tack the after_include chain at the end of the include chain. */ 1.1.1.4 root 1887: append_include_chain (after_include, last_after_include); 1888: if (first_system_include == 0) 1889: first_system_include = after_include; 1.1 root 1890: 1.1.1.6 root 1891: /* With -v, print the list of dirs to search. */ 1892: if (verbose) { 1893: struct file_name_list *p; 1894: fprintf (stderr, "#include \"...\" search starts here:\n"); 1895: for (p = include; p; p = p->next) { 1896: if (p == first_bracket_include) 1897: fprintf (stderr, "#include <...> search starts here:\n"); 1898: fprintf (stderr, " %s\n", p->fname); 1899: } 1900: fprintf (stderr, "End of search list.\n"); 1901: } 1902: 1.1 root 1903: /* Scan the -imacros files before the main input. 1904: Much like #including them, but with no_output set 1905: so that only their macro definitions matter. */ 1906: 1.1.1.7 ! root 1907: no_output++; no_record_file++; 1.1 root 1908: for (i = 1; i < argc; i++) 1909: if (pend_files[i]) { 1910: int fd = open (pend_files[i], O_RDONLY, 0666); 1911: if (fd < 0) { 1912: perror_with_name (pend_files[i]); 1913: return FAILURE_EXIT_CODE; 1914: } 1.1.1.4 root 1915: finclude (fd, pend_files[i], &outbuf, 0, NULL_PTR); 1.1 root 1916: } 1.1.1.7 ! root 1917: no_output--; no_record_file--; 1.1 root 1918: 1919: /* Copy the entire contents of the main input file into 1920: the stacked input buffer previously allocated for it. */ 1921: 1922: /* JF check for stdin */ 1923: if (in_fname == NULL || *in_fname == 0) { 1924: in_fname = ""; 1925: f = 0; 1926: } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0) 1927: goto perror; 1928: 1.1.1.7 ! root 1929: /* -MG doesn't select the form of output and must be specified with one of ! 1930: -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't ! 1931: inhibit compilation. */ ! 1932: if (print_deps_missing_files && (print_deps == 0 || !inhibit_output)) ! 1933: fatal ("-MG must be specified with one of -M or -MM"); ! 1934: 1.1 root 1935: /* Either of two environment variables can specify output of deps. 1936: Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", 1937: where OUTPUT_FILE is the file to write deps info to 1938: and DEPS_TARGET is the target to mention in the deps. */ 1939: 1940: if (print_deps == 0 1941: && (getenv ("SUNPRO_DEPENDENCIES") != 0 1942: || getenv ("DEPENDENCIES_OUTPUT") != 0)) { 1943: char *spec = getenv ("DEPENDENCIES_OUTPUT"); 1944: char *s; 1945: char *output_file; 1946: 1947: if (spec == 0) { 1948: spec = getenv ("SUNPRO_DEPENDENCIES"); 1949: print_deps = 2; 1950: } 1951: else 1952: print_deps = 1; 1953: 1954: s = spec; 1955: /* Find the space before the DEPS_TARGET, if there is one. */ 1.1.1.4 root 1956: /* This should use index. (mrs) */ 1.1 root 1957: while (*s != 0 && *s != ' ') s++; 1958: if (*s != 0) { 1959: deps_target = s + 1; 1960: output_file = (char *) xmalloc (s - spec + 1); 1961: bcopy (spec, output_file, s - spec); 1962: output_file[s - spec] = 0; 1963: } 1964: else { 1965: deps_target = 0; 1966: output_file = spec; 1967: } 1968: 1969: deps_file = output_file; 1.1.1.5 root 1970: deps_mode = "a"; 1.1 root 1971: } 1972: 1973: /* For -M, print the expected object file name 1974: as the target of this Make-rule. */ 1975: if (print_deps) { 1976: deps_allocated_size = 200; 1977: deps_buffer = (char *) xmalloc (deps_allocated_size); 1978: deps_buffer[0] = 0; 1979: deps_size = 0; 1980: deps_column = 0; 1981: 1982: if (deps_target) { 1.1.1.7 ! root 1983: deps_output (deps_target, ':'); ! 1984: } else if (*in_fname == 0) { ! 1985: deps_output ("-", ':'); ! 1986: } else { ! 1987: char *p, *q; 1.1 root 1988: int len; 1.1.1.7 ! root 1989: ! 1990: /* Discard all directory prefixes from filename. */ ! 1991: if ((q = rindex (in_fname, '/')) != NULL ! 1992: #ifdef DIR_SEPARATOR ! 1993: && (q = rindex (in_fname, DIR_SEPARATOR)) != NULL ! 1994: #endif ! 1995: ) ! 1996: ++q; ! 1997: else ! 1998: q = in_fname; ! 1999: ! 2000: /* Copy remainder to mungable area. */ ! 2001: p = (char *) alloca (strlen(q) + 8); ! 2002: strcpy (p, q); ! 2003: 1.1 root 2004: /* Output P, but remove known suffixes. */ 2005: len = strlen (p); 1.1.1.7 ! root 2006: q = p + len; ! 2007: if (len >= 2 ! 2008: && p[len - 2] == '.' ! 2009: && index("cCsSm", p[len - 1])) ! 2010: q = p + (len - 2); ! 2011: else if (len >= 3 ! 2012: && p[len - 3] == '.' 1.1 root 2013: && p[len - 2] == 'c' 2014: && p[len - 1] == 'c') 1.1.1.7 ! root 2015: q = p + (len - 3); ! 2016: else if (len >= 4 ! 2017: && p[len - 4] == '.' 1.1.1.5 root 2018: && p[len - 3] == 'c' 2019: && p[len - 2] == 'x' 2020: && p[len - 1] == 'x') 1.1.1.7 ! root 2021: q = p + (len - 4); ! 2022: else if (len >= 4 ! 2023: && p[len - 4] == '.' ! 2024: && p[len - 3] == 'c' ! 2025: && p[len - 2] == 'p' ! 2026: && p[len - 1] == 'p') ! 2027: q = p + (len - 4); ! 2028: 1.1 root 2029: /* Supply our own suffix. */ 1.1.1.4 root 2030: #ifndef VMS 1.1.1.7 ! root 2031: strcpy (q, ".o"); 1.1.1.4 root 2032: #else 1.1.1.7 ! root 2033: strcpy (q, ".obj"); 1.1.1.4 root 2034: #endif 1.1.1.7 ! root 2035: ! 2036: deps_output (p, ':'); ! 2037: deps_output (in_fname, ' '); 1.1 root 2038: } 2039: } 2040: 2041: file_size_and_mode (f, &st_mode, &st_size); 2042: fp->nominal_fname = fp->fname = in_fname; 2043: fp->lineno = 1; 2044: fp->system_header_p = 0; 2045: /* JF all this is mine about reading pipes and ttys */ 2046: if (! S_ISREG (st_mode)) { 2047: /* Read input from a file that is not a normal disk file. 2048: We cannot preallocate a buffer with the correct size, 2049: so we must read in the file a piece at the time and make it bigger. */ 2050: int size; 2051: int bsize; 2052: int cnt; 2053: 2054: bsize = 2000; 2055: size = 0; 2056: fp->buf = (U_CHAR *) xmalloc (bsize + 2); 2057: for (;;) { 1.1.1.7 ! root 2058: cnt = safe_read (f, fp->buf + size, bsize - size); 1.1 root 2059: if (cnt < 0) goto perror; /* error! */ 2060: size += cnt; 1.1.1.7 ! root 2061: if (size != bsize) break; /* End of file */ ! 2062: bsize *= 2; ! 2063: fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2); 1.1 root 2064: } 2065: fp->length = size; 2066: } else { 2067: /* Read a file whose size we can determine in advance. 2068: For the sake of VMS, st_size is just an upper bound. */ 2069: fp->buf = (U_CHAR *) xmalloc (st_size + 2); 1.1.1.7 ! root 2070: fp->length = safe_read (f, fp->buf, st_size); ! 2071: if (fp->length < 0) goto perror; 1.1 root 2072: } 2073: fp->bufp = fp->buf; 2074: fp->if_stack = if_stack; 2075: 2076: /* Make sure data ends with a newline. And put a null after it. */ 2077: 2078: if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n') 2079: /* Backslash-newline at end is not good enough. */ 2080: || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) { 2081: fp->buf[fp->length++] = '\n'; 2082: missing_newline = 1; 2083: } 2084: fp->buf[fp->length] = '\0'; 2085: 2086: /* Unless inhibited, convert trigraphs in the input. */ 2087: 2088: if (!no_trigraphs) 2089: trigraph_pcp (fp); 2090: 2091: /* Now that we know the input file is valid, open the output. */ 2092: 2093: if (!out_fname || !strcmp (out_fname, "")) 2094: out_fname = "stdout"; 2095: else if (! freopen (out_fname, "w", stdout)) 2096: pfatal_with_name (out_fname); 2097: 2098: output_line_command (fp, &outbuf, 0, same_file); 2099: 2100: /* Scan the -include files before the main input. */ 2101: 1.1.1.7 ! root 2102: no_record_file++; 1.1 root 2103: for (i = 1; i < argc; i++) 2104: if (pend_includes[i]) { 2105: int fd = open (pend_includes[i], O_RDONLY, 0666); 2106: if (fd < 0) { 2107: perror_with_name (pend_includes[i]); 2108: return FAILURE_EXIT_CODE; 2109: } 1.1.1.4 root 2110: finclude (fd, pend_includes[i], &outbuf, 0, NULL_PTR); 1.1 root 2111: } 1.1.1.7 ! root 2112: no_record_file--; 1.1 root 2113: 2114: /* Scan the input, processing macros and directives. */ 2115: 2116: rescan (&outbuf, 0); 2117: 1.1.1.5 root 2118: if (missing_newline) 2119: fp->lineno--; 2120: 1.1 root 2121: if (pedantic && missing_newline) 2122: pedwarn ("file does not end in newline"); 2123: 2124: /* Now we have processed the entire input 2125: Write whichever kind of output has been requested. */ 2126: 2127: if (dump_macros == dump_only) 2128: dump_all_macros (); 2129: else if (! inhibit_output) { 2130: write_output (); 2131: } 2132: 2133: if (print_deps) { 1.1.1.4 root 2134: /* Don't actually write the deps file if compilation has failed. */ 2135: if (errors == 0) { 1.1.1.5 root 2136: if (deps_file && ! (deps_stream = fopen (deps_file, deps_mode))) 1.1.1.4 root 2137: pfatal_with_name (deps_file); 1.1 root 2138: fputs (deps_buffer, deps_stream); 2139: putc ('\n', deps_stream); 1.1.1.4 root 2140: if (deps_file) { 2141: if (ferror (deps_stream) || fclose (deps_stream) != 0) 1.1 root 2142: fatal ("I/O error on output"); 2143: } 2144: } 2145: } 2146: 1.1.1.5 root 2147: if (pcp_outfile && pcp_outfile != stdout 2148: && (ferror (pcp_outfile) || fclose (pcp_outfile) != 0)) 2149: fatal ("I/O error on `-pcp' output"); 2150: 1.1.1.4 root 2151: if (ferror (stdout) || fclose (stdout) != 0) 1.1 root 2152: fatal ("I/O error on output"); 2153: 2154: if (errors) 2155: exit (FAILURE_EXIT_CODE); 2156: exit (SUCCESS_EXIT_CODE); 2157: 2158: perror: 2159: pfatal_with_name (in_fname); 2160: return 0; 2161: } 2162: 2163: /* Given a colon-separated list of file names PATH, 2164: add all the names to the search path for include files. */ 2165: 2166: static void 2167: path_include (path) 2168: char *path; 2169: { 2170: char *p; 2171: 2172: p = path; 2173: 2174: if (*p) 2175: while (1) { 2176: char *q = p; 2177: char *name; 2178: struct file_name_list *dirtmp; 2179: 2180: /* Find the end of this name. */ 1.1.1.3 root 2181: while (*q != 0 && *q != PATH_SEPARATOR) q++; 1.1 root 2182: if (p == q) { 2183: /* An empty name in the path stands for the current directory. */ 2184: name = (char *) xmalloc (2); 2185: name[0] = '.'; 2186: name[1] = 0; 2187: } else { 2188: /* Otherwise use the directory that is named. */ 2189: name = (char *) xmalloc (q - p + 1); 2190: bcopy (p, name, q - p); 2191: name[q - p] = 0; 2192: } 2193: 2194: dirtmp = (struct file_name_list *) 2195: xmalloc (sizeof (struct file_name_list)); 2196: dirtmp->next = 0; /* New one goes on the end */ 2197: dirtmp->control_macro = 0; 1.1.1.6 root 2198: dirtmp->c_system_include_path = 0; 1.1 root 2199: dirtmp->fname = name; 1.1.1.7 ! root 2200: dirtmp->got_name_map = 0; 1.1.1.4 root 2201: append_include_chain (dirtmp, dirtmp); 1.1 root 2202: 2203: /* Advance past this name. */ 2204: p = q; 2205: if (*p == 0) 2206: break; 2207: /* Skip the colon. */ 2208: p++; 2209: } 2210: } 2211: 1.1.1.7 ! root 2212: /* Return the address of the first character in S that equals C. ! 2213: S is an array of length N, possibly containing '\0's, and followed by '\0'. ! 2214: Return 0 if there is no such character. Assume that C itself is not '\0'. ! 2215: If we knew we could use memchr, we could just invoke memchr (S, C, N), ! 2216: but unfortunately memchr isn't autoconfigured yet. */ ! 2217: ! 2218: static U_CHAR * ! 2219: index0 (s, c, n) ! 2220: U_CHAR *s; ! 2221: int c; ! 2222: int n; ! 2223: { ! 2224: for (;;) { ! 2225: char *q = index (s, c); ! 2226: if (q) ! 2227: return (U_CHAR *) q; ! 2228: else { ! 2229: int l = strlen (s); ! 2230: if (l == n) ! 2231: return 0; ! 2232: l++; ! 2233: s += l; ! 2234: n -= l; ! 2235: } ! 2236: } ! 2237: } ! 2238: 1.1 root 2239: /* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF 2240: before main CCCP processing. Name `pcp' is also in honor of the 2241: drugs the trigraph designers must have been on. 2242: 2243: Using an extra pass through the buffer takes a little extra time, 2244: but is infinitely less hairy than trying to handle trigraphs inside 2245: strings, etc. everywhere, and also makes sure that trigraphs are 2246: only translated in the top level of processing. */ 2247: 2248: static void 2249: trigraph_pcp (buf) 2250: FILE_BUF *buf; 2251: { 1.1.1.7 ! root 2252: register U_CHAR c, *fptr, *bptr, *sptr, *lptr; 1.1 root 2253: int len; 2254: 2255: fptr = bptr = sptr = buf->buf; 1.1.1.7 ! root 2256: lptr = fptr + buf->length; ! 2257: while ((sptr = (U_CHAR *) index0 (sptr, '?', lptr - sptr)) != NULL) { 1.1 root 2258: if (*++sptr != '?') 2259: continue; 2260: switch (*++sptr) { 2261: case '=': 2262: c = '#'; 2263: break; 2264: case '(': 2265: c = '['; 2266: break; 2267: case '/': 2268: c = '\\'; 2269: break; 2270: case ')': 2271: c = ']'; 2272: break; 2273: case '\'': 2274: c = '^'; 2275: break; 2276: case '<': 2277: c = '{'; 2278: break; 2279: case '!': 2280: c = '|'; 2281: break; 2282: case '>': 2283: c = '}'; 2284: break; 2285: case '-': 2286: c = '~'; 2287: break; 2288: case '?': 2289: sptr--; 2290: continue; 2291: default: 2292: continue; 2293: } 2294: len = sptr - fptr - 2; 1.1.1.7 ! root 2295: ! 2296: /* BSD doc says bcopy () works right for overlapping strings. In ANSI ! 2297: C, this will be memmove (). */ 1.1 root 2298: if (bptr != fptr && len > 0) 1.1.1.7 ! root 2299: bcopy ((char *) fptr, (char *) bptr, len); ! 2300: 1.1 root 2301: bptr += len; 2302: *bptr++ = c; 2303: fptr = ++sptr; 2304: } 2305: len = buf->length - (fptr - buf->buf); 2306: if (bptr != fptr && len > 0) 1.1.1.7 ! root 2307: bcopy ((char *) fptr, (char *) bptr, len); 1.1 root 2308: buf->length -= fptr - bptr; 2309: buf->buf[buf->length] = '\0'; 2310: if (warn_trigraphs && fptr != bptr) 2311: warning ("%d trigraph(s) encountered", (fptr - bptr) / 2); 2312: } 2313: 2314: /* Move all backslash-newline pairs out of embarrassing places. 2315: Exchange all such pairs following BP 1.1.1.2 root 2316: with any potentially-embarrassing characters that follow them. 1.1 root 2317: Potentially-embarrassing characters are / and * 2318: (because a backslash-newline inside a comment delimiter 2319: would cause it not to be recognized). */ 2320: 2321: static void 2322: newline_fix (bp) 2323: U_CHAR *bp; 2324: { 2325: register U_CHAR *p = bp; 2326: 2327: /* First count the backslash-newline pairs here. */ 2328: 1.1.1.7 ! root 2329: while (p[0] == '\\' && p[1] == '\n') ! 2330: p += 2; 1.1 root 2331: 2332: /* What follows the backslash-newlines is not embarrassing. */ 2333: 1.1.1.7 ! root 2334: if (*p != '/' && *p != '*') 1.1 root 2335: return; 2336: 2337: /* Copy all potentially embarrassing characters 2338: that follow the backslash-newline pairs 2339: down to where the pairs originally started. */ 2340: 2341: while (*p == '*' || *p == '/') 2342: *bp++ = *p++; 2343: 2344: /* Now write the same number of pairs after the embarrassing chars. */ 1.1.1.7 ! root 2345: while (bp < p) { 1.1 root 2346: *bp++ = '\\'; 2347: *bp++ = '\n'; 2348: } 2349: } 2350: 2351: /* Like newline_fix but for use within a directive-name. 2352: Move any backslash-newlines up past any following symbol constituents. */ 2353: 2354: static void 2355: name_newline_fix (bp) 2356: U_CHAR *bp; 2357: { 2358: register U_CHAR *p = bp; 2359: 2360: /* First count the backslash-newline pairs here. */ 1.1.1.7 ! root 2361: while (p[0] == '\\' && p[1] == '\n') ! 2362: p += 2; 1.1 root 2363: 2364: /* What follows the backslash-newlines is not embarrassing. */ 2365: 1.1.1.7 ! root 2366: if (!is_idchar[*p]) 1.1 root 2367: return; 2368: 2369: /* Copy all potentially embarrassing characters 2370: that follow the backslash-newline pairs 2371: down to where the pairs originally started. */ 2372: 2373: while (is_idchar[*p]) 2374: *bp++ = *p++; 2375: 2376: /* Now write the same number of pairs after the embarrassing chars. */ 1.1.1.7 ! root 2377: while (bp < p) { 1.1 root 2378: *bp++ = '\\'; 2379: *bp++ = '\n'; 2380: } 2381: } 2382: 2383: /* Look for lint commands in comments. 2384: 2385: When we come in here, ibp points into a comment. Limit is as one expects. 2386: scan within the comment -- it should start, after lwsp, with a lint command. 2387: If so that command is returned as a (constant) string. 2388: 2389: Upon return, any arg will be pointed to with argstart and will be 2390: arglen long. Note that we don't parse that arg since it will just 2391: be printed out again. 2392: */ 2393: 2394: static char * 2395: get_lintcmd (ibp, limit, argstart, arglen, cmdlen) 2396: register U_CHAR *ibp; 2397: register U_CHAR *limit; 2398: U_CHAR **argstart; /* point to command arg */ 2399: int *arglen, *cmdlen; /* how long they are */ 2400: { 2401: long linsize; 2402: register U_CHAR *numptr; /* temp for arg parsing */ 2403: 2404: *arglen = 0; 2405: 2406: SKIP_WHITE_SPACE (ibp); 2407: 2408: if (ibp >= limit) return NULL; 2409: 2410: linsize = limit - ibp; 2411: 2412: /* Oh, I wish C had lexical functions... hell, I'll just open-code the set */ 2413: if ((linsize >= 10) && !strncmp (ibp, "NOTREACHED", 10)) { 2414: *cmdlen = 10; 2415: return "NOTREACHED"; 2416: } 2417: if ((linsize >= 8) && !strncmp (ibp, "ARGSUSED", 8)) { 2418: *cmdlen = 8; 2419: return "ARGSUSED"; 2420: } 1.1.1.4 root 2421: if ((linsize >= 11) && !strncmp (ibp, "LINTLIBRARY", 11)) { 2422: *cmdlen = 11; 1.1 root 2423: return "LINTLIBRARY"; 2424: } 2425: if ((linsize >= 7) && !strncmp (ibp, "VARARGS", 7)) { 2426: *cmdlen = 7; 2427: ibp += 7; linsize -= 7; 2428: if ((linsize == 0) || ! isdigit (*ibp)) return "VARARGS"; 2429: 2430: /* OK, read a number */ 2431: for (numptr = *argstart = ibp; (numptr < limit) && isdigit (*numptr); 2432: numptr++); 2433: *arglen = numptr - *argstart; 2434: return "VARARGS"; 2435: } 2436: return NULL; 2437: } 2438: 2439: /* 2440: * The main loop of the program. 2441: * 2442: * Read characters from the input stack, transferring them to the 2443: * output buffer OP. 2444: * 2445: * Macros are expanded and push levels on the input stack. 2446: * At the end of such a level it is popped off and we keep reading. 2447: * At the end of any other kind of level, we return. 2448: * #-directives are handled, except within macros. 2449: * 2450: * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input 2451: * and insert them when appropriate. This is set while scanning macro 2452: * arguments before substitution. It is zero when scanning for final output. 2453: * There are three types of Newline markers: 2454: * * Newline - follows a macro name that was not expanded 2455: * because it appeared inside an expansion of the same macro. 2456: * This marker prevents future expansion of that identifier. 2457: * When the input is rescanned into the final output, these are deleted. 2458: * These are also deleted by ## concatenation. 2459: * * Newline Space (or Newline and any other whitespace character) 2460: * stands for a place that tokens must be separated or whitespace 2461: * is otherwise desirable, but where the ANSI standard specifies there 2462: * is no whitespace. This marker turns into a Space (or whichever other 2463: * whitespace char appears in the marker) in the final output, 2464: * but it turns into nothing in an argument that is stringified with #. 2465: * Such stringified arguments are the only place where the ANSI standard 2466: * specifies with precision that whitespace may not appear. 2467: * 2468: * During this function, IP->bufp is kept cached in IBP for speed of access. 2469: * Likewise, OP->bufp is kept in OBP. Before calling a subroutine 2470: * IBP, IP and OBP must be copied back to memory. IP and IBP are 2471: * copied back with the RECACHE macro. OBP must be copied back from OP->bufp 2472: * explicitly, and before RECACHE, since RECACHE uses OBP. 2473: */ 2474: 2475: static void 2476: rescan (op, output_marks) 2477: FILE_BUF *op; 2478: int output_marks; 2479: { 2480: /* Character being scanned in main loop. */ 2481: register U_CHAR c; 2482: 2483: /* Length of pending accumulated identifier. */ 2484: register int ident_length = 0; 2485: 2486: /* Hash code of pending accumulated identifier. */ 2487: register int hash = 0; 2488: 2489: /* Current input level (&instack[indepth]). */ 2490: FILE_BUF *ip; 2491: 2492: /* Pointer for scanning input. */ 2493: register U_CHAR *ibp; 2494: 2495: /* Pointer to end of input. End of scan is controlled by LIMIT. */ 2496: register U_CHAR *limit; 2497: 2498: /* Pointer for storing output. */ 2499: register U_CHAR *obp; 2500: 2501: /* REDO_CHAR is nonzero if we are processing an identifier 2502: after backing up over the terminating character. 2503: Sometimes we process an identifier without backing up over 2504: the terminating character, if the terminating character 2505: is not special. Backing up is done so that the terminating character 2506: will be dispatched on again once the identifier is dealt with. */ 2507: int redo_char = 0; 2508: 2509: /* 1 if within an identifier inside of which a concatenation 2510: marker (Newline -) has been seen. */ 2511: int concatenated = 0; 2512: 2513: /* While scanning a comment or a string constant, 2514: this records the line it started on, for error messages. */ 2515: int start_line; 2516: 2517: /* Record position of last `real' newline. */ 2518: U_CHAR *beg_of_line; 2519: 2520: /* Pop the innermost input stack level, assuming it is a macro expansion. */ 2521: 2522: #define POPMACRO \ 2523: do { ip->macro->type = T_MACRO; \ 2524: if (ip->free_ptr) free (ip->free_ptr); \ 2525: --indepth; } while (0) 2526: 2527: /* Reload `rescan's local variables that describe the current 2528: level of the input stack. */ 2529: 2530: #define RECACHE \ 2531: do { ip = &instack[indepth]; \ 2532: ibp = ip->bufp; \ 2533: limit = ip->buf + ip->length; \ 2534: op->bufp = obp; \ 2535: check_expand (op, limit - ibp); \ 2536: beg_of_line = 0; \ 2537: obp = op->bufp; } while (0) 2538: 2539: if (no_output && instack[indepth].fname != 0) 1.1.1.7 ! root 2540: skip_if_group (&instack[indepth], 1, NULL); 1.1 root 2541: 2542: obp = op->bufp; 2543: RECACHE; 1.1.1.4 root 2544: 1.1 root 2545: beg_of_line = ibp; 2546: 2547: /* Our caller must always put a null after the end of 2548: the input at each input stack level. */ 2549: if (*limit != 0) 2550: abort (); 2551: 2552: while (1) { 2553: c = *ibp++; 2554: *obp++ = c; 2555: 2556: switch (c) { 2557: case '\\': 1.1.1.7 ! root 2558: if (*ibp == '\n' && !ip->macro) { ! 2559: /* At the top level, always merge lines ending with backslash-newline, ! 2560: even in middle of identifier. But do not merge lines in a macro, ! 2561: since backslash might be followed by a newline-space marker. */ 1.1 root 2562: ++ibp; 2563: ++ip->lineno; 2564: --obp; /* remove backslash from obuf */ 2565: break; 2566: } 1.1.1.7 ! root 2567: /* If ANSI, backslash is just another character outside a string. */ ! 2568: if (!traditional) ! 2569: goto randomchar; 1.1 root 2570: /* Otherwise, backslash suppresses specialness of following char, 2571: so copy it here to prevent the switch from seeing it. 2572: But first get any pending identifier processed. */ 2573: if (ident_length > 0) 2574: goto specialchar; 1.1.1.7 ! root 2575: if (ibp < limit) ! 2576: *obp++ = *ibp++; 1.1 root 2577: break; 2578: 2579: case '#': 2580: if (assertions_flag) { 2581: /* Copy #foo (bar lose) without macro expansion. */ 2582: SKIP_WHITE_SPACE (ibp); 2583: while (is_idchar[*ibp]) 2584: *obp++ = *ibp++; 2585: SKIP_WHITE_SPACE (ibp); 2586: if (*ibp == '(') { 2587: ip->bufp = ibp; 2588: skip_paren_group (ip); 1.1.1.7 ! root 2589: bcopy ((char *) ibp, (char *) obp, ip->bufp - ibp); 1.1 root 2590: obp += ip->bufp - ibp; 2591: ibp = ip->bufp; 2592: } 2593: } 2594: 2595: /* If this is expanding a macro definition, don't recognize 2596: preprocessor directives. */ 2597: if (ip->macro != 0) 2598: goto randomchar; 1.1.1.4 root 2599: /* If this is expand_into_temp_buffer, recognize them 2600: only after an actual newline at this level, 2601: not at the beginning of the input level. */ 2602: if (ip->fname == 0 && beg_of_line == ip->buf) 2603: goto randomchar; 1.1 root 2604: if (ident_length) 2605: goto specialchar; 2606: 1.1.1.4 root 2607: 1.1 root 2608: /* # keyword: a # must be first nonblank char on the line */ 2609: if (beg_of_line == 0) 2610: goto randomchar; 2611: { 2612: U_CHAR *bp; 2613: 2614: /* Scan from start of line, skipping whitespace, comments 2615: and backslash-newlines, and see if we reach this #. 2616: If not, this # is not special. */ 2617: bp = beg_of_line; 1.1.1.4 root 2618: /* If -traditional, require # to be at beginning of line. */ 2619: if (!traditional) 2620: while (1) { 2621: if (is_hor_space[*bp]) 1.1 root 2622: bp++; 1.1.1.4 root 2623: else if (*bp == '\\' && bp[1] == '\n') 2624: bp += 2; 2625: else if (*bp == '/' && bp[1] == '*') { 2626: bp += 2; 2627: while (!(*bp == '*' && bp[1] == '/')) 2628: bp++; 2629: bp += 2; 2630: } 1.1.1.7 ! root 2631: /* There is no point in trying to deal with C++ // comments here, ! 2632: because if there is one, then this # must be part of the ! 2633: comment and we would never reach here. */ 1.1.1.4 root 2634: else break; 1.1 root 2635: } 2636: if (bp + 1 != ibp) 2637: goto randomchar; 2638: } 2639: 2640: /* This # can start a directive. */ 2641: 2642: --obp; /* Don't copy the '#' */ 2643: 2644: ip->bufp = ibp; 2645: op->bufp = obp; 2646: if (! handle_directive (ip, op)) { 2647: #ifdef USE_C_ALLOCA 2648: alloca (0); 2649: #endif 2650: /* Not a known directive: treat it as ordinary text. 2651: IP, OP, IBP, etc. have not been changed. */ 2652: if (no_output && instack[indepth].fname) { 2653: /* If not generating expanded output, 2654: what we do with ordinary text is skip it. 2655: Discard everything until next # directive. */ 1.1.1.7 ! root 2656: skip_if_group (&instack[indepth], 1, 0); 1.1 root 2657: RECACHE; 2658: beg_of_line = ibp; 2659: break; 2660: } 2661: ++obp; /* Copy the '#' after all */ 1.1.1.6 root 2662: /* Don't expand an identifier that could be a macro directive. 2663: (Section 3.8.3 of the ANSI C standard) */ 2664: SKIP_WHITE_SPACE (ibp); 2665: if (is_idstart[*ibp]) 2666: { 2667: *obp++ = *ibp++; 2668: while (is_idchar[*ibp]) 2669: *obp++ = *ibp++; 2670: } 1.1 root 2671: goto randomchar; 2672: } 2673: #ifdef USE_C_ALLOCA 2674: alloca (0); 2675: #endif 2676: /* A # directive has been successfully processed. */ 2677: /* If not generating expanded output, ignore everything until 2678: next # directive. */ 2679: if (no_output && instack[indepth].fname) 1.1.1.7 ! root 2680: skip_if_group (&instack[indepth], 1, 0); 1.1 root 2681: obp = op->bufp; 2682: RECACHE; 2683: beg_of_line = ibp; 2684: break; 2685: 2686: case '\"': /* skip quoted string */ 2687: case '\'': 2688: /* A single quoted string is treated like a double -- some 2689: programs (e.g., troff) are perverse this way */ 2690: 2691: if (ident_length) 2692: goto specialchar; 2693: 2694: start_line = ip->lineno; 2695: 2696: /* Skip ahead to a matching quote. */ 2697: 2698: while (1) { 2699: if (ibp >= limit) { 1.1.1.4 root 2700: if (ip->macro != 0) { 2701: /* try harder: this string crosses a macro expansion boundary. 2702: This can happen naturally if -traditional. 2703: Otherwise, only -D can make a macro with an unmatched quote. */ 2704: POPMACRO; 2705: RECACHE; 2706: continue; 2707: } 2708: if (!traditional) { 1.1 root 2709: error_with_line (line_for_error (start_line), 2710: "unterminated string or character constant"); 2711: error_with_line (multiline_string_line, 2712: "possible real start of unterminated constant"); 2713: multiline_string_line = 0; 2714: } 2715: break; 2716: } 2717: *obp++ = *ibp; 2718: switch (*ibp++) { 2719: case '\n': 2720: ++ip->lineno; 2721: ++op->lineno; 2722: /* Traditionally, end of line ends a string constant with no error. 2723: So exit the loop and record the new line. */ 2724: if (traditional) { 2725: beg_of_line = ibp; 2726: goto while2end; 2727: } 1.1.1.5 root 2728: if (c == '\'') { 1.1 root 2729: error_with_line (line_for_error (start_line), 1.1.1.5 root 2730: "unterminated character constant"); 1.1 root 2731: goto while2end; 2732: } 1.1.1.5 root 2733: if (pedantic && multiline_string_line == 0) { 2734: pedwarn_with_line (line_for_error (start_line), 2735: "string constant runs past end of line"); 2736: } 1.1 root 2737: if (multiline_string_line == 0) 2738: multiline_string_line = ip->lineno - 1; 2739: break; 2740: 2741: case '\\': 2742: if (ibp >= limit) 2743: break; 2744: if (*ibp == '\n') { 2745: /* Backslash newline is replaced by nothing at all, 2746: but keep the line counts correct. */ 2747: --obp; 2748: ++ibp; 2749: ++ip->lineno; 2750: } else { 2751: /* ANSI stupidly requires that in \\ the second \ 2752: is *not* prevented from combining with a newline. */ 2753: while (*ibp == '\\' && ibp[1] == '\n') { 2754: ibp += 2; 2755: ++ip->lineno; 2756: } 2757: *obp++ = *ibp++; 2758: } 2759: break; 2760: 2761: case '\"': 2762: case '\'': 2763: if (ibp[-1] == c) 2764: goto while2end; 2765: break; 2766: } 2767: } 2768: while2end: 2769: break; 2770: 2771: case '/': 2772: if (*ibp == '\\' && ibp[1] == '\n') 2773: newline_fix (ibp); 2774: 2775: if (*ibp != '*' 1.1.1.4 root 2776: && !(cplusplus_comments && *ibp == '/')) 1.1 root 2777: goto randomchar; 2778: if (ip->macro != 0) 2779: goto randomchar; 2780: if (ident_length) 2781: goto specialchar; 2782: 2783: if (*ibp == '/') { 2784: /* C++ style comment... */ 2785: start_line = ip->lineno; 2786: 2787: --ibp; /* Back over the slash */ 2788: --obp; 2789: 2790: /* Comments are equivalent to spaces. */ 2791: if (! put_out_comments) 2792: *obp++ = ' '; 2793: else { 2794: /* must fake up a comment here */ 2795: *obp++ = '/'; 2796: *obp++ = '/'; 2797: } 2798: { 2799: U_CHAR *before_bp = ibp+2; 2800: 2801: while (ibp < limit) { 1.1.1.7 ! root 2802: if (ibp[-1] != '\\' && *ibp == '\n') { 1.1 root 2803: if (put_out_comments) { 1.1.1.7 ! root 2804: bcopy ((char *) before_bp, (char *) obp, ibp - before_bp); 1.1 root 2805: obp += ibp - before_bp; 2806: } 2807: break; 1.1.1.7 ! root 2808: } else { ! 2809: if (*ibp == '\n') { ! 2810: ++ip->lineno; ! 2811: /* Copy the newline into the output buffer, in order to ! 2812: avoid the pain of a #line every time a multiline comment ! 2813: is seen. */ ! 2814: if (!put_out_comments) ! 2815: *obp++ = '\n'; ! 2816: ++op->lineno; ! 2817: } ! 2818: ibp++; 1.1 root 2819: } 2820: } 2821: break; 2822: } 2823: } 2824: 2825: /* Ordinary C comment. Skip it, optionally copying it to output. */ 2826: 2827: start_line = ip->lineno; 2828: 2829: ++ibp; /* Skip the star. */ 2830: 2831: /* If this cpp is for lint, we peek inside the comments: */ 1.1.1.7 ! root 2832: if (for_lint) { 1.1 root 2833: U_CHAR *argbp; 2834: int cmdlen, arglen; 2835: char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen); 2836: 2837: if (lintcmd != NULL) { 1.1.1.7 ! root 2838: op->bufp = obp; ! 2839: check_expand (op, cmdlen + arglen + 14); ! 2840: obp = op->bufp; 1.1 root 2841: /* I believe it is always safe to emit this newline: */ 2842: obp[-1] = '\n'; 1.1.1.7 ! root 2843: bcopy ("#pragma lint ", (char *) obp, 13); 1.1 root 2844: obp += 13; 1.1.1.7 ! root 2845: bcopy (lintcmd, (char *) obp, cmdlen); 1.1 root 2846: obp += cmdlen; 2847: 2848: if (arglen != 0) { 2849: *(obp++) = ' '; 1.1.1.7 ! root 2850: bcopy (argbp, (char *) obp, arglen); 1.1 root 2851: obp += arglen; 2852: } 2853: 2854: /* OK, now bring us back to the state we were in before we entered 1.1.1.7 ! root 2855: this branch. We need #line because the #pragma's newline always ! 2856: messes up the line count. */ ! 2857: op->bufp = obp; 1.1 root 2858: output_line_command (ip, op, 0, same_file); 1.1.1.7 ! root 2859: check_expand (op, limit - ibp + 2); ! 2860: obp = op->bufp; 1.1 root 2861: *(obp++) = '/'; 2862: } 2863: } 2864: 2865: /* Comments are equivalent to spaces. 2866: Note that we already output the slash; we might not want it. 2867: For -traditional, a comment is equivalent to nothing. */ 2868: if (! put_out_comments) { 2869: if (traditional) 2870: obp--; 2871: else 2872: obp[-1] = ' '; 2873: } 2874: else 2875: *obp++ = '*'; 2876: 2877: { 2878: U_CHAR *before_bp = ibp; 2879: 2880: while (ibp < limit) { 2881: switch (*ibp++) { 2882: case '/': 2883: if (warn_comments && ibp < limit && *ibp == '*') 1.1.1.5 root 2884: warning ("`/*' within comment"); 1.1 root 2885: break; 2886: case '*': 2887: if (*ibp == '\\' && ibp[1] == '\n') 2888: newline_fix (ibp); 2889: if (ibp >= limit || *ibp == '/') 2890: goto comment_end; 2891: break; 2892: case '\n': 2893: ++ip->lineno; 2894: /* Copy the newline into the output buffer, in order to 2895: avoid the pain of a #line every time a multiline comment 2896: is seen. */ 2897: if (!put_out_comments) 2898: *obp++ = '\n'; 2899: ++op->lineno; 2900: } 2901: } 2902: comment_end: 2903: 2904: if (ibp >= limit) 2905: error_with_line (line_for_error (start_line), 2906: "unterminated comment"); 2907: else { 2908: ibp++; 2909: if (put_out_comments) { 1.1.1.7 ! root 2910: bcopy ((char *) before_bp, (char *) obp, ibp - before_bp); 1.1 root 2911: obp += ibp - before_bp; 2912: } 2913: } 2914: } 2915: break; 2916: 2917: case '$': 2918: if (!dollars_in_ident) 2919: goto randomchar; 2920: goto letter; 2921: 2922: case '0': case '1': case '2': case '3': case '4': 2923: case '5': case '6': case '7': case '8': case '9': 2924: /* If digit is not part of identifier, it starts a number, 2925: which means that following letters are not an identifier. 2926: "0x5" does not refer to an identifier "x5". 2927: So copy all alphanumerics that follow without accumulating 2928: as an identifier. Periods also, for sake of "3.e7". */ 2929: 2930: if (ident_length == 0) { 2931: while (ibp < limit) { 2932: while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') { 2933: ++ip->lineno; 2934: ibp += 2; 2935: } 2936: c = *ibp++; 1.1.1.7 ! root 2937: if (!is_idchar[c] && c != '.') { 1.1 root 2938: --ibp; 2939: break; 2940: } 2941: *obp++ = c; 2942: /* A sign can be part of a preprocessing number 2943: if it follows an e. */ 2944: if (c == 'e' || c == 'E') { 2945: while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') { 2946: ++ip->lineno; 2947: ibp += 2; 2948: } 2949: if (ibp < limit && (*ibp == '+' || *ibp == '-')) { 2950: *obp++ = *ibp++; 2951: /* But traditional C does not let the token go past the sign. */ 2952: if (traditional) 2953: break; 2954: } 2955: } 2956: } 2957: break; 2958: } 2959: /* fall through */ 2960: 2961: case '_': 2962: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 2963: case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': 2964: case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': 2965: case 's': case 't': case 'u': case 'v': case 'w': case 'x': 2966: case 'y': case 'z': 2967: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 2968: case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 2969: case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 2970: case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 2971: case 'Y': case 'Z': 2972: letter: 2973: ident_length++; 2974: /* Compute step of hash function, to avoid a proc call on every token */ 2975: hash = HASHSTEP (hash, c); 2976: break; 2977: 2978: case '\n': 1.1.1.5 root 2979: if (ip->fname == 0 && *ibp == '-') { 2980: /* Newline - inhibits expansion of preceding token. 2981: If expanding a macro arg, we keep the newline -. 2982: In final output, it is deleted. 2983: We recognize Newline - in macro bodies and macro args. */ 2984: if (! concatenated) { 2985: ident_length = 0; 2986: hash = 0; 2987: } 2988: ibp++; 2989: if (!output_marks) { 2990: obp--; 2991: } else { 2992: /* If expanding a macro arg, keep the newline -. */ 2993: *obp++ = '-'; 2994: } 2995: break; 2996: } 2997: 1.1 root 2998: /* If reprocessing a macro expansion, newline is a special marker. */ 1.1.1.5 root 2999: else if (ip->macro != 0) { 1.1 root 3000: /* Newline White is a "funny space" to separate tokens that are 3001: supposed to be separate but without space between. 3002: Here White means any whitespace character. 3003: Newline - marks a recursive macro use that is not 3004: supposed to be expandable. */ 3005: 1.1.1.5 root 3006: if (is_space[*ibp]) { 1.1 root 3007: /* Newline Space does not prevent expansion of preceding token 3008: so expand the preceding token and then come back. */ 3009: if (ident_length > 0) 3010: goto specialchar; 3011: 3012: /* If generating final output, newline space makes a space. */ 3013: if (!output_marks) { 3014: obp[-1] = *ibp++; 3015: /* And Newline Newline makes a newline, so count it. */ 3016: if (obp[-1] == '\n') 3017: op->lineno++; 3018: } else { 3019: /* If expanding a macro arg, keep the newline space. 3020: If the arg gets stringified, newline space makes nothing. */ 3021: *obp++ = *ibp++; 3022: } 3023: } else abort (); /* Newline followed by something random? */ 3024: break; 3025: } 3026: 3027: /* If there is a pending identifier, handle it and come back here. */ 3028: if (ident_length > 0) 3029: goto specialchar; 3030: 3031: beg_of_line = ibp; 3032: 3033: /* Update the line counts and output a #line if necessary. */ 3034: ++ip->lineno; 3035: ++op->lineno; 3036: if (ip->lineno != op->lineno) { 3037: op->bufp = obp; 3038: output_line_command (ip, op, 1, same_file); 1.1.1.7 ! root 3039: check_expand (op, limit - ibp); 1.1 root 3040: obp = op->bufp; 3041: } 3042: break; 3043: 3044: /* Come here either after (1) a null character that is part of the input 3045: or (2) at the end of the input, because there is a null there. */ 3046: case 0: 3047: if (ibp <= limit) 3048: /* Our input really contains a null character. */ 3049: goto randomchar; 3050: 3051: /* At end of a macro-expansion level, pop it and read next level. */ 3052: if (ip->macro != 0) { 3053: obp--; 3054: ibp--; 3055: /* If traditional, and we have an identifier that ends here, 3056: process it now, so we get the right error for recursion. */ 3057: if (traditional && ident_length 3058: && ! is_idchar[*instack[indepth - 1].bufp]) { 3059: redo_char = 1; 3060: goto randomchar; 3061: } 3062: POPMACRO; 3063: RECACHE; 3064: break; 3065: } 3066: 3067: /* If we don't have a pending identifier, 3068: return at end of input. */ 3069: if (ident_length == 0) { 3070: obp--; 3071: ibp--; 3072: op->bufp = obp; 3073: ip->bufp = ibp; 3074: goto ending; 3075: } 3076: 3077: /* If we do have a pending identifier, just consider this null 3078: a special character and arrange to dispatch on it again. 3079: The second time, IDENT_LENGTH will be zero so we will return. */ 3080: 3081: /* Fall through */ 3082: 3083: specialchar: 3084: 3085: /* Handle the case of a character such as /, ', " or null 3086: seen following an identifier. Back over it so that 3087: after the identifier is processed the special char 3088: will be dispatched on again. */ 3089: 3090: ibp--; 3091: obp--; 3092: redo_char = 1; 3093: 3094: default: 3095: 3096: randomchar: 3097: 3098: if (ident_length > 0) { 3099: register HASHNODE *hp; 3100: 3101: /* We have just seen an identifier end. If it's a macro, expand it. 3102: 3103: IDENT_LENGTH is the length of the identifier 3104: and HASH is its hash code. 3105: 3106: The identifier has already been copied to the output, 3107: so if it is a macro we must remove it. 3108: 3109: If REDO_CHAR is 0, the char that terminated the identifier 3110: has been skipped in the output and the input. 3111: OBP-IDENT_LENGTH-1 points to the identifier. 3112: If the identifier is a macro, we must back over the terminator. 3113: 3114: If REDO_CHAR is 1, the terminating char has already been 3115: backed over. OBP-IDENT_LENGTH points to the identifier. */ 3116: 3117: if (!pcp_outfile || pcp_inside_if) { 3118: startagain: 3119: for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL; 3120: hp = hp->next) { 3121: 3122: if (hp->length == ident_length) { 3123: int obufp_before_macroname; 3124: int op_lineno_before_macroname; 3125: register int i = ident_length; 3126: register U_CHAR *p = hp->name; 3127: register U_CHAR *q = obp - i; 3128: int disabled; 3129: 3130: if (! redo_char) 3131: q--; 3132: 3133: do { /* All this to avoid a strncmp () */ 3134: if (*p++ != *q++) 3135: goto hashcollision; 3136: } while (--i); 3137: 3138: /* We found a use of a macro name. 3139: see if the context shows it is a macro call. */ 3140: 3141: /* Back up over terminating character if not already done. */ 3142: if (! redo_char) { 3143: ibp--; 3144: obp--; 3145: } 3146: 3147: /* Save this as a displacement from the beginning of the output 3148: buffer. We can not save this as a position in the output 3149: buffer, because it may get realloc'ed by RECACHE. */ 3150: obufp_before_macroname = (obp - op->buf) - ident_length; 3151: op_lineno_before_macroname = op->lineno; 3152: 3153: if (hp->type == T_PCSTRING) { 3154: pcstring_used (hp); /* Mark the definition of this key 3155: as needed, ensuring that it 3156: will be output. */ 3157: break; /* Exit loop, since the key cannot have a 3158: definition any longer. */ 3159: } 3160: 3161: /* Record whether the macro is disabled. */ 3162: disabled = hp->type == T_DISABLED; 3163: 3164: /* This looks like a macro ref, but if the macro was disabled, 3165: just copy its name and put in a marker if requested. */ 3166: 3167: if (disabled) { 3168: #if 0 3169: /* This error check caught useful cases such as 1.1.1.5 root 3170: #define foo(x,y) bar (x (y,0), y) 3171: foo (foo, baz) */ 1.1 root 3172: if (traditional) 3173: error ("recursive use of macro `%s'", hp->name); 3174: #endif 3175: 3176: if (output_marks) { 3177: check_expand (op, limit - ibp + 2); 3178: *obp++ = '\n'; 3179: *obp++ = '-'; 3180: } 3181: break; 3182: } 3183: 3184: /* If macro wants an arglist, verify that a '(' follows. 3185: first skip all whitespace, copying it to the output 3186: after the macro name. Then, if there is no '(', 3187: decide this is not a macro call and leave things that way. */ 3188: if ((hp->type == T_MACRO || hp->type == T_DISABLED) 3189: && hp->value.defn->nargs >= 0) 3190: { 3191: U_CHAR *old_ibp = ibp; 3192: U_CHAR *old_obp = obp; 3193: int old_iln = ip->lineno; 3194: int old_oln = op->lineno; 3195: 3196: while (1) { 3197: /* Scan forward over whitespace, copying it to the output. */ 3198: if (ibp == limit && ip->macro != 0) { 3199: POPMACRO; 3200: RECACHE; 3201: old_ibp = ibp; 3202: old_obp = obp; 3203: old_iln = ip->lineno; 3204: old_oln = op->lineno; 3205: } 3206: /* A comment: copy it unchanged or discard it. */ 3207: else if (*ibp == '/' && ibp+1 != limit && ibp[1] == '*') { 3208: if (put_out_comments) { 3209: *obp++ = '/'; 3210: *obp++ = '*'; 3211: } else if (! traditional) { 3212: *obp++ = ' '; 3213: } 3214: ibp += 2; 3215: while (ibp + 1 != limit 3216: && !(ibp[0] == '*' && ibp[1] == '/')) { 3217: /* We need not worry about newline-marks, 3218: since they are never found in comments. */ 3219: if (*ibp == '\n') { 3220: /* Newline in a file. Count it. */ 3221: ++ip->lineno; 3222: ++op->lineno; 3223: } 3224: if (put_out_comments) 3225: *obp++ = *ibp++; 3226: else 3227: ibp++; 3228: } 3229: ibp += 2; 3230: if (put_out_comments) { 3231: *obp++ = '*'; 3232: *obp++ = '/'; 3233: } 3234: } 3235: else if (is_space[*ibp]) { 3236: *obp++ = *ibp++; 3237: if (ibp[-1] == '\n') { 3238: if (ip->macro == 0) { 3239: /* Newline in a file. Count it. */ 3240: ++ip->lineno; 3241: ++op->lineno; 3242: } else if (!output_marks) { 3243: /* A newline mark, and we don't want marks 3244: in the output. If it is newline-hyphen, 3245: discard it entirely. Otherwise, it is 3246: newline-whitechar, so keep the whitechar. */ 3247: obp--; 3248: if (*ibp == '-') 3249: ibp++; 3250: else { 3251: if (*ibp == '\n') 3252: ++op->lineno; 3253: *obp++ = *ibp++; 3254: } 3255: } else { 3256: /* A newline mark; copy both chars to the output. */ 3257: *obp++ = *ibp++; 3258: } 3259: } 3260: } 3261: else break; 3262: } 3263: if (*ibp != '(') { 3264: /* It isn't a macro call. 3265: Put back the space that we just skipped. */ 3266: ibp = old_ibp; 3267: obp = old_obp; 3268: ip->lineno = old_iln; 3269: op->lineno = old_oln; 3270: /* Exit the for loop. */ 3271: break; 3272: } 3273: } 3274: 3275: /* This is now known to be a macro call. 3276: Discard the macro name from the output, 1.1.1.7 ! root 3277: along with any following whitespace just copied, ! 3278: but preserve newlines if not outputting marks since this ! 3279: is more likely to do the right thing with line numbers. */ 1.1 root 3280: obp = op->buf + obufp_before_macroname; 1.1.1.7 ! root 3281: if (output_marks) ! 3282: op->lineno = op_lineno_before_macroname; ! 3283: else { ! 3284: int newlines = op->lineno - op_lineno_before_macroname; ! 3285: while (0 < newlines--) ! 3286: *obp++ = '\n'; ! 3287: } 1.1.1.5 root 3288: 3289: /* Prevent accidental token-pasting with a character 3290: before the macro call. */ 3291: if (!traditional && obp != op->buf 3292: && (obp[-1] == '-' || obp[1] == '+' || obp[1] == '&' 3293: || obp[-1] == '|' || obp[1] == '<' || obp[1] == '>')) { 3294: /* If we are expanding a macro arg, make a newline marker 3295: to separate the tokens. If we are making real output, 3296: a plain space will do. */ 3297: if (output_marks) 3298: *obp++ = '\n'; 3299: *obp++ = ' '; 3300: } 3301: 1.1 root 3302: /* Expand the macro, reading arguments as needed, 3303: and push the expansion on the input stack. */ 3304: ip->bufp = ibp; 3305: op->bufp = obp; 3306: macroexpand (hp, op); 3307: 3308: /* Reexamine input stack, since macroexpand has pushed 3309: a new level on it. */ 3310: obp = op->bufp; 3311: RECACHE; 3312: break; 3313: } 3314: hashcollision: 3315: ; 3316: } /* End hash-table-search loop */ 3317: } 3318: ident_length = hash = 0; /* Stop collecting identifier */ 3319: redo_char = 0; 3320: concatenated = 0; 3321: } /* End if (ident_length > 0) */ 3322: } /* End switch */ 3323: } /* End per-char loop */ 3324: 3325: /* Come here to return -- but first give an error message 3326: if there was an unterminated successful conditional. */ 3327: ending: 1.1.1.7 ! root 3328: if (if_stack != ip->if_stack) ! 3329: { ! 3330: char *str = "unknown"; ! 3331: ! 3332: switch (if_stack->type) ! 3333: { ! 3334: case T_IF: ! 3335: str = "if"; ! 3336: break; ! 3337: case T_IFDEF: ! 3338: str = "ifdef"; ! 3339: break; ! 3340: case T_IFNDEF: ! 3341: str = "ifndef"; ! 3342: break; ! 3343: case T_ELSE: ! 3344: str = "else"; ! 3345: break; ! 3346: case T_ELIF: ! 3347: str = "elif"; ! 3348: break; ! 3349: } ! 3350: ! 3351: error_with_line (line_for_error (if_stack->lineno), ! 3352: "unterminated `#%s' conditional", str); 1.1 root 3353: } 3354: if_stack = ip->if_stack; 3355: } 3356: 3357: /* 3358: * Rescan a string into a temporary buffer and return the result 3359: * as a FILE_BUF. Note this function returns a struct, not a pointer. 3360: * 3361: * OUTPUT_MARKS nonzero means keep Newline markers found in the input 3362: * and insert such markers when appropriate. See `rescan' for details. 3363: * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately 3364: * before substitution; it is 0 for other uses. 3365: */ 3366: static FILE_BUF 3367: expand_to_temp_buffer (buf, limit, output_marks, assertions) 3368: U_CHAR *buf, *limit; 3369: int output_marks, assertions; 3370: { 3371: register FILE_BUF *ip; 3372: FILE_BUF obuf; 3373: int length = limit - buf; 3374: U_CHAR *buf1; 3375: int odepth = indepth; 3376: int save_assertions_flag = assertions_flag; 3377: 3378: assertions_flag = assertions; 3379: 3380: if (length < 0) 3381: abort (); 3382: 3383: /* Set up the input on the input stack. */ 3384: 3385: buf1 = (U_CHAR *) alloca (length + 1); 3386: { 3387: register U_CHAR *p1 = buf; 3388: register U_CHAR *p2 = buf1; 3389: 3390: while (p1 != limit) 3391: *p2++ = *p1++; 3392: } 3393: buf1[length] = 0; 3394: 3395: /* Set up to receive the output. */ 3396: 3397: obuf.length = length * 2 + 100; /* Usually enough. Why be stingy? */ 3398: obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length); 3399: obuf.fname = 0; 3400: obuf.macro = 0; 3401: obuf.free_ptr = 0; 3402: 3403: CHECK_DEPTH ({return obuf;}); 3404: 3405: ++indepth; 3406: 3407: ip = &instack[indepth]; 3408: ip->fname = 0; 3409: ip->nominal_fname = 0; 3410: ip->system_header_p = 0; 3411: ip->macro = 0; 3412: ip->free_ptr = 0; 3413: ip->length = length; 3414: ip->buf = ip->bufp = buf1; 3415: ip->if_stack = if_stack; 3416: 3417: ip->lineno = obuf.lineno = 1; 3418: 3419: /* Scan the input, create the output. */ 3420: rescan (&obuf, output_marks); 3421: 3422: /* Pop input stack to original state. */ 3423: --indepth; 3424: 3425: if (indepth != odepth) 3426: abort (); 3427: 3428: /* Record the output. */ 3429: obuf.length = obuf.bufp - obuf.buf; 3430: 3431: assertions_flag = save_assertions_flag; 3432: return obuf; 3433: } 3434: 3435: /* 3436: * Process a # directive. Expects IP->bufp to point after the '#', as in 3437: * `#define foo bar'. Passes to the command handler 3438: * (do_define, do_include, etc.): the addresses of the 1st and 3439: * last chars of the command (starting immediately after the # 3440: * keyword), plus op and the keyword table pointer. If the command 3441: * contains comments it is copied into a temporary buffer sans comments 3442: * and the temporary buffer is passed to the command handler instead. 3443: * Likewise for backslash-newlines. 3444: * 3445: * Returns nonzero if this was a known # directive. 3446: * Otherwise, returns zero, without advancing the input pointer. 3447: */ 3448: 3449: static int 3450: handle_directive (ip, op) 3451: FILE_BUF *ip, *op; 3452: { 3453: register U_CHAR *bp, *cp; 3454: register struct directive *kt; 3455: register int ident_length; 3456: U_CHAR *resume_p; 3457: 3458: /* Nonzero means we must copy the entire command 3459: to get rid of comments or backslash-newlines. */ 3460: int copy_command = 0; 3461: 3462: U_CHAR *ident, *after_ident; 3463: 3464: bp = ip->bufp; 3465: 3466: /* Record where the directive started. do_xifdef needs this. */ 3467: directive_start = bp - 1; 3468: 3469: /* Skip whitespace and \-newline. */ 3470: while (1) { 3471: if (is_hor_space[*bp]) { 3472: if ((*bp == '\f' || *bp == '\v') && pedantic) 3473: pedwarn ("%s in preprocessing directive", 3474: *bp == '\f' ? "formfeed" : "vertical tab"); 3475: bp++; 1.1.1.7 ! root 3476: } else if (*bp == '/' && (bp[1] == '*' ! 3477: || (cplusplus_comments && bp[1] == '/'))) { ! 3478: ip->bufp = bp + 2; 1.1.1.2 root 3479: skip_to_end_of_comment (ip, &ip->lineno, 0); 1.1 root 3480: bp = ip->bufp; 3481: } else if (*bp == '\\' && bp[1] == '\n') { 3482: bp += 2; ip->lineno++; 3483: } else break; 3484: } 3485: 3486: /* Now find end of directive name. 3487: If we encounter a backslash-newline, exchange it with any following 3488: symbol-constituents so that we end up with a contiguous name. */ 3489: 3490: cp = bp; 3491: while (1) { 3492: if (is_idchar[*cp]) 3493: cp++; 3494: else { 3495: if (*cp == '\\' && cp[1] == '\n') 3496: name_newline_fix (cp); 3497: if (is_idchar[*cp]) 3498: cp++; 3499: else break; 3500: } 3501: } 3502: ident_length = cp - bp; 3503: ident = bp; 3504: after_ident = cp; 3505: 3506: /* A line of just `#' becomes blank. */ 3507: 3508: if (ident_length == 0 && *after_ident == '\n') { 3509: ip->bufp = after_ident; 3510: return 1; 3511: } 3512: 3513: if (ident_length == 0 || !is_idstart[*ident]) { 3514: U_CHAR *p = ident; 3515: while (is_idchar[*p]) { 3516: if (*p < '0' || *p > '9') 3517: break; 3518: p++; 3519: } 3520: /* Handle # followed by a line number. */ 3521: if (p != ident && !is_idchar[*p]) { 3522: static struct directive line_directive_table[] = { 3523: { 4, do_line, "line", T_LINE}, 3524: }; 3525: if (pedantic) 3526: pedwarn ("`#' followed by integer"); 3527: after_ident = ident; 3528: kt = line_directive_table; 3529: goto old_linenum; 3530: } 3531: 3532: /* Avoid error for `###' and similar cases unless -pedantic. */ 3533: if (p == ident) { 3534: while (*p == '#' || is_hor_space[*p]) p++; 3535: if (*p == '\n') { 3536: if (pedantic && !lang_asm) 3537: warning ("invalid preprocessor directive"); 3538: return 0; 3539: } 3540: } 3541: 3542: if (!lang_asm) 3543: error ("invalid preprocessor directive name"); 3544: 3545: return 0; 3546: } 3547: 3548: /* 3549: * Decode the keyword and call the appropriate expansion 3550: * routine, after moving the input pointer up to the next line. 3551: */ 3552: for (kt = directive_table; kt->length > 0; kt++) { 3553: if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length)) { 3554: register U_CHAR *buf; 3555: register U_CHAR *limit; 3556: int unterminated; 3557: int junk; 1.1.1.5 root 3558: int *already_output; 1.1 root 3559: 3560: /* Nonzero means do not delete comments within the directive. 3561: #define needs this when -traditional. */ 3562: int keep_comments; 3563: 3564: old_linenum: 3565: 3566: limit = ip->buf + ip->length; 3567: unterminated = 0; 1.1.1.5 root 3568: already_output = 0; 1.1 root 3569: keep_comments = traditional && kt->traditional_comments; 3570: /* #import is defined only in Objective C, or when on the NeXT. */ 3571: if (kt->type == T_IMPORT && !(objc || lookup ("__NeXT__", -1, -1))) 3572: break; 3573: 3574: /* Find the end of this command (first newline not backslashed 3575: and not in a string or comment). 3576: Set COPY_COMMAND if the command must be copied 3577: (it contains a backslash-newline or a comment). */ 3578: 3579: buf = bp = after_ident; 3580: while (bp < limit) { 3581: register U_CHAR c = *bp++; 3582: switch (c) { 3583: case '\\': 3584: if (bp < limit) { 3585: if (*bp == '\n') { 3586: ip->lineno++; 3587: copy_command = 1; 1.1.1.7 ! root 3588: bp++; ! 3589: } else if (traditional) ! 3590: bp++; 1.1 root 3591: } 3592: break; 3593: 3594: case '\'': 3595: case '\"': 3596: bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, ©_command, &unterminated); 3597: /* Don't bother calling the directive if we already got an error 3598: message due to unterminated string. Skip everything and pretend 3599: we called the directive. */ 3600: if (unterminated) { 3601: if (traditional) { 3602: /* Traditional preprocessing permits unterminated strings. */ 3603: ip->bufp = bp; 3604: goto endloop1; 3605: } 3606: ip->bufp = bp; 3607: return 1; 3608: } 3609: break; 3610: 3611: /* <...> is special for #include. */ 3612: case '<': 3613: if (!kt->angle_brackets) 3614: break; 1.1.1.7 ! root 3615: while (bp < limit && *bp != '>' && *bp != '\n') { ! 3616: if (*bp == '\\' && bp[1] == '\n') { ! 3617: ip->lineno++; ! 3618: copy_command = 1; ! 3619: bp++; ! 3620: } ! 3621: bp++; ! 3622: } 1.1 root 3623: break; 3624: 3625: case '/': 3626: if (*bp == '\\' && bp[1] == '\n') 3627: newline_fix (bp); 3628: if (*bp == '*' 1.1.1.4 root 3629: || (cplusplus_comments && *bp == '/')) { 1.1 root 3630: U_CHAR *obp = bp - 1; 3631: ip->bufp = bp + 1; 1.1.1.2 root 3632: skip_to_end_of_comment (ip, &ip->lineno, 0); 1.1 root 3633: bp = ip->bufp; 3634: /* No need to copy the command because of a comment at the end; 3635: just don't include the comment in the directive. */ 3636: if (bp == limit || *bp == '\n') { 3637: bp = obp; 3638: goto endloop1; 3639: } 3640: /* Don't remove the comments if -traditional. */ 3641: if (! keep_comments) 3642: copy_command++; 3643: } 3644: break; 3645: 3646: case '\f': 3647: case '\v': 3648: if (pedantic) 3649: pedwarn ("%s in preprocessing directive", 3650: c == '\f' ? "formfeed" : "vertical tab"); 3651: break; 3652: 3653: case '\n': 3654: --bp; /* Point to the newline */ 3655: ip->bufp = bp; 3656: goto endloop1; 3657: } 3658: } 3659: ip->bufp = bp; 3660: 3661: endloop1: 3662: resume_p = ip->bufp; 3663: /* BP is the end of the directive. 3664: RESUME_P is the next interesting data after the directive. 3665: A comment may come between. */ 3666: 3667: /* If a directive should be copied through, and -E was given, 3668: pass it through before removing comments. */ 3669: if (!no_output && kt->pass_thru && put_out_comments) { 3670: int len; 3671: 3672: /* Output directive name. */ 3673: check_expand (op, kt->length + 2); 3674: /* Make sure # is at the start of a line */ 3675: if (op->bufp > op->buf && op->bufp[-1] != '\n') { 3676: op->lineno++; 3677: *op->bufp++ = '\n'; 3678: } 3679: *op->bufp++ = '#'; 3680: bcopy (kt->name, op->bufp, kt->length); 3681: op->bufp += kt->length; 3682: 3683: /* Output arguments. */ 3684: len = (bp - buf); 3685: check_expand (op, len); 1.1.1.7 ! root 3686: bcopy (buf, (char *) op->bufp, len); 1.1 root 3687: op->bufp += len; 3688: /* Take account of any (escaped) newlines just output. */ 3689: while (--len >= 0) 3690: if (buf[len] == '\n') 3691: op->lineno++; 3692: 3693: already_output = &junk; 3694: } /* Don't we need a newline or #line? */ 3695: 3696: if (copy_command) { 3697: register U_CHAR *xp = buf; 3698: /* Need to copy entire command into temp buffer before dispatching */ 3699: 3700: cp = (U_CHAR *) alloca (bp - buf + 5); /* room for cmd plus 3701: some slop */ 3702: buf = cp; 3703: 3704: /* Copy to the new buffer, deleting comments 3705: and backslash-newlines (and whitespace surrounding the latter). */ 3706: 3707: while (xp < bp) { 3708: register U_CHAR c = *xp++; 3709: *cp++ = c; 3710: 3711: switch (c) { 3712: case '\n': 3713: abort (); /* A bare newline should never part of the line. */ 3714: break; 3715: 3716: /* <...> is special for #include. */ 3717: case '<': 3718: if (!kt->angle_brackets) 3719: break; 3720: while (xp < bp && c != '>') { 3721: c = *xp++; 3722: if (c == '\\' && xp < bp && *xp == '\n') 3723: xp++; 3724: else 3725: *cp++ = c; 3726: } 3727: break; 3728: 3729: case '\\': 3730: if (*xp == '\n') { 3731: xp++; 3732: cp--; 3733: if (cp != buf && is_space[cp[-1]]) { 3734: while (cp != buf && is_space[cp[-1]]) cp--; 3735: cp++; 3736: SKIP_WHITE_SPACE (xp); 3737: } else if (is_space[*xp]) { 3738: *cp++ = *xp++; 3739: SKIP_WHITE_SPACE (xp); 3740: } 1.1.1.3 root 3741: } else { 3742: *cp++ = *xp++; 1.1 root 3743: } 3744: break; 3745: 3746: case '\'': 3747: case '\"': 3748: { 3749: register U_CHAR *bp1 1.1.1.4 root 3750: = skip_quoted_string (xp - 1, bp, ip->lineno, 3751: NULL_PTR, NULL_PTR, NULL_PTR); 1.1 root 3752: while (xp != bp1) 3753: if (*xp == '\\') { 3754: if (*++xp != '\n') 3755: *cp++ = '\\'; 3756: else 3757: xp++; 3758: } else 3759: *cp++ = *xp++; 3760: } 3761: break; 3762: 3763: case '/': 3764: if (*xp == '*' 1.1.1.4 root 3765: || (cplusplus_comments && *xp == '/')) { 1.1 root 3766: ip->bufp = xp + 1; 3767: /* If we already copied the command through, 3768: already_output != 0 prevents outputting comment now. */ 1.1.1.2 root 3769: skip_to_end_of_comment (ip, already_output, 0); 1.1 root 3770: if (keep_comments) 3771: while (xp != ip->bufp) 3772: *cp++ = *xp++; 3773: /* Delete or replace the slash. */ 3774: else if (traditional) 3775: cp--; 3776: else 3777: cp[-1] = ' '; 3778: xp = ip->bufp; 3779: } 3780: } 3781: } 3782: 3783: /* Null-terminate the copy. */ 3784: 3785: *cp = 0; 3786: } else 3787: cp = bp; 3788: 3789: ip->bufp = resume_p; 3790: 3791: /* Some directives should be written out for cc1 to process, 3792: just as if they were not defined. And sometimes we're copying 3793: definitions through. */ 3794: 3795: if (!no_output && already_output == 0 3796: && (kt->pass_thru 3797: || (kt->type == T_DEFINE 3798: && (dump_macros == dump_names 3799: || dump_macros == dump_definitions)))) { 3800: int len; 3801: 3802: /* Output directive name. */ 3803: check_expand (op, kt->length + 1); 3804: *op->bufp++ = '#'; 1.1.1.7 ! root 3805: bcopy (kt->name, (char *) op->bufp, kt->length); 1.1 root 3806: op->bufp += kt->length; 3807: 3808: if (kt->pass_thru || dump_macros == dump_definitions) { 3809: /* Output arguments. */ 3810: len = (cp - buf); 3811: check_expand (op, len); 1.1.1.7 ! root 3812: bcopy (buf, (char *) op->bufp, len); 1.1 root 3813: op->bufp += len; 1.1.1.4 root 3814: } else if (kt->type == T_DEFINE && dump_macros == dump_names) { 3815: U_CHAR *xp = buf; 3816: U_CHAR *yp; 3817: SKIP_WHITE_SPACE (xp); 3818: yp = xp; 3819: while (is_idchar[*xp]) xp++; 3820: len = (xp - yp); 3821: check_expand (op, len + 1); 3822: *op->bufp++ = ' '; 3823: bcopy (yp, op->bufp, len); 3824: op->bufp += len; 1.1 root 3825: } 3826: } /* Don't we need a newline or #line? */ 3827: 3828: /* Call the appropriate command handler. buf now points to 3829: either the appropriate place in the input buffer, or to 3830: the temp buffer if it was necessary to make one. cp 3831: points to the first char after the contents of the (possibly 3832: copied) command, in either case. */ 3833: (*kt->func) (buf, cp, op, kt); 3834: check_expand (op, ip->length - (ip->bufp - ip->buf)); 3835: 3836: return 1; 3837: } 3838: } 3839: 3840: /* It is deliberate that we don't warn about undefined directives. 3841: That is the responsibility of cc1. */ 3842: return 0; 3843: } 3844: 1.1.1.3 root 3845: static struct tm * 3846: timestamp () 3847: { 3848: static struct tm *timebuf; 3849: if (!timebuf) { 1.1.1.7 ! root 3850: time_t t = time ((time_t *)0); 1.1.1.3 root 3851: timebuf = localtime (&t); 3852: } 3853: return timebuf; 3854: } 3855: 1.1 root 3856: static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 3857: "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 3858: }; 3859: 3860: /* 3861: * expand things like __FILE__. Place the expansion into the output 3862: * buffer *without* rescanning. 3863: */ 3864: 3865: static void 3866: special_symbol (hp, op) 3867: HASHNODE *hp; 3868: FILE_BUF *op; 3869: { 3870: char *buf; 3871: int i, len; 3872: int true_indepth; 3873: FILE_BUF *ip = NULL; 1.1.1.3 root 3874: struct tm *timebuf; 1.1 root 3875: 3876: int paren = 0; /* For special `defined' keyword */ 3877: 3878: if (pcp_outfile && pcp_inside_if 3879: && hp->type != T_SPEC_DEFINED && hp->type != T_CONST) 3880: error ("Predefined macro `%s' used inside `#if' during precompilation", 3881: hp->name); 3882: 3883: for (i = indepth; i >= 0; i--) 3884: if (instack[i].fname != NULL) { 3885: ip = &instack[i]; 3886: break; 3887: } 3888: if (ip == NULL) { 3889: error ("cccp error: not in any file?!"); 3890: return; /* the show must go on */ 3891: } 3892: 3893: switch (hp->type) { 3894: case T_FILE: 3895: case T_BASE_FILE: 3896: { 3897: char *string; 3898: if (hp->type == T_FILE) 3899: string = ip->nominal_fname; 3900: else 3901: string = instack[0].nominal_fname; 3902: 3903: if (string) 3904: { 1.1.1.6 root 3905: buf = (char *) alloca (3 + 4 * strlen (string)); 3906: quote_string (buf, string); 1.1 root 3907: } 3908: else 3909: buf = "\"\""; 3910: 3911: break; 3912: } 3913: 3914: case T_INCLUDE_LEVEL: 3915: true_indepth = 0; 3916: for (i = indepth; i >= 0; i--) 3917: if (instack[i].fname != NULL) 3918: true_indepth++; 3919: 3920: buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */ 3921: sprintf (buf, "%d", true_indepth - 1); 3922: break; 3923: 3924: case T_VERSION: 3925: buf = (char *) alloca (3 + strlen (version_string)); 3926: sprintf (buf, "\"%s\"", version_string); 3927: break; 3928: 1.1.1.6 root 3929: #ifndef NO_BUILTIN_SIZE_TYPE 1.1 root 3930: case T_SIZE_TYPE: 1.1.1.7 ! root 3931: buf = SIZE_TYPE; 1.1 root 3932: break; 1.1.1.6 root 3933: #endif 1.1 root 3934: 1.1.1.6 root 3935: #ifndef NO_BUILTIN_PTRDIFF_TYPE 1.1 root 3936: case T_PTRDIFF_TYPE: 1.1.1.7 ! root 3937: buf = PTRDIFF_TYPE; 1.1 root 3938: break; 1.1.1.6 root 3939: #endif 1.1 root 3940: 3941: case T_WCHAR_TYPE: 1.1.1.7 ! root 3942: buf = wchar_type; 1.1 root 3943: break; 3944: 1.1.1.5 root 3945: case T_USER_LABEL_PREFIX_TYPE: 1.1.1.7 ! root 3946: buf = USER_LABEL_PREFIX; 1.1.1.5 root 3947: break; 3948: 3949: case T_REGISTER_PREFIX_TYPE: 1.1.1.7 ! root 3950: buf = REGISTER_PREFIX; 1.1.1.5 root 3951: break; 3952: 1.1 root 3953: case T_CONST: 3954: buf = (char *) alloca (4 * sizeof (int)); 3955: sprintf (buf, "%d", hp->value.ival); 3956: if (pcp_inside_if && pcp_outfile) 3957: /* Output a precondition for this macro use */ 3958: fprintf (pcp_outfile, "#define %s %d\n", hp->name, hp->value.ival); 3959: break; 3960: 3961: case T_SPECLINE: 3962: buf = (char *) alloca (10); 3963: sprintf (buf, "%d", ip->lineno); 3964: break; 3965: 3966: case T_DATE: 3967: case T_TIME: 3968: buf = (char *) alloca (20); 1.1.1.3 root 3969: timebuf = timestamp (); 1.1 root 3970: if (hp->type == T_DATE) 3971: sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon], 3972: timebuf->tm_mday, timebuf->tm_year + 1900); 3973: else 3974: sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min, 3975: timebuf->tm_sec); 3976: break; 3977: 3978: case T_SPEC_DEFINED: 3979: buf = " 0 "; /* Assume symbol is not defined */ 3980: ip = &instack[indepth]; 3981: SKIP_WHITE_SPACE (ip->bufp); 3982: if (*ip->bufp == '(') { 3983: paren++; 3984: ip->bufp++; /* Skip over the paren */ 3985: SKIP_WHITE_SPACE (ip->bufp); 3986: } 3987: 3988: if (!is_idstart[*ip->bufp]) 3989: goto oops; 3990: if (hp = lookup (ip->bufp, -1, -1)) { 3991: if (pcp_outfile && pcp_inside_if 1.1.1.7 ! root 3992: && (hp->type == T_CONST ! 3993: || (hp->type == T_MACRO && hp->value.defn->predefined))) 1.1 root 3994: /* Output a precondition for this macro use. */ 3995: fprintf (pcp_outfile, "#define %s\n", hp->name); 3996: buf = " 1 "; 3997: } 3998: else 3999: if (pcp_outfile && pcp_inside_if) { 4000: /* Output a precondition for this macro use */ 4001: U_CHAR *cp = ip->bufp; 4002: fprintf (pcp_outfile, "#undef "); 4003: while (is_idchar[*cp]) /* Ick! */ 4004: fputc (*cp++, pcp_outfile); 4005: putc ('\n', pcp_outfile); 4006: } 4007: while (is_idchar[*ip->bufp]) 4008: ++ip->bufp; 4009: SKIP_WHITE_SPACE (ip->bufp); 4010: if (paren) { 4011: if (*ip->bufp != ')') 4012: goto oops; 4013: ++ip->bufp; 4014: } 4015: break; 4016: 4017: oops: 4018: 4019: error ("`defined' without an identifier"); 4020: break; 4021: 4022: default: 4023: error ("cccp error: invalid special hash type"); /* time for gdb */ 4024: abort (); 4025: } 4026: len = strlen (buf); 4027: check_expand (op, len); 1.1.1.7 ! root 4028: bcopy (buf, (char *) op->bufp, len); 1.1 root 4029: op->bufp += len; 4030: 4031: return; 4032: } 4033: 4034: 4035: /* Routines to handle #directives */ 4036: 4037: /* Handle #include and #import. 4038: This function expects to see "fname" or <fname> on the input. */ 4039: 4040: static int 4041: do_include (buf, limit, op, keyword) 4042: U_CHAR *buf, *limit; 4043: FILE_BUF *op; 4044: struct directive *keyword; 4045: { 4046: int importing = (keyword->type == T_IMPORT); 4047: int skip_dirs = (keyword->type == T_INCLUDE_NEXT); 4048: static int import_warning = 0; 4049: char *fname; /* Dynamically allocated fname buffer */ 4050: char *pcftry; 4051: char *pcfname; 4052: U_CHAR *fbeg, *fend; /* Beginning and end of fname */ 4053: 4054: struct file_name_list *search_start = include; /* Chain of dirs to search */ 4055: struct file_name_list dsp[1]; /* First in chain, if #include "..." */ 1.1.1.4 root 4056: struct file_name_list *searchptr = 0; 1.1 root 4057: int flen; 4058: 4059: int f; /* file number */ 4060: 4061: int retried = 0; /* Have already tried macro 4062: expanding the include line*/ 4063: FILE_BUF trybuf; /* It got expanded into here */ 1.1.1.4 root 4064: int angle_brackets = 0; /* 0 for "...", 1 for <...> */ 1.1 root 4065: int pcf = -1; 4066: char *pcfbuf; 4067: int pcfbuflimit; 4068: int pcfnum; 4069: f= -1; /* JF we iz paranoid! */ 4070: 1.1.1.4 root 4071: if (importing && warn_import && !inhibit_warnings 1.1.1.2 root 4072: && !instack[indepth].system_header_p && !import_warning) { 1.1 root 4073: import_warning = 1; 4074: warning ("using `#import' is not recommended"); 4075: fprintf (stderr, "The fact that a certain header file need not be processed more than once\n"); 4076: fprintf (stderr, "should be indicated in the header file, not where it is used.\n"); 4077: fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n"); 4078: fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n"); 4079: fprintf (stderr, " #define _FOO_H_INCLUDED\n"); 4080: fprintf (stderr, " ... <real contents of file> ...\n"); 4081: fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n"); 4082: fprintf (stderr, "Then users can use `#include' any number of times.\n"); 4083: fprintf (stderr, "GNU C automatically avoids processing the file more than once\n"); 4084: fprintf (stderr, "when it is equipped with such a conditional.\n"); 4085: } 4086: 4087: get_filename: 4088: 4089: fbeg = buf; 4090: SKIP_WHITE_SPACE (fbeg); 4091: /* Discard trailing whitespace so we can easily see 4092: if we have parsed all the significant chars we were given. */ 4093: while (limit != fbeg && is_hor_space[limit[-1]]) limit--; 4094: 4095: switch (*fbeg++) { 4096: case '\"': 1.1.1.4 root 4097: { 1.1 root 4098: FILE_BUF *fp; 1.1.1.4 root 4099: /* Copy the operand text, concatenating the strings. */ 4100: { 4101: U_CHAR *fin = fbeg; 4102: fbeg = (U_CHAR *) alloca (limit - fbeg + 1); 4103: fend = fbeg; 4104: while (fin != limit) { 4105: while (fin != limit && *fin != '\"') 4106: *fend++ = *fin++; 4107: fin++; 4108: if (fin == limit) 4109: break; 4110: /* If not at the end, there had better be another string. */ 4111: /* Skip just horiz space, and don't go past limit. */ 4112: while (fin != limit && is_hor_space[*fin]) fin++; 4113: if (fin != limit && *fin == '\"') 4114: fin++; 4115: else 4116: goto fail; 4117: } 4118: } 1.1.1.5 root 4119: *fend = 0; 1.1 root 4120: 4121: /* We have "filename". Figure out directory this source 4122: file is coming from and put it on the front of the list. */ 4123: 4124: /* If -I- was specified, don't search current dir, only spec'd ones. */ 4125: if (ignore_srcdir) break; 4126: 4127: for (fp = &instack[indepth]; fp >= instack; fp--) 4128: { 4129: int n; 4130: char *ep,*nam; 4131: 4132: if ((nam = fp->nominal_fname) != NULL) { 4133: /* Found a named file. Figure out dir of the file, 4134: and put it in front of the search list. */ 4135: dsp[0].next = search_start; 4136: search_start = dsp; 4137: #ifndef VMS 4138: ep = rindex (nam, '/'); 4139: #else /* VMS */ 4140: ep = rindex (nam, ']'); 4141: if (ep == NULL) ep = rindex (nam, '>'); 4142: if (ep == NULL) ep = rindex (nam, ':'); 4143: if (ep != NULL) ep++; 4144: #endif /* VMS */ 4145: if (ep != NULL) { 4146: n = ep - nam; 4147: dsp[0].fname = (char *) alloca (n + 1); 4148: strncpy (dsp[0].fname, nam, n); 4149: dsp[0].fname[n] = '\0'; 1.1.1.4 root 4150: if (n + INCLUDE_LEN_FUDGE > max_include_len) 4151: max_include_len = n + INCLUDE_LEN_FUDGE; 1.1 root 4152: } else { 4153: dsp[0].fname = 0; /* Current directory */ 4154: } 1.1.1.7 ! root 4155: dsp[0].got_name_map = 0; 1.1 root 4156: break; 4157: } 4158: } 4159: break; 4160: } 4161: 4162: case '<': 4163: fend = fbeg; 4164: while (fend != limit && *fend != '>') fend++; 4165: if (*fend == '>' && fend + 1 == limit) { 1.1.1.4 root 4166: angle_brackets = 1; 1.1 root 4167: /* If -I-, start with the first -I dir after the -I-. */ 4168: if (first_bracket_include) 4169: search_start = first_bracket_include; 4170: break; 4171: } 4172: goto fail; 4173: 4174: default: 1.1.1.7 ! root 4175: #ifdef VMS ! 4176: /* ! 4177: * Support '#include xyz' like VAX-C to allow for easy use of all the ! 4178: * decwindow include files. It defaults to '#include <xyz.h>' (so the ! 4179: * code from case '<' is repeated here) and generates a warning. ! 4180: */ ! 4181: if (isalpha(*(--fbeg))) { ! 4182: fend = fbeg; ! 4183: while (fend != limit && (!isspace(*fend))) fend++; ! 4184: warning ("VAX-C-style include specification found, use '#include <filename.h>' !"); ! 4185: if (fend == limit) { ! 4186: angle_brackets = 1; ! 4187: /* If -I-, start with the first -I dir after the -I-. */ ! 4188: if (first_bracket_include) ! 4189: search_start = first_bracket_include; ! 4190: break; ! 4191: } ! 4192: } ! 4193: #endif ! 4194: 1.1 root 4195: fail: 4196: if (retried) { 1.1.1.5 root 4197: error ("`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name); 1.1 root 4198: return 0; 4199: } else { 4200: trybuf = expand_to_temp_buffer (buf, limit, 0, 0); 4201: buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1); 1.1.1.7 ! root 4202: bcopy ((char *) trybuf.buf, (char *) buf, trybuf.bufp - trybuf.buf); 1.1 root 4203: limit = buf + (trybuf.bufp - trybuf.buf); 4204: free (trybuf.buf); 4205: retried++; 4206: goto get_filename; 4207: } 4208: } 4209: 4210: /* For #include_next, skip in the search path 4211: past the dir in which the containing file was found. */ 4212: if (skip_dirs) { 4213: FILE_BUF *fp; 4214: for (fp = &instack[indepth]; fp >= instack; fp--) 4215: if (fp->fname != NULL) { 4216: /* fp->dir is null if the containing file was specified 4217: with an absolute file name. In that case, don't skip anything. */ 4218: if (fp->dir) 4219: search_start = fp->dir->next; 4220: break; 4221: } 4222: } 4223: 4224: flen = fend - fbeg; 1.1.1.5 root 4225: 4226: if (flen == 0) 4227: { 4228: error ("empty file name in `#%s'", keyword->name); 4229: return 0; 4230: } 4231: 1.1 root 4232: /* Allocate this permanently, because it gets stored in the definitions 4233: of macros. */ 1.1.1.7 ! root 4234: fname = (char *) xmalloc (max_include_len + flen + 4); 1.1 root 4235: /* + 2 above for slash and terminating null. */ 1.1.1.7 ! root 4236: /* + 2 added for '.h' on VMS (to support '#include filename') */ 1.1 root 4237: 4238: /* If specified file name is absolute, just open it. */ 4239: 4240: if (*fbeg == '/') { 4241: strncpy (fname, fbeg, flen); 4242: fname[flen] = 0; 1.1.1.4 root 4243: if (redundant_include_p (fname)) 1.1.1.2 root 4244: return 0; 1.1 root 4245: if (importing) 1.1.1.7 ! root 4246: f = lookup_import (fname, NULL_PTR); 1.1 root 4247: else 1.1.1.7 ! root 4248: f = open_include_file (fname, NULL_PTR); 1.1 root 4249: if (f == -2) 4250: return 0; /* Already included this file */ 4251: } else { 4252: /* Search directory path, trying to open the file. 4253: Copy each filename tried into FNAME. */ 4254: 4255: for (searchptr = search_start; searchptr; searchptr = searchptr->next) { 4256: if (searchptr->fname) { 4257: /* The empty string in a search path is ignored. 4258: This makes it possible to turn off entirely 4259: a standard piece of the list. */ 4260: if (searchptr->fname[0] == 0) 4261: continue; 4262: strcpy (fname, searchptr->fname); 4263: strcat (fname, "/"); 4264: fname[strlen (fname) + flen] = 0; 4265: } else { 4266: fname[0] = 0; 4267: } 4268: strncat (fname, fbeg, flen); 4269: #ifdef VMS 4270: /* Change this 1/2 Unix 1/2 VMS file specification into a 4271: full VMS file specification */ 4272: if (searchptr->fname && (searchptr->fname[0] != 0)) { 4273: /* Fix up the filename */ 4274: hack_vms_include_specification (fname); 4275: } else { 4276: /* This is a normal VMS filespec, so use it unchanged. */ 4277: strncpy (fname, fbeg, flen); 4278: fname[flen] = 0; 1.1.1.7 ! root 4279: /* if it's '#include filename', add the missing .h */ ! 4280: if (index(fname,'.')==NULL) { ! 4281: strcat (fname, ".h"); ! 4282: } 1.1 root 4283: } 4284: #endif /* VMS */ 4285: if (importing) 1.1.1.7 ! root 4286: f = lookup_import (fname, searchptr); 1.1 root 4287: else 1.1.1.7 ! root 4288: f = open_include_file (fname, searchptr); 1.1 root 4289: if (f == -2) 4290: return 0; /* Already included this file */ 1.1.1.5 root 4291: #ifdef EACCES 4292: else if (f == -1 && errno == EACCES) 4293: warning ("Header file %s exists, but is not readable", fname); 4294: #endif 1.1.1.4 root 4295: if (redundant_include_p (fname)) { 1.1.1.2 root 4296: close (f); 4297: return 0; 4298: } 1.1 root 4299: if (f >= 0) 4300: break; 4301: } 4302: } 4303: 4304: if (f < 0) { 4305: /* A file that was not found. */ 4306: 4307: strncpy (fname, fbeg, flen); 4308: fname[flen] = 0; 1.1.1.7 ! root 4309: /* If generating dependencies and -MG was specified, we assume missing ! 4310: files are leaf files, living in the same directory as the source file ! 4311: or other similar place; these missing files may be generated from ! 4312: other files and may not exist yet (eg: y.tab.h). */ ! 4313: if (print_deps_missing_files ! 4314: && print_deps > (angle_brackets || (system_include_depth > 0))) ! 4315: { ! 4316: /* If it was requested as a system header file, ! 4317: then assume it belongs in the first place to look for such. */ ! 4318: if (angle_brackets) ! 4319: { ! 4320: for (searchptr = search_start; searchptr; searchptr = searchptr->next) ! 4321: { ! 4322: if (searchptr->fname) ! 4323: { ! 4324: char *p; ! 4325: ! 4326: if (searchptr->fname[0] == 0) ! 4327: continue; ! 4328: p = xmalloc (strlen (searchptr->fname) ! 4329: + strlen (fname) + 2); ! 4330: strcpy (p, searchptr->fname); ! 4331: strcat (p, "/"); ! 4332: strcat (p, fname); ! 4333: deps_output (p, ' '); ! 4334: break; ! 4335: } ! 4336: } ! 4337: } ! 4338: else ! 4339: { ! 4340: /* Otherwise, omit the directory, as if the file existed ! 4341: in the directory with the source. */ ! 4342: deps_output (fname, ' '); ! 4343: } ! 4344: } 1.1.1.5 root 4345: /* If -M was specified, and this header file won't be added to the 4346: dependency list, then don't count this as an error, because we can 4347: still produce correct output. Otherwise, we can't produce correct 4348: output, because there may be dependencies we need inside the missing 4349: file, and we don't know what directory this missing file exists in. */ 1.1.1.7 ! root 4350: else if (print_deps 1.1.1.5 root 4351: && (print_deps <= (angle_brackets || (system_include_depth > 0)))) 4352: warning ("No include path in which to find %s", fname); 4353: else if (search_start) 1.1.1.4 root 4354: error_from_errno (fname); 4355: else 4356: error ("No include path in which to find %s", fname); 1.1 root 4357: } else { 4358: struct stat stat_f; 4359: 4360: /* Check to see if this include file is a once-only include file. 4361: If so, give up. */ 4362: 4363: struct file_name_list* ptr; 4364: 4365: for (ptr = dont_repeat_files; ptr; ptr = ptr->next) { 4366: if (!strcmp (ptr->fname, fname)) { 4367: close (f); 4368: return 0; /* This file was once'd. */ 4369: } 4370: } 4371: 4372: for (ptr = all_include_files; ptr; ptr = ptr->next) { 4373: if (!strcmp (ptr->fname, fname)) 4374: break; /* This file was included before. */ 4375: } 4376: 4377: if (ptr == 0) { 4378: /* This is the first time for this file. */ 4379: /* Add it to list of files included. */ 4380: 4381: ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 4382: ptr->control_macro = 0; 1.1.1.6 root 4383: ptr->c_system_include_path = 0; 1.1 root 4384: ptr->next = all_include_files; 4385: all_include_files = ptr; 4386: ptr->fname = savestring (fname); 1.1.1.7 ! root 4387: ptr->got_name_map = 0; 1.1 root 4388: 4389: /* For -M, add this file to the dependencies. */ 1.1.1.7 ! root 4390: if (print_deps > (angle_brackets || (system_include_depth > 0))) ! 4391: deps_output (fname, ' '); 1.1 root 4392: } 4393: 4394: /* Handle -H option. */ 1.1.1.6 root 4395: if (print_include_names) { 4396: output_dots (stderr, indepth); 1.1 root 4397: fprintf (stderr, "%s\n", fname); 1.1.1.6 root 4398: } 1.1 root 4399: 1.1.1.4 root 4400: if (angle_brackets) 1.1 root 4401: system_include_depth++; 4402: 4403: /* Actually process the file. */ 4404: add_import (f, fname); /* Record file on "seen" list for #import. */ 4405: 4406: pcftry = (char *) alloca (strlen (fname) + 30); 4407: pcfbuf = 0; 4408: pcfnum = 0; 4409: 4410: fstat (f, &stat_f); 4411: 4412: if (!no_precomp) 4413: do { 4414: sprintf (pcftry, "%s%d", fname, pcfnum++); 4415: 4416: pcf = open (pcftry, O_RDONLY, 0666); 4417: if (pcf != -1) 4418: { 4419: struct stat s; 4420: 4421: fstat (pcf, &s); 1.1.1.7 ! root 4422: if (bcmp ((char *) &stat_f.st_ino, (char *) &s.st_ino, ! 4423: sizeof (s.st_ino)) 1.1 root 4424: || stat_f.st_dev != s.st_dev) 4425: { 4426: pcfbuf = check_precompiled (pcf, fname, &pcfbuflimit); 4427: /* Don't need it any more. */ 4428: close (pcf); 4429: } 4430: else 4431: { 4432: /* Don't need it at all. */ 4433: close (pcf); 4434: break; 4435: } 4436: } 4437: } while (pcf != -1 && !pcfbuf); 4438: 4439: /* Actually process the file */ 4440: if (pcfbuf) { 4441: pcfname = xmalloc (strlen (pcftry) + 1); 4442: strcpy (pcfname, pcftry); 4443: pcfinclude (pcfbuf, pcfbuflimit, fname, op); 4444: } 4445: else 1.1.1.4 root 4446: finclude (f, fname, op, is_system_include (fname), searchptr); 1.1 root 4447: 1.1.1.4 root 4448: if (angle_brackets) 1.1 root 4449: system_include_depth--; 4450: } 4451: return 0; 4452: } 4453: 1.1.1.2 root 4454: /* Return nonzero if there is no need to include file NAME 4455: because it has already been included and it contains a conditional 4456: to make a repeated include do nothing. */ 4457: 4458: static int 1.1.1.4 root 4459: redundant_include_p (name) 1.1.1.2 root 4460: char *name; 4461: { 4462: struct file_name_list *l = all_include_files; 4463: for (; l; l = l->next) 4464: if (! strcmp (name, l->fname) 4465: && l->control_macro 4466: && lookup (l->control_macro, -1, -1)) 4467: return 1; 4468: return 0; 4469: } 4470: 1.1.1.4 root 4471: /* Return nonzero if the given FILENAME is an absolute pathname which 4472: designates a file within one of the known "system" include file 4473: directories. We assume here that if the given FILENAME looks like 4474: it is the name of a file which resides either directly in a "system" 4475: include file directory, or within any subdirectory thereof, then the 4476: given file must be a "system" include file. This function tells us 1.1.1.6 root 4477: if we should suppress pedantic errors/warnings for the given FILENAME. 4478: 4479: The value is 2 if the file is a C-language system header file 4480: for which C++ should (on most systems) assume `extern "C"'. */ 1.1.1.4 root 4481: 4482: static int 4483: is_system_include (filename) 4484: register char *filename; 4485: { 4486: struct file_name_list *searchptr; 4487: 4488: for (searchptr = first_system_include; searchptr; 4489: searchptr = searchptr->next) 4490: if (searchptr->fname) { 4491: register char *sys_dir = searchptr->fname; 4492: register unsigned length = strlen (sys_dir); 4493: 4494: if (! strncmp (sys_dir, filename, length) && filename[length] == '/') 1.1.1.6 root 4495: { 4496: if (searchptr->c_system_include_path) 4497: return 2; 4498: else 4499: return 1; 4500: } 1.1.1.4 root 4501: } 4502: return 0; 4503: } 4504: 1.1.1.7 ! root 4505: /* The file_name_map structure holds a mapping of file names for a ! 4506: particular directory. This mapping is read from the file named ! 4507: FILE_NAME_MAP_FILE in that directory. Such a file can be used to ! 4508: map filenames on a file system with severe filename restrictions, ! 4509: such as DOS. The format of the file name map file is just a series ! 4510: of lines with two tokens on each line. The first token is the name ! 4511: to map, and the second token is the actual name to use. */ ! 4512: ! 4513: struct file_name_map ! 4514: { ! 4515: struct file_name_map *map_next; ! 4516: char *map_from; ! 4517: char *map_to; ! 4518: }; ! 4519: ! 4520: #define FILE_NAME_MAP_FILE "header.gcc" ! 4521: ! 4522: /* Read a space delimited string of unlimited length from a stdio ! 4523: file. */ ! 4524: ! 4525: static char * ! 4526: read_filename_string (ch, f) ! 4527: int ch; ! 4528: FILE *f; ! 4529: { ! 4530: char *alloc, *set; ! 4531: int len; ! 4532: ! 4533: len = 20; ! 4534: set = alloc = xmalloc (len + 1); ! 4535: if (! is_space[ch]) ! 4536: { ! 4537: *set++ = ch; ! 4538: while ((ch = getc (f)) != EOF && ! is_space[ch]) ! 4539: { ! 4540: if (set - alloc == len) ! 4541: { ! 4542: len *= 2; ! 4543: alloc = xrealloc (alloc, len + 1); ! 4544: set = alloc + len / 2; ! 4545: } ! 4546: *set++ = ch; ! 4547: } ! 4548: } ! 4549: *set = '\0'; ! 4550: ungetc (ch, f); ! 4551: return alloc; ! 4552: } ! 4553: ! 4554: /* Read the file name map file for DIRNAME. */ ! 4555: ! 4556: static struct file_name_map * ! 4557: read_name_map (dirname) ! 4558: char *dirname; ! 4559: { ! 4560: /* This structure holds a linked list of file name maps, one per ! 4561: directory. */ ! 4562: struct file_name_map_list ! 4563: { ! 4564: struct file_name_map_list *map_list_next; ! 4565: char *map_list_name; ! 4566: struct file_name_map *map_list_map; ! 4567: }; ! 4568: static struct file_name_map_list *map_list; ! 4569: register struct file_name_map_list *map_list_ptr; ! 4570: char *name; ! 4571: FILE *f; ! 4572: ! 4573: for (map_list_ptr = map_list; map_list_ptr; ! 4574: map_list_ptr = map_list_ptr->map_list_next) ! 4575: if (! strcmp (map_list_ptr->map_list_name, dirname)) ! 4576: return map_list_ptr->map_list_map; ! 4577: ! 4578: map_list_ptr = ((struct file_name_map_list *) ! 4579: xmalloc (sizeof (struct file_name_map_list))); ! 4580: map_list_ptr->map_list_name = savestring (dirname); ! 4581: map_list_ptr->map_list_map = NULL; ! 4582: ! 4583: name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2); ! 4584: strcpy (name, dirname); ! 4585: if (*dirname) ! 4586: strcat (name, "/"); ! 4587: strcat (name, FILE_NAME_MAP_FILE); ! 4588: f = fopen (name, "r"); ! 4589: if (!f) ! 4590: map_list_ptr->map_list_map = NULL; ! 4591: else ! 4592: { ! 4593: int ch; ! 4594: int dirlen = strlen (dirname); ! 4595: ! 4596: while ((ch = getc (f)) != EOF) ! 4597: { ! 4598: char *from, *to; ! 4599: struct file_name_map *ptr; ! 4600: ! 4601: if (is_space[ch]) ! 4602: continue; ! 4603: from = read_filename_string (ch, f); ! 4604: while ((ch = getc (f)) != EOF && is_hor_space[ch]) ! 4605: ; ! 4606: to = read_filename_string (ch, f); ! 4607: ! 4608: ptr = ((struct file_name_map *) ! 4609: xmalloc (sizeof (struct file_name_map))); ! 4610: ptr->map_from = from; ! 4611: ! 4612: /* Make the real filename absolute. */ ! 4613: if (*to == '/') ! 4614: ptr->map_to = to; ! 4615: else ! 4616: { ! 4617: ptr->map_to = xmalloc (dirlen + strlen (to) + 2); ! 4618: strcpy (ptr->map_to, dirname); ! 4619: ptr->map_to[dirlen] = '/'; ! 4620: strcpy (ptr->map_to + dirlen + 1, to); ! 4621: free (to); ! 4622: } ! 4623: ! 4624: ptr->map_next = map_list_ptr->map_list_map; ! 4625: map_list_ptr->map_list_map = ptr; ! 4626: ! 4627: while ((ch = getc (f)) != '\n') ! 4628: if (ch == EOF) ! 4629: break; ! 4630: } ! 4631: fclose (f); ! 4632: } ! 4633: ! 4634: map_list_ptr->map_list_next = map_list; ! 4635: map_list = map_list_ptr; ! 4636: ! 4637: return map_list_ptr->map_list_map; ! 4638: } ! 4639: ! 4640: /* Try to open include file FILENAME. SEARCHPTR is the directory ! 4641: being tried from the include file search path. This function maps ! 4642: filenames on file systems based on information read by ! 4643: read_name_map. */ ! 4644: ! 4645: static int ! 4646: open_include_file (filename, searchptr) ! 4647: char *filename; ! 4648: struct file_name_list *searchptr; ! 4649: { ! 4650: register struct file_name_map *map; ! 4651: register char *from; ! 4652: char *p, *dir; ! 4653: ! 4654: if (searchptr && ! searchptr->got_name_map) ! 4655: { ! 4656: searchptr->name_map = read_name_map (searchptr->fname ! 4657: ? searchptr->fname : "."); ! 4658: searchptr->got_name_map = 1; ! 4659: } ! 4660: ! 4661: /* First check the mapping for the directory we are using. */ ! 4662: if (searchptr && searchptr->name_map) ! 4663: { ! 4664: from = filename; ! 4665: if (searchptr->fname) ! 4666: from += strlen (searchptr->fname) + 1; ! 4667: for (map = searchptr->name_map; map; map = map->map_next) ! 4668: { ! 4669: if (! strcmp (map->map_from, from)) ! 4670: { ! 4671: /* Found a match. */ ! 4672: return open (map->map_to, O_RDONLY, 0666); ! 4673: } ! 4674: } ! 4675: } ! 4676: ! 4677: /* Try to find a mapping file for the particular directory we are ! 4678: looking in. Thus #include <sys/types.h> will look up sys/types.h ! 4679: in /usr/include/header.gcc and look up types.h in ! 4680: /usr/include/sys/header.gcc. */ ! 4681: p = rindex (filename, '/'); ! 4682: if (! p) ! 4683: p = filename; ! 4684: if (searchptr ! 4685: && searchptr->fname ! 4686: && strlen (searchptr->fname) == p - filename ! 4687: && ! strncmp (searchptr->fname, filename, p - filename)) ! 4688: { ! 4689: /* FILENAME is in SEARCHPTR, which we've already checked. */ ! 4690: return open (filename, O_RDONLY, 0666); ! 4691: } ! 4692: ! 4693: if (p == filename) ! 4694: { ! 4695: dir = "."; ! 4696: from = filename; ! 4697: } ! 4698: else ! 4699: { ! 4700: dir = (char *) alloca (p - filename + 1); ! 4701: bcopy (filename, dir, p - filename); ! 4702: dir[p - filename] = '\0'; ! 4703: from = p + 1; ! 4704: } ! 4705: for (map = read_name_map (dir); map; map = map->map_next) ! 4706: if (! strcmp (map->map_from, from)) ! 4707: return open (map->map_to, O_RDONLY, 0666); ! 4708: ! 4709: return open (filename, O_RDONLY, 0666); ! 4710: } ! 4711: 1.1 root 4712: /* Process the contents of include file FNAME, already open on descriptor F, 4713: with output to OP. 1.1.1.5 root 4714: SYSTEM_HEADER_P is 1 if this file resides in any one of the known 4715: "system" include directories (as decided by the `is_system_include' 4716: function above). 1.1 root 4717: DIRPTR is the link in the dir path through which this file was found, 4718: or 0 if the file name was absolute. */ 4719: 4720: static void 4721: finclude (f, fname, op, system_header_p, dirptr) 4722: int f; 4723: char *fname; 4724: FILE_BUF *op; 4725: int system_header_p; 4726: struct file_name_list *dirptr; 4727: { 4728: int st_mode; 4729: long st_size; 4730: long i; 4731: FILE_BUF *fp; /* For input stack frame */ 4732: int missing_newline = 0; 4733: 4734: CHECK_DEPTH (return;); 4735: 4736: if (file_size_and_mode (f, &st_mode, &st_size) < 0) 1.1.1.4 root 4737: { 4738: perror_with_name (fname); 4739: close (f); 4740: return; 4741: } 1.1 root 4742: 4743: fp = &instack[indepth + 1]; 1.1.1.7 ! root 4744: bzero ((char *) fp, sizeof (FILE_BUF)); 1.1 root 4745: fp->nominal_fname = fp->fname = fname; 4746: fp->length = 0; 4747: fp->lineno = 1; 4748: fp->if_stack = if_stack; 4749: fp->system_header_p = system_header_p; 4750: fp->dir = dirptr; 4751: 4752: if (S_ISREG (st_mode)) { 1.1.1.3 root 4753: fp->buf = (U_CHAR *) xmalloc (st_size + 2); 1.1 root 4754: fp->bufp = fp->buf; 4755: 4756: /* Read the file contents, knowing that st_size is an upper bound 4757: on the number of bytes we can read. */ 1.1.1.7 ! root 4758: fp->length = safe_read (f, fp->buf, st_size); ! 4759: if (fp->length < 0) goto nope; 1.1 root 4760: } 1.1.1.5 root 4761: else if (S_ISDIR (st_mode)) { 4762: error ("directory `%s' specified in #include", fname); 4763: close (f); 4764: return; 4765: } else { 1.1 root 4766: /* Cannot count its file size before reading. 4767: First read the entire file into heap and 4768: copy them into buffer on stack. */ 4769: 4770: int bsize = 2000; 4771: 4772: st_size = 0; 1.1.1.7 ! root 4773: fp->buf = (U_CHAR *) xmalloc (bsize + 2); 1.1 root 4774: 4775: for (;;) { 1.1.1.7 ! root 4776: i = safe_read (f, fp->buf + st_size, bsize - st_size); 1.1 root 4777: if (i < 0) 4778: goto nope; /* error! */ 4779: st_size += i; 1.1.1.7 ! root 4780: if (st_size != bsize) ! 4781: break; /* End of file */ ! 4782: bsize *= 2; ! 4783: fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2); 1.1 root 4784: } 4785: fp->bufp = fp->buf; 4786: fp->length = st_size; 4787: } 4788: 1.1.1.5 root 4789: if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n') 4790: /* Backslash-newline at end is not good enough. */ 4791: || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) { 4792: fp->buf[fp->length++] = '\n'; 4793: missing_newline = 1; 4794: } 4795: fp->buf[fp->length] = '\0'; 4796: 1.1 root 4797: /* Close descriptor now, so nesting does not use lots of descriptors. */ 4798: close (f); 4799: 1.1.1.4 root 4800: /* Must do this before calling trigraph_pcp, so that the correct file name 4801: will be printed in warning messages. */ 4802: 4803: indepth++; 4804: input_file_stack_tick++; 4805: 1.1 root 4806: if (!no_trigraphs) 4807: trigraph_pcp (fp); 4808: 4809: output_line_command (fp, op, 0, enter_file); 4810: rescan (op, 0); 4811: 1.1.1.5 root 4812: if (missing_newline) 4813: fp->lineno--; 4814: 1.1 root 4815: if (pedantic && missing_newline) 4816: pedwarn ("file does not end in newline"); 4817: 4818: indepth--; 4819: input_file_stack_tick++; 4820: output_line_command (&instack[indepth], op, 0, leave_file); 1.1.1.3 root 4821: free (fp->buf); 1.1 root 4822: return; 4823: 4824: nope: 4825: 4826: perror_with_name (fname); 4827: close (f); 1.1.1.3 root 4828: free (fp->buf); 1.1 root 4829: } 4830: 4831: /* Record that inclusion of the file named FILE 4832: should be controlled by the macro named MACRO_NAME. 4833: This means that trying to include the file again 4834: will do something if that macro is defined. */ 4835: 4836: static void 4837: record_control_macro (file, macro_name) 4838: char *file; 4839: U_CHAR *macro_name; 4840: { 4841: struct file_name_list *new; 4842: 4843: for (new = all_include_files; new; new = new->next) { 4844: if (!strcmp (new->fname, file)) { 4845: new->control_macro = macro_name; 4846: return; 4847: } 4848: } 4849: 4850: /* If the file is not in all_include_files, something's wrong. */ 4851: abort (); 4852: } 4853: 4854: /* Maintain and search list of included files, for #import. */ 4855: 4856: #define IMPORT_HASH_SIZE 31 4857: 4858: struct import_file { 4859: char *name; 4860: ino_t inode; 4861: dev_t dev; 4862: struct import_file *next; 4863: }; 4864: 4865: /* Hash table of files already included with #include or #import. */ 4866: 4867: static struct import_file *import_hash_table[IMPORT_HASH_SIZE]; 4868: 4869: /* Hash a file name for import_hash_table. */ 4870: 4871: static int 4872: import_hash (f) 4873: char *f; 4874: { 4875: int val = 0; 4876: 4877: while (*f) val += *f++; 4878: return (val%IMPORT_HASH_SIZE); 4879: } 4880: 4881: /* Search for file FILENAME in import_hash_table. 4882: Return -2 if found, either a matching name or a matching inode. 4883: Otherwise, open the file and return a file descriptor if successful 4884: or -1 if unsuccessful. */ 4885: 4886: static int 1.1.1.7 ! root 4887: lookup_import (filename, searchptr) 1.1 root 4888: char *filename; 1.1.1.7 ! root 4889: struct file_name_list *searchptr; 1.1 root 4890: { 4891: struct import_file *i; 4892: int h; 4893: int hashval; 4894: struct stat sb; 4895: int fd; 4896: 4897: hashval = import_hash (filename); 4898: 4899: /* Attempt to find file in list of already included files */ 4900: i = import_hash_table[hashval]; 4901: 4902: while (i) { 4903: if (!strcmp (filename, i->name)) 4904: return -2; /* return found */ 4905: i = i->next; 4906: } 4907: /* Open it and try a match on inode/dev */ 1.1.1.7 ! root 4908: fd = open_include_file (filename, searchptr); 1.1 root 4909: if (fd < 0) 4910: return fd; 4911: fstat (fd, &sb); 4912: for (h = 0; h < IMPORT_HASH_SIZE; h++) { 4913: i = import_hash_table[h]; 4914: while (i) { 4915: /* Compare the inode and the device. 4916: Supposedly on some systems the inode is not a scalar. */ 1.1.1.7 ! root 4917: if (!bcmp ((char *) &i->inode, (char *) &sb.st_ino, sizeof (sb.st_ino)) 1.1 root 4918: && i->dev == sb.st_dev) { 4919: close (fd); 4920: return -2; /* return found */ 4921: } 4922: i = i->next; 4923: } 4924: } 4925: return fd; /* Not found, return open file */ 4926: } 4927: 4928: /* Add the file FNAME, open on descriptor FD, to import_hash_table. */ 4929: 4930: static void 4931: add_import (fd, fname) 4932: int fd; 4933: char *fname; 4934: { 4935: struct import_file *i; 4936: int hashval; 4937: struct stat sb; 4938: 4939: hashval = import_hash (fname); 4940: fstat (fd, &sb); 4941: i = (struct import_file *)xmalloc (sizeof (struct import_file)); 4942: i->name = (char *)xmalloc (strlen (fname)+1); 4943: strcpy (i->name, fname); 1.1.1.7 ! root 4944: bcopy ((char *) &sb.st_ino, (char *) &i->inode, sizeof (sb.st_ino)); 1.1 root 4945: i->dev = sb.st_dev; 4946: i->next = import_hash_table[hashval]; 4947: import_hash_table[hashval] = i; 4948: } 4949: 4950: /* Load the specified precompiled header into core, and verify its 4951: preconditions. PCF indicates the file descriptor to read, which must 4952: be a regular file. FNAME indicates the file name of the original 4953: header. *LIMIT will be set to an address one past the end of the file. 4954: If the preconditions of the file are not satisfied, the buffer is 4955: freed and we return 0. If the preconditions are satisfied, return 4956: the address of the buffer following the preconditions. The buffer, in 4957: this case, should never be freed because various pieces of it will 4958: be referred to until all precompiled strings are output at the end of 4959: the run. 4960: */ 4961: static char * 4962: check_precompiled (pcf, fname, limit) 4963: int pcf; 4964: char *fname; 4965: char **limit; 4966: { 4967: int st_mode; 4968: long st_size; 4969: int length = 0; 4970: char *buf; 4971: char *cp; 4972: 4973: if (pcp_outfile) 4974: return 0; 4975: 4976: if (file_size_and_mode (pcf, &st_mode, &st_size) < 0) 4977: return 0; 4978: 4979: if (S_ISREG (st_mode)) 4980: { 4981: buf = xmalloc (st_size + 2); 1.1.1.7 ! root 4982: length = safe_read (pcf, buf, st_size); ! 4983: if (length < 0) ! 4984: goto nope; 1.1 root 4985: } 4986: else 4987: abort (); 4988: 4989: if (length > 0 && buf[length-1] != '\n') 4990: buf[length++] = '\n'; 4991: buf[length] = '\0'; 4992: 4993: *limit = buf + length; 4994: 4995: /* File is in core. Check the preconditions. */ 4996: if (!check_preconditions (buf)) 4997: goto nope; 4998: for (cp = buf; *cp; cp++) 4999: ; 5000: #ifdef DEBUG_PCP 5001: fprintf (stderr, "Using preinclude %s\n", fname); 5002: #endif 5003: return cp + 1; 5004: 5005: nope: 5006: #ifdef DEBUG_PCP 5007: fprintf (stderr, "Cannot use preinclude %s\n", fname); 5008: #endif 5009: free (buf); 5010: return 0; 5011: } 5012: 5013: /* PREC (null terminated) points to the preconditions of a 5014: precompiled header. These are a series of #define and #undef 5015: lines which must match the current contents of the hash 5016: table. */ 5017: static int 5018: check_preconditions (prec) 5019: char *prec; 5020: { 5021: MACRODEF mdef; 5022: char *lineend; 5023: 5024: while (*prec) { 5025: lineend = (char *) index (prec, '\n'); 5026: 5027: if (*prec++ != '#') { 5028: error ("Bad format encountered while reading precompiled file"); 5029: return 0; 5030: } 5031: if (!strncmp (prec, "define", 6)) { 5032: HASHNODE *hp; 5033: 5034: prec += 6; 1.1.1.4 root 5035: mdef = create_definition (prec, lineend, NULL_PTR); 5036: 1.1 root 5037: if (mdef.defn == 0) 1.1.1.5 root 5038: abort (); 1.1 root 5039: 5040: if ((hp = lookup (mdef.symnam, mdef.symlen, -1)) == NULL 5041: || (hp->type != T_MACRO && hp->type != T_CONST) 5042: || (hp->type == T_MACRO 5043: && !compare_defs (mdef.defn, hp->value.defn) 5044: && (mdef.defn->length != 2 5045: || mdef.defn->expansion[0] != '\n' 5046: || mdef.defn->expansion[1] != ' '))) 5047: return 0; 5048: } else if (!strncmp (prec, "undef", 5)) { 5049: char *name; 5050: int len; 5051: 5052: prec += 5; 1.1.1.5 root 5053: while (is_hor_space[(U_CHAR) *prec]) 1.1 root 5054: prec++; 5055: name = prec; 1.1.1.5 root 5056: while (is_idchar[(U_CHAR) *prec]) 1.1 root 5057: prec++; 5058: len = prec - name; 5059: 5060: if (lookup (name, len, -1)) 5061: return 0; 5062: } else { 5063: error ("Bad format encountered while reading precompiled file"); 5064: return 0; 5065: } 5066: prec = lineend + 1; 5067: } 5068: /* They all passed successfully */ 5069: return 1; 5070: } 5071: 5072: /* Process the main body of a precompiled file. BUF points to the 5073: string section of the file, following the preconditions. LIMIT is one 5074: character past the end. NAME is the name of the file being read 5075: in. OP is the main output buffer */ 5076: static void 5077: pcfinclude (buf, limit, name, op) 5078: U_CHAR *buf, *limit, *name; 5079: FILE_BUF *op; 5080: { 5081: FILE_BUF tmpbuf; 5082: int nstrings; 5083: U_CHAR *cp = buf; 5084: 5085: /* First in the file comes 4 bytes indicating the number of strings, */ 5086: /* in network byte order. (MSB first). */ 5087: nstrings = *cp++; 5088: nstrings = (nstrings << 8) | *cp++; 5089: nstrings = (nstrings << 8) | *cp++; 5090: nstrings = (nstrings << 8) | *cp++; 5091: 5092: /* Looping over each string... */ 5093: while (nstrings--) { 5094: U_CHAR *string_start; 5095: U_CHAR *endofthiskey; 5096: STRINGDEF *str; 5097: int nkeys; 5098: 5099: /* Each string starts with a STRINGDEF structure (str), followed */ 5100: /* by the text of the string (string_start) */ 5101: 5102: /* First skip to a longword boundary */ 1.1.1.4 root 5103: /* ??? Why a 4-byte boundary? On all machines? */ 5104: /* NOTE: This works correctly even if HOST_WIDE_INT 5105: is narrower than a pointer. 5106: Do not try risky measures here to get another type to use! 1.1.1.7 ! root 5107: Do not include stddef.h--it will fail! */ 1.1.1.4 root 5108: if ((HOST_WIDE_INT) cp & 3) 5109: cp += 4 - ((HOST_WIDE_INT) cp & 3); 1.1 root 5110: 5111: /* Now get the string. */ 5112: str = (STRINGDEF *) cp; 5113: string_start = cp += sizeof (STRINGDEF); 5114: 5115: for (; *cp; cp++) /* skip the string */ 5116: ; 5117: 5118: /* We need to macro expand the string here to ensure that the 5119: proper definition environment is in place. If it were only 5120: expanded when we find out it is needed, macros necessary for 5121: its proper expansion might have had their definitions changed. */ 5122: tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0); 5123: /* Lineno is already set in the precompiled file */ 5124: str->contents = tmpbuf.buf; 5125: str->len = tmpbuf.length; 5126: str->writeflag = 0; 5127: str->filename = name; 5128: str->output_mark = outbuf.bufp - outbuf.buf; 5129: 5130: str->chain = 0; 5131: *stringlist_tailp = str; 5132: stringlist_tailp = &str->chain; 5133: 5134: /* Next comes a fourbyte number indicating the number of keys */ 5135: /* for this string. */ 5136: nkeys = *cp++; 5137: nkeys = (nkeys << 8) | *cp++; 5138: nkeys = (nkeys << 8) | *cp++; 5139: nkeys = (nkeys << 8) | *cp++; 5140: 5141: /* If this number is -1, then the string is mandatory. */ 5142: if (nkeys == -1) 5143: str->writeflag = 1; 5144: else 1.1.1.2 root 5145: /* Otherwise, for each key, */ 1.1 root 5146: for (; nkeys--; free (tmpbuf.buf), cp = endofthiskey + 1) { 5147: KEYDEF *kp = (KEYDEF *) cp; 5148: HASHNODE *hp; 5149: 5150: /* It starts with a KEYDEF structure */ 5151: cp += sizeof (KEYDEF); 5152: 5153: /* Find the end of the key. At the end of this for loop we 5154: advance CP to the start of the next key using this variable. */ 5155: endofthiskey = cp + strlen (cp); 5156: kp->str = str; 5157: 5158: /* Expand the key, and enter it into the hash table. */ 5159: tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0); 5160: tmpbuf.bufp = tmpbuf.buf; 5161: 5162: while (is_hor_space[*tmpbuf.bufp]) 5163: tmpbuf.bufp++; 5164: if (!is_idstart[*tmpbuf.bufp] 5165: || tmpbuf.bufp == tmpbuf.buf + tmpbuf.length) { 5166: str->writeflag = 1; 5167: continue; 5168: } 5169: 5170: hp = lookup (tmpbuf.bufp, -1, -1); 5171: if (hp == NULL) { 5172: kp->chain = 0; 1.1.1.4 root 5173: install (tmpbuf.bufp, -1, T_PCSTRING, 0, (char *) kp, -1); 1.1 root 5174: } 5175: else if (hp->type == T_PCSTRING) { 5176: kp->chain = hp->value.keydef; 5177: hp->value.keydef = kp; 5178: } 5179: else 5180: str->writeflag = 1; 5181: } 5182: } 5183: /* This output_line_command serves to switch us back to the current 5184: input file in case some of these strings get output (which will 5185: result in line commands for the header file being output). */ 5186: output_line_command (&instack[indepth], op, 0, enter_file); 5187: } 5188: 5189: /* Called from rescan when it hits a key for strings. Mark them all */ 5190: /* used and clean up. */ 5191: static void 5192: pcstring_used (hp) 5193: HASHNODE *hp; 5194: { 1.1.1.7 ! root 5195: KEYDEF *kp; 1.1 root 5196: 5197: for (kp = hp->value.keydef; kp; kp = kp->chain) 5198: kp->str->writeflag = 1; 5199: delete_macro (hp); 5200: } 5201: 5202: /* Write the output, interspersing precompiled strings in their */ 5203: /* appropriate places. */ 5204: static void 5205: write_output () 5206: { 5207: STRINGDEF *next_string; 5208: U_CHAR *cur_buf_loc; 5209: int line_command_len = 80; 5210: char *line_command = xmalloc (line_command_len); 5211: int len; 5212: 5213: /* In each run through the loop, either cur_buf_loc == */ 5214: /* next_string_loc, in which case we print a series of strings, or */ 5215: /* it is less than next_string_loc, in which case we write some of */ 5216: /* the buffer. */ 5217: cur_buf_loc = outbuf.buf; 5218: next_string = stringlist; 5219: 5220: while (cur_buf_loc < outbuf.bufp || next_string) { 5221: if (next_string 5222: && cur_buf_loc - outbuf.buf == next_string->output_mark) { 5223: if (next_string->writeflag) { 1.1.1.6 root 5224: len = 4 * strlen (next_string->filename) + 32; 5225: while (len > line_command_len) 1.1 root 5226: line_command = xrealloc (line_command, 5227: line_command_len *= 2); 1.1.1.6 root 5228: sprintf (line_command, "\n# %d ", next_string->lineno); 5229: strcpy (quote_string (line_command + strlen (line_command), 5230: next_string->filename), 5231: "\n"); 5232: safe_write (fileno (stdout), line_command, strlen (line_command)); 5233: safe_write (fileno (stdout), next_string->contents, next_string->len); 1.1 root 5234: } 5235: next_string = next_string->chain; 5236: } 5237: else { 5238: len = (next_string 5239: ? (next_string->output_mark 5240: - (cur_buf_loc - outbuf.buf)) 5241: : outbuf.bufp - cur_buf_loc); 5242: 1.1.1.6 root 5243: safe_write (fileno (stdout), cur_buf_loc, len); 1.1 root 5244: cur_buf_loc += len; 5245: } 5246: } 1.1.1.5 root 5247: free (line_command); 1.1 root 5248: } 5249: 5250: /* Pass a directive through to the output file. 1.1.1.2 root 5251: BUF points to the contents of the directive, as a contiguous string. 1.1 root 5252: LIMIT points to the first character past the end of the directive. 5253: KEYWORD is the keyword-table entry for the directive. */ 5254: 5255: static void 5256: pass_thru_directive (buf, limit, op, keyword) 5257: U_CHAR *buf, *limit; 5258: FILE_BUF *op; 5259: struct directive *keyword; 5260: { 5261: register unsigned keyword_length = keyword->length; 5262: 5263: check_expand (op, 1 + keyword_length + (limit - buf)); 5264: *op->bufp++ = '#'; 1.1.1.7 ! root 5265: bcopy (keyword->name, (char *) op->bufp, keyword_length); 1.1 root 5266: op->bufp += keyword_length; 5267: if (limit != buf && buf[0] != ' ') 5268: *op->bufp++ = ' '; 1.1.1.7 ! root 5269: bcopy ((char *) buf, (char *) op->bufp, limit - buf); 1.1 root 5270: op->bufp += (limit - buf); 1.1.1.3 root 5271: #if 0 1.1 root 5272: *op->bufp++ = '\n'; 1.1.1.3 root 5273: /* Count the line we have just made in the output, 5274: to get in sync properly. */ 5275: op->lineno++; 5276: #endif 1.1 root 5277: } 5278: 5279: /* The arglist structure is built by do_define to tell 5280: collect_definition where the argument names begin. That 5281: is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist 5282: would contain pointers to the strings x, y, and z. 5283: Collect_definition would then build a DEFINITION node, 5284: with reflist nodes pointing to the places x, y, and z had 5285: appeared. So the arglist is just convenience data passed 5286: between these two routines. It is not kept around after 5287: the current #define has been processed and entered into the 5288: hash table. */ 5289: 5290: struct arglist { 5291: struct arglist *next; 5292: U_CHAR *name; 5293: int length; 5294: int argno; 1.1.1.3 root 5295: char rest_args; 1.1 root 5296: }; 5297: 5298: /* Create a DEFINITION node from a #define directive. Arguments are 5299: as for do_define. */ 5300: static MACRODEF 5301: create_definition (buf, limit, op) 5302: U_CHAR *buf, *limit; 5303: FILE_BUF *op; 5304: { 5305: U_CHAR *bp; /* temp ptr into input buffer */ 5306: U_CHAR *symname; /* remember where symbol name starts */ 5307: int sym_length; /* and how long it is */ 5308: int line = instack[indepth].lineno; 5309: char *file = instack[indepth].nominal_fname; 1.1.1.3 root 5310: int rest_args = 0; 1.1 root 5311: 5312: DEFINITION *defn; 5313: int arglengths = 0; /* Accumulate lengths of arg names 5314: plus number of args. */ 5315: MACRODEF mdef; 5316: 5317: bp = buf; 5318: 5319: while (is_hor_space[*bp]) 5320: bp++; 5321: 5322: symname = bp; /* remember where it starts */ 5323: sym_length = check_macro_name (bp, "macro"); 5324: bp += sym_length; 5325: 5326: /* Lossage will occur if identifiers or control keywords are broken 5327: across lines using backslash. This is not the right place to take 5328: care of that. */ 5329: 5330: if (*bp == '(') { 5331: struct arglist *arg_ptrs = NULL; 5332: int argno = 0; 5333: 5334: bp++; /* skip '(' */ 5335: SKIP_WHITE_SPACE (bp); 5336: 5337: /* Loop over macro argument names. */ 5338: while (*bp != ')') { 5339: struct arglist *temp; 5340: 5341: temp = (struct arglist *) alloca (sizeof (struct arglist)); 5342: temp->name = bp; 5343: temp->next = arg_ptrs; 5344: temp->argno = argno++; 1.1.1.3 root 5345: temp->rest_args = 0; 1.1 root 5346: arg_ptrs = temp; 5347: 1.1.1.3 root 5348: if (rest_args) 5349: pedwarn ("another parameter follows `%s'", 5350: rest_extension); 1.1 root 5351: 1.1.1.3 root 5352: if (!is_idstart[*bp]) 5353: pedwarn ("invalid character in macro parameter name"); 5354: 1.1 root 5355: /* Find the end of the arg name. */ 5356: while (is_idchar[*bp]) { 5357: bp++; 1.1.1.3 root 5358: /* do we have a "special" rest-args extension here? */ 5359: if (limit - bp > REST_EXTENSION_LENGTH && 5360: strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) { 5361: rest_args = 1; 5362: temp->rest_args = 1; 5363: break; 5364: } 1.1 root 5365: } 5366: temp->length = bp - temp->name; 1.1.1.3 root 5367: if (rest_args == 1) 5368: bp += REST_EXTENSION_LENGTH; 1.1 root 5369: arglengths += temp->length + 2; 5370: SKIP_WHITE_SPACE (bp); 5371: if (temp->length == 0 || (*bp != ',' && *bp != ')')) { 5372: error ("badly punctuated parameter list in `#define'"); 5373: goto nope; 5374: } 5375: if (*bp == ',') { 5376: bp++; 5377: SKIP_WHITE_SPACE (bp); 5378: } 5379: if (bp >= limit) { 5380: error ("unterminated parameter list in `#define'"); 5381: goto nope; 5382: } 5383: { 5384: struct arglist *otemp; 5385: 5386: for (otemp = temp->next; otemp != NULL; otemp = otemp->next) 5387: if (temp->length == otemp->length && 1.1.1.5 root 5388: strncmp (temp->name, otemp->name, temp->length) == 0) { 1.1 root 5389: U_CHAR *name; 5390: 1.1.1.5 root 5391: name = (U_CHAR *) alloca (temp->length + 1); 5392: (void) strncpy (name, temp->name, temp->length); 1.1 root 5393: name[temp->length] = '\0'; 5394: error ("duplicate argument name `%s' in `#define'", name); 5395: goto nope; 5396: } 5397: } 5398: } 5399: 5400: ++bp; /* skip paren */ 1.1.1.7 ! root 5401: /* Skip spaces and tabs if any. */ ! 5402: while (bp < limit && (*bp == ' ' || *bp == '\t')) ! 5403: ++bp; 1.1 root 5404: /* now everything from bp before limit is the definition. */ 5405: defn = collect_expansion (bp, limit, argno, arg_ptrs); 1.1.1.3 root 5406: defn->rest_args = rest_args; 1.1 root 5407: 5408: /* Now set defn->args.argnames to the result of concatenating 5409: the argument names in reverse order 5410: with comma-space between them. */ 5411: defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1); 5412: { 5413: struct arglist *temp; 5414: int i = 0; 5415: for (temp = arg_ptrs; temp; temp = temp->next) { 5416: bcopy (temp->name, &defn->args.argnames[i], temp->length); 5417: i += temp->length; 5418: if (temp->next != 0) { 5419: defn->args.argnames[i++] = ','; 5420: defn->args.argnames[i++] = ' '; 5421: } 5422: } 5423: defn->args.argnames[i] = 0; 5424: } 5425: } else { 1.1.1.7 ! root 5426: /* Simple expansion or empty definition. */ ! 5427: ! 5428: if (bp < limit) ! 5429: { ! 5430: switch (*bp) ! 5431: { ! 5432: case '\t': case ' ': case '\r': ! 5433: /* Skip spaces and tabs. */ ! 5434: while (++bp < limit && (*bp == ' ' || *bp == '\t' || *bp == '\r')) ! 5435: continue; ! 5436: break; ! 5437: ! 5438: case '!': case '"': case '#': case '%': case '&': case '\'': ! 5439: case ')': case '*': case '+': case ',': case '-': case '.': ! 5440: case '/': case ':': case ';': case '<': case '=': case '>': ! 5441: case '?': case '[': case '\\': case ']': case '^': case '{': ! 5442: case '|': case '}': case '~': ! 5443: warning ("missing white space after `#define %.*s'", ! 5444: sym_length, symname); ! 5445: break; ! 5446: ! 5447: default: ! 5448: pedwarn ("missing white space after `#define %.*s'", ! 5449: sym_length, symname); ! 5450: break; ! 5451: } ! 5452: } ! 5453: /* Now everything from bp before limit is the definition. */ 1.1.1.4 root 5454: defn = collect_expansion (bp, limit, -1, NULL_PTR); 1.1 root 5455: defn->args.argnames = (U_CHAR *) ""; 5456: } 5457: 5458: defn->line = line; 5459: defn->file = file; 5460: 5461: /* OP is null if this is a predefinition */ 5462: defn->predefined = !op; 5463: mdef.defn = defn; 5464: mdef.symnam = symname; 5465: mdef.symlen = sym_length; 5466: 5467: return mdef; 5468: 5469: nope: 5470: mdef.defn = 0; 5471: return mdef; 5472: } 5473: 5474: /* Process a #define command. 1.1.1.2 root 5475: BUF points to the contents of the #define command, as a contiguous string. 1.1 root 5476: LIMIT points to the first character past the end of the definition. 5477: KEYWORD is the keyword-table entry for #define. */ 5478: 5479: static int 5480: do_define (buf, limit, op, keyword) 5481: U_CHAR *buf, *limit; 5482: FILE_BUF *op; 5483: struct directive *keyword; 5484: { 5485: int hashcode; 5486: MACRODEF mdef; 5487: 5488: /* If this is a precompiler run (with -pcp) pass thru #define commands. */ 5489: if (pcp_outfile && op) 5490: pass_thru_directive (buf, limit, op, keyword); 5491: 5492: mdef = create_definition (buf, limit, op); 5493: if (mdef.defn == 0) 5494: goto nope; 5495: 5496: hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE); 5497: 5498: { 5499: HASHNODE *hp; 5500: if ((hp = lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) { 5501: int ok = 0; 5502: /* Redefining a precompiled key is ok. */ 5503: if (hp->type == T_PCSTRING) 5504: ok = 1; 5505: /* Redefining a macro is ok if the definitions are the same. */ 5506: else if (hp->type == T_MACRO) 5507: ok = ! compare_defs (mdef.defn, hp->value.defn); 5508: /* Redefining a constant is ok with -D. */ 5509: else if (hp->type == T_CONST) 5510: ok = ! done_initializing; 5511: /* Print the warning if it's not ok. */ 5512: if (!ok) { 5513: U_CHAR *msg; /* what pain... */ 5514: 5515: /* If we are passing through #define and #undef directives, do 5516: that for this re-definition now. */ 5517: if (debug_output && op) 5518: pass_thru_directive (buf, limit, op, keyword); 5519: 5520: msg = (U_CHAR *) alloca (mdef.symlen + 22); 5521: *msg = '`'; 1.1.1.7 ! root 5522: bcopy ((char *) mdef.symnam, (char *) (msg + 1), mdef.symlen); 1.1 root 5523: strcpy ((char *) (msg + mdef.symlen + 1), "' redefined"); 5524: pedwarn (msg); 5525: if (hp->type == T_MACRO) 5526: pedwarn_with_file_and_line (hp->value.defn->file, hp->value.defn->line, 5527: "this is the location of the previous definition"); 5528: } 5529: /* Replace the old definition. */ 5530: hp->type = T_MACRO; 5531: hp->value.defn = mdef.defn; 5532: } else { 5533: /* If we are passing through #define and #undef directives, do 5534: that for this new definition now. */ 5535: if (debug_output && op) 5536: pass_thru_directive (buf, limit, op, keyword); 1.1.1.4 root 5537: install (mdef.symnam, mdef.symlen, T_MACRO, 0, 5538: (char *) mdef.defn, hashcode); 1.1 root 5539: } 5540: } 5541: 5542: return 0; 5543: 5544: nope: 5545: 5546: return 1; 5547: } 5548: 5549: /* Check a purported macro name SYMNAME, and yield its length. 5550: USAGE is the kind of name this is intended for. */ 5551: 5552: static int 5553: check_macro_name (symname, usage) 5554: U_CHAR *symname; 5555: char *usage; 5556: { 5557: U_CHAR *p; 5558: int sym_length; 5559: 5560: for (p = symname; is_idchar[*p]; p++) 5561: ; 5562: sym_length = p - symname; 5563: if (sym_length == 0) 5564: error ("invalid %s name", usage); 5565: else if (!is_idstart[*symname]) { 5566: U_CHAR *msg; /* what pain... */ 5567: msg = (U_CHAR *) alloca (sym_length + 1); 1.1.1.7 ! root 5568: bcopy ((char *) symname, (char *) msg, sym_length); 1.1 root 5569: msg[sym_length] = 0; 5570: error ("invalid %s name `%s'", usage, msg); 5571: } else { 5572: if (! strncmp (symname, "defined", 7) && sym_length == 7) 5573: error ("invalid %s name `defined'", usage); 5574: } 5575: return sym_length; 5576: } 5577: 5578: /* 5579: * return zero if two DEFINITIONs are isomorphic 5580: */ 5581: static int 5582: compare_defs (d1, d2) 5583: DEFINITION *d1, *d2; 5584: { 5585: register struct reflist *a1, *a2; 5586: register U_CHAR *p1 = d1->expansion; 5587: register U_CHAR *p2 = d2->expansion; 5588: int first = 1; 5589: 5590: if (d1->nargs != d2->nargs) 5591: return 1; 5592: if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames)) 5593: return 1; 5594: for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2; 5595: a1 = a1->next, a2 = a2->next) { 5596: if (!((a1->nchars == a2->nchars && ! strncmp (p1, p2, a1->nchars)) 5597: || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0)) 5598: || a1->argno != a2->argno 5599: || a1->stringify != a2->stringify 5600: || a1->raw_before != a2->raw_before 5601: || a1->raw_after != a2->raw_after) 5602: return 1; 5603: first = 0; 5604: p1 += a1->nchars; 5605: p2 += a2->nchars; 5606: } 5607: if (a1 != a2) 5608: return 1; 5609: if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion), 5610: p2, d2->length - (p2 - d2->expansion), 1)) 5611: return 1; 5612: return 0; 5613: } 5614: 5615: /* Return 1 if two parts of two macro definitions are effectively different. 5616: One of the parts starts at BEG1 and has LEN1 chars; 5617: the other has LEN2 chars at BEG2. 5618: Any sequence of whitespace matches any other sequence of whitespace. 5619: FIRST means these parts are the first of a macro definition; 5620: so ignore leading whitespace entirely. 5621: LAST means these parts are the last of a macro definition; 5622: so ignore trailing whitespace entirely. */ 5623: 5624: static int 5625: comp_def_part (first, beg1, len1, beg2, len2, last) 5626: int first; 5627: U_CHAR *beg1, *beg2; 5628: int len1, len2; 5629: int last; 5630: { 5631: register U_CHAR *end1 = beg1 + len1; 5632: register U_CHAR *end2 = beg2 + len2; 5633: if (first) { 5634: while (beg1 != end1 && is_space[*beg1]) beg1++; 5635: while (beg2 != end2 && is_space[*beg2]) beg2++; 5636: } 5637: if (last) { 5638: while (beg1 != end1 && is_space[end1[-1]]) end1--; 5639: while (beg2 != end2 && is_space[end2[-1]]) end2--; 5640: } 5641: while (beg1 != end1 && beg2 != end2) { 5642: if (is_space[*beg1] && is_space[*beg2]) { 5643: while (beg1 != end1 && is_space[*beg1]) beg1++; 5644: while (beg2 != end2 && is_space[*beg2]) beg2++; 5645: } else if (*beg1 == *beg2) { 5646: beg1++; beg2++; 5647: } else break; 5648: } 5649: return (beg1 != end1) || (beg2 != end2); 5650: } 5651: 5652: /* Read a replacement list for a macro with parameters. 5653: Build the DEFINITION structure. 5654: Reads characters of text starting at BUF until END. 5655: ARGLIST specifies the formal parameters to look for 5656: in the text of the definition; NARGS is the number of args 5657: in that list, or -1 for a macro name that wants no argument list. 5658: MACRONAME is the macro name itself (so we can avoid recursive expansion) 5659: and NAMELEN is its length in characters. 5660: 5661: Note that comments and backslash-newlines have already been deleted 5662: from the argument. */ 5663: 5664: /* Leading and trailing Space, Tab, etc. are converted to markers 5665: Newline Space, Newline Tab, etc. 5666: Newline Space makes a space in the final output 5667: but is discarded if stringified. (Newline Tab is similar but 5668: makes a Tab instead.) 5669: 5670: If there is no trailing whitespace, a Newline Space is added at the end 5671: to prevent concatenation that would be contrary to the standard. */ 5672: 5673: static DEFINITION * 5674: collect_expansion (buf, end, nargs, arglist) 5675: U_CHAR *buf, *end; 5676: int nargs; 5677: struct arglist *arglist; 5678: { 5679: DEFINITION *defn; 5680: register U_CHAR *p, *limit, *lastp, *exp_p; 5681: struct reflist *endpat = NULL; 5682: /* Pointer to first nonspace after last ## seen. */ 5683: U_CHAR *concat = 0; 5684: /* Pointer to first nonspace after last single-# seen. */ 5685: U_CHAR *stringify = 0; 5686: int maxsize; 5687: int expected_delimiter = '\0'; 5688: 5689: /* Scan thru the replacement list, ignoring comments and quoted 5690: strings, picking up on the macro calls. It does a linear search 5691: thru the arg list on every potential symbol. Profiling might say 5692: that something smarter should happen. */ 5693: 5694: if (end < buf) 5695: abort (); 5696: 5697: /* Find the beginning of the trailing whitespace. */ 5698: /* Find end of leading whitespace. */ 5699: limit = end; 5700: p = buf; 5701: while (p < limit && is_space[limit[-1]]) limit--; 5702: while (p < limit && is_space[*p]) p++; 5703: 5704: /* Allocate space for the text in the macro definition. 5705: Leading and trailing whitespace chars need 2 bytes each. 5706: Each other input char may or may not need 1 byte, 5707: so this is an upper bound. 5708: The extra 2 are for invented trailing newline-marker and final null. */ 5709: maxsize = (sizeof (DEFINITION) 5710: + 2 * (end - limit) + 2 * (p - buf) 5711: + (limit - p) + 3); 5712: defn = (DEFINITION *) xcalloc (1, maxsize); 5713: 5714: defn->nargs = nargs; 5715: exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION); 5716: lastp = exp_p; 5717: 5718: p = buf; 5719: 5720: /* Convert leading whitespace to Newline-markers. */ 5721: while (p < limit && is_space[*p]) { 5722: *exp_p++ = '\n'; 5723: *exp_p++ = *p++; 5724: } 5725: 5726: if (limit - p >= 2 && p[0] == '#' && p[1] == '#') { 5727: error ("`##' at start of macro definition"); 5728: p += 2; 5729: } 5730: 5731: /* Process the main body of the definition. */ 5732: while (p < limit) { 5733: int skipped_arg = 0; 5734: register U_CHAR c = *p++; 5735: 5736: *exp_p++ = c; 5737: 5738: if (!traditional) { 5739: switch (c) { 5740: case '\'': 5741: case '\"': 5742: if (expected_delimiter != '\0') { 5743: if (c == expected_delimiter) 5744: expected_delimiter = '\0'; 5745: } else 5746: expected_delimiter = c; 5747: break; 5748: 5749: case '\\': 1.1.1.7 ! root 5750: if (p < limit && expected_delimiter) { 1.1 root 5751: /* In a string, backslash goes through 5752: and makes next char ordinary. */ 5753: *exp_p++ = *p++; 5754: } 5755: break; 5756: 5757: case '#': 5758: /* # is ordinary inside a string. */ 5759: if (expected_delimiter) 5760: break; 5761: if (p < limit && *p == '#') { 5762: /* ##: concatenate preceding and following tokens. */ 5763: /* Take out the first #, discard preceding whitespace. */ 5764: exp_p--; 5765: while (exp_p > lastp && is_hor_space[exp_p[-1]]) 5766: --exp_p; 5767: /* Skip the second #. */ 5768: p++; 5769: /* Discard following whitespace. */ 5770: SKIP_WHITE_SPACE (p); 5771: concat = p; 5772: if (p == limit) 5773: error ("`##' at end of macro definition"); 1.1.1.5 root 5774: } else if (nargs >= 0) { 1.1 root 5775: /* Single #: stringify following argument ref. 5776: Don't leave the # in the expansion. */ 5777: exp_p--; 5778: SKIP_WHITE_SPACE (p); 1.1.1.5 root 5779: if (p == limit || ! is_idstart[*p]) 1.1 root 5780: error ("`#' operator is not followed by a macro argument name"); 5781: else 5782: stringify = p; 5783: } 5784: break; 5785: } 5786: } else { 5787: /* In -traditional mode, recognize arguments inside strings and 5788: and character constants, and ignore special properties of #. 5789: Arguments inside strings are considered "stringified", but no 5790: extra quote marks are supplied. */ 5791: switch (c) { 5792: case '\'': 5793: case '\"': 5794: if (expected_delimiter != '\0') { 5795: if (c == expected_delimiter) 5796: expected_delimiter = '\0'; 5797: } else 5798: expected_delimiter = c; 5799: break; 5800: 5801: case '\\': 5802: /* Backslash quotes delimiters and itself, but not macro args. */ 5803: if (expected_delimiter != 0 && p < limit 5804: && (*p == expected_delimiter || *p == '\\')) { 5805: *exp_p++ = *p++; 5806: continue; 5807: } 5808: break; 5809: 5810: case '/': 5811: if (expected_delimiter != '\0') /* No comments inside strings. */ 5812: break; 5813: if (*p == '*') { 5814: /* If we find a comment that wasn't removed by handle_directive, 5815: this must be -traditional. So replace the comment with 5816: nothing at all. */ 5817: exp_p--; 5818: p += 1; 5819: while (p < limit && !(p[-2] == '*' && p[-1] == '/')) 5820: p++; 5821: #if 0 5822: /* Mark this as a concatenation-point, as if it had been ##. */ 5823: concat = p; 5824: #endif 5825: } 5826: break; 5827: } 5828: } 5829: 5830: /* Handle the start of a symbol. */ 5831: if (is_idchar[c] && nargs > 0) { 5832: U_CHAR *id_beg = p - 1; 5833: int id_len; 5834: 5835: --exp_p; 5836: while (p != limit && is_idchar[*p]) p++; 5837: id_len = p - id_beg; 5838: 5839: if (is_idstart[c]) { 5840: register struct arglist *arg; 5841: 5842: for (arg = arglist; arg != NULL; arg = arg->next) { 5843: struct reflist *tpat; 5844: 5845: if (arg->name[0] == c 5846: && arg->length == id_len 5847: && strncmp (arg->name, id_beg, id_len) == 0) { 5848: if (expected_delimiter && warn_stringify) { 5849: if (traditional) { 5850: warning ("macro argument `%.*s' is stringified.", 5851: id_len, arg->name); 5852: } else { 5853: warning ("macro arg `%.*s' would be stringified with -traditional.", 5854: id_len, arg->name); 5855: } 5856: } 5857: /* If ANSI, don't actually substitute inside a string. */ 5858: if (!traditional && expected_delimiter) 5859: break; 5860: /* make a pat node for this arg and append it to the end of 5861: the pat list */ 5862: tpat = (struct reflist *) xmalloc (sizeof (struct reflist)); 5863: tpat->next = NULL; 5864: tpat->raw_before = concat == id_beg; 5865: tpat->raw_after = 0; 1.1.1.3 root 5866: tpat->rest_args = arg->rest_args; 1.1 root 5867: tpat->stringify = (traditional ? expected_delimiter != '\0' 5868: : stringify == id_beg); 5869: 5870: if (endpat == NULL) 5871: defn->pattern = tpat; 5872: else 5873: endpat->next = tpat; 5874: endpat = tpat; 5875: 5876: tpat->argno = arg->argno; 5877: tpat->nchars = exp_p - lastp; 5878: { 5879: register U_CHAR *p1 = p; 5880: SKIP_WHITE_SPACE (p1); 5881: if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#') 5882: tpat->raw_after = 1; 5883: } 5884: lastp = exp_p; /* place to start copying from next time */ 5885: skipped_arg = 1; 5886: break; 5887: } 5888: } 5889: } 5890: 5891: /* If this was not a macro arg, copy it into the expansion. */ 5892: if (! skipped_arg) { 5893: register U_CHAR *lim1 = p; 5894: p = id_beg; 5895: while (p != lim1) 5896: *exp_p++ = *p++; 5897: if (stringify == id_beg) 5898: error ("`#' operator should be followed by a macro argument name"); 5899: } 5900: } 5901: } 5902: 1.1.1.7 ! root 5903: if (!traditional && expected_delimiter == 0) { 1.1.1.4 root 5904: /* There is no trailing whitespace, so invent some in ANSI mode. 5905: But not if "inside a string" (which in ANSI mode 5906: happens only for -D option). */ 1.1 root 5907: *exp_p++ = '\n'; 5908: *exp_p++ = ' '; 5909: } 5910: 5911: *exp_p = '\0'; 5912: 5913: defn->length = exp_p - defn->expansion; 5914: 5915: /* Crash now if we overrun the allocated size. */ 5916: if (defn->length + 1 > maxsize) 5917: abort (); 5918: 5919: #if 0 5920: /* This isn't worth the time it takes. */ 5921: /* give back excess storage */ 5922: defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1); 5923: #endif 5924: 5925: return defn; 5926: } 5927: 5928: static int 5929: do_assert (buf, limit, op, keyword) 5930: U_CHAR *buf, *limit; 5931: FILE_BUF *op; 5932: struct directive *keyword; 5933: { 5934: U_CHAR *bp; /* temp ptr into input buffer */ 5935: U_CHAR *symname; /* remember where symbol name starts */ 5936: int sym_length; /* and how long it is */ 5937: struct arglist *tokens = NULL; 5938: 5939: if (pedantic && done_initializing && !instack[indepth].system_header_p) 5940: pedwarn ("ANSI C does not allow `#assert'"); 5941: 5942: bp = buf; 5943: 5944: while (is_hor_space[*bp]) 5945: bp++; 5946: 5947: symname = bp; /* remember where it starts */ 5948: sym_length = check_macro_name (bp, "assertion"); 5949: bp += sym_length; 5950: /* #define doesn't do this, but we should. */ 5951: SKIP_WHITE_SPACE (bp); 5952: 5953: /* Lossage will occur if identifiers or control tokens are broken 5954: across lines using backslash. This is not the right place to take 5955: care of that. */ 5956: 5957: if (*bp != '(') { 5958: error ("missing token-sequence in `#assert'"); 5959: return 1; 5960: } 5961: 5962: { 5963: int error_flag = 0; 5964: 5965: bp++; /* skip '(' */ 5966: SKIP_WHITE_SPACE (bp); 5967: 5968: tokens = read_token_list (&bp, limit, &error_flag); 5969: if (error_flag) 5970: return 1; 5971: if (tokens == 0) { 5972: error ("empty token-sequence in `#assert'"); 5973: return 1; 5974: } 5975: 5976: ++bp; /* skip paren */ 5977: SKIP_WHITE_SPACE (bp); 5978: } 5979: 5980: /* If this name isn't already an assertion name, make it one. 5981: Error if it was already in use in some other way. */ 5982: 5983: { 5984: ASSERTION_HASHNODE *hp; 5985: int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE); 5986: struct tokenlist_list *value 5987: = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list)); 5988: 5989: hp = assertion_lookup (symname, sym_length, hashcode); 5990: if (hp == NULL) { 5991: if (sym_length == 7 && ! strncmp (symname, "defined", sym_length)) 5992: error ("`defined' redefined as assertion"); 5993: hp = assertion_install (symname, sym_length, hashcode); 5994: } 5995: 5996: /* Add the spec'd token-sequence to the list of such. */ 5997: value->tokens = tokens; 5998: value->next = hp->value; 5999: hp->value = value; 6000: } 6001: 6002: return 0; 6003: } 6004: 6005: static int 6006: do_unassert (buf, limit, op, keyword) 6007: U_CHAR *buf, *limit; 6008: FILE_BUF *op; 6009: struct directive *keyword; 6010: { 6011: U_CHAR *bp; /* temp ptr into input buffer */ 6012: U_CHAR *symname; /* remember where symbol name starts */ 6013: int sym_length; /* and how long it is */ 6014: 6015: struct arglist *tokens = NULL; 6016: int tokens_specified = 0; 6017: 6018: if (pedantic && done_initializing && !instack[indepth].system_header_p) 6019: pedwarn ("ANSI C does not allow `#unassert'"); 6020: 6021: bp = buf; 6022: 6023: while (is_hor_space[*bp]) 6024: bp++; 6025: 6026: symname = bp; /* remember where it starts */ 6027: sym_length = check_macro_name (bp, "assertion"); 6028: bp += sym_length; 6029: /* #define doesn't do this, but we should. */ 6030: SKIP_WHITE_SPACE (bp); 6031: 6032: /* Lossage will occur if identifiers or control tokens are broken 6033: across lines using backslash. This is not the right place to take 6034: care of that. */ 6035: 6036: if (*bp == '(') { 6037: int error_flag = 0; 6038: 6039: bp++; /* skip '(' */ 6040: SKIP_WHITE_SPACE (bp); 6041: 6042: tokens = read_token_list (&bp, limit, &error_flag); 6043: if (error_flag) 6044: return 1; 6045: if (tokens == 0) { 6046: error ("empty token list in `#unassert'"); 6047: return 1; 6048: } 6049: 6050: tokens_specified = 1; 6051: 6052: ++bp; /* skip paren */ 6053: SKIP_WHITE_SPACE (bp); 6054: } 6055: 6056: { 6057: ASSERTION_HASHNODE *hp; 6058: int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE); 6059: struct tokenlist_list *tail, *prev; 6060: 6061: hp = assertion_lookup (symname, sym_length, hashcode); 6062: if (hp == NULL) 6063: return 1; 6064: 6065: /* If no token list was specified, then eliminate this assertion 6066: entirely. */ 6067: if (! tokens_specified) { 6068: struct tokenlist_list *next; 6069: for (tail = hp->value; tail; tail = next) { 6070: next = tail->next; 6071: free_token_list (tail->tokens); 6072: free (tail); 6073: } 6074: delete_assertion (hp); 6075: } else { 6076: /* If a list of tokens was given, then delete any matching list. */ 6077: 6078: tail = hp->value; 6079: prev = 0; 6080: while (tail) { 6081: struct tokenlist_list *next = tail->next; 6082: if (compare_token_lists (tail->tokens, tokens)) { 6083: if (prev) 6084: prev->next = next; 6085: else 6086: hp->value = tail->next; 6087: free_token_list (tail->tokens); 6088: free (tail); 6089: } else { 6090: prev = tail; 6091: } 6092: tail = next; 6093: } 6094: } 6095: } 6096: 6097: return 0; 6098: } 6099: 6100: /* Test whether there is an assertion named NAME 6101: and optionally whether it has an asserted token list TOKENS. 6102: NAME is not null terminated; its length is SYM_LENGTH. 6103: If TOKENS_SPECIFIED is 0, then don't check for any token list. */ 6104: 6105: int 6106: check_assertion (name, sym_length, tokens_specified, tokens) 6107: U_CHAR *name; 6108: int sym_length; 6109: int tokens_specified; 6110: struct arglist *tokens; 6111: { 6112: ASSERTION_HASHNODE *hp; 6113: int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE); 6114: 6115: if (pedantic && !instack[indepth].system_header_p) 6116: pedwarn ("ANSI C does not allow testing assertions"); 6117: 6118: hp = assertion_lookup (name, sym_length, hashcode); 6119: if (hp == NULL) 6120: /* It is not an assertion; just return false. */ 6121: return 0; 6122: 6123: /* If no token list was specified, then value is 1. */ 6124: if (! tokens_specified) 6125: return 1; 6126: 6127: { 6128: struct tokenlist_list *tail; 6129: 6130: tail = hp->value; 6131: 6132: /* If a list of tokens was given, 6133: then succeed if the assertion records a matching list. */ 6134: 6135: while (tail) { 6136: if (compare_token_lists (tail->tokens, tokens)) 6137: return 1; 6138: tail = tail->next; 6139: } 6140: 6141: /* Fail if the assertion has no matching list. */ 6142: return 0; 6143: } 6144: } 6145: 6146: /* Compare two lists of tokens for equality including order of tokens. */ 6147: 6148: static int 6149: compare_token_lists (l1, l2) 6150: struct arglist *l1, *l2; 6151: { 6152: while (l1 && l2) { 6153: if (l1->length != l2->length) 6154: return 0; 6155: if (strncmp (l1->name, l2->name, l1->length)) 6156: return 0; 6157: l1 = l1->next; 6158: l2 = l2->next; 6159: } 6160: 6161: /* Succeed if both lists end at the same time. */ 6162: return l1 == l2; 6163: } 6164: 6165: /* Read a space-separated list of tokens ending in a close parenthesis. 6166: Return a list of strings, in the order they were written. 6167: (In case of error, return 0 and store -1 in *ERROR_FLAG.) 6168: Parse the text starting at *BPP, and update *BPP. 6169: Don't parse beyond LIMIT. */ 6170: 6171: static struct arglist * 6172: read_token_list (bpp, limit, error_flag) 6173: U_CHAR **bpp; 6174: U_CHAR *limit; 6175: int *error_flag; 6176: { 6177: struct arglist *token_ptrs = 0; 6178: U_CHAR *bp = *bpp; 6179: int depth = 1; 6180: 6181: *error_flag = 0; 6182: 6183: /* Loop over the assertion value tokens. */ 6184: while (depth > 0) { 6185: struct arglist *temp; 6186: int eofp = 0; 6187: U_CHAR *beg = bp; 6188: 6189: /* Find the end of the token. */ 6190: if (*bp == '(') { 6191: bp++; 6192: depth++; 6193: } else if (*bp == ')') { 6194: depth--; 6195: if (depth == 0) 6196: break; 6197: bp++; 6198: } else if (*bp == '"' || *bp == '\'') 1.1.1.4 root 6199: bp = skip_quoted_string (bp, limit, 0, NULL_PTR, NULL_PTR, &eofp); 1.1 root 6200: else 6201: while (! is_hor_space[*bp] && *bp != '(' && *bp != ')' 6202: && *bp != '"' && *bp != '\'' && bp != limit) 6203: bp++; 6204: 6205: temp = (struct arglist *) xmalloc (sizeof (struct arglist)); 6206: temp->name = (U_CHAR *) xmalloc (bp - beg + 1); 1.1.1.7 ! root 6207: bcopy ((char *) beg, (char *) temp->name, bp - beg); 1.1 root 6208: temp->name[bp - beg] = 0; 6209: temp->next = token_ptrs; 6210: token_ptrs = temp; 6211: temp->length = bp - beg; 6212: 6213: SKIP_WHITE_SPACE (bp); 6214: 6215: if (bp >= limit) { 6216: error ("unterminated token sequence in `#assert' or `#unassert'"); 6217: *error_flag = -1; 6218: return 0; 6219: } 6220: } 6221: *bpp = bp; 6222: 6223: /* We accumulated the names in reverse order. 6224: Now reverse them to get the proper order. */ 6225: { 6226: register struct arglist *prev = 0, *this, *next; 6227: for (this = token_ptrs; this; this = next) { 6228: next = this->next; 6229: this->next = prev; 6230: prev = this; 6231: } 6232: return prev; 6233: } 6234: } 6235: 6236: static void 6237: free_token_list (tokens) 6238: struct arglist *tokens; 6239: { 6240: while (tokens) { 6241: struct arglist *next = tokens->next; 6242: free (tokens->name); 6243: free (tokens); 6244: tokens = next; 6245: } 6246: } 6247: 6248: /* 6249: * Install a name in the assertion hash table. 6250: * 6251: * If LEN is >= 0, it is the length of the name. 6252: * Otherwise, compute the length by scanning the entire name. 6253: * 6254: * If HASH is >= 0, it is the precomputed hash code. 6255: * Otherwise, compute the hash code. 6256: */ 6257: static ASSERTION_HASHNODE * 6258: assertion_install (name, len, hash) 6259: U_CHAR *name; 6260: int len; 6261: int hash; 6262: { 6263: register ASSERTION_HASHNODE *hp; 6264: register int i, bucket; 6265: register U_CHAR *p, *q; 6266: 6267: i = sizeof (ASSERTION_HASHNODE) + len + 1; 6268: hp = (ASSERTION_HASHNODE *) xmalloc (i); 6269: bucket = hash; 6270: hp->bucket_hdr = &assertion_hashtab[bucket]; 6271: hp->next = assertion_hashtab[bucket]; 6272: assertion_hashtab[bucket] = hp; 6273: hp->prev = NULL; 6274: if (hp->next != NULL) 6275: hp->next->prev = hp; 6276: hp->length = len; 6277: hp->value = 0; 6278: hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE); 6279: p = hp->name; 6280: q = name; 6281: for (i = 0; i < len; i++) 6282: *p++ = *q++; 6283: hp->name[len] = 0; 6284: return hp; 6285: } 6286: 6287: /* 6288: * find the most recent hash node for name name (ending with first 6289: * non-identifier char) installed by install 6290: * 6291: * If LEN is >= 0, it is the length of the name. 6292: * Otherwise, compute the length by scanning the entire name. 6293: * 6294: * If HASH is >= 0, it is the precomputed hash code. 6295: * Otherwise, compute the hash code. 6296: */ 6297: static ASSERTION_HASHNODE * 6298: assertion_lookup (name, len, hash) 6299: U_CHAR *name; 6300: int len; 6301: int hash; 6302: { 6303: register ASSERTION_HASHNODE *bucket; 6304: 6305: bucket = assertion_hashtab[hash]; 6306: while (bucket) { 6307: if (bucket->length == len && strncmp (bucket->name, name, len) == 0) 6308: return bucket; 6309: bucket = bucket->next; 6310: } 6311: return NULL; 6312: } 6313: 6314: static void 6315: delete_assertion (hp) 6316: ASSERTION_HASHNODE *hp; 6317: { 6318: 6319: if (hp->prev != NULL) 6320: hp->prev->next = hp->next; 6321: if (hp->next != NULL) 6322: hp->next->prev = hp->prev; 6323: 6324: /* make sure that the bucket chain header that 6325: the deleted guy was on points to the right thing afterwards. */ 6326: if (hp == *hp->bucket_hdr) 6327: *hp->bucket_hdr = hp->next; 6328: 6329: free (hp); 6330: } 6331: 6332: /* 6333: * interpret #line command. Remembers previously seen fnames 6334: * in its very own hash table. 6335: */ 6336: #define FNAME_HASHSIZE 37 6337: 6338: static int 6339: do_line (buf, limit, op, keyword) 6340: U_CHAR *buf, *limit; 6341: FILE_BUF *op; 6342: struct directive *keyword; 6343: { 6344: register U_CHAR *bp; 6345: FILE_BUF *ip = &instack[indepth]; 6346: FILE_BUF tem; 6347: int new_lineno; 6348: enum file_change_code file_change = same_file; 6349: 6350: /* Expand any macros. */ 6351: tem = expand_to_temp_buffer (buf, limit, 0, 0); 6352: 6353: /* Point to macroexpanded line, which is null-terminated now. */ 6354: bp = tem.buf; 6355: SKIP_WHITE_SPACE (bp); 6356: 6357: if (!isdigit (*bp)) { 6358: error ("invalid format `#line' command"); 6359: return 0; 6360: } 6361: 6362: /* The Newline at the end of this line remains to be processed. 6363: To put the next line at the specified line number, 6364: we must store a line number now that is one less. */ 6365: new_lineno = atoi (bp) - 1; 6366: 1.1.1.5 root 6367: /* NEW_LINENO is one less than the actual line number here. */ 6368: if (pedantic && new_lineno < 0) 6369: pedwarn ("line number out of range in `#line' command"); 6370: 1.1 root 6371: /* skip over the line number. */ 6372: while (isdigit (*bp)) 6373: bp++; 6374: 6375: #if 0 /* #line 10"foo.c" is supposed to be allowed. */ 6376: if (*bp && !is_space[*bp]) { 6377: error ("invalid format `#line' command"); 6378: return; 6379: } 6380: #endif 6381: 6382: SKIP_WHITE_SPACE (bp); 6383: 6384: if (*bp == '\"') { 6385: static HASHNODE *fname_table[FNAME_HASHSIZE]; 6386: HASHNODE *hp, **hash_bucket; 1.1.1.6 root 6387: U_CHAR *fname, *p; 1.1 root 6388: int fname_length; 6389: 6390: fname = ++bp; 6391: 1.1.1.6 root 6392: /* Turn the file name, which is a character string literal, 6393: into a null-terminated string. Do this in place. */ 6394: p = bp; 6395: for (;;) 6396: switch ((*p++ = *bp++)) { 6397: case '\0': 6398: error ("invalid format `#line' command"); 6399: return 0; 1.1 root 6400: 1.1.1.6 root 6401: case '\\': 6402: { 6403: char *bpc = (char *) bp; 6404: int c = parse_escape (&bpc); 6405: bp = (U_CHAR *) bpc; 6406: if (c < 0) 6407: p--; 6408: else 6409: p[-1] = c; 6410: } 6411: break; 6412: 6413: case '\"': 6414: p[-1] = 0; 6415: goto fname_done; 6416: } 6417: fname_done: 6418: fname_length = p - fname; 1.1 root 6419: 6420: SKIP_WHITE_SPACE (bp); 6421: if (*bp) { 1.1.1.5 root 6422: if (pedantic) 6423: pedwarn ("garbage at end of `#line' command"); 1.1 root 6424: if (*bp == '1') 6425: file_change = enter_file; 6426: else if (*bp == '2') 6427: file_change = leave_file; 1.1.1.2 root 6428: else if (*bp == '3') 6429: ip->system_header_p = 1; 1.1.1.6 root 6430: else if (*bp == '4') 6431: ip->system_header_p = 2; 1.1 root 6432: else { 6433: error ("invalid format `#line' command"); 6434: return 0; 6435: } 6436: 6437: bp++; 6438: SKIP_WHITE_SPACE (bp); 1.1.1.2 root 6439: if (*bp == '3') { 6440: ip->system_header_p = 1; 6441: bp++; 6442: SKIP_WHITE_SPACE (bp); 6443: } 1.1.1.6 root 6444: if (*bp == '4') { 6445: ip->system_header_p = 2; 6446: bp++; 6447: SKIP_WHITE_SPACE (bp); 6448: } 1.1 root 6449: if (*bp) { 6450: error ("invalid format `#line' command"); 6451: return 0; 6452: } 6453: } 6454: 6455: hash_bucket = 6456: &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)]; 6457: for (hp = *hash_bucket; hp != NULL; hp = hp->next) 6458: if (hp->length == fname_length && 6459: strncmp (hp->value.cpval, fname, fname_length) == 0) { 6460: ip->nominal_fname = hp->value.cpval; 6461: break; 6462: } 6463: if (hp == 0) { 6464: /* Didn't find it; cons up a new one. */ 6465: hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1); 6466: hp->next = *hash_bucket; 6467: *hash_bucket = hp; 6468: 6469: hp->length = fname_length; 6470: ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE); 6471: bcopy (fname, hp->value.cpval, fname_length); 6472: } 6473: } else if (*bp) { 6474: error ("invalid format `#line' command"); 6475: return 0; 6476: } 6477: 6478: ip->lineno = new_lineno; 6479: output_line_command (ip, op, 0, file_change); 6480: check_expand (op, ip->length - (ip->bufp - ip->buf)); 6481: return 0; 6482: } 6483: 6484: /* 6485: * remove the definition of a symbol from the symbol table. 6486: * according to un*x /lib/cpp, it is not an error to undef 6487: * something that has no definitions, so it isn't one here either. 6488: */ 6489: 6490: static int 6491: do_undef (buf, limit, op, keyword) 6492: U_CHAR *buf, *limit; 6493: FILE_BUF *op; 6494: struct directive *keyword; 6495: { 6496: int sym_length; 6497: HASHNODE *hp; 6498: U_CHAR *orig_buf = buf; 6499: 6500: /* If this is a precompiler run (with -pcp) pass thru #undef commands. */ 6501: if (pcp_outfile && op) 6502: pass_thru_directive (buf, limit, op, keyword); 6503: 6504: SKIP_WHITE_SPACE (buf); 6505: sym_length = check_macro_name (buf, "macro"); 6506: 6507: while ((hp = lookup (buf, sym_length, -1)) != NULL) { 6508: /* If we are generating additional info for debugging (with -g) we 6509: need to pass through all effective #undef commands. */ 6510: if (debug_output && op) 6511: pass_thru_directive (orig_buf, limit, op, keyword); 6512: if (hp->type != T_MACRO) 6513: warning ("undefining `%s'", hp->name); 6514: delete_macro (hp); 6515: } 6516: 6517: if (pedantic) { 6518: buf += sym_length; 6519: SKIP_WHITE_SPACE (buf); 6520: if (buf != limit) 6521: pedwarn ("garbage after `#undef' directive"); 6522: } 6523: return 0; 6524: } 6525: 6526: /* 1.1.1.7 ! root 6527: * Report an error detected by the program we are processing. ! 6528: * Use the text of the line in the error message. 1.1.1.5 root 6529: * (We use error because it prints the filename & line#.) 1.1 root 6530: */ 6531: 6532: static int 6533: do_error (buf, limit, op, keyword) 6534: U_CHAR *buf, *limit; 6535: FILE_BUF *op; 6536: struct directive *keyword; 6537: { 6538: int length = limit - buf; 1.1.1.5 root 6539: U_CHAR *copy = (U_CHAR *) xmalloc (length + 1); 1.1.1.7 ! root 6540: bcopy ((char *) buf, (char *) copy, length); 1.1 root 6541: copy[length] = 0; 6542: SKIP_WHITE_SPACE (copy); 6543: error ("#error %s", copy); 6544: return 0; 6545: } 6546: 6547: /* 6548: * Report a warning detected by the program we are processing. 6549: * Use the text of the line in the warning message, then continue. 1.1.1.5 root 6550: * (We use error because it prints the filename & line#.) 1.1 root 6551: */ 6552: 6553: static int 6554: do_warning (buf, limit, op, keyword) 6555: U_CHAR *buf, *limit; 6556: FILE_BUF *op; 6557: struct directive *keyword; 6558: { 6559: int length = limit - buf; 1.1.1.5 root 6560: U_CHAR *copy = (U_CHAR *) xmalloc (length + 1); 1.1.1.7 ! root 6561: bcopy ((char *) buf, (char *) copy, length); 1.1 root 6562: copy[length] = 0; 6563: SKIP_WHITE_SPACE (copy); 1.1.1.3 root 6564: warning ("#warning %s", copy); 1.1 root 6565: return 0; 6566: } 6567: 6568: /* Remember the name of the current file being read from so that we can 6569: avoid ever including it again. */ 6570: 6571: static int 6572: do_once () 6573: { 6574: int i; 6575: FILE_BUF *ip = NULL; 6576: 6577: for (i = indepth; i >= 0; i--) 6578: if (instack[i].fname != NULL) { 6579: ip = &instack[i]; 6580: break; 6581: } 6582: 6583: if (ip != NULL) { 6584: struct file_name_list *new; 6585: 6586: new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 6587: new->next = dont_repeat_files; 6588: dont_repeat_files = new; 6589: new->fname = savestring (ip->fname); 6590: new->control_macro = 0; 1.1.1.7 ! root 6591: new->got_name_map = 0; 1.1.1.6 root 6592: new->c_system_include_path = 0; 1.1 root 6593: } 6594: return 0; 6595: } 6596: 6597: /* #ident has already been copied to the output file, so just ignore it. */ 6598: 6599: static int 6600: do_ident (buf, limit) 6601: U_CHAR *buf, *limit; 6602: { 1.1.1.6 root 6603: FILE_BUF trybuf; 6604: int len; 6605: FILE_BUF *op = &outbuf; 6606: 1.1 root 6607: /* Allow #ident in system headers, since that's not user's fault. */ 6608: if (pedantic && !instack[indepth].system_header_p) 6609: pedwarn ("ANSI C does not allow `#ident'"); 1.1.1.6 root 6610: 6611: trybuf = expand_to_temp_buffer (buf, limit, 0, 0); 6612: buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1); 1.1.1.7 ! root 6613: bcopy ((char *) trybuf.buf, (char *) buf, trybuf.bufp - trybuf.buf); 1.1.1.6 root 6614: limit = buf + (trybuf.bufp - trybuf.buf); 6615: len = (limit - buf); 6616: free (trybuf.buf); 6617: 6618: /* Output directive name. */ 1.1.1.7 ! root 6619: check_expand (op, 7); ! 6620: bcopy ("#ident ", (char *) op->bufp, 7); 1.1.1.6 root 6621: op->bufp += 7; 6622: 6623: /* Output the expanded argument line. */ 6624: check_expand (op, len); 1.1.1.7 ! root 6625: bcopy ((char *) buf, (char *) op->bufp, len); 1.1.1.6 root 6626: op->bufp += len; 6627: 1.1 root 6628: return 0; 6629: } 6630: 6631: /* #pragma and its argument line have already been copied to the output file. 1.1.1.4 root 6632: Just check for some recognized pragmas that need validation here. */ 1.1 root 6633: 6634: static int 6635: do_pragma (buf, limit) 6636: U_CHAR *buf, *limit; 6637: { 6638: while (*buf == ' ' || *buf == '\t') 6639: buf++; 6640: if (!strncmp (buf, "once", 4)) { 1.1.1.3 root 6641: /* Allow #pragma once in system headers, since that's not the user's 6642: fault. */ 6643: if (!instack[indepth].system_header_p) 6644: warning ("`#pragma once' is obsolete"); 1.1 root 6645: do_once (); 6646: } 1.1.1.4 root 6647: 6648: if (!strncmp (buf, "implementation", 14)) { 6649: /* Be quiet about `#pragma implementation' for a file only if it hasn't 6650: been included yet. */ 6651: struct file_name_list *ptr; 6652: U_CHAR *p = buf + 14, *fname, *inc_fname; 6653: SKIP_WHITE_SPACE (p); 6654: if (*p == '\n' || *p != '\"') 6655: return 0; 6656: 6657: fname = p + 1; 6658: if (p = (U_CHAR *) index (fname, '\"')) 6659: *p = '\0'; 6660: 6661: for (ptr = all_include_files; ptr; ptr = ptr->next) { 6662: inc_fname = (U_CHAR *) rindex (ptr->fname, '/'); 6663: inc_fname = inc_fname ? inc_fname + 1 : (U_CHAR *) ptr->fname; 6664: if (inc_fname && !strcmp (inc_fname, fname)) 6665: warning ("`#pragma implementation' for `%s' appears after file is included", 6666: fname); 6667: } 6668: } 6669: 1.1 root 6670: return 0; 6671: } 6672: 6673: #if 0 6674: /* This was a fun hack, but #pragma seems to start to be useful. 6675: By failing to recognize it, we pass it through unchanged to cc1. */ 6676: 6677: /* 6678: * the behavior of the #pragma directive is implementation defined. 6679: * this implementation defines it as follows. 6680: */ 6681: 6682: static int 6683: do_pragma () 6684: { 6685: close (0); 6686: if (open ("/dev/tty", O_RDONLY, 0666) != 0) 6687: goto nope; 6688: close (1); 6689: if (open ("/dev/tty", O_WRONLY, 0666) != 1) 6690: goto nope; 6691: execl ("/usr/games/hack", "#pragma", 0); 6692: execl ("/usr/games/rogue", "#pragma", 0); 6693: execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0); 6694: execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0); 6695: nope: 6696: fatal ("You are in a maze of twisty compiler features, all different"); 6697: } 6698: #endif 6699: 6700: /* Just ignore #sccs, on systems where we define it at all. */ 6701: 6702: static int 6703: do_sccs () 6704: { 6705: if (pedantic) 6706: pedwarn ("ANSI C does not allow `#sccs'"); 6707: return 0; 6708: } 6709: 6710: /* 6711: * handle #if command by 6712: * 1) inserting special `defined' keyword into the hash table 6713: * that gets turned into 0 or 1 by special_symbol (thus, 6714: * if the luser has a symbol called `defined' already, it won't 6715: * work inside the #if command) 6716: * 2) rescan the input into a temporary output buffer 6717: * 3) pass the output buffer to the yacc parser and collect a value 6718: * 4) clean up the mess left from steps 1 and 2. 6719: * 5) call conditional_skip to skip til the next #endif (etc.), 6720: * or not, depending on the value from step 3. 6721: */ 6722: 6723: static int 6724: do_if (buf, limit, op, keyword) 6725: U_CHAR *buf, *limit; 6726: FILE_BUF *op; 6727: struct directive *keyword; 6728: { 1.1.1.7 ! root 6729: HOST_WIDE_INT value; 1.1 root 6730: FILE_BUF *ip = &instack[indepth]; 6731: 6732: value = eval_if_expression (buf, limit - buf); 1.1.1.7 ! root 6733: conditional_skip (ip, value == 0, T_IF, NULL_PTR, op); 1.1 root 6734: return 0; 6735: } 6736: 6737: /* 6738: * handle a #elif directive by not changing if_stack either. 6739: * see the comment above do_else. 6740: */ 6741: 6742: static int 6743: do_elif (buf, limit, op, keyword) 6744: U_CHAR *buf, *limit; 6745: FILE_BUF *op; 6746: struct directive *keyword; 6747: { 1.1.1.7 ! root 6748: HOST_WIDE_INT value; 1.1 root 6749: FILE_BUF *ip = &instack[indepth]; 6750: 6751: if (if_stack == instack[indepth].if_stack) { 6752: error ("`#elif' not within a conditional"); 6753: return 0; 6754: } else { 6755: if (if_stack->type != T_IF && if_stack->type != T_ELIF) { 6756: error ("`#elif' after `#else'"); 6757: fprintf (stderr, " (matches line %d", if_stack->lineno); 6758: if (if_stack->fname != NULL && ip->fname != NULL && 6759: strcmp (if_stack->fname, ip->nominal_fname) != 0) 6760: fprintf (stderr, ", file %s", if_stack->fname); 6761: fprintf (stderr, ")\n"); 6762: } 6763: if_stack->type = T_ELIF; 6764: } 6765: 6766: if (if_stack->if_succeeded) 1.1.1.7 ! root 6767: skip_if_group (ip, 0, op); 1.1 root 6768: else { 6769: value = eval_if_expression (buf, limit - buf); 6770: if (value == 0) 1.1.1.7 ! root 6771: skip_if_group (ip, 0, op); 1.1 root 6772: else { 6773: ++if_stack->if_succeeded; /* continue processing input */ 6774: output_line_command (ip, op, 1, same_file); 6775: } 6776: } 6777: return 0; 6778: } 6779: 6780: /* 6781: * evaluate a #if expression in BUF, of length LENGTH, 6782: * then parse the result as a C expression and return the value as an int. 6783: */ 1.1.1.7 ! root 6784: static HOST_WIDE_INT 1.1 root 6785: eval_if_expression (buf, length) 6786: U_CHAR *buf; 6787: int length; 6788: { 6789: FILE_BUF temp_obuf; 6790: HASHNODE *save_defined; 1.1.1.7 ! root 6791: HOST_WIDE_INT value; 1.1 root 6792: 1.1.1.7 ! root 6793: save_defined = install ("defined", -1, T_SPEC_DEFINED, 0, NULL_PTR, -1); 1.1 root 6794: pcp_inside_if = 1; 6795: temp_obuf = expand_to_temp_buffer (buf, buf + length, 0, 1); 6796: pcp_inside_if = 0; 6797: delete_macro (save_defined); /* clean up special symbol */ 6798: 6799: value = parse_c_expression (temp_obuf.buf); 6800: 6801: free (temp_obuf.buf); 6802: 6803: return value; 6804: } 6805: 6806: /* 6807: * routine to handle ifdef/ifndef. Try to look up the symbol, 6808: * then do or don't skip to the #endif/#else/#elif depending 6809: * on what directive is actually being processed. 6810: */ 6811: 6812: static int 6813: do_xifdef (buf, limit, op, keyword) 6814: U_CHAR *buf, *limit; 6815: FILE_BUF *op; 6816: struct directive *keyword; 6817: { 6818: int skip; 6819: FILE_BUF *ip = &instack[indepth]; 6820: U_CHAR *end; 6821: int start_of_file = 0; 6822: U_CHAR *control_macro = 0; 6823: 6824: /* Detect a #ifndef at start of file (not counting comments). */ 6825: if (ip->fname != 0 && keyword->type == T_IFNDEF) { 6826: U_CHAR *p = ip->buf; 6827: while (p != directive_start) { 1.1.1.5 root 6828: U_CHAR c = *p++; 1.1.1.4 root 6829: if (is_space[c]) 6830: ; 6831: else if (c == '/' && p != ip->bufp && *p == '*') { 6832: /* Skip this comment. */ 1.1.1.7 ! root 6833: int junk = 0; 1.1.1.4 root 6834: U_CHAR *save_bufp = ip->bufp; 6835: ip->bufp = p + 1; 6836: p = skip_to_end_of_comment (ip, &junk, 1); 6837: ip->bufp = save_bufp; 6838: } else { 1.1 root 6839: goto fail; 6840: } 6841: } 6842: /* If we get here, this conditional is the beginning of the file. */ 6843: start_of_file = 1; 6844: fail: ; 6845: } 6846: 6847: /* Discard leading and trailing whitespace. */ 6848: SKIP_WHITE_SPACE (buf); 6849: while (limit != buf && is_hor_space[limit[-1]]) limit--; 6850: 6851: /* Find the end of the identifier at the beginning. */ 6852: for (end = buf; is_idchar[*end]; end++); 6853: 6854: if (end == buf) { 6855: skip = (keyword->type == T_IFDEF); 6856: if (! traditional) 6857: pedwarn (end == limit ? "`#%s' with no argument" 6858: : "`#%s' argument starts with punctuation", 6859: keyword->name); 6860: } else { 6861: HASHNODE *hp; 6862: 6863: if (pedantic && buf[0] >= '0' && buf[0] <= '9') 6864: pedwarn ("`#%s' argument starts with a digit", keyword->name); 6865: else if (end != limit && !traditional) 6866: pedwarn ("garbage at end of `#%s' argument", keyword->name); 6867: 6868: hp = lookup (buf, end-buf, -1); 6869: 6870: if (pcp_outfile) { 6871: /* Output a precondition for this macro. */ 1.1.1.7 ! root 6872: if (hp && ! 6873: (hp->type == T_CONST ! 6874: || (hp->type == T_MACRO && hp->value.defn->predefined))) 1.1.1.5 root 6875: fprintf (pcp_outfile, "#define %s\n", hp->name); 1.1 root 6876: else { 6877: U_CHAR *cp = buf; 1.1.1.5 root 6878: fprintf (pcp_outfile, "#undef "); 1.1 root 6879: while (is_idchar[*cp]) /* Ick! */ 6880: fputc (*cp++, pcp_outfile); 6881: putc ('\n', pcp_outfile); 6882: } 6883: } 6884: 6885: skip = (hp == NULL) ^ (keyword->type == T_IFNDEF); 6886: if (start_of_file && !skip) { 6887: control_macro = (U_CHAR *) xmalloc (end - buf + 1); 1.1.1.7 ! root 6888: bcopy ((char *) buf, (char *) control_macro, end - buf); 1.1 root 6889: control_macro[end - buf] = 0; 6890: } 6891: } 6892: 1.1.1.7 ! root 6893: conditional_skip (ip, skip, T_IF, control_macro, op); 1.1 root 6894: return 0; 6895: } 6896: 6897: /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead. 6898: If this is a #ifndef starting at the beginning of a file, 6899: CONTROL_MACRO is the macro name tested by the #ifndef. 6900: Otherwise, CONTROL_MACRO is 0. */ 6901: 6902: static void 1.1.1.7 ! root 6903: conditional_skip (ip, skip, type, control_macro, op) 1.1 root 6904: FILE_BUF *ip; 6905: int skip; 6906: enum node_type type; 6907: U_CHAR *control_macro; 1.1.1.7 ! root 6908: FILE_BUF *op; 1.1 root 6909: { 6910: IF_STACK_FRAME *temp; 6911: 6912: temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME)); 6913: temp->fname = ip->nominal_fname; 6914: temp->lineno = ip->lineno; 6915: temp->next = if_stack; 6916: temp->control_macro = control_macro; 6917: if_stack = temp; 6918: 6919: if_stack->type = type; 6920: 6921: if (skip != 0) { 1.1.1.7 ! root 6922: skip_if_group (ip, 0, op); 1.1 root 6923: return; 6924: } else { 6925: ++if_stack->if_succeeded; 6926: output_line_command (ip, &outbuf, 1, same_file); 6927: } 6928: } 6929: 6930: /* 6931: * skip to #endif, #else, or #elif. adjust line numbers, etc. 6932: * leaves input ptr at the sharp sign found. 6933: * If ANY is nonzero, return at next directive of any sort. 6934: */ 6935: static void 1.1.1.7 ! root 6936: skip_if_group (ip, any, op) 1.1 root 6937: FILE_BUF *ip; 6938: int any; 1.1.1.7 ! root 6939: FILE_BUF *op; 1.1 root 6940: { 6941: register U_CHAR *bp = ip->bufp, *cp; 6942: register U_CHAR *endb = ip->buf + ip->length; 6943: struct directive *kt; 6944: IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */ 6945: U_CHAR *beg_of_line = bp; 6946: register int ident_length; 6947: U_CHAR *ident, *after_ident; 1.1.1.7 ! root 6948: /* Save info about where the group starts. */ ! 6949: U_CHAR *beg_of_group = bp; ! 6950: int beg_lineno = ip->lineno; ! 6951: ! 6952: if (output_conditionals && op != 0) { ! 6953: char *ptr = "#failed\n"; ! 6954: int len = strlen (ptr); ! 6955: ! 6956: if (op->bufp > op->buf && op->bufp[-1] != '\n') ! 6957: { ! 6958: *op->bufp++ = '\n'; ! 6959: op->lineno++; ! 6960: } ! 6961: check_expand (op, len); ! 6962: bcopy (ptr, (char *) op->bufp, len); ! 6963: op->bufp += len; ! 6964: op->lineno++; ! 6965: output_line_command (ip, op, 1, 0); ! 6966: } 1.1 root 6967: 6968: while (bp < endb) { 6969: switch (*bp++) { 6970: case '/': /* possible comment */ 6971: if (*bp == '\\' && bp[1] == '\n') 6972: newline_fix (bp); 6973: if (*bp == '*' 1.1.1.4 root 6974: || (cplusplus_comments && *bp == '/')) { 1.1 root 6975: ip->bufp = ++bp; 1.1.1.2 root 6976: bp = skip_to_end_of_comment (ip, &ip->lineno, 0); 1.1 root 6977: } 6978: break; 6979: case '\"': 6980: case '\'': 1.1.1.4 root 6981: bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno, 6982: NULL_PTR, NULL_PTR); 1.1 root 6983: break; 6984: case '\\': 6985: /* Char after backslash loses its special meaning. */ 6986: if (bp < endb) { 6987: if (*bp == '\n') 6988: ++ip->lineno; /* But do update the line-count. */ 6989: bp++; 6990: } 6991: break; 6992: case '\n': 6993: ++ip->lineno; 6994: beg_of_line = bp; 6995: break; 6996: case '#': 6997: ip->bufp = bp - 1; 6998: 6999: /* # keyword: a # must be first nonblank char on the line */ 7000: if (beg_of_line == 0) 7001: break; 7002: /* Scan from start of line, skipping whitespace, comments 7003: and backslash-newlines, and see if we reach this #. 7004: If not, this # is not special. */ 7005: bp = beg_of_line; 1.1.1.6 root 7006: /* If -traditional, require # to be at beginning of line. */ 7007: if (!traditional) 7008: while (1) { 7009: if (is_hor_space[*bp]) 1.1 root 7010: bp++; 1.1.1.6 root 7011: else if (*bp == '\\' && bp[1] == '\n') 7012: bp += 2; 7013: else if (*bp == '/' && bp[1] == '*') { 7014: bp += 2; 7015: while (!(*bp == '*' && bp[1] == '/')) 7016: bp++; 7017: bp += 2; 7018: } 1.1.1.7 ! root 7019: /* There is no point in trying to deal with C++ // comments here, ! 7020: because if there is one, then this # must be part of the ! 7021: comment and we would never reach here. */ 1.1.1.6 root 7022: else break; 7023: } 1.1 root 7024: if (bp != ip->bufp) { 7025: bp = ip->bufp + 1; /* Reset bp to after the #. */ 7026: break; 7027: } 7028: 7029: bp = ip->bufp + 1; /* Point after the '#' */ 7030: 7031: /* Skip whitespace and \-newline. */ 7032: while (1) { 7033: if (is_hor_space[*bp]) 7034: bp++; 7035: else if (*bp == '\\' && bp[1] == '\n') 7036: bp += 2; 7037: else if (*bp == '/' && bp[1] == '*') { 7038: bp += 2; 7039: while (!(*bp == '*' && bp[1] == '/')) { 7040: if (*bp == '\n') 7041: ip->lineno++; 7042: bp++; 7043: } 7044: bp += 2; 1.1.1.4 root 7045: } else if (cplusplus_comments && *bp == '/' && bp[1] == '/') { 1.1 root 7046: bp += 2; 1.1.1.7 ! root 7047: while (bp[-1] == '\\' || *bp != '\n') { ! 7048: if (*bp == '\n') ! 7049: ip->lineno++; ! 7050: bp++; ! 7051: } 1.1 root 7052: } 7053: else break; 7054: } 7055: 7056: cp = bp; 7057: 7058: /* Now find end of directive name. 7059: If we encounter a backslash-newline, exchange it with any following 7060: symbol-constituents so that we end up with a contiguous name. */ 7061: 7062: while (1) { 7063: if (is_idchar[*bp]) 7064: bp++; 7065: else { 7066: if (*bp == '\\' && bp[1] == '\n') 7067: name_newline_fix (bp); 7068: if (is_idchar[*bp]) 7069: bp++; 7070: else break; 7071: } 7072: } 7073: ident_length = bp - cp; 7074: ident = cp; 7075: after_ident = bp; 7076: 7077: /* A line of just `#' becomes blank. */ 7078: 7079: if (ident_length == 0 && *after_ident == '\n') { 7080: continue; 7081: } 7082: 7083: if (ident_length == 0 || !is_idstart[*ident]) { 7084: U_CHAR *p = ident; 7085: while (is_idchar[*p]) { 7086: if (*p < '0' || *p > '9') 7087: break; 7088: p++; 7089: } 7090: /* Handle # followed by a line number. */ 7091: if (p != ident && !is_idchar[*p]) { 7092: if (pedantic) 7093: pedwarn ("`#' followed by integer"); 7094: continue; 7095: } 7096: 7097: /* Avoid error for `###' and similar cases unless -pedantic. */ 7098: if (p == ident) { 7099: while (*p == '#' || is_hor_space[*p]) p++; 7100: if (*p == '\n') { 7101: if (pedantic && !lang_asm) 7102: pedwarn ("invalid preprocessor directive"); 7103: continue; 7104: } 7105: } 7106: 7107: if (!lang_asm && pedantic) 7108: pedwarn ("invalid preprocessor directive name"); 7109: continue; 7110: } 7111: 7112: for (kt = directive_table; kt->length >= 0; kt++) { 7113: IF_STACK_FRAME *temp; 7114: if (ident_length == kt->length 7115: && strncmp (cp, kt->name, kt->length) == 0) { 7116: /* If we are asked to return on next directive, do so now. */ 7117: if (any) 1.1.1.7 ! root 7118: goto done; 1.1 root 7119: 7120: switch (kt->type) { 7121: case T_IF: 7122: case T_IFDEF: 7123: case T_IFNDEF: 7124: temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME)); 7125: temp->next = if_stack; 7126: if_stack = temp; 7127: temp->lineno = ip->lineno; 7128: temp->fname = ip->nominal_fname; 7129: temp->type = kt->type; 7130: break; 7131: case T_ELSE: 7132: case T_ENDIF: 7133: if (pedantic && if_stack != save_if_stack) 7134: validate_else (bp); 7135: case T_ELIF: 7136: if (if_stack == instack[indepth].if_stack) { 7137: error ("`#%s' not within a conditional", kt->name); 7138: break; 7139: } 7140: else if (if_stack == save_if_stack) 1.1.1.7 ! root 7141: goto done; /* found what we came for */ 1.1 root 7142: 7143: if (kt->type != T_ENDIF) { 7144: if (if_stack->type == T_ELSE) 7145: error ("`#else' or `#elif' after `#else'"); 7146: if_stack->type = kt->type; 7147: break; 7148: } 7149: 7150: temp = if_stack; 7151: if_stack = if_stack->next; 7152: free (temp); 7153: break; 7154: } 7155: break; 7156: } 7157: } 7158: /* Don't let erroneous code go by. */ 7159: if (kt->length < 0 && !lang_asm && pedantic) 7160: pedwarn ("invalid preprocessor directive name"); 7161: } 7162: } 1.1.1.7 ! root 7163: 1.1 root 7164: ip->bufp = bp; 7165: /* after this returns, rescan will exit because ip->bufp 7166: now points to the end of the buffer. 7167: rescan is responsible for the error message also. */ 1.1.1.7 ! root 7168: ! 7169: done: ! 7170: if (output_conditionals && op != 0) { ! 7171: char *ptr = "#endfailed\n"; ! 7172: int len = strlen (ptr); ! 7173: ! 7174: if (op->bufp > op->buf && op->bufp[-1] != '\n') ! 7175: { ! 7176: *op->bufp++ = '\n'; ! 7177: op->lineno++; ! 7178: } ! 7179: check_expand (op, beg_of_line - beg_of_group); ! 7180: bcopy ((char *) beg_of_group, (char *) op->bufp, ! 7181: beg_of_line - beg_of_group); ! 7182: op->bufp += beg_of_line - beg_of_group; ! 7183: op->lineno += ip->lineno - beg_lineno; ! 7184: check_expand (op, len); ! 7185: bcopy (ptr, (char *) op->bufp, len); ! 7186: op->bufp += len; ! 7187: op->lineno++; ! 7188: } 1.1 root 7189: } 7190: 7191: /* 7192: * handle a #else directive. Do this by just continuing processing 7193: * without changing if_stack ; this is so that the error message 7194: * for missing #endif's etc. will point to the original #if. It 7195: * is possible that something different would be better. 7196: */ 7197: 7198: static int 7199: do_else (buf, limit, op, keyword) 7200: U_CHAR *buf, *limit; 7201: FILE_BUF *op; 7202: struct directive *keyword; 7203: { 7204: FILE_BUF *ip = &instack[indepth]; 7205: 7206: if (pedantic) { 7207: SKIP_WHITE_SPACE (buf); 7208: if (buf != limit) 7209: pedwarn ("text following `#else' violates ANSI standard"); 7210: } 7211: 7212: if (if_stack == instack[indepth].if_stack) { 7213: error ("`#else' not within a conditional"); 7214: return 0; 7215: } else { 7216: /* #ifndef can't have its special treatment for containing the whole file 7217: if it has a #else clause. */ 7218: if_stack->control_macro = 0; 7219: 7220: if (if_stack->type != T_IF && if_stack->type != T_ELIF) { 7221: error ("`#else' after `#else'"); 7222: fprintf (stderr, " (matches line %d", if_stack->lineno); 7223: if (strcmp (if_stack->fname, ip->nominal_fname) != 0) 7224: fprintf (stderr, ", file %s", if_stack->fname); 7225: fprintf (stderr, ")\n"); 7226: } 7227: if_stack->type = T_ELSE; 7228: } 7229: 7230: if (if_stack->if_succeeded) 1.1.1.7 ! root 7231: skip_if_group (ip, 0, op); 1.1 root 7232: else { 7233: ++if_stack->if_succeeded; /* continue processing input */ 7234: output_line_command (ip, op, 1, same_file); 7235: } 7236: return 0; 7237: } 7238: 7239: /* 7240: * unstack after #endif command 7241: */ 7242: 7243: static int 7244: do_endif (buf, limit, op, keyword) 7245: U_CHAR *buf, *limit; 7246: FILE_BUF *op; 7247: struct directive *keyword; 7248: { 7249: if (pedantic) { 7250: SKIP_WHITE_SPACE (buf); 7251: if (buf != limit) 7252: pedwarn ("text following `#endif' violates ANSI standard"); 7253: } 7254: 7255: if (if_stack == instack[indepth].if_stack) 7256: error ("unbalanced `#endif'"); 7257: else { 7258: IF_STACK_FRAME *temp = if_stack; 7259: if_stack = if_stack->next; 7260: if (temp->control_macro != 0) { 7261: /* This #endif matched a #ifndef at the start of the file. 7262: See if it is at the end of the file. */ 7263: FILE_BUF *ip = &instack[indepth]; 7264: U_CHAR *p = ip->bufp; 7265: U_CHAR *ep = ip->buf + ip->length; 7266: 7267: while (p != ep) { 7268: U_CHAR c = *p++; 7269: switch (c) { 7270: case ' ': 7271: case '\t': 7272: case '\n': 7273: break; 7274: case '/': 7275: if (p != ep && *p == '*') { 7276: /* Skip this comment. */ 1.1.1.7 ! root 7277: int junk = 0; 1.1 root 7278: U_CHAR *save_bufp = ip->bufp; 7279: ip->bufp = p + 1; 1.1.1.2 root 7280: p = skip_to_end_of_comment (ip, &junk, 1); 1.1 root 7281: ip->bufp = save_bufp; 7282: } 7283: break; 7284: default: 7285: goto fail; 7286: } 7287: } 7288: /* If we get here, this #endif ends a #ifndef 7289: that contains all of the file (aside from whitespace). 7290: Arrange not to include the file again 1.1.1.7 ! root 7291: if the macro that was tested is defined. ! 7292: ! 7293: Do not do this for the top-level file in a -include or any ! 7294: file in a -imacros. */ ! 7295: if (indepth != 0 ! 7296: && ! (indepth == 1 && no_record_file) ! 7297: && ! (no_record_file && no_output)) 1.1 root 7298: record_control_macro (ip->fname, temp->control_macro); 7299: fail: ; 7300: } 7301: free (temp); 7302: output_line_command (&instack[indepth], op, 1, same_file); 7303: } 7304: return 0; 7305: } 7306: 7307: /* When an #else or #endif is found while skipping failed conditional, 7308: if -pedantic was specified, this is called to warn about text after 7309: the command name. P points to the first char after the command name. */ 7310: 7311: static void 7312: validate_else (p) 7313: register U_CHAR *p; 7314: { 7315: /* Advance P over whitespace and comments. */ 7316: while (1) { 7317: if (*p == '\\' && p[1] == '\n') 7318: p += 2; 7319: if (is_hor_space[*p]) 7320: p++; 7321: else if (*p == '/') { 7322: if (p[1] == '\\' && p[2] == '\n') 7323: newline_fix (p + 1); 7324: if (p[1] == '*') { 7325: p += 2; 7326: /* Don't bother warning about unterminated comments 7327: since that will happen later. Just be sure to exit. */ 7328: while (*p) { 7329: if (p[1] == '\\' && p[2] == '\n') 7330: newline_fix (p + 1); 7331: if (*p == '*' && p[1] == '/') { 7332: p += 2; 7333: break; 7334: } 7335: p++; 7336: } 7337: } 1.1.1.4 root 7338: else if (cplusplus_comments && p[1] == '/') { 1.1 root 7339: p += 2; 1.1.1.7 ! root 7340: while (*p && (*p != '\n' || p[-1] == '\\')) ! 7341: p++; 1.1 root 7342: } 7343: } else break; 7344: } 7345: if (*p && *p != '\n') 7346: pedwarn ("text following `#else' or `#endif' violates ANSI standard"); 7347: } 7348: 1.1.1.2 root 7349: /* Skip a comment, assuming the input ptr immediately follows the 7350: initial slash-star. Bump *LINE_COUNTER for each newline. 7351: (The canonical line counter is &ip->lineno.) 7352: Don't use this routine (or the next one) if bumping the line 7353: counter is not sufficient to deal with newlines in the string. 7354: 7355: If NOWARN is nonzero, don't warn about slash-star inside a comment. 7356: This feature is useful when processing a comment that is going to be 7357: processed or was processed at another point in the preprocessor, 1.1.1.7 ! root 7358: to avoid a duplicate warning. Likewise for unterminated comment errors. */ ! 7359: 1.1 root 7360: static U_CHAR * 1.1.1.2 root 7361: skip_to_end_of_comment (ip, line_counter, nowarn) 1.1 root 7362: register FILE_BUF *ip; 7363: int *line_counter; /* place to remember newlines, or NULL */ 1.1.1.2 root 7364: int nowarn; 1.1 root 7365: { 7366: register U_CHAR *limit = ip->buf + ip->length; 7367: register U_CHAR *bp = ip->bufp; 7368: FILE_BUF *op = &outbuf; /* JF */ 7369: int output = put_out_comments && !line_counter; 1.1.1.7 ! root 7370: int start_line = line_counter ? *line_counter : 0; 1.1 root 7371: 7372: /* JF this line_counter stuff is a crock to make sure the 7373: comment is only put out once, no matter how many times 7374: the comment is skipped. It almost works */ 7375: if (output) { 7376: *op->bufp++ = '/'; 7377: *op->bufp++ = '*'; 7378: } 1.1.1.4 root 7379: if (cplusplus_comments && bp[-1] == '/') { 1.1 root 7380: if (output) { 1.1.1.7 ! root 7381: while (bp < limit) { ! 7382: *op->bufp++ = *bp; ! 7383: if (*bp == '\n' && bp[-1] != '\\') 1.1 root 7384: break; 1.1.1.7 ! root 7385: if (*bp == '\n') { ! 7386: ++*line_counter; ! 7387: ++op->lineno; 1.1 root 7388: } 1.1.1.7 ! root 7389: bp++; ! 7390: } 1.1 root 7391: op->bufp[-1] = '*'; 7392: *op->bufp++ = '/'; 7393: *op->bufp++ = '\n'; 7394: } else { 7395: while (bp < limit) { 1.1.1.7 ! root 7396: if (bp[-1] != '\\' && *bp == '\n') { 1.1 root 7397: break; 1.1.1.7 ! root 7398: } else { ! 7399: if (*bp == '\n' && line_counter) ! 7400: ++*line_counter; ! 7401: bp++; 1.1 root 7402: } 7403: } 7404: } 7405: ip->bufp = bp; 7406: return bp; 7407: } 7408: while (bp < limit) { 7409: if (output) 7410: *op->bufp++ = *bp; 7411: switch (*bp++) { 7412: case '/': 1.1.1.2 root 7413: if (warn_comments && !nowarn && bp < limit && *bp == '*') 1.1 root 7414: warning ("`/*' within comment"); 7415: break; 7416: case '\n': 1.1.1.7 ! root 7417: /* If this is the end of the file, we have an unterminated comment. ! 7418: Don't swallow the newline. We are guaranteed that there will be a ! 7419: trailing newline and various pieces assume it's there. */ ! 7420: if (bp == limit) ! 7421: { ! 7422: --bp; ! 7423: --limit; ! 7424: break; ! 7425: } 1.1 root 7426: if (line_counter != NULL) 7427: ++*line_counter; 7428: if (output) 7429: ++op->lineno; 7430: break; 7431: case '*': 7432: if (*bp == '\\' && bp[1] == '\n') 7433: newline_fix (bp); 7434: if (*bp == '/') { 7435: if (output) 7436: *op->bufp++ = '/'; 7437: ip->bufp = ++bp; 7438: return bp; 7439: } 7440: break; 7441: } 7442: } 1.1.1.7 ! root 7443: ! 7444: if (!nowarn) ! 7445: error_with_line (line_for_error (start_line), "unterminated comment"); 1.1 root 7446: ip->bufp = bp; 7447: return bp; 7448: } 7449: 7450: /* 7451: * Skip over a quoted string. BP points to the opening quote. 7452: * Returns a pointer after the closing quote. Don't go past LIMIT. 7453: * START_LINE is the line number of the starting point (but it need 7454: * not be valid if the starting point is inside a macro expansion). 7455: * 7456: * The input stack state is not changed. 7457: * 7458: * If COUNT_NEWLINES is nonzero, it points to an int to increment 7459: * for each newline passed. 7460: * 7461: * If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it 7462: * if we pass a backslash-newline. 7463: * 7464: * If EOFP is nonzero, set *EOFP to 1 if the string is unterminated. 7465: */ 7466: static U_CHAR * 7467: skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp) 7468: register U_CHAR *bp; 7469: register U_CHAR *limit; 7470: int start_line; 7471: int *count_newlines; 7472: int *backslash_newlines_p; 7473: int *eofp; 7474: { 7475: register U_CHAR c, match; 7476: 7477: match = *bp++; 7478: while (1) { 7479: if (bp >= limit) { 7480: error_with_line (line_for_error (start_line), 7481: "unterminated string or character constant"); 1.1.1.5 root 7482: error_with_line (multiline_string_line, 7483: "possible real start of unterminated constant"); 7484: multiline_string_line = 0; 1.1 root 7485: if (eofp) 7486: *eofp = 1; 7487: break; 7488: } 7489: c = *bp++; 7490: if (c == '\\') { 7491: while (*bp == '\\' && bp[1] == '\n') { 7492: if (backslash_newlines_p) 7493: *backslash_newlines_p = 1; 7494: if (count_newlines) 7495: ++*count_newlines; 7496: bp += 2; 7497: } 7498: if (*bp == '\n' && count_newlines) { 7499: if (backslash_newlines_p) 7500: *backslash_newlines_p = 1; 7501: ++*count_newlines; 7502: } 7503: bp++; 7504: } else if (c == '\n') { 7505: if (traditional) { 7506: /* Unterminated strings and character constants are 'legal'. */ 7507: bp--; /* Don't consume the newline. */ 7508: if (eofp) 7509: *eofp = 1; 7510: break; 7511: } 1.1.1.5 root 7512: if (pedantic || match == '\'') { 1.1 root 7513: error_with_line (line_for_error (start_line), 1.1.1.5 root 7514: "unterminated string or character constant"); 1.1 root 7515: bp--; 7516: if (eofp) 7517: *eofp = 1; 7518: break; 7519: } 7520: /* If not traditional, then allow newlines inside strings. */ 7521: if (count_newlines) 7522: ++*count_newlines; 1.1.1.5 root 7523: if (multiline_string_line == 0) 7524: multiline_string_line = start_line; 1.1 root 7525: } else if (c == match) 7526: break; 7527: } 7528: return bp; 7529: } 7530: 1.1.1.6 root 7531: /* Place into DST a quoted string representing the string SRC. 7532: Return the address of DST's terminating null. */ 7533: static char * 7534: quote_string (dst, src) 7535: char *dst, *src; 7536: { 7537: U_CHAR c; 7538: 7539: *dst++ = '\"'; 7540: for (;;) 7541: switch ((c = *src++)) 7542: { 7543: default: 7544: if (isprint (c)) 7545: *dst++ = c; 7546: else 7547: { 7548: sprintf (dst, "\\%03o", c); 7549: dst += 4; 7550: } 7551: break; 7552: 7553: case '\"': 7554: case '\\': 7555: *dst++ = '\\'; 7556: *dst++ = c; 7557: break; 7558: 7559: case '\0': 7560: *dst++ = '\"'; 7561: *dst = '\0'; 7562: return dst; 7563: } 7564: } 7565: 1.1 root 7566: /* Skip across a group of balanced parens, starting from IP->bufp. 7567: IP->bufp is updated. Use this with IP->bufp pointing at an open-paren. 7568: 7569: This does not handle newlines, because it's used for the arg of #if, 1.1.1.2 root 7570: where there aren't any newlines. Also, backslash-newline can't appear. */ 1.1 root 7571: 7572: static U_CHAR * 7573: skip_paren_group (ip) 7574: register FILE_BUF *ip; 7575: { 7576: U_CHAR *limit = ip->buf + ip->length; 7577: U_CHAR *p = ip->bufp; 7578: int depth = 0; 7579: int lines_dummy = 0; 7580: 7581: while (p != limit) { 7582: int c = *p++; 7583: switch (c) { 7584: case '(': 7585: depth++; 7586: break; 7587: 7588: case ')': 7589: depth--; 7590: if (depth == 0) 7591: return ip->bufp = p; 7592: break; 7593: 7594: case '/': 7595: if (*p == '*') { 7596: ip->bufp = p; 1.1.1.2 root 7597: p = skip_to_end_of_comment (ip, &lines_dummy, 0); 1.1 root 7598: p = ip->bufp; 7599: } 7600: 7601: case '"': 7602: case '\'': 7603: { 7604: int eofp = 0; 1.1.1.4 root 7605: p = skip_quoted_string (p - 1, limit, 0, NULL_PTR, NULL_PTR, &eofp); 1.1 root 7606: if (eofp) 7607: return ip->bufp = p; 7608: } 7609: break; 7610: } 7611: } 7612: 7613: ip->bufp = p; 7614: return p; 7615: } 7616: 7617: /* 7618: * write out a #line command, for instance, after an #include file. 7619: * If CONDITIONAL is nonzero, we can omit the #line if it would 7620: * appear to be a no-op, and we can output a few newlines instead 7621: * if we want to increase the line number by a small amount. 7622: * FILE_CHANGE says whether we are entering a file, leaving, or neither. 7623: */ 7624: 7625: static void 7626: output_line_command (ip, op, conditional, file_change) 7627: FILE_BUF *ip, *op; 7628: int conditional; 7629: enum file_change_code file_change; 7630: { 7631: int len; 1.1.1.6 root 7632: char *line_cmd_buf, *line_end; 1.1 root 7633: 7634: if (no_line_commands 7635: || ip->fname == NULL 7636: || no_output) { 7637: op->lineno = ip->lineno; 7638: return; 7639: } 7640: 7641: if (conditional) { 7642: if (ip->lineno == op->lineno) 7643: return; 7644: 7645: /* If the inherited line number is a little too small, 7646: output some newlines instead of a #line command. */ 7647: if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) { 7648: check_expand (op, 10); 7649: while (ip->lineno > op->lineno) { 7650: *op->bufp++ = '\n'; 7651: op->lineno++; 7652: } 7653: return; 7654: } 7655: } 7656: 1.1.1.2 root 7657: /* Don't output a line number of 0 if we can help it. */ 7658: if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length 7659: && *ip->bufp == '\n') { 7660: ip->lineno++; 7661: ip->bufp++; 7662: } 7663: 1.1.1.6 root 7664: line_cmd_buf = (char *) alloca (4 * strlen (ip->nominal_fname) + 100); 1.1 root 7665: #ifdef OUTPUT_LINE_COMMANDS 1.1.1.6 root 7666: sprintf (line_cmd_buf, "#line %d ", ip->lineno); 1.1 root 7667: #else 1.1.1.6 root 7668: sprintf (line_cmd_buf, "# %d ", ip->lineno); 1.1 root 7669: #endif 1.1.1.6 root 7670: line_end = quote_string (line_cmd_buf + strlen (line_cmd_buf), 7671: ip->nominal_fname); 7672: if (file_change != same_file) { 7673: *line_end++ = ' '; 7674: *line_end++ = file_change == enter_file ? '1' : '2'; 7675: } 1.1 root 7676: /* Tell cc1 if following text comes from a system header file. */ 1.1.1.6 root 7677: if (ip->system_header_p) { 7678: *line_end++ = ' '; 7679: *line_end++ = '3'; 7680: } 7681: #ifndef NO_IMPLICIT_EXTERN_C 7682: /* Tell cc1plus if following text should be treated as C. */ 7683: if (ip->system_header_p == 2 && cplusplus) { 7684: *line_end++ = ' '; 7685: *line_end++ = '4'; 7686: } 7687: #endif 7688: *line_end++ = '\n'; 7689: len = line_end - line_cmd_buf; 1.1 root 7690: check_expand (op, len + 1); 7691: if (op->bufp > op->buf && op->bufp[-1] != '\n') 7692: *op->bufp++ = '\n'; 1.1.1.7 ! root 7693: bcopy ((char *) line_cmd_buf, (char *) op->bufp, len); 1.1 root 7694: op->bufp += len; 7695: op->lineno = ip->lineno; 7696: } 7697: 7698: /* This structure represents one parsed argument in a macro call. 7699: `raw' points to the argument text as written (`raw_length' is its length). 7700: `expanded' points to the argument's macro-expansion 7701: (its length is `expand_length'). 7702: `stringified_length' is the length the argument would have 7703: if stringified. 7704: `use_count' is the number of times this macro arg is substituted 7705: into the macro. If the actual use count exceeds 10, 7706: the value stored is 10. 7707: `free1' and `free2', if nonzero, point to blocks to be freed 7708: when the macro argument data is no longer needed. */ 7709: 7710: struct argdata { 7711: U_CHAR *raw, *expanded; 7712: int raw_length, expand_length; 7713: int stringified_length; 7714: U_CHAR *free1, *free2; 7715: char newlines; 7716: char comments; 7717: char use_count; 7718: }; 7719: 7720: /* Expand a macro call. 7721: HP points to the symbol that is the macro being called. 7722: Put the result of expansion onto the input stack 7723: so that subsequent input by our caller will use it. 7724: 7725: If macro wants arguments, caller has already verified that 7726: an argument list follows; arguments come from the input stack. */ 7727: 7728: static void 7729: macroexpand (hp, op) 7730: HASHNODE *hp; 7731: FILE_BUF *op; 7732: { 7733: int nargs; 7734: DEFINITION *defn = hp->value.defn; 7735: register U_CHAR *xbuf; 7736: int xbuf_len; 7737: int start_line = instack[indepth].lineno; 1.1.1.3 root 7738: int rest_args, rest_zero; 1.1 root 7739: 7740: CHECK_DEPTH (return;); 7741: 7742: /* it might not actually be a macro. */ 7743: if (hp->type != T_MACRO) { 7744: special_symbol (hp, op); 7745: return; 7746: } 7747: 7748: /* This macro is being used inside a #if, which means it must be */ 7749: /* recorded as a precondition. */ 7750: if (pcp_inside_if && pcp_outfile && defn->predefined) 7751: dump_single_macro (hp, pcp_outfile); 7752: 7753: nargs = defn->nargs; 7754: 7755: if (nargs >= 0) { 7756: register int i; 7757: struct argdata *args; 7758: char *parse_error = 0; 7759: 7760: args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata)); 7761: 7762: for (i = 0; i < nargs; i++) { 1.1.1.5 root 7763: args[i].raw = (U_CHAR *) ""; 7764: args[i].expanded = 0; 1.1 root 7765: args[i].raw_length = args[i].expand_length 7766: = args[i].stringified_length = 0; 7767: args[i].free1 = args[i].free2 = 0; 7768: args[i].use_count = 0; 7769: } 7770: 7771: /* Parse all the macro args that are supplied. I counts them. 7772: The first NARGS args are stored in ARGS. 1.1.1.3 root 7773: The rest are discarded. 7774: If rest_args is set then we assume macarg absorbed the rest of the args. 7775: */ 1.1 root 7776: i = 0; 1.1.1.3 root 7777: rest_args = 0; 1.1 root 7778: do { 7779: /* Discard the open-parenthesis or comma before the next arg. */ 7780: ++instack[indepth].bufp; 1.1.1.3 root 7781: if (rest_args) 7782: continue; 7783: if (i < nargs || (nargs == 0 && i == 0)) { 1.1.1.4 root 7784: /* if we are working on last arg which absorbs rest of args... */ 1.1.1.3 root 7785: if (i == nargs - 1 && defn->rest_args) 7786: rest_args = 1; 7787: parse_error = macarg (&args[i], rest_args); 7788: } 7789: else 1.1.1.4 root 7790: parse_error = macarg (NULL_PTR, 0); 1.1 root 7791: if (parse_error) { 7792: error_with_line (line_for_error (start_line), parse_error); 7793: break; 7794: } 7795: i++; 7796: } while (*instack[indepth].bufp != ')'); 7797: 7798: /* If we got one arg but it was just whitespace, call that 0 args. */ 7799: if (i == 1) { 7800: register U_CHAR *bp = args[0].raw; 7801: register U_CHAR *lim = bp + args[0].raw_length; 1.1.1.5 root 7802: /* cpp.texi says for foo ( ) we provide one argument. 7803: However, if foo wants just 0 arguments, treat this as 0. */ 7804: if (nargs == 0) 7805: while (bp != lim && is_space[*bp]) bp++; 1.1 root 7806: if (bp == lim) 7807: i = 0; 7808: } 7809: 1.1.1.4 root 7810: /* Don't output an error message if we have already output one for 7811: a parse error above. */ 1.1.1.3 root 7812: rest_zero = 0; 1.1.1.4 root 7813: if (nargs == 0 && i > 0) { 7814: if (! parse_error) 7815: error ("arguments given to macro `%s'", hp->name); 7816: } else if (i < nargs) { 1.1 root 7817: /* traditional C allows foo() if foo wants one argument. */ 7818: if (nargs == 1 && i == 0 && traditional) 7819: ; 1.1.1.3 root 7820: /* the rest args token is allowed to absorb 0 tokens */ 7821: else if (i == nargs - 1 && defn->rest_args) 7822: rest_zero = 1; 1.1.1.4 root 7823: else if (parse_error) 7824: ; 1.1 root 7825: else if (i == 0) 7826: error ("macro `%s' used without args", hp->name); 7827: else if (i == 1) 7828: error ("macro `%s' used with just one arg", hp->name); 7829: else 7830: error ("macro `%s' used with only %d args", hp->name, i); 1.1.1.4 root 7831: } else if (i > nargs) { 7832: if (! parse_error) 7833: error ("macro `%s' used with too many (%d) args", hp->name, i); 7834: } 1.1 root 7835: 7836: /* Swallow the closeparen. */ 7837: ++instack[indepth].bufp; 7838: 7839: /* If macro wants zero args, we parsed the arglist for checking only. 7840: Read directly from the macro definition. */ 7841: if (nargs == 0) { 7842: xbuf = defn->expansion; 7843: xbuf_len = defn->length; 7844: } else { 7845: register U_CHAR *exp = defn->expansion; 7846: register int offset; /* offset in expansion, 7847: copied a piece at a time */ 7848: register int totlen; /* total amount of exp buffer filled so far */ 7849: 1.1.1.3 root 7850: register struct reflist *ap, *last_ap; 1.1 root 7851: 7852: /* Macro really takes args. Compute the expansion of this call. */ 7853: 7854: /* Compute length in characters of the macro's expansion. 7855: Also count number of times each arg is used. */ 7856: xbuf_len = defn->length; 7857: for (ap = defn->pattern; ap != NULL; ap = ap->next) { 7858: if (ap->stringify) 7859: xbuf_len += args[ap->argno].stringified_length; 7860: else if (ap->raw_before || ap->raw_after || traditional) 1.1.1.5 root 7861: /* Add 4 for two newline-space markers to prevent 7862: token concatenation. */ 7863: xbuf_len += args[ap->argno].raw_length + 4; 7864: else { 7865: /* We have an ordinary (expanded) occurrence of the arg. 7866: So compute its expansion, if we have not already. */ 7867: if (args[ap->argno].expanded == 0) { 7868: FILE_BUF obuf; 7869: obuf = expand_to_temp_buffer (args[ap->argno].raw, 7870: args[ap->argno].raw + args[ap->argno].raw_length, 7871: 1, 0); 7872: 7873: args[ap->argno].expanded = obuf.buf; 7874: args[ap->argno].expand_length = obuf.length; 7875: args[ap->argno].free2 = obuf.buf; 7876: } 7877: 7878: /* Add 4 for two newline-space markers to prevent 7879: token concatenation. */ 7880: xbuf_len += args[ap->argno].expand_length + 4; 7881: } 1.1 root 7882: if (args[ap->argno].use_count < 10) 7883: args[ap->argno].use_count++; 7884: } 7885: 7886: xbuf = (U_CHAR *) xmalloc (xbuf_len + 1); 7887: 7888: /* Generate in XBUF the complete expansion 7889: with arguments substituted in. 7890: TOTLEN is the total size generated so far. 7891: OFFSET is the index in the definition 7892: of where we are copying from. */ 7893: offset = totlen = 0; 1.1.1.3 root 7894: for (last_ap = NULL, ap = defn->pattern; ap != NULL; 7895: last_ap = ap, ap = ap->next) { 1.1 root 7896: register struct argdata *arg = &args[ap->argno]; 1.1.1.5 root 7897: int count_before = totlen; 1.1 root 7898: 1.1.1.5 root 7899: /* Add chars to XBUF. */ 1.1.1.3 root 7900: for (i = 0; i < ap->nchars; i++, offset++) 1.1.1.5 root 7901: xbuf[totlen++] = exp[offset]; 7902: 7903: /* If followed by an empty rest arg with concatenation, 7904: delete the last run of nonwhite chars. */ 7905: if (rest_zero && totlen > count_before 7906: && ((ap->rest_args && ap->raw_before) 7907: || (last_ap != NULL && last_ap->rest_args 7908: && last_ap->raw_after))) { 7909: /* Delete final whitespace. */ 7910: while (totlen > count_before && is_space[xbuf[totlen - 1]]) { 7911: totlen--; 7912: } 7913: 7914: /* Delete the nonwhites before them. */ 7915: while (totlen > count_before && ! is_space[xbuf[totlen - 1]]) { 7916: totlen--; 7917: } 7918: } 1.1 root 7919: 7920: if (ap->stringify != 0) { 7921: int arglen = arg->raw_length; 7922: int escaped = 0; 7923: int in_string = 0; 7924: int c; 7925: i = 0; 7926: while (i < arglen 7927: && (c = arg->raw[i], is_space[c])) 7928: i++; 7929: while (i < arglen 7930: && (c = arg->raw[arglen - 1], is_space[c])) 7931: arglen--; 7932: if (!traditional) 7933: xbuf[totlen++] = '\"'; /* insert beginning quote */ 7934: for (; i < arglen; i++) { 7935: c = arg->raw[i]; 7936: 7937: /* Special markers Newline Space 7938: generate nothing for a stringified argument. */ 7939: if (c == '\n' && arg->raw[i+1] != '\n') { 7940: i++; 7941: continue; 7942: } 7943: 7944: /* Internal sequences of whitespace are replaced by one space 7945: except within an string or char token. */ 7946: if (! in_string 7947: && (c == '\n' ? arg->raw[i+1] == '\n' : is_space[c])) { 7948: while (1) { 7949: /* Note that Newline Space does occur within whitespace 7950: sequences; consider it part of the sequence. */ 7951: if (c == '\n' && is_space[arg->raw[i+1]]) 7952: i += 2; 7953: else if (c != '\n' && is_space[c]) 7954: i++; 7955: else break; 7956: c = arg->raw[i]; 7957: } 7958: i--; 7959: c = ' '; 7960: } 7961: 7962: if (escaped) 7963: escaped = 0; 7964: else { 7965: if (c == '\\') 7966: escaped = 1; 7967: if (in_string) { 7968: if (c == in_string) 7969: in_string = 0; 7970: } else if (c == '\"' || c == '\'') 7971: in_string = c; 7972: } 7973: 7974: /* Escape these chars */ 7975: if (c == '\"' || (in_string && c == '\\')) 7976: xbuf[totlen++] = '\\'; 7977: if (isprint (c)) 7978: xbuf[totlen++] = c; 7979: else { 7980: sprintf ((char *) &xbuf[totlen], "\\%03o", (unsigned int) c); 7981: totlen += 4; 7982: } 7983: } 7984: if (!traditional) 7985: xbuf[totlen++] = '\"'; /* insert ending quote */ 7986: } else if (ap->raw_before || ap->raw_after || traditional) { 7987: U_CHAR *p1 = arg->raw; 7988: U_CHAR *l1 = p1 + arg->raw_length; 7989: if (ap->raw_before) { 7990: while (p1 != l1 && is_space[*p1]) p1++; 7991: while (p1 != l1 && is_idchar[*p1]) 7992: xbuf[totlen++] = *p1++; 7993: /* Delete any no-reexpansion marker that follows 7994: an identifier at the beginning of the argument 7995: if the argument is concatenated with what precedes it. */ 7996: if (p1[0] == '\n' && p1[1] == '-') 7997: p1 += 2; 1.1.1.5 root 7998: } else if (!traditional) { 7999: /* Ordinary expanded use of the argument. 8000: Put in newline-space markers to prevent token pasting. */ 8001: xbuf[totlen++] = '\n'; 8002: xbuf[totlen++] = ' '; 1.1 root 8003: } 8004: if (ap->raw_after) { 8005: /* Arg is concatenated after: delete trailing whitespace, 8006: whitespace markers, and no-reexpansion markers. */ 8007: while (p1 != l1) { 8008: if (is_space[l1[-1]]) l1--; 8009: else if (l1[-1] == '-') { 8010: U_CHAR *p2 = l1 - 1; 8011: /* If a `-' is preceded by an odd number of newlines then it 8012: and the last newline are a no-reexpansion marker. */ 8013: while (p2 != p1 && p2[-1] == '\n') p2--; 8014: if ((l1 - 1 - p2) & 1) { 8015: l1 -= 2; 8016: } 8017: else break; 8018: } 8019: else break; 8020: } 8021: } 1.1.1.5 root 8022: 1.1.1.7 ! root 8023: bcopy ((char *) p1, (char *) (xbuf + totlen), l1 - p1); 1.1 root 8024: totlen += l1 - p1; 1.1.1.5 root 8025: if (!traditional && !ap->raw_after) { 8026: /* Ordinary expanded use of the argument. 8027: Put in newline-space markers to prevent token pasting. */ 8028: xbuf[totlen++] = '\n'; 8029: xbuf[totlen++] = ' '; 8030: } 1.1 root 8031: } else { 1.1.1.5 root 8032: /* Ordinary expanded use of the argument. 8033: Put in newline-space markers to prevent token pasting. */ 8034: if (!traditional) { 8035: xbuf[totlen++] = '\n'; 8036: xbuf[totlen++] = ' '; 8037: } 1.1.1.7 ! root 8038: bcopy ((char *) arg->expanded, (char *) (xbuf + totlen), ! 8039: arg->expand_length); 1.1 root 8040: totlen += arg->expand_length; 1.1.1.5 root 8041: if (!traditional) { 8042: xbuf[totlen++] = '\n'; 8043: xbuf[totlen++] = ' '; 8044: } 1.1 root 8045: /* If a macro argument with newlines is used multiple times, 8046: then only expand the newlines once. This avoids creating output 8047: lines which don't correspond to any input line, which confuses 8048: gdb and gcov. */ 8049: if (arg->use_count > 1 && arg->newlines > 0) { 1.1.1.5 root 8050: /* Don't bother doing change_newlines for subsequent 1.1 root 8051: uses of arg. */ 8052: arg->use_count = 1; 8053: arg->expand_length 1.1.1.5 root 8054: = change_newlines (arg->expanded, arg->expand_length); 1.1 root 8055: } 8056: } 8057: 8058: if (totlen > xbuf_len) 8059: abort (); 8060: } 8061: 8062: /* if there is anything left of the definition 8063: after handling the arg list, copy that in too. */ 8064: 1.1.1.3 root 8065: for (i = offset; i < defn->length; i++) { 8066: /* if we've reached the end of the macro */ 8067: if (exp[i] == ')') 8068: rest_zero = 0; 8069: if (! (rest_zero && last_ap != NULL && last_ap->rest_args 8070: && last_ap->raw_after)) 8071: xbuf[totlen++] = exp[i]; 8072: } 1.1 root 8073: 8074: xbuf[totlen] = 0; 8075: xbuf_len = totlen; 8076: 8077: for (i = 0; i < nargs; i++) { 8078: if (args[i].free1 != 0) 8079: free (args[i].free1); 8080: if (args[i].free2 != 0) 8081: free (args[i].free2); 8082: } 8083: } 8084: } else { 8085: xbuf = defn->expansion; 8086: xbuf_len = defn->length; 8087: } 8088: 8089: /* Now put the expansion on the input stack 8090: so our caller will commence reading from it. */ 8091: { 8092: register FILE_BUF *ip2; 8093: 8094: ip2 = &instack[++indepth]; 8095: 8096: ip2->fname = 0; 8097: ip2->nominal_fname = 0; 1.1.1.7 ! root 8098: /* This may not be exactly correct, but will give much better error ! 8099: messages for nested macro calls than using a line number of zero. */ ! 8100: ip2->lineno = start_line; 1.1 root 8101: ip2->buf = xbuf; 8102: ip2->length = xbuf_len; 8103: ip2->bufp = xbuf; 8104: ip2->free_ptr = (nargs > 0) ? xbuf : 0; 8105: ip2->macro = hp; 8106: ip2->if_stack = if_stack; 8107: ip2->system_header_p = 0; 8108: 8109: /* Recursive macro use sometimes works traditionally. 1.1.1.5 root 8110: #define foo(x,y) bar (x (y,0), y) 8111: foo (foo, baz) */ 1.1 root 8112: 8113: if (!traditional) 8114: hp->type = T_DISABLED; 8115: } 8116: } 8117: 8118: /* 8119: * Parse a macro argument and store the info on it into *ARGPTR. 1.1.1.3 root 8120: * REST_ARGS is passed to macarg1 to make it absorb the rest of the args. 1.1 root 8121: * Return nonzero to indicate a syntax error. 8122: */ 8123: 8124: static char * 1.1.1.3 root 8125: macarg (argptr, rest_args) 1.1 root 8126: register struct argdata *argptr; 1.1.1.3 root 8127: int rest_args; 1.1 root 8128: { 8129: FILE_BUF *ip = &instack[indepth]; 8130: int paren = 0; 8131: int newlines = 0; 8132: int comments = 0; 8133: 8134: /* Try to parse as much of the argument as exists at this 8135: input stack level. */ 8136: U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length, 1.1.1.3 root 8137: &paren, &newlines, &comments, rest_args); 1.1 root 8138: 8139: /* If we find the end of the argument at this level, 8140: set up *ARGPTR to point at it in the input stack. */ 8141: if (!(ip->fname != 0 && (newlines != 0 || comments != 0)) 8142: && bp != ip->buf + ip->length) { 8143: if (argptr != 0) { 8144: argptr->raw = ip->bufp; 8145: argptr->raw_length = bp - ip->bufp; 8146: argptr->newlines = newlines; 8147: } 8148: ip->bufp = bp; 8149: } else { 8150: /* This input stack level ends before the macro argument does. 8151: We must pop levels and keep parsing. 8152: Therefore, we must allocate a temporary buffer and copy 8153: the macro argument into it. */ 8154: int bufsize = bp - ip->bufp; 8155: int extra = newlines; 8156: U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1); 8157: int final_start = 0; 8158: 1.1.1.7 ! root 8159: bcopy ((char *) ip->bufp, (char *) buffer, bufsize); 1.1 root 8160: ip->bufp = bp; 8161: ip->lineno += newlines; 8162: 8163: while (bp == ip->buf + ip->length) { 8164: if (instack[indepth].macro == 0) { 8165: free (buffer); 8166: return "unterminated macro call"; 8167: } 8168: ip->macro->type = T_MACRO; 8169: if (ip->free_ptr) 8170: free (ip->free_ptr); 8171: ip = &instack[--indepth]; 8172: newlines = 0; 8173: comments = 0; 8174: bp = macarg1 (ip->bufp, ip->buf + ip->length, &paren, 1.1.1.3 root 8175: &newlines, &comments, rest_args); 1.1 root 8176: final_start = bufsize; 8177: bufsize += bp - ip->bufp; 8178: extra += newlines; 8179: buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1); 1.1.1.7 ! root 8180: bcopy ((char *) ip->bufp, (char *) (buffer + bufsize - (bp - ip->bufp)), ! 8181: bp - ip->bufp); 1.1 root 8182: ip->bufp = bp; 8183: ip->lineno += newlines; 8184: } 8185: 8186: /* Now, if arg is actually wanted, record its raw form, 8187: discarding comments and duplicating newlines in whatever 8188: part of it did not come from a macro expansion. 8189: EXTRA space has been preallocated for duplicating the newlines. 8190: FINAL_START is the index of the start of that part. */ 8191: if (argptr != 0) { 8192: argptr->raw = buffer; 8193: argptr->raw_length = bufsize; 8194: argptr->free1 = buffer; 8195: argptr->newlines = newlines; 8196: argptr->comments = comments; 8197: if ((newlines || comments) && ip->fname != 0) 8198: argptr->raw_length 8199: = final_start + 8200: discard_comments (argptr->raw + final_start, 8201: argptr->raw_length - final_start, 8202: newlines); 8203: argptr->raw[argptr->raw_length] = 0; 8204: if (argptr->raw_length > bufsize + extra) 8205: abort (); 8206: } 8207: } 8208: 8209: /* If we are not discarding this argument, 8210: macroexpand it and compute its length as stringified. 8211: All this info goes into *ARGPTR. */ 8212: 8213: if (argptr != 0) { 8214: register U_CHAR *buf, *lim; 8215: register int totlen; 8216: 8217: buf = argptr->raw; 8218: lim = buf + argptr->raw_length; 8219: 8220: while (buf != lim && is_space[*buf]) 8221: buf++; 8222: while (buf != lim && is_space[lim[-1]]) 8223: lim--; 8224: totlen = traditional ? 0 : 2; /* Count opening and closing quote. */ 8225: while (buf != lim) { 8226: register U_CHAR c = *buf++; 8227: totlen++; 8228: /* Internal sequences of whitespace are replaced by one space 8229: in most cases, but not always. So count all the whitespace 8230: in case we need to keep it all. */ 8231: #if 0 8232: if (is_space[c]) 8233: SKIP_ALL_WHITE_SPACE (buf); 8234: else 8235: #endif 8236: if (c == '\"' || c == '\\') /* escape these chars */ 8237: totlen++; 8238: else if (!isprint (c)) 8239: totlen += 3; 8240: } 8241: argptr->stringified_length = totlen; 8242: } 8243: return 0; 8244: } 8245: 8246: /* Scan text from START (inclusive) up to LIMIT (exclusive), 8247: counting parens in *DEPTHPTR, 8248: and return if reach LIMIT 8249: or before a `)' that would make *DEPTHPTR negative 8250: or before a comma when *DEPTHPTR is zero. 8251: Single and double quotes are matched and termination 8252: is inhibited within them. Comments also inhibit it. 8253: Value returned is pointer to stopping place. 8254: 8255: Increment *NEWLINES each time a newline is passed. 1.1.1.3 root 8256: REST_ARGS notifies macarg1 that it should absorb the rest of the args. 1.1 root 8257: Set *COMMENTS to 1 if a comment is seen. */ 8258: 8259: static U_CHAR * 1.1.1.3 root 8260: macarg1 (start, limit, depthptr, newlines, comments, rest_args) 1.1 root 8261: U_CHAR *start; 8262: register U_CHAR *limit; 8263: int *depthptr, *newlines, *comments; 1.1.1.3 root 8264: int rest_args; 1.1 root 8265: { 8266: register U_CHAR *bp = start; 8267: 8268: while (bp < limit) { 8269: switch (*bp) { 8270: case '(': 8271: (*depthptr)++; 8272: break; 8273: case ')': 8274: if (--(*depthptr) < 0) 8275: return bp; 8276: break; 8277: case '\\': 8278: /* Traditionally, backslash makes following char not special. */ 8279: if (bp + 1 < limit && traditional) 8280: { 8281: bp++; 8282: /* But count source lines anyway. */ 8283: if (*bp == '\n') 8284: ++*newlines; 8285: } 8286: break; 8287: case '\n': 8288: ++*newlines; 8289: break; 8290: case '/': 8291: if (bp[1] == '\\' && bp[2] == '\n') 8292: newline_fix (bp + 1); 1.1.1.4 root 8293: if (cplusplus_comments && bp[1] == '/') { 1.1 root 8294: *comments = 1; 8295: bp += 2; 1.1.1.7 ! root 8296: while (bp < limit && (*bp != '\n' || bp[-1] == '\\')) { ! 8297: if (*bp == '\n') ++*newlines; ! 8298: bp++; ! 8299: } 1.1 root 8300: break; 8301: } 8302: if (bp[1] != '*' || bp + 1 >= limit) 8303: break; 8304: *comments = 1; 8305: bp += 2; 8306: while (bp + 1 < limit) { 8307: if (bp[0] == '*' 8308: && bp[1] == '\\' && bp[2] == '\n') 8309: newline_fix (bp + 1); 8310: if (bp[0] == '*' && bp[1] == '/') 8311: break; 8312: if (*bp == '\n') ++*newlines; 8313: bp++; 8314: } 8315: break; 8316: case '\'': 8317: case '\"': 8318: { 8319: int quotec; 8320: for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) { 8321: if (*bp == '\\') { 8322: bp++; 8323: if (*bp == '\n') 8324: ++*newlines; 8325: while (*bp == '\\' && bp[1] == '\n') { 8326: bp += 2; 8327: } 8328: } else if (*bp == '\n') { 8329: ++*newlines; 8330: if (quotec == '\'') 8331: break; 8332: } 8333: } 8334: } 8335: break; 8336: case ',': 1.1.1.3 root 8337: /* if we've returned to lowest level and we aren't absorbing all args */ 8338: if ((*depthptr) == 0 && rest_args == 0) 1.1 root 8339: return bp; 8340: break; 8341: } 8342: bp++; 8343: } 8344: 8345: return bp; 8346: } 8347: 8348: /* Discard comments and duplicate newlines 8349: in the string of length LENGTH at START, 8350: except inside of string constants. 8351: The string is copied into itself with its beginning staying fixed. 8352: 8353: NEWLINES is the number of newlines that must be duplicated. 8354: We assume that that much extra space is available past the end 8355: of the string. */ 8356: 8357: static int 8358: discard_comments (start, length, newlines) 8359: U_CHAR *start; 8360: int length; 8361: int newlines; 8362: { 8363: register U_CHAR *ibp; 8364: register U_CHAR *obp; 8365: register U_CHAR *limit; 8366: register int c; 8367: 8368: /* If we have newlines to duplicate, copy everything 8369: that many characters up. Then, in the second part, 8370: we will have room to insert the newlines 8371: while copying down. 8372: NEWLINES may actually be too large, because it counts 8373: newlines in string constants, and we don't duplicate those. 8374: But that does no harm. */ 8375: if (newlines > 0) { 8376: ibp = start + length; 8377: obp = ibp + newlines; 8378: limit = start; 8379: while (limit != ibp) 8380: *--obp = *--ibp; 8381: } 8382: 8383: ibp = start + newlines; 8384: limit = start + length + newlines; 8385: obp = start; 8386: 8387: while (ibp < limit) { 8388: *obp++ = c = *ibp++; 8389: switch (c) { 8390: case '\n': 8391: /* Duplicate the newline. */ 8392: *obp++ = '\n'; 8393: break; 8394: 8395: case '\\': 8396: if (*ibp == '\n') { 8397: obp--; 8398: ibp++; 8399: } 8400: break; 8401: 8402: case '/': 8403: if (*ibp == '\\' && ibp[1] == '\n') 8404: newline_fix (ibp); 8405: /* Delete any comment. */ 1.1.1.4 root 8406: if (cplusplus_comments && ibp[0] == '/') { 1.1.1.7 ! root 8407: /* Comments are equivalent to spaces. */ ! 8408: obp[-1] = ' '; 1.1 root 8409: ibp++; 1.1.1.7 ! root 8410: while (ibp < limit && (*ibp != '\n' || ibp[-1] == '\\')) ! 8411: ibp++; 1.1 root 8412: break; 8413: } 8414: if (ibp[0] != '*' || ibp + 1 >= limit) 8415: break; 1.1.1.7 ! root 8416: /* Comments are equivalent to spaces. */ ! 8417: obp[-1] = ' '; 1.1 root 8418: ibp++; 8419: while (ibp + 1 < limit) { 8420: if (ibp[0] == '*' 8421: && ibp[1] == '\\' && ibp[2] == '\n') 8422: newline_fix (ibp + 1); 8423: if (ibp[0] == '*' && ibp[1] == '/') 8424: break; 8425: ibp++; 8426: } 8427: ibp += 2; 8428: break; 8429: 8430: case '\'': 8431: case '\"': 8432: /* Notice and skip strings, so that we don't 8433: think that comments start inside them, 8434: and so we don't duplicate newlines in them. */ 8435: { 8436: int quotec = c; 8437: while (ibp < limit) { 8438: *obp++ = c = *ibp++; 8439: if (c == quotec) 8440: break; 8441: if (c == '\n' && quotec == '\'') 8442: break; 8443: if (c == '\\' && ibp < limit) { 8444: while (*ibp == '\\' && ibp[1] == '\n') 8445: ibp += 2; 8446: *obp++ = *ibp++; 8447: } 8448: } 8449: } 8450: break; 8451: } 8452: } 8453: 8454: return obp - start; 8455: } 8456: 1.1.1.5 root 8457: /* Turn newlines to spaces in the string of length LENGTH at START, 8458: except inside of string constants. 8459: The string is copied into itself with its beginning staying fixed. */ 1.1 root 8460: 8461: static int 1.1.1.5 root 8462: change_newlines (start, length) 1.1 root 8463: U_CHAR *start; 8464: int length; 8465: { 8466: register U_CHAR *ibp; 8467: register U_CHAR *obp; 8468: register U_CHAR *limit; 8469: register int c; 8470: 8471: ibp = start; 8472: limit = start + length; 8473: obp = start; 8474: 8475: while (ibp < limit) { 8476: *obp++ = c = *ibp++; 8477: switch (c) { 8478: case '\n': 8479: /* If this is a NEWLINE NEWLINE, then this is a real newline in the 1.1.1.5 root 8480: string. Skip past the newline and its duplicate. 8481: Put a space in the output. */ 1.1 root 8482: if (*ibp == '\n') 8483: { 8484: ibp++; 8485: obp--; 1.1.1.5 root 8486: *obp++ = ' '; 1.1 root 8487: } 8488: break; 8489: 8490: case '\'': 8491: case '\"': 8492: /* Notice and skip strings, so that we don't delete newlines in them. */ 8493: { 8494: int quotec = c; 8495: while (ibp < limit) { 8496: *obp++ = c = *ibp++; 8497: if (c == quotec) 8498: break; 8499: if (c == '\n' && quotec == '\'') 8500: break; 8501: } 8502: } 8503: break; 8504: } 8505: } 8506: 8507: return obp - start; 8508: } 8509: 8510: /* 1.1.1.7 ! root 8511: * my_strerror - return the descriptive text associated with an `errno' code. ! 8512: */ ! 8513: ! 8514: char * ! 8515: my_strerror (errnum) ! 8516: int errnum; ! 8517: { ! 8518: char *result; ! 8519: ! 8520: #ifndef VMS ! 8521: #ifndef HAVE_STRERROR ! 8522: result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0); ! 8523: #else ! 8524: result = strerror (errnum); ! 8525: #endif ! 8526: #else /* VMS */ ! 8527: /* VAXCRTL's strerror() takes an optional second argument, which only ! 8528: matters when the first argument is EVMSERR. However, it's simplest ! 8529: just to pass it unconditionally. `vaxc$errno' is declared in ! 8530: <errno.h>, and maintained by the library in parallel with `errno'. ! 8531: We assume that caller's `errnum' either matches the last setting of ! 8532: `errno' by the library or else does not have the value `EVMSERR'. */ ! 8533: ! 8534: result = strerror (errnum, vaxc$errno); ! 8535: #endif ! 8536: ! 8537: if (!result) ! 8538: result = "undocumented I/O error"; ! 8539: ! 8540: return result; ! 8541: } ! 8542: ! 8543: /* 1.1 root 8544: * error - print error message and increment count of errors. 8545: */ 8546: 8547: void 8548: error (msg, arg1, arg2, arg3) 8549: char *msg; 1.1.1.4 root 8550: char *arg1, *arg2, *arg3; 1.1 root 8551: { 8552: int i; 8553: FILE_BUF *ip = NULL; 8554: 8555: print_containing_files (); 8556: 8557: for (i = indepth; i >= 0; i--) 8558: if (instack[i].fname != NULL) { 8559: ip = &instack[i]; 8560: break; 8561: } 8562: 8563: if (ip != NULL) 8564: fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno); 8565: fprintf (stderr, msg, arg1, arg2, arg3); 8566: fprintf (stderr, "\n"); 8567: errors++; 8568: } 8569: 8570: /* Error including a message from `errno'. */ 8571: 8572: static void 8573: error_from_errno (name) 8574: char *name; 8575: { 8576: int i; 8577: FILE_BUF *ip = NULL; 8578: 8579: print_containing_files (); 8580: 8581: for (i = indepth; i >= 0; i--) 8582: if (instack[i].fname != NULL) { 8583: ip = &instack[i]; 8584: break; 8585: } 8586: 8587: if (ip != NULL) 8588: fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno); 8589: 1.1.1.7 ! root 8590: fprintf (stderr, "%s: %s\n", name, my_strerror (errno)); 1.1 root 8591: 8592: errors++; 8593: } 8594: 8595: /* Print error message but don't count it. */ 8596: 8597: void 8598: warning (msg, arg1, arg2, arg3) 8599: char *msg; 1.1.1.4 root 8600: char *arg1, *arg2, *arg3; 1.1 root 8601: { 8602: int i; 8603: FILE_BUF *ip = NULL; 8604: 8605: if (inhibit_warnings) 8606: return; 8607: 8608: if (warnings_are_errors) 8609: errors++; 8610: 8611: print_containing_files (); 8612: 8613: for (i = indepth; i >= 0; i--) 8614: if (instack[i].fname != NULL) { 8615: ip = &instack[i]; 8616: break; 8617: } 8618: 8619: if (ip != NULL) 8620: fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno); 8621: fprintf (stderr, "warning: "); 8622: fprintf (stderr, msg, arg1, arg2, arg3); 8623: fprintf (stderr, "\n"); 8624: } 8625: 8626: static void 8627: error_with_line (line, msg, arg1, arg2, arg3) 8628: int line; 8629: char *msg; 1.1.1.4 root 8630: char *arg1, *arg2, *arg3; 1.1 root 8631: { 8632: int i; 8633: FILE_BUF *ip = NULL; 8634: 8635: print_containing_files (); 8636: 8637: for (i = indepth; i >= 0; i--) 8638: if (instack[i].fname != NULL) { 8639: ip = &instack[i]; 8640: break; 8641: } 8642: 8643: if (ip != NULL) 8644: fprintf (stderr, "%s:%d: ", ip->nominal_fname, line); 8645: fprintf (stderr, msg, arg1, arg2, arg3); 8646: fprintf (stderr, "\n"); 8647: errors++; 8648: } 8649: 1.1.1.5 root 8650: static void 8651: warning_with_line (line, msg, arg1, arg2, arg3) 8652: int line; 8653: char *msg; 8654: char *arg1, *arg2, *arg3; 8655: { 8656: int i; 8657: FILE_BUF *ip = NULL; 8658: 8659: if (inhibit_warnings) 8660: return; 8661: 8662: if (warnings_are_errors) 8663: errors++; 8664: 8665: print_containing_files (); 8666: 8667: for (i = indepth; i >= 0; i--) 8668: if (instack[i].fname != NULL) { 8669: ip = &instack[i]; 8670: break; 8671: } 8672: 8673: if (ip != NULL) 8674: fprintf (stderr, "%s:%d: ", ip->nominal_fname, line); 8675: fprintf (stderr, "warning: "); 8676: fprintf (stderr, msg, arg1, arg2, arg3); 8677: fprintf (stderr, "\n"); 8678: } 8679: 1.1 root 8680: /* print an error message and maybe count it. */ 8681: 8682: void 8683: pedwarn (msg, arg1, arg2, arg3) 8684: char *msg; 1.1.1.4 root 8685: char *arg1, *arg2, *arg3; 1.1 root 8686: { 8687: if (pedantic_errors) 8688: error (msg, arg1, arg2, arg3); 8689: else 8690: warning (msg, arg1, arg2, arg3); 8691: } 8692: 1.1.1.5 root 8693: void 8694: pedwarn_with_line (line, msg, arg1, arg2, arg3) 8695: int line; 8696: char *msg; 8697: char *arg1, *arg2, *arg3; 8698: { 8699: if (pedantic_errors) 8700: error_with_line (line, msg, arg1, arg2, arg3); 8701: else 8702: warning_with_line (line, msg, arg1, arg2, arg3); 8703: } 8704: 1.1 root 8705: /* Report a warning (or an error if pedantic_errors) 8706: giving specified file name and line number, not current. */ 8707: 8708: static void 8709: pedwarn_with_file_and_line (file, line, msg, arg1, arg2, arg3) 8710: char *file; 8711: int line; 8712: char *msg; 1.1.1.4 root 8713: char *arg1, *arg2, *arg3; 1.1 root 8714: { 8715: if (!pedantic_errors && inhibit_warnings) 8716: return; 8717: if (file != NULL) 8718: fprintf (stderr, "%s:%d: ", file, line); 1.1.1.5 root 8719: if (pedantic_errors) 1.1 root 8720: errors++; 8721: if (!pedantic_errors) 8722: fprintf (stderr, "warning: "); 8723: fprintf (stderr, msg, arg1, arg2, arg3); 8724: fprintf (stderr, "\n"); 8725: } 8726: 8727: /* Print the file names and line numbers of the #include 8728: commands which led to the current file. */ 8729: 8730: static void 8731: print_containing_files () 8732: { 8733: FILE_BUF *ip = NULL; 8734: int i; 8735: int first = 1; 8736: 8737: /* If stack of files hasn't changed since we last printed 8738: this info, don't repeat it. */ 8739: if (last_error_tick == input_file_stack_tick) 8740: return; 8741: 8742: for (i = indepth; i >= 0; i--) 8743: if (instack[i].fname != NULL) { 8744: ip = &instack[i]; 8745: break; 8746: } 8747: 8748: /* Give up if we don't find a source file. */ 8749: if (ip == NULL) 8750: return; 8751: 8752: /* Find the other, outer source files. */ 8753: for (i--; i >= 0; i--) 8754: if (instack[i].fname != NULL) { 8755: ip = &instack[i]; 8756: if (first) { 8757: first = 0; 8758: fprintf (stderr, "In file included"); 8759: } else { 1.1.1.6 root 8760: fprintf (stderr, ",\n "); 1.1 root 8761: } 8762: 8763: fprintf (stderr, " from %s:%d", ip->nominal_fname, ip->lineno); 8764: } 8765: if (! first) 8766: fprintf (stderr, ":\n"); 8767: 8768: /* Record we have printed the status as of this time. */ 8769: last_error_tick = input_file_stack_tick; 8770: } 8771: 8772: /* Return the line at which an error occurred. 8773: The error is not necessarily associated with the current spot 8774: in the input stack, so LINE says where. LINE will have been 8775: copied from ip->lineno for the current input level. 8776: If the current level is for a file, we return LINE. 8777: But if the current level is not for a file, LINE is meaningless. 8778: In that case, we return the lineno of the innermost file. */ 8779: 8780: static int 8781: line_for_error (line) 8782: int line; 8783: { 8784: int i; 8785: int line1 = line; 8786: 8787: for (i = indepth; i >= 0; ) { 8788: if (instack[i].fname != 0) 8789: return line1; 8790: i--; 8791: if (i < 0) 8792: return 0; 8793: line1 = instack[i].lineno; 8794: } 8795: abort (); 8796: /*NOTREACHED*/ 8797: return 0; 8798: } 8799: 8800: /* 8801: * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger. 8802: * 8803: * As things stand, nothing is ever placed in the output buffer to be 8804: * removed again except when it's KNOWN to be part of an identifier, 8805: * so flushing and moving down everything left, instead of expanding, 8806: * should work ok. 8807: */ 8808: 8809: /* You might think void was cleaner for the return type, 8810: but that would get type mismatch in check_expand in strict ANSI. */ 8811: static int 8812: grow_outbuf (obuf, needed) 8813: register FILE_BUF *obuf; 8814: register int needed; 8815: { 8816: register U_CHAR *p; 8817: int minsize; 8818: 8819: if (obuf->length - (obuf->bufp - obuf->buf) > needed) 8820: return 0; 8821: 8822: /* Make it at least twice as big as it is now. */ 8823: obuf->length *= 2; 8824: /* Make it have at least 150% of the free space we will need. */ 8825: minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf); 8826: if (minsize > obuf->length) 8827: obuf->length = minsize; 8828: 8829: if ((p = (U_CHAR *) xrealloc (obuf->buf, obuf->length)) == NULL) 8830: memory_full (); 8831: 8832: obuf->bufp = p + (obuf->bufp - obuf->buf); 8833: obuf->buf = p; 8834: 8835: return 0; 8836: } 8837: 8838: /* Symbol table for macro names and special symbols */ 8839: 8840: /* 8841: * install a name in the main hash table, even if it is already there. 8842: * name stops with first non alphanumeric, except leading '#'. 8843: * caller must check against redefinition if that is desired. 8844: * delete_macro () removes things installed by install () in fifo order. 8845: * this is important because of the `defined' special symbol used 8846: * in #if, and also if pushdef/popdef directives are ever implemented. 8847: * 8848: * If LEN is >= 0, it is the length of the name. 8849: * Otherwise, compute the length by scanning the entire name. 8850: * 8851: * If HASH is >= 0, it is the precomputed hash code. 8852: * Otherwise, compute the hash code. 8853: */ 8854: static HASHNODE * 1.1.1.4 root 8855: install (name, len, type, ivalue, value, hash) 1.1 root 8856: U_CHAR *name; 8857: int len; 8858: enum node_type type; 1.1.1.4 root 8859: int ivalue; 8860: char *value; 1.1 root 8861: int hash; 8862: { 8863: register HASHNODE *hp; 8864: register int i, bucket; 8865: register U_CHAR *p, *q; 8866: 8867: if (len < 0) { 8868: p = name; 8869: while (is_idchar[*p]) 8870: p++; 8871: len = p - name; 8872: } 8873: 8874: if (hash < 0) 8875: hash = hashf (name, len, HASHSIZE); 8876: 8877: i = sizeof (HASHNODE) + len + 1; 8878: hp = (HASHNODE *) xmalloc (i); 8879: bucket = hash; 8880: hp->bucket_hdr = &hashtab[bucket]; 8881: hp->next = hashtab[bucket]; 8882: hashtab[bucket] = hp; 8883: hp->prev = NULL; 8884: if (hp->next != NULL) 8885: hp->next->prev = hp; 8886: hp->type = type; 8887: hp->length = len; 1.1.1.4 root 8888: if (hp->type == T_CONST) 8889: hp->value.ival = ivalue; 8890: else 8891: hp->value.cpval = value; 1.1 root 8892: hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE); 8893: p = hp->name; 8894: q = name; 8895: for (i = 0; i < len; i++) 8896: *p++ = *q++; 8897: hp->name[len] = 0; 8898: return hp; 8899: } 8900: 8901: /* 8902: * find the most recent hash node for name name (ending with first 8903: * non-identifier char) installed by install 8904: * 8905: * If LEN is >= 0, it is the length of the name. 8906: * Otherwise, compute the length by scanning the entire name. 8907: * 8908: * If HASH is >= 0, it is the precomputed hash code. 8909: * Otherwise, compute the hash code. 8910: */ 8911: HASHNODE * 8912: lookup (name, len, hash) 8913: U_CHAR *name; 8914: int len; 8915: int hash; 8916: { 8917: register U_CHAR *bp; 8918: register HASHNODE *bucket; 8919: 8920: if (len < 0) { 8921: for (bp = name; is_idchar[*bp]; bp++) ; 8922: len = bp - name; 8923: } 8924: 8925: if (hash < 0) 8926: hash = hashf (name, len, HASHSIZE); 8927: 8928: bucket = hashtab[hash]; 8929: while (bucket) { 8930: if (bucket->length == len && strncmp (bucket->name, name, len) == 0) 8931: return bucket; 8932: bucket = bucket->next; 8933: } 8934: return NULL; 8935: } 8936: 8937: /* 8938: * Delete a hash node. Some weirdness to free junk from macros. 8939: * More such weirdness will have to be added if you define more hash 8940: * types that need it. 8941: */ 8942: 8943: /* Note that the DEFINITION of a macro is removed from the hash table 8944: but its storage is not freed. This would be a storage leak 8945: except that it is not reasonable to keep undefining and redefining 8946: large numbers of macros many times. 8947: In any case, this is necessary, because a macro can be #undef'd 8948: in the middle of reading the arguments to a call to it. 8949: If #undef freed the DEFINITION, that would crash. */ 8950: 8951: static void 8952: delete_macro (hp) 8953: HASHNODE *hp; 8954: { 8955: 8956: if (hp->prev != NULL) 8957: hp->prev->next = hp->next; 8958: if (hp->next != NULL) 8959: hp->next->prev = hp->prev; 8960: 8961: /* make sure that the bucket chain header that 8962: the deleted guy was on points to the right thing afterwards. */ 8963: if (hp == *hp->bucket_hdr) 8964: *hp->bucket_hdr = hp->next; 8965: 8966: #if 0 8967: if (hp->type == T_MACRO) { 8968: DEFINITION *d = hp->value.defn; 8969: struct reflist *ap, *nextap; 8970: 8971: for (ap = d->pattern; ap != NULL; ap = nextap) { 8972: nextap = ap->next; 8973: free (ap); 8974: } 8975: free (d); 8976: } 8977: #endif 8978: free (hp); 8979: } 8980: 8981: /* 8982: * return hash function on name. must be compatible with the one 8983: * computed a step at a time, elsewhere 8984: */ 8985: static int 8986: hashf (name, len, hashsize) 8987: register U_CHAR *name; 8988: register int len; 8989: int hashsize; 8990: { 8991: register int r = 0; 8992: 8993: while (len--) 8994: r = HASHSTEP (r, *name++); 8995: 8996: return MAKE_POS (r) % hashsize; 8997: } 8998: 8999: 9000: /* Dump the definition of a single macro HP to OF. */ 9001: static void 9002: dump_single_macro (hp, of) 9003: register HASHNODE *hp; 9004: FILE *of; 9005: { 9006: register DEFINITION *defn = hp->value.defn; 9007: struct reflist *ap; 9008: int offset; 9009: int concat; 9010: 9011: 9012: /* Print the definition of the macro HP. */ 9013: 9014: fprintf (of, "#define %s", hp->name); 9015: 9016: if (defn->nargs >= 0) { 9017: int i; 9018: 9019: fprintf (of, "("); 9020: for (i = 0; i < defn->nargs; i++) { 9021: dump_arg_n (defn, i, of); 9022: if (i + 1 < defn->nargs) 9023: fprintf (of, ", "); 9024: } 9025: fprintf (of, ")"); 9026: } 9027: 9028: fprintf (of, " "); 9029: 9030: offset = 0; 9031: concat = 0; 9032: for (ap = defn->pattern; ap != NULL; ap = ap->next) { 9033: dump_defn_1 (defn->expansion, offset, ap->nchars, of); 9034: offset += ap->nchars; 1.1.1.7 ! root 9035: if (!traditional) { ! 9036: if (ap->nchars != 0) ! 9037: concat = 0; ! 9038: if (ap->stringify) ! 9039: fprintf (of, " #"); ! 9040: if (ap->raw_before && !concat) ! 9041: fprintf (of, " ## "); ! 9042: concat = 0; ! 9043: } 1.1 root 9044: dump_arg_n (defn, ap->argno, of); 1.1.1.7 ! root 9045: if (!traditional && ap->raw_after) { 1.1 root 9046: fprintf (of, " ## "); 9047: concat = 1; 9048: } 9049: } 9050: dump_defn_1 (defn->expansion, offset, defn->length - offset, of); 9051: fprintf (of, "\n"); 9052: } 9053: 9054: /* Dump all macro definitions as #defines to stdout. */ 9055: 9056: static void 9057: dump_all_macros () 9058: { 9059: int bucket; 9060: 9061: for (bucket = 0; bucket < HASHSIZE; bucket++) { 9062: register HASHNODE *hp; 9063: 9064: for (hp = hashtab[bucket]; hp; hp= hp->next) { 9065: if (hp->type == T_MACRO) 9066: dump_single_macro (hp, stdout); 9067: } 9068: } 9069: } 9070: 9071: /* Output to OF a substring of a macro definition. 9072: BASE is the beginning of the definition. 9073: Output characters START thru LENGTH. 1.1.1.7 ! root 9074: Unless traditional, discard newlines outside of strings, thus 1.1 root 9075: converting funny-space markers to ordinary spaces. */ 9076: 9077: static void 9078: dump_defn_1 (base, start, length, of) 9079: U_CHAR *base; 9080: int start; 9081: int length; 9082: FILE *of; 9083: { 9084: U_CHAR *p = base + start; 9085: U_CHAR *limit = base + start + length; 9086: 1.1.1.7 ! root 9087: if (traditional) ! 9088: fwrite (p, sizeof (*p), length, of); ! 9089: else { ! 9090: while (p < limit) { ! 9091: if (*p == '\"' || *p =='\'') { ! 9092: U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR, ! 9093: NULL_PTR, NULL_PTR); ! 9094: fwrite (p, sizeof (*p), p1 - p, of); ! 9095: p = p1; ! 9096: } else { ! 9097: if (*p != '\n') ! 9098: putc (*p, of); ! 9099: p++; ! 9100: } 1.1 root 9101: } 9102: } 9103: } 9104: 9105: /* Print the name of argument number ARGNUM of macro definition DEFN 9106: to OF. 9107: Recall that DEFN->args.argnames contains all the arg names 9108: concatenated in reverse order with comma-space in between. */ 9109: 9110: static void 9111: dump_arg_n (defn, argnum, of) 9112: DEFINITION *defn; 9113: int argnum; 9114: FILE *of; 9115: { 9116: register U_CHAR *p = defn->args.argnames; 9117: while (argnum + 1 < defn->nargs) { 9118: p = (U_CHAR *) index (p, ' ') + 1; 9119: argnum++; 9120: } 9121: 9122: while (*p && *p != ',') { 9123: putc (*p, of); 9124: p++; 9125: } 9126: } 9127: 9128: /* Initialize syntactic classifications of characters. */ 9129: 9130: static void 9131: initialize_char_syntax () 9132: { 9133: register int i; 9134: 9135: /* 9136: * Set up is_idchar and is_idstart tables. These should be 9137: * faster than saying (is_alpha (c) || c == '_'), etc. 9138: * Set up these things before calling any routines tthat 9139: * refer to them. 9140: */ 9141: for (i = 'a'; i <= 'z'; i++) { 9142: is_idchar[i - 'a' + 'A'] = 1; 9143: is_idchar[i] = 1; 9144: is_idstart[i - 'a' + 'A'] = 1; 9145: is_idstart[i] = 1; 9146: } 9147: for (i = '0'; i <= '9'; i++) 9148: is_idchar[i] = 1; 9149: is_idchar['_'] = 1; 9150: is_idstart['_'] = 1; 9151: is_idchar['$'] = dollars_in_ident; 9152: is_idstart['$'] = dollars_in_ident; 9153: 9154: /* horizontal space table */ 9155: is_hor_space[' '] = 1; 9156: is_hor_space['\t'] = 1; 9157: is_hor_space['\v'] = 1; 9158: is_hor_space['\f'] = 1; 9159: is_hor_space['\r'] = 1; 9160: 9161: is_space[' '] = 1; 9162: is_space['\t'] = 1; 9163: is_space['\v'] = 1; 9164: is_space['\f'] = 1; 9165: is_space['\n'] = 1; 9166: is_space['\r'] = 1; 9167: } 9168: 9169: /* Initialize the built-in macros. */ 9170: 9171: static void 9172: initialize_builtins (inp, outp) 9173: FILE_BUF *inp; 9174: FILE_BUF *outp; 9175: { 1.1.1.7 ! root 9176: install ("__LINE__", -1, T_SPECLINE, 0, NULL_PTR, -1); ! 9177: install ("__DATE__", -1, T_DATE, 0, NULL_PTR, -1); ! 9178: install ("__FILE__", -1, T_FILE, 0, NULL_PTR, -1); ! 9179: install ("__BASE_FILE__", -1, T_BASE_FILE, 0, NULL_PTR, -1); ! 9180: install ("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, NULL_PTR, -1); ! 9181: install ("__VERSION__", -1, T_VERSION, 0, NULL_PTR, -1); 1.1.1.5 root 9182: #ifndef NO_BUILTIN_SIZE_TYPE 1.1.1.7 ! root 9183: install ("__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, NULL_PTR, -1); 1.1.1.5 root 9184: #endif 9185: #ifndef NO_BUILTIN_PTRDIFF_TYPE 1.1.1.7 ! root 9186: install ("__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0, NULL_PTR, -1); 1.1.1.5 root 9187: #endif 1.1.1.7 ! root 9188: install ("__WCHAR_TYPE__", -1, T_WCHAR_TYPE, 0, NULL_PTR, -1); ! 9189: install ("__USER_LABEL_PREFIX__",-1,T_USER_LABEL_PREFIX_TYPE,0,NULL_PTR, -1); ! 9190: install ("__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE, 0, NULL_PTR, -1); ! 9191: install ("__TIME__", -1, T_TIME, 0, NULL_PTR, -1); 1.1 root 9192: if (!traditional) 1.1.1.7 ! root 9193: install ("__STDC__", -1, T_CONST, STDC_VALUE, NULL_PTR, -1); 1.1 root 9194: if (objc) 1.1.1.7 ! root 9195: install ("__OBJC__", -1, T_CONST, 1, NULL_PTR, -1); 1.1 root 9196: /* This is supplied using a -D by the compiler driver 9197: so that it is present only when truly compiling with GNU C. */ 1.1.1.7 ! root 9198: /* install ("__GNUC__", -1, T_CONST, 2, NULL_PTR, -1); */ 1.1 root 9199: 9200: if (debug_output) 9201: { 9202: char directive[2048]; 9203: register struct directive *dp = &directive_table[0]; 1.1.1.3 root 9204: struct tm *timebuf = timestamp (); 1.1 root 9205: 1.1.1.3 root 9206: sprintf (directive, " __BASE_FILE__ \"%s\"\n", 1.1 root 9207: instack[0].nominal_fname); 9208: output_line_command (inp, outp, 0, same_file); 9209: pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); 9210: 1.1.1.3 root 9211: sprintf (directive, " __VERSION__ \"%s\"\n", version_string); 1.1 root 9212: output_line_command (inp, outp, 0, same_file); 9213: pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); 9214: 1.1.1.6 root 9215: #ifndef NO_BUILTIN_SIZE_TYPE 1.1.1.3 root 9216: sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE); 1.1 root 9217: output_line_command (inp, outp, 0, same_file); 9218: pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); 1.1.1.6 root 9219: #endif 1.1 root 9220: 1.1.1.6 root 9221: #ifndef NO_BUILTIN_PTRDIFF_TYPE 1.1.1.3 root 9222: sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE); 1.1 root 9223: output_line_command (inp, outp, 0, same_file); 9224: pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); 1.1.1.6 root 9225: #endif 1.1 root 9226: 1.1.1.7 ! root 9227: sprintf (directive, " __WCHAR_TYPE__ %s\n", wchar_type); 1.1 root 9228: output_line_command (inp, outp, 0, same_file); 9229: pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); 9230: 1.1.1.3 root 9231: sprintf (directive, " __DATE__ \"%s %2d %4d\"\n", 1.1 root 9232: monthnames[timebuf->tm_mon], 9233: timebuf->tm_mday, timebuf->tm_year + 1900); 9234: output_line_command (inp, outp, 0, same_file); 9235: pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); 9236: 1.1.1.3 root 9237: sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n", 1.1 root 9238: timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec); 9239: output_line_command (inp, outp, 0, same_file); 9240: pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); 9241: 9242: if (!traditional) 9243: { 9244: sprintf (directive, " __STDC__ 1"); 9245: output_line_command (inp, outp, 0, same_file); 9246: pass_thru_directive (directive, &directive[strlen (directive)], 9247: outp, dp); 9248: } 9249: if (objc) 9250: { 9251: sprintf (directive, " __OBJC__ 1"); 9252: output_line_command (inp, outp, 0, same_file); 9253: pass_thru_directive (directive, &directive[strlen (directive)], 9254: outp, dp); 9255: } 9256: } 9257: } 9258: 9259: /* 9260: * process a given definition string, for initialization 9261: * If STR is just an identifier, define it with value 1. 9262: * If STR has anything after the identifier, then it should 9263: * be identifier=definition. 9264: */ 9265: 9266: static void 9267: make_definition (str, op) 9268: U_CHAR *str; 9269: FILE_BUF *op; 9270: { 9271: FILE_BUF *ip; 9272: struct directive *kt; 9273: U_CHAR *buf, *p; 9274: 9275: buf = str; 9276: p = str; 9277: if (!is_idstart[*p]) { 9278: error ("malformed option `-D %s'", str); 9279: return; 9280: } 9281: while (is_idchar[*++p]) 9282: ; 1.1.1.7 ! root 9283: if (*p == '(') { ! 9284: while (is_idchar[*++p] || *p == ',' || is_hor_space[*p]) ! 9285: ; ! 9286: if (*p++ != ')') ! 9287: p = str; /* Error */ ! 9288: } 1.1 root 9289: if (*p == 0) { 9290: buf = (U_CHAR *) alloca (p - buf + 4); 9291: strcpy ((char *)buf, str); 9292: strcat ((char *)buf, " 1"); 9293: } else if (*p != '=') { 9294: error ("malformed option `-D %s'", str); 9295: return; 9296: } else { 9297: U_CHAR *q; 9298: /* Copy the entire option so we can modify it. */ 9299: buf = (U_CHAR *) alloca (2 * strlen (str) + 1); 9300: strncpy (buf, str, p - str); 9301: /* Change the = to a space. */ 9302: buf[p - str] = ' '; 9303: /* Scan for any backslash-newline and remove it. */ 9304: p++; 9305: q = &buf[p - str]; 9306: while (*p) { 1.1.1.7 ! root 9307: if (*p == '\"' || *p == '\'') { ! 9308: int unterminated = 0; ! 9309: U_CHAR *p1 = skip_quoted_string (p, p + strlen (p), 0, ! 9310: NULL_PTR, NULL_PTR, &unterminated); ! 9311: if (unterminated) ! 9312: return; ! 9313: while (p != p1) ! 9314: if (*p == '\\' && p[1] == '\n') ! 9315: p += 2; ! 9316: else ! 9317: *q++ = *p++; ! 9318: } else if (*p == '\\' && p[1] == '\n') 1.1 root 9319: p += 2; 9320: /* Change newline chars into newline-markers. */ 9321: else if (*p == '\n') 9322: { 9323: *q++ = '\n'; 9324: *q++ = '\n'; 9325: p++; 9326: } 9327: else 9328: *q++ = *p++; 9329: } 9330: *q = 0; 9331: } 9332: 9333: ip = &instack[++indepth]; 9334: ip->nominal_fname = ip->fname = "*Initialization*"; 9335: 9336: ip->buf = ip->bufp = buf; 9337: ip->length = strlen (buf); 9338: ip->lineno = 1; 9339: ip->macro = 0; 9340: ip->free_ptr = 0; 9341: ip->if_stack = if_stack; 9342: ip->system_header_p = 0; 9343: 9344: for (kt = directive_table; kt->type != T_DEFINE; kt++) 9345: ; 9346: 1.1.1.5 root 9347: /* Pass NULL instead of OP, since this is a "predefined" macro. */ 1.1.1.7 ! root 9348: do_define (buf, buf + strlen (buf), NULL_PTR, kt); 1.1 root 9349: --indepth; 9350: } 9351: 9352: /* JF, this does the work for the -U option */ 9353: 9354: static void 9355: make_undef (str, op) 9356: U_CHAR *str; 9357: FILE_BUF *op; 9358: { 9359: FILE_BUF *ip; 9360: struct directive *kt; 9361: 9362: ip = &instack[++indepth]; 9363: ip->nominal_fname = ip->fname = "*undef*"; 9364: 9365: ip->buf = ip->bufp = str; 9366: ip->length = strlen (str); 9367: ip->lineno = 1; 9368: ip->macro = 0; 9369: ip->free_ptr = 0; 9370: ip->if_stack = if_stack; 9371: ip->system_header_p = 0; 9372: 9373: for (kt = directive_table; kt->type != T_UNDEF; kt++) 9374: ; 9375: 9376: do_undef (str, str + strlen (str), op, kt); 9377: --indepth; 9378: } 9379: 9380: /* Process the string STR as if it appeared as the body of a #assert. 9381: OPTION is the option name for which STR was the argument. */ 9382: 9383: static void 9384: make_assertion (option, str) 9385: char *option; 9386: U_CHAR *str; 9387: { 9388: FILE_BUF *ip; 9389: struct directive *kt; 9390: U_CHAR *buf, *p, *q; 9391: 9392: /* Copy the entire option so we can modify it. */ 9393: buf = (U_CHAR *) alloca (strlen (str) + 1); 9394: strcpy ((char *) buf, str); 9395: /* Scan for any backslash-newline and remove it. */ 9396: p = q = buf; 9397: while (*p) { 9398: if (*p == '\\' && p[1] == '\n') 9399: p += 2; 9400: else 9401: *q++ = *p++; 9402: } 9403: *q = 0; 9404: 9405: p = buf; 9406: if (!is_idstart[*p]) { 9407: error ("malformed option `%s %s'", option, str); 9408: return; 9409: } 9410: while (is_idchar[*++p]) 9411: ; 9412: while (*p == ' ' || *p == '\t') p++; 9413: if (! (*p == 0 || *p == '(')) { 9414: error ("malformed option `%s %s'", option, str); 9415: return; 9416: } 9417: 9418: ip = &instack[++indepth]; 9419: ip->nominal_fname = ip->fname = "*Initialization*"; 9420: 9421: ip->buf = ip->bufp = buf; 9422: ip->length = strlen (buf); 9423: ip->lineno = 1; 9424: ip->macro = 0; 9425: ip->free_ptr = 0; 9426: ip->if_stack = if_stack; 9427: ip->system_header_p = 0; 9428: 9429: for (kt = directive_table; kt->type != T_ASSERT; kt++) 9430: ; 9431: 9432: /* pass NULL as output ptr to do_define since we KNOW it never 9433: does any output.... */ 1.1.1.4 root 9434: do_assert (buf, buf + strlen (buf) , NULL_PTR, kt); 1.1 root 9435: --indepth; 9436: } 9437: 1.1.1.4 root 9438: /* Append a chain of `struct file_name_list's 9439: to the end of the main include chain. 9440: FIRST is the beginning of the chain to append, and LAST is the end. */ 9441: 9442: static void 9443: append_include_chain (first, last) 9444: struct file_name_list *first, *last; 9445: { 9446: struct file_name_list *dir; 9447: 9448: if (!first || !last) 9449: return; 9450: 9451: if (include == 0) 9452: include = first; 9453: else 9454: last_include->next = first; 9455: 9456: if (first_bracket_include == 0) 9457: first_bracket_include = first; 9458: 9459: for (dir = first; ; dir = dir->next) { 9460: int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE; 9461: if (len > max_include_len) 9462: max_include_len = len; 9463: if (dir == last) 9464: break; 9465: } 9466: 9467: last->next = NULL; 9468: last_include = last; 9469: } 9470: 1.1 root 9471: /* Add output to `deps_buffer' for the -M switch. 9472: STRING points to the text to be output. 1.1.1.7 ! root 9473: SPACER is ':' for targets, ' ' for dependencies, zero for text ! 9474: to be inserted literally. */ 1.1 root 9475: 9476: static void 1.1.1.7 ! root 9477: deps_output (string, spacer) 1.1 root 9478: char *string; 1.1.1.7 ! root 9479: int spacer; 1.1 root 9480: { 1.1.1.7 ! root 9481: int size = strlen (string); ! 9482: 1.1 root 9483: if (size == 0) 1.1.1.7 ! root 9484: return; 1.1 root 9485: 9486: #ifndef MAX_OUTPUT_COLUMNS 1.1.1.7 ! root 9487: #define MAX_OUTPUT_COLUMNS 72 1.1 root 9488: #endif 1.1.1.7 ! root 9489: if (spacer ! 9490: && deps_column > 0 ! 9491: && (deps_column + size) > MAX_OUTPUT_COLUMNS) ! 9492: { ! 9493: deps_output (" \\\n ", 0); 1.1 root 9494: deps_column = 0; 9495: } 9496: 1.1.1.7 ! root 9497: if (deps_size + size + 8 > deps_allocated_size) { ! 9498: deps_allocated_size = (deps_size + size + 50) * 2; 1.1 root 9499: deps_buffer = (char *) xrealloc (deps_buffer, deps_allocated_size); 9500: } 1.1.1.7 ! root 9501: if (spacer == ' ' && deps_column > 0) ! 9502: deps_buffer[deps_size++] = ' '; 1.1 root 9503: bcopy (string, &deps_buffer[deps_size], size); 9504: deps_size += size; 9505: deps_column += size; 1.1.1.7 ! root 9506: if (spacer == ':') ! 9507: deps_buffer[deps_size++] = ':'; 1.1 root 9508: deps_buffer[deps_size] = 0; 9509: } 9510: 9511: #if defined(USG) || defined(VMS) 9512: #ifndef BSTRING 9513: 9514: void 9515: bzero (b, length) 9516: register char *b; 9517: register unsigned length; 9518: { 9519: while (length-- > 0) 9520: *b++ = 0; 9521: } 9522: 9523: void 9524: bcopy (b1, b2, length) 9525: register char *b1; 9526: register char *b2; 9527: register unsigned length; 9528: { 9529: while (length-- > 0) 9530: *b2++ = *b1++; 9531: } 9532: 9533: int 9534: bcmp (b1, b2, length) /* This could be a macro! */ 9535: register char *b1; 9536: register char *b2; 9537: register unsigned length; 9538: { 9539: while (length-- > 0) 9540: if (*b1++ != *b2++) 9541: return 1; 9542: 9543: return 0; 9544: } 9545: #endif /* not BSTRING */ 9546: #endif /* USG or VMS */ 9547: 9548: 9549: static void 9550: fatal (str, arg) 9551: char *str, *arg; 9552: { 9553: fprintf (stderr, "%s: ", progname); 9554: fprintf (stderr, str, arg); 9555: fprintf (stderr, "\n"); 9556: exit (FAILURE_EXIT_CODE); 9557: } 9558: 9559: /* More 'friendly' abort that prints the line and file. 9560: config.h can #define abort fancy_abort if you like that sort of thing. */ 9561: 9562: void 9563: fancy_abort () 9564: { 9565: fatal ("Internal gcc abort."); 9566: } 9567: 9568: static void 9569: perror_with_name (name) 9570: char *name; 9571: { 9572: fprintf (stderr, "%s: ", progname); 1.1.1.7 ! root 9573: fprintf (stderr, "%s: %s\n", name, my_strerror (errno)); 1.1 root 9574: errors++; 9575: } 9576: 9577: static void 9578: pfatal_with_name (name) 9579: char *name; 9580: { 9581: perror_with_name (name); 9582: #ifdef VMS 9583: exit (vaxc$errno); 9584: #else 9585: exit (FAILURE_EXIT_CODE); 9586: #endif 9587: } 9588: 1.1.1.5 root 9589: /* Handler for SIGPIPE. */ 9590: 9591: static void 9592: pipe_closed (signo) 9593: /* If this is missing, some compilers complain. */ 9594: int signo; 9595: { 9596: fatal ("output pipe has been closed"); 9597: } 1.1 root 9598: 9599: static void 9600: memory_full () 9601: { 9602: fatal ("Memory exhausted."); 9603: } 9604: 9605: 9606: char * 9607: xmalloc (size) 9608: unsigned size; 9609: { 9610: register char *ptr = (char *) malloc (size); 9611: if (ptr != 0) return (ptr); 9612: memory_full (); 9613: /*NOTREACHED*/ 9614: return 0; 9615: } 9616: 9617: static char * 9618: xrealloc (old, size) 9619: char *old; 9620: unsigned size; 9621: { 9622: register char *ptr = (char *) realloc (old, size); 9623: if (ptr != 0) return (ptr); 9624: memory_full (); 9625: /*NOTREACHED*/ 9626: return 0; 9627: } 9628: 9629: static char * 9630: xcalloc (number, size) 9631: unsigned number, size; 9632: { 9633: register unsigned total = number * size; 9634: register char *ptr = (char *) malloc (total); 9635: if (ptr != 0) { 9636: if (total > 100) 9637: bzero (ptr, total); 9638: else { 9639: /* It's not too long, so loop, zeroing by longs. 9640: It must be safe because malloc values are always well aligned. */ 9641: register long *zp = (long *) ptr; 9642: register long *zl = (long *) (ptr + total - 4); 9643: register int i = total - 4; 9644: while (zp < zl) 9645: *zp++ = 0; 9646: if (i < 0) 9647: i = 0; 9648: while (i < total) 9649: ptr[i++] = 0; 9650: } 9651: return ptr; 9652: } 9653: memory_full (); 9654: /*NOTREACHED*/ 9655: return 0; 9656: } 9657: 9658: static char * 9659: savestring (input) 9660: char *input; 9661: { 9662: unsigned size = strlen (input); 9663: char *output = xmalloc (size + 1); 9664: strcpy (output, input); 9665: return output; 9666: } 9667: 9668: /* Get the file-mode and data size of the file open on FD 9669: and store them in *MODE_POINTER and *SIZE_POINTER. */ 9670: 9671: static int 9672: file_size_and_mode (fd, mode_pointer, size_pointer) 9673: int fd; 9674: int *mode_pointer; 9675: long int *size_pointer; 9676: { 9677: struct stat sbuf; 9678: 9679: if (fstat (fd, &sbuf) < 0) return (-1); 9680: if (mode_pointer) *mode_pointer = sbuf.st_mode; 9681: if (size_pointer) *size_pointer = sbuf.st_size; 9682: return 0; 9683: } 1.1.1.6 root 9684: 9685: static void 9686: output_dots (fd, depth) 9687: FILE* fd; 9688: int depth; 9689: { 9690: while (depth > 0) { 9691: putc ('.', fd); 9692: depth--; 9693: } 9694: } 9695: 1.1 root 9696: 9697: #ifdef VMS 9698: 9699: /* Under VMS we need to fix up the "include" specification 9700: filename so that everything following the 1st slash is 9701: changed into its correct VMS file specification. */ 9702: 9703: static void 9704: hack_vms_include_specification (fname) 9705: char *fname; 9706: { 9707: register char *cp, *cp1, *cp2; 9708: int f, check_filename_before_returning, no_prefix_seen; 9709: char Local[512]; 9710: 9711: check_filename_before_returning = 0; 9712: no_prefix_seen = 0; 9713: 9714: /* Ignore leading "./"s */ 9715: while (fname[0] == '.' && fname[1] == '/') { 9716: strcpy (fname, fname+2); 9717: no_prefix_seen = 1; /* mark this for later */ 9718: } 9719: /* Look for the boundary between the VMS and UNIX filespecs */ 9720: cp = rindex (fname, ']'); /* Look for end of dirspec. */ 9721: if (cp == 0) cp = rindex (fname, '>'); /* ... Ditto */ 9722: if (cp == 0) cp = rindex (fname, ':'); /* Look for end of devspec. */ 9723: if (cp) { 9724: cp++; 9725: } else { 9726: cp = index (fname, '/'); /* Look for the "/" */ 9727: } 9728: 1.1.1.7 ! root 9729: /* ! 9730: * Check if we have a vax-c style '#include filename' ! 9731: * and add the missing .h ! 9732: */ ! 9733: if (cp == 0) { ! 9734: if (index(fname,'.') == 0) ! 9735: strcat(fname, ".h"); ! 9736: } else { ! 9737: if (index(cp,'.') == 0) ! 9738: strcat(cp, ".h"); ! 9739: } ! 9740: 1.1 root 9741: cp2 = Local; /* initialize */ 9742: 9743: /* We are trying to do a number of things here. First of all, we are 9744: trying to hammer the filenames into a standard format, such that later 9745: processing can handle them. 9746: 9747: If the file name contains something like [dir.], then it recognizes this 9748: as a root, and strips the ".]". Later processing will add whatever is 9749: needed to get things working properly. 9750: 9751: If no device is specified, then the first directory name is taken to be 9752: a device name (or a rooted logical). */ 9753: 9754: /* See if we found that 1st slash */ 9755: if (cp == 0) return; /* Nothing to do!!! */ 9756: if (*cp != '/') return; /* Nothing to do!!! */ 9757: /* Point to the UNIX filename part (which needs to be fixed!) */ 9758: cp1 = cp+1; 9759: /* If the directory spec is not rooted, we can just copy 9760: the UNIX filename part and we are done */ 9761: if (((cp - fname) > 1) && ((cp[-1] == ']') || (cp[-1] == '>'))) { 9762: if (cp[-2] != '.') { 9763: /* 1.1.1.2 root 9764: * The VMS part ends in a `]', and the preceding character is not a `.'. 1.1 root 9765: * We strip the `]', and then splice the two parts of the name in the 9766: * usual way. Given the default locations for include files in cccp.c, 9767: * we will only use this code if the user specifies alternate locations 9768: * with the /include (-I) switch on the command line. */ 9769: cp -= 1; /* Strip "]" */ 9770: cp1--; /* backspace */ 9771: } else { 9772: /* 9773: * The VMS part has a ".]" at the end, and this will not do. Later 9774: * processing will add a second directory spec, and this would be a syntax 9775: * error. Thus we strip the ".]", and thus merge the directory specs. 9776: * We also backspace cp1, so that it points to a '/'. This inhibits the 9777: * generation of the 000000 root directory spec (which does not belong here 9778: * in this case). 9779: */ 9780: cp -= 2; /* Strip ".]" */ 9781: cp1--; }; /* backspace */ 9782: } else { 9783: 9784: /* We drop in here if there is no VMS style directory specification yet. 9785: * If there is no device specification either, we make the first dir a 9786: * device and try that. If we do not do this, then we will be essentially 9787: * searching the users default directory (as if they did a #include "asdf.h"). 9788: * 9789: * Then all we need to do is to push a '[' into the output string. Later 9790: * processing will fill this in, and close the bracket. 9791: */ 1.1.1.5 root 9792: if (cp[-1] != ':') *cp2++ = ':'; /* dev not in spec. take first dir */ 1.1 root 9793: *cp2++ = '['; /* Open the directory specification */ 9794: } 9795: 9796: /* at this point we assume that we have the device spec, and (at least 9797: the opening "[" for a directory specification. We may have directories 9798: specified already */ 9799: 9800: /* If there are no other slashes then the filename will be 9801: in the "root" directory. Otherwise, we need to add 9802: directory specifications. */ 9803: if (index (cp1, '/') == 0) { 9804: /* Just add "000000]" as the directory string */ 9805: strcpy (cp2, "000000]"); 9806: cp2 += strlen (cp2); 9807: check_filename_before_returning = 1; /* we might need to fool with this later */ 9808: } else { 9809: /* As long as there are still subdirectories to add, do them. */ 9810: while (index (cp1, '/') != 0) { 9811: /* If this token is "." we can ignore it */ 9812: if ((cp1[0] == '.') && (cp1[1] == '/')) { 9813: cp1 += 2; 9814: continue; 9815: } 9816: /* Add a subdirectory spec. Do not duplicate "." */ 9817: if (cp2[-1] != '.' && cp2[-1] != '[' && cp2[-1] != '<') 9818: *cp2++ = '.'; 9819: /* If this is ".." then the spec becomes "-" */ 9820: if ((cp1[0] == '.') && (cp1[1] == '.') && (cp[2] == '/')) { 9821: /* Add "-" and skip the ".." */ 9822: *cp2++ = '-'; 9823: cp1 += 3; 9824: continue; 9825: } 9826: /* Copy the subdirectory */ 9827: while (*cp1 != '/') *cp2++= *cp1++; 9828: cp1++; /* Skip the "/" */ 9829: } 9830: /* Close the directory specification */ 1.1.1.5 root 9831: if (cp2[-1] == '.') /* no trailing periods */ 1.1 root 9832: cp2--; 9833: *cp2++ = ']'; 9834: } 9835: /* Now add the filename */ 9836: while (*cp1) *cp2++ = *cp1++; 9837: *cp2 = 0; 9838: /* Now append it to the original VMS spec. */ 9839: strcpy (cp, Local); 9840: 9841: /* If we put a [000000] in the filename, try to open it first. If this fails, 9842: remove the [000000], and return that name. This provides flexibility 9843: to the user in that they can use both rooted and non-rooted logical names 9844: to point to the location of the file. */ 9845: 9846: if (check_filename_before_returning && no_prefix_seen) { 9847: f = open (fname, O_RDONLY, 0666); 9848: if (f >= 0) { 9849: /* The file name is OK as it is, so return it as is. */ 9850: close (f); 9851: return; 9852: } 9853: /* The filename did not work. Try to remove the [000000] from the name, 9854: and return it. */ 9855: cp = index (fname, '['); 9856: cp2 = index (fname, ']') + 1; 9857: strcpy (cp, cp2); /* this gets rid of it */ 9858: } 9859: return; 9860: } 9861: #endif /* VMS */ 9862: 9863: #ifdef VMS 9864: 9865: /* These are the read/write replacement routines for 9866: VAX-11 "C". They make read/write behave enough 9867: like their UNIX counterparts that CCCP will work */ 9868: 9869: static int 9870: read (fd, buf, size) 9871: int fd; 9872: char *buf; 9873: int size; 9874: { 9875: #undef read /* Get back the REAL read routine */ 9876: register int i; 9877: register int total = 0; 9878: 9879: /* Read until the buffer is exhausted */ 9880: while (size > 0) { 9881: /* Limit each read to 32KB */ 9882: i = (size > (32*1024)) ? (32*1024) : size; 9883: i = read (fd, buf, i); 9884: if (i <= 0) { 9885: if (i == 0) return (total); 1.1.1.5 root 9886: return (i); 1.1 root 9887: } 9888: /* Account for this read */ 9889: total += i; 9890: buf += i; 9891: size -= i; 9892: } 9893: return (total); 9894: } 9895: 9896: static int 9897: write (fd, buf, size) 9898: int fd; 9899: char *buf; 9900: int size; 9901: { 9902: #undef write /* Get back the REAL write routine */ 9903: int i; 9904: int j; 9905: 9906: /* Limit individual writes to 32Kb */ 9907: i = size; 9908: while (i > 0) { 9909: j = (i > (32*1024)) ? (32*1024) : i; 9910: if (write (fd, buf, j) < 0) return (-1); 9911: /* Account for the data written */ 9912: buf += j; 9913: i -= j; 9914: } 9915: return (size); 9916: } 9917: 9918: /* The following wrapper functions supply additional arguments to the VMS 9919: I/O routines to optimize performance with file handling. The arguments 9920: are: 9921: "mbc=16" - Set multi-block count to 16 (use a 8192 byte buffer). 9922: "deq=64" - When extending the file, extend it in chunks of 32Kbytes. 9923: "fop=tef"- Truncate unused portions of file when closing file. 9924: "shr=nil"- Disallow file sharing while file is open. 9925: */ 9926: 9927: static FILE * 9928: freopen (fname, type, oldfile) 9929: char *fname; 9930: char *type; 9931: FILE *oldfile; 9932: { 9933: #undef freopen /* Get back the REAL fopen routine */ 9934: if (strcmp (type, "w") == 0) 9935: return freopen (fname, type, oldfile, "mbc=16", "deq=64", "fop=tef", "shr=nil"); 9936: return freopen (fname, type, oldfile, "mbc=16"); 9937: } 9938: 9939: static FILE * 9940: fopen (fname, type) 9941: char *fname; 9942: char *type; 9943: { 9944: #undef fopen /* Get back the REAL fopen routine */ 9945: if (strcmp (type, "w") == 0) 9946: return fopen (fname, type, "mbc=16", "deq=64", "fop=tef", "shr=nil"); 9947: return fopen (fname, type, "mbc=16"); 9948: } 9949: 9950: static int 9951: open (fname, flags, prot) 9952: char *fname; 9953: int flags; 9954: int prot; 9955: { 9956: #undef open /* Get back the REAL open routine */ 9957: return open (fname, flags, prot, "mbc=16", "deq=64", "fop=tef"); 9958: } 9959: 1.1.1.4 root 9960: /* Avoid run-time library bug, where copying M out of N+M characters with 9961: N >= 65535 results in VAXCRTL's strncat falling into an infinite loop. 9962: gcc-cpp exercises this particular bug. */ 9963: 9964: static char * 9965: strncat (dst, src, cnt) 9966: char *dst; 9967: const char *src; 9968: unsigned cnt; 9969: { 9970: register char *d = dst, *s = (char *) src; 9971: register int n = cnt; /* convert to _signed_ type */ 9972: 9973: while (*d) d++; /* advance to end */ 9974: while (--n >= 0) 9975: if (!(*d++ = *s++)) break; 9976: if (n < 0) *d = '\0'; 9977: return dst; 9978: } 1.1 root 9979: #endif /* VMS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.