|
|
1.1 root 1: /* C Compatible Compiler Preprocessor (CCCP) 1.1.1.8 ! root 2: Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. 1.1.1.7 root 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 1.1.1.8 ! root 18: Foundation, 59 Temple Place - Suite 330, ! 19: Boston, MA 02111-1307, USA. 1.1 root 20: 21: In other words, you are welcome to use, share and improve this program. 22: You are forbidden to forbid anyone else to use, share and improve 23: what you give them. Help stamp out software-hoarding! */ 24: 25: typedef unsigned char U_CHAR; 26: 27: #ifdef EMACS 28: #define NO_SHORTNAMES 29: #include "../src/config.h" 30: #ifdef open 31: #undef open 32: #undef read 33: #undef write 34: #endif /* open */ 35: #endif /* EMACS */ 36: 37: /* The macro EMACS is defined when cpp is distributed as part of Emacs, 38: for the sake of machines with limited C compilers. */ 39: #ifndef EMACS 40: #include "config.h" 41: #endif /* not EMACS */ 42: 43: #ifndef STANDARD_INCLUDE_DIR 44: #define STANDARD_INCLUDE_DIR "/usr/include" 45: #endif 46: 47: #ifndef LOCAL_INCLUDE_DIR 48: #define LOCAL_INCLUDE_DIR "/usr/local/include" 49: #endif 50: 1.1.1.4 root 51: #if 0 /* We can't get ptrdiff_t, so I arranged not to need PTR_INT_TYPE. */ 52: #ifdef __STDC__ 53: #define PTR_INT_TYPE ptrdiff_t 54: #else 55: #define PTR_INT_TYPE long 56: #endif 57: #endif /* 0 */ 58: 1.1 root 59: #include "pcp.h" 60: 1.1.1.3 root 61: /* By default, colon separates directories in a path. */ 62: #ifndef PATH_SEPARATOR 63: #define PATH_SEPARATOR ':' 64: #endif 65: 1.1 root 66: #include <sys/types.h> 67: #include <sys/stat.h> 68: #include <ctype.h> 69: #include <stdio.h> 1.1.1.5 root 70: #include <signal.h> 1.1 root 71: 1.1.1.8 ! root 72: /* The following symbols should be autoconfigured: ! 73: HAVE_FCNTL_H ! 74: HAVE_STDLIB_H ! 75: HAVE_SYS_TIME_H ! 76: HAVE_UNISTD_H ! 77: STDC_HEADERS ! 78: TIME_WITH_SYS_TIME ! 79: In the mean time, we'll get by with approximations based ! 80: on existing GCC configuration symbols. */ ! 81: ! 82: #ifdef POSIX ! 83: # ifndef HAVE_STDLIB_H ! 84: # define HAVE_STDLIB_H 1 ! 85: # endif ! 86: # ifndef HAVE_UNISTD_H ! 87: # define HAVE_UNISTD_H 1 ! 88: # endif ! 89: # ifndef STDC_HEADERS ! 90: # define STDC_HEADERS 1 ! 91: # endif ! 92: #endif /* defined (POSIX) */ ! 93: ! 94: #if defined (POSIX) || (defined (USG) && !defined (VMS)) ! 95: # ifndef HAVE_FCNTL_H ! 96: # define HAVE_FCNTL_H 1 ! 97: # endif ! 98: #endif ! 99: ! 100: #ifndef RLIMIT_STACK ! 101: # include <time.h> 1.1 root 102: #else 1.1.1.8 ! root 103: # if TIME_WITH_SYS_TIME ! 104: # include <sys/time.h> ! 105: # include <time.h> ! 106: # else ! 107: # if HAVE_SYS_TIME_H ! 108: # include <sys/time.h> ! 109: # else ! 110: # include <time.h> ! 111: # endif ! 112: # endif ! 113: # include <sys/resource.h> ! 114: #endif ! 115: ! 116: #if HAVE_FCNTL_H ! 117: # include <fcntl.h> ! 118: #endif 1.1 root 119: 1.1.1.5 root 120: /* This defines "errno" properly for VMS, and gives us EACCES. */ 121: #include <errno.h> 122: 1.1.1.8 ! root 123: #if HAVE_STDLIB_H ! 124: # include <stdlib.h> ! 125: #else ! 126: char *getenv (); ! 127: #endif ! 128: ! 129: #if STDC_HEADERS ! 130: # include <string.h> ! 131: # ifndef bcmp ! 132: # define bcmp(a, b, n) memcmp (a, b, n) ! 133: # endif ! 134: # ifndef bcopy ! 135: # define bcopy(s, d, n) memcpy (d, s, n) ! 136: # endif ! 137: # ifndef bzero ! 138: # define bzero(d, n) memset (d, 0, n) ! 139: # endif ! 140: #else /* !STDC_HEADERS */ ! 141: char *index (); ! 142: char *rindex (); ! 143: ! 144: # if !defined (BSTRING) && (defined (USG) || defined (VMS)) ! 145: ! 146: # ifndef bcmp ! 147: # define bcmp my_bcmp ! 148: static int ! 149: my_bcmp (a, b, n) ! 150: register char *a; ! 151: register char *b; ! 152: register unsigned n; ! 153: { ! 154: while (n-- > 0) ! 155: if (*a++ != *b++) ! 156: return 1; ! 157: ! 158: return 0; ! 159: } ! 160: # endif /* !defined (bcmp) */ ! 161: ! 162: # ifndef bcopy ! 163: # define bcopy my_bcopy ! 164: static void ! 165: my_bcopy (s, d, n) ! 166: register char *s; ! 167: register char *d; ! 168: register unsigned n; ! 169: { ! 170: while (n-- > 0) ! 171: *d++ = *s++; ! 172: } ! 173: # endif /* !defined (bcopy) */ ! 174: ! 175: # ifndef bzero ! 176: # define bzero my_bzero ! 177: static void ! 178: my_bzero (b, length) ! 179: register char *b; ! 180: register unsigned length; ! 181: { ! 182: while (length-- > 0) ! 183: *b++ = 0; ! 184: } ! 185: # endif /* !defined (bzero) */ ! 186: ! 187: # endif /* !defined (BSTRING) && (defined (USG) || defined (VMS)) */ ! 188: #endif /* ! STDC_HEADERS */ ! 189: ! 190: #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) ! 191: # define __attribute__(x) ! 192: #endif ! 193: ! 194: #ifndef PROTO ! 195: # if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) ! 196: # define PROTO(ARGS) ARGS ! 197: # else ! 198: # define PROTO(ARGS) () ! 199: # endif ! 200: #endif ! 201: ! 202: #if defined (__STDC__) && defined (HAVE_VPRINTF) ! 203: # include <stdarg.h> ! 204: # define VA_START(va_list, var) va_start (va_list, var) ! 205: # define PRINTF_ALIST(msg) char *msg, ... ! 206: # define PRINTF_DCL(msg) ! 207: # define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (printf, m, n))) ! 208: #else ! 209: # include <varargs.h> ! 210: # define VA_START(va_list, var) va_start (va_list) ! 211: # define PRINTF_ALIST(msg) msg, va_alist ! 212: # define PRINTF_DCL(msg) char *msg; va_dcl ! 213: # define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (printf, m, n))) ! 214: # define vfprintf(file, msg, args) \ ! 215: { \ ! 216: char *a0 = va_arg(args, char *); \ ! 217: char *a1 = va_arg(args, char *); \ ! 218: char *a2 = va_arg(args, char *); \ ! 219: char *a3 = va_arg(args, char *); \ ! 220: fprintf (file, msg, a0, a1, a2, a3); \ ! 221: } ! 222: #endif ! 223: ! 224: #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2) ! 225: #define PRINTF_PROTO_2(ARGS) PRINTF_PROTO(ARGS, 2, 3) ! 226: #define PRINTF_PROTO_3(ARGS) PRINTF_PROTO(ARGS, 3, 4) ! 227: ! 228: #if HAVE_UNISTD_H ! 229: # include <unistd.h> ! 230: #endif ! 231: 1.1 root 232: /* VMS-specific definitions */ 233: #ifdef VMS 234: #include <descrip.h> 235: #define O_RDONLY 0 /* Open arg for Read/Only */ 236: #define O_WRONLY 1 /* Open arg for Write/Only */ 1.1.1.5 root 237: #define read(fd,buf,size) VMS_read (fd,buf,size) 238: #define write(fd,buf,size) VMS_write (fd,buf,size) 239: #define open(fname,mode,prot) VMS_open (fname,mode,prot) 240: #define fopen(fname,mode) VMS_fopen (fname,mode) 241: #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile) 242: #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt) 1.1.1.8 ! root 243: #define fstat(fd,stbuf) VMS_fstat (fd,stbuf) ! 244: static int VMS_fstat (), VMS_stat (); 1.1.1.4 root 245: static char * VMS_strncat (); 1.1 root 246: static int VMS_read (); 247: static int VMS_write (); 248: static int VMS_open (); 249: static FILE * VMS_fopen (); 250: static FILE * VMS_freopen (); 251: static void hack_vms_include_specification (); 252: typedef struct { unsigned :16, :16, :16; } vms_ino_t; 253: #define ino_t vms_ino_t 1.1.1.4 root 254: #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */ 1.1 root 255: #ifdef __GNUC__ 256: #define BSTRING /* VMS/GCC supplies the bstring routines */ 257: #endif /* __GNUC__ */ 258: #endif /* VMS */ 259: 260: #ifndef O_RDONLY 261: #define O_RDONLY 0 262: #endif 263: 264: #undef MIN 265: #undef MAX 266: #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) 267: #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) 268: 1.1.1.4 root 269: /* Find the largest host integer type and set its size and type. */ 270: 271: #ifndef HOST_BITS_PER_WIDE_INT 272: 273: #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT 274: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG 275: #define HOST_WIDE_INT long 276: #else 277: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT 278: #define HOST_WIDE_INT int 279: #endif 280: 281: #endif 282: 1.1 root 283: #ifndef S_ISREG 284: #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 285: #endif 286: 1.1.1.5 root 287: #ifndef S_ISDIR 288: #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 289: #endif 290: 1.1.1.4 root 291: /* Define a generic NULL if one hasn't already been defined. */ 292: 293: #ifndef NULL 294: #define NULL 0 295: #endif 296: 297: #ifndef GENERIC_PTR 298: #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) 299: #define GENERIC_PTR void * 300: #else 301: #define GENERIC_PTR char * 302: #endif 303: #endif 304: 305: #ifndef NULL_PTR 306: #define NULL_PTR ((GENERIC_PTR)0) 307: #endif 308: 309: #ifndef INCLUDE_LEN_FUDGE 310: #define INCLUDE_LEN_FUDGE 0 311: #endif 312: 1.1 root 313: /* External declarations. */ 314: 315: extern char *version_string; 1.1.1.7 root 316: #ifndef VMS 317: #ifndef HAVE_STRERROR 1.1 root 318: extern int sys_nerr; 1.1.1.8 ! root 319: #if defined(bsd4_4) 1.1.1.6 root 320: extern const char *const sys_errlist[]; 321: #else 1.1 root 322: extern char *sys_errlist[]; 1.1.1.6 root 323: #endif 1.1.1.8 ! root 324: #else /* HAVE_STRERROR */ 1.1.1.7 root 325: char *strerror (); 326: #endif 327: #else /* VMS */ 328: char *strerror (int,...); 329: #endif 1.1.1.8 ! root 330: int parse_escape PROTO((char **)); ! 331: HOST_WIDE_INT parse_c_expression PROTO((char *)); 1.1 root 332: 333: #ifndef errno 334: extern int errno; 335: #endif 336: 337: /* Name under which this program was invoked. */ 338: 339: static char *progname; 340: 1.1.1.4 root 341: /* Nonzero means use extra default include directories for C++. */ 1.1 root 342: 343: static int cplusplus; 344: 1.1.1.4 root 345: /* Nonzero means handle cplusplus style comments */ 346: 347: static int cplusplus_comments; 348: 1.1 root 349: /* Nonzero means handle #import, for objective C. */ 350: 351: static int objc; 352: 353: /* Nonzero means this is an assembly file, and allow 354: unknown directives, which could be comments. */ 355: 356: static int lang_asm; 357: 358: /* Current maximum length of directory names in the search path 359: for include files. (Altered as we get more of them.) */ 360: 361: static int max_include_len; 362: 363: /* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */ 364: 1.1.1.7 root 365: static int for_lint = 0; 1.1 root 366: 367: /* Nonzero means copy comments into the output file. */ 368: 369: static int put_out_comments = 0; 370: 371: /* Nonzero means don't process the ANSI trigraph sequences. */ 372: 373: static int no_trigraphs = 0; 374: 375: /* Nonzero means print the names of included files rather than 376: the preprocessed output. 1 means just the #include "...", 377: 2 means #include <...> as well. */ 378: 379: static int print_deps = 0; 380: 1.1.1.7 root 381: /* Nonzero if missing .h files in -M output are assumed to be generated 382: files and not errors. */ 383: 384: static int print_deps_missing_files = 0; 385: 1.1 root 386: /* Nonzero means print names of header files (-H). */ 387: 388: static int print_include_names = 0; 389: 390: /* Nonzero means don't output line number information. */ 391: 1.1.1.8 ! root 392: static int no_line_directives; 1.1 root 393: 1.1.1.7 root 394: /* Nonzero means output the text in failing conditionals, 395: inside #failed ... #endfailed. */ 396: 397: static int output_conditionals; 398: 1.1 root 399: /* dump_only means inhibit output of the preprocessed text 400: and instead output the definitions of all user-defined 401: macros in a form suitable for use as input to cccp. 402: dump_names means pass #define and the macro name through to output. 403: dump_definitions means pass the whole definition (plus #define) through 404: */ 405: 406: static enum {dump_none, dump_only, dump_names, dump_definitions} 407: dump_macros = dump_none; 408: 409: /* Nonzero means pass all #define and #undef directives which we actually 410: process through to the output stream. This feature is used primarily 411: to allow cc1 to record the #defines and #undefs for the sake of 412: debuggers which understand about preprocessor macros, but it may 413: also be useful with -E to figure out how symbols are defined, and 414: where they are defined. */ 415: static int debug_output = 0; 416: 417: /* Nonzero indicates special processing used by the pcp program. The 418: special effects of this mode are: 419: 420: Inhibit all macro expansion, except those inside #if directives. 421: 422: Process #define directives normally, and output their contents 423: to the output file. 424: 425: Output preconditions to pcp_outfile indicating all the relevant 426: preconditions for use of this file in a later cpp run. 427: */ 428: static FILE *pcp_outfile; 429: 430: /* Nonzero means we are inside an IF during a -pcp run. In this mode 431: macro expansion is done, and preconditions are output for all macro 432: uses requiring them. */ 433: static int pcp_inside_if; 434: 1.1.1.5 root 435: /* Nonzero means never to include precompiled files. 436: This is 1 since there's no way now to make precompiled files, 437: so it's not worth testing for them. */ 438: static int no_precomp = 1; 1.1 root 439: 440: /* Nonzero means give all the error messages the ANSI standard requires. */ 441: 442: int pedantic; 443: 444: /* Nonzero means try to make failure to fit ANSI C an error. */ 445: 446: static int pedantic_errors; 447: 448: /* Nonzero means don't print warning messages. -w. */ 449: 450: static int inhibit_warnings = 0; 451: 452: /* Nonzero means warn if slash-star appears in a comment. */ 453: 454: static int warn_comments; 455: 456: /* Nonzero means warn if a macro argument is (or would be) 457: stringified with -traditional. */ 458: 459: static int warn_stringify; 460: 461: /* Nonzero means warn if there are any trigraphs. */ 462: 463: static int warn_trigraphs; 464: 1.1.1.2 root 465: /* Nonzero means warn if #import is used. */ 466: 467: static int warn_import = 1; 468: 1.1 root 469: /* Nonzero means turn warnings into errors. */ 470: 471: static int warnings_are_errors; 472: 473: /* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */ 474: 475: int traditional; 476: 477: /* Nonzero causes output not to be done, 478: but directives such as #define that have side effects 479: are still obeyed. */ 480: 481: static int no_output; 482: 1.1.1.7 root 483: /* Nonzero means this file was included with a -imacros or -include 484: command line and should not be recorded as an include file. */ 485: 486: static int no_record_file; 487: 1.1 root 488: /* Nonzero means that we have finished processing the command line options. 489: This flag is used to decide whether or not to issue certain errors 490: and/or warnings. */ 491: 492: static int done_initializing = 0; 1.1.1.5 root 493: 494: /* Line where a newline was first seen in a string constant. */ 495: 496: static int multiline_string_line = 0; 1.1 root 497: 498: /* I/O buffer structure. 499: The `fname' field is nonzero for source files and #include files 500: and for the dummy text used for -D and -U. 501: It is zero for rescanning results of macro expansion 502: and for expanding macro arguments. */ 1.1.1.6 root 503: #define INPUT_STACK_MAX 400 1.1 root 504: static struct file_buf { 505: char *fname; 1.1.1.8 ! root 506: /* Filename specified with #line directive. */ 1.1 root 507: char *nominal_fname; 508: /* Record where in the search path this file was found. 509: For #include_next. */ 510: struct file_name_list *dir; 511: int lineno; 512: int length; 513: U_CHAR *buf; 514: U_CHAR *bufp; 515: /* Macro that this level is the expansion of. 516: Included so that we can reenable the macro 517: at the end of this level. */ 518: struct hashnode *macro; 519: /* Value of if_stack at start of this file. 520: Used to prohibit unmatched #endif (etc) in an include file. */ 521: struct if_stack *if_stack; 522: /* Object to be freed at end of input at this level. */ 523: U_CHAR *free_ptr; 524: /* True if this is a header file included using <FILENAME>. */ 525: char system_header_p; 526: } instack[INPUT_STACK_MAX]; 527: 528: static int last_error_tick; /* Incremented each time we print it. */ 529: static int input_file_stack_tick; /* Incremented when the status changes. */ 530: 531: /* Current nesting level of input sources. 532: `instack[indepth]' is the level currently being read. */ 533: static int indepth = -1; 534: #define CHECK_DEPTH(code) \ 535: if (indepth >= (INPUT_STACK_MAX - 1)) \ 536: { \ 537: error_with_line (line_for_error (instack[indepth].lineno), \ 538: "macro or `#include' recursion too deep"); \ 539: code; \ 540: } 541: 542: /* Current depth in #include directives that use <...>. */ 543: static int system_include_depth = 0; 544: 545: typedef struct file_buf FILE_BUF; 546: 547: /* The output buffer. Its LENGTH field is the amount of room allocated 548: for the buffer, not the number of chars actually present. To get 549: that, subtract outbuf.buf from outbuf.bufp. */ 550: 551: #define OUTBUF_SIZE 10 /* initial size of output buffer */ 552: static FILE_BUF outbuf; 553: 554: /* Grow output buffer OBUF points at 555: so it can hold at least NEEDED more chars. */ 556: 557: #define check_expand(OBUF, NEEDED) \ 558: (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED)) \ 559: ? grow_outbuf ((OBUF), (NEEDED)) : 0) 560: 561: struct file_name_list 562: { 563: struct file_name_list *next; 564: char *fname; 565: /* If the following is nonzero, it is a macro name. 566: Don't include the file again if that macro is defined. */ 567: U_CHAR *control_macro; 1.1.1.6 root 568: /* If the following is nonzero, it is a C-language system include 569: directory. */ 570: int c_system_include_path; 1.1.1.7 root 571: /* Mapping of file names for this directory. */ 572: struct file_name_map *name_map; 573: /* Non-zero if name_map is valid. */ 574: int got_name_map; 1.1 root 575: }; 576: 577: /* #include "file" looks in source file dir, then stack. */ 578: /* #include <file> just looks in the stack. */ 579: /* -I directories are added to the end, then the defaults are added. */ 1.1.1.7 root 580: /* The */ 581: static struct default_include { 582: char *fname; /* The name of the directory. */ 583: int cplusplus; /* Only look here if we're compiling C++. */ 584: int cxx_aware; /* Includes in this directory don't need to 585: be wrapped in extern "C" when compiling 586: C++. */ 587: } include_defaults_array[] 1.1 root 588: #ifdef INCLUDE_DEFAULTS 589: = INCLUDE_DEFAULTS; 590: #else 591: = { 592: /* Pick up GNU C++ specific include files. */ 1.1.1.7 root 593: { GPLUSPLUS_INCLUDE_DIR, 1, 1 }, 1.1 root 594: #ifdef CROSS_COMPILE 1.1.1.5 root 595: /* This is the dir for fixincludes. Put it just before 596: the files that we fix. */ 1.1.1.7 root 597: { GCC_INCLUDE_DIR, 0, 0 }, 1.1 root 598: /* For cross-compilation, this dir name is generated 599: automatically in Makefile.in. */ 1.1.1.7 root 600: { CROSS_INCLUDE_DIR, 0, 0 }, 1.1.1.5 root 601: /* This is another place that the target system's headers might be. */ 1.1.1.7 root 602: { TOOL_INCLUDE_DIR, 0, 0 }, 1.1 root 603: #else /* not CROSS_COMPILE */ 1.1.1.7 root 604: /* This should be /usr/local/include and should come before 1.1.1.5 root 605: the fixincludes-fixed header files. */ 1.1.1.7 root 606: { LOCAL_INCLUDE_DIR, 0, 1 }, 1.1.1.5 root 607: /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here. 608: Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */ 1.1.1.7 root 609: { TOOL_INCLUDE_DIR, 0, 0 }, 1.1.1.5 root 610: /* This is the dir for fixincludes. Put it just before 611: the files that we fix. */ 1.1.1.7 root 612: { GCC_INCLUDE_DIR, 0, 0 }, 1.1 root 613: /* Some systems have an extra dir of include files. */ 614: #ifdef SYSTEM_INCLUDE_DIR 1.1.1.7 root 615: { SYSTEM_INCLUDE_DIR, 0, 0 }, 1.1 root 616: #endif 1.1.1.7 root 617: { STANDARD_INCLUDE_DIR, 0, 0 }, 1.1 root 618: #endif /* not CROSS_COMPILE */ 1.1.1.7 root 619: { 0, 0, 0 } 1.1 root 620: }; 621: #endif /* no INCLUDE_DEFAULTS */ 622: 623: /* The code looks at the defaults through this pointer, rather than through 624: the constant structure above. This pointer gets changed if an environment 625: variable specifies other defaults. */ 626: static struct default_include *include_defaults = include_defaults_array; 627: 628: static struct file_name_list *include = 0; /* First dir to search */ 629: /* First dir to search for <file> */ 1.1.1.4 root 630: /* This is the first element to use for #include <...>. 631: If it is 0, use the entire chain for such includes. */ 1.1 root 632: static struct file_name_list *first_bracket_include = 0; 1.1.1.4 root 633: /* This is the first element in the chain that corresponds to 634: a directory of system header files. */ 635: static struct file_name_list *first_system_include = 0; 1.1 root 636: static struct file_name_list *last_include = 0; /* Last in chain */ 637: 638: /* Chain of include directories to put at the end of the other chain. */ 639: static struct file_name_list *after_include = 0; 640: static struct file_name_list *last_after_include = 0; /* Last in chain */ 641: 1.1.1.7 root 642: /* Chain to put at the start of the system include files. */ 643: static struct file_name_list *before_system = 0; 644: static struct file_name_list *last_before_system = 0; /* Last in chain */ 645: 1.1 root 646: /* List of included files that contained #pragma once. */ 647: static struct file_name_list *dont_repeat_files = 0; 648: 649: /* List of other included files. 650: If ->control_macro if nonzero, the file had a #ifndef 651: around the entire contents, and ->control_macro gives the macro name. */ 652: static struct file_name_list *all_include_files = 0; 653: 1.1.1.3 root 654: /* Directory prefix that should replace `/usr' in the standard 655: include file directories. */ 656: static char *include_prefix; 657: 1.1 root 658: /* Global list of strings read in from precompiled files. This list 659: is kept in the order the strings are read in, with new strings being 660: added at the end through stringlist_tailp. We use this list to output 661: the strings at the end of the run. 662: */ 663: static STRINGDEF *stringlist; 664: static STRINGDEF **stringlist_tailp = &stringlist; 665: 666: 667: /* Structure returned by create_definition */ 668: typedef struct macrodef MACRODEF; 669: struct macrodef 670: { 671: struct definition *defn; 672: U_CHAR *symnam; 673: int symlen; 674: }; 1.1.1.8 ! root 675: ! 676: enum sharp_token_type { ! 677: NO_SHARP_TOKEN = 0, /* token not present */ 1.1 root 678: 1.1.1.8 ! root 679: SHARP_TOKEN = '#', /* token spelled with # only */ ! 680: WHITE_SHARP_TOKEN, /* token spelled with # and white space */ ! 681: ! 682: PERCENT_COLON_TOKEN = '%', /* token spelled with %: only */ ! 683: WHITE_PERCENT_COLON_TOKEN /* token spelled with %: and white space */ ! 684: }; 1.1.1.4 root 685: 1.1 root 686: /* Structure allocated for every #define. For a simple replacement 687: such as 688: #define foo bar , 689: nargs = -1, the `pattern' list is null, and the expansion is just 690: the replacement text. Nargs = 0 means a functionlike macro with no args, 691: e.g., 692: #define getchar() getc (stdin) . 693: When there are args, the expansion is the replacement text with the 694: args squashed out, and the reflist is a list describing how to 695: build the output from the input: e.g., "3 chars, then the 1st arg, 696: then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg". 697: The chars here come from the expansion. Whatever is left of the 698: expansion after the last arg-occurrence is copied after that arg. 699: Note that the reflist can be arbitrarily long--- 700: its length depends on the number of times the arguments appear in 701: the replacement text, not how many args there are. Example: 702: #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and 703: pattern list 704: { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL } 705: where (x, y) means (nchars, argno). */ 706: 707: typedef struct definition DEFINITION; 708: struct definition { 709: int nargs; 710: int length; /* length of expansion string */ 711: int predefined; /* True if the macro was builtin or */ 712: /* came from the command line */ 713: U_CHAR *expansion; 714: int line; /* Line number of definition */ 715: char *file; /* File of definition */ 1.1.1.3 root 716: char rest_args; /* Nonzero if last arg. absorbs the rest */ 1.1 root 717: struct reflist { 718: struct reflist *next; 1.1.1.8 ! root 719: ! 720: enum sharp_token_type stringify; /* set if a # operator before arg */ ! 721: enum sharp_token_type raw_before; /* set if a ## operator before arg */ ! 722: enum sharp_token_type raw_after; /* set if a ## operator after arg */ ! 723: 1.1.1.3 root 724: char rest_args; /* Nonzero if this arg. absorbs the rest */ 1.1 root 725: int nchars; /* Number of literal chars to copy before 726: this arg occurrence. */ 727: int argno; /* Number of arg to substitute (origin-0) */ 728: } *pattern; 729: union { 730: /* Names of macro args, concatenated in reverse order 731: with comma-space between them. 732: The only use of this is that we warn on redefinition 733: if this differs between the old and new definitions. */ 734: U_CHAR *argnames; 735: } args; 736: }; 737: 738: /* different kinds of things that can appear in the value field 739: of a hash node. Actually, this may be useless now. */ 740: union hashval { 741: char *cpval; 742: DEFINITION *defn; 743: KEYDEF *keydef; 744: }; 745: 1.1.1.3 root 746: /* 747: * special extension string that can be added to the last macro argument to 748: * allow it to absorb the "rest" of the arguments when expanded. Ex: 1.1.1.5 root 749: * #define wow(a, b...) process (b, a, b) 750: * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); } 751: * { wow (one, two); } -> { process (two, one, two); } 1.1.1.3 root 752: * if this "rest_arg" is used with the concat token '##' and if it is not 1.1.1.4 root 753: * supplied then the token attached to with ## will not be outputted. Ex: 1.1.1.5 root 754: * #define wow (a, b...) process (b ## , a, ## b) 755: * { wow (1, 2); } -> { process (2, 1, 2); } 756: * { wow (one); } -> { process (one); { 1.1.1.3 root 757: */ 758: static char rest_extension[] = "..."; 759: #define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) 1.1 root 760: 761: /* The structure of a node in the hash table. The hash table 1.1.1.8 ! root 762: has entries for all tokens defined by #define directives (type T_MACRO), 1.1 root 763: plus some special tokens like __LINE__ (these each have their own 764: type, and the appropriate code is run when that type of node is seen. 765: It does not contain control words like "#define", which are recognized 766: by a separate piece of code. */ 767: 768: /* different flavors of hash nodes --- also used in keyword table */ 769: enum node_type { 770: T_DEFINE = 1, /* the `#define' keyword */ 771: T_INCLUDE, /* the `#include' keyword */ 772: T_INCLUDE_NEXT, /* the `#include_next' keyword */ 773: T_IMPORT, /* the `#import' keyword */ 774: T_IFDEF, /* the `#ifdef' keyword */ 775: T_IFNDEF, /* the `#ifndef' keyword */ 776: T_IF, /* the `#if' keyword */ 777: T_ELSE, /* `#else' */ 778: T_PRAGMA, /* `#pragma' */ 779: T_ELIF, /* `#elif' */ 780: T_UNDEF, /* `#undef' */ 781: T_LINE, /* `#line' */ 782: T_ERROR, /* `#error' */ 783: T_WARNING, /* `#warning' */ 784: T_ENDIF, /* `#endif' */ 785: T_SCCS, /* `#sccs', used on system V. */ 786: T_IDENT, /* `#ident', used on system V. */ 787: T_ASSERT, /* `#assert', taken from system V. */ 788: T_UNASSERT, /* `#unassert', taken from system V. */ 789: T_SPECLINE, /* special symbol `__LINE__' */ 790: T_DATE, /* `__DATE__' */ 791: T_FILE, /* `__FILE__' */ 792: T_BASE_FILE, /* `__BASE_FILE__' */ 793: T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ 794: T_VERSION, /* `__VERSION__' */ 795: T_SIZE_TYPE, /* `__SIZE_TYPE__' */ 796: T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */ 797: T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */ 1.1.1.5 root 798: T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */ 799: T_REGISTER_PREFIX_TYPE, /* `__REGISTER_PREFIX__' */ 1.1.1.8 ! root 800: T_IMMEDIATE_PREFIX_TYPE, /* `__IMMEDIATE_PREFIX__' */ 1.1 root 801: T_TIME, /* `__TIME__' */ 802: T_CONST, /* Constant value, used by `__STDC__' */ 803: T_MACRO, /* macro defined by `#define' */ 804: T_DISABLED, /* macro temporarily turned off for rescan */ 805: T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */ 806: T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */ 807: T_UNUSED /* Used for something not defined. */ 808: }; 809: 810: struct hashnode { 811: struct hashnode *next; /* double links for easy deletion */ 812: struct hashnode *prev; 813: struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash 814: chain is kept, in case the node is the head 815: of the chain and gets deleted. */ 816: enum node_type type; /* type of special token */ 817: int length; /* length of token, for quick comparison */ 818: U_CHAR *name; /* the actual name */ 819: union hashval value; /* pointer to expansion, or whatever */ 820: }; 821: 822: typedef struct hashnode HASHNODE; 823: 824: /* Some definitions for the hash table. The hash function MUST be 825: computed as shown in hashf () below. That is because the rescan 826: loop computes the hash value `on the fly' for most tokens, 827: in order to avoid the overhead of a lot of procedure calls to 828: the hashf () function. Hashf () only exists for the sake of 829: politeness, for use when speed isn't so important. */ 830: 831: #define HASHSIZE 1403 832: static HASHNODE *hashtab[HASHSIZE]; 833: #define HASHSTEP(old, c) ((old << 2) + c) 834: #define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */ 835: 836: /* Symbols to predefine. */ 837: 838: #ifdef CPP_PREDEFINES 839: static char *predefs = CPP_PREDEFINES; 840: #else 841: static char *predefs = ""; 842: #endif 843: 844: /* We let tm.h override the types used here, to handle trivial differences 845: such as the choice of unsigned int or long unsigned int for size_t. 846: When machines start needing nontrivial differences in the size type, 847: it would be best to do something here to figure out automatically 848: from other information what type to use. */ 849: 1.1.1.7 root 850: /* The string value for __SIZE_TYPE__. */ 1.1 root 851: 852: #ifndef SIZE_TYPE 853: #define SIZE_TYPE "long unsigned int" 854: #endif 855: 1.1.1.7 root 856: /* The string value for __PTRDIFF_TYPE__. */ 1.1 root 857: 858: #ifndef PTRDIFF_TYPE 859: #define PTRDIFF_TYPE "long int" 860: #endif 861: 1.1.1.7 root 862: /* The string value for __WCHAR_TYPE__. */ 1.1 root 863: 864: #ifndef WCHAR_TYPE 865: #define WCHAR_TYPE "int" 866: #endif 1.1.1.7 root 867: char * wchar_type = WCHAR_TYPE; 868: #undef WCHAR_TYPE 1.1.1.5 root 869: 870: /* The string value for __USER_LABEL_PREFIX__ */ 871: 872: #ifndef USER_LABEL_PREFIX 873: #define USER_LABEL_PREFIX "" 874: #endif 875: 876: /* The string value for __REGISTER_PREFIX__ */ 877: 878: #ifndef REGISTER_PREFIX 879: #define REGISTER_PREFIX "" 880: #endif 1.1.1.8 ! root 881: ! 882: /* The string value for __IMMEDIATE_PREFIX__ */ ! 883: ! 884: #ifndef IMMEDIATE_PREFIX ! 885: #define IMMEDIATE_PREFIX "" ! 886: #endif 1.1 root 887: 888: /* In the definition of a #assert name, this structure forms 889: a list of the individual values asserted. 890: Each value is itself a list of "tokens". 891: These are strings that are compared by name. */ 892: 893: struct tokenlist_list { 894: struct tokenlist_list *next; 895: struct arglist *tokens; 896: }; 897: 898: struct assertion_hashnode { 899: struct assertion_hashnode *next; /* double links for easy deletion */ 900: struct assertion_hashnode *prev; 901: /* also, a back pointer to this node's hash 902: chain is kept, in case the node is the head 903: of the chain and gets deleted. */ 904: struct assertion_hashnode **bucket_hdr; 905: int length; /* length of token, for quick comparison */ 906: U_CHAR *name; /* the actual name */ 907: /* List of token-sequences. */ 908: struct tokenlist_list *value; 909: }; 910: 911: typedef struct assertion_hashnode ASSERTION_HASHNODE; 912: 913: /* Some definitions for the hash table. The hash function MUST be 1.1.1.4 root 914: computed as shown in hashf below. That is because the rescan 1.1 root 915: loop computes the hash value `on the fly' for most tokens, 916: in order to avoid the overhead of a lot of procedure calls to 1.1.1.4 root 917: the hashf function. hashf only exists for the sake of 1.1 root 918: politeness, for use when speed isn't so important. */ 919: 920: #define ASSERTION_HASHSIZE 37 921: static ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE]; 922: 923: /* Nonzero means inhibit macroexpansion of what seem to be 924: assertion tests, in rescan. For #if. */ 925: static int assertions_flag; 926: 927: /* `struct directive' defines one #-directive, including how to handle it. */ 928: 1.1.1.8 ! root 929: #define DO_PROTO PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *)) ! 930: 1.1 root 931: struct directive { 932: int length; /* Length of name */ 1.1.1.8 ! root 933: int (*func) DO_PROTO; /* Function to handle directive */ 1.1 root 934: char *name; /* Name of directive */ 935: enum node_type type; /* Code which describes which directive. */ 936: char angle_brackets; /* Nonzero => <...> is special. */ 937: char traditional_comments; /* Nonzero: keep comments if -traditional. */ 938: char pass_thru; /* Copy preprocessed directive to output file. */ 939: }; 940: 1.1.1.8 ! root 941: /* These functions are declared to return int instead of void since they ! 942: are going to be placed in the table and some old compilers have trouble with ! 943: pointers to functions returning void. */ ! 944: ! 945: static int do_assert DO_PROTO; ! 946: static int do_define DO_PROTO; ! 947: static int do_elif DO_PROTO; ! 948: static int do_else DO_PROTO; ! 949: static int do_endif DO_PROTO; ! 950: static int do_error DO_PROTO; ! 951: static int do_ident DO_PROTO; ! 952: static int do_if DO_PROTO; ! 953: static int do_include DO_PROTO; ! 954: static int do_line DO_PROTO; ! 955: static int do_pragma DO_PROTO; ! 956: #ifdef SCCS_DIRECTIVE ! 957: static int do_sccs DO_PROTO; ! 958: #endif ! 959: static int do_unassert DO_PROTO; ! 960: static int do_undef DO_PROTO; ! 961: static int do_warning DO_PROTO; ! 962: static int do_xifdef DO_PROTO; ! 963: 1.1 root 964: /* Here is the actual list of #-directives, most-often-used first. */ 965: 966: static struct directive directive_table[] = { 967: { 6, do_define, "define", T_DEFINE, 0, 1}, 968: { 2, do_if, "if", T_IF}, 969: { 5, do_xifdef, "ifdef", T_IFDEF}, 970: { 6, do_xifdef, "ifndef", T_IFNDEF}, 971: { 5, do_endif, "endif", T_ENDIF}, 972: { 4, do_else, "else", T_ELSE}, 973: { 4, do_elif, "elif", T_ELIF}, 974: { 4, do_line, "line", T_LINE}, 975: { 7, do_include, "include", T_INCLUDE, 1}, 976: { 12, do_include, "include_next", T_INCLUDE_NEXT, 1}, 977: { 6, do_include, "import", T_IMPORT, 1}, 978: { 5, do_undef, "undef", T_UNDEF}, 979: { 5, do_error, "error", T_ERROR}, 980: { 7, do_warning, "warning", T_WARNING}, 981: #ifdef SCCS_DIRECTIVE 982: { 4, do_sccs, "sccs", T_SCCS}, 983: #endif 984: { 6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1}, 1.1.1.6 root 985: { 5, do_ident, "ident", T_IDENT}, 1.1 root 986: { 6, do_assert, "assert", T_ASSERT}, 987: { 8, do_unassert, "unassert", T_UNASSERT}, 988: { -1, 0, "", T_UNUSED}, 989: }; 990: 991: /* When a directive handler is called, 1.1.1.8 ! root 992: this points to the # (or the : of the %:) that started the directive. */ 1.1 root 993: U_CHAR *directive_start; 994: 995: /* table to tell if char can be part of a C identifier. */ 996: U_CHAR is_idchar[256]; 997: /* table to tell if char can be first char of a c identifier. */ 998: U_CHAR is_idstart[256]; 999: /* table to tell if c is horizontal space. */ 1000: U_CHAR is_hor_space[256]; 1001: /* table to tell if c is horizontal or vertical space. */ 1002: static U_CHAR is_space[256]; 1.1.1.8 ! root 1003: /* names of some characters */ ! 1004: static char *char_name[256]; 1.1 root 1005: 1006: #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0) 1007: #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0) 1008: 1009: static int errors = 0; /* Error counter for exit code */ 1010: 1.1.1.5 root 1011: /* Name of output file, for error messages. */ 1012: static char *out_fname; 1013: 1.1 root 1014: /* Zero means dollar signs are punctuation. 1015: -$ stores 0; -traditional may store 1. Default is 1 for VMS, 0 otherwise. 1016: This must be 0 for correct processing of this ANSI C program: 1017: #define foo(a) #a 1.1.1.5 root 1018: #define lose(b) foo (b) 1.1 root 1019: #define test$ 1.1.1.5 root 1020: lose (test) */ 1.1 root 1021: static int dollars_in_ident; 1022: #ifndef DOLLARS_IN_IDENTIFIERS 1023: #define DOLLARS_IN_IDENTIFIERS 1 1024: #endif 1025: 1026: 1027: /* Stack of conditionals currently in progress 1028: (including both successful and failing conditionals). */ 1029: 1030: struct if_stack { 1031: struct if_stack *next; /* for chaining to the next stack frame */ 1032: char *fname; /* copied from input when frame is made */ 1033: int lineno; /* similarly */ 1034: int if_succeeded; /* true if a leg of this if-group 1035: has been passed through rescan */ 1036: U_CHAR *control_macro; /* For #ifndef at start of file, 1037: this is the macro name tested. */ 1038: enum node_type type; /* type of last directive seen in this group */ 1039: }; 1040: typedef struct if_stack IF_STACK_FRAME; 1041: static IF_STACK_FRAME *if_stack = NULL; 1042: 1043: /* Buffer of -M output. */ 1044: static char *deps_buffer; 1045: 1046: /* Number of bytes allocated in above. */ 1047: static int deps_allocated_size; 1048: 1049: /* Number of bytes used. */ 1050: static int deps_size; 1051: 1052: /* Number of bytes since the last newline. */ 1053: static int deps_column; 1054: 1055: /* Nonzero means -I- has been seen, 1056: so don't look for #include "foo" the source-file directory. */ 1057: static int ignore_srcdir; 1058: 1.1.1.8 ! root 1059: static int safe_read PROTO((int, char *, int)); ! 1060: static void safe_write PROTO((int, char *, int)); ! 1061: ! 1062: int main PROTO((int, char **)); ! 1063: ! 1064: static void path_include PROTO((char *)); ! 1065: ! 1066: static U_CHAR *index0 PROTO((U_CHAR *, int, size_t)); ! 1067: ! 1068: static void trigraph_pcp PROTO((FILE_BUF *)); ! 1069: ! 1070: static void newline_fix PROTO((U_CHAR *)); ! 1071: static void name_newline_fix PROTO((U_CHAR *)); ! 1072: ! 1073: static char *get_lintcmd PROTO((U_CHAR *, U_CHAR *, U_CHAR **, int *, int *)); ! 1074: ! 1075: static void rescan PROTO((FILE_BUF *, int)); ! 1076: ! 1077: static FILE_BUF expand_to_temp_buffer PROTO((U_CHAR *, U_CHAR *, int, int)); ! 1078: ! 1079: static int handle_directive PROTO((FILE_BUF *, FILE_BUF *)); ! 1080: ! 1081: static struct tm *timestamp PROTO((void)); ! 1082: static void special_symbol PROTO((HASHNODE *, FILE_BUF *)); ! 1083: ! 1084: static int redundant_include_p PROTO((char *)); ! 1085: static int is_system_include PROTO((char *)); ! 1086: static char *skip_redundant_dir_prefix PROTO((char *)); ! 1087: ! 1088: static char *read_filename_string PROTO((int, FILE *)); ! 1089: static struct file_name_map *read_name_map PROTO((char *)); ! 1090: static int open_include_file PROTO((char *, struct file_name_list *)); ! 1091: ! 1092: static void finclude PROTO((int, char *, FILE_BUF *, int, struct file_name_list *)); ! 1093: static void record_control_macro PROTO((char *, U_CHAR *)); ! 1094: ! 1095: static int import_hash PROTO((char *)); ! 1096: static int lookup_import PROTO((char *, struct file_name_list *)); ! 1097: static void add_import PROTO((int, char *)); ! 1098: ! 1099: static char *check_precompiled PROTO((int, char *, char **)); ! 1100: static int check_preconditions PROTO((char *)); ! 1101: static void pcfinclude PROTO((U_CHAR *, U_CHAR *, U_CHAR *, FILE_BUF *)); ! 1102: static void pcstring_used PROTO((HASHNODE *)); ! 1103: static void write_output PROTO((void)); ! 1104: static void pass_thru_directive PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *)); ! 1105: ! 1106: static MACRODEF create_definition PROTO((U_CHAR *, U_CHAR *, FILE_BUF *)); ! 1107: ! 1108: static int check_macro_name PROTO((U_CHAR *, char *)); ! 1109: static int compare_defs PROTO((DEFINITION *, DEFINITION *)); ! 1110: static int comp_def_part PROTO((int, U_CHAR *, int, U_CHAR *, int, int)); ! 1111: ! 1112: static DEFINITION *collect_expansion PROTO((U_CHAR *, U_CHAR *, int, struct arglist *)); ! 1113: ! 1114: int check_assertion PROTO((U_CHAR *, int, int, struct arglist *)); ! 1115: static int compare_token_lists PROTO((struct arglist *, struct arglist *)); ! 1116: ! 1117: static struct arglist *read_token_list PROTO((U_CHAR **, U_CHAR *, int *)); ! 1118: static void free_token_list PROTO((struct arglist *)); ! 1119: ! 1120: static ASSERTION_HASHNODE *assertion_install PROTO((U_CHAR *, int, int)); ! 1121: static ASSERTION_HASHNODE *assertion_lookup PROTO((U_CHAR *, int, int)); ! 1122: static void delete_assertion PROTO((ASSERTION_HASHNODE *)); ! 1123: ! 1124: static void do_once PROTO((void)); ! 1125: ! 1126: static HOST_WIDE_INT eval_if_expression PROTO((U_CHAR *, int)); ! 1127: static void conditional_skip PROTO((FILE_BUF *, int, enum node_type, U_CHAR *, FILE_BUF *)); ! 1128: static void skip_if_group PROTO((FILE_BUF *, int, FILE_BUF *)); ! 1129: static void validate_else PROTO((U_CHAR *)); ! 1130: ! 1131: static U_CHAR *skip_to_end_of_comment PROTO((FILE_BUF *, int *, int)); ! 1132: static U_CHAR *skip_quoted_string PROTO((U_CHAR *, U_CHAR *, int, int *, int *, int *)); ! 1133: static char *quote_string PROTO((char *, char *)); ! 1134: static U_CHAR *skip_paren_group PROTO((FILE_BUF *)); ! 1135: ! 1136: /* Last arg to output_line_directive. */ ! 1137: enum file_change_code {same_file, enter_file, leave_file}; ! 1138: static void output_line_directive PROTO((FILE_BUF *, FILE_BUF *, int, enum file_change_code)); ! 1139: ! 1140: static void macroexpand PROTO((HASHNODE *, FILE_BUF *)); ! 1141: ! 1142: struct argdata; ! 1143: static char *macarg PROTO((struct argdata *, int)); ! 1144: ! 1145: static U_CHAR *macarg1 PROTO((U_CHAR *, U_CHAR *, int *, int *, int *, int)); ! 1146: ! 1147: static int discard_comments PROTO((U_CHAR *, int, int)); ! 1148: ! 1149: static int change_newlines PROTO((U_CHAR *, int)); ! 1150: ! 1151: char *my_strerror PROTO((int)); ! 1152: void error PRINTF_PROTO_1((char *, ...)); ! 1153: static void verror PROTO((char *, va_list)); ! 1154: static void error_from_errno PROTO((char *)); ! 1155: void warning PRINTF_PROTO_1((char *, ...)); ! 1156: static void vwarning PROTO((char *, va_list)); ! 1157: static void error_with_line PRINTF_PROTO_2((int, char *, ...)); ! 1158: static void verror_with_line PROTO((int, char *, va_list)); ! 1159: static void vwarning_with_line PROTO((int, char *, va_list)); ! 1160: static void warning_with_line PRINTF_PROTO_2((int, char *, ...)); ! 1161: void pedwarn PRINTF_PROTO_1((char *, ...)); ! 1162: void pedwarn_with_line PRINTF_PROTO_2((int, char *, ...)); ! 1163: static void pedwarn_with_file_and_line PRINTF_PROTO_3((char *, int, char *, ...)); ! 1164: ! 1165: static void print_containing_files PROTO((void)); ! 1166: ! 1167: static int line_for_error PROTO((int)); ! 1168: static int grow_outbuf PROTO((FILE_BUF *, int)); ! 1169: ! 1170: static HASHNODE *install PROTO((U_CHAR *, int, enum node_type, char *, int)); ! 1171: HASHNODE *lookup PROTO((U_CHAR *, int, int)); ! 1172: static void delete_macro PROTO((HASHNODE *)); ! 1173: static int hashf PROTO((U_CHAR *, int, int)); ! 1174: ! 1175: static void dump_single_macro PROTO((HASHNODE *, FILE *)); ! 1176: static void dump_all_macros PROTO((void)); ! 1177: static void dump_defn_1 PROTO((U_CHAR *, int, int, FILE *)); ! 1178: static void dump_arg_n PROTO((DEFINITION *, int, FILE *)); ! 1179: ! 1180: static void initialize_char_syntax PROTO((void)); ! 1181: static void initialize_builtins PROTO((FILE_BUF *, FILE_BUF *)); ! 1182: ! 1183: static void make_definition PROTO((char *, FILE_BUF *)); ! 1184: static void make_undef PROTO((char *, FILE_BUF *)); ! 1185: ! 1186: static void make_assertion PROTO((char *, char *)); ! 1187: ! 1188: static void append_include_chain PROTO((struct file_name_list *, struct file_name_list *)); ! 1189: ! 1190: static void deps_output PROTO((char *, int)); ! 1191: ! 1192: static void fatal PRINTF_PROTO_1((char *, ...)) __attribute__ ((noreturn)); ! 1193: void fancy_abort PROTO((void)) __attribute__ ((noreturn)); ! 1194: static void perror_with_name PROTO((char *)); ! 1195: static void pfatal_with_name PROTO((char *)) __attribute__ ((noreturn)); ! 1196: static void pipe_closed PROTO((int)) __attribute__ ((noreturn)); ! 1197: ! 1198: static void memory_full PROTO((void)) __attribute__ ((noreturn)); ! 1199: GENERIC_PTR xmalloc PROTO((size_t)); ! 1200: static GENERIC_PTR xrealloc PROTO((GENERIC_PTR, size_t)); ! 1201: static GENERIC_PTR xcalloc PROTO((size_t, size_t)); ! 1202: static char *savestring PROTO((char *)); ! 1203: ! 1204: static int file_size_and_mode PROTO((int, int *, long int *)); ! 1205: 1.1.1.6 root 1206: /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME, 1.1.1.7 root 1207: retrying if necessary. Return a negative value if an error occurs, 1208: otherwise return the actual number of bytes read, 1209: which must be LEN unless end-of-file was reached. */ 1.1.1.6 root 1210: 1211: static int 1212: safe_read (desc, ptr, len) 1213: int desc; 1214: char *ptr; 1215: int len; 1216: { 1217: int left = len; 1218: while (left > 0) { 1219: int nchars = read (desc, ptr, left); 1220: if (nchars < 0) 1221: { 1222: #ifdef EINTR 1223: if (errno == EINTR) 1224: continue; 1225: #endif 1226: return nchars; 1227: } 1228: if (nchars == 0) 1229: break; 1230: ptr += nchars; 1231: left -= nchars; 1232: } 1233: return len - left; 1234: } 1235: 1236: /* Write LEN bytes at PTR to descriptor DESC, 1237: retrying if necessary, and treating any real error as fatal. */ 1238: 1239: static void 1240: safe_write (desc, ptr, len) 1241: int desc; 1242: char *ptr; 1243: int len; 1244: { 1245: while (len > 0) { 1246: int written = write (desc, ptr, len); 1247: if (written < 0) 1248: { 1249: #ifdef EINTR 1250: if (errno == EINTR) 1251: continue; 1252: #endif 1253: pfatal_with_name (out_fname); 1254: } 1255: ptr += written; 1256: len -= written; 1257: } 1258: } 1259: 1.1 root 1260: int 1261: main (argc, argv) 1262: int argc; 1263: char **argv; 1264: { 1265: int st_mode; 1266: long st_size; 1.1.1.5 root 1267: char *in_fname; 1.1.1.8 ! root 1268: char *cp; 1.1 root 1269: int f, i; 1270: FILE_BUF *fp; 1271: char **pend_files = (char **) xmalloc (argc * sizeof (char *)); 1272: char **pend_defs = (char **) xmalloc (argc * sizeof (char *)); 1273: char **pend_undefs = (char **) xmalloc (argc * sizeof (char *)); 1274: char **pend_assertions = (char **) xmalloc (argc * sizeof (char *)); 1275: char **pend_includes = (char **) xmalloc (argc * sizeof (char *)); 1276: 1277: /* Record the option used with each element of pend_assertions. 1278: This is preparation for supporting more than one option for making 1279: an assertion. */ 1280: char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *)); 1281: int inhibit_predefs = 0; 1282: int no_standard_includes = 0; 1.1.1.3 root 1283: int no_standard_cplusplus_includes = 0; 1.1 root 1284: int missing_newline = 0; 1285: 1286: /* Non-0 means don't output the preprocessed program. */ 1287: int inhibit_output = 0; 1.1.1.6 root 1288: /* Non-0 means -v, so print the full set of include dirs. */ 1289: int verbose = 0; 1.1 root 1290: 1.1.1.4 root 1291: /* File name which deps are being written to. 1292: This is 0 if deps are being written to stdout. */ 1293: char *deps_file = 0; 1.1.1.5 root 1294: /* Fopen file mode to open deps_file with. */ 1295: char *deps_mode = "a"; 1.1 root 1296: /* Stream on which to print the dependency information. */ 1297: FILE *deps_stream = 0; 1298: /* Target-name to write with the dependency information. */ 1299: char *deps_target = 0; 1300: 1301: #ifdef RLIMIT_STACK 1302: /* Get rid of any avoidable limit on stack size. */ 1303: { 1304: struct rlimit rlim; 1305: 1306: /* Set the stack limit huge so that alloca (particularly stringtab 1307: * in dbxread.c) does not fail. */ 1308: getrlimit (RLIMIT_STACK, &rlim); 1309: rlim.rlim_cur = rlim.rlim_max; 1310: setrlimit (RLIMIT_STACK, &rlim); 1311: } 1312: #endif /* RLIMIT_STACK defined */ 1313: 1.1.1.6 root 1314: #ifdef SIGPIPE 1.1.1.5 root 1315: signal (SIGPIPE, pipe_closed); 1.1.1.6 root 1316: #endif 1.1.1.5 root 1317: 1.1.1.8 ! root 1318: cp = argv[0] + strlen (argv[0]); ! 1319: while (cp != argv[0] && cp[-1] != '/' 1.1.1.7 root 1320: #ifdef DIR_SEPARATOR 1.1.1.8 ! root 1321: && cp[-1] != DIR_SEPARATOR 1.1.1.7 root 1322: #endif 1323: ) 1.1.1.8 ! root 1324: --cp; ! 1325: progname = cp; 1.1.1.5 root 1326: 1.1 root 1327: #ifdef VMS 1328: { 1329: /* Remove directories from PROGNAME. */ 1.1.1.8 ! root 1330: char *p; ! 1331: char *s = progname; 1.1 root 1332: 1.1.1.8 ! root 1333: if ((p = rindex (s, ':')) != 0) s = p + 1; /* skip device */ ! 1334: if ((p = rindex (s, ']')) != 0) s = p + 1; /* skip directory */ ! 1335: if ((p = rindex (s, '>')) != 0) s = p + 1; /* alternate (int'n'l) dir */ ! 1336: s = progname = savestring (s); ! 1337: if ((p = rindex (s, ';')) != 0) *p = '\0'; /* strip version number */ ! 1338: if ((p = rindex (s, '.')) != 0 /* strip type iff ".exe" */ ! 1339: && (p[1] == 'e' || p[1] == 'E') ! 1340: && (p[2] == 'x' || p[2] == 'X') ! 1341: && (p[3] == 'e' || p[3] == 'E') ! 1342: && !p[4]) ! 1343: *p = '\0'; 1.1 root 1344: } 1345: #endif 1346: 1347: in_fname = NULL; 1348: out_fname = NULL; 1349: 1350: /* Initialize is_idchar to allow $. */ 1351: dollars_in_ident = 1; 1352: initialize_char_syntax (); 1353: dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0; 1354: 1.1.1.8 ! root 1355: no_line_directives = 0; 1.1 root 1356: no_trigraphs = 1; 1357: dump_macros = dump_none; 1358: no_output = 0; 1359: cplusplus = 0; 1.1.1.8 ! root 1360: cplusplus_comments = 1; 1.1 root 1361: 1.1.1.7 root 1362: bzero ((char *) pend_files, argc * sizeof (char *)); 1363: bzero ((char *) pend_defs, argc * sizeof (char *)); 1364: bzero ((char *) pend_undefs, argc * sizeof (char *)); 1365: bzero ((char *) pend_assertions, argc * sizeof (char *)); 1366: bzero ((char *) pend_includes, argc * sizeof (char *)); 1.1 root 1367: 1368: /* Process switches and find input file name. */ 1369: 1370: for (i = 1; i < argc; i++) { 1371: if (argv[i][0] != '-') { 1372: if (out_fname != NULL) 1373: fatal ("Usage: %s [switches] input output", argv[0]); 1374: else if (in_fname != NULL) 1375: out_fname = argv[i]; 1376: else 1377: in_fname = argv[i]; 1378: } else { 1379: switch (argv[i][1]) { 1380: 1381: case 'i': 1382: if (!strcmp (argv[i], "-include")) { 1383: if (i + 1 == argc) 1.1.1.5 root 1384: fatal ("Filename missing after `-include' option"); 1.1 root 1385: else 1386: pend_includes[i] = argv[i+1], i++; 1387: } 1388: if (!strcmp (argv[i], "-imacros")) { 1389: if (i + 1 == argc) 1.1.1.5 root 1390: fatal ("Filename missing after `-imacros' option"); 1.1 root 1391: else 1392: pend_files[i] = argv[i+1], i++; 1393: } 1.1.1.3 root 1394: if (!strcmp (argv[i], "-iprefix")) { 1395: if (i + 1 == argc) 1.1.1.5 root 1396: fatal ("Filename missing after `-iprefix' option"); 1.1.1.3 root 1397: else 1398: include_prefix = argv[++i]; 1399: } 1.1.1.7 root 1400: if (!strcmp (argv[i], "-ifoutput")) { 1401: output_conditionals = 1; 1402: } 1403: if (!strcmp (argv[i], "-isystem")) { 1404: struct file_name_list *dirtmp; 1405: 1406: if (i + 1 == argc) 1407: fatal ("Filename missing after `-isystem' option"); 1408: 1409: dirtmp = (struct file_name_list *) 1410: xmalloc (sizeof (struct file_name_list)); 1411: dirtmp->next = 0; 1412: dirtmp->control_macro = 0; 1413: dirtmp->c_system_include_path = 1; 1.1.1.8 ! root 1414: dirtmp->fname = xmalloc (strlen (argv[i+1]) + 1); 1.1.1.7 root 1415: strcpy (dirtmp->fname, argv[++i]); 1416: dirtmp->got_name_map = 0; 1417: 1418: if (before_system == 0) 1419: before_system = dirtmp; 1420: else 1421: last_before_system->next = dirtmp; 1422: last_before_system = dirtmp; /* Tail follows the last one */ 1423: } 1.1.1.5 root 1424: /* Add directory to end of path for includes, 1425: with the default prefix at the front of its name. */ 1426: if (!strcmp (argv[i], "-iwithprefix")) { 1427: struct file_name_list *dirtmp; 1.1.1.6 root 1428: char *prefix; 1429: 1430: if (include_prefix != 0) 1431: prefix = include_prefix; 1432: else { 1433: prefix = savestring (GCC_INCLUDE_DIR); 1434: /* Remove the `include' from /usr/local/lib/gcc.../include. */ 1435: if (!strcmp (prefix + strlen (prefix) - 8, "/include")) 1436: prefix[strlen (prefix) - 7] = 0; 1437: } 1.1.1.5 root 1438: 1439: dirtmp = (struct file_name_list *) 1440: xmalloc (sizeof (struct file_name_list)); 1441: dirtmp->next = 0; /* New one goes on the end */ 1442: dirtmp->control_macro = 0; 1.1.1.6 root 1443: dirtmp->c_system_include_path = 0; 1.1.1.5 root 1444: if (i + 1 == argc) 1445: fatal ("Directory name missing after `-iwithprefix' option"); 1446: 1.1.1.8 ! root 1447: dirtmp->fname = xmalloc (strlen (argv[i+1]) + strlen (prefix) + 1); 1.1.1.6 root 1448: strcpy (dirtmp->fname, prefix); 1.1.1.5 root 1449: strcat (dirtmp->fname, argv[++i]); 1.1.1.7 root 1450: dirtmp->got_name_map = 0; 1.1.1.5 root 1451: 1452: if (after_include == 0) 1453: after_include = dirtmp; 1454: else 1455: last_after_include->next = dirtmp; 1456: last_after_include = dirtmp; /* Tail follows the last one */ 1457: } 1.1.1.6 root 1458: /* Add directory to main path for includes, 1459: with the default prefix at the front of its name. */ 1460: if (!strcmp (argv[i], "-iwithprefixbefore")) { 1461: struct file_name_list *dirtmp; 1462: char *prefix; 1463: 1464: if (include_prefix != 0) 1465: prefix = include_prefix; 1466: else { 1467: prefix = savestring (GCC_INCLUDE_DIR); 1468: /* Remove the `include' from /usr/local/lib/gcc.../include. */ 1469: if (!strcmp (prefix + strlen (prefix) - 8, "/include")) 1470: prefix[strlen (prefix) - 7] = 0; 1471: } 1472: 1473: dirtmp = (struct file_name_list *) 1474: xmalloc (sizeof (struct file_name_list)); 1475: dirtmp->next = 0; /* New one goes on the end */ 1476: dirtmp->control_macro = 0; 1477: dirtmp->c_system_include_path = 0; 1478: if (i + 1 == argc) 1479: fatal ("Directory name missing after `-iwithprefixbefore' option"); 1480: 1.1.1.8 ! root 1481: dirtmp->fname = xmalloc (strlen (argv[i+1]) + strlen (prefix) + 1); 1.1.1.6 root 1482: strcpy (dirtmp->fname, prefix); 1483: strcat (dirtmp->fname, argv[++i]); 1.1.1.7 root 1484: dirtmp->got_name_map = 0; 1.1.1.6 root 1485: 1486: append_include_chain (dirtmp, dirtmp); 1487: } 1.1 root 1488: /* Add directory to end of path for includes. */ 1489: if (!strcmp (argv[i], "-idirafter")) { 1490: struct file_name_list *dirtmp; 1491: 1492: dirtmp = (struct file_name_list *) 1493: xmalloc (sizeof (struct file_name_list)); 1494: dirtmp->next = 0; /* New one goes on the end */ 1495: dirtmp->control_macro = 0; 1.1.1.6 root 1496: dirtmp->c_system_include_path = 0; 1.1 root 1497: if (i + 1 == argc) 1.1.1.5 root 1498: fatal ("Directory name missing after `-idirafter' option"); 1.1 root 1499: else 1500: dirtmp->fname = argv[++i]; 1.1.1.7 root 1501: dirtmp->got_name_map = 0; 1.1 root 1502: 1.1.1.4 root 1503: if (after_include == 0) 1504: after_include = dirtmp; 1505: else 1506: last_after_include->next = dirtmp; 1507: last_after_include = dirtmp; /* Tail follows the last one */ 1.1 root 1508: } 1509: break; 1510: 1511: case 'o': 1512: if (out_fname != NULL) 1513: fatal ("Output filename specified twice"); 1514: if (i + 1 == argc) 1515: fatal ("Filename missing after -o option"); 1516: out_fname = argv[++i]; 1517: if (!strcmp (out_fname, "-")) 1518: out_fname = ""; 1519: break; 1520: 1521: case 'p': 1522: if (!strcmp (argv[i], "-pedantic")) 1523: pedantic = 1; 1524: else if (!strcmp (argv[i], "-pedantic-errors")) { 1525: pedantic = 1; 1526: pedantic_errors = 1; 1527: } else if (!strcmp (argv[i], "-pcp")) { 1.1.1.7 root 1528: char *pcp_fname; 1529: if (i + 1 == argc) 1530: fatal ("Filename missing after -pcp option"); 1531: pcp_fname = argv[++i]; 1.1 root 1532: pcp_outfile = 1533: ((pcp_fname[0] != '-' || pcp_fname[1] != '\0') 1534: ? fopen (pcp_fname, "w") 1.1.1.8 ! root 1535: : stdout); 1.1 root 1536: if (pcp_outfile == 0) 1537: pfatal_with_name (pcp_fname); 1538: no_precomp = 1; 1539: } 1540: break; 1541: 1542: case 't': 1543: if (!strcmp (argv[i], "-traditional")) { 1544: traditional = 1; 1.1.1.8 ! root 1545: cplusplus_comments = 0; 1.1 root 1546: if (dollars_in_ident > 0) 1547: dollars_in_ident = 1; 1548: } else if (!strcmp (argv[i], "-trigraphs")) { 1549: no_trigraphs = 0; 1550: } 1551: break; 1552: 1553: case 'l': 1554: if (! strcmp (argv[i], "-lang-c")) 1.1.1.8 ! root 1555: cplusplus = 0, cplusplus_comments = 1, objc = 0; ! 1556: if (! strcmp (argv[i], "-lang-c89")) 1.1.1.4 root 1557: cplusplus = 0, cplusplus_comments = 0, objc = 0; 1.1 root 1558: if (! strcmp (argv[i], "-lang-c++")) 1.1.1.4 root 1559: cplusplus = 1, cplusplus_comments = 1, objc = 0; 1.1 root 1560: if (! strcmp (argv[i], "-lang-objc")) 1.1.1.4 root 1561: objc = 1, cplusplus = 0, cplusplus_comments = 1; 1.1 root 1562: if (! strcmp (argv[i], "-lang-objc++")) 1.1.1.4 root 1563: objc = 1, cplusplus = 1, cplusplus_comments = 1; 1.1 root 1564: if (! strcmp (argv[i], "-lang-asm")) 1565: lang_asm = 1; 1566: if (! strcmp (argv[i], "-lint")) 1.1.1.7 root 1567: for_lint = 1; 1.1 root 1568: break; 1569: 1570: case '+': 1.1.1.4 root 1571: cplusplus = 1, cplusplus_comments = 1; 1.1 root 1572: break; 1573: 1574: case 'w': 1575: inhibit_warnings = 1; 1576: break; 1577: 1578: case 'W': 1579: if (!strcmp (argv[i], "-Wtrigraphs")) 1580: warn_trigraphs = 1; 1581: else if (!strcmp (argv[i], "-Wno-trigraphs")) 1582: warn_trigraphs = 0; 1583: else if (!strcmp (argv[i], "-Wcomment")) 1584: warn_comments = 1; 1585: else if (!strcmp (argv[i], "-Wno-comment")) 1586: warn_comments = 0; 1587: else if (!strcmp (argv[i], "-Wcomments")) 1588: warn_comments = 1; 1589: else if (!strcmp (argv[i], "-Wno-comments")) 1590: warn_comments = 0; 1591: else if (!strcmp (argv[i], "-Wtraditional")) 1592: warn_stringify = 1; 1593: else if (!strcmp (argv[i], "-Wno-traditional")) 1594: warn_stringify = 0; 1.1.1.2 root 1595: else if (!strcmp (argv[i], "-Wimport")) 1596: warn_import = 1; 1597: else if (!strcmp (argv[i], "-Wno-import")) 1598: warn_import = 0; 1.1 root 1599: else if (!strcmp (argv[i], "-Werror")) 1600: warnings_are_errors = 1; 1601: else if (!strcmp (argv[i], "-Wno-error")) 1602: warnings_are_errors = 0; 1603: else if (!strcmp (argv[i], "-Wall")) 1604: { 1605: warn_trigraphs = 1; 1606: warn_comments = 1; 1607: } 1608: break; 1609: 1610: case 'M': 1.1.1.7 root 1611: /* The style of the choices here is a bit mixed. 1612: The chosen scheme is a hybrid of keeping all options in one string 1613: and specifying each option in a separate argument: 1614: -M|-MM|-MD file|-MMD file [-MG]. An alternative is: 1615: -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: 1616: -M[M][G][D file]. This is awkward to handle in specs, and is not 1617: as extensible. */ 1618: /* ??? -MG must be specified in addition to one of -M or -MM. 1619: This can be relaxed in the future without breaking anything. 1620: The converse isn't true. */ 1621: 1622: /* -MG isn't valid with -MD or -MMD. This is checked for later. */ 1623: if (!strcmp (argv[i], "-MG")) 1624: { 1625: print_deps_missing_files = 1; 1626: break; 1627: } 1.1 root 1628: if (!strcmp (argv[i], "-M")) 1629: print_deps = 2; 1630: else if (!strcmp (argv[i], "-MM")) 1631: print_deps = 1; 1632: else if (!strcmp (argv[i], "-MD")) 1633: print_deps = 2; 1634: else if (!strcmp (argv[i], "-MMD")) 1635: print_deps = 1; 1636: /* For -MD and -MMD options, write deps on file named by next arg. */ 1637: if (!strcmp (argv[i], "-MD") 1638: || !strcmp (argv[i], "-MMD")) { 1.1.1.7 root 1639: if (i + 1 == argc) 1640: fatal ("Filename missing after %s option", argv[i]); 1.1 root 1641: i++; 1642: deps_file = argv[i]; 1.1.1.5 root 1643: deps_mode = "w"; 1.1 root 1644: } else { 1645: /* For -M and -MM, write deps on standard output 1646: and suppress the usual output. */ 1647: deps_stream = stdout; 1648: inhibit_output = 1; 1649: } 1650: break; 1651: 1652: case 'd': 1653: { 1654: char *p = argv[i] + 2; 1655: char c; 1.1.1.8 ! root 1656: while ((c = *p++)) { 1.1 root 1657: /* Arg to -d specifies what parts of macros to dump */ 1658: switch (c) { 1659: case 'M': 1660: dump_macros = dump_only; 1661: no_output = 1; 1662: break; 1663: case 'N': 1664: dump_macros = dump_names; 1665: break; 1666: case 'D': 1667: dump_macros = dump_definitions; 1668: break; 1669: } 1670: } 1671: } 1672: break; 1673: 1674: case 'g': 1675: if (argv[i][2] == '3') 1676: debug_output = 1; 1677: break; 1678: 1679: case 'v': 1680: fprintf (stderr, "GNU CPP version %s", version_string); 1681: #ifdef TARGET_VERSION 1682: TARGET_VERSION; 1683: #endif 1684: fprintf (stderr, "\n"); 1.1.1.6 root 1685: verbose = 1; 1.1 root 1686: break; 1687: 1688: case 'H': 1689: print_include_names = 1; 1690: break; 1691: 1692: case 'D': 1.1.1.7 root 1693: if (argv[i][2] != 0) 1694: pend_defs[i] = argv[i] + 2; 1695: else if (i + 1 == argc) 1696: fatal ("Macro name missing after -D option"); 1697: else 1698: i++, pend_defs[i] = argv[i]; 1.1 root 1699: break; 1700: 1701: case 'A': 1702: { 1.1.1.7 root 1703: char *p; 1.1 root 1704: 1705: if (argv[i][2] != 0) 1706: p = argv[i] + 2; 1707: else if (i + 1 == argc) 1708: fatal ("Assertion missing after -A option"); 1709: else 1710: p = argv[++i]; 1711: 1712: if (!strcmp (p, "-")) { 1713: /* -A- eliminates all predefined macros and assertions. 1714: Let's include also any that were specified earlier 1715: on the command line. That way we can get rid of any 1716: that were passed automatically in from GCC. */ 1717: int j; 1718: inhibit_predefs = 1; 1719: for (j = 0; j < i; j++) 1720: pend_defs[j] = pend_assertions[j] = 0; 1721: } else { 1722: pend_assertions[i] = p; 1723: pend_assertion_options[i] = "-A"; 1724: } 1725: } 1726: break; 1727: 1728: case 'U': /* JF #undef something */ 1729: if (argv[i][2] != 0) 1730: pend_undefs[i] = argv[i] + 2; 1731: else if (i + 1 == argc) 1732: fatal ("Macro name missing after -U option"); 1733: else 1734: pend_undefs[i] = argv[i+1], i++; 1735: break; 1736: 1737: case 'C': 1738: put_out_comments = 1; 1739: break; 1740: 1741: case 'E': /* -E comes from cc -E; ignore it. */ 1742: break; 1743: 1744: case 'P': 1.1.1.8 ! root 1745: no_line_directives = 1; 1.1 root 1746: break; 1747: 1748: case '$': /* Don't include $ in identifiers. */ 1749: dollars_in_ident = 0; 1750: break; 1751: 1752: case 'I': /* Add directory to path for includes. */ 1753: { 1754: struct file_name_list *dirtmp; 1755: 1.1.1.4 root 1756: if (! ignore_srcdir && !strcmp (argv[i] + 2, "-")) { 1.1 root 1757: ignore_srcdir = 1; 1.1.1.4 root 1758: /* Don't use any preceding -I directories for #include <...>. */ 1759: first_bracket_include = 0; 1760: } 1.1 root 1761: else { 1762: dirtmp = (struct file_name_list *) 1763: xmalloc (sizeof (struct file_name_list)); 1764: dirtmp->next = 0; /* New one goes on the end */ 1765: dirtmp->control_macro = 0; 1.1.1.6 root 1766: dirtmp->c_system_include_path = 0; 1.1 root 1767: if (argv[i][2] != 0) 1768: dirtmp->fname = argv[i] + 2; 1769: else if (i + 1 == argc) 1770: fatal ("Directory name missing after -I option"); 1771: else 1772: dirtmp->fname = argv[++i]; 1.1.1.7 root 1773: dirtmp->got_name_map = 0; 1.1.1.4 root 1774: append_include_chain (dirtmp, dirtmp); 1775: } 1.1 root 1776: } 1777: break; 1778: 1779: case 'n': 1780: if (!strcmp (argv[i], "-nostdinc")) 1781: /* -nostdinc causes no default include directories. 1782: You must specify all include-file directories with -I. */ 1783: no_standard_includes = 1; 1.1.1.3 root 1784: else if (!strcmp (argv[i], "-nostdinc++")) 1785: /* -nostdinc++ causes no default C++-specific include directories. */ 1786: no_standard_cplusplus_includes = 1; 1.1 root 1787: else if (!strcmp (argv[i], "-noprecomp")) 1788: no_precomp = 1; 1789: break; 1790: 1791: case 'u': 1792: /* Sun compiler passes undocumented switch "-undef". 1793: Let's assume it means to inhibit the predefined symbols. */ 1794: inhibit_predefs = 1; 1795: break; 1796: 1797: case '\0': /* JF handle '-' as file name meaning stdin or stdout */ 1798: if (in_fname == NULL) { 1799: in_fname = ""; 1800: break; 1801: } else if (out_fname == NULL) { 1802: out_fname = ""; 1803: break; 1804: } /* else fall through into error */ 1805: 1806: default: 1807: fatal ("Invalid option `%s'", argv[i]); 1808: } 1809: } 1810: } 1811: 1812: /* Add dirs from CPATH after dirs from -I. */ 1813: /* There seems to be confusion about what CPATH should do, 1814: so for the moment it is not documented. */ 1815: /* Some people say that CPATH should replace the standard include dirs, 1816: but that seems pointless: it comes before them, so it overrides them 1817: anyway. */ 1.1.1.8 ! root 1818: cp = getenv ("CPATH"); ! 1819: if (cp && ! no_standard_includes) ! 1820: path_include (cp); 1.1 root 1821: 1822: /* Now that dollars_in_ident is known, initialize is_idchar. */ 1823: initialize_char_syntax (); 1824: 1825: /* Initialize output buffer */ 1826: 1827: outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE); 1828: outbuf.bufp = outbuf.buf; 1829: outbuf.length = OUTBUF_SIZE; 1830: 1831: /* Do partial setup of input buffer for the sake of generating 1832: early #line directives (when -g is in effect). */ 1833: 1834: fp = &instack[++indepth]; 1835: if (in_fname == NULL) 1836: in_fname = ""; 1837: fp->nominal_fname = fp->fname = in_fname; 1838: fp->lineno = 0; 1839: 1.1.1.7 root 1840: /* In C++, wchar_t is a distinct basic type, and we can expect 1841: __wchar_t to be defined by cc1plus. */ 1842: if (cplusplus) 1843: wchar_type = "__wchar_t"; 1844: 1.1 root 1845: /* Install __LINE__, etc. Must follow initialize_char_syntax 1846: and option processing. */ 1847: initialize_builtins (fp, &outbuf); 1848: 1849: /* Do standard #defines and assertions 1850: that identify system and machine type. */ 1851: 1852: if (!inhibit_predefs) { 1853: char *p = (char *) alloca (strlen (predefs) + 1); 1854: strcpy (p, predefs); 1855: while (*p) { 1856: char *q; 1857: while (*p == ' ' || *p == '\t') 1858: p++; 1859: /* Handle -D options. */ 1860: if (p[0] == '-' && p[1] == 'D') { 1861: q = &p[2]; 1862: while (*p && *p != ' ' && *p != '\t') 1863: p++; 1864: if (*p != 0) 1865: *p++= 0; 1866: if (debug_output) 1.1.1.8 ! root 1867: output_line_directive (fp, &outbuf, 0, same_file); 1.1 root 1868: make_definition (q, &outbuf); 1869: while (*p == ' ' || *p == '\t') 1870: p++; 1871: } else if (p[0] == '-' && p[1] == 'A') { 1872: /* Handle -A options (assertions). */ 1873: char *assertion; 1874: char *past_name; 1875: char *value; 1876: char *past_value; 1877: char *termination; 1878: int save_char; 1879: 1880: assertion = &p[2]; 1881: past_name = assertion; 1882: /* Locate end of name. */ 1883: while (*past_name && *past_name != ' ' 1884: && *past_name != '\t' && *past_name != '(') 1885: past_name++; 1886: /* Locate `(' at start of value. */ 1887: value = past_name; 1888: while (*value && (*value == ' ' || *value == '\t')) 1889: value++; 1890: if (*value++ != '(') 1891: abort (); 1892: while (*value && (*value == ' ' || *value == '\t')) 1893: value++; 1894: past_value = value; 1895: /* Locate end of value. */ 1896: while (*past_value && *past_value != ' ' 1897: && *past_value != '\t' && *past_value != ')') 1898: past_value++; 1899: termination = past_value; 1900: while (*termination && (*termination == ' ' || *termination == '\t')) 1901: termination++; 1902: if (*termination++ != ')') 1903: abort (); 1904: if (*termination && *termination != ' ' && *termination != '\t') 1905: abort (); 1906: /* Temporarily null-terminate the value. */ 1907: save_char = *termination; 1908: *termination = '\0'; 1909: /* Install the assertion. */ 1910: make_assertion ("-A", assertion); 1911: *termination = (char) save_char; 1912: p = termination; 1913: while (*p == ' ' || *p == '\t') 1914: p++; 1915: } else { 1916: abort (); 1917: } 1918: } 1919: } 1920: 1921: /* Now handle the command line options. */ 1922: 1.1.1.4 root 1923: /* Do -U's, -D's and -A's in the order they were seen. */ 1924: for (i = 1; i < argc; i++) { 1925: if (pend_undefs[i]) { 1.1 root 1926: if (debug_output) 1.1.1.8 ! root 1927: output_line_directive (fp, &outbuf, 0, same_file); 1.1.1.4 root 1928: make_undef (pend_undefs[i], &outbuf); 1.1 root 1929: } 1.1.1.4 root 1930: if (pend_defs[i]) { 1.1 root 1931: if (debug_output) 1.1.1.8 ! root 1932: output_line_directive (fp, &outbuf, 0, same_file); 1.1.1.4 root 1933: make_definition (pend_defs[i], &outbuf); 1.1 root 1934: } 1.1.1.4 root 1935: if (pend_assertions[i]) 1936: make_assertion (pend_assertion_options[i], pend_assertions[i]); 1937: } 1.1 root 1938: 1939: done_initializing = 1; 1940: 1941: { /* read the appropriate environment variable and if it exists 1942: replace include_defaults with the listed path. */ 1943: char *epath = 0; 1944: switch ((objc << 1) + cplusplus) 1945: { 1946: case 0: 1947: epath = getenv ("C_INCLUDE_PATH"); 1948: break; 1949: case 1: 1.1.1.2 root 1950: epath = getenv ("CPLUS_INCLUDE_PATH"); 1.1 root 1951: break; 1952: case 2: 1953: epath = getenv ("OBJC_INCLUDE_PATH"); 1954: break; 1955: case 3: 1.1.1.2 root 1956: epath = getenv ("OBJCPLUS_INCLUDE_PATH"); 1.1 root 1957: break; 1958: } 1959: /* If the environment var for this language is set, 1960: add to the default list of include directories. */ 1961: if (epath) { 1962: char *nstore = (char *) alloca (strlen (epath) + 2); 1963: int num_dirs; 1964: char *startp, *endp; 1965: 1966: for (num_dirs = 1, startp = epath; *startp; startp++) 1.1.1.3 root 1967: if (*startp == PATH_SEPARATOR) 1.1 root 1968: num_dirs++; 1969: include_defaults 1970: = (struct default_include *) xmalloc ((num_dirs 1971: * sizeof (struct default_include)) 1972: + sizeof (include_defaults_array)); 1973: startp = endp = epath; 1974: num_dirs = 0; 1975: while (1) { 1.1.1.2 root 1976: /* Handle cases like c:/usr/lib:d:/gcc/lib */ 1.1.1.3 root 1977: if ((*endp == PATH_SEPARATOR 1978: #if 0 /* Obsolete, now that we use semicolons as the path separator. */ 1.1.1.2 root 1979: #ifdef __MSDOS__ 1.1.1.4 root 1980: && (endp-startp != 1 || !isalpha (*startp)) 1.1.1.2 root 1981: #endif 1.1.1.3 root 1982: #endif 1.1.1.2 root 1983: ) 1.1.1.3 root 1984: || *endp == 0) { 1.1 root 1985: strncpy (nstore, startp, endp-startp); 1986: if (endp == startp) 1987: strcpy (nstore, "."); 1988: else 1989: nstore[endp-startp] = '\0'; 1990: 1991: include_defaults[num_dirs].fname = savestring (nstore); 1992: include_defaults[num_dirs].cplusplus = cplusplus; 1.1.1.7 root 1993: include_defaults[num_dirs].cxx_aware = 1; 1.1 root 1994: num_dirs++; 1995: if (*endp == '\0') 1996: break; 1997: endp = startp = endp + 1; 1998: } else 1999: endp++; 2000: } 2001: /* Put the usual defaults back in at the end. */ 1.1.1.7 root 2002: bcopy ((char *) include_defaults_array, 2003: (char *) &include_defaults[num_dirs], 1.1 root 2004: sizeof (include_defaults_array)); 2005: } 2006: } 2007: 1.1.1.7 root 2008: append_include_chain (before_system, last_before_system); 2009: first_system_include = before_system; 2010: 1.1 root 2011: /* Unless -fnostdinc, 2012: tack on the standard include file dirs to the specified list */ 2013: if (!no_standard_includes) { 2014: struct default_include *p = include_defaults; 1.1.1.3 root 2015: char *specd_prefix = include_prefix; 1.1 root 2016: char *default_prefix = savestring (GCC_INCLUDE_DIR); 2017: int default_len = 0; 2018: /* Remove the `include' from /usr/local/lib/gcc.../include. */ 2019: if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) { 2020: default_len = strlen (default_prefix) - 7; 2021: default_prefix[default_len] = 0; 2022: } 2023: /* Search "translated" versions of GNU directories. 2024: These have /usr/local/lib/gcc... replaced by specd_prefix. */ 2025: if (specd_prefix != 0 && default_len != 0) 2026: for (p = include_defaults; p->fname; p++) { 2027: /* Some standard dirs are only for C++. */ 1.1.1.3 root 2028: if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) { 1.1 root 2029: /* Does this dir start with the prefix? */ 2030: if (!strncmp (p->fname, default_prefix, default_len)) { 2031: /* Yes; change prefix and add to search list. */ 2032: struct file_name_list *new 2033: = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 2034: int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len; 1.1.1.8 ! root 2035: char *str = xmalloc (this_len + 1); 1.1 root 2036: strcpy (str, specd_prefix); 2037: strcat (str, p->fname + default_len); 2038: new->fname = str; 2039: new->control_macro = 0; 1.1.1.7 root 2040: new->c_system_include_path = !p->cxx_aware; 2041: new->got_name_map = 0; 1.1.1.4 root 2042: append_include_chain (new, new); 2043: if (first_system_include == 0) 2044: first_system_include = new; 1.1 root 2045: } 2046: } 2047: } 2048: /* Search ordinary names for GNU include directories. */ 2049: for (p = include_defaults; p->fname; p++) { 2050: /* Some standard dirs are only for C++. */ 1.1.1.3 root 2051: if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) { 1.1 root 2052: struct file_name_list *new 2053: = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 2054: new->control_macro = 0; 1.1.1.7 root 2055: new->c_system_include_path = !p->cxx_aware; 1.1 root 2056: new->fname = p->fname; 1.1.1.7 root 2057: new->got_name_map = 0; 1.1.1.4 root 2058: append_include_chain (new, new); 2059: if (first_system_include == 0) 2060: first_system_include = new; 1.1 root 2061: } 2062: } 2063: } 2064: 2065: /* Tack the after_include chain at the end of the include chain. */ 1.1.1.4 root 2066: append_include_chain (after_include, last_after_include); 2067: if (first_system_include == 0) 2068: first_system_include = after_include; 1.1 root 2069: 1.1.1.6 root 2070: /* With -v, print the list of dirs to search. */ 2071: if (verbose) { 2072: struct file_name_list *p; 2073: fprintf (stderr, "#include \"...\" search starts here:\n"); 2074: for (p = include; p; p = p->next) { 2075: if (p == first_bracket_include) 2076: fprintf (stderr, "#include <...> search starts here:\n"); 2077: fprintf (stderr, " %s\n", p->fname); 2078: } 2079: fprintf (stderr, "End of search list.\n"); 2080: } 2081: 1.1 root 2082: /* Scan the -imacros files before the main input. 2083: Much like #including them, but with no_output set 2084: so that only their macro definitions matter. */ 2085: 1.1.1.7 root 2086: no_output++; no_record_file++; 1.1 root 2087: for (i = 1; i < argc; i++) 2088: if (pend_files[i]) { 2089: int fd = open (pend_files[i], O_RDONLY, 0666); 2090: if (fd < 0) { 2091: perror_with_name (pend_files[i]); 1.1.1.8 ! root 2092: return FATAL_EXIT_CODE; 1.1 root 2093: } 1.1.1.4 root 2094: finclude (fd, pend_files[i], &outbuf, 0, NULL_PTR); 1.1 root 2095: } 1.1.1.7 root 2096: no_output--; no_record_file--; 1.1 root 2097: 2098: /* Copy the entire contents of the main input file into 2099: the stacked input buffer previously allocated for it. */ 2100: 2101: /* JF check for stdin */ 2102: if (in_fname == NULL || *in_fname == 0) { 2103: in_fname = ""; 2104: f = 0; 2105: } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0) 2106: goto perror; 2107: 1.1.1.7 root 2108: /* -MG doesn't select the form of output and must be specified with one of 2109: -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't 2110: inhibit compilation. */ 2111: if (print_deps_missing_files && (print_deps == 0 || !inhibit_output)) 2112: fatal ("-MG must be specified with one of -M or -MM"); 2113: 1.1 root 2114: /* Either of two environment variables can specify output of deps. 2115: Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", 2116: where OUTPUT_FILE is the file to write deps info to 2117: and DEPS_TARGET is the target to mention in the deps. */ 2118: 2119: if (print_deps == 0 2120: && (getenv ("SUNPRO_DEPENDENCIES") != 0 2121: || getenv ("DEPENDENCIES_OUTPUT") != 0)) { 2122: char *spec = getenv ("DEPENDENCIES_OUTPUT"); 2123: char *s; 2124: char *output_file; 2125: 2126: if (spec == 0) { 2127: spec = getenv ("SUNPRO_DEPENDENCIES"); 2128: print_deps = 2; 2129: } 2130: else 2131: print_deps = 1; 2132: 2133: s = spec; 2134: /* Find the space before the DEPS_TARGET, if there is one. */ 1.1.1.4 root 2135: /* This should use index. (mrs) */ 1.1 root 2136: while (*s != 0 && *s != ' ') s++; 2137: if (*s != 0) { 2138: deps_target = s + 1; 1.1.1.8 ! root 2139: output_file = xmalloc (s - spec + 1); 1.1 root 2140: bcopy (spec, output_file, s - spec); 2141: output_file[s - spec] = 0; 2142: } 2143: else { 2144: deps_target = 0; 2145: output_file = spec; 2146: } 2147: 2148: deps_file = output_file; 1.1.1.5 root 2149: deps_mode = "a"; 1.1 root 2150: } 2151: 2152: /* For -M, print the expected object file name 2153: as the target of this Make-rule. */ 2154: if (print_deps) { 2155: deps_allocated_size = 200; 1.1.1.8 ! root 2156: deps_buffer = xmalloc (deps_allocated_size); 1.1 root 2157: deps_buffer[0] = 0; 2158: deps_size = 0; 2159: deps_column = 0; 2160: 2161: if (deps_target) { 1.1.1.7 root 2162: deps_output (deps_target, ':'); 2163: } else if (*in_fname == 0) { 2164: deps_output ("-", ':'); 2165: } else { 2166: char *p, *q; 1.1 root 2167: int len; 1.1.1.7 root 2168: 2169: /* Discard all directory prefixes from filename. */ 2170: if ((q = rindex (in_fname, '/')) != NULL 2171: #ifdef DIR_SEPARATOR 2172: && (q = rindex (in_fname, DIR_SEPARATOR)) != NULL 2173: #endif 2174: ) 2175: ++q; 2176: else 2177: q = in_fname; 2178: 2179: /* Copy remainder to mungable area. */ 2180: p = (char *) alloca (strlen(q) + 8); 2181: strcpy (p, q); 2182: 1.1 root 2183: /* Output P, but remove known suffixes. */ 2184: len = strlen (p); 1.1.1.7 root 2185: q = p + len; 2186: if (len >= 2 2187: && p[len - 2] == '.' 2188: && index("cCsSm", p[len - 1])) 2189: q = p + (len - 2); 2190: else if (len >= 3 2191: && p[len - 3] == '.' 1.1 root 2192: && p[len - 2] == 'c' 2193: && p[len - 1] == 'c') 1.1.1.7 root 2194: q = p + (len - 3); 2195: else if (len >= 4 2196: && p[len - 4] == '.' 1.1.1.5 root 2197: && p[len - 3] == 'c' 2198: && p[len - 2] == 'x' 2199: && p[len - 1] == 'x') 1.1.1.7 root 2200: q = p + (len - 4); 2201: else if (len >= 4 2202: && p[len - 4] == '.' 2203: && p[len - 3] == 'c' 2204: && p[len - 2] == 'p' 2205: && p[len - 1] == 'p') 2206: q = p + (len - 4); 2207: 1.1 root 2208: /* Supply our own suffix. */ 1.1.1.4 root 2209: #ifndef VMS 1.1.1.7 root 2210: strcpy (q, ".o"); 1.1.1.4 root 2211: #else 1.1.1.7 root 2212: strcpy (q, ".obj"); 1.1.1.4 root 2213: #endif 1.1.1.7 root 2214: 2215: deps_output (p, ':'); 2216: deps_output (in_fname, ' '); 1.1 root 2217: } 2218: } 2219: 2220: file_size_and_mode (f, &st_mode, &st_size); 2221: fp->nominal_fname = fp->fname = in_fname; 2222: fp->lineno = 1; 2223: fp->system_header_p = 0; 2224: /* JF all this is mine about reading pipes and ttys */ 2225: if (! S_ISREG (st_mode)) { 2226: /* Read input from a file that is not a normal disk file. 2227: We cannot preallocate a buffer with the correct size, 2228: so we must read in the file a piece at the time and make it bigger. */ 2229: int size; 2230: int bsize; 2231: int cnt; 2232: 2233: bsize = 2000; 2234: size = 0; 2235: fp->buf = (U_CHAR *) xmalloc (bsize + 2); 2236: for (;;) { 1.1.1.8 ! root 2237: cnt = safe_read (f, (char *) fp->buf + size, bsize - size); 1.1 root 2238: if (cnt < 0) goto perror; /* error! */ 2239: size += cnt; 1.1.1.7 root 2240: if (size != bsize) break; /* End of file */ 2241: bsize *= 2; 2242: fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2); 1.1 root 2243: } 2244: fp->length = size; 2245: } else { 2246: /* Read a file whose size we can determine in advance. 2247: For the sake of VMS, st_size is just an upper bound. */ 2248: fp->buf = (U_CHAR *) xmalloc (st_size + 2); 1.1.1.8 ! root 2249: fp->length = safe_read (f, (char *) fp->buf, st_size); 1.1.1.7 root 2250: if (fp->length < 0) goto perror; 1.1 root 2251: } 2252: fp->bufp = fp->buf; 2253: fp->if_stack = if_stack; 2254: 2255: /* Make sure data ends with a newline. And put a null after it. */ 2256: 2257: if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n') 2258: /* Backslash-newline at end is not good enough. */ 2259: || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) { 2260: fp->buf[fp->length++] = '\n'; 2261: missing_newline = 1; 2262: } 2263: fp->buf[fp->length] = '\0'; 2264: 2265: /* Unless inhibited, convert trigraphs in the input. */ 2266: 2267: if (!no_trigraphs) 2268: trigraph_pcp (fp); 2269: 2270: /* Now that we know the input file is valid, open the output. */ 2271: 2272: if (!out_fname || !strcmp (out_fname, "")) 2273: out_fname = "stdout"; 2274: else if (! freopen (out_fname, "w", stdout)) 2275: pfatal_with_name (out_fname); 2276: 1.1.1.8 ! root 2277: output_line_directive (fp, &outbuf, 0, same_file); 1.1 root 2278: 2279: /* Scan the -include files before the main input. */ 2280: 1.1.1.7 root 2281: no_record_file++; 1.1 root 2282: for (i = 1; i < argc; i++) 2283: if (pend_includes[i]) { 2284: int fd = open (pend_includes[i], O_RDONLY, 0666); 2285: if (fd < 0) { 2286: perror_with_name (pend_includes[i]); 1.1.1.8 ! root 2287: return FATAL_EXIT_CODE; 1.1 root 2288: } 1.1.1.4 root 2289: finclude (fd, pend_includes[i], &outbuf, 0, NULL_PTR); 1.1 root 2290: } 1.1.1.7 root 2291: no_record_file--; 1.1 root 2292: 2293: /* Scan the input, processing macros and directives. */ 2294: 2295: rescan (&outbuf, 0); 2296: 1.1.1.5 root 2297: if (missing_newline) 2298: fp->lineno--; 2299: 1.1 root 2300: if (pedantic && missing_newline) 2301: pedwarn ("file does not end in newline"); 2302: 2303: /* Now we have processed the entire input 2304: Write whichever kind of output has been requested. */ 2305: 2306: if (dump_macros == dump_only) 2307: dump_all_macros (); 2308: else if (! inhibit_output) { 2309: write_output (); 2310: } 2311: 2312: if (print_deps) { 1.1.1.4 root 2313: /* Don't actually write the deps file if compilation has failed. */ 2314: if (errors == 0) { 1.1.1.5 root 2315: if (deps_file && ! (deps_stream = fopen (deps_file, deps_mode))) 1.1.1.4 root 2316: pfatal_with_name (deps_file); 1.1 root 2317: fputs (deps_buffer, deps_stream); 2318: putc ('\n', deps_stream); 1.1.1.4 root 2319: if (deps_file) { 2320: if (ferror (deps_stream) || fclose (deps_stream) != 0) 1.1 root 2321: fatal ("I/O error on output"); 2322: } 2323: } 2324: } 2325: 1.1.1.5 root 2326: if (pcp_outfile && pcp_outfile != stdout 2327: && (ferror (pcp_outfile) || fclose (pcp_outfile) != 0)) 2328: fatal ("I/O error on `-pcp' output"); 2329: 1.1.1.4 root 2330: if (ferror (stdout) || fclose (stdout) != 0) 1.1 root 2331: fatal ("I/O error on output"); 2332: 2333: if (errors) 1.1.1.8 ! root 2334: exit (FATAL_EXIT_CODE); 1.1 root 2335: exit (SUCCESS_EXIT_CODE); 2336: 2337: perror: 2338: pfatal_with_name (in_fname); 2339: return 0; 2340: } 2341: 2342: /* Given a colon-separated list of file names PATH, 2343: add all the names to the search path for include files. */ 2344: 2345: static void 2346: path_include (path) 2347: char *path; 2348: { 2349: char *p; 2350: 2351: p = path; 2352: 2353: if (*p) 2354: while (1) { 2355: char *q = p; 2356: char *name; 2357: struct file_name_list *dirtmp; 2358: 2359: /* Find the end of this name. */ 1.1.1.3 root 2360: while (*q != 0 && *q != PATH_SEPARATOR) q++; 1.1 root 2361: if (p == q) { 2362: /* An empty name in the path stands for the current directory. */ 1.1.1.8 ! root 2363: name = xmalloc (2); 1.1 root 2364: name[0] = '.'; 2365: name[1] = 0; 2366: } else { 2367: /* Otherwise use the directory that is named. */ 1.1.1.8 ! root 2368: name = xmalloc (q - p + 1); 1.1 root 2369: bcopy (p, name, q - p); 2370: name[q - p] = 0; 2371: } 2372: 2373: dirtmp = (struct file_name_list *) 2374: xmalloc (sizeof (struct file_name_list)); 2375: dirtmp->next = 0; /* New one goes on the end */ 2376: dirtmp->control_macro = 0; 1.1.1.6 root 2377: dirtmp->c_system_include_path = 0; 1.1 root 2378: dirtmp->fname = name; 1.1.1.7 root 2379: dirtmp->got_name_map = 0; 1.1.1.4 root 2380: append_include_chain (dirtmp, dirtmp); 1.1 root 2381: 2382: /* Advance past this name. */ 2383: p = q; 2384: if (*p == 0) 2385: break; 2386: /* Skip the colon. */ 2387: p++; 2388: } 2389: } 2390: 1.1.1.7 root 2391: /* Return the address of the first character in S that equals C. 2392: S is an array of length N, possibly containing '\0's, and followed by '\0'. 2393: Return 0 if there is no such character. Assume that C itself is not '\0'. 2394: If we knew we could use memchr, we could just invoke memchr (S, C, N), 2395: but unfortunately memchr isn't autoconfigured yet. */ 2396: 2397: static U_CHAR * 2398: index0 (s, c, n) 2399: U_CHAR *s; 2400: int c; 1.1.1.8 ! root 2401: size_t n; 1.1.1.7 root 2402: { 1.1.1.8 ! root 2403: char *p = (char *) s; 1.1.1.7 root 2404: for (;;) { 1.1.1.8 ! root 2405: char *q = index (p, c); 1.1.1.7 root 2406: if (q) 2407: return (U_CHAR *) q; 2408: else { 1.1.1.8 ! root 2409: size_t l = strlen (p); 1.1.1.7 root 2410: if (l == n) 2411: return 0; 2412: l++; 1.1.1.8 ! root 2413: p += l; 1.1.1.7 root 2414: n -= l; 2415: } 2416: } 2417: } 2418: 1.1 root 2419: /* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF 2420: before main CCCP processing. Name `pcp' is also in honor of the 2421: drugs the trigraph designers must have been on. 2422: 2423: Using an extra pass through the buffer takes a little extra time, 2424: but is infinitely less hairy than trying to handle trigraphs inside 2425: strings, etc. everywhere, and also makes sure that trigraphs are 2426: only translated in the top level of processing. */ 2427: 2428: static void 2429: trigraph_pcp (buf) 2430: FILE_BUF *buf; 2431: { 1.1.1.7 root 2432: register U_CHAR c, *fptr, *bptr, *sptr, *lptr; 1.1 root 2433: int len; 2434: 2435: fptr = bptr = sptr = buf->buf; 1.1.1.7 root 2436: lptr = fptr + buf->length; 1.1.1.8 ! root 2437: while ((sptr = index0 (sptr, '?', (size_t) (lptr - sptr))) != NULL) { 1.1 root 2438: if (*++sptr != '?') 2439: continue; 2440: switch (*++sptr) { 2441: case '=': 2442: c = '#'; 2443: break; 2444: case '(': 2445: c = '['; 2446: break; 2447: case '/': 2448: c = '\\'; 2449: break; 2450: case ')': 2451: c = ']'; 2452: break; 2453: case '\'': 2454: c = '^'; 2455: break; 2456: case '<': 2457: c = '{'; 2458: break; 2459: case '!': 2460: c = '|'; 2461: break; 2462: case '>': 2463: c = '}'; 2464: break; 2465: case '-': 2466: c = '~'; 2467: break; 2468: case '?': 2469: sptr--; 2470: continue; 2471: default: 2472: continue; 2473: } 2474: len = sptr - fptr - 2; 1.1.1.7 root 2475: 2476: /* BSD doc says bcopy () works right for overlapping strings. In ANSI 2477: C, this will be memmove (). */ 1.1 root 2478: if (bptr != fptr && len > 0) 1.1.1.7 root 2479: bcopy ((char *) fptr, (char *) bptr, len); 2480: 1.1 root 2481: bptr += len; 2482: *bptr++ = c; 2483: fptr = ++sptr; 2484: } 2485: len = buf->length - (fptr - buf->buf); 2486: if (bptr != fptr && len > 0) 1.1.1.7 root 2487: bcopy ((char *) fptr, (char *) bptr, len); 1.1 root 2488: buf->length -= fptr - bptr; 2489: buf->buf[buf->length] = '\0'; 2490: if (warn_trigraphs && fptr != bptr) 1.1.1.8 ! root 2491: warning_with_line (0, "%d trigraph(s) encountered", (fptr - bptr) / 2); 1.1 root 2492: } 2493: 2494: /* Move all backslash-newline pairs out of embarrassing places. 2495: Exchange all such pairs following BP 1.1.1.2 root 2496: with any potentially-embarrassing characters that follow them. 1.1 root 2497: Potentially-embarrassing characters are / and * 2498: (because a backslash-newline inside a comment delimiter 2499: would cause it not to be recognized). */ 2500: 2501: static void 2502: newline_fix (bp) 2503: U_CHAR *bp; 2504: { 2505: register U_CHAR *p = bp; 2506: 2507: /* First count the backslash-newline pairs here. */ 2508: 1.1.1.7 root 2509: while (p[0] == '\\' && p[1] == '\n') 2510: p += 2; 1.1 root 2511: 2512: /* What follows the backslash-newlines is not embarrassing. */ 2513: 1.1.1.7 root 2514: if (*p != '/' && *p != '*') 1.1 root 2515: return; 2516: 2517: /* Copy all potentially embarrassing characters 2518: that follow the backslash-newline pairs 2519: down to where the pairs originally started. */ 2520: 2521: while (*p == '*' || *p == '/') 2522: *bp++ = *p++; 2523: 2524: /* Now write the same number of pairs after the embarrassing chars. */ 1.1.1.7 root 2525: while (bp < p) { 1.1 root 2526: *bp++ = '\\'; 2527: *bp++ = '\n'; 2528: } 2529: } 2530: 2531: /* Like newline_fix but for use within a directive-name. 2532: Move any backslash-newlines up past any following symbol constituents. */ 2533: 2534: static void 2535: name_newline_fix (bp) 2536: U_CHAR *bp; 2537: { 2538: register U_CHAR *p = bp; 2539: 2540: /* First count the backslash-newline pairs here. */ 1.1.1.7 root 2541: while (p[0] == '\\' && p[1] == '\n') 2542: p += 2; 1.1 root 2543: 2544: /* What follows the backslash-newlines is not embarrassing. */ 2545: 1.1.1.7 root 2546: if (!is_idchar[*p]) 1.1 root 2547: return; 2548: 2549: /* Copy all potentially embarrassing characters 2550: that follow the backslash-newline pairs 2551: down to where the pairs originally started. */ 2552: 2553: while (is_idchar[*p]) 2554: *bp++ = *p++; 2555: 2556: /* Now write the same number of pairs after the embarrassing chars. */ 1.1.1.7 root 2557: while (bp < p) { 1.1 root 2558: *bp++ = '\\'; 2559: *bp++ = '\n'; 2560: } 2561: } 2562: 2563: /* Look for lint commands in comments. 2564: 2565: When we come in here, ibp points into a comment. Limit is as one expects. 2566: scan within the comment -- it should start, after lwsp, with a lint command. 2567: If so that command is returned as a (constant) string. 2568: 2569: Upon return, any arg will be pointed to with argstart and will be 2570: arglen long. Note that we don't parse that arg since it will just 2571: be printed out again. 2572: */ 2573: 2574: static char * 2575: get_lintcmd (ibp, limit, argstart, arglen, cmdlen) 2576: register U_CHAR *ibp; 2577: register U_CHAR *limit; 2578: U_CHAR **argstart; /* point to command arg */ 2579: int *arglen, *cmdlen; /* how long they are */ 2580: { 2581: long linsize; 2582: register U_CHAR *numptr; /* temp for arg parsing */ 2583: 2584: *arglen = 0; 2585: 2586: SKIP_WHITE_SPACE (ibp); 2587: 2588: if (ibp >= limit) return NULL; 2589: 2590: linsize = limit - ibp; 2591: 2592: /* Oh, I wish C had lexical functions... hell, I'll just open-code the set */ 1.1.1.8 ! root 2593: if ((linsize >= 10) && !bcmp (ibp, "NOTREACHED", 10)) { 1.1 root 2594: *cmdlen = 10; 2595: return "NOTREACHED"; 2596: } 1.1.1.8 ! root 2597: if ((linsize >= 8) && !bcmp (ibp, "ARGSUSED", 8)) { 1.1 root 2598: *cmdlen = 8; 2599: return "ARGSUSED"; 2600: } 1.1.1.8 ! root 2601: if ((linsize >= 11) && !bcmp (ibp, "LINTLIBRARY", 11)) { 1.1.1.4 root 2602: *cmdlen = 11; 1.1 root 2603: return "LINTLIBRARY"; 2604: } 1.1.1.8 ! root 2605: if ((linsize >= 7) && !bcmp (ibp, "VARARGS", 7)) { 1.1 root 2606: *cmdlen = 7; 2607: ibp += 7; linsize -= 7; 2608: if ((linsize == 0) || ! isdigit (*ibp)) return "VARARGS"; 2609: 2610: /* OK, read a number */ 2611: for (numptr = *argstart = ibp; (numptr < limit) && isdigit (*numptr); 2612: numptr++); 2613: *arglen = numptr - *argstart; 2614: return "VARARGS"; 2615: } 2616: return NULL; 2617: } 2618: 2619: /* 2620: * The main loop of the program. 2621: * 2622: * Read characters from the input stack, transferring them to the 2623: * output buffer OP. 2624: * 2625: * Macros are expanded and push levels on the input stack. 2626: * At the end of such a level it is popped off and we keep reading. 2627: * At the end of any other kind of level, we return. 2628: * #-directives are handled, except within macros. 2629: * 2630: * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input 2631: * and insert them when appropriate. This is set while scanning macro 2632: * arguments before substitution. It is zero when scanning for final output. 2633: * There are three types of Newline markers: 2634: * * Newline - follows a macro name that was not expanded 2635: * because it appeared inside an expansion of the same macro. 2636: * This marker prevents future expansion of that identifier. 2637: * When the input is rescanned into the final output, these are deleted. 2638: * These are also deleted by ## concatenation. 2639: * * Newline Space (or Newline and any other whitespace character) 2640: * stands for a place that tokens must be separated or whitespace 2641: * is otherwise desirable, but where the ANSI standard specifies there 2642: * is no whitespace. This marker turns into a Space (or whichever other 2643: * whitespace char appears in the marker) in the final output, 2644: * but it turns into nothing in an argument that is stringified with #. 2645: * Such stringified arguments are the only place where the ANSI standard 2646: * specifies with precision that whitespace may not appear. 2647: * 2648: * During this function, IP->bufp is kept cached in IBP for speed of access. 2649: * Likewise, OP->bufp is kept in OBP. Before calling a subroutine 2650: * IBP, IP and OBP must be copied back to memory. IP and IBP are 2651: * copied back with the RECACHE macro. OBP must be copied back from OP->bufp 2652: * explicitly, and before RECACHE, since RECACHE uses OBP. 2653: */ 2654: 2655: static void 2656: rescan (op, output_marks) 2657: FILE_BUF *op; 2658: int output_marks; 2659: { 2660: /* Character being scanned in main loop. */ 2661: register U_CHAR c; 2662: 2663: /* Length of pending accumulated identifier. */ 2664: register int ident_length = 0; 2665: 2666: /* Hash code of pending accumulated identifier. */ 2667: register int hash = 0; 2668: 2669: /* Current input level (&instack[indepth]). */ 2670: FILE_BUF *ip; 2671: 2672: /* Pointer for scanning input. */ 2673: register U_CHAR *ibp; 2674: 2675: /* Pointer to end of input. End of scan is controlled by LIMIT. */ 2676: register U_CHAR *limit; 2677: 2678: /* Pointer for storing output. */ 2679: register U_CHAR *obp; 2680: 2681: /* REDO_CHAR is nonzero if we are processing an identifier 2682: after backing up over the terminating character. 2683: Sometimes we process an identifier without backing up over 2684: the terminating character, if the terminating character 2685: is not special. Backing up is done so that the terminating character 2686: will be dispatched on again once the identifier is dealt with. */ 2687: int redo_char = 0; 2688: 2689: /* 1 if within an identifier inside of which a concatenation 2690: marker (Newline -) has been seen. */ 2691: int concatenated = 0; 2692: 2693: /* While scanning a comment or a string constant, 2694: this records the line it started on, for error messages. */ 2695: int start_line; 2696: 2697: /* Record position of last `real' newline. */ 2698: U_CHAR *beg_of_line; 2699: 2700: /* Pop the innermost input stack level, assuming it is a macro expansion. */ 2701: 2702: #define POPMACRO \ 2703: do { ip->macro->type = T_MACRO; \ 2704: if (ip->free_ptr) free (ip->free_ptr); \ 2705: --indepth; } while (0) 2706: 2707: /* Reload `rescan's local variables that describe the current 2708: level of the input stack. */ 2709: 2710: #define RECACHE \ 2711: do { ip = &instack[indepth]; \ 2712: ibp = ip->bufp; \ 2713: limit = ip->buf + ip->length; \ 2714: op->bufp = obp; \ 2715: check_expand (op, limit - ibp); \ 2716: beg_of_line = 0; \ 2717: obp = op->bufp; } while (0) 2718: 2719: if (no_output && instack[indepth].fname != 0) 1.1.1.7 root 2720: skip_if_group (&instack[indepth], 1, NULL); 1.1 root 2721: 2722: obp = op->bufp; 2723: RECACHE; 1.1.1.4 root 2724: 1.1 root 2725: beg_of_line = ibp; 2726: 2727: /* Our caller must always put a null after the end of 2728: the input at each input stack level. */ 2729: if (*limit != 0) 2730: abort (); 2731: 2732: while (1) { 2733: c = *ibp++; 2734: *obp++ = c; 2735: 2736: switch (c) { 2737: case '\\': 1.1.1.7 root 2738: if (*ibp == '\n' && !ip->macro) { 2739: /* At the top level, always merge lines ending with backslash-newline, 2740: even in middle of identifier. But do not merge lines in a macro, 2741: since backslash might be followed by a newline-space marker. */ 1.1 root 2742: ++ibp; 2743: ++ip->lineno; 2744: --obp; /* remove backslash from obuf */ 2745: break; 2746: } 1.1.1.7 root 2747: /* If ANSI, backslash is just another character outside a string. */ 2748: if (!traditional) 2749: goto randomchar; 1.1 root 2750: /* Otherwise, backslash suppresses specialness of following char, 2751: so copy it here to prevent the switch from seeing it. 2752: But first get any pending identifier processed. */ 2753: if (ident_length > 0) 2754: goto specialchar; 1.1.1.7 root 2755: if (ibp < limit) 2756: *obp++ = *ibp++; 1.1 root 2757: break; 2758: 1.1.1.8 ! root 2759: case '%': ! 2760: if (ident_length || ip->macro || traditional) ! 2761: goto randomchar; ! 2762: while (*ibp == '\\' && ibp[1] == '\n') { ! 2763: ibp += 2; ! 2764: ++ip->lineno; ! 2765: } ! 2766: if (*ibp != ':') ! 2767: break; ! 2768: /* Treat this %: digraph as if it were #. */ ! 2769: /* Fall through. */ ! 2770: 1.1 root 2771: case '#': 2772: if (assertions_flag) { 1.1.1.8 ! root 2773: if (ident_length) ! 2774: goto specialchar; 1.1 root 2775: /* Copy #foo (bar lose) without macro expansion. */ 1.1.1.8 ! root 2776: obp[-1] = '#'; /* In case it was '%'. */ 1.1 root 2777: SKIP_WHITE_SPACE (ibp); 2778: while (is_idchar[*ibp]) 2779: *obp++ = *ibp++; 2780: SKIP_WHITE_SPACE (ibp); 2781: if (*ibp == '(') { 2782: ip->bufp = ibp; 2783: skip_paren_group (ip); 1.1.1.7 root 2784: bcopy ((char *) ibp, (char *) obp, ip->bufp - ibp); 1.1 root 2785: obp += ip->bufp - ibp; 2786: ibp = ip->bufp; 2787: } 1.1.1.8 ! root 2788: break; 1.1 root 2789: } 2790: 2791: /* If this is expanding a macro definition, don't recognize 1.1.1.8 ! root 2792: preprocessing directives. */ 1.1 root 2793: if (ip->macro != 0) 2794: goto randomchar; 1.1.1.8 ! root 2795: /* If this is expand_into_temp_buffer, ! 2796: don't recognize them either. Warn about them 1.1.1.4 root 2797: only after an actual newline at this level, 2798: not at the beginning of the input level. */ 1.1.1.8 ! root 2799: if (! ip->fname) { ! 2800: if (ip->buf != beg_of_line) ! 2801: warning ("preprocessing directive not recognized within macro arg"); 1.1.1.4 root 2802: goto randomchar; 1.1.1.8 ! root 2803: } 1.1 root 2804: if (ident_length) 2805: goto specialchar; 2806: 1.1.1.4 root 2807: 1.1 root 2808: /* # keyword: a # must be first nonblank char on the line */ 2809: if (beg_of_line == 0) 2810: goto randomchar; 2811: { 2812: U_CHAR *bp; 2813: 2814: /* Scan from start of line, skipping whitespace, comments 2815: and backslash-newlines, and see if we reach this #. 2816: If not, this # is not special. */ 2817: bp = beg_of_line; 1.1.1.4 root 2818: /* If -traditional, require # to be at beginning of line. */ 1.1.1.8 ! root 2819: if (!traditional) { 1.1.1.4 root 2820: while (1) { 2821: if (is_hor_space[*bp]) 1.1 root 2822: bp++; 1.1.1.4 root 2823: else if (*bp == '\\' && bp[1] == '\n') 2824: bp += 2; 2825: else if (*bp == '/' && bp[1] == '*') { 2826: bp += 2; 2827: while (!(*bp == '*' && bp[1] == '/')) 2828: bp++; 2829: bp += 2; 2830: } 1.1.1.7 root 2831: /* There is no point in trying to deal with C++ // comments here, 2832: because if there is one, then this # must be part of the 2833: comment and we would never reach here. */ 1.1.1.4 root 2834: else break; 1.1 root 2835: } 1.1.1.8 ! root 2836: if (c == '%') { ! 2837: if (bp[0] != '%') ! 2838: break; ! 2839: while (bp[1] == '\\' && bp[2] == '\n') ! 2840: bp += 2; ! 2841: if (bp + 1 != ibp) ! 2842: break; ! 2843: /* %: appears at start of line; skip past the ':' too. */ ! 2844: bp++; ! 2845: ibp++; ! 2846: } ! 2847: } 1.1 root 2848: if (bp + 1 != ibp) 2849: goto randomchar; 2850: } 2851: 2852: /* This # can start a directive. */ 2853: 2854: --obp; /* Don't copy the '#' */ 2855: 2856: ip->bufp = ibp; 2857: op->bufp = obp; 2858: if (! handle_directive (ip, op)) { 2859: #ifdef USE_C_ALLOCA 2860: alloca (0); 2861: #endif 2862: /* Not a known directive: treat it as ordinary text. 2863: IP, OP, IBP, etc. have not been changed. */ 2864: if (no_output && instack[indepth].fname) { 2865: /* If not generating expanded output, 2866: what we do with ordinary text is skip it. 2867: Discard everything until next # directive. */ 1.1.1.7 root 2868: skip_if_group (&instack[indepth], 1, 0); 1.1 root 2869: RECACHE; 2870: beg_of_line = ibp; 2871: break; 2872: } 1.1.1.8 ! root 2873: *obp++ = '#'; /* Copy # (even if it was originally %:). */ 1.1.1.6 root 2874: /* Don't expand an identifier that could be a macro directive. 2875: (Section 3.8.3 of the ANSI C standard) */ 2876: SKIP_WHITE_SPACE (ibp); 2877: if (is_idstart[*ibp]) 2878: { 2879: *obp++ = *ibp++; 2880: while (is_idchar[*ibp]) 2881: *obp++ = *ibp++; 2882: } 1.1 root 2883: goto randomchar; 2884: } 2885: #ifdef USE_C_ALLOCA 2886: alloca (0); 2887: #endif 2888: /* A # directive has been successfully processed. */ 2889: /* If not generating expanded output, ignore everything until 2890: next # directive. */ 2891: if (no_output && instack[indepth].fname) 1.1.1.7 root 2892: skip_if_group (&instack[indepth], 1, 0); 1.1 root 2893: obp = op->bufp; 2894: RECACHE; 2895: beg_of_line = ibp; 2896: break; 2897: 2898: case '\"': /* skip quoted string */ 2899: case '\'': 2900: /* A single quoted string is treated like a double -- some 2901: programs (e.g., troff) are perverse this way */ 2902: 2903: if (ident_length) 2904: goto specialchar; 2905: 2906: start_line = ip->lineno; 2907: 2908: /* Skip ahead to a matching quote. */ 2909: 2910: while (1) { 2911: if (ibp >= limit) { 1.1.1.4 root 2912: if (ip->macro != 0) { 2913: /* try harder: this string crosses a macro expansion boundary. 2914: This can happen naturally if -traditional. 2915: Otherwise, only -D can make a macro with an unmatched quote. */ 2916: POPMACRO; 2917: RECACHE; 2918: continue; 2919: } 2920: if (!traditional) { 1.1 root 2921: error_with_line (line_for_error (start_line), 2922: "unterminated string or character constant"); 2923: error_with_line (multiline_string_line, 2924: "possible real start of unterminated constant"); 2925: multiline_string_line = 0; 2926: } 2927: break; 2928: } 2929: *obp++ = *ibp; 2930: switch (*ibp++) { 2931: case '\n': 2932: ++ip->lineno; 2933: ++op->lineno; 2934: /* Traditionally, end of line ends a string constant with no error. 2935: So exit the loop and record the new line. */ 2936: if (traditional) { 2937: beg_of_line = ibp; 2938: goto while2end; 2939: } 1.1.1.5 root 2940: if (c == '\'') { 1.1 root 2941: error_with_line (line_for_error (start_line), 1.1.1.5 root 2942: "unterminated character constant"); 1.1 root 2943: goto while2end; 2944: } 1.1.1.5 root 2945: if (pedantic && multiline_string_line == 0) { 2946: pedwarn_with_line (line_for_error (start_line), 2947: "string constant runs past end of line"); 2948: } 1.1 root 2949: if (multiline_string_line == 0) 2950: multiline_string_line = ip->lineno - 1; 2951: break; 2952: 2953: case '\\': 2954: if (ibp >= limit) 2955: break; 2956: if (*ibp == '\n') { 2957: /* Backslash newline is replaced by nothing at all, 2958: but keep the line counts correct. */ 2959: --obp; 2960: ++ibp; 2961: ++ip->lineno; 2962: } else { 2963: /* ANSI stupidly requires that in \\ the second \ 2964: is *not* prevented from combining with a newline. */ 2965: while (*ibp == '\\' && ibp[1] == '\n') { 2966: ibp += 2; 2967: ++ip->lineno; 2968: } 2969: *obp++ = *ibp++; 2970: } 2971: break; 2972: 2973: case '\"': 2974: case '\'': 2975: if (ibp[-1] == c) 2976: goto while2end; 2977: break; 2978: } 2979: } 2980: while2end: 2981: break; 2982: 2983: case '/': 2984: if (*ibp == '\\' && ibp[1] == '\n') 2985: newline_fix (ibp); 2986: 2987: if (*ibp != '*' 1.1.1.4 root 2988: && !(cplusplus_comments && *ibp == '/')) 1.1 root 2989: goto randomchar; 2990: if (ip->macro != 0) 2991: goto randomchar; 2992: if (ident_length) 2993: goto specialchar; 2994: 2995: if (*ibp == '/') { 2996: /* C++ style comment... */ 2997: start_line = ip->lineno; 2998: 2999: /* Comments are equivalent to spaces. */ 3000: if (! put_out_comments) 1.1.1.8 ! root 3001: obp[-1] = ' '; ! 3002: 1.1 root 3003: { 1.1.1.8 ! root 3004: U_CHAR *before_bp = ibp; 1.1 root 3005: 1.1.1.8 ! root 3006: while (++ibp < limit) { ! 3007: if (*ibp == '\n') { ! 3008: if (ibp[-1] != '\\') { ! 3009: if (put_out_comments) { ! 3010: bcopy ((char *) before_bp, (char *) obp, ibp - before_bp); ! 3011: obp += ibp - before_bp; ! 3012: } ! 3013: break; 1.1.1.7 root 3014: } 1.1.1.8 ! root 3015: ++ip->lineno; ! 3016: /* Copy the newline into the output buffer, in order to ! 3017: avoid the pain of a #line every time a multiline comment ! 3018: is seen. */ ! 3019: if (!put_out_comments) ! 3020: *obp++ = '\n'; ! 3021: ++op->lineno; 1.1 root 3022: } 3023: } 3024: break; 3025: } 3026: } 3027: 3028: /* Ordinary C comment. Skip it, optionally copying it to output. */ 3029: 3030: start_line = ip->lineno; 3031: 3032: ++ibp; /* Skip the star. */ 3033: 3034: /* If this cpp is for lint, we peek inside the comments: */ 1.1.1.7 root 3035: if (for_lint) { 1.1 root 3036: U_CHAR *argbp; 3037: int cmdlen, arglen; 3038: char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen); 3039: 3040: if (lintcmd != NULL) { 1.1.1.7 root 3041: op->bufp = obp; 3042: check_expand (op, cmdlen + arglen + 14); 3043: obp = op->bufp; 1.1 root 3044: /* I believe it is always safe to emit this newline: */ 3045: obp[-1] = '\n'; 1.1.1.7 root 3046: bcopy ("#pragma lint ", (char *) obp, 13); 1.1 root 3047: obp += 13; 1.1.1.7 root 3048: bcopy (lintcmd, (char *) obp, cmdlen); 1.1 root 3049: obp += cmdlen; 3050: 3051: if (arglen != 0) { 3052: *(obp++) = ' '; 1.1.1.7 root 3053: bcopy (argbp, (char *) obp, arglen); 1.1 root 3054: obp += arglen; 3055: } 3056: 3057: /* OK, now bring us back to the state we were in before we entered 1.1.1.7 root 3058: this branch. We need #line because the #pragma's newline always 3059: messes up the line count. */ 3060: op->bufp = obp; 1.1.1.8 ! root 3061: output_line_directive (ip, op, 0, same_file); 1.1.1.7 root 3062: check_expand (op, limit - ibp + 2); 3063: obp = op->bufp; 1.1 root 3064: *(obp++) = '/'; 3065: } 3066: } 3067: 3068: /* Comments are equivalent to spaces. 3069: Note that we already output the slash; we might not want it. 3070: For -traditional, a comment is equivalent to nothing. */ 3071: if (! put_out_comments) { 3072: if (traditional) 3073: obp--; 3074: else 3075: obp[-1] = ' '; 3076: } 3077: else 3078: *obp++ = '*'; 3079: 3080: { 3081: U_CHAR *before_bp = ibp; 3082: 3083: while (ibp < limit) { 3084: switch (*ibp++) { 3085: case '/': 1.1.1.8 ! root 3086: if (warn_comments && *ibp == '*') 1.1.1.5 root 3087: warning ("`/*' within comment"); 1.1 root 3088: break; 3089: case '*': 3090: if (*ibp == '\\' && ibp[1] == '\n') 3091: newline_fix (ibp); 3092: if (ibp >= limit || *ibp == '/') 3093: goto comment_end; 3094: break; 3095: case '\n': 3096: ++ip->lineno; 3097: /* Copy the newline into the output buffer, in order to 3098: avoid the pain of a #line every time a multiline comment 3099: is seen. */ 3100: if (!put_out_comments) 3101: *obp++ = '\n'; 3102: ++op->lineno; 3103: } 3104: } 3105: comment_end: 3106: 3107: if (ibp >= limit) 3108: error_with_line (line_for_error (start_line), 3109: "unterminated comment"); 3110: else { 3111: ibp++; 3112: if (put_out_comments) { 1.1.1.7 root 3113: bcopy ((char *) before_bp, (char *) obp, ibp - before_bp); 1.1 root 3114: obp += ibp - before_bp; 3115: } 3116: } 3117: } 3118: break; 3119: 3120: case '$': 3121: if (!dollars_in_ident) 3122: goto randomchar; 3123: goto letter; 3124: 3125: case '0': case '1': case '2': case '3': case '4': 3126: case '5': case '6': case '7': case '8': case '9': 3127: /* If digit is not part of identifier, it starts a number, 3128: which means that following letters are not an identifier. 3129: "0x5" does not refer to an identifier "x5". 3130: So copy all alphanumerics that follow without accumulating 3131: as an identifier. Periods also, for sake of "3.e7". */ 3132: 3133: if (ident_length == 0) { 1.1.1.8 ! root 3134: for (;;) { ! 3135: while (ibp[0] == '\\' && ibp[1] == '\n') { 1.1 root 3136: ++ip->lineno; 3137: ibp += 2; 3138: } 3139: c = *ibp++; 1.1.1.7 root 3140: if (!is_idchar[c] && c != '.') { 1.1 root 3141: --ibp; 3142: break; 3143: } 3144: *obp++ = c; 3145: /* A sign can be part of a preprocessing number 3146: if it follows an e. */ 3147: if (c == 'e' || c == 'E') { 1.1.1.8 ! root 3148: while (ibp[0] == '\\' && ibp[1] == '\n') { 1.1 root 3149: ++ip->lineno; 3150: ibp += 2; 3151: } 1.1.1.8 ! root 3152: if (*ibp == '+' || *ibp == '-') { 1.1 root 3153: *obp++ = *ibp++; 3154: /* But traditional C does not let the token go past the sign. */ 3155: if (traditional) 3156: break; 3157: } 3158: } 3159: } 3160: break; 3161: } 3162: /* fall through */ 3163: 3164: case '_': 3165: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 3166: case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': 3167: case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': 3168: case 's': case 't': case 'u': case 'v': case 'w': case 'x': 3169: case 'y': case 'z': 3170: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 3171: case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 3172: case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 3173: case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 3174: case 'Y': case 'Z': 3175: letter: 3176: ident_length++; 3177: /* Compute step of hash function, to avoid a proc call on every token */ 3178: hash = HASHSTEP (hash, c); 3179: break; 3180: 3181: case '\n': 1.1.1.5 root 3182: if (ip->fname == 0 && *ibp == '-') { 3183: /* Newline - inhibits expansion of preceding token. 3184: If expanding a macro arg, we keep the newline -. 3185: In final output, it is deleted. 3186: We recognize Newline - in macro bodies and macro args. */ 3187: if (! concatenated) { 3188: ident_length = 0; 3189: hash = 0; 3190: } 3191: ibp++; 3192: if (!output_marks) { 3193: obp--; 3194: } else { 3195: /* If expanding a macro arg, keep the newline -. */ 3196: *obp++ = '-'; 3197: } 3198: break; 3199: } 3200: 1.1 root 3201: /* If reprocessing a macro expansion, newline is a special marker. */ 1.1.1.5 root 3202: else if (ip->macro != 0) { 1.1 root 3203: /* Newline White is a "funny space" to separate tokens that are 3204: supposed to be separate but without space between. 3205: Here White means any whitespace character. 3206: Newline - marks a recursive macro use that is not 3207: supposed to be expandable. */ 3208: 1.1.1.5 root 3209: if (is_space[*ibp]) { 1.1 root 3210: /* Newline Space does not prevent expansion of preceding token 3211: so expand the preceding token and then come back. */ 3212: if (ident_length > 0) 3213: goto specialchar; 3214: 3215: /* If generating final output, newline space makes a space. */ 3216: if (!output_marks) { 3217: obp[-1] = *ibp++; 3218: /* And Newline Newline makes a newline, so count it. */ 3219: if (obp[-1] == '\n') 3220: op->lineno++; 3221: } else { 3222: /* If expanding a macro arg, keep the newline space. 3223: If the arg gets stringified, newline space makes nothing. */ 3224: *obp++ = *ibp++; 3225: } 3226: } else abort (); /* Newline followed by something random? */ 3227: break; 3228: } 3229: 3230: /* If there is a pending identifier, handle it and come back here. */ 3231: if (ident_length > 0) 3232: goto specialchar; 3233: 3234: beg_of_line = ibp; 3235: 3236: /* Update the line counts and output a #line if necessary. */ 3237: ++ip->lineno; 3238: ++op->lineno; 3239: if (ip->lineno != op->lineno) { 3240: op->bufp = obp; 1.1.1.8 ! root 3241: output_line_directive (ip, op, 1, same_file); 1.1.1.7 root 3242: check_expand (op, limit - ibp); 1.1 root 3243: obp = op->bufp; 3244: } 3245: break; 3246: 3247: /* Come here either after (1) a null character that is part of the input 3248: or (2) at the end of the input, because there is a null there. */ 3249: case 0: 3250: if (ibp <= limit) 3251: /* Our input really contains a null character. */ 3252: goto randomchar; 3253: 3254: /* At end of a macro-expansion level, pop it and read next level. */ 3255: if (ip->macro != 0) { 3256: obp--; 3257: ibp--; 3258: /* If traditional, and we have an identifier that ends here, 3259: process it now, so we get the right error for recursion. */ 3260: if (traditional && ident_length 3261: && ! is_idchar[*instack[indepth - 1].bufp]) { 3262: redo_char = 1; 3263: goto randomchar; 3264: } 3265: POPMACRO; 3266: RECACHE; 3267: break; 3268: } 3269: 3270: /* If we don't have a pending identifier, 3271: return at end of input. */ 3272: if (ident_length == 0) { 3273: obp--; 3274: ibp--; 3275: op->bufp = obp; 3276: ip->bufp = ibp; 3277: goto ending; 3278: } 3279: 3280: /* If we do have a pending identifier, just consider this null 3281: a special character and arrange to dispatch on it again. 3282: The second time, IDENT_LENGTH will be zero so we will return. */ 3283: 3284: /* Fall through */ 3285: 3286: specialchar: 3287: 3288: /* Handle the case of a character such as /, ', " or null 3289: seen following an identifier. Back over it so that 3290: after the identifier is processed the special char 3291: will be dispatched on again. */ 3292: 3293: ibp--; 3294: obp--; 3295: redo_char = 1; 3296: 3297: default: 3298: 3299: randomchar: 3300: 3301: if (ident_length > 0) { 3302: register HASHNODE *hp; 3303: 3304: /* We have just seen an identifier end. If it's a macro, expand it. 3305: 3306: IDENT_LENGTH is the length of the identifier 3307: and HASH is its hash code. 3308: 3309: The identifier has already been copied to the output, 3310: so if it is a macro we must remove it. 3311: 3312: If REDO_CHAR is 0, the char that terminated the identifier 3313: has been skipped in the output and the input. 3314: OBP-IDENT_LENGTH-1 points to the identifier. 3315: If the identifier is a macro, we must back over the terminator. 3316: 3317: If REDO_CHAR is 1, the terminating char has already been 3318: backed over. OBP-IDENT_LENGTH points to the identifier. */ 3319: 3320: if (!pcp_outfile || pcp_inside_if) { 3321: for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL; 3322: hp = hp->next) { 3323: 3324: if (hp->length == ident_length) { 3325: int obufp_before_macroname; 3326: int op_lineno_before_macroname; 3327: register int i = ident_length; 3328: register U_CHAR *p = hp->name; 3329: register U_CHAR *q = obp - i; 3330: int disabled; 3331: 3332: if (! redo_char) 3333: q--; 3334: 3335: do { /* All this to avoid a strncmp () */ 3336: if (*p++ != *q++) 3337: goto hashcollision; 3338: } while (--i); 3339: 3340: /* We found a use of a macro name. 3341: see if the context shows it is a macro call. */ 3342: 3343: /* Back up over terminating character if not already done. */ 3344: if (! redo_char) { 3345: ibp--; 3346: obp--; 3347: } 3348: 3349: /* Save this as a displacement from the beginning of the output 3350: buffer. We can not save this as a position in the output 3351: buffer, because it may get realloc'ed by RECACHE. */ 3352: obufp_before_macroname = (obp - op->buf) - ident_length; 3353: op_lineno_before_macroname = op->lineno; 3354: 3355: if (hp->type == T_PCSTRING) { 3356: pcstring_used (hp); /* Mark the definition of this key 3357: as needed, ensuring that it 3358: will be output. */ 3359: break; /* Exit loop, since the key cannot have a 3360: definition any longer. */ 3361: } 3362: 3363: /* Record whether the macro is disabled. */ 3364: disabled = hp->type == T_DISABLED; 3365: 3366: /* This looks like a macro ref, but if the macro was disabled, 3367: just copy its name and put in a marker if requested. */ 3368: 3369: if (disabled) { 3370: #if 0 3371: /* This error check caught useful cases such as 1.1.1.5 root 3372: #define foo(x,y) bar (x (y,0), y) 3373: foo (foo, baz) */ 1.1 root 3374: if (traditional) 3375: error ("recursive use of macro `%s'", hp->name); 3376: #endif 3377: 3378: if (output_marks) { 3379: check_expand (op, limit - ibp + 2); 3380: *obp++ = '\n'; 3381: *obp++ = '-'; 3382: } 3383: break; 3384: } 3385: 3386: /* If macro wants an arglist, verify that a '(' follows. 3387: first skip all whitespace, copying it to the output 3388: after the macro name. Then, if there is no '(', 3389: decide this is not a macro call and leave things that way. */ 3390: if ((hp->type == T_MACRO || hp->type == T_DISABLED) 3391: && hp->value.defn->nargs >= 0) 3392: { 3393: U_CHAR *old_ibp = ibp; 3394: U_CHAR *old_obp = obp; 3395: int old_iln = ip->lineno; 3396: int old_oln = op->lineno; 3397: 3398: while (1) { 3399: /* Scan forward over whitespace, copying it to the output. */ 3400: if (ibp == limit && ip->macro != 0) { 3401: POPMACRO; 3402: RECACHE; 3403: old_ibp = ibp; 3404: old_obp = obp; 3405: old_iln = ip->lineno; 3406: old_oln = op->lineno; 3407: } 3408: /* A comment: copy it unchanged or discard it. */ 1.1.1.8 ! root 3409: else if (*ibp == '/' && ibp[1] == '*') { 1.1 root 3410: if (put_out_comments) { 3411: *obp++ = '/'; 3412: *obp++ = '*'; 3413: } else if (! traditional) { 3414: *obp++ = ' '; 3415: } 3416: ibp += 2; 3417: while (ibp + 1 != limit 3418: && !(ibp[0] == '*' && ibp[1] == '/')) { 3419: /* We need not worry about newline-marks, 3420: since they are never found in comments. */ 3421: if (*ibp == '\n') { 3422: /* Newline in a file. Count it. */ 3423: ++ip->lineno; 3424: ++op->lineno; 3425: } 3426: if (put_out_comments) 3427: *obp++ = *ibp++; 3428: else 3429: ibp++; 3430: } 3431: ibp += 2; 3432: if (put_out_comments) { 3433: *obp++ = '*'; 3434: *obp++ = '/'; 3435: } 3436: } 3437: else if (is_space[*ibp]) { 3438: *obp++ = *ibp++; 3439: if (ibp[-1] == '\n') { 3440: if (ip->macro == 0) { 3441: /* Newline in a file. Count it. */ 3442: ++ip->lineno; 3443: ++op->lineno; 3444: } else if (!output_marks) { 3445: /* A newline mark, and we don't want marks 3446: in the output. If it is newline-hyphen, 3447: discard it entirely. Otherwise, it is 3448: newline-whitechar, so keep the whitechar. */ 3449: obp--; 3450: if (*ibp == '-') 3451: ibp++; 3452: else { 3453: if (*ibp == '\n') 3454: ++op->lineno; 3455: *obp++ = *ibp++; 3456: } 3457: } else { 3458: /* A newline mark; copy both chars to the output. */ 3459: *obp++ = *ibp++; 3460: } 3461: } 3462: } 3463: else break; 3464: } 3465: if (*ibp != '(') { 3466: /* It isn't a macro call. 3467: Put back the space that we just skipped. */ 3468: ibp = old_ibp; 3469: obp = old_obp; 3470: ip->lineno = old_iln; 3471: op->lineno = old_oln; 3472: /* Exit the for loop. */ 3473: break; 3474: } 3475: } 3476: 3477: /* This is now known to be a macro call. 3478: Discard the macro name from the output, 1.1.1.7 root 3479: along with any following whitespace just copied, 3480: but preserve newlines if not outputting marks since this 3481: is more likely to do the right thing with line numbers. */ 1.1 root 3482: obp = op->buf + obufp_before_macroname; 1.1.1.7 root 3483: if (output_marks) 3484: op->lineno = op_lineno_before_macroname; 3485: else { 3486: int newlines = op->lineno - op_lineno_before_macroname; 3487: while (0 < newlines--) 3488: *obp++ = '\n'; 3489: } 1.1.1.5 root 3490: 3491: /* Prevent accidental token-pasting with a character 3492: before the macro call. */ 1.1.1.8 ! root 3493: if (!traditional && obp != op->buf) { ! 3494: switch (obp[-1]) { ! 3495: case '!': case '%': case '&': case '*': ! 3496: case '+': case '-': case '/': case ':': ! 3497: case '<': case '=': case '>': case '^': ! 3498: case '|': ! 3499: /* If we are expanding a macro arg, make a newline marker ! 3500: to separate the tokens. If we are making real output, ! 3501: a plain space will do. */ ! 3502: if (output_marks) ! 3503: *obp++ = '\n'; ! 3504: *obp++ = ' '; ! 3505: } 1.1.1.5 root 3506: } 3507: 1.1 root 3508: /* Expand the macro, reading arguments as needed, 3509: and push the expansion on the input stack. */ 3510: ip->bufp = ibp; 3511: op->bufp = obp; 3512: macroexpand (hp, op); 3513: 3514: /* Reexamine input stack, since macroexpand has pushed 3515: a new level on it. */ 3516: obp = op->bufp; 3517: RECACHE; 3518: break; 3519: } 3520: hashcollision: 3521: ; 3522: } /* End hash-table-search loop */ 3523: } 3524: ident_length = hash = 0; /* Stop collecting identifier */ 3525: redo_char = 0; 3526: concatenated = 0; 3527: } /* End if (ident_length > 0) */ 3528: } /* End switch */ 3529: } /* End per-char loop */ 3530: 3531: /* Come here to return -- but first give an error message 3532: if there was an unterminated successful conditional. */ 3533: ending: 1.1.1.7 root 3534: if (if_stack != ip->if_stack) 3535: { 1.1.1.8 ! root 3536: char *str; 1.1.1.7 root 3537: 3538: switch (if_stack->type) 3539: { 3540: case T_IF: 3541: str = "if"; 3542: break; 3543: case T_IFDEF: 3544: str = "ifdef"; 3545: break; 3546: case T_IFNDEF: 3547: str = "ifndef"; 3548: break; 3549: case T_ELSE: 3550: str = "else"; 3551: break; 3552: case T_ELIF: 3553: str = "elif"; 3554: break; 1.1.1.8 ! root 3555: default: ! 3556: abort (); 1.1.1.7 root 3557: } 3558: 3559: error_with_line (line_for_error (if_stack->lineno), 3560: "unterminated `#%s' conditional", str); 1.1 root 3561: } 3562: if_stack = ip->if_stack; 3563: } 3564: 3565: /* 3566: * Rescan a string into a temporary buffer and return the result 3567: * as a FILE_BUF. Note this function returns a struct, not a pointer. 3568: * 3569: * OUTPUT_MARKS nonzero means keep Newline markers found in the input 3570: * and insert such markers when appropriate. See `rescan' for details. 3571: * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately 3572: * before substitution; it is 0 for other uses. 3573: */ 3574: static FILE_BUF 3575: expand_to_temp_buffer (buf, limit, output_marks, assertions) 3576: U_CHAR *buf, *limit; 3577: int output_marks, assertions; 3578: { 3579: register FILE_BUF *ip; 3580: FILE_BUF obuf; 3581: int length = limit - buf; 3582: U_CHAR *buf1; 3583: int odepth = indepth; 3584: int save_assertions_flag = assertions_flag; 3585: 3586: assertions_flag = assertions; 3587: 3588: if (length < 0) 3589: abort (); 3590: 3591: /* Set up the input on the input stack. */ 3592: 3593: buf1 = (U_CHAR *) alloca (length + 1); 3594: { 3595: register U_CHAR *p1 = buf; 3596: register U_CHAR *p2 = buf1; 3597: 3598: while (p1 != limit) 3599: *p2++ = *p1++; 3600: } 3601: buf1[length] = 0; 3602: 3603: /* Set up to receive the output. */ 3604: 3605: obuf.length = length * 2 + 100; /* Usually enough. Why be stingy? */ 3606: obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length); 3607: obuf.fname = 0; 3608: obuf.macro = 0; 3609: obuf.free_ptr = 0; 3610: 3611: CHECK_DEPTH ({return obuf;}); 3612: 3613: ++indepth; 3614: 3615: ip = &instack[indepth]; 3616: ip->fname = 0; 3617: ip->nominal_fname = 0; 3618: ip->system_header_p = 0; 3619: ip->macro = 0; 3620: ip->free_ptr = 0; 3621: ip->length = length; 3622: ip->buf = ip->bufp = buf1; 3623: ip->if_stack = if_stack; 3624: 3625: ip->lineno = obuf.lineno = 1; 3626: 3627: /* Scan the input, create the output. */ 3628: rescan (&obuf, output_marks); 3629: 3630: /* Pop input stack to original state. */ 3631: --indepth; 3632: 3633: if (indepth != odepth) 3634: abort (); 3635: 3636: /* Record the output. */ 3637: obuf.length = obuf.bufp - obuf.buf; 3638: 3639: assertions_flag = save_assertions_flag; 3640: return obuf; 3641: } 3642: 3643: /* 3644: * Process a # directive. Expects IP->bufp to point after the '#', as in 1.1.1.8 ! root 3645: * `#define foo bar'. Passes to the directive handler 1.1 root 3646: * (do_define, do_include, etc.): the addresses of the 1st and 1.1.1.8 ! root 3647: * last chars of the directive (starting immediately after the # ! 3648: * keyword), plus op and the keyword table pointer. If the directive 1.1 root 3649: * contains comments it is copied into a temporary buffer sans comments 1.1.1.8 ! root 3650: * and the temporary buffer is passed to the directive handler instead. 1.1 root 3651: * Likewise for backslash-newlines. 3652: * 3653: * Returns nonzero if this was a known # directive. 3654: * Otherwise, returns zero, without advancing the input pointer. 3655: */ 3656: 3657: static int 3658: handle_directive (ip, op) 3659: FILE_BUF *ip, *op; 3660: { 3661: register U_CHAR *bp, *cp; 3662: register struct directive *kt; 3663: register int ident_length; 3664: U_CHAR *resume_p; 3665: 1.1.1.8 ! root 3666: /* Nonzero means we must copy the entire directive 1.1 root 3667: to get rid of comments or backslash-newlines. */ 1.1.1.8 ! root 3668: int copy_directive = 0; 1.1 root 3669: 3670: U_CHAR *ident, *after_ident; 3671: 3672: bp = ip->bufp; 3673: 3674: /* Record where the directive started. do_xifdef needs this. */ 3675: directive_start = bp - 1; 3676: 3677: /* Skip whitespace and \-newline. */ 3678: while (1) { 3679: if (is_hor_space[*bp]) { 1.1.1.8 ! root 3680: if (*bp != ' ' && *bp != '\t' && pedantic) ! 3681: pedwarn ("%s in preprocessing directive", char_name[*bp]); 1.1 root 3682: bp++; 1.1.1.7 root 3683: } else if (*bp == '/' && (bp[1] == '*' 3684: || (cplusplus_comments && bp[1] == '/'))) { 3685: ip->bufp = bp + 2; 1.1.1.2 root 3686: skip_to_end_of_comment (ip, &ip->lineno, 0); 1.1 root 3687: bp = ip->bufp; 3688: } else if (*bp == '\\' && bp[1] == '\n') { 3689: bp += 2; ip->lineno++; 3690: } else break; 3691: } 3692: 3693: /* Now find end of directive name. 3694: If we encounter a backslash-newline, exchange it with any following 3695: symbol-constituents so that we end up with a contiguous name. */ 3696: 3697: cp = bp; 3698: while (1) { 3699: if (is_idchar[*cp]) 3700: cp++; 3701: else { 3702: if (*cp == '\\' && cp[1] == '\n') 3703: name_newline_fix (cp); 3704: if (is_idchar[*cp]) 3705: cp++; 3706: else break; 3707: } 3708: } 3709: ident_length = cp - bp; 3710: ident = bp; 3711: after_ident = cp; 3712: 3713: /* A line of just `#' becomes blank. */ 3714: 3715: if (ident_length == 0 && *after_ident == '\n') { 3716: ip->bufp = after_ident; 3717: return 1; 3718: } 3719: 3720: if (ident_length == 0 || !is_idstart[*ident]) { 3721: U_CHAR *p = ident; 3722: while (is_idchar[*p]) { 3723: if (*p < '0' || *p > '9') 3724: break; 3725: p++; 3726: } 3727: /* Handle # followed by a line number. */ 3728: if (p != ident && !is_idchar[*p]) { 3729: static struct directive line_directive_table[] = { 3730: { 4, do_line, "line", T_LINE}, 3731: }; 3732: if (pedantic) 3733: pedwarn ("`#' followed by integer"); 3734: after_ident = ident; 3735: kt = line_directive_table; 3736: goto old_linenum; 3737: } 3738: 3739: /* Avoid error for `###' and similar cases unless -pedantic. */ 3740: if (p == ident) { 3741: while (*p == '#' || is_hor_space[*p]) p++; 3742: if (*p == '\n') { 3743: if (pedantic && !lang_asm) 1.1.1.8 ! root 3744: warning ("invalid preprocessing directive"); 1.1 root 3745: return 0; 3746: } 3747: } 3748: 3749: if (!lang_asm) 1.1.1.8 ! root 3750: error ("invalid preprocessing directive name"); 1.1 root 3751: 3752: return 0; 3753: } 3754: 3755: /* 3756: * Decode the keyword and call the appropriate expansion 3757: * routine, after moving the input pointer up to the next line. 3758: */ 3759: for (kt = directive_table; kt->length > 0; kt++) { 1.1.1.8 ! root 3760: if (kt->length == ident_length && !bcmp (kt->name, ident, ident_length)) { 1.1 root 3761: register U_CHAR *buf; 3762: register U_CHAR *limit; 3763: int unterminated; 3764: int junk; 1.1.1.5 root 3765: int *already_output; 1.1 root 3766: 3767: /* Nonzero means do not delete comments within the directive. 3768: #define needs this when -traditional. */ 3769: int keep_comments; 3770: 3771: old_linenum: 3772: 3773: limit = ip->buf + ip->length; 3774: unterminated = 0; 1.1.1.5 root 3775: already_output = 0; 1.1 root 3776: keep_comments = traditional && kt->traditional_comments; 3777: /* #import is defined only in Objective C, or when on the NeXT. */ 1.1.1.8 ! root 3778: if (kt->type == T_IMPORT ! 3779: && !(objc || lookup ((U_CHAR *) "__NeXT__", -1, -1))) 1.1 root 3780: break; 3781: 1.1.1.8 ! root 3782: /* Find the end of this directive (first newline not backslashed 1.1 root 3783: and not in a string or comment). 1.1.1.8 ! root 3784: Set COPY_DIRECTIVE if the directive must be copied 1.1 root 3785: (it contains a backslash-newline or a comment). */ 3786: 3787: buf = bp = after_ident; 3788: while (bp < limit) { 3789: register U_CHAR c = *bp++; 3790: switch (c) { 3791: case '\\': 3792: if (bp < limit) { 3793: if (*bp == '\n') { 3794: ip->lineno++; 1.1.1.8 ! root 3795: copy_directive = 1; 1.1.1.7 root 3796: bp++; 3797: } else if (traditional) 3798: bp++; 1.1 root 3799: } 3800: break; 3801: 3802: case '\'': 3803: case '\"': 1.1.1.8 ! root 3804: bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, ©_directive, &unterminated); 1.1 root 3805: /* Don't bother calling the directive if we already got an error 3806: message due to unterminated string. Skip everything and pretend 3807: we called the directive. */ 3808: if (unterminated) { 3809: if (traditional) { 3810: /* Traditional preprocessing permits unterminated strings. */ 3811: ip->bufp = bp; 3812: goto endloop1; 3813: } 3814: ip->bufp = bp; 3815: return 1; 3816: } 3817: break; 3818: 3819: /* <...> is special for #include. */ 3820: case '<': 3821: if (!kt->angle_brackets) 3822: break; 1.1.1.7 root 3823: while (bp < limit && *bp != '>' && *bp != '\n') { 3824: if (*bp == '\\' && bp[1] == '\n') { 3825: ip->lineno++; 1.1.1.8 ! root 3826: copy_directive = 1; 1.1.1.7 root 3827: bp++; 3828: } 3829: bp++; 3830: } 1.1 root 3831: break; 3832: 3833: case '/': 3834: if (*bp == '\\' && bp[1] == '\n') 3835: newline_fix (bp); 3836: if (*bp == '*' 1.1.1.4 root 3837: || (cplusplus_comments && *bp == '/')) { 1.1 root 3838: U_CHAR *obp = bp - 1; 3839: ip->bufp = bp + 1; 1.1.1.2 root 3840: skip_to_end_of_comment (ip, &ip->lineno, 0); 1.1 root 3841: bp = ip->bufp; 1.1.1.8 ! root 3842: /* No need to copy the directive because of a comment at the end; 1.1 root 3843: just don't include the comment in the directive. */ 3844: if (bp == limit || *bp == '\n') { 3845: bp = obp; 3846: goto endloop1; 3847: } 3848: /* Don't remove the comments if -traditional. */ 3849: if (! keep_comments) 1.1.1.8 ! root 3850: copy_directive++; 1.1 root 3851: } 3852: break; 3853: 3854: case '\f': 1.1.1.8 ! root 3855: case '\r': 1.1 root 3856: case '\v': 3857: if (pedantic) 1.1.1.8 ! root 3858: pedwarn ("%s in preprocessing directive", char_name[c]); 1.1 root 3859: break; 3860: 3861: case '\n': 3862: --bp; /* Point to the newline */ 3863: ip->bufp = bp; 3864: goto endloop1; 3865: } 3866: } 3867: ip->bufp = bp; 3868: 3869: endloop1: 3870: resume_p = ip->bufp; 3871: /* BP is the end of the directive. 3872: RESUME_P is the next interesting data after the directive. 3873: A comment may come between. */ 3874: 3875: /* If a directive should be copied through, and -E was given, 3876: pass it through before removing comments. */ 3877: if (!no_output && kt->pass_thru && put_out_comments) { 3878: int len; 3879: 3880: /* Output directive name. */ 3881: check_expand (op, kt->length + 2); 3882: /* Make sure # is at the start of a line */ 3883: if (op->bufp > op->buf && op->bufp[-1] != '\n') { 3884: op->lineno++; 3885: *op->bufp++ = '\n'; 3886: } 3887: *op->bufp++ = '#'; 3888: bcopy (kt->name, op->bufp, kt->length); 3889: op->bufp += kt->length; 3890: 3891: /* Output arguments. */ 3892: len = (bp - buf); 3893: check_expand (op, len); 1.1.1.7 root 3894: bcopy (buf, (char *) op->bufp, len); 1.1 root 3895: op->bufp += len; 3896: /* Take account of any (escaped) newlines just output. */ 3897: while (--len >= 0) 3898: if (buf[len] == '\n') 3899: op->lineno++; 3900: 3901: already_output = &junk; 3902: } /* Don't we need a newline or #line? */ 3903: 1.1.1.8 ! root 3904: if (copy_directive) { 1.1 root 3905: register U_CHAR *xp = buf; 1.1.1.8 ! root 3906: /* Need to copy entire directive into temp buffer before dispatching */ 1.1 root 3907: 1.1.1.8 ! root 3908: cp = (U_CHAR *) alloca (bp - buf + 5); /* room for directive plus 1.1 root 3909: some slop */ 3910: buf = cp; 3911: 3912: /* Copy to the new buffer, deleting comments 3913: and backslash-newlines (and whitespace surrounding the latter). */ 3914: 3915: while (xp < bp) { 3916: register U_CHAR c = *xp++; 3917: *cp++ = c; 3918: 3919: switch (c) { 3920: case '\n': 3921: abort (); /* A bare newline should never part of the line. */ 3922: break; 3923: 3924: /* <...> is special for #include. */ 3925: case '<': 3926: if (!kt->angle_brackets) 3927: break; 3928: while (xp < bp && c != '>') { 3929: c = *xp++; 3930: if (c == '\\' && xp < bp && *xp == '\n') 3931: xp++; 3932: else 3933: *cp++ = c; 3934: } 3935: break; 3936: 3937: case '\\': 3938: if (*xp == '\n') { 3939: xp++; 3940: cp--; 1.1.1.8 ! root 3941: if (cp != buf && is_hor_space[cp[-1]]) { ! 3942: while (cp - 1 != buf && is_hor_space[cp[-2]]) ! 3943: cp--; 1.1 root 3944: SKIP_WHITE_SPACE (xp); 1.1.1.8 ! root 3945: } else if (is_hor_space[*xp]) { 1.1 root 3946: *cp++ = *xp++; 3947: SKIP_WHITE_SPACE (xp); 3948: } 1.1.1.8 ! root 3949: } else if (traditional && xp < bp) { 1.1.1.3 root 3950: *cp++ = *xp++; 1.1 root 3951: } 3952: break; 3953: 3954: case '\'': 3955: case '\"': 3956: { 3957: register U_CHAR *bp1 1.1.1.4 root 3958: = skip_quoted_string (xp - 1, bp, ip->lineno, 3959: NULL_PTR, NULL_PTR, NULL_PTR); 1.1 root 3960: while (xp != bp1) 3961: if (*xp == '\\') { 3962: if (*++xp != '\n') 3963: *cp++ = '\\'; 3964: else 3965: xp++; 3966: } else 3967: *cp++ = *xp++; 3968: } 3969: break; 3970: 3971: case '/': 3972: if (*xp == '*' 1.1.1.4 root 3973: || (cplusplus_comments && *xp == '/')) { 1.1 root 3974: ip->bufp = xp + 1; 1.1.1.8 ! root 3975: /* If we already copied the directive through, 1.1 root 3976: already_output != 0 prevents outputting comment now. */ 1.1.1.2 root 3977: skip_to_end_of_comment (ip, already_output, 0); 1.1 root 3978: if (keep_comments) 3979: while (xp != ip->bufp) 3980: *cp++ = *xp++; 3981: /* Delete or replace the slash. */ 3982: else if (traditional) 3983: cp--; 3984: else 3985: cp[-1] = ' '; 3986: xp = ip->bufp; 3987: } 3988: } 3989: } 3990: 3991: /* Null-terminate the copy. */ 3992: 3993: *cp = 0; 3994: } else 3995: cp = bp; 3996: 3997: ip->bufp = resume_p; 3998: 3999: /* Some directives should be written out for cc1 to process, 4000: just as if they were not defined. And sometimes we're copying 4001: definitions through. */ 4002: 4003: if (!no_output && already_output == 0 4004: && (kt->pass_thru 4005: || (kt->type == T_DEFINE 4006: && (dump_macros == dump_names 4007: || dump_macros == dump_definitions)))) { 4008: int len; 4009: 4010: /* Output directive name. */ 4011: check_expand (op, kt->length + 1); 4012: *op->bufp++ = '#'; 1.1.1.7 root 4013: bcopy (kt->name, (char *) op->bufp, kt->length); 1.1 root 4014: op->bufp += kt->length; 4015: 4016: if (kt->pass_thru || dump_macros == dump_definitions) { 4017: /* Output arguments. */ 4018: len = (cp - buf); 4019: check_expand (op, len); 1.1.1.7 root 4020: bcopy (buf, (char *) op->bufp, len); 1.1 root 4021: op->bufp += len; 1.1.1.4 root 4022: } else if (kt->type == T_DEFINE && dump_macros == dump_names) { 4023: U_CHAR *xp = buf; 4024: U_CHAR *yp; 4025: SKIP_WHITE_SPACE (xp); 4026: yp = xp; 4027: while (is_idchar[*xp]) xp++; 4028: len = (xp - yp); 4029: check_expand (op, len + 1); 4030: *op->bufp++ = ' '; 4031: bcopy (yp, op->bufp, len); 4032: op->bufp += len; 1.1 root 4033: } 4034: } /* Don't we need a newline or #line? */ 4035: 1.1.1.8 ! root 4036: /* Call the appropriate directive handler. buf now points to 1.1 root 4037: either the appropriate place in the input buffer, or to 4038: the temp buffer if it was necessary to make one. cp 4039: points to the first char after the contents of the (possibly 1.1.1.8 ! root 4040: copied) directive, in either case. */ 1.1 root 4041: (*kt->func) (buf, cp, op, kt); 4042: check_expand (op, ip->length - (ip->bufp - ip->buf)); 4043: 4044: return 1; 4045: } 4046: } 4047: 4048: /* It is deliberate that we don't warn about undefined directives. 4049: That is the responsibility of cc1. */ 4050: return 0; 4051: } 4052: 1.1.1.3 root 4053: static struct tm * 4054: timestamp () 4055: { 4056: static struct tm *timebuf; 4057: if (!timebuf) { 1.1.1.7 root 4058: time_t t = time ((time_t *)0); 1.1.1.3 root 4059: timebuf = localtime (&t); 4060: } 4061: return timebuf; 4062: } 4063: 1.1 root 4064: static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 4065: "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 4066: }; 4067: 4068: /* 4069: * expand things like __FILE__. Place the expansion into the output 4070: * buffer *without* rescanning. 4071: */ 4072: 4073: static void 4074: special_symbol (hp, op) 4075: HASHNODE *hp; 4076: FILE_BUF *op; 4077: { 4078: char *buf; 4079: int i, len; 4080: int true_indepth; 4081: FILE_BUF *ip = NULL; 1.1.1.3 root 4082: struct tm *timebuf; 1.1 root 4083: 4084: int paren = 0; /* For special `defined' keyword */ 4085: 4086: if (pcp_outfile && pcp_inside_if 4087: && hp->type != T_SPEC_DEFINED && hp->type != T_CONST) 4088: error ("Predefined macro `%s' used inside `#if' during precompilation", 4089: hp->name); 4090: 4091: for (i = indepth; i >= 0; i--) 4092: if (instack[i].fname != NULL) { 4093: ip = &instack[i]; 4094: break; 4095: } 4096: if (ip == NULL) { 4097: error ("cccp error: not in any file?!"); 4098: return; /* the show must go on */ 4099: } 4100: 4101: switch (hp->type) { 4102: case T_FILE: 4103: case T_BASE_FILE: 4104: { 4105: char *string; 4106: if (hp->type == T_FILE) 4107: string = ip->nominal_fname; 4108: else 4109: string = instack[0].nominal_fname; 4110: 4111: if (string) 4112: { 1.1.1.6 root 4113: buf = (char *) alloca (3 + 4 * strlen (string)); 4114: quote_string (buf, string); 1.1 root 4115: } 4116: else 4117: buf = "\"\""; 4118: 4119: break; 4120: } 4121: 4122: case T_INCLUDE_LEVEL: 4123: true_indepth = 0; 4124: for (i = indepth; i >= 0; i--) 4125: if (instack[i].fname != NULL) 4126: true_indepth++; 4127: 4128: buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */ 4129: sprintf (buf, "%d", true_indepth - 1); 4130: break; 4131: 4132: case T_VERSION: 4133: buf = (char *) alloca (3 + strlen (version_string)); 4134: sprintf (buf, "\"%s\"", version_string); 4135: break; 4136: 1.1.1.6 root 4137: #ifndef NO_BUILTIN_SIZE_TYPE 1.1 root 4138: case T_SIZE_TYPE: 1.1.1.7 root 4139: buf = SIZE_TYPE; 1.1 root 4140: break; 1.1.1.6 root 4141: #endif 1.1 root 4142: 1.1.1.6 root 4143: #ifndef NO_BUILTIN_PTRDIFF_TYPE 1.1 root 4144: case T_PTRDIFF_TYPE: 1.1.1.7 root 4145: buf = PTRDIFF_TYPE; 1.1 root 4146: break; 1.1.1.6 root 4147: #endif 1.1 root 4148: 4149: case T_WCHAR_TYPE: 1.1.1.7 root 4150: buf = wchar_type; 1.1 root 4151: break; 4152: 1.1.1.5 root 4153: case T_USER_LABEL_PREFIX_TYPE: 1.1.1.7 root 4154: buf = USER_LABEL_PREFIX; 1.1.1.5 root 4155: break; 4156: 4157: case T_REGISTER_PREFIX_TYPE: 1.1.1.7 root 4158: buf = REGISTER_PREFIX; 1.1.1.5 root 4159: break; 4160: 1.1.1.8 ! root 4161: case T_IMMEDIATE_PREFIX_TYPE: ! 4162: buf = IMMEDIATE_PREFIX; ! 4163: break; ! 4164: 1.1 root 4165: case T_CONST: 1.1.1.8 ! root 4166: buf = hp->value.cpval; 1.1 root 4167: if (pcp_inside_if && pcp_outfile) 4168: /* Output a precondition for this macro use */ 1.1.1.8 ! root 4169: fprintf (pcp_outfile, "#define %s %s\n", hp->name, buf); 1.1 root 4170: break; 4171: 4172: case T_SPECLINE: 4173: buf = (char *) alloca (10); 4174: sprintf (buf, "%d", ip->lineno); 4175: break; 4176: 4177: case T_DATE: 4178: case T_TIME: 4179: buf = (char *) alloca (20); 1.1.1.3 root 4180: timebuf = timestamp (); 1.1 root 4181: if (hp->type == T_DATE) 4182: sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon], 4183: timebuf->tm_mday, timebuf->tm_year + 1900); 4184: else 4185: sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min, 4186: timebuf->tm_sec); 4187: break; 4188: 4189: case T_SPEC_DEFINED: 4190: buf = " 0 "; /* Assume symbol is not defined */ 4191: ip = &instack[indepth]; 4192: SKIP_WHITE_SPACE (ip->bufp); 4193: if (*ip->bufp == '(') { 4194: paren++; 4195: ip->bufp++; /* Skip over the paren */ 4196: SKIP_WHITE_SPACE (ip->bufp); 4197: } 4198: 4199: if (!is_idstart[*ip->bufp]) 4200: goto oops; 1.1.1.8 ! root 4201: if ((hp = lookup (ip->bufp, -1, -1))) { 1.1 root 4202: if (pcp_outfile && pcp_inside_if 1.1.1.7 root 4203: && (hp->type == T_CONST 4204: || (hp->type == T_MACRO && hp->value.defn->predefined))) 1.1 root 4205: /* Output a precondition for this macro use. */ 4206: fprintf (pcp_outfile, "#define %s\n", hp->name); 4207: buf = " 1 "; 4208: } 4209: else 4210: if (pcp_outfile && pcp_inside_if) { 4211: /* Output a precondition for this macro use */ 4212: U_CHAR *cp = ip->bufp; 4213: fprintf (pcp_outfile, "#undef "); 4214: while (is_idchar[*cp]) /* Ick! */ 4215: fputc (*cp++, pcp_outfile); 4216: putc ('\n', pcp_outfile); 4217: } 4218: while (is_idchar[*ip->bufp]) 4219: ++ip->bufp; 4220: SKIP_WHITE_SPACE (ip->bufp); 4221: if (paren) { 4222: if (*ip->bufp != ')') 4223: goto oops; 4224: ++ip->bufp; 4225: } 4226: break; 4227: 4228: oops: 4229: 4230: error ("`defined' without an identifier"); 4231: break; 4232: 4233: default: 4234: error ("cccp error: invalid special hash type"); /* time for gdb */ 4235: abort (); 4236: } 4237: len = strlen (buf); 4238: check_expand (op, len); 1.1.1.7 root 4239: bcopy (buf, (char *) op->bufp, len); 1.1 root 4240: op->bufp += len; 4241: 4242: return; 4243: } 4244: 4245: 4246: /* Routines to handle #directives */ 4247: 4248: /* Handle #include and #import. 4249: This function expects to see "fname" or <fname> on the input. */ 4250: 4251: static int 4252: do_include (buf, limit, op, keyword) 4253: U_CHAR *buf, *limit; 4254: FILE_BUF *op; 4255: struct directive *keyword; 4256: { 4257: int importing = (keyword->type == T_IMPORT); 4258: int skip_dirs = (keyword->type == T_INCLUDE_NEXT); 4259: static int import_warning = 0; 4260: char *fname; /* Dynamically allocated fname buffer */ 4261: char *pcftry; 4262: char *pcfname; 4263: U_CHAR *fbeg, *fend; /* Beginning and end of fname */ 4264: 4265: struct file_name_list *search_start = include; /* Chain of dirs to search */ 4266: struct file_name_list dsp[1]; /* First in chain, if #include "..." */ 1.1.1.4 root 4267: struct file_name_list *searchptr = 0; 1.1.1.8 ! root 4268: size_t flen; 1.1 root 4269: 4270: int f; /* file number */ 4271: 4272: int retried = 0; /* Have already tried macro 4273: expanding the include line*/ 1.1.1.4 root 4274: int angle_brackets = 0; /* 0 for "...", 1 for <...> */ 1.1 root 4275: int pcf = -1; 4276: char *pcfbuf; 1.1.1.8 ! root 4277: char *pcfbuflimit; 1.1 root 4278: int pcfnum; 4279: f= -1; /* JF we iz paranoid! */ 4280: 1.1.1.4 root 4281: if (importing && warn_import && !inhibit_warnings 1.1.1.2 root 4282: && !instack[indepth].system_header_p && !import_warning) { 1.1 root 4283: import_warning = 1; 4284: warning ("using `#import' is not recommended"); 4285: fprintf (stderr, "The fact that a certain header file need not be processed more than once\n"); 4286: fprintf (stderr, "should be indicated in the header file, not where it is used.\n"); 4287: fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n"); 4288: fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n"); 4289: fprintf (stderr, " #define _FOO_H_INCLUDED\n"); 4290: fprintf (stderr, " ... <real contents of file> ...\n"); 4291: fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n"); 4292: fprintf (stderr, "Then users can use `#include' any number of times.\n"); 4293: fprintf (stderr, "GNU C automatically avoids processing the file more than once\n"); 4294: fprintf (stderr, "when it is equipped with such a conditional.\n"); 4295: } 4296: 4297: get_filename: 4298: 4299: fbeg = buf; 4300: SKIP_WHITE_SPACE (fbeg); 4301: /* Discard trailing whitespace so we can easily see 4302: if we have parsed all the significant chars we were given. */ 4303: while (limit != fbeg && is_hor_space[limit[-1]]) limit--; 4304: 4305: switch (*fbeg++) { 4306: case '\"': 1.1.1.4 root 4307: { 1.1 root 4308: FILE_BUF *fp; 1.1.1.4 root 4309: /* Copy the operand text, concatenating the strings. */ 4310: { 4311: U_CHAR *fin = fbeg; 4312: fbeg = (U_CHAR *) alloca (limit - fbeg + 1); 4313: fend = fbeg; 4314: while (fin != limit) { 4315: while (fin != limit && *fin != '\"') 4316: *fend++ = *fin++; 4317: fin++; 4318: if (fin == limit) 4319: break; 4320: /* If not at the end, there had better be another string. */ 4321: /* Skip just horiz space, and don't go past limit. */ 4322: while (fin != limit && is_hor_space[*fin]) fin++; 4323: if (fin != limit && *fin == '\"') 4324: fin++; 4325: else 4326: goto fail; 4327: } 4328: } 1.1.1.5 root 4329: *fend = 0; 1.1 root 4330: 4331: /* We have "filename". Figure out directory this source 4332: file is coming from and put it on the front of the list. */ 4333: 4334: /* If -I- was specified, don't search current dir, only spec'd ones. */ 4335: if (ignore_srcdir) break; 4336: 4337: for (fp = &instack[indepth]; fp >= instack; fp--) 4338: { 4339: int n; 4340: char *ep,*nam; 4341: 4342: if ((nam = fp->nominal_fname) != NULL) { 4343: /* Found a named file. Figure out dir of the file, 4344: and put it in front of the search list. */ 4345: dsp[0].next = search_start; 4346: search_start = dsp; 4347: #ifndef VMS 4348: ep = rindex (nam, '/'); 1.1.1.8 ! root 4349: #ifdef DIR_SEPARATOR ! 4350: if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR); ! 4351: else { ! 4352: char *tmp = rindex (nam, DIR_SEPARATOR); ! 4353: if (tmp != NULL && tmp > ep) ep = tmp; ! 4354: } ! 4355: #endif 1.1 root 4356: #else /* VMS */ 4357: ep = rindex (nam, ']'); 4358: if (ep == NULL) ep = rindex (nam, '>'); 4359: if (ep == NULL) ep = rindex (nam, ':'); 4360: if (ep != NULL) ep++; 4361: #endif /* VMS */ 4362: if (ep != NULL) { 4363: n = ep - nam; 4364: dsp[0].fname = (char *) alloca (n + 1); 4365: strncpy (dsp[0].fname, nam, n); 4366: dsp[0].fname[n] = '\0'; 1.1.1.4 root 4367: if (n + INCLUDE_LEN_FUDGE > max_include_len) 4368: max_include_len = n + INCLUDE_LEN_FUDGE; 1.1 root 4369: } else { 4370: dsp[0].fname = 0; /* Current directory */ 4371: } 1.1.1.7 root 4372: dsp[0].got_name_map = 0; 1.1 root 4373: break; 4374: } 4375: } 4376: break; 4377: } 4378: 4379: case '<': 4380: fend = fbeg; 4381: while (fend != limit && *fend != '>') fend++; 4382: if (*fend == '>' && fend + 1 == limit) { 1.1.1.4 root 4383: angle_brackets = 1; 1.1 root 4384: /* If -I-, start with the first -I dir after the -I-. */ 4385: if (first_bracket_include) 4386: search_start = first_bracket_include; 4387: break; 4388: } 4389: goto fail; 4390: 4391: default: 1.1.1.7 root 4392: #ifdef VMS 4393: /* 4394: * Support '#include xyz' like VAX-C to allow for easy use of all the 4395: * decwindow include files. It defaults to '#include <xyz.h>' (so the 4396: * code from case '<' is repeated here) and generates a warning. 1.1.1.8 ! root 4397: * (Note: macro expansion of `xyz' takes precedence.) 1.1.1.7 root 4398: */ 1.1.1.8 ! root 4399: if (retried && isalpha(*(--fbeg))) { 1.1.1.7 root 4400: fend = fbeg; 4401: while (fend != limit && (!isspace(*fend))) fend++; 4402: warning ("VAX-C-style include specification found, use '#include <filename.h>' !"); 4403: if (fend == limit) { 4404: angle_brackets = 1; 4405: /* If -I-, start with the first -I dir after the -I-. */ 4406: if (first_bracket_include) 4407: search_start = first_bracket_include; 4408: break; 4409: } 4410: } 4411: #endif 4412: 1.1 root 4413: fail: 4414: if (retried) { 1.1.1.5 root 4415: error ("`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name); 1.1 root 4416: return 0; 4417: } else { 1.1.1.8 ! root 4418: /* Expand buffer and then remove any newline markers. ! 4419: We can't just tell expand_to_temp_buffer to omit the markers, ! 4420: since it would put extra spaces in include file names. */ ! 4421: FILE_BUF trybuf; ! 4422: U_CHAR *src; ! 4423: trybuf = expand_to_temp_buffer (buf, limit, 1, 0); ! 4424: src = trybuf.buf; 1.1 root 4425: buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1); 1.1.1.8 ! root 4426: limit = buf; ! 4427: while (src != trybuf.bufp) { ! 4428: switch ((*limit++ = *src++)) { ! 4429: case '\n': ! 4430: limit--; ! 4431: src++; ! 4432: break; ! 4433: ! 4434: case '\'': ! 4435: case '\"': ! 4436: { ! 4437: U_CHAR *src1 = skip_quoted_string (src - 1, trybuf.bufp, 0, ! 4438: NULL_PTR, NULL_PTR, NULL_PTR); ! 4439: while (src != src1) ! 4440: *limit++ = *src++; ! 4441: } ! 4442: break; ! 4443: } ! 4444: } ! 4445: *limit = 0; 1.1 root 4446: free (trybuf.buf); 4447: retried++; 4448: goto get_filename; 4449: } 4450: } 4451: 4452: /* For #include_next, skip in the search path 4453: past the dir in which the containing file was found. */ 4454: if (skip_dirs) { 4455: FILE_BUF *fp; 4456: for (fp = &instack[indepth]; fp >= instack; fp--) 4457: if (fp->fname != NULL) { 4458: /* fp->dir is null if the containing file was specified 4459: with an absolute file name. In that case, don't skip anything. */ 4460: if (fp->dir) 4461: search_start = fp->dir->next; 4462: break; 4463: } 4464: } 4465: 4466: flen = fend - fbeg; 1.1.1.5 root 4467: 4468: if (flen == 0) 4469: { 4470: error ("empty file name in `#%s'", keyword->name); 4471: return 0; 4472: } 4473: 1.1 root 4474: /* Allocate this permanently, because it gets stored in the definitions 4475: of macros. */ 1.1.1.8 ! root 4476: fname = xmalloc (max_include_len + flen + 4); 1.1 root 4477: /* + 2 above for slash and terminating null. */ 1.1.1.7 root 4478: /* + 2 added for '.h' on VMS (to support '#include filename') */ 1.1 root 4479: 4480: /* If specified file name is absolute, just open it. */ 4481: 1.1.1.8 ! root 4482: if (*fbeg == '/' ! 4483: #ifdef DIR_SEPARATOR ! 4484: || *fbeg == DIR_SEPARATOR ! 4485: #endif ! 4486: ) { ! 4487: strncpy (fname, (char *) fbeg, flen); 1.1 root 4488: fname[flen] = 0; 1.1.1.4 root 4489: if (redundant_include_p (fname)) 1.1.1.2 root 4490: return 0; 1.1 root 4491: if (importing) 1.1.1.7 root 4492: f = lookup_import (fname, NULL_PTR); 1.1 root 4493: else 1.1.1.7 root 4494: f = open_include_file (fname, NULL_PTR); 1.1 root 4495: if (f == -2) 4496: return 0; /* Already included this file */ 4497: } else { 4498: /* Search directory path, trying to open the file. 4499: Copy each filename tried into FNAME. */ 4500: 4501: for (searchptr = search_start; searchptr; searchptr = searchptr->next) { 4502: if (searchptr->fname) { 4503: /* The empty string in a search path is ignored. 4504: This makes it possible to turn off entirely 4505: a standard piece of the list. */ 4506: if (searchptr->fname[0] == 0) 4507: continue; 1.1.1.8 ! root 4508: strcpy (fname, skip_redundant_dir_prefix (searchptr->fname)); ! 4509: if (fname[0] && fname[strlen (fname) - 1] != '/') ! 4510: strcat (fname, "/"); 1.1 root 4511: } else { 4512: fname[0] = 0; 4513: } 1.1.1.8 ! root 4514: strncat (fname, (char *) fbeg, flen); 1.1 root 4515: #ifdef VMS 4516: /* Change this 1/2 Unix 1/2 VMS file specification into a 4517: full VMS file specification */ 4518: if (searchptr->fname && (searchptr->fname[0] != 0)) { 4519: /* Fix up the filename */ 4520: hack_vms_include_specification (fname); 4521: } else { 4522: /* This is a normal VMS filespec, so use it unchanged. */ 4523: strncpy (fname, fbeg, flen); 4524: fname[flen] = 0; 1.1.1.7 root 4525: /* if it's '#include filename', add the missing .h */ 4526: if (index(fname,'.')==NULL) { 4527: strcat (fname, ".h"); 4528: } 1.1 root 4529: } 4530: #endif /* VMS */ 1.1.1.8 ! root 4531: /* ??? There are currently 3 separate mechanisms for avoiding processing ! 4532: of redundant include files: #import, #pragma once, and ! 4533: redundant_include_p. It would be nice if they were unified. */ ! 4534: if (redundant_include_p (fname)) ! 4535: return 0; 1.1 root 4536: if (importing) 1.1.1.7 root 4537: f = lookup_import (fname, searchptr); 1.1 root 4538: else 1.1.1.7 root 4539: f = open_include_file (fname, searchptr); 1.1 root 4540: if (f == -2) 4541: return 0; /* Already included this file */ 1.1.1.5 root 4542: #ifdef EACCES 4543: else if (f == -1 && errno == EACCES) 4544: warning ("Header file %s exists, but is not readable", fname); 4545: #endif 1.1 root 4546: if (f >= 0) 4547: break; 4548: } 4549: } 4550: 4551: if (f < 0) { 4552: /* A file that was not found. */ 4553: 1.1.1.8 ! root 4554: strncpy (fname, (char *) fbeg, flen); 1.1 root 4555: fname[flen] = 0; 1.1.1.7 root 4556: /* If generating dependencies and -MG was specified, we assume missing 4557: files are leaf files, living in the same directory as the source file 4558: or other similar place; these missing files may be generated from 4559: other files and may not exist yet (eg: y.tab.h). */ 4560: if (print_deps_missing_files 4561: && print_deps > (angle_brackets || (system_include_depth > 0))) 4562: { 4563: /* If it was requested as a system header file, 4564: then assume it belongs in the first place to look for such. */ 4565: if (angle_brackets) 4566: { 4567: for (searchptr = search_start; searchptr; searchptr = searchptr->next) 4568: { 4569: if (searchptr->fname) 4570: { 4571: char *p; 4572: 4573: if (searchptr->fname[0] == 0) 4574: continue; 1.1.1.8 ! root 4575: p = (char *) alloca (strlen (searchptr->fname) ! 4576: + strlen (fname) + 2); ! 4577: strcpy (p, skip_redundant_dir_prefix (searchptr->fname)); ! 4578: if (p[0] && p[strlen (p) - 1] != '/') ! 4579: strcat (p, "/"); 1.1.1.7 root 4580: strcat (p, fname); 4581: deps_output (p, ' '); 4582: break; 4583: } 4584: } 4585: } 4586: else 4587: { 4588: /* Otherwise, omit the directory, as if the file existed 4589: in the directory with the source. */ 4590: deps_output (fname, ' '); 4591: } 4592: } 1.1.1.5 root 4593: /* If -M was specified, and this header file won't be added to the 4594: dependency list, then don't count this as an error, because we can 4595: still produce correct output. Otherwise, we can't produce correct 4596: output, because there may be dependencies we need inside the missing 4597: file, and we don't know what directory this missing file exists in. */ 1.1.1.7 root 4598: else if (print_deps 1.1.1.5 root 4599: && (print_deps <= (angle_brackets || (system_include_depth > 0)))) 4600: warning ("No include path in which to find %s", fname); 4601: else if (search_start) 1.1.1.4 root 4602: error_from_errno (fname); 4603: else 4604: error ("No include path in which to find %s", fname); 1.1 root 4605: } else { 4606: /* Check to see if this include file is a once-only include file. 4607: If so, give up. */ 4608: 4609: struct file_name_list* ptr; 4610: 4611: for (ptr = dont_repeat_files; ptr; ptr = ptr->next) { 4612: if (!strcmp (ptr->fname, fname)) { 4613: close (f); 4614: return 0; /* This file was once'd. */ 4615: } 4616: } 4617: 4618: for (ptr = all_include_files; ptr; ptr = ptr->next) { 4619: if (!strcmp (ptr->fname, fname)) 4620: break; /* This file was included before. */ 4621: } 4622: 4623: if (ptr == 0) { 4624: /* This is the first time for this file. */ 4625: /* Add it to list of files included. */ 4626: 4627: ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 4628: ptr->control_macro = 0; 1.1.1.6 root 4629: ptr->c_system_include_path = 0; 1.1 root 4630: ptr->next = all_include_files; 4631: all_include_files = ptr; 4632: ptr->fname = savestring (fname); 1.1.1.7 root 4633: ptr->got_name_map = 0; 1.1 root 4634: 4635: /* For -M, add this file to the dependencies. */ 1.1.1.7 root 4636: if (print_deps > (angle_brackets || (system_include_depth > 0))) 4637: deps_output (fname, ' '); 1.1 root 4638: } 4639: 4640: /* Handle -H option. */ 1.1.1.8 ! root 4641: if (print_include_names) ! 4642: fprintf (stderr, "%*s%s\n", indepth, "", fname); 1.1 root 4643: 1.1.1.4 root 4644: if (angle_brackets) 1.1 root 4645: system_include_depth++; 4646: 4647: /* Actually process the file. */ 4648: add_import (f, fname); /* Record file on "seen" list for #import. */ 4649: 4650: pcftry = (char *) alloca (strlen (fname) + 30); 4651: pcfbuf = 0; 4652: pcfnum = 0; 4653: 4654: if (!no_precomp) 1.1.1.8 ! root 4655: { ! 4656: struct stat stat_f; 1.1 root 4657: 1.1.1.8 ! root 4658: fstat (f, &stat_f); ! 4659: ! 4660: do { ! 4661: sprintf (pcftry, "%s%d", fname, pcfnum++); ! 4662: ! 4663: pcf = open (pcftry, O_RDONLY, 0666); ! 4664: if (pcf != -1) ! 4665: { ! 4666: struct stat s; ! 4667: ! 4668: fstat (pcf, &s); ! 4669: if (bcmp ((char *) &stat_f.st_ino, (char *) &s.st_ino, ! 4670: sizeof (s.st_ino)) ! 4671: || stat_f.st_dev != s.st_dev) ! 4672: { ! 4673: pcfbuf = check_precompiled (pcf, fname, &pcfbuflimit); ! 4674: /* Don't need it any more. */ ! 4675: close (pcf); ! 4676: } ! 4677: else ! 4678: { ! 4679: /* Don't need it at all. */ ! 4680: close (pcf); ! 4681: break; ! 4682: } ! 4683: } ! 4684: } while (pcf != -1 && !pcfbuf); ! 4685: } 1.1 root 4686: 4687: /* Actually process the file */ 4688: if (pcfbuf) { 4689: pcfname = xmalloc (strlen (pcftry) + 1); 4690: strcpy (pcfname, pcftry); 1.1.1.8 ! root 4691: pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) pcfbuflimit, ! 4692: (U_CHAR *) fname, op); 1.1 root 4693: } 4694: else 1.1.1.4 root 4695: finclude (f, fname, op, is_system_include (fname), searchptr); 1.1 root 4696: 1.1.1.4 root 4697: if (angle_brackets) 1.1 root 4698: system_include_depth--; 4699: } 4700: return 0; 4701: } 4702: 1.1.1.2 root 4703: /* Return nonzero if there is no need to include file NAME 4704: because it has already been included and it contains a conditional 4705: to make a repeated include do nothing. */ 4706: 4707: static int 1.1.1.4 root 4708: redundant_include_p (name) 1.1.1.2 root 4709: char *name; 4710: { 4711: struct file_name_list *l = all_include_files; 4712: for (; l; l = l->next) 4713: if (! strcmp (name, l->fname) 4714: && l->control_macro 4715: && lookup (l->control_macro, -1, -1)) 4716: return 1; 4717: return 0; 4718: } 4719: 1.1.1.4 root 4720: /* Return nonzero if the given FILENAME is an absolute pathname which 4721: designates a file within one of the known "system" include file 4722: directories. We assume here that if the given FILENAME looks like 4723: it is the name of a file which resides either directly in a "system" 4724: include file directory, or within any subdirectory thereof, then the 4725: given file must be a "system" include file. This function tells us 1.1.1.6 root 4726: if we should suppress pedantic errors/warnings for the given FILENAME. 4727: 4728: The value is 2 if the file is a C-language system header file 4729: for which C++ should (on most systems) assume `extern "C"'. */ 1.1.1.4 root 4730: 4731: static int 4732: is_system_include (filename) 4733: register char *filename; 4734: { 4735: struct file_name_list *searchptr; 4736: 4737: for (searchptr = first_system_include; searchptr; 4738: searchptr = searchptr->next) 4739: if (searchptr->fname) { 1.1.1.8 ! root 4740: register char *sys_dir = skip_redundant_dir_prefix (searchptr->fname); 1.1.1.4 root 4741: register unsigned length = strlen (sys_dir); 4742: 1.1.1.8 ! root 4743: if (! strncmp (sys_dir, filename, length) ! 4744: && (filename[length] == '/' ! 4745: #ifdef DIR_SEPARATOR ! 4746: || filename[length] == DIR_SEPARATOR ! 4747: #endif ! 4748: )) { ! 4749: if (searchptr->c_system_include_path) ! 4750: return 2; ! 4751: else ! 4752: return 1; ! 4753: } 1.1.1.4 root 4754: } 4755: return 0; 4756: } 4757: 1.1.1.8 ! root 4758: /* Skip leading "./" from a directory name. ! 4759: This may yield the empty string, which represents the current directory. */ ! 4760: ! 4761: static char * ! 4762: skip_redundant_dir_prefix (dir) ! 4763: char *dir; ! 4764: { ! 4765: while (dir[0] == '.' && dir[1] == '/') ! 4766: for (dir += 2; *dir == '/'; dir++) ! 4767: continue; ! 4768: if (dir[0] == '.' && !dir[1]) ! 4769: dir++; ! 4770: return dir; ! 4771: } ! 4772: 1.1.1.7 root 4773: /* The file_name_map structure holds a mapping of file names for a 4774: particular directory. This mapping is read from the file named 4775: FILE_NAME_MAP_FILE in that directory. Such a file can be used to 4776: map filenames on a file system with severe filename restrictions, 4777: such as DOS. The format of the file name map file is just a series 4778: of lines with two tokens on each line. The first token is the name 4779: to map, and the second token is the actual name to use. */ 4780: 4781: struct file_name_map 4782: { 4783: struct file_name_map *map_next; 4784: char *map_from; 4785: char *map_to; 4786: }; 4787: 4788: #define FILE_NAME_MAP_FILE "header.gcc" 4789: 4790: /* Read a space delimited string of unlimited length from a stdio 4791: file. */ 4792: 4793: static char * 4794: read_filename_string (ch, f) 4795: int ch; 4796: FILE *f; 4797: { 4798: char *alloc, *set; 4799: int len; 4800: 4801: len = 20; 4802: set = alloc = xmalloc (len + 1); 4803: if (! is_space[ch]) 4804: { 4805: *set++ = ch; 4806: while ((ch = getc (f)) != EOF && ! is_space[ch]) 4807: { 4808: if (set - alloc == len) 4809: { 4810: len *= 2; 4811: alloc = xrealloc (alloc, len + 1); 4812: set = alloc + len / 2; 4813: } 4814: *set++ = ch; 4815: } 4816: } 4817: *set = '\0'; 4818: ungetc (ch, f); 4819: return alloc; 4820: } 4821: 4822: /* Read the file name map file for DIRNAME. */ 4823: 4824: static struct file_name_map * 4825: read_name_map (dirname) 4826: char *dirname; 4827: { 4828: /* This structure holds a linked list of file name maps, one per 4829: directory. */ 4830: struct file_name_map_list 4831: { 4832: struct file_name_map_list *map_list_next; 4833: char *map_list_name; 4834: struct file_name_map *map_list_map; 4835: }; 4836: static struct file_name_map_list *map_list; 4837: register struct file_name_map_list *map_list_ptr; 4838: char *name; 4839: FILE *f; 1.1.1.8 ! root 4840: size_t dirlen; ! 4841: int separator_needed; ! 4842: ! 4843: dirname = skip_redundant_dir_prefix (dirname); 1.1.1.7 root 4844: 4845: for (map_list_ptr = map_list; map_list_ptr; 4846: map_list_ptr = map_list_ptr->map_list_next) 4847: if (! strcmp (map_list_ptr->map_list_name, dirname)) 4848: return map_list_ptr->map_list_map; 4849: 4850: map_list_ptr = ((struct file_name_map_list *) 4851: xmalloc (sizeof (struct file_name_map_list))); 4852: map_list_ptr->map_list_name = savestring (dirname); 4853: map_list_ptr->map_list_map = NULL; 4854: 1.1.1.8 ! root 4855: dirlen = strlen (dirname); ! 4856: separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/'; ! 4857: name = (char *) alloca (dirlen + strlen (FILE_NAME_MAP_FILE) + 2); 1.1.1.7 root 4858: strcpy (name, dirname); 1.1.1.8 ! root 4859: name[dirlen] = '/'; ! 4860: strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE); 1.1.1.7 root 4861: f = fopen (name, "r"); 4862: if (!f) 4863: map_list_ptr->map_list_map = NULL; 4864: else 4865: { 4866: int ch; 4867: 4868: while ((ch = getc (f)) != EOF) 4869: { 4870: char *from, *to; 4871: struct file_name_map *ptr; 4872: 4873: if (is_space[ch]) 4874: continue; 4875: from = read_filename_string (ch, f); 4876: while ((ch = getc (f)) != EOF && is_hor_space[ch]) 4877: ; 4878: to = read_filename_string (ch, f); 4879: 4880: ptr = ((struct file_name_map *) 4881: xmalloc (sizeof (struct file_name_map))); 4882: ptr->map_from = from; 4883: 4884: /* Make the real filename absolute. */ 4885: if (*to == '/') 4886: ptr->map_to = to; 4887: else 4888: { 4889: ptr->map_to = xmalloc (dirlen + strlen (to) + 2); 4890: strcpy (ptr->map_to, dirname); 4891: ptr->map_to[dirlen] = '/'; 1.1.1.8 ! root 4892: strcpy (ptr->map_to + dirlen + separator_needed, to); 1.1.1.7 root 4893: free (to); 4894: } 4895: 4896: ptr->map_next = map_list_ptr->map_list_map; 4897: map_list_ptr->map_list_map = ptr; 4898: 4899: while ((ch = getc (f)) != '\n') 4900: if (ch == EOF) 4901: break; 4902: } 4903: fclose (f); 4904: } 4905: 4906: map_list_ptr->map_list_next = map_list; 4907: map_list = map_list_ptr; 4908: 4909: return map_list_ptr->map_list_map; 4910: } 4911: 4912: /* Try to open include file FILENAME. SEARCHPTR is the directory 4913: being tried from the include file search path. This function maps 4914: filenames on file systems based on information read by 4915: read_name_map. */ 4916: 4917: static int 4918: open_include_file (filename, searchptr) 4919: char *filename; 4920: struct file_name_list *searchptr; 4921: { 4922: register struct file_name_map *map; 4923: register char *from; 4924: char *p, *dir; 4925: 4926: if (searchptr && ! searchptr->got_name_map) 4927: { 4928: searchptr->name_map = read_name_map (searchptr->fname 4929: ? searchptr->fname : "."); 4930: searchptr->got_name_map = 1; 4931: } 4932: 4933: /* First check the mapping for the directory we are using. */ 4934: if (searchptr && searchptr->name_map) 4935: { 4936: from = filename; 4937: if (searchptr->fname) 4938: from += strlen (searchptr->fname) + 1; 4939: for (map = searchptr->name_map; map; map = map->map_next) 4940: { 4941: if (! strcmp (map->map_from, from)) 4942: { 4943: /* Found a match. */ 4944: return open (map->map_to, O_RDONLY, 0666); 4945: } 4946: } 4947: } 4948: 4949: /* Try to find a mapping file for the particular directory we are 4950: looking in. Thus #include <sys/types.h> will look up sys/types.h 4951: in /usr/include/header.gcc and look up types.h in 4952: /usr/include/sys/header.gcc. */ 4953: p = rindex (filename, '/'); 1.1.1.8 ! root 4954: #ifdef DIR_SEPARATOR ! 4955: if (! p) p = rindex (filename, DIR_SEPARATOR); ! 4956: else { ! 4957: char *tmp = rindex (filename, DIR_SEPARATOR); ! 4958: if (tmp != NULL && tmp > p) p = tmp; ! 4959: } ! 4960: #endif 1.1.1.7 root 4961: if (! p) 4962: p = filename; 4963: if (searchptr 4964: && searchptr->fname 4965: && strlen (searchptr->fname) == p - filename 4966: && ! strncmp (searchptr->fname, filename, p - filename)) 4967: { 4968: /* FILENAME is in SEARCHPTR, which we've already checked. */ 4969: return open (filename, O_RDONLY, 0666); 4970: } 4971: 4972: if (p == filename) 4973: { 4974: dir = "."; 4975: from = filename; 4976: } 4977: else 4978: { 4979: dir = (char *) alloca (p - filename + 1); 4980: bcopy (filename, dir, p - filename); 4981: dir[p - filename] = '\0'; 4982: from = p + 1; 4983: } 4984: for (map = read_name_map (dir); map; map = map->map_next) 4985: if (! strcmp (map->map_from, from)) 4986: return open (map->map_to, O_RDONLY, 0666); 4987: 4988: return open (filename, O_RDONLY, 0666); 4989: } 4990: 1.1 root 4991: /* Process the contents of include file FNAME, already open on descriptor F, 4992: with output to OP. 1.1.1.5 root 4993: SYSTEM_HEADER_P is 1 if this file resides in any one of the known 4994: "system" include directories (as decided by the `is_system_include' 4995: function above). 1.1 root 4996: DIRPTR is the link in the dir path through which this file was found, 4997: or 0 if the file name was absolute. */ 4998: 4999: static void 5000: finclude (f, fname, op, system_header_p, dirptr) 5001: int f; 5002: char *fname; 5003: FILE_BUF *op; 5004: int system_header_p; 5005: struct file_name_list *dirptr; 5006: { 5007: int st_mode; 5008: long st_size; 5009: long i; 5010: FILE_BUF *fp; /* For input stack frame */ 5011: int missing_newline = 0; 5012: 5013: CHECK_DEPTH (return;); 5014: 5015: if (file_size_and_mode (f, &st_mode, &st_size) < 0) 1.1.1.4 root 5016: { 5017: perror_with_name (fname); 5018: close (f); 5019: return; 5020: } 1.1 root 5021: 5022: fp = &instack[indepth + 1]; 1.1.1.7 root 5023: bzero ((char *) fp, sizeof (FILE_BUF)); 1.1 root 5024: fp->nominal_fname = fp->fname = fname; 5025: fp->length = 0; 5026: fp->lineno = 1; 5027: fp->if_stack = if_stack; 5028: fp->system_header_p = system_header_p; 5029: fp->dir = dirptr; 5030: 5031: if (S_ISREG (st_mode)) { 1.1.1.3 root 5032: fp->buf = (U_CHAR *) xmalloc (st_size + 2); 1.1 root 5033: fp->bufp = fp->buf; 5034: 5035: /* Read the file contents, knowing that st_size is an upper bound 5036: on the number of bytes we can read. */ 1.1.1.8 ! root 5037: fp->length = safe_read (f, (char *) fp->buf, st_size); 1.1.1.7 root 5038: if (fp->length < 0) goto nope; 1.1 root 5039: } 1.1.1.5 root 5040: else if (S_ISDIR (st_mode)) { 5041: error ("directory `%s' specified in #include", fname); 5042: close (f); 5043: return; 5044: } else { 1.1 root 5045: /* Cannot count its file size before reading. 5046: First read the entire file into heap and 5047: copy them into buffer on stack. */ 5048: 5049: int bsize = 2000; 5050: 5051: st_size = 0; 1.1.1.7 root 5052: fp->buf = (U_CHAR *) xmalloc (bsize + 2); 1.1 root 5053: 5054: for (;;) { 1.1.1.8 ! root 5055: i = safe_read (f, (char *) fp->buf + st_size, bsize - st_size); 1.1 root 5056: if (i < 0) 5057: goto nope; /* error! */ 5058: st_size += i; 1.1.1.7 root 5059: if (st_size != bsize) 5060: break; /* End of file */ 5061: bsize *= 2; 5062: fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2); 1.1 root 5063: } 5064: fp->bufp = fp->buf; 5065: fp->length = st_size; 5066: } 5067: 1.1.1.5 root 5068: if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n') 5069: /* Backslash-newline at end is not good enough. */ 5070: || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) { 5071: fp->buf[fp->length++] = '\n'; 5072: missing_newline = 1; 5073: } 5074: fp->buf[fp->length] = '\0'; 5075: 1.1 root 5076: /* Close descriptor now, so nesting does not use lots of descriptors. */ 5077: close (f); 5078: 1.1.1.4 root 5079: /* Must do this before calling trigraph_pcp, so that the correct file name 5080: will be printed in warning messages. */ 5081: 5082: indepth++; 5083: input_file_stack_tick++; 5084: 1.1 root 5085: if (!no_trigraphs) 5086: trigraph_pcp (fp); 5087: 1.1.1.8 ! root 5088: output_line_directive (fp, op, 0, enter_file); 1.1 root 5089: rescan (op, 0); 5090: 1.1.1.5 root 5091: if (missing_newline) 5092: fp->lineno--; 5093: 1.1 root 5094: if (pedantic && missing_newline) 5095: pedwarn ("file does not end in newline"); 5096: 5097: indepth--; 5098: input_file_stack_tick++; 1.1.1.8 ! root 5099: output_line_directive (&instack[indepth], op, 0, leave_file); 1.1.1.3 root 5100: free (fp->buf); 1.1 root 5101: return; 5102: 5103: nope: 5104: 5105: perror_with_name (fname); 5106: close (f); 1.1.1.3 root 5107: free (fp->buf); 1.1 root 5108: } 5109: 5110: /* Record that inclusion of the file named FILE 5111: should be controlled by the macro named MACRO_NAME. 5112: This means that trying to include the file again 5113: will do something if that macro is defined. */ 5114: 5115: static void 5116: record_control_macro (file, macro_name) 5117: char *file; 5118: U_CHAR *macro_name; 5119: { 5120: struct file_name_list *new; 5121: 5122: for (new = all_include_files; new; new = new->next) { 5123: if (!strcmp (new->fname, file)) { 5124: new->control_macro = macro_name; 5125: return; 5126: } 5127: } 5128: 5129: /* If the file is not in all_include_files, something's wrong. */ 5130: abort (); 5131: } 5132: 5133: /* Maintain and search list of included files, for #import. */ 5134: 5135: #define IMPORT_HASH_SIZE 31 5136: 5137: struct import_file { 5138: char *name; 5139: ino_t inode; 5140: dev_t dev; 5141: struct import_file *next; 5142: }; 5143: 5144: /* Hash table of files already included with #include or #import. */ 5145: 5146: static struct import_file *import_hash_table[IMPORT_HASH_SIZE]; 5147: 5148: /* Hash a file name for import_hash_table. */ 5149: 5150: static int 5151: import_hash (f) 5152: char *f; 5153: { 5154: int val = 0; 5155: 5156: while (*f) val += *f++; 5157: return (val%IMPORT_HASH_SIZE); 5158: } 5159: 5160: /* Search for file FILENAME in import_hash_table. 5161: Return -2 if found, either a matching name or a matching inode. 5162: Otherwise, open the file and return a file descriptor if successful 5163: or -1 if unsuccessful. */ 5164: 5165: static int 1.1.1.7 root 5166: lookup_import (filename, searchptr) 1.1 root 5167: char *filename; 1.1.1.7 root 5168: struct file_name_list *searchptr; 1.1 root 5169: { 5170: struct import_file *i; 5171: int h; 5172: int hashval; 5173: struct stat sb; 5174: int fd; 5175: 5176: hashval = import_hash (filename); 5177: 5178: /* Attempt to find file in list of already included files */ 5179: i = import_hash_table[hashval]; 5180: 5181: while (i) { 5182: if (!strcmp (filename, i->name)) 5183: return -2; /* return found */ 5184: i = i->next; 5185: } 5186: /* Open it and try a match on inode/dev */ 1.1.1.7 root 5187: fd = open_include_file (filename, searchptr); 1.1 root 5188: if (fd < 0) 5189: return fd; 5190: fstat (fd, &sb); 5191: for (h = 0; h < IMPORT_HASH_SIZE; h++) { 5192: i = import_hash_table[h]; 5193: while (i) { 5194: /* Compare the inode and the device. 5195: Supposedly on some systems the inode is not a scalar. */ 1.1.1.7 root 5196: if (!bcmp ((char *) &i->inode, (char *) &sb.st_ino, sizeof (sb.st_ino)) 1.1 root 5197: && i->dev == sb.st_dev) { 5198: close (fd); 5199: return -2; /* return found */ 5200: } 5201: i = i->next; 5202: } 5203: } 5204: return fd; /* Not found, return open file */ 5205: } 5206: 5207: /* Add the file FNAME, open on descriptor FD, to import_hash_table. */ 5208: 5209: static void 5210: add_import (fd, fname) 5211: int fd; 5212: char *fname; 5213: { 5214: struct import_file *i; 5215: int hashval; 5216: struct stat sb; 5217: 5218: hashval = import_hash (fname); 5219: fstat (fd, &sb); 5220: i = (struct import_file *)xmalloc (sizeof (struct import_file)); 1.1.1.8 ! root 5221: i->name = xmalloc (strlen (fname)+1); 1.1 root 5222: strcpy (i->name, fname); 1.1.1.7 root 5223: bcopy ((char *) &sb.st_ino, (char *) &i->inode, sizeof (sb.st_ino)); 1.1 root 5224: i->dev = sb.st_dev; 5225: i->next = import_hash_table[hashval]; 5226: import_hash_table[hashval] = i; 5227: } 5228: 5229: /* Load the specified precompiled header into core, and verify its 5230: preconditions. PCF indicates the file descriptor to read, which must 5231: be a regular file. FNAME indicates the file name of the original 5232: header. *LIMIT will be set to an address one past the end of the file. 5233: If the preconditions of the file are not satisfied, the buffer is 5234: freed and we return 0. If the preconditions are satisfied, return 5235: the address of the buffer following the preconditions. The buffer, in 5236: this case, should never be freed because various pieces of it will 5237: be referred to until all precompiled strings are output at the end of 5238: the run. 5239: */ 5240: static char * 5241: check_precompiled (pcf, fname, limit) 5242: int pcf; 5243: char *fname; 5244: char **limit; 5245: { 5246: int st_mode; 5247: long st_size; 5248: int length = 0; 5249: char *buf; 5250: char *cp; 5251: 5252: if (pcp_outfile) 5253: return 0; 5254: 5255: if (file_size_and_mode (pcf, &st_mode, &st_size) < 0) 5256: return 0; 5257: 5258: if (S_ISREG (st_mode)) 5259: { 5260: buf = xmalloc (st_size + 2); 1.1.1.7 root 5261: length = safe_read (pcf, buf, st_size); 5262: if (length < 0) 5263: goto nope; 1.1 root 5264: } 5265: else 5266: abort (); 5267: 5268: if (length > 0 && buf[length-1] != '\n') 5269: buf[length++] = '\n'; 5270: buf[length] = '\0'; 5271: 5272: *limit = buf + length; 5273: 5274: /* File is in core. Check the preconditions. */ 5275: if (!check_preconditions (buf)) 5276: goto nope; 5277: for (cp = buf; *cp; cp++) 5278: ; 5279: #ifdef DEBUG_PCP 5280: fprintf (stderr, "Using preinclude %s\n", fname); 5281: #endif 5282: return cp + 1; 5283: 5284: nope: 5285: #ifdef DEBUG_PCP 5286: fprintf (stderr, "Cannot use preinclude %s\n", fname); 5287: #endif 5288: free (buf); 5289: return 0; 5290: } 5291: 5292: /* PREC (null terminated) points to the preconditions of a 5293: precompiled header. These are a series of #define and #undef 5294: lines which must match the current contents of the hash 5295: table. */ 5296: static int 5297: check_preconditions (prec) 5298: char *prec; 5299: { 5300: MACRODEF mdef; 5301: char *lineend; 5302: 5303: while (*prec) { 1.1.1.8 ! root 5304: lineend = index (prec, '\n'); 1.1 root 5305: 5306: if (*prec++ != '#') { 5307: error ("Bad format encountered while reading precompiled file"); 5308: return 0; 5309: } 5310: if (!strncmp (prec, "define", 6)) { 5311: HASHNODE *hp; 5312: 5313: prec += 6; 1.1.1.8 ! root 5314: mdef = create_definition ((U_CHAR *) prec, (U_CHAR *) lineend, NULL_PTR); 1.1.1.4 root 5315: 1.1 root 5316: if (mdef.defn == 0) 1.1.1.5 root 5317: abort (); 1.1 root 5318: 5319: if ((hp = lookup (mdef.symnam, mdef.symlen, -1)) == NULL 5320: || (hp->type != T_MACRO && hp->type != T_CONST) 5321: || (hp->type == T_MACRO 5322: && !compare_defs (mdef.defn, hp->value.defn) 5323: && (mdef.defn->length != 2 5324: || mdef.defn->expansion[0] != '\n' 5325: || mdef.defn->expansion[1] != ' '))) 5326: return 0; 5327: } else if (!strncmp (prec, "undef", 5)) { 5328: char *name; 5329: int len; 5330: 5331: prec += 5; 1.1.1.5 root 5332: while (is_hor_space[(U_CHAR) *prec]) 1.1 root 5333: prec++; 5334: name = prec; 1.1.1.5 root 5335: while (is_idchar[(U_CHAR) *prec]) 1.1 root 5336: prec++; 5337: len = prec - name; 5338: 1.1.1.8 ! root 5339: if (lookup ((U_CHAR *) name, len, -1)) 1.1 root 5340: return 0; 5341: } else { 5342: error ("Bad format encountered while reading precompiled file"); 5343: return 0; 5344: } 5345: prec = lineend + 1; 5346: } 5347: /* They all passed successfully */ 5348: return 1; 5349: } 5350: 5351: /* Process the main body of a precompiled file. BUF points to the 5352: string section of the file, following the preconditions. LIMIT is one 5353: character past the end. NAME is the name of the file being read 5354: in. OP is the main output buffer */ 5355: static void 5356: pcfinclude (buf, limit, name, op) 5357: U_CHAR *buf, *limit, *name; 5358: FILE_BUF *op; 5359: { 5360: FILE_BUF tmpbuf; 5361: int nstrings; 5362: U_CHAR *cp = buf; 5363: 5364: /* First in the file comes 4 bytes indicating the number of strings, */ 5365: /* in network byte order. (MSB first). */ 5366: nstrings = *cp++; 5367: nstrings = (nstrings << 8) | *cp++; 5368: nstrings = (nstrings << 8) | *cp++; 5369: nstrings = (nstrings << 8) | *cp++; 5370: 5371: /* Looping over each string... */ 5372: while (nstrings--) { 5373: U_CHAR *string_start; 5374: U_CHAR *endofthiskey; 5375: STRINGDEF *str; 5376: int nkeys; 5377: 5378: /* Each string starts with a STRINGDEF structure (str), followed */ 5379: /* by the text of the string (string_start) */ 5380: 5381: /* First skip to a longword boundary */ 1.1.1.4 root 5382: /* ??? Why a 4-byte boundary? On all machines? */ 5383: /* NOTE: This works correctly even if HOST_WIDE_INT 5384: is narrower than a pointer. 5385: Do not try risky measures here to get another type to use! 1.1.1.7 root 5386: Do not include stddef.h--it will fail! */ 1.1.1.4 root 5387: if ((HOST_WIDE_INT) cp & 3) 5388: cp += 4 - ((HOST_WIDE_INT) cp & 3); 1.1 root 5389: 5390: /* Now get the string. */ 1.1.1.8 ! root 5391: str = (STRINGDEF *) (GENERIC_PTR) cp; 1.1 root 5392: string_start = cp += sizeof (STRINGDEF); 5393: 5394: for (; *cp; cp++) /* skip the string */ 5395: ; 5396: 5397: /* We need to macro expand the string here to ensure that the 5398: proper definition environment is in place. If it were only 5399: expanded when we find out it is needed, macros necessary for 5400: its proper expansion might have had their definitions changed. */ 5401: tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0); 5402: /* Lineno is already set in the precompiled file */ 5403: str->contents = tmpbuf.buf; 5404: str->len = tmpbuf.length; 5405: str->writeflag = 0; 5406: str->filename = name; 5407: str->output_mark = outbuf.bufp - outbuf.buf; 5408: 5409: str->chain = 0; 5410: *stringlist_tailp = str; 5411: stringlist_tailp = &str->chain; 5412: 5413: /* Next comes a fourbyte number indicating the number of keys */ 5414: /* for this string. */ 5415: nkeys = *cp++; 5416: nkeys = (nkeys << 8) | *cp++; 5417: nkeys = (nkeys << 8) | *cp++; 5418: nkeys = (nkeys << 8) | *cp++; 5419: 5420: /* If this number is -1, then the string is mandatory. */ 5421: if (nkeys == -1) 5422: str->writeflag = 1; 5423: else 1.1.1.2 root 5424: /* Otherwise, for each key, */ 1.1 root 5425: for (; nkeys--; free (tmpbuf.buf), cp = endofthiskey + 1) { 1.1.1.8 ! root 5426: KEYDEF *kp = (KEYDEF *) (GENERIC_PTR) cp; 1.1 root 5427: HASHNODE *hp; 5428: 5429: /* It starts with a KEYDEF structure */ 5430: cp += sizeof (KEYDEF); 5431: 5432: /* Find the end of the key. At the end of this for loop we 5433: advance CP to the start of the next key using this variable. */ 1.1.1.8 ! root 5434: endofthiskey = cp + strlen ((char *) cp); 1.1 root 5435: kp->str = str; 5436: 5437: /* Expand the key, and enter it into the hash table. */ 5438: tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0); 5439: tmpbuf.bufp = tmpbuf.buf; 5440: 5441: while (is_hor_space[*tmpbuf.bufp]) 5442: tmpbuf.bufp++; 5443: if (!is_idstart[*tmpbuf.bufp] 5444: || tmpbuf.bufp == tmpbuf.buf + tmpbuf.length) { 5445: str->writeflag = 1; 5446: continue; 5447: } 5448: 5449: hp = lookup (tmpbuf.bufp, -1, -1); 5450: if (hp == NULL) { 5451: kp->chain = 0; 1.1.1.8 ! root 5452: install (tmpbuf.bufp, -1, T_PCSTRING, (char *) kp, -1); 1.1 root 5453: } 5454: else if (hp->type == T_PCSTRING) { 5455: kp->chain = hp->value.keydef; 5456: hp->value.keydef = kp; 5457: } 5458: else 5459: str->writeflag = 1; 5460: } 5461: } 1.1.1.8 ! root 5462: /* This output_line_directive serves to switch us back to the current 1.1 root 5463: input file in case some of these strings get output (which will 1.1.1.8 ! root 5464: result in line directives for the header file being output). */ ! 5465: output_line_directive (&instack[indepth], op, 0, enter_file); 1.1 root 5466: } 5467: 5468: /* Called from rescan when it hits a key for strings. Mark them all */ 5469: /* used and clean up. */ 5470: static void 5471: pcstring_used (hp) 5472: HASHNODE *hp; 5473: { 1.1.1.7 root 5474: KEYDEF *kp; 1.1 root 5475: 5476: for (kp = hp->value.keydef; kp; kp = kp->chain) 5477: kp->str->writeflag = 1; 5478: delete_macro (hp); 5479: } 5480: 5481: /* Write the output, interspersing precompiled strings in their */ 5482: /* appropriate places. */ 5483: static void 5484: write_output () 5485: { 5486: STRINGDEF *next_string; 5487: U_CHAR *cur_buf_loc; 1.1.1.8 ! root 5488: int line_directive_len = 80; ! 5489: char *line_directive = xmalloc (line_directive_len); 1.1 root 5490: int len; 5491: 5492: /* In each run through the loop, either cur_buf_loc == */ 5493: /* next_string_loc, in which case we print a series of strings, or */ 5494: /* it is less than next_string_loc, in which case we write some of */ 5495: /* the buffer. */ 5496: cur_buf_loc = outbuf.buf; 5497: next_string = stringlist; 5498: 5499: while (cur_buf_loc < outbuf.bufp || next_string) { 5500: if (next_string 5501: && cur_buf_loc - outbuf.buf == next_string->output_mark) { 5502: if (next_string->writeflag) { 1.1.1.8 ! root 5503: len = 4 * strlen ((char *) next_string->filename) + 32; ! 5504: while (len > line_directive_len) ! 5505: line_directive = xrealloc (line_directive, ! 5506: line_directive_len *= 2); ! 5507: sprintf (line_directive, "\n# %d ", next_string->lineno); ! 5508: strcpy (quote_string (line_directive + strlen (line_directive), ! 5509: (char *) next_string->filename), 1.1.1.6 root 5510: "\n"); 1.1.1.8 ! root 5511: safe_write (fileno (stdout), line_directive, strlen (line_directive)); ! 5512: safe_write (fileno (stdout), ! 5513: (char *) next_string->contents, next_string->len); 1.1 root 5514: } 5515: next_string = next_string->chain; 5516: } 5517: else { 5518: len = (next_string 5519: ? (next_string->output_mark 5520: - (cur_buf_loc - outbuf.buf)) 5521: : outbuf.bufp - cur_buf_loc); 5522: 1.1.1.8 ! root 5523: safe_write (fileno (stdout), (char *) cur_buf_loc, len); 1.1 root 5524: cur_buf_loc += len; 5525: } 5526: } 1.1.1.8 ! root 5527: free (line_directive); 1.1 root 5528: } 5529: 5530: /* Pass a directive through to the output file. 1.1.1.2 root 5531: BUF points to the contents of the directive, as a contiguous string. 1.1 root 5532: LIMIT points to the first character past the end of the directive. 5533: KEYWORD is the keyword-table entry for the directive. */ 5534: 5535: static void 5536: pass_thru_directive (buf, limit, op, keyword) 5537: U_CHAR *buf, *limit; 5538: FILE_BUF *op; 5539: struct directive *keyword; 5540: { 5541: register unsigned keyword_length = keyword->length; 5542: 5543: check_expand (op, 1 + keyword_length + (limit - buf)); 5544: *op->bufp++ = '#'; 1.1.1.7 root 5545: bcopy (keyword->name, (char *) op->bufp, keyword_length); 1.1 root 5546: op->bufp += keyword_length; 5547: if (limit != buf && buf[0] != ' ') 5548: *op->bufp++ = ' '; 1.1.1.7 root 5549: bcopy ((char *) buf, (char *) op->bufp, limit - buf); 1.1 root 5550: op->bufp += (limit - buf); 1.1.1.3 root 5551: #if 0 1.1 root 5552: *op->bufp++ = '\n'; 1.1.1.3 root 5553: /* Count the line we have just made in the output, 5554: to get in sync properly. */ 5555: op->lineno++; 5556: #endif 1.1 root 5557: } 5558: 5559: /* The arglist structure is built by do_define to tell 5560: collect_definition where the argument names begin. That 5561: is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist 5562: would contain pointers to the strings x, y, and z. 5563: Collect_definition would then build a DEFINITION node, 5564: with reflist nodes pointing to the places x, y, and z had 5565: appeared. So the arglist is just convenience data passed 5566: between these two routines. It is not kept around after 5567: the current #define has been processed and entered into the 5568: hash table. */ 5569: 5570: struct arglist { 5571: struct arglist *next; 5572: U_CHAR *name; 5573: int length; 5574: int argno; 1.1.1.3 root 5575: char rest_args; 1.1 root 5576: }; 5577: 5578: /* Create a DEFINITION node from a #define directive. Arguments are 5579: as for do_define. */ 5580: static MACRODEF 5581: create_definition (buf, limit, op) 5582: U_CHAR *buf, *limit; 5583: FILE_BUF *op; 5584: { 5585: U_CHAR *bp; /* temp ptr into input buffer */ 5586: U_CHAR *symname; /* remember where symbol name starts */ 5587: int sym_length; /* and how long it is */ 5588: int line = instack[indepth].lineno; 5589: char *file = instack[indepth].nominal_fname; 1.1.1.3 root 5590: int rest_args = 0; 1.1 root 5591: 5592: DEFINITION *defn; 5593: int arglengths = 0; /* Accumulate lengths of arg names 5594: plus number of args. */ 5595: MACRODEF mdef; 5596: 5597: bp = buf; 5598: 5599: while (is_hor_space[*bp]) 5600: bp++; 5601: 5602: symname = bp; /* remember where it starts */ 5603: sym_length = check_macro_name (bp, "macro"); 5604: bp += sym_length; 5605: 5606: /* Lossage will occur if identifiers or control keywords are broken 5607: across lines using backslash. This is not the right place to take 5608: care of that. */ 5609: 5610: if (*bp == '(') { 5611: struct arglist *arg_ptrs = NULL; 5612: int argno = 0; 5613: 5614: bp++; /* skip '(' */ 5615: SKIP_WHITE_SPACE (bp); 5616: 5617: /* Loop over macro argument names. */ 5618: while (*bp != ')') { 5619: struct arglist *temp; 5620: 5621: temp = (struct arglist *) alloca (sizeof (struct arglist)); 5622: temp->name = bp; 5623: temp->next = arg_ptrs; 5624: temp->argno = argno++; 1.1.1.3 root 5625: temp->rest_args = 0; 1.1 root 5626: arg_ptrs = temp; 5627: 1.1.1.3 root 5628: if (rest_args) 5629: pedwarn ("another parameter follows `%s'", 5630: rest_extension); 1.1 root 5631: 1.1.1.3 root 5632: if (!is_idstart[*bp]) 5633: pedwarn ("invalid character in macro parameter name"); 5634: 1.1 root 5635: /* Find the end of the arg name. */ 5636: while (is_idchar[*bp]) { 5637: bp++; 1.1.1.3 root 5638: /* do we have a "special" rest-args extension here? */ 5639: if (limit - bp > REST_EXTENSION_LENGTH && 1.1.1.8 ! root 5640: bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) { 1.1.1.3 root 5641: rest_args = 1; 5642: temp->rest_args = 1; 5643: break; 5644: } 1.1 root 5645: } 5646: temp->length = bp - temp->name; 1.1.1.3 root 5647: if (rest_args == 1) 5648: bp += REST_EXTENSION_LENGTH; 1.1 root 5649: arglengths += temp->length + 2; 5650: SKIP_WHITE_SPACE (bp); 5651: if (temp->length == 0 || (*bp != ',' && *bp != ')')) { 5652: error ("badly punctuated parameter list in `#define'"); 5653: goto nope; 5654: } 5655: if (*bp == ',') { 5656: bp++; 5657: SKIP_WHITE_SPACE (bp); 1.1.1.8 ! root 5658: /* A comma at this point can only be followed by an identifier. */ ! 5659: if (!is_idstart[*bp]) { ! 5660: error ("badly punctuated parameter list in `#define'"); ! 5661: goto nope; ! 5662: } 1.1 root 5663: } 5664: if (bp >= limit) { 5665: error ("unterminated parameter list in `#define'"); 5666: goto nope; 5667: } 5668: { 5669: struct arglist *otemp; 5670: 5671: for (otemp = temp->next; otemp != NULL; otemp = otemp->next) 5672: if (temp->length == otemp->length && 1.1.1.8 ! root 5673: bcmp (temp->name, otemp->name, temp->length) == 0) { ! 5674: error ("duplicate argument name `%.*s' in `#define'", ! 5675: temp->length, temp->name); 1.1 root 5676: goto nope; 5677: } 5678: } 5679: } 5680: 5681: ++bp; /* skip paren */ 1.1.1.8 ! root 5682: SKIP_WHITE_SPACE (bp); 1.1 root 5683: /* now everything from bp before limit is the definition. */ 5684: defn = collect_expansion (bp, limit, argno, arg_ptrs); 1.1.1.3 root 5685: defn->rest_args = rest_args; 1.1 root 5686: 5687: /* Now set defn->args.argnames to the result of concatenating 5688: the argument names in reverse order 5689: with comma-space between them. */ 5690: defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1); 5691: { 5692: struct arglist *temp; 5693: int i = 0; 5694: for (temp = arg_ptrs; temp; temp = temp->next) { 5695: bcopy (temp->name, &defn->args.argnames[i], temp->length); 5696: i += temp->length; 5697: if (temp->next != 0) { 5698: defn->args.argnames[i++] = ','; 5699: defn->args.argnames[i++] = ' '; 5700: } 5701: } 5702: defn->args.argnames[i] = 0; 5703: } 5704: } else { 1.1.1.7 root 5705: /* Simple expansion or empty definition. */ 5706: 5707: if (bp < limit) 5708: { 1.1.1.8 ! root 5709: if (is_hor_space[*bp]) { ! 5710: bp++; ! 5711: SKIP_WHITE_SPACE (bp); ! 5712: } else { ! 5713: switch (*bp) { 1.1.1.7 root 5714: case '!': case '"': case '#': case '%': case '&': case '\'': 5715: case ')': case '*': case '+': case ',': case '-': case '.': 5716: case '/': case ':': case ';': case '<': case '=': case '>': 5717: case '?': case '[': case '\\': case ']': case '^': case '{': 5718: case '|': case '}': case '~': 5719: warning ("missing white space after `#define %.*s'", 5720: sym_length, symname); 5721: break; 5722: 5723: default: 5724: pedwarn ("missing white space after `#define %.*s'", 5725: sym_length, symname); 5726: break; 5727: } 1.1.1.8 ! root 5728: } 1.1.1.7 root 5729: } 5730: /* Now everything from bp before limit is the definition. */ 1.1.1.4 root 5731: defn = collect_expansion (bp, limit, -1, NULL_PTR); 1.1 root 5732: defn->args.argnames = (U_CHAR *) ""; 5733: } 5734: 5735: defn->line = line; 5736: defn->file = file; 5737: 5738: /* OP is null if this is a predefinition */ 5739: defn->predefined = !op; 5740: mdef.defn = defn; 5741: mdef.symnam = symname; 5742: mdef.symlen = sym_length; 5743: 5744: return mdef; 5745: 5746: nope: 5747: mdef.defn = 0; 5748: return mdef; 5749: } 5750: 1.1.1.8 ! root 5751: /* Process a #define directive. ! 5752: BUF points to the contents of the #define directive, as a contiguous string. 1.1 root 5753: LIMIT points to the first character past the end of the definition. 5754: KEYWORD is the keyword-table entry for #define. */ 5755: 5756: static int 5757: do_define (buf, limit, op, keyword) 5758: U_CHAR *buf, *limit; 5759: FILE_BUF *op; 5760: struct directive *keyword; 5761: { 5762: int hashcode; 5763: MACRODEF mdef; 5764: 1.1.1.8 ! root 5765: /* If this is a precompiler run (with -pcp) pass thru #define directives. */ 1.1 root 5766: if (pcp_outfile && op) 5767: pass_thru_directive (buf, limit, op, keyword); 5768: 5769: mdef = create_definition (buf, limit, op); 5770: if (mdef.defn == 0) 5771: goto nope; 5772: 5773: hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE); 5774: 5775: { 5776: HASHNODE *hp; 5777: if ((hp = lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) { 5778: int ok = 0; 5779: /* Redefining a precompiled key is ok. */ 5780: if (hp->type == T_PCSTRING) 5781: ok = 1; 5782: /* Redefining a macro is ok if the definitions are the same. */ 5783: else if (hp->type == T_MACRO) 5784: ok = ! compare_defs (mdef.defn, hp->value.defn); 5785: /* Redefining a constant is ok with -D. */ 5786: else if (hp->type == T_CONST) 5787: ok = ! done_initializing; 5788: /* Print the warning if it's not ok. */ 5789: if (!ok) { 5790: /* If we are passing through #define and #undef directives, do 5791: that for this re-definition now. */ 5792: if (debug_output && op) 5793: pass_thru_directive (buf, limit, op, keyword); 5794: 1.1.1.8 ! root 5795: pedwarn ("`%.*s' redefined", mdef.symlen, mdef.symnam); 1.1 root 5796: if (hp->type == T_MACRO) 5797: pedwarn_with_file_and_line (hp->value.defn->file, hp->value.defn->line, 5798: "this is the location of the previous definition"); 5799: } 5800: /* Replace the old definition. */ 5801: hp->type = T_MACRO; 5802: hp->value.defn = mdef.defn; 5803: } else { 5804: /* If we are passing through #define and #undef directives, do 5805: that for this new definition now. */ 5806: if (debug_output && op) 5807: pass_thru_directive (buf, limit, op, keyword); 1.1.1.8 ! root 5808: install (mdef.symnam, mdef.symlen, T_MACRO, 1.1.1.4 root 5809: (char *) mdef.defn, hashcode); 1.1 root 5810: } 5811: } 5812: 5813: return 0; 5814: 5815: nope: 5816: 5817: return 1; 5818: } 5819: 5820: /* Check a purported macro name SYMNAME, and yield its length. 5821: USAGE is the kind of name this is intended for. */ 5822: 5823: static int 5824: check_macro_name (symname, usage) 5825: U_CHAR *symname; 5826: char *usage; 5827: { 5828: U_CHAR *p; 5829: int sym_length; 5830: 5831: for (p = symname; is_idchar[*p]; p++) 5832: ; 5833: sym_length = p - symname; 5834: if (sym_length == 0) 5835: error ("invalid %s name", usage); 1.1.1.8 ! root 5836: else if (!is_idstart[*symname] ! 5837: || (sym_length == 7 && ! bcmp (symname, "defined", 7))) ! 5838: error ("invalid %s name `%.*s'", usage, sym_length, symname); 1.1 root 5839: return sym_length; 5840: } 5841: 5842: /* 5843: * return zero if two DEFINITIONs are isomorphic 5844: */ 5845: static int 5846: compare_defs (d1, d2) 5847: DEFINITION *d1, *d2; 5848: { 5849: register struct reflist *a1, *a2; 5850: register U_CHAR *p1 = d1->expansion; 5851: register U_CHAR *p2 = d2->expansion; 5852: int first = 1; 5853: 5854: if (d1->nargs != d2->nargs) 5855: return 1; 5856: if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames)) 5857: return 1; 5858: for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2; 5859: a1 = a1->next, a2 = a2->next) { 1.1.1.8 ! root 5860: if (!((a1->nchars == a2->nchars && ! bcmp (p1, p2, a1->nchars)) 1.1 root 5861: || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0)) 5862: || a1->argno != a2->argno 5863: || a1->stringify != a2->stringify 5864: || a1->raw_before != a2->raw_before 5865: || a1->raw_after != a2->raw_after) 5866: return 1; 5867: first = 0; 5868: p1 += a1->nchars; 5869: p2 += a2->nchars; 5870: } 5871: if (a1 != a2) 5872: return 1; 5873: if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion), 5874: p2, d2->length - (p2 - d2->expansion), 1)) 5875: return 1; 5876: return 0; 5877: } 5878: 5879: /* Return 1 if two parts of two macro definitions are effectively different. 5880: One of the parts starts at BEG1 and has LEN1 chars; 5881: the other has LEN2 chars at BEG2. 5882: Any sequence of whitespace matches any other sequence of whitespace. 5883: FIRST means these parts are the first of a macro definition; 5884: so ignore leading whitespace entirely. 5885: LAST means these parts are the last of a macro definition; 5886: so ignore trailing whitespace entirely. */ 5887: 5888: static int 5889: comp_def_part (first, beg1, len1, beg2, len2, last) 5890: int first; 5891: U_CHAR *beg1, *beg2; 5892: int len1, len2; 5893: int last; 5894: { 5895: register U_CHAR *end1 = beg1 + len1; 5896: register U_CHAR *end2 = beg2 + len2; 5897: if (first) { 5898: while (beg1 != end1 && is_space[*beg1]) beg1++; 5899: while (beg2 != end2 && is_space[*beg2]) beg2++; 5900: } 5901: if (last) { 5902: while (beg1 != end1 && is_space[end1[-1]]) end1--; 5903: while (beg2 != end2 && is_space[end2[-1]]) end2--; 5904: } 5905: while (beg1 != end1 && beg2 != end2) { 5906: if (is_space[*beg1] && is_space[*beg2]) { 5907: while (beg1 != end1 && is_space[*beg1]) beg1++; 5908: while (beg2 != end2 && is_space[*beg2]) beg2++; 5909: } else if (*beg1 == *beg2) { 5910: beg1++; beg2++; 5911: } else break; 5912: } 5913: return (beg1 != end1) || (beg2 != end2); 5914: } 5915: 5916: /* Read a replacement list for a macro with parameters. 5917: Build the DEFINITION structure. 5918: Reads characters of text starting at BUF until END. 5919: ARGLIST specifies the formal parameters to look for 5920: in the text of the definition; NARGS is the number of args 5921: in that list, or -1 for a macro name that wants no argument list. 5922: MACRONAME is the macro name itself (so we can avoid recursive expansion) 5923: and NAMELEN is its length in characters. 5924: 1.1.1.8 ! root 5925: Note that comments, backslash-newlines, and leading white space ! 5926: have already been deleted from the argument. */ 1.1 root 5927: 1.1.1.8 ! root 5928: /* If there is no trailing whitespace, a Newline Space is added at the end 1.1 root 5929: to prevent concatenation that would be contrary to the standard. */ 5930: 5931: static DEFINITION * 5932: collect_expansion (buf, end, nargs, arglist) 5933: U_CHAR *buf, *end; 5934: int nargs; 5935: struct arglist *arglist; 5936: { 5937: DEFINITION *defn; 5938: register U_CHAR *p, *limit, *lastp, *exp_p; 5939: struct reflist *endpat = NULL; 5940: /* Pointer to first nonspace after last ## seen. */ 5941: U_CHAR *concat = 0; 5942: /* Pointer to first nonspace after last single-# seen. */ 5943: U_CHAR *stringify = 0; 1.1.1.8 ! root 5944: /* How those tokens were spelled. */ ! 5945: enum sharp_token_type concat_sharp_token_type = NO_SHARP_TOKEN; ! 5946: enum sharp_token_type stringify_sharp_token_type = NO_SHARP_TOKEN; 1.1 root 5947: int maxsize; 5948: int expected_delimiter = '\0'; 5949: 5950: /* Scan thru the replacement list, ignoring comments and quoted 5951: strings, picking up on the macro calls. It does a linear search 5952: thru the arg list on every potential symbol. Profiling might say 5953: that something smarter should happen. */ 5954: 5955: if (end < buf) 5956: abort (); 5957: 5958: /* Find the beginning of the trailing whitespace. */ 5959: limit = end; 5960: p = buf; 5961: while (p < limit && is_space[limit[-1]]) limit--; 5962: 5963: /* Allocate space for the text in the macro definition. 1.1.1.8 ! root 5964: Each input char may or may not need 1 byte, 1.1 root 5965: so this is an upper bound. 1.1.1.8 ! root 5966: The extra 3 are for invented trailing newline-marker and final null. */ 1.1 root 5967: maxsize = (sizeof (DEFINITION) 5968: + (limit - p) + 3); 5969: defn = (DEFINITION *) xcalloc (1, maxsize); 5970: 5971: defn->nargs = nargs; 5972: exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION); 5973: lastp = exp_p; 5974: 1.1.1.8 ! root 5975: if (p[0] == '#' ! 5976: ? p[1] == '#' ! 5977: : p[0] == '%' && p[1] == ':' && p[2] == '%' && p[3] == ':') { 1.1 root 5978: error ("`##' at start of macro definition"); 1.1.1.8 ! root 5979: p += p[0] == '#' ? 2 : 4; 1.1 root 5980: } 5981: 5982: /* Process the main body of the definition. */ 5983: while (p < limit) { 5984: int skipped_arg = 0; 5985: register U_CHAR c = *p++; 5986: 5987: *exp_p++ = c; 5988: 5989: if (!traditional) { 5990: switch (c) { 5991: case '\'': 5992: case '\"': 5993: if (expected_delimiter != '\0') { 5994: if (c == expected_delimiter) 5995: expected_delimiter = '\0'; 5996: } else 5997: expected_delimiter = c; 5998: break; 5999: 6000: case '\\': 1.1.1.7 root 6001: if (p < limit && expected_delimiter) { 1.1 root 6002: /* In a string, backslash goes through 6003: and makes next char ordinary. */ 6004: *exp_p++ = *p++; 6005: } 6006: break; 6007: 1.1.1.8 ! root 6008: case '%': ! 6009: if (!expected_delimiter && *p == ':') { ! 6010: /* %: is not a digraph if preceded by an odd number of '<'s. */ ! 6011: U_CHAR *p0 = p - 1; ! 6012: while (buf < p0 && p0[-1] == '<') ! 6013: p0--; ! 6014: if ((p - p0) & 1) { ! 6015: /* Treat %:%: as ## and %: as #. */ ! 6016: if (p[1] == '%' && p[2] == ':') { ! 6017: p += 2; ! 6018: goto sharp_sharp_token; ! 6019: } ! 6020: if (nargs >= 0) { ! 6021: p++; ! 6022: goto sharp_token; ! 6023: } ! 6024: } ! 6025: } ! 6026: break; ! 6027: 1.1 root 6028: case '#': 6029: /* # is ordinary inside a string. */ 6030: if (expected_delimiter) 6031: break; 1.1.1.8 ! root 6032: if (*p == '#') { ! 6033: sharp_sharp_token: 1.1 root 6034: /* ##: concatenate preceding and following tokens. */ 6035: /* Take out the first #, discard preceding whitespace. */ 6036: exp_p--; 6037: while (exp_p > lastp && is_hor_space[exp_p[-1]]) 6038: --exp_p; 6039: /* Skip the second #. */ 6040: p++; 1.1.1.8 ! root 6041: concat_sharp_token_type = c; ! 6042: if (is_hor_space[*p]) { ! 6043: concat_sharp_token_type = c + 1; ! 6044: p++; ! 6045: SKIP_WHITE_SPACE (p); ! 6046: } 1.1 root 6047: concat = p; 6048: if (p == limit) 6049: error ("`##' at end of macro definition"); 1.1.1.5 root 6050: } else if (nargs >= 0) { 1.1 root 6051: /* Single #: stringify following argument ref. 6052: Don't leave the # in the expansion. */ 1.1.1.8 ! root 6053: sharp_token: 1.1 root 6054: exp_p--; 1.1.1.8 ! root 6055: stringify_sharp_token_type = c; ! 6056: if (is_hor_space[*p]) { ! 6057: stringify_sharp_token_type = c + 1; ! 6058: p++; ! 6059: SKIP_WHITE_SPACE (p); ! 6060: } ! 6061: if (! is_idstart[*p] || nargs == 0) 1.1 root 6062: error ("`#' operator is not followed by a macro argument name"); 6063: else 6064: stringify = p; 6065: } 6066: break; 6067: } 6068: } else { 6069: /* In -traditional mode, recognize arguments inside strings and 6070: and character constants, and ignore special properties of #. 6071: Arguments inside strings are considered "stringified", but no 6072: extra quote marks are supplied. */ 6073: switch (c) { 6074: case '\'': 6075: case '\"': 6076: if (expected_delimiter != '\0') { 6077: if (c == expected_delimiter) 6078: expected_delimiter = '\0'; 6079: } else 6080: expected_delimiter = c; 6081: break; 6082: 6083: case '\\': 6084: /* Backslash quotes delimiters and itself, but not macro args. */ 6085: if (expected_delimiter != 0 && p < limit 6086: && (*p == expected_delimiter || *p == '\\')) { 6087: *exp_p++ = *p++; 6088: continue; 6089: } 6090: break; 6091: 6092: case '/': 6093: if (expected_delimiter != '\0') /* No comments inside strings. */ 6094: break; 6095: if (*p == '*') { 6096: /* If we find a comment that wasn't removed by handle_directive, 6097: this must be -traditional. So replace the comment with 6098: nothing at all. */ 6099: exp_p--; 6100: p += 1; 6101: while (p < limit && !(p[-2] == '*' && p[-1] == '/')) 6102: p++; 6103: #if 0 6104: /* Mark this as a concatenation-point, as if it had been ##. */ 6105: concat = p; 6106: #endif 6107: } 6108: break; 6109: } 6110: } 6111: 6112: /* Handle the start of a symbol. */ 6113: if (is_idchar[c] && nargs > 0) { 6114: U_CHAR *id_beg = p - 1; 6115: int id_len; 6116: 6117: --exp_p; 6118: while (p != limit && is_idchar[*p]) p++; 6119: id_len = p - id_beg; 6120: 6121: if (is_idstart[c]) { 6122: register struct arglist *arg; 6123: 6124: for (arg = arglist; arg != NULL; arg = arg->next) { 6125: struct reflist *tpat; 6126: 6127: if (arg->name[0] == c 6128: && arg->length == id_len 1.1.1.8 ! root 6129: && bcmp (arg->name, id_beg, id_len) == 0) { ! 6130: enum sharp_token_type tpat_stringify; ! 6131: if (expected_delimiter) { ! 6132: if (warn_stringify) { ! 6133: if (traditional) { ! 6134: warning ("macro argument `%.*s' is stringified.", ! 6135: id_len, arg->name); ! 6136: } else { ! 6137: warning ("macro arg `%.*s' would be stringified with -traditional.", ! 6138: id_len, arg->name); ! 6139: } 1.1 root 6140: } 1.1.1.8 ! root 6141: /* If ANSI, don't actually substitute inside a string. */ ! 6142: if (!traditional) ! 6143: break; ! 6144: tpat_stringify = SHARP_TOKEN; ! 6145: } else { ! 6146: tpat_stringify ! 6147: = (stringify == id_beg ! 6148: ? stringify_sharp_token_type : NO_SHARP_TOKEN); 1.1 root 6149: } 6150: /* make a pat node for this arg and append it to the end of 6151: the pat list */ 6152: tpat = (struct reflist *) xmalloc (sizeof (struct reflist)); 6153: tpat->next = NULL; 1.1.1.8 ! root 6154: tpat->raw_before ! 6155: = concat == id_beg ? concat_sharp_token_type : NO_SHARP_TOKEN; ! 6156: tpat->raw_after = NO_SHARP_TOKEN; 1.1.1.3 root 6157: tpat->rest_args = arg->rest_args; 1.1.1.8 ! root 6158: tpat->stringify = tpat_stringify; 1.1 root 6159: 6160: if (endpat == NULL) 6161: defn->pattern = tpat; 6162: else 6163: endpat->next = tpat; 6164: endpat = tpat; 6165: 6166: tpat->argno = arg->argno; 6167: tpat->nchars = exp_p - lastp; 6168: { 6169: register U_CHAR *p1 = p; 6170: SKIP_WHITE_SPACE (p1); 1.1.1.8 ! root 6171: if (p1[0]=='#' ! 6172: ? p1[1]=='#' ! 6173: : p1[0]=='%' && p1[1]==':' && p1[2]=='%' && p1[3]==':') ! 6174: tpat->raw_after = p1[0] + (p != p1); 1.1 root 6175: } 6176: lastp = exp_p; /* place to start copying from next time */ 6177: skipped_arg = 1; 6178: break; 6179: } 6180: } 6181: } 6182: 6183: /* If this was not a macro arg, copy it into the expansion. */ 6184: if (! skipped_arg) { 6185: register U_CHAR *lim1 = p; 6186: p = id_beg; 6187: while (p != lim1) 6188: *exp_p++ = *p++; 6189: if (stringify == id_beg) 6190: error ("`#' operator should be followed by a macro argument name"); 6191: } 6192: } 6193: } 6194: 1.1.1.7 root 6195: if (!traditional && expected_delimiter == 0) { 1.1.1.8 ! root 6196: /* If ANSI, put in a newline-space marker to prevent token pasting. ! 6197: But not if "inside a string" (which in ANSI mode happens only for ! 6198: -D option). */ 1.1 root 6199: *exp_p++ = '\n'; 6200: *exp_p++ = ' '; 6201: } 6202: 6203: *exp_p = '\0'; 6204: 6205: defn->length = exp_p - defn->expansion; 6206: 6207: /* Crash now if we overrun the allocated size. */ 6208: if (defn->length + 1 > maxsize) 6209: abort (); 6210: 6211: #if 0 6212: /* This isn't worth the time it takes. */ 6213: /* give back excess storage */ 6214: defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1); 6215: #endif 6216: 6217: return defn; 6218: } 6219: 6220: static int 6221: do_assert (buf, limit, op, keyword) 6222: U_CHAR *buf, *limit; 6223: FILE_BUF *op; 6224: struct directive *keyword; 6225: { 6226: U_CHAR *bp; /* temp ptr into input buffer */ 6227: U_CHAR *symname; /* remember where symbol name starts */ 6228: int sym_length; /* and how long it is */ 6229: struct arglist *tokens = NULL; 6230: 6231: if (pedantic && done_initializing && !instack[indepth].system_header_p) 6232: pedwarn ("ANSI C does not allow `#assert'"); 6233: 6234: bp = buf; 6235: 6236: while (is_hor_space[*bp]) 6237: bp++; 6238: 6239: symname = bp; /* remember where it starts */ 6240: sym_length = check_macro_name (bp, "assertion"); 6241: bp += sym_length; 6242: /* #define doesn't do this, but we should. */ 6243: SKIP_WHITE_SPACE (bp); 6244: 6245: /* Lossage will occur if identifiers or control tokens are broken 6246: across lines using backslash. This is not the right place to take 6247: care of that. */ 6248: 6249: if (*bp != '(') { 6250: error ("missing token-sequence in `#assert'"); 6251: return 1; 6252: } 6253: 6254: { 6255: int error_flag = 0; 6256: 6257: bp++; /* skip '(' */ 6258: SKIP_WHITE_SPACE (bp); 6259: 6260: tokens = read_token_list (&bp, limit, &error_flag); 6261: if (error_flag) 6262: return 1; 6263: if (tokens == 0) { 6264: error ("empty token-sequence in `#assert'"); 6265: return 1; 6266: } 6267: 6268: ++bp; /* skip paren */ 6269: SKIP_WHITE_SPACE (bp); 6270: } 6271: 6272: /* If this name isn't already an assertion name, make it one. 6273: Error if it was already in use in some other way. */ 6274: 6275: { 6276: ASSERTION_HASHNODE *hp; 6277: int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE); 6278: struct tokenlist_list *value 6279: = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list)); 6280: 6281: hp = assertion_lookup (symname, sym_length, hashcode); 6282: if (hp == NULL) { 1.1.1.8 ! root 6283: if (sym_length == 7 && ! bcmp (symname, "defined", 7)) 1.1 root 6284: error ("`defined' redefined as assertion"); 6285: hp = assertion_install (symname, sym_length, hashcode); 6286: } 6287: 6288: /* Add the spec'd token-sequence to the list of such. */ 6289: value->tokens = tokens; 6290: value->next = hp->value; 6291: hp->value = value; 6292: } 6293: 6294: return 0; 6295: } 6296: 6297: static int 6298: do_unassert (buf, limit, op, keyword) 6299: U_CHAR *buf, *limit; 6300: FILE_BUF *op; 6301: struct directive *keyword; 6302: { 6303: U_CHAR *bp; /* temp ptr into input buffer */ 6304: U_CHAR *symname; /* remember where symbol name starts */ 6305: int sym_length; /* and how long it is */ 6306: 6307: struct arglist *tokens = NULL; 6308: int tokens_specified = 0; 6309: 6310: if (pedantic && done_initializing && !instack[indepth].system_header_p) 6311: pedwarn ("ANSI C does not allow `#unassert'"); 6312: 6313: bp = buf; 6314: 6315: while (is_hor_space[*bp]) 6316: bp++; 6317: 6318: symname = bp; /* remember where it starts */ 6319: sym_length = check_macro_name (bp, "assertion"); 6320: bp += sym_length; 6321: /* #define doesn't do this, but we should. */ 6322: SKIP_WHITE_SPACE (bp); 6323: 6324: /* Lossage will occur if identifiers or control tokens are broken 6325: across lines using backslash. This is not the right place to take 6326: care of that. */ 6327: 6328: if (*bp == '(') { 6329: int error_flag = 0; 6330: 6331: bp++; /* skip '(' */ 6332: SKIP_WHITE_SPACE (bp); 6333: 6334: tokens = read_token_list (&bp, limit, &error_flag); 6335: if (error_flag) 6336: return 1; 6337: if (tokens == 0) { 6338: error ("empty token list in `#unassert'"); 6339: return 1; 6340: } 6341: 6342: tokens_specified = 1; 6343: 6344: ++bp; /* skip paren */ 6345: SKIP_WHITE_SPACE (bp); 6346: } 6347: 6348: { 6349: ASSERTION_HASHNODE *hp; 6350: int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE); 6351: struct tokenlist_list *tail, *prev; 6352: 6353: hp = assertion_lookup (symname, sym_length, hashcode); 6354: if (hp == NULL) 6355: return 1; 6356: 6357: /* If no token list was specified, then eliminate this assertion 6358: entirely. */ 6359: if (! tokens_specified) { 6360: struct tokenlist_list *next; 6361: for (tail = hp->value; tail; tail = next) { 6362: next = tail->next; 6363: free_token_list (tail->tokens); 6364: free (tail); 6365: } 6366: delete_assertion (hp); 6367: } else { 6368: /* If a list of tokens was given, then delete any matching list. */ 6369: 6370: tail = hp->value; 6371: prev = 0; 6372: while (tail) { 6373: struct tokenlist_list *next = tail->next; 6374: if (compare_token_lists (tail->tokens, tokens)) { 6375: if (prev) 6376: prev->next = next; 6377: else 6378: hp->value = tail->next; 6379: free_token_list (tail->tokens); 6380: free (tail); 6381: } else { 6382: prev = tail; 6383: } 6384: tail = next; 6385: } 6386: } 6387: } 6388: 6389: return 0; 6390: } 6391: 6392: /* Test whether there is an assertion named NAME 6393: and optionally whether it has an asserted token list TOKENS. 6394: NAME is not null terminated; its length is SYM_LENGTH. 6395: If TOKENS_SPECIFIED is 0, then don't check for any token list. */ 6396: 6397: int 6398: check_assertion (name, sym_length, tokens_specified, tokens) 6399: U_CHAR *name; 6400: int sym_length; 6401: int tokens_specified; 6402: struct arglist *tokens; 6403: { 6404: ASSERTION_HASHNODE *hp; 6405: int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE); 6406: 6407: if (pedantic && !instack[indepth].system_header_p) 6408: pedwarn ("ANSI C does not allow testing assertions"); 6409: 6410: hp = assertion_lookup (name, sym_length, hashcode); 6411: if (hp == NULL) 6412: /* It is not an assertion; just return false. */ 6413: return 0; 6414: 6415: /* If no token list was specified, then value is 1. */ 6416: if (! tokens_specified) 6417: return 1; 6418: 6419: { 6420: struct tokenlist_list *tail; 6421: 6422: tail = hp->value; 6423: 6424: /* If a list of tokens was given, 6425: then succeed if the assertion records a matching list. */ 6426: 6427: while (tail) { 6428: if (compare_token_lists (tail->tokens, tokens)) 6429: return 1; 6430: tail = tail->next; 6431: } 6432: 6433: /* Fail if the assertion has no matching list. */ 6434: return 0; 6435: } 6436: } 6437: 6438: /* Compare two lists of tokens for equality including order of tokens. */ 6439: 6440: static int 6441: compare_token_lists (l1, l2) 6442: struct arglist *l1, *l2; 6443: { 6444: while (l1 && l2) { 6445: if (l1->length != l2->length) 6446: return 0; 1.1.1.8 ! root 6447: if (bcmp (l1->name, l2->name, l1->length)) 1.1 root 6448: return 0; 6449: l1 = l1->next; 6450: l2 = l2->next; 6451: } 6452: 6453: /* Succeed if both lists end at the same time. */ 6454: return l1 == l2; 6455: } 6456: 6457: /* Read a space-separated list of tokens ending in a close parenthesis. 6458: Return a list of strings, in the order they were written. 6459: (In case of error, return 0 and store -1 in *ERROR_FLAG.) 6460: Parse the text starting at *BPP, and update *BPP. 6461: Don't parse beyond LIMIT. */ 6462: 6463: static struct arglist * 6464: read_token_list (bpp, limit, error_flag) 6465: U_CHAR **bpp; 6466: U_CHAR *limit; 6467: int *error_flag; 6468: { 6469: struct arglist *token_ptrs = 0; 6470: U_CHAR *bp = *bpp; 6471: int depth = 1; 6472: 6473: *error_flag = 0; 6474: 6475: /* Loop over the assertion value tokens. */ 6476: while (depth > 0) { 6477: struct arglist *temp; 6478: int eofp = 0; 6479: U_CHAR *beg = bp; 6480: 6481: /* Find the end of the token. */ 6482: if (*bp == '(') { 6483: bp++; 6484: depth++; 6485: } else if (*bp == ')') { 6486: depth--; 6487: if (depth == 0) 6488: break; 6489: bp++; 6490: } else if (*bp == '"' || *bp == '\'') 1.1.1.4 root 6491: bp = skip_quoted_string (bp, limit, 0, NULL_PTR, NULL_PTR, &eofp); 1.1 root 6492: else 6493: while (! is_hor_space[*bp] && *bp != '(' && *bp != ')' 6494: && *bp != '"' && *bp != '\'' && bp != limit) 6495: bp++; 6496: 6497: temp = (struct arglist *) xmalloc (sizeof (struct arglist)); 6498: temp->name = (U_CHAR *) xmalloc (bp - beg + 1); 1.1.1.7 root 6499: bcopy ((char *) beg, (char *) temp->name, bp - beg); 1.1 root 6500: temp->name[bp - beg] = 0; 6501: temp->next = token_ptrs; 6502: token_ptrs = temp; 6503: temp->length = bp - beg; 6504: 6505: SKIP_WHITE_SPACE (bp); 6506: 6507: if (bp >= limit) { 6508: error ("unterminated token sequence in `#assert' or `#unassert'"); 6509: *error_flag = -1; 6510: return 0; 6511: } 6512: } 6513: *bpp = bp; 6514: 6515: /* We accumulated the names in reverse order. 6516: Now reverse them to get the proper order. */ 6517: { 6518: register struct arglist *prev = 0, *this, *next; 6519: for (this = token_ptrs; this; this = next) { 6520: next = this->next; 6521: this->next = prev; 6522: prev = this; 6523: } 6524: return prev; 6525: } 6526: } 6527: 6528: static void 6529: free_token_list (tokens) 6530: struct arglist *tokens; 6531: { 6532: while (tokens) { 6533: struct arglist *next = tokens->next; 6534: free (tokens->name); 6535: free (tokens); 6536: tokens = next; 6537: } 6538: } 6539: 6540: /* 6541: * Install a name in the assertion hash table. 6542: * 6543: * If LEN is >= 0, it is the length of the name. 6544: * Otherwise, compute the length by scanning the entire name. 6545: * 6546: * If HASH is >= 0, it is the precomputed hash code. 6547: * Otherwise, compute the hash code. 6548: */ 6549: static ASSERTION_HASHNODE * 6550: assertion_install (name, len, hash) 6551: U_CHAR *name; 6552: int len; 6553: int hash; 6554: { 6555: register ASSERTION_HASHNODE *hp; 6556: register int i, bucket; 6557: register U_CHAR *p, *q; 6558: 6559: i = sizeof (ASSERTION_HASHNODE) + len + 1; 6560: hp = (ASSERTION_HASHNODE *) xmalloc (i); 6561: bucket = hash; 6562: hp->bucket_hdr = &assertion_hashtab[bucket]; 6563: hp->next = assertion_hashtab[bucket]; 6564: assertion_hashtab[bucket] = hp; 6565: hp->prev = NULL; 6566: if (hp->next != NULL) 6567: hp->next->prev = hp; 6568: hp->length = len; 6569: hp->value = 0; 6570: hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE); 6571: p = hp->name; 6572: q = name; 6573: for (i = 0; i < len; i++) 6574: *p++ = *q++; 6575: hp->name[len] = 0; 6576: return hp; 6577: } 6578: 6579: /* 6580: * find the most recent hash node for name name (ending with first 6581: * non-identifier char) installed by install 6582: * 6583: * If LEN is >= 0, it is the length of the name. 6584: * Otherwise, compute the length by scanning the entire name. 6585: * 6586: * If HASH is >= 0, it is the precomputed hash code. 6587: * Otherwise, compute the hash code. 6588: */ 6589: static ASSERTION_HASHNODE * 6590: assertion_lookup (name, len, hash) 6591: U_CHAR *name; 6592: int len; 6593: int hash; 6594: { 6595: register ASSERTION_HASHNODE *bucket; 6596: 6597: bucket = assertion_hashtab[hash]; 6598: while (bucket) { 1.1.1.8 ! root 6599: if (bucket->length == len && bcmp (bucket->name, name, len) == 0) 1.1 root 6600: return bucket; 6601: bucket = bucket->next; 6602: } 6603: return NULL; 6604: } 6605: 6606: static void 6607: delete_assertion (hp) 6608: ASSERTION_HASHNODE *hp; 6609: { 6610: 6611: if (hp->prev != NULL) 6612: hp->prev->next = hp->next; 6613: if (hp->next != NULL) 6614: hp->next->prev = hp->prev; 6615: 6616: /* make sure that the bucket chain header that 6617: the deleted guy was on points to the right thing afterwards. */ 6618: if (hp == *hp->bucket_hdr) 6619: *hp->bucket_hdr = hp->next; 6620: 6621: free (hp); 6622: } 6623: 6624: /* 1.1.1.8 ! root 6625: * interpret #line directive. Remembers previously seen fnames 1.1 root 6626: * in its very own hash table. 6627: */ 6628: #define FNAME_HASHSIZE 37 6629: 6630: static int 6631: do_line (buf, limit, op, keyword) 6632: U_CHAR *buf, *limit; 6633: FILE_BUF *op; 6634: struct directive *keyword; 6635: { 6636: register U_CHAR *bp; 6637: FILE_BUF *ip = &instack[indepth]; 6638: FILE_BUF tem; 6639: int new_lineno; 6640: enum file_change_code file_change = same_file; 6641: 6642: /* Expand any macros. */ 6643: tem = expand_to_temp_buffer (buf, limit, 0, 0); 6644: 6645: /* Point to macroexpanded line, which is null-terminated now. */ 6646: bp = tem.buf; 6647: SKIP_WHITE_SPACE (bp); 6648: 6649: if (!isdigit (*bp)) { 1.1.1.8 ! root 6650: error ("invalid format `#line' directive"); 1.1 root 6651: return 0; 6652: } 6653: 6654: /* The Newline at the end of this line remains to be processed. 6655: To put the next line at the specified line number, 6656: we must store a line number now that is one less. */ 1.1.1.8 ! root 6657: new_lineno = atoi ((char *) bp) - 1; 1.1 root 6658: 1.1.1.5 root 6659: /* NEW_LINENO is one less than the actual line number here. */ 6660: if (pedantic && new_lineno < 0) 1.1.1.8 ! root 6661: pedwarn ("line number out of range in `#line' directive"); 1.1.1.5 root 6662: 1.1 root 6663: /* skip over the line number. */ 6664: while (isdigit (*bp)) 6665: bp++; 6666: 6667: #if 0 /* #line 10"foo.c" is supposed to be allowed. */ 6668: if (*bp && !is_space[*bp]) { 1.1.1.8 ! root 6669: error ("invalid format `#line' directive"); 1.1 root 6670: return; 6671: } 6672: #endif 6673: 6674: SKIP_WHITE_SPACE (bp); 6675: 6676: if (*bp == '\"') { 6677: static HASHNODE *fname_table[FNAME_HASHSIZE]; 6678: HASHNODE *hp, **hash_bucket; 1.1.1.6 root 6679: U_CHAR *fname, *p; 1.1 root 6680: int fname_length; 6681: 6682: fname = ++bp; 6683: 1.1.1.6 root 6684: /* Turn the file name, which is a character string literal, 6685: into a null-terminated string. Do this in place. */ 6686: p = bp; 6687: for (;;) 6688: switch ((*p++ = *bp++)) { 6689: case '\0': 1.1.1.8 ! root 6690: error ("invalid format `#line' directive"); 1.1.1.6 root 6691: return 0; 1.1 root 6692: 1.1.1.6 root 6693: case '\\': 6694: { 6695: char *bpc = (char *) bp; 6696: int c = parse_escape (&bpc); 6697: bp = (U_CHAR *) bpc; 6698: if (c < 0) 6699: p--; 6700: else 6701: p[-1] = c; 6702: } 6703: break; 6704: 6705: case '\"': 6706: p[-1] = 0; 6707: goto fname_done; 6708: } 6709: fname_done: 6710: fname_length = p - fname; 1.1 root 6711: 6712: SKIP_WHITE_SPACE (bp); 6713: if (*bp) { 1.1.1.5 root 6714: if (pedantic) 1.1.1.8 ! root 6715: pedwarn ("garbage at end of `#line' directive"); 1.1 root 6716: if (*bp == '1') 6717: file_change = enter_file; 6718: else if (*bp == '2') 6719: file_change = leave_file; 1.1.1.2 root 6720: else if (*bp == '3') 6721: ip->system_header_p = 1; 1.1.1.6 root 6722: else if (*bp == '4') 6723: ip->system_header_p = 2; 1.1 root 6724: else { 1.1.1.8 ! root 6725: error ("invalid format `#line' directive"); 1.1 root 6726: return 0; 6727: } 6728: 6729: bp++; 6730: SKIP_WHITE_SPACE (bp); 1.1.1.2 root 6731: if (*bp == '3') { 6732: ip->system_header_p = 1; 6733: bp++; 6734: SKIP_WHITE_SPACE (bp); 6735: } 1.1.1.6 root 6736: if (*bp == '4') { 6737: ip->system_header_p = 2; 6738: bp++; 6739: SKIP_WHITE_SPACE (bp); 6740: } 1.1 root 6741: if (*bp) { 1.1.1.8 ! root 6742: error ("invalid format `#line' directive"); 1.1 root 6743: return 0; 6744: } 6745: } 6746: 6747: hash_bucket = 6748: &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)]; 6749: for (hp = *hash_bucket; hp != NULL; hp = hp->next) 6750: if (hp->length == fname_length && 1.1.1.8 ! root 6751: bcmp (hp->value.cpval, fname, fname_length) == 0) { 1.1 root 6752: ip->nominal_fname = hp->value.cpval; 6753: break; 6754: } 6755: if (hp == 0) { 6756: /* Didn't find it; cons up a new one. */ 6757: hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1); 6758: hp->next = *hash_bucket; 6759: *hash_bucket = hp; 6760: 6761: hp->length = fname_length; 6762: ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE); 6763: bcopy (fname, hp->value.cpval, fname_length); 6764: } 6765: } else if (*bp) { 1.1.1.8 ! root 6766: error ("invalid format `#line' directive"); 1.1 root 6767: return 0; 6768: } 6769: 6770: ip->lineno = new_lineno; 1.1.1.8 ! root 6771: output_line_directive (ip, op, 0, file_change); 1.1 root 6772: check_expand (op, ip->length - (ip->bufp - ip->buf)); 6773: return 0; 6774: } 6775: 6776: /* 6777: * remove the definition of a symbol from the symbol table. 6778: * according to un*x /lib/cpp, it is not an error to undef 6779: * something that has no definitions, so it isn't one here either. 6780: */ 6781: 6782: static int 6783: do_undef (buf, limit, op, keyword) 6784: U_CHAR *buf, *limit; 6785: FILE_BUF *op; 6786: struct directive *keyword; 6787: { 6788: int sym_length; 6789: HASHNODE *hp; 6790: U_CHAR *orig_buf = buf; 6791: 1.1.1.8 ! root 6792: /* If this is a precompiler run (with -pcp) pass thru #undef directives. */ 1.1 root 6793: if (pcp_outfile && op) 6794: pass_thru_directive (buf, limit, op, keyword); 6795: 6796: SKIP_WHITE_SPACE (buf); 6797: sym_length = check_macro_name (buf, "macro"); 6798: 6799: while ((hp = lookup (buf, sym_length, -1)) != NULL) { 6800: /* If we are generating additional info for debugging (with -g) we 1.1.1.8 ! root 6801: need to pass through all effective #undef directives. */ 1.1 root 6802: if (debug_output && op) 6803: pass_thru_directive (orig_buf, limit, op, keyword); 6804: if (hp->type != T_MACRO) 6805: warning ("undefining `%s'", hp->name); 6806: delete_macro (hp); 6807: } 6808: 6809: if (pedantic) { 6810: buf += sym_length; 6811: SKIP_WHITE_SPACE (buf); 6812: if (buf != limit) 6813: pedwarn ("garbage after `#undef' directive"); 6814: } 6815: return 0; 6816: } 6817: 6818: /* 1.1.1.7 root 6819: * Report an error detected by the program we are processing. 6820: * Use the text of the line in the error message. 1.1.1.5 root 6821: * (We use error because it prints the filename & line#.) 1.1 root 6822: */ 6823: 6824: static int 6825: do_error (buf, limit, op, keyword) 6826: U_CHAR *buf, *limit; 6827: FILE_BUF *op; 6828: struct directive *keyword; 6829: { 6830: int length = limit - buf; 1.1.1.5 root 6831: U_CHAR *copy = (U_CHAR *) xmalloc (length + 1); 1.1.1.7 root 6832: bcopy ((char *) buf, (char *) copy, length); 1.1 root 6833: copy[length] = 0; 6834: SKIP_WHITE_SPACE (copy); 6835: error ("#error %s", copy); 6836: return 0; 6837: } 6838: 6839: /* 6840: * Report a warning detected by the program we are processing. 6841: * Use the text of the line in the warning message, then continue. 1.1.1.5 root 6842: * (We use error because it prints the filename & line#.) 1.1 root 6843: */ 6844: 6845: static int 6846: do_warning (buf, limit, op, keyword) 6847: U_CHAR *buf, *limit; 6848: FILE_BUF *op; 6849: struct directive *keyword; 6850: { 6851: int length = limit - buf; 1.1.1.5 root 6852: U_CHAR *copy = (U_CHAR *) xmalloc (length + 1); 1.1.1.7 root 6853: bcopy ((char *) buf, (char *) copy, length); 1.1 root 6854: copy[length] = 0; 6855: SKIP_WHITE_SPACE (copy); 1.1.1.3 root 6856: warning ("#warning %s", copy); 1.1 root 6857: return 0; 6858: } 6859: 6860: /* Remember the name of the current file being read from so that we can 6861: avoid ever including it again. */ 6862: 1.1.1.8 ! root 6863: static void 1.1 root 6864: do_once () 6865: { 6866: int i; 6867: FILE_BUF *ip = NULL; 6868: 6869: for (i = indepth; i >= 0; i--) 6870: if (instack[i].fname != NULL) { 6871: ip = &instack[i]; 6872: break; 6873: } 6874: 6875: if (ip != NULL) { 6876: struct file_name_list *new; 6877: 6878: new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); 6879: new->next = dont_repeat_files; 6880: dont_repeat_files = new; 6881: new->fname = savestring (ip->fname); 6882: new->control_macro = 0; 1.1.1.7 root 6883: new->got_name_map = 0; 1.1.1.6 root 6884: new->c_system_include_path = 0; 1.1 root 6885: } 6886: } 6887: 6888: /* #ident has already been copied to the output file, so just ignore it. */ 6889: 6890: static int 1.1.1.8 ! root 6891: do_ident (buf, limit, op, keyword) 1.1 root 6892: U_CHAR *buf, *limit; 1.1.1.8 ! root 6893: FILE_BUF *op; ! 6894: struct directive *keyword; 1.1 root 6895: { 1.1.1.6 root 6896: FILE_BUF trybuf; 6897: int len; 6898: 1.1 root 6899: /* Allow #ident in system headers, since that's not user's fault. */ 6900: if (pedantic && !instack[indepth].system_header_p) 6901: pedwarn ("ANSI C does not allow `#ident'"); 1.1.1.6 root 6902: 6903: trybuf = expand_to_temp_buffer (buf, limit, 0, 0); 6904: buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1); 1.1.1.7 root 6905: bcopy ((char *) trybuf.buf, (char *) buf, trybuf.bufp - trybuf.buf); 1.1.1.6 root 6906: limit = buf + (trybuf.bufp - trybuf.buf); 6907: len = (limit - buf); 6908: free (trybuf.buf); 6909: 6910: /* Output directive name. */ 1.1.1.7 root 6911: check_expand (op, 7); 6912: bcopy ("#ident ", (char *) op->bufp, 7); 1.1.1.6 root 6913: op->bufp += 7; 6914: 6915: /* Output the expanded argument line. */ 6916: check_expand (op, len); 1.1.1.7 root 6917: bcopy ((char *) buf, (char *) op->bufp, len); 1.1.1.6 root 6918: op->bufp += len; 6919: 1.1 root 6920: return 0; 6921: } 6922: 6923: /* #pragma and its argument line have already been copied to the output file. 1.1.1.4 root 6924: Just check for some recognized pragmas that need validation here. */ 1.1 root 6925: 6926: static int 1.1.1.8 ! root 6927: do_pragma (buf, limit, op, keyword) 1.1 root 6928: U_CHAR *buf, *limit; 1.1.1.8 ! root 6929: FILE_BUF *op; ! 6930: struct directive *keyword; 1.1 root 6931: { 1.1.1.8 ! root 6932: SKIP_WHITE_SPACE (buf); ! 6933: if (!strncmp ((char *) buf, "once", 4)) { 1.1.1.3 root 6934: /* Allow #pragma once in system headers, since that's not the user's 6935: fault. */ 6936: if (!instack[indepth].system_header_p) 6937: warning ("`#pragma once' is obsolete"); 1.1 root 6938: do_once (); 6939: } 1.1.1.4 root 6940: 1.1.1.8 ! root 6941: if (!strncmp ((char *) buf, "implementation", 14)) { 1.1.1.4 root 6942: /* Be quiet about `#pragma implementation' for a file only if it hasn't 6943: been included yet. */ 6944: struct file_name_list *ptr; 6945: U_CHAR *p = buf + 14, *fname, *inc_fname; 6946: SKIP_WHITE_SPACE (p); 6947: if (*p == '\n' || *p != '\"') 6948: return 0; 6949: 6950: fname = p + 1; 1.1.1.8 ! root 6951: if ((p = (U_CHAR *) index ((char *) fname, '\"'))) 1.1.1.4 root 6952: *p = '\0'; 6953: 6954: for (ptr = all_include_files; ptr; ptr = ptr->next) { 6955: inc_fname = (U_CHAR *) rindex (ptr->fname, '/'); 6956: inc_fname = inc_fname ? inc_fname + 1 : (U_CHAR *) ptr->fname; 1.1.1.8 ! root 6957: if (inc_fname && !strcmp ((char *) inc_fname, (char *) fname)) 1.1.1.4 root 6958: warning ("`#pragma implementation' for `%s' appears after file is included", 6959: fname); 6960: } 6961: } 6962: 1.1 root 6963: return 0; 6964: } 6965: 6966: #if 0 6967: /* This was a fun hack, but #pragma seems to start to be useful. 6968: By failing to recognize it, we pass it through unchanged to cc1. */ 6969: 6970: /* 6971: * the behavior of the #pragma directive is implementation defined. 6972: * this implementation defines it as follows. 6973: */ 6974: 6975: static int 6976: do_pragma () 6977: { 6978: close (0); 6979: if (open ("/dev/tty", O_RDONLY, 0666) != 0) 6980: goto nope; 6981: close (1); 6982: if (open ("/dev/tty", O_WRONLY, 0666) != 1) 6983: goto nope; 6984: execl ("/usr/games/hack", "#pragma", 0); 6985: execl ("/usr/games/rogue", "#pragma", 0); 6986: execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0); 6987: execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0); 6988: nope: 6989: fatal ("You are in a maze of twisty compiler features, all different"); 6990: } 6991: #endif 6992: 1.1.1.8 ! root 6993: #ifdef SCCS_DIRECTIVE ! 6994: 1.1 root 6995: /* Just ignore #sccs, on systems where we define it at all. */ 6996: 6997: static int 1.1.1.8 ! root 6998: do_sccs (buf, limit, op, keyword) ! 6999: U_CHAR *buf, *limit; ! 7000: FILE_BUF *op; ! 7001: struct directive *keyword; 1.1 root 7002: { 7003: if (pedantic) 7004: pedwarn ("ANSI C does not allow `#sccs'"); 7005: return 0; 7006: } 1.1.1.8 ! root 7007: ! 7008: #endif /* defined (SCCS_DIRECTIVE) */ 1.1 root 7009: 7010: /* 1.1.1.8 ! root 7011: * handle #if directive by 1.1 root 7012: * 1) inserting special `defined' keyword into the hash table 7013: * that gets turned into 0 or 1 by special_symbol (thus, 7014: * if the luser has a symbol called `defined' already, it won't 1.1.1.8 ! root 7015: * work inside the #if directive) 1.1 root 7016: * 2) rescan the input into a temporary output buffer 7017: * 3) pass the output buffer to the yacc parser and collect a value 7018: * 4) clean up the mess left from steps 1 and 2. 7019: * 5) call conditional_skip to skip til the next #endif (etc.), 7020: * or not, depending on the value from step 3. 7021: */ 7022: 7023: static int 7024: do_if (buf, limit, op, keyword) 7025: U_CHAR *buf, *limit; 7026: FILE_BUF *op; 7027: struct directive *keyword; 7028: { 1.1.1.7 root 7029: HOST_WIDE_INT value; 1.1 root 7030: FILE_BUF *ip = &instack[indepth]; 7031: 7032: value = eval_if_expression (buf, limit - buf); 1.1.1.7 root 7033: conditional_skip (ip, value == 0, T_IF, NULL_PTR, op); 1.1 root 7034: return 0; 7035: } 7036: 7037: /* 7038: * handle a #elif directive by not changing if_stack either. 7039: * see the comment above do_else. 7040: */ 7041: 7042: static int 7043: do_elif (buf, limit, op, keyword) 7044: U_CHAR *buf, *limit; 7045: FILE_BUF *op; 7046: struct directive *keyword; 7047: { 1.1.1.7 root 7048: HOST_WIDE_INT value; 1.1 root 7049: FILE_BUF *ip = &instack[indepth]; 7050: 7051: if (if_stack == instack[indepth].if_stack) { 7052: error ("`#elif' not within a conditional"); 7053: return 0; 7054: } else { 7055: if (if_stack->type != T_IF && if_stack->type != T_ELIF) { 7056: error ("`#elif' after `#else'"); 7057: fprintf (stderr, " (matches line %d", if_stack->lineno); 7058: if (if_stack->fname != NULL && ip->fname != NULL && 7059: strcmp (if_stack->fname, ip->nominal_fname) != 0) 7060: fprintf (stderr, ", file %s", if_stack->fname); 7061: fprintf (stderr, ")\n"); 7062: } 7063: if_stack->type = T_ELIF; 7064: } 7065: 7066: if (if_stack->if_succeeded) 1.1.1.7 root 7067: skip_if_group (ip, 0, op); 1.1 root 7068: else { 7069: value = eval_if_expression (buf, limit - buf); 7070: if (value == 0) 1.1.1.7 root 7071: skip_if_group (ip, 0, op); 1.1 root 7072: else { 7073: ++if_stack->if_succeeded; /* continue processing input */ 1.1.1.8 ! root 7074: output_line_directive (ip, op, 1, same_file); 1.1 root 7075: } 7076: } 7077: return 0; 7078: } 7079: 7080: /* 7081: * evaluate a #if expression in BUF, of length LENGTH, 7082: * then parse the result as a C expression and return the value as an int. 7083: */ 1.1.1.7 root 7084: static HOST_WIDE_INT 1.1 root 7085: eval_if_expression (buf, length) 7086: U_CHAR *buf; 7087: int length; 7088: { 7089: FILE_BUF temp_obuf; 7090: HASHNODE *save_defined; 1.1.1.7 root 7091: HOST_WIDE_INT value; 1.1 root 7092: 1.1.1.8 ! root 7093: save_defined = install ((U_CHAR *) "defined", -1, T_SPEC_DEFINED, ! 7094: NULL_PTR, -1); 1.1 root 7095: pcp_inside_if = 1; 7096: temp_obuf = expand_to_temp_buffer (buf, buf + length, 0, 1); 7097: pcp_inside_if = 0; 7098: delete_macro (save_defined); /* clean up special symbol */ 7099: 1.1.1.8 ! root 7100: value = parse_c_expression ((char *) temp_obuf.buf); 1.1 root 7101: 7102: free (temp_obuf.buf); 7103: 7104: return value; 7105: } 7106: 7107: /* 7108: * routine to handle ifdef/ifndef. Try to look up the symbol, 7109: * then do or don't skip to the #endif/#else/#elif depending 7110: * on what directive is actually being processed. 7111: */ 7112: 7113: static int 7114: do_xifdef (buf, limit, op, keyword) 7115: U_CHAR *buf, *limit; 7116: FILE_BUF *op; 7117: struct directive *keyword; 7118: { 7119: int skip; 7120: FILE_BUF *ip = &instack[indepth]; 7121: U_CHAR *end; 7122: int start_of_file = 0; 7123: U_CHAR *control_macro = 0; 7124: 7125: /* Detect a #ifndef at start of file (not counting comments). */ 7126: if (ip->fname != 0 && keyword->type == T_IFNDEF) { 7127: U_CHAR *p = ip->buf; 7128: while (p != directive_start) { 1.1.1.5 root 7129: U_CHAR c = *p++; 1.1.1.4 root 7130: if (is_space[c]) 7131: ; 1.1.1.8 ! root 7132: /* Make no special provision for backslash-newline here; this is ! 7133: slower if backslash-newlines are present, but it's correct, ! 7134: and it's not worth it to tune for the rare backslash-newline. */ ! 7135: else if (c == '/' ! 7136: && (*p == '*' || (cplusplus_comments && *p == '/'))) { 1.1.1.4 root 7137: /* Skip this comment. */ 1.1.1.7 root 7138: int junk = 0; 1.1.1.4 root 7139: U_CHAR *save_bufp = ip->bufp; 7140: ip->bufp = p + 1; 7141: p = skip_to_end_of_comment (ip, &junk, 1); 7142: ip->bufp = save_bufp; 7143: } else { 1.1 root 7144: goto fail; 7145: } 7146: } 7147: /* If we get here, this conditional is the beginning of the file. */ 7148: start_of_file = 1; 7149: fail: ; 7150: } 7151: 7152: /* Discard leading and trailing whitespace. */ 7153: SKIP_WHITE_SPACE (buf); 7154: while (limit != buf && is_hor_space[limit[-1]]) limit--; 7155: 7156: /* Find the end of the identifier at the beginning. */ 7157: for (end = buf; is_idchar[*end]; end++); 7158: 7159: if (end == buf) { 7160: skip = (keyword->type == T_IFDEF); 7161: if (! traditional) 7162: pedwarn (end == limit ? "`#%s' with no argument" 7163: : "`#%s' argument starts with punctuation", 7164: keyword->name); 7165: } else { 7166: HASHNODE *hp; 7167: 7168: if (pedantic && buf[0] >= '0' && buf[0] <= '9') 7169: pedwarn ("`#%s' argument starts with a digit", keyword->name); 7170: else if (end != limit && !traditional) 7171: pedwarn ("garbage at end of `#%s' argument", keyword->name); 7172: 7173: hp = lookup (buf, end-buf, -1); 7174: 7175: if (pcp_outfile) { 7176: /* Output a precondition for this macro. */ 1.1.1.7 root 7177: if (hp && 7178: (hp->type == T_CONST 7179: || (hp->type == T_MACRO && hp->value.defn->predefined))) 1.1.1.5 root 7180: fprintf (pcp_outfile, "#define %s\n", hp->name); 1.1 root 7181: else { 7182: U_CHAR *cp = buf; 1.1.1.5 root 7183: fprintf (pcp_outfile, "#undef "); 1.1 root 7184: while (is_idchar[*cp]) /* Ick! */ 7185: fputc (*cp++, pcp_outfile); 7186: putc ('\n', pcp_outfile); 7187: } 7188: } 7189: 7190: skip = (hp == NULL) ^ (keyword->type == T_IFNDEF); 7191: if (start_of_file && !skip) { 7192: control_macro = (U_CHAR *) xmalloc (end - buf + 1); 1.1.1.7 root 7193: bcopy ((char *) buf, (char *) control_macro, end - buf); 1.1 root 7194: control_macro[end - buf] = 0; 7195: } 7196: } 7197: 1.1.1.7 root 7198: conditional_skip (ip, skip, T_IF, control_macro, op); 1.1 root 7199: return 0; 7200: } 7201: 7202: /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead. 7203: If this is a #ifndef starting at the beginning of a file, 7204: CONTROL_MACRO is the macro name tested by the #ifndef. 7205: Otherwise, CONTROL_MACRO is 0. */ 7206: 7207: static void 1.1.1.7 root 7208: conditional_skip (ip, skip, type, control_macro, op) 1.1 root 7209: FILE_BUF *ip; 7210: int skip; 7211: enum node_type type; 7212: U_CHAR *control_macro; 1.1.1.7 root 7213: FILE_BUF *op; 1.1 root 7214: { 7215: IF_STACK_FRAME *temp; 7216: 7217: temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME)); 7218: temp->fname = ip->nominal_fname; 7219: temp->lineno = ip->lineno; 7220: temp->next = if_stack; 7221: temp->control_macro = control_macro; 7222: if_stack = temp; 7223: 7224: if_stack->type = type; 7225: 7226: if (skip != 0) { 1.1.1.7 root 7227: skip_if_group (ip, 0, op); 1.1 root 7228: return; 7229: } else { 7230: ++if_stack->if_succeeded; 1.1.1.8 ! root 7231: output_line_directive (ip, &outbuf, 1, same_file); 1.1 root 7232: } 7233: } 7234: 7235: /* 7236: * skip to #endif, #else, or #elif. adjust line numbers, etc. 7237: * leaves input ptr at the sharp sign found. 7238: * If ANY is nonzero, return at next directive of any sort. 7239: */ 7240: static void 1.1.1.7 root 7241: skip_if_group (ip, any, op) 1.1 root 7242: FILE_BUF *ip; 7243: int any; 1.1.1.7 root 7244: FILE_BUF *op; 1.1 root 7245: { 7246: register U_CHAR *bp = ip->bufp, *cp; 7247: register U_CHAR *endb = ip->buf + ip->length; 7248: struct directive *kt; 7249: IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */ 7250: U_CHAR *beg_of_line = bp; 7251: register int ident_length; 7252: U_CHAR *ident, *after_ident; 1.1.1.7 root 7253: /* Save info about where the group starts. */ 7254: U_CHAR *beg_of_group = bp; 7255: int beg_lineno = ip->lineno; 7256: 7257: if (output_conditionals && op != 0) { 7258: char *ptr = "#failed\n"; 7259: int len = strlen (ptr); 7260: 7261: if (op->bufp > op->buf && op->bufp[-1] != '\n') 7262: { 7263: *op->bufp++ = '\n'; 7264: op->lineno++; 7265: } 7266: check_expand (op, len); 7267: bcopy (ptr, (char *) op->bufp, len); 7268: op->bufp += len; 7269: op->lineno++; 1.1.1.8 ! root 7270: output_line_directive (ip, op, 1, 0); 1.1.1.7 root 7271: } 1.1 root 7272: 7273: while (bp < endb) { 7274: switch (*bp++) { 7275: case '/': /* possible comment */ 7276: if (*bp == '\\' && bp[1] == '\n') 7277: newline_fix (bp); 7278: if (*bp == '*' 1.1.1.4 root 7279: || (cplusplus_comments && *bp == '/')) { 1.1 root 7280: ip->bufp = ++bp; 1.1.1.2 root 7281: bp = skip_to_end_of_comment (ip, &ip->lineno, 0); 1.1 root 7282: } 7283: break; 7284: case '\"': 7285: case '\'': 1.1.1.4 root 7286: bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno, 7287: NULL_PTR, NULL_PTR); 1.1 root 7288: break; 7289: case '\\': 7290: /* Char after backslash loses its special meaning. */ 7291: if (bp < endb) { 7292: if (*bp == '\n') 7293: ++ip->lineno; /* But do update the line-count. */ 7294: bp++; 7295: } 7296: break; 7297: case '\n': 7298: ++ip->lineno; 7299: beg_of_line = bp; 7300: break; 1.1.1.8 ! root 7301: case '%': ! 7302: if (beg_of_line == 0 || traditional) ! 7303: break; 1.1 root 7304: ip->bufp = bp - 1; 1.1.1.8 ! root 7305: while (bp[0] == '\\' && bp[1] == '\n') ! 7306: bp += 2; ! 7307: if (*bp == ':') ! 7308: goto sharp_token; ! 7309: break; ! 7310: case '#': 1.1 root 7311: /* # keyword: a # must be first nonblank char on the line */ 7312: if (beg_of_line == 0) 7313: break; 1.1.1.8 ! root 7314: ip->bufp = bp - 1; ! 7315: sharp_token: 1.1 root 7316: /* Scan from start of line, skipping whitespace, comments 7317: and backslash-newlines, and see if we reach this #. 7318: If not, this # is not special. */ 7319: bp = beg_of_line; 1.1.1.6 root 7320: /* If -traditional, require # to be at beginning of line. */ 1.1.1.8 ! root 7321: if (!traditional) { 1.1.1.6 root 7322: while (1) { 7323: if (is_hor_space[*bp]) 1.1 root 7324: bp++; 1.1.1.6 root 7325: else if (*bp == '\\' && bp[1] == '\n') 7326: bp += 2; 7327: else if (*bp == '/' && bp[1] == '*') { 7328: bp += 2; 7329: while (!(*bp == '*' && bp[1] == '/')) 7330: bp++; 7331: bp += 2; 7332: } 1.1.1.7 root 7333: /* There is no point in trying to deal with C++ // comments here, 7334: because if there is one, then this # must be part of the 7335: comment and we would never reach here. */ 1.1.1.6 root 7336: else break; 7337: } 1.1.1.8 ! root 7338: } 1.1 root 7339: if (bp != ip->bufp) { 7340: bp = ip->bufp + 1; /* Reset bp to after the #. */ 7341: break; 7342: } 7343: 7344: bp = ip->bufp + 1; /* Point after the '#' */ 1.1.1.8 ! root 7345: if (ip->bufp[0] == '%') { ! 7346: /* Skip past the ':' again. */ ! 7347: while (*bp == '\\') { ! 7348: ip->lineno++; ! 7349: bp += 2; ! 7350: } ! 7351: bp++; ! 7352: } 1.1 root 7353: 7354: /* Skip whitespace and \-newline. */ 7355: while (1) { 7356: if (is_hor_space[*bp]) 7357: bp++; 7358: else if (*bp == '\\' && bp[1] == '\n') 7359: bp += 2; 7360: else if (*bp == '/' && bp[1] == '*') { 7361: bp += 2; 7362: while (!(*bp == '*' && bp[1] == '/')) { 7363: if (*bp == '\n') 7364: ip->lineno++; 7365: bp++; 7366: } 7367: bp += 2; 1.1.1.4 root 7368: } else if (cplusplus_comments && *bp == '/' && bp[1] == '/') { 1.1 root 7369: bp += 2; 1.1.1.7 root 7370: while (bp[-1] == '\\' || *bp != '\n') { 7371: if (*bp == '\n') 7372: ip->lineno++; 7373: bp++; 7374: } 1.1 root 7375: } 7376: else break; 7377: } 7378: 7379: cp = bp; 7380: 7381: /* Now find end of directive name. 7382: If we encounter a backslash-newline, exchange it with any following 7383: symbol-constituents so that we end up with a contiguous name. */ 7384: 7385: while (1) { 7386: if (is_idchar[*bp]) 7387: bp++; 7388: else { 7389: if (*bp == '\\' && bp[1] == '\n') 7390: name_newline_fix (bp); 7391: if (is_idchar[*bp]) 7392: bp++; 7393: else break; 7394: } 7395: } 7396: ident_length = bp - cp; 7397: ident = cp; 7398: after_ident = bp; 7399: 7400: /* A line of just `#' becomes blank. */ 7401: 7402: if (ident_length == 0 && *after_ident == '\n') { 7403: continue; 7404: } 7405: 7406: if (ident_length == 0 || !is_idstart[*ident]) { 7407: U_CHAR *p = ident; 7408: while (is_idchar[*p]) { 7409: if (*p < '0' || *p > '9') 7410: break; 7411: p++; 7412: } 7413: /* Handle # followed by a line number. */ 7414: if (p != ident && !is_idchar[*p]) { 7415: if (pedantic) 7416: pedwarn ("`#' followed by integer"); 7417: continue; 7418: } 7419: 7420: /* Avoid error for `###' and similar cases unless -pedantic. */ 7421: if (p == ident) { 7422: while (*p == '#' || is_hor_space[*p]) p++; 7423: if (*p == '\n') { 7424: if (pedantic && !lang_asm) 1.1.1.8 ! root 7425: pedwarn ("invalid preprocessing directive"); 1.1 root 7426: continue; 7427: } 7428: } 7429: 7430: if (!lang_asm && pedantic) 1.1.1.8 ! root 7431: pedwarn ("invalid preprocessing directive name"); 1.1 root 7432: continue; 7433: } 7434: 7435: for (kt = directive_table; kt->length >= 0; kt++) { 7436: IF_STACK_FRAME *temp; 7437: if (ident_length == kt->length 1.1.1.8 ! root 7438: && bcmp (cp, kt->name, kt->length) == 0) { 1.1 root 7439: /* If we are asked to return on next directive, do so now. */ 7440: if (any) 1.1.1.7 root 7441: goto done; 1.1 root 7442: 7443: switch (kt->type) { 7444: case T_IF: 7445: case T_IFDEF: 7446: case T_IFNDEF: 7447: temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME)); 7448: temp->next = if_stack; 7449: if_stack = temp; 7450: temp->lineno = ip->lineno; 7451: temp->fname = ip->nominal_fname; 7452: temp->type = kt->type; 7453: break; 7454: case T_ELSE: 7455: case T_ENDIF: 7456: if (pedantic && if_stack != save_if_stack) 7457: validate_else (bp); 7458: case T_ELIF: 7459: if (if_stack == instack[indepth].if_stack) { 7460: error ("`#%s' not within a conditional", kt->name); 7461: break; 7462: } 7463: else if (if_stack == save_if_stack) 1.1.1.7 root 7464: goto done; /* found what we came for */ 1.1 root 7465: 7466: if (kt->type != T_ENDIF) { 7467: if (if_stack->type == T_ELSE) 7468: error ("`#else' or `#elif' after `#else'"); 7469: if_stack->type = kt->type; 7470: break; 7471: } 7472: 7473: temp = if_stack; 7474: if_stack = if_stack->next; 7475: free (temp); 7476: break; 1.1.1.8 ! root 7477: ! 7478: default: ! 7479: break; 1.1 root 7480: } 7481: break; 7482: } 7483: } 7484: /* Don't let erroneous code go by. */ 7485: if (kt->length < 0 && !lang_asm && pedantic) 1.1.1.8 ! root 7486: pedwarn ("invalid preprocessing directive name"); 1.1 root 7487: } 7488: } 1.1.1.7 root 7489: 1.1 root 7490: ip->bufp = bp; 7491: /* after this returns, rescan will exit because ip->bufp 7492: now points to the end of the buffer. 7493: rescan is responsible for the error message also. */ 1.1.1.7 root 7494: 7495: done: 7496: if (output_conditionals && op != 0) { 7497: char *ptr = "#endfailed\n"; 7498: int len = strlen (ptr); 7499: 7500: if (op->bufp > op->buf && op->bufp[-1] != '\n') 7501: { 7502: *op->bufp++ = '\n'; 7503: op->lineno++; 7504: } 7505: check_expand (op, beg_of_line - beg_of_group); 7506: bcopy ((char *) beg_of_group, (char *) op->bufp, 7507: beg_of_line - beg_of_group); 7508: op->bufp += beg_of_line - beg_of_group; 7509: op->lineno += ip->lineno - beg_lineno; 7510: check_expand (op, len); 7511: bcopy (ptr, (char *) op->bufp, len); 7512: op->bufp += len; 7513: op->lineno++; 7514: } 1.1 root 7515: } 7516: 7517: /* 7518: * handle a #else directive. Do this by just continuing processing 7519: * without changing if_stack ; this is so that the error message 7520: * for missing #endif's etc. will point to the original #if. It 7521: * is possible that something different would be better. 7522: */ 7523: 7524: static int 7525: do_else (buf, limit, op, keyword) 7526: U_CHAR *buf, *limit; 7527: FILE_BUF *op; 7528: struct directive *keyword; 7529: { 7530: FILE_BUF *ip = &instack[indepth]; 7531: 7532: if (pedantic) { 7533: SKIP_WHITE_SPACE (buf); 7534: if (buf != limit) 7535: pedwarn ("text following `#else' violates ANSI standard"); 7536: } 7537: 7538: if (if_stack == instack[indepth].if_stack) { 7539: error ("`#else' not within a conditional"); 7540: return 0; 7541: } else { 7542: /* #ifndef can't have its special treatment for containing the whole file 7543: if it has a #else clause. */ 7544: if_stack->control_macro = 0; 7545: 7546: if (if_stack->type != T_IF && if_stack->type != T_ELIF) { 7547: error ("`#else' after `#else'"); 7548: fprintf (stderr, " (matches line %d", if_stack->lineno); 7549: if (strcmp (if_stack->fname, ip->nominal_fname) != 0) 7550: fprintf (stderr, ", file %s", if_stack->fname); 7551: fprintf (stderr, ")\n"); 7552: } 7553: if_stack->type = T_ELSE; 7554: } 7555: 7556: if (if_stack->if_succeeded) 1.1.1.7 root 7557: skip_if_group (ip, 0, op); 1.1 root 7558: else { 7559: ++if_stack->if_succeeded; /* continue processing input */ 1.1.1.8 ! root 7560: output_line_directive (ip, op, 1, same_file); 1.1 root 7561: } 7562: return 0; 7563: } 7564: 7565: /* 1.1.1.8 ! root 7566: * unstack after #endif directive 1.1 root 7567: */ 7568: 7569: static int 7570: do_endif (buf, limit, op, keyword) 7571: U_CHAR *buf, *limit; 7572: FILE_BUF *op; 7573: struct directive *keyword; 7574: { 7575: if (pedantic) { 7576: SKIP_WHITE_SPACE (buf); 7577: if (buf != limit) 7578: pedwarn ("text following `#endif' violates ANSI standard"); 7579: } 7580: 7581: if (if_stack == instack[indepth].if_stack) 7582: error ("unbalanced `#endif'"); 7583: else { 7584: IF_STACK_FRAME *temp = if_stack; 7585: if_stack = if_stack->next; 7586: if (temp->control_macro != 0) { 7587: /* This #endif matched a #ifndef at the start of the file. 7588: See if it is at the end of the file. */ 7589: FILE_BUF *ip = &instack[indepth]; 7590: U_CHAR *p = ip->bufp; 7591: U_CHAR *ep = ip->buf + ip->length; 7592: 7593: while (p != ep) { 7594: U_CHAR c = *p++; 1.1.1.8 ! root 7595: if (!is_space[c]) { ! 7596: if (c == '/' ! 7597: && (*p == '*' || (cplusplus_comments && *p == '/'))) { 1.1 root 7598: /* Skip this comment. */ 1.1.1.7 root 7599: int junk = 0; 1.1 root 7600: U_CHAR *save_bufp = ip->bufp; 7601: ip->bufp = p + 1; 1.1.1.2 root 7602: p = skip_to_end_of_comment (ip, &junk, 1); 1.1 root 7603: ip->bufp = save_bufp; 1.1.1.8 ! root 7604: } else ! 7605: goto fail; 1.1 root 7606: } 7607: } 7608: /* If we get here, this #endif ends a #ifndef 7609: that contains all of the file (aside from whitespace). 7610: Arrange not to include the file again 1.1.1.7 root 7611: if the macro that was tested is defined. 7612: 7613: Do not do this for the top-level file in a -include or any 7614: file in a -imacros. */ 7615: if (indepth != 0 7616: && ! (indepth == 1 && no_record_file) 7617: && ! (no_record_file && no_output)) 1.1 root 7618: record_control_macro (ip->fname, temp->control_macro); 7619: fail: ; 7620: } 7621: free (temp); 1.1.1.8 ! root 7622: output_line_directive (&instack[indepth], op, 1, same_file); 1.1 root 7623: } 7624: return 0; 7625: } 7626: 7627: /* When an #else or #endif is found while skipping failed conditional, 7628: if -pedantic was specified, this is called to warn about text after 1.1.1.8 ! root 7629: the directive name. P points to the first char after the directive name. */ 1.1 root 7630: 7631: static void 7632: validate_else (p) 7633: register U_CHAR *p; 7634: { 7635: /* Advance P over whitespace and comments. */ 7636: while (1) { 7637: if (*p == '\\' && p[1] == '\n') 7638: p += 2; 7639: if (is_hor_space[*p]) 7640: p++; 7641: else if (*p == '/') { 7642: if (p[1] == '\\' && p[2] == '\n') 7643: newline_fix (p + 1); 7644: if (p[1] == '*') { 7645: p += 2; 7646: /* Don't bother warning about unterminated comments 7647: since that will happen later. Just be sure to exit. */ 7648: while (*p) { 7649: if (p[1] == '\\' && p[2] == '\n') 7650: newline_fix (p + 1); 7651: if (*p == '*' && p[1] == '/') { 7652: p += 2; 7653: break; 7654: } 7655: p++; 7656: } 7657: } 1.1.1.4 root 7658: else if (cplusplus_comments && p[1] == '/') { 1.1 root 7659: p += 2; 1.1.1.7 root 7660: while (*p && (*p != '\n' || p[-1] == '\\')) 7661: p++; 1.1 root 7662: } 7663: } else break; 7664: } 7665: if (*p && *p != '\n') 7666: pedwarn ("text following `#else' or `#endif' violates ANSI standard"); 7667: } 7668: 1.1.1.2 root 7669: /* Skip a comment, assuming the input ptr immediately follows the 7670: initial slash-star. Bump *LINE_COUNTER for each newline. 7671: (The canonical line counter is &ip->lineno.) 7672: Don't use this routine (or the next one) if bumping the line 7673: counter is not sufficient to deal with newlines in the string. 7674: 7675: If NOWARN is nonzero, don't warn about slash-star inside a comment. 7676: This feature is useful when processing a comment that is going to be 7677: processed or was processed at another point in the preprocessor, 1.1.1.7 root 7678: to avoid a duplicate warning. Likewise for unterminated comment errors. */ 7679: 1.1 root 7680: static U_CHAR * 1.1.1.2 root 7681: skip_to_end_of_comment (ip, line_counter, nowarn) 1.1 root 7682: register FILE_BUF *ip; 7683: int *line_counter; /* place to remember newlines, or NULL */ 1.1.1.2 root 7684: int nowarn; 1.1 root 7685: { 7686: register U_CHAR *limit = ip->buf + ip->length; 7687: register U_CHAR *bp = ip->bufp; 7688: FILE_BUF *op = &outbuf; /* JF */ 7689: int output = put_out_comments && !line_counter; 1.1.1.7 root 7690: int start_line = line_counter ? *line_counter : 0; 1.1 root 7691: 7692: /* JF this line_counter stuff is a crock to make sure the 7693: comment is only put out once, no matter how many times 7694: the comment is skipped. It almost works */ 7695: if (output) { 7696: *op->bufp++ = '/'; 7697: *op->bufp++ = '*'; 7698: } 1.1.1.4 root 7699: if (cplusplus_comments && bp[-1] == '/') { 1.1 root 7700: if (output) { 1.1.1.7 root 7701: while (bp < limit) { 7702: *op->bufp++ = *bp; 7703: if (*bp == '\n' && bp[-1] != '\\') 1.1 root 7704: break; 1.1.1.7 root 7705: if (*bp == '\n') { 7706: ++*line_counter; 7707: ++op->lineno; 1.1 root 7708: } 1.1.1.7 root 7709: bp++; 7710: } 1.1 root 7711: op->bufp[-1] = '*'; 7712: *op->bufp++ = '/'; 7713: *op->bufp++ = '\n'; 7714: } else { 7715: while (bp < limit) { 1.1.1.7 root 7716: if (bp[-1] != '\\' && *bp == '\n') { 1.1 root 7717: break; 1.1.1.7 root 7718: } else { 7719: if (*bp == '\n' && line_counter) 7720: ++*line_counter; 7721: bp++; 1.1 root 7722: } 7723: } 7724: } 7725: ip->bufp = bp; 7726: return bp; 7727: } 7728: while (bp < limit) { 7729: if (output) 7730: *op->bufp++ = *bp; 7731: switch (*bp++) { 7732: case '/': 1.1.1.2 root 7733: if (warn_comments && !nowarn && bp < limit && *bp == '*') 1.1 root 7734: warning ("`/*' within comment"); 7735: break; 7736: case '\n': 1.1.1.7 root 7737: /* If this is the end of the file, we have an unterminated comment. 7738: Don't swallow the newline. We are guaranteed that there will be a 7739: trailing newline and various pieces assume it's there. */ 7740: if (bp == limit) 7741: { 7742: --bp; 7743: --limit; 7744: break; 7745: } 1.1 root 7746: if (line_counter != NULL) 7747: ++*line_counter; 7748: if (output) 7749: ++op->lineno; 7750: break; 7751: case '*': 7752: if (*bp == '\\' && bp[1] == '\n') 7753: newline_fix (bp); 7754: if (*bp == '/') { 7755: if (output) 7756: *op->bufp++ = '/'; 7757: ip->bufp = ++bp; 7758: return bp; 7759: } 7760: break; 7761: } 7762: } 1.1.1.7 root 7763: 7764: if (!nowarn) 7765: error_with_line (line_for_error (start_line), "unterminated comment"); 1.1 root 7766: ip->bufp = bp; 7767: return bp; 7768: } 7769: 7770: /* 7771: * Skip over a quoted string. BP points to the opening quote. 7772: * Returns a pointer after the closing quote. Don't go past LIMIT. 7773: * START_LINE is the line number of the starting point (but it need 7774: * not be valid if the starting point is inside a macro expansion). 7775: * 7776: * The input stack state is not changed. 7777: * 7778: * If COUNT_NEWLINES is nonzero, it points to an int to increment 7779: * for each newline passed. 7780: * 7781: * If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it 7782: * if we pass a backslash-newline. 7783: * 7784: * If EOFP is nonzero, set *EOFP to 1 if the string is unterminated. 7785: */ 7786: static U_CHAR * 7787: skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp) 7788: register U_CHAR *bp; 7789: register U_CHAR *limit; 7790: int start_line; 7791: int *count_newlines; 7792: int *backslash_newlines_p; 7793: int *eofp; 7794: { 7795: register U_CHAR c, match; 7796: 7797: match = *bp++; 7798: while (1) { 7799: if (bp >= limit) { 7800: error_with_line (line_for_error (start_line), 7801: "unterminated string or character constant"); 1.1.1.5 root 7802: error_with_line (multiline_string_line, 7803: "possible real start of unterminated constant"); 7804: multiline_string_line = 0; 1.1 root 7805: if (eofp) 7806: *eofp = 1; 7807: break; 7808: } 7809: c = *bp++; 7810: if (c == '\\') { 7811: while (*bp == '\\' && bp[1] == '\n') { 7812: if (backslash_newlines_p) 7813: *backslash_newlines_p = 1; 7814: if (count_newlines) 7815: ++*count_newlines; 7816: bp += 2; 7817: } 7818: if (*bp == '\n' && count_newlines) { 7819: if (backslash_newlines_p) 7820: *backslash_newlines_p = 1; 7821: ++*count_newlines; 7822: } 7823: bp++; 7824: } else if (c == '\n') { 7825: if (traditional) { 1.1.1.8 ! root 7826: /* Unterminated strings and character constants are 'valid'. */ 1.1 root 7827: bp--; /* Don't consume the newline. */ 7828: if (eofp) 7829: *eofp = 1; 7830: break; 7831: } 1.1.1.5 root 7832: if (pedantic || match == '\'') { 1.1 root 7833: error_with_line (line_for_error (start_line), 1.1.1.5 root 7834: "unterminated string or character constant"); 1.1 root 7835: bp--; 7836: if (eofp) 7837: *eofp = 1; 7838: break; 7839: } 7840: /* If not traditional, then allow newlines inside strings. */ 7841: if (count_newlines) 7842: ++*count_newlines; 1.1.1.5 root 7843: if (multiline_string_line == 0) 7844: multiline_string_line = start_line; 1.1 root 7845: } else if (c == match) 7846: break; 7847: } 7848: return bp; 7849: } 7850: 1.1.1.6 root 7851: /* Place into DST a quoted string representing the string SRC. 7852: Return the address of DST's terminating null. */ 7853: static char * 7854: quote_string (dst, src) 7855: char *dst, *src; 7856: { 7857: U_CHAR c; 7858: 7859: *dst++ = '\"'; 7860: for (;;) 7861: switch ((c = *src++)) 7862: { 7863: default: 7864: if (isprint (c)) 7865: *dst++ = c; 7866: else 7867: { 7868: sprintf (dst, "\\%03o", c); 7869: dst += 4; 7870: } 7871: break; 7872: 7873: case '\"': 7874: case '\\': 7875: *dst++ = '\\'; 7876: *dst++ = c; 7877: break; 7878: 7879: case '\0': 7880: *dst++ = '\"'; 7881: *dst = '\0'; 7882: return dst; 7883: } 7884: } 7885: 1.1 root 7886: /* Skip across a group of balanced parens, starting from IP->bufp. 7887: IP->bufp is updated. Use this with IP->bufp pointing at an open-paren. 7888: 7889: This does not handle newlines, because it's used for the arg of #if, 1.1.1.2 root 7890: where there aren't any newlines. Also, backslash-newline can't appear. */ 1.1 root 7891: 7892: static U_CHAR * 7893: skip_paren_group (ip) 7894: register FILE_BUF *ip; 7895: { 7896: U_CHAR *limit = ip->buf + ip->length; 7897: U_CHAR *p = ip->bufp; 7898: int depth = 0; 7899: int lines_dummy = 0; 7900: 7901: while (p != limit) { 7902: int c = *p++; 7903: switch (c) { 7904: case '(': 7905: depth++; 7906: break; 7907: 7908: case ')': 7909: depth--; 7910: if (depth == 0) 7911: return ip->bufp = p; 7912: break; 7913: 7914: case '/': 7915: if (*p == '*') { 7916: ip->bufp = p; 1.1.1.2 root 7917: p = skip_to_end_of_comment (ip, &lines_dummy, 0); 1.1 root 7918: p = ip->bufp; 7919: } 7920: 7921: case '"': 7922: case '\'': 7923: { 7924: int eofp = 0; 1.1.1.4 root 7925: p = skip_quoted_string (p - 1, limit, 0, NULL_PTR, NULL_PTR, &eofp); 1.1 root 7926: if (eofp) 7927: return ip->bufp = p; 7928: } 7929: break; 7930: } 7931: } 7932: 7933: ip->bufp = p; 7934: return p; 7935: } 7936: 7937: /* 1.1.1.8 ! root 7938: * write out a #line directive, for instance, after an #include file. 1.1 root 7939: * If CONDITIONAL is nonzero, we can omit the #line if it would 7940: * appear to be a no-op, and we can output a few newlines instead 7941: * if we want to increase the line number by a small amount. 7942: * FILE_CHANGE says whether we are entering a file, leaving, or neither. 7943: */ 7944: 7945: static void 1.1.1.8 ! root 7946: output_line_directive (ip, op, conditional, file_change) 1.1 root 7947: FILE_BUF *ip, *op; 7948: int conditional; 7949: enum file_change_code file_change; 7950: { 7951: int len; 1.1.1.8 ! root 7952: char *line_directive_buf, *line_end; 1.1 root 7953: 1.1.1.8 ! root 7954: if (no_line_directives 1.1 root 7955: || ip->fname == NULL 7956: || no_output) { 7957: op->lineno = ip->lineno; 7958: return; 7959: } 7960: 7961: if (conditional) { 7962: if (ip->lineno == op->lineno) 7963: return; 7964: 7965: /* If the inherited line number is a little too small, 1.1.1.8 ! root 7966: output some newlines instead of a #line directive. */ 1.1 root 7967: if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) { 7968: check_expand (op, 10); 7969: while (ip->lineno > op->lineno) { 7970: *op->bufp++ = '\n'; 7971: op->lineno++; 7972: } 7973: return; 7974: } 7975: } 7976: 1.1.1.2 root 7977: /* Don't output a line number of 0 if we can help it. */ 7978: if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length 7979: && *ip->bufp == '\n') { 7980: ip->lineno++; 7981: ip->bufp++; 7982: } 7983: 1.1.1.8 ! root 7984: line_directive_buf = (char *) alloca (4 * strlen (ip->nominal_fname) + 100); ! 7985: sprintf (line_directive_buf, "# %d ", ip->lineno); ! 7986: line_end = quote_string (line_directive_buf + strlen (line_directive_buf), 1.1.1.6 root 7987: ip->nominal_fname); 7988: if (file_change != same_file) { 7989: *line_end++ = ' '; 7990: *line_end++ = file_change == enter_file ? '1' : '2'; 7991: } 1.1 root 7992: /* Tell cc1 if following text comes from a system header file. */ 1.1.1.6 root 7993: if (ip->system_header_p) { 7994: *line_end++ = ' '; 7995: *line_end++ = '3'; 7996: } 7997: #ifndef NO_IMPLICIT_EXTERN_C 7998: /* Tell cc1plus if following text should be treated as C. */ 7999: if (ip->system_header_p == 2 && cplusplus) { 8000: *line_end++ = ' '; 8001: *line_end++ = '4'; 8002: } 8003: #endif 8004: *line_end++ = '\n'; 1.1.1.8 ! root 8005: len = line_end - line_directive_buf; 1.1 root 8006: check_expand (op, len + 1); 8007: if (op->bufp > op->buf && op->bufp[-1] != '\n') 8008: *op->bufp++ = '\n'; 1.1.1.8 ! root 8009: bcopy ((char *) line_directive_buf, (char *) op->bufp, len); 1.1 root 8010: op->bufp += len; 8011: op->lineno = ip->lineno; 8012: } 8013: 8014: /* This structure represents one parsed argument in a macro call. 8015: `raw' points to the argument text as written (`raw_length' is its length). 8016: `expanded' points to the argument's macro-expansion 8017: (its length is `expand_length'). 8018: `stringified_length' is the length the argument would have 8019: if stringified. 8020: `use_count' is the number of times this macro arg is substituted 8021: into the macro. If the actual use count exceeds 10, 8022: the value stored is 10. 8023: `free1' and `free2', if nonzero, point to blocks to be freed 8024: when the macro argument data is no longer needed. */ 8025: 8026: struct argdata { 8027: U_CHAR *raw, *expanded; 8028: int raw_length, expand_length; 8029: int stringified_length; 8030: U_CHAR *free1, *free2; 8031: char newlines; 8032: char use_count; 8033: }; 8034: 8035: /* Expand a macro call. 8036: HP points to the symbol that is the macro being called. 8037: Put the result of expansion onto the input stack 8038: so that subsequent input by our caller will use it. 8039: 8040: If macro wants arguments, caller has already verified that 8041: an argument list follows; arguments come from the input stack. */ 8042: 8043: static void 8044: macroexpand (hp, op) 8045: HASHNODE *hp; 8046: FILE_BUF *op; 8047: { 8048: int nargs; 8049: DEFINITION *defn = hp->value.defn; 8050: register U_CHAR *xbuf; 8051: int xbuf_len; 8052: int start_line = instack[indepth].lineno; 1.1.1.3 root 8053: int rest_args, rest_zero; 1.1 root 8054: 8055: CHECK_DEPTH (return;); 8056: 8057: /* it might not actually be a macro. */ 8058: if (hp->type != T_MACRO) { 8059: special_symbol (hp, op); 8060: return; 8061: } 8062: 8063: /* This macro is being used inside a #if, which means it must be */ 8064: /* recorded as a precondition. */ 8065: if (pcp_inside_if && pcp_outfile && defn->predefined) 8066: dump_single_macro (hp, pcp_outfile); 8067: 8068: nargs = defn->nargs; 8069: 8070: if (nargs >= 0) { 8071: register int i; 8072: struct argdata *args; 8073: char *parse_error = 0; 8074: 8075: args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata)); 8076: 8077: for (i = 0; i < nargs; i++) { 1.1.1.5 root 8078: args[i].raw = (U_CHAR *) ""; 8079: args[i].expanded = 0; 1.1 root 8080: args[i].raw_length = args[i].expand_length 8081: = args[i].stringified_length = 0; 8082: args[i].free1 = args[i].free2 = 0; 8083: args[i].use_count = 0; 8084: } 8085: 8086: /* Parse all the macro args that are supplied. I counts them. 8087: The first NARGS args are stored in ARGS. 1.1.1.3 root 8088: The rest are discarded. 8089: If rest_args is set then we assume macarg absorbed the rest of the args. 8090: */ 1.1 root 8091: i = 0; 1.1.1.3 root 8092: rest_args = 0; 1.1 root 8093: do { 8094: /* Discard the open-parenthesis or comma before the next arg. */ 8095: ++instack[indepth].bufp; 1.1.1.3 root 8096: if (rest_args) 8097: continue; 8098: if (i < nargs || (nargs == 0 && i == 0)) { 1.1.1.4 root 8099: /* if we are working on last arg which absorbs rest of args... */ 1.1.1.3 root 8100: if (i == nargs - 1 && defn->rest_args) 8101: rest_args = 1; 8102: parse_error = macarg (&args[i], rest_args); 8103: } 8104: else 1.1.1.4 root 8105: parse_error = macarg (NULL_PTR, 0); 1.1 root 8106: if (parse_error) { 8107: error_with_line (line_for_error (start_line), parse_error); 8108: break; 8109: } 8110: i++; 8111: } while (*instack[indepth].bufp != ')'); 8112: 8113: /* If we got one arg but it was just whitespace, call that 0 args. */ 8114: if (i == 1) { 8115: register U_CHAR *bp = args[0].raw; 8116: register U_CHAR *lim = bp + args[0].raw_length; 1.1.1.5 root 8117: /* cpp.texi says for foo ( ) we provide one argument. 8118: However, if foo wants just 0 arguments, treat this as 0. */ 8119: if (nargs == 0) 8120: while (bp != lim && is_space[*bp]) bp++; 1.1 root 8121: if (bp == lim) 8122: i = 0; 8123: } 8124: 1.1.1.4 root 8125: /* Don't output an error message if we have already output one for 8126: a parse error above. */ 1.1.1.3 root 8127: rest_zero = 0; 1.1.1.4 root 8128: if (nargs == 0 && i > 0) { 8129: if (! parse_error) 8130: error ("arguments given to macro `%s'", hp->name); 8131: } else if (i < nargs) { 1.1 root 8132: /* traditional C allows foo() if foo wants one argument. */ 8133: if (nargs == 1 && i == 0 && traditional) 8134: ; 1.1.1.3 root 8135: /* the rest args token is allowed to absorb 0 tokens */ 8136: else if (i == nargs - 1 && defn->rest_args) 8137: rest_zero = 1; 1.1.1.4 root 8138: else if (parse_error) 8139: ; 1.1 root 8140: else if (i == 0) 8141: error ("macro `%s' used without args", hp->name); 8142: else if (i == 1) 8143: error ("macro `%s' used with just one arg", hp->name); 8144: else 8145: error ("macro `%s' used with only %d args", hp->name, i); 1.1.1.4 root 8146: } else if (i > nargs) { 8147: if (! parse_error) 8148: error ("macro `%s' used with too many (%d) args", hp->name, i); 8149: } 1.1 root 8150: 8151: /* Swallow the closeparen. */ 8152: ++instack[indepth].bufp; 8153: 8154: /* If macro wants zero args, we parsed the arglist for checking only. 8155: Read directly from the macro definition. */ 8156: if (nargs == 0) { 8157: xbuf = defn->expansion; 8158: xbuf_len = defn->length; 8159: } else { 8160: register U_CHAR *exp = defn->expansion; 8161: register int offset; /* offset in expansion, 8162: copied a piece at a time */ 8163: register int totlen; /* total amount of exp buffer filled so far */ 8164: 1.1.1.3 root 8165: register struct reflist *ap, *last_ap; 1.1 root 8166: 8167: /* Macro really takes args. Compute the expansion of this call. */ 8168: 8169: /* Compute length in characters of the macro's expansion. 8170: Also count number of times each arg is used. */ 8171: xbuf_len = defn->length; 8172: for (ap = defn->pattern; ap != NULL; ap = ap->next) { 8173: if (ap->stringify) 8174: xbuf_len += args[ap->argno].stringified_length; 1.1.1.8 ! root 8175: else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional) 1.1.1.5 root 8176: /* Add 4 for two newline-space markers to prevent 8177: token concatenation. */ 8178: xbuf_len += args[ap->argno].raw_length + 4; 8179: else { 8180: /* We have an ordinary (expanded) occurrence of the arg. 8181: So compute its expansion, if we have not already. */ 8182: if (args[ap->argno].expanded == 0) { 8183: FILE_BUF obuf; 8184: obuf = expand_to_temp_buffer (args[ap->argno].raw, 8185: args[ap->argno].raw + args[ap->argno].raw_length, 8186: 1, 0); 8187: 8188: args[ap->argno].expanded = obuf.buf; 8189: args[ap->argno].expand_length = obuf.length; 8190: args[ap->argno].free2 = obuf.buf; 8191: } 8192: 8193: /* Add 4 for two newline-space markers to prevent 8194: token concatenation. */ 8195: xbuf_len += args[ap->argno].expand_length + 4; 8196: } 1.1 root 8197: if (args[ap->argno].use_count < 10) 8198: args[ap->argno].use_count++; 8199: } 8200: 8201: xbuf = (U_CHAR *) xmalloc (xbuf_len + 1); 8202: 8203: /* Generate in XBUF the complete expansion 8204: with arguments substituted in. 8205: TOTLEN is the total size generated so far. 8206: OFFSET is the index in the definition 8207: of where we are copying from. */ 8208: offset = totlen = 0; 1.1.1.3 root 8209: for (last_ap = NULL, ap = defn->pattern; ap != NULL; 8210: last_ap = ap, ap = ap->next) { 1.1 root 8211: register struct argdata *arg = &args[ap->argno]; 1.1.1.5 root 8212: int count_before = totlen; 1.1 root 8213: 1.1.1.5 root 8214: /* Add chars to XBUF. */ 1.1.1.3 root 8215: for (i = 0; i < ap->nchars; i++, offset++) 1.1.1.5 root 8216: xbuf[totlen++] = exp[offset]; 8217: 8218: /* If followed by an empty rest arg with concatenation, 8219: delete the last run of nonwhite chars. */ 8220: if (rest_zero && totlen > count_before 1.1.1.8 ! root 8221: && ((ap->rest_args && ap->raw_before != 0) 1.1.1.5 root 8222: || (last_ap != NULL && last_ap->rest_args 1.1.1.8 ! root 8223: && last_ap->raw_after != 0))) { 1.1.1.5 root 8224: /* Delete final whitespace. */ 8225: while (totlen > count_before && is_space[xbuf[totlen - 1]]) { 8226: totlen--; 8227: } 8228: 8229: /* Delete the nonwhites before them. */ 8230: while (totlen > count_before && ! is_space[xbuf[totlen - 1]]) { 8231: totlen--; 8232: } 8233: } 1.1 root 8234: 8235: if (ap->stringify != 0) { 8236: int arglen = arg->raw_length; 8237: int escaped = 0; 8238: int in_string = 0; 8239: int c; 8240: i = 0; 8241: while (i < arglen 8242: && (c = arg->raw[i], is_space[c])) 8243: i++; 8244: while (i < arglen 8245: && (c = arg->raw[arglen - 1], is_space[c])) 8246: arglen--; 8247: if (!traditional) 8248: xbuf[totlen++] = '\"'; /* insert beginning quote */ 8249: for (; i < arglen; i++) { 8250: c = arg->raw[i]; 8251: 8252: /* Special markers Newline Space 8253: generate nothing for a stringified argument. */ 8254: if (c == '\n' && arg->raw[i+1] != '\n') { 8255: i++; 8256: continue; 8257: } 8258: 8259: /* Internal sequences of whitespace are replaced by one space 8260: except within an string or char token. */ 8261: if (! in_string 8262: && (c == '\n' ? arg->raw[i+1] == '\n' : is_space[c])) { 8263: while (1) { 8264: /* Note that Newline Space does occur within whitespace 8265: sequences; consider it part of the sequence. */ 8266: if (c == '\n' && is_space[arg->raw[i+1]]) 8267: i += 2; 8268: else if (c != '\n' && is_space[c]) 8269: i++; 8270: else break; 8271: c = arg->raw[i]; 8272: } 8273: i--; 8274: c = ' '; 8275: } 8276: 8277: if (escaped) 8278: escaped = 0; 8279: else { 8280: if (c == '\\') 8281: escaped = 1; 8282: if (in_string) { 8283: if (c == in_string) 8284: in_string = 0; 8285: } else if (c == '\"' || c == '\'') 8286: in_string = c; 8287: } 8288: 8289: /* Escape these chars */ 8290: if (c == '\"' || (in_string && c == '\\')) 8291: xbuf[totlen++] = '\\'; 8292: if (isprint (c)) 8293: xbuf[totlen++] = c; 8294: else { 8295: sprintf ((char *) &xbuf[totlen], "\\%03o", (unsigned int) c); 8296: totlen += 4; 8297: } 8298: } 8299: if (!traditional) 8300: xbuf[totlen++] = '\"'; /* insert ending quote */ 1.1.1.8 ! root 8301: } else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional) { 1.1 root 8302: U_CHAR *p1 = arg->raw; 8303: U_CHAR *l1 = p1 + arg->raw_length; 1.1.1.8 ! root 8304: if (ap->raw_before != 0) { 1.1 root 8305: while (p1 != l1 && is_space[*p1]) p1++; 8306: while (p1 != l1 && is_idchar[*p1]) 8307: xbuf[totlen++] = *p1++; 8308: /* Delete any no-reexpansion marker that follows 8309: an identifier at the beginning of the argument 8310: if the argument is concatenated with what precedes it. */ 8311: if (p1[0] == '\n' && p1[1] == '-') 8312: p1 += 2; 1.1.1.5 root 8313: } else if (!traditional) { 8314: /* Ordinary expanded use of the argument. 8315: Put in newline-space markers to prevent token pasting. */ 8316: xbuf[totlen++] = '\n'; 8317: xbuf[totlen++] = ' '; 1.1 root 8318: } 1.1.1.8 ! root 8319: if (ap->raw_after != 0) { 1.1 root 8320: /* Arg is concatenated after: delete trailing whitespace, 8321: whitespace markers, and no-reexpansion markers. */ 8322: while (p1 != l1) { 8323: if (is_space[l1[-1]]) l1--; 8324: else if (l1[-1] == '-') { 8325: U_CHAR *p2 = l1 - 1; 8326: /* If a `-' is preceded by an odd number of newlines then it 8327: and the last newline are a no-reexpansion marker. */ 8328: while (p2 != p1 && p2[-1] == '\n') p2--; 8329: if ((l1 - 1 - p2) & 1) { 8330: l1 -= 2; 8331: } 8332: else break; 8333: } 8334: else break; 8335: } 8336: } 1.1.1.5 root 8337: 1.1.1.7 root 8338: bcopy ((char *) p1, (char *) (xbuf + totlen), l1 - p1); 1.1 root 8339: totlen += l1 - p1; 1.1.1.8 ! root 8340: if (!traditional && ap->raw_after == 0) { 1.1.1.5 root 8341: /* Ordinary expanded use of the argument. 8342: Put in newline-space markers to prevent token pasting. */ 8343: xbuf[totlen++] = '\n'; 8344: xbuf[totlen++] = ' '; 8345: } 1.1 root 8346: } else { 1.1.1.5 root 8347: /* Ordinary expanded use of the argument. 8348: Put in newline-space markers to prevent token pasting. */ 8349: if (!traditional) { 8350: xbuf[totlen++] = '\n'; 8351: xbuf[totlen++] = ' '; 8352: } 1.1.1.7 root 8353: bcopy ((char *) arg->expanded, (char *) (xbuf + totlen), 8354: arg->expand_length); 1.1 root 8355: totlen += arg->expand_length; 1.1.1.5 root 8356: if (!traditional) { 8357: xbuf[totlen++] = '\n'; 8358: xbuf[totlen++] = ' '; 8359: } 1.1 root 8360: /* If a macro argument with newlines is used multiple times, 8361: then only expand the newlines once. This avoids creating output 8362: lines which don't correspond to any input line, which confuses 8363: gdb and gcov. */ 8364: if (arg->use_count > 1 && arg->newlines > 0) { 1.1.1.5 root 8365: /* Don't bother doing change_newlines for subsequent 1.1 root 8366: uses of arg. */ 8367: arg->use_count = 1; 8368: arg->expand_length 1.1.1.5 root 8369: = change_newlines (arg->expanded, arg->expand_length); 1.1 root 8370: } 8371: } 8372: 8373: if (totlen > xbuf_len) 8374: abort (); 8375: } 8376: 8377: /* if there is anything left of the definition 8378: after handling the arg list, copy that in too. */ 8379: 1.1.1.3 root 8380: for (i = offset; i < defn->length; i++) { 8381: /* if we've reached the end of the macro */ 8382: if (exp[i] == ')') 8383: rest_zero = 0; 8384: if (! (rest_zero && last_ap != NULL && last_ap->rest_args 1.1.1.8 ! root 8385: && last_ap->raw_after != 0)) 1.1.1.3 root 8386: xbuf[totlen++] = exp[i]; 8387: } 1.1 root 8388: 8389: xbuf[totlen] = 0; 8390: xbuf_len = totlen; 8391: 8392: for (i = 0; i < nargs; i++) { 8393: if (args[i].free1 != 0) 8394: free (args[i].free1); 8395: if (args[i].free2 != 0) 8396: free (args[i].free2); 8397: } 8398: } 8399: } else { 8400: xbuf = defn->expansion; 8401: xbuf_len = defn->length; 8402: } 8403: 8404: /* Now put the expansion on the input stack 8405: so our caller will commence reading from it. */ 8406: { 8407: register FILE_BUF *ip2; 8408: 8409: ip2 = &instack[++indepth]; 8410: 8411: ip2->fname = 0; 8412: ip2->nominal_fname = 0; 1.1.1.7 root 8413: /* This may not be exactly correct, but will give much better error 8414: messages for nested macro calls than using a line number of zero. */ 8415: ip2->lineno = start_line; 1.1 root 8416: ip2->buf = xbuf; 8417: ip2->length = xbuf_len; 8418: ip2->bufp = xbuf; 8419: ip2->free_ptr = (nargs > 0) ? xbuf : 0; 8420: ip2->macro = hp; 8421: ip2->if_stack = if_stack; 8422: ip2->system_header_p = 0; 8423: 8424: /* Recursive macro use sometimes works traditionally. 1.1.1.5 root 8425: #define foo(x,y) bar (x (y,0), y) 8426: foo (foo, baz) */ 1.1 root 8427: 8428: if (!traditional) 8429: hp->type = T_DISABLED; 8430: } 8431: } 8432: 8433: /* 8434: * Parse a macro argument and store the info on it into *ARGPTR. 1.1.1.3 root 8435: * REST_ARGS is passed to macarg1 to make it absorb the rest of the args. 1.1 root 8436: * Return nonzero to indicate a syntax error. 8437: */ 8438: 8439: static char * 1.1.1.3 root 8440: macarg (argptr, rest_args) 1.1 root 8441: register struct argdata *argptr; 1.1.1.3 root 8442: int rest_args; 1.1 root 8443: { 8444: FILE_BUF *ip = &instack[indepth]; 8445: int paren = 0; 8446: int newlines = 0; 8447: int comments = 0; 1.1.1.8 ! root 8448: char *result = 0; 1.1 root 8449: 8450: /* Try to parse as much of the argument as exists at this 8451: input stack level. */ 8452: U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length, 1.1.1.3 root 8453: &paren, &newlines, &comments, rest_args); 1.1 root 8454: 8455: /* If we find the end of the argument at this level, 8456: set up *ARGPTR to point at it in the input stack. */ 8457: if (!(ip->fname != 0 && (newlines != 0 || comments != 0)) 8458: && bp != ip->buf + ip->length) { 8459: if (argptr != 0) { 8460: argptr->raw = ip->bufp; 8461: argptr->raw_length = bp - ip->bufp; 8462: argptr->newlines = newlines; 8463: } 8464: ip->bufp = bp; 8465: } else { 8466: /* This input stack level ends before the macro argument does. 8467: We must pop levels and keep parsing. 8468: Therefore, we must allocate a temporary buffer and copy 8469: the macro argument into it. */ 8470: int bufsize = bp - ip->bufp; 8471: int extra = newlines; 8472: U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1); 8473: int final_start = 0; 8474: 1.1.1.7 root 8475: bcopy ((char *) ip->bufp, (char *) buffer, bufsize); 1.1 root 8476: ip->bufp = bp; 8477: ip->lineno += newlines; 8478: 8479: while (bp == ip->buf + ip->length) { 8480: if (instack[indepth].macro == 0) { 1.1.1.8 ! root 8481: result = "unterminated macro call"; ! 8482: break; 1.1 root 8483: } 8484: ip->macro->type = T_MACRO; 8485: if (ip->free_ptr) 8486: free (ip->free_ptr); 8487: ip = &instack[--indepth]; 8488: newlines = 0; 8489: comments = 0; 8490: bp = macarg1 (ip->bufp, ip->buf + ip->length, &paren, 1.1.1.3 root 8491: &newlines, &comments, rest_args); 1.1 root 8492: final_start = bufsize; 8493: bufsize += bp - ip->bufp; 8494: extra += newlines; 8495: buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1); 1.1.1.7 root 8496: bcopy ((char *) ip->bufp, (char *) (buffer + bufsize - (bp - ip->bufp)), 8497: bp - ip->bufp); 1.1 root 8498: ip->bufp = bp; 8499: ip->lineno += newlines; 8500: } 8501: 8502: /* Now, if arg is actually wanted, record its raw form, 8503: discarding comments and duplicating newlines in whatever 8504: part of it did not come from a macro expansion. 8505: EXTRA space has been preallocated for duplicating the newlines. 8506: FINAL_START is the index of the start of that part. */ 8507: if (argptr != 0) { 8508: argptr->raw = buffer; 8509: argptr->raw_length = bufsize; 8510: argptr->free1 = buffer; 8511: argptr->newlines = newlines; 8512: if ((newlines || comments) && ip->fname != 0) 8513: argptr->raw_length 8514: = final_start + 8515: discard_comments (argptr->raw + final_start, 8516: argptr->raw_length - final_start, 8517: newlines); 8518: argptr->raw[argptr->raw_length] = 0; 8519: if (argptr->raw_length > bufsize + extra) 8520: abort (); 8521: } 8522: } 8523: 8524: /* If we are not discarding this argument, 8525: macroexpand it and compute its length as stringified. 8526: All this info goes into *ARGPTR. */ 8527: 8528: if (argptr != 0) { 8529: register U_CHAR *buf, *lim; 8530: register int totlen; 8531: 8532: buf = argptr->raw; 8533: lim = buf + argptr->raw_length; 8534: 8535: while (buf != lim && is_space[*buf]) 8536: buf++; 8537: while (buf != lim && is_space[lim[-1]]) 8538: lim--; 8539: totlen = traditional ? 0 : 2; /* Count opening and closing quote. */ 8540: while (buf != lim) { 8541: register U_CHAR c = *buf++; 8542: totlen++; 8543: /* Internal sequences of whitespace are replaced by one space 8544: in most cases, but not always. So count all the whitespace 8545: in case we need to keep it all. */ 8546: #if 0 8547: if (is_space[c]) 8548: SKIP_ALL_WHITE_SPACE (buf); 8549: else 8550: #endif 8551: if (c == '\"' || c == '\\') /* escape these chars */ 8552: totlen++; 8553: else if (!isprint (c)) 8554: totlen += 3; 8555: } 8556: argptr->stringified_length = totlen; 8557: } 1.1.1.8 ! root 8558: return result; 1.1 root 8559: } 8560: 8561: /* Scan text from START (inclusive) up to LIMIT (exclusive), 8562: counting parens in *DEPTHPTR, 8563: and return if reach LIMIT 8564: or before a `)' that would make *DEPTHPTR negative 8565: or before a comma when *DEPTHPTR is zero. 8566: Single and double quotes are matched and termination 8567: is inhibited within them. Comments also inhibit it. 8568: Value returned is pointer to stopping place. 8569: 8570: Increment *NEWLINES each time a newline is passed. 1.1.1.3 root 8571: REST_ARGS notifies macarg1 that it should absorb the rest of the args. 1.1 root 8572: Set *COMMENTS to 1 if a comment is seen. */ 8573: 8574: static U_CHAR * 1.1.1.3 root 8575: macarg1 (start, limit, depthptr, newlines, comments, rest_args) 1.1 root 8576: U_CHAR *start; 8577: register U_CHAR *limit; 8578: int *depthptr, *newlines, *comments; 1.1.1.3 root 8579: int rest_args; 1.1 root 8580: { 8581: register U_CHAR *bp = start; 8582: 8583: while (bp < limit) { 8584: switch (*bp) { 8585: case '(': 8586: (*depthptr)++; 8587: break; 8588: case ')': 8589: if (--(*depthptr) < 0) 8590: return bp; 8591: break; 8592: case '\\': 8593: /* Traditionally, backslash makes following char not special. */ 8594: if (bp + 1 < limit && traditional) 8595: { 8596: bp++; 8597: /* But count source lines anyway. */ 8598: if (*bp == '\n') 8599: ++*newlines; 8600: } 8601: break; 8602: case '\n': 8603: ++*newlines; 8604: break; 8605: case '/': 8606: if (bp[1] == '\\' && bp[2] == '\n') 8607: newline_fix (bp + 1); 1.1.1.4 root 8608: if (cplusplus_comments && bp[1] == '/') { 1.1 root 8609: *comments = 1; 8610: bp += 2; 1.1.1.7 root 8611: while (bp < limit && (*bp != '\n' || bp[-1] == '\\')) { 8612: if (*bp == '\n') ++*newlines; 8613: bp++; 8614: } 1.1.1.8 ! root 8615: /* Now count the newline that we are about to skip. */ ! 8616: ++*newlines; 1.1 root 8617: break; 8618: } 8619: if (bp[1] != '*' || bp + 1 >= limit) 8620: break; 8621: *comments = 1; 8622: bp += 2; 8623: while (bp + 1 < limit) { 8624: if (bp[0] == '*' 8625: && bp[1] == '\\' && bp[2] == '\n') 8626: newline_fix (bp + 1); 8627: if (bp[0] == '*' && bp[1] == '/') 8628: break; 8629: if (*bp == '\n') ++*newlines; 8630: bp++; 8631: } 8632: break; 8633: case '\'': 8634: case '\"': 8635: { 8636: int quotec; 8637: for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) { 8638: if (*bp == '\\') { 8639: bp++; 8640: if (*bp == '\n') 8641: ++*newlines; 8642: while (*bp == '\\' && bp[1] == '\n') { 8643: bp += 2; 8644: } 8645: } else if (*bp == '\n') { 8646: ++*newlines; 8647: if (quotec == '\'') 8648: break; 8649: } 8650: } 8651: } 8652: break; 8653: case ',': 1.1.1.3 root 8654: /* if we've returned to lowest level and we aren't absorbing all args */ 8655: if ((*depthptr) == 0 && rest_args == 0) 1.1 root 8656: return bp; 8657: break; 8658: } 8659: bp++; 8660: } 8661: 8662: return bp; 8663: } 8664: 8665: /* Discard comments and duplicate newlines 8666: in the string of length LENGTH at START, 8667: except inside of string constants. 8668: The string is copied into itself with its beginning staying fixed. 8669: 8670: NEWLINES is the number of newlines that must be duplicated. 8671: We assume that that much extra space is available past the end 8672: of the string. */ 8673: 8674: static int 8675: discard_comments (start, length, newlines) 8676: U_CHAR *start; 8677: int length; 8678: int newlines; 8679: { 8680: register U_CHAR *ibp; 8681: register U_CHAR *obp; 8682: register U_CHAR *limit; 8683: register int c; 8684: 8685: /* If we have newlines to duplicate, copy everything 8686: that many characters up. Then, in the second part, 8687: we will have room to insert the newlines 8688: while copying down. 8689: NEWLINES may actually be too large, because it counts 8690: newlines in string constants, and we don't duplicate those. 8691: But that does no harm. */ 8692: if (newlines > 0) { 8693: ibp = start + length; 8694: obp = ibp + newlines; 8695: limit = start; 8696: while (limit != ibp) 8697: *--obp = *--ibp; 8698: } 8699: 8700: ibp = start + newlines; 8701: limit = start + length + newlines; 8702: obp = start; 8703: 8704: while (ibp < limit) { 8705: *obp++ = c = *ibp++; 8706: switch (c) { 8707: case '\n': 8708: /* Duplicate the newline. */ 8709: *obp++ = '\n'; 8710: break; 8711: 8712: case '\\': 8713: if (*ibp == '\n') { 8714: obp--; 8715: ibp++; 8716: } 8717: break; 8718: 8719: case '/': 8720: if (*ibp == '\\' && ibp[1] == '\n') 8721: newline_fix (ibp); 8722: /* Delete any comment. */ 1.1.1.4 root 8723: if (cplusplus_comments && ibp[0] == '/') { 1.1.1.7 root 8724: /* Comments are equivalent to spaces. */ 8725: obp[-1] = ' '; 1.1 root 8726: ibp++; 1.1.1.7 root 8727: while (ibp < limit && (*ibp != '\n' || ibp[-1] == '\\')) 8728: ibp++; 1.1 root 8729: break; 8730: } 8731: if (ibp[0] != '*' || ibp + 1 >= limit) 8732: break; 1.1.1.8 ! root 8733: /* Comments are equivalent to spaces. ! 8734: For -traditional, a comment is equivalent to nothing. */ ! 8735: if (traditional) ! 8736: obp--; ! 8737: else ! 8738: obp[-1] = ' '; 1.1 root 8739: ibp++; 8740: while (ibp + 1 < limit) { 8741: if (ibp[0] == '*' 8742: && ibp[1] == '\\' && ibp[2] == '\n') 8743: newline_fix (ibp + 1); 8744: if (ibp[0] == '*' && ibp[1] == '/') 8745: break; 8746: ibp++; 8747: } 8748: ibp += 2; 8749: break; 8750: 8751: case '\'': 8752: case '\"': 8753: /* Notice and skip strings, so that we don't 8754: think that comments start inside them, 8755: and so we don't duplicate newlines in them. */ 8756: { 8757: int quotec = c; 8758: while (ibp < limit) { 8759: *obp++ = c = *ibp++; 8760: if (c == quotec) 8761: break; 8762: if (c == '\n' && quotec == '\'') 8763: break; 8764: if (c == '\\' && ibp < limit) { 8765: while (*ibp == '\\' && ibp[1] == '\n') 8766: ibp += 2; 8767: *obp++ = *ibp++; 8768: } 8769: } 8770: } 8771: break; 8772: } 8773: } 8774: 8775: return obp - start; 8776: } 8777: 1.1.1.5 root 8778: /* Turn newlines to spaces in the string of length LENGTH at START, 8779: except inside of string constants. 8780: The string is copied into itself with its beginning staying fixed. */ 1.1 root 8781: 8782: static int 1.1.1.5 root 8783: change_newlines (start, length) 1.1 root 8784: U_CHAR *start; 8785: int length; 8786: { 8787: register U_CHAR *ibp; 8788: register U_CHAR *obp; 8789: register U_CHAR *limit; 8790: register int c; 8791: 8792: ibp = start; 8793: limit = start + length; 8794: obp = start; 8795: 8796: while (ibp < limit) { 8797: *obp++ = c = *ibp++; 8798: switch (c) { 8799: case '\n': 8800: /* If this is a NEWLINE NEWLINE, then this is a real newline in the 1.1.1.5 root 8801: string. Skip past the newline and its duplicate. 8802: Put a space in the output. */ 1.1 root 8803: if (*ibp == '\n') 8804: { 8805: ibp++; 8806: obp--; 1.1.1.5 root 8807: *obp++ = ' '; 1.1 root 8808: } 8809: break; 8810: 8811: case '\'': 8812: case '\"': 8813: /* Notice and skip strings, so that we don't delete newlines in them. */ 8814: { 8815: int quotec = c; 8816: while (ibp < limit) { 8817: *obp++ = c = *ibp++; 8818: if (c == quotec) 8819: break; 8820: if (c == '\n' && quotec == '\'') 8821: break; 8822: } 8823: } 8824: break; 8825: } 8826: } 8827: 8828: return obp - start; 8829: } 8830: 8831: /* 1.1.1.7 root 8832: * my_strerror - return the descriptive text associated with an `errno' code. 8833: */ 8834: 8835: char * 8836: my_strerror (errnum) 8837: int errnum; 8838: { 8839: char *result; 8840: 8841: #ifndef VMS 8842: #ifndef HAVE_STRERROR 8843: result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0); 8844: #else 8845: result = strerror (errnum); 8846: #endif 8847: #else /* VMS */ 8848: /* VAXCRTL's strerror() takes an optional second argument, which only 8849: matters when the first argument is EVMSERR. However, it's simplest 8850: just to pass it unconditionally. `vaxc$errno' is declared in 8851: <errno.h>, and maintained by the library in parallel with `errno'. 8852: We assume that caller's `errnum' either matches the last setting of 8853: `errno' by the library or else does not have the value `EVMSERR'. */ 8854: 8855: result = strerror (errnum, vaxc$errno); 8856: #endif 8857: 8858: if (!result) 8859: result = "undocumented I/O error"; 8860: 8861: return result; 8862: } 8863: 8864: /* 1.1 root 8865: * error - print error message and increment count of errors. 8866: */ 8867: 8868: void 1.1.1.8 ! root 8869: error (PRINTF_ALIST (msg)) ! 8870: PRINTF_DCL (msg) ! 8871: { ! 8872: va_list args; ! 8873: ! 8874: VA_START (args, msg); ! 8875: verror (msg, args); ! 8876: va_end (args); ! 8877: } ! 8878: ! 8879: static void ! 8880: verror (msg, args) 1.1 root 8881: char *msg; 1.1.1.8 ! root 8882: va_list args; 1.1 root 8883: { 8884: int i; 8885: FILE_BUF *ip = NULL; 8886: 8887: print_containing_files (); 8888: 8889: for (i = indepth; i >= 0; i--) 8890: if (instack[i].fname != NULL) { 8891: ip = &instack[i]; 8892: break; 8893: } 8894: 8895: if (ip != NULL) 8896: fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno); 1.1.1.8 ! root 8897: vfprintf (stderr, msg, args); 1.1 root 8898: fprintf (stderr, "\n"); 8899: errors++; 8900: } 8901: 8902: /* Error including a message from `errno'. */ 8903: 8904: static void 8905: error_from_errno (name) 8906: char *name; 8907: { 8908: int i; 8909: FILE_BUF *ip = NULL; 8910: 8911: print_containing_files (); 8912: 8913: for (i = indepth; i >= 0; i--) 8914: if (instack[i].fname != NULL) { 8915: ip = &instack[i]; 8916: break; 8917: } 8918: 8919: if (ip != NULL) 8920: fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno); 8921: 1.1.1.7 root 8922: fprintf (stderr, "%s: %s\n", name, my_strerror (errno)); 1.1 root 8923: 8924: errors++; 8925: } 8926: 8927: /* Print error message but don't count it. */ 8928: 8929: void 1.1.1.8 ! root 8930: warning (PRINTF_ALIST (msg)) ! 8931: PRINTF_DCL (msg) ! 8932: { ! 8933: va_list args; ! 8934: ! 8935: VA_START (args, msg); ! 8936: vwarning (msg, args); ! 8937: va_end (args); ! 8938: } ! 8939: ! 8940: static void ! 8941: vwarning (msg, args) 1.1 root 8942: char *msg; 1.1.1.8 ! root 8943: va_list args; 1.1 root 8944: { 8945: int i; 8946: FILE_BUF *ip = NULL; 8947: 8948: if (inhibit_warnings) 8949: return; 8950: 8951: if (warnings_are_errors) 8952: errors++; 8953: 8954: print_containing_files (); 8955: 8956: for (i = indepth; i >= 0; i--) 8957: if (instack[i].fname != NULL) { 8958: ip = &instack[i]; 8959: break; 8960: } 8961: 8962: if (ip != NULL) 8963: fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno); 8964: fprintf (stderr, "warning: "); 1.1.1.8 ! root 8965: vfprintf (stderr, msg, args); 1.1 root 8966: fprintf (stderr, "\n"); 8967: } 8968: 8969: static void 1.1.1.8 ! root 8970: #if defined (__STDC__) && defined (HAVE_VPRINTF) ! 8971: error_with_line (int line, PRINTF_ALIST (msg)) ! 8972: #else ! 8973: error_with_line (line, PRINTF_ALIST (msg)) ! 8974: int line; ! 8975: PRINTF_DCL (msg) ! 8976: #endif ! 8977: { ! 8978: va_list args; ! 8979: ! 8980: VA_START (args, msg); ! 8981: verror_with_line (line, msg, args); ! 8982: va_end (args); ! 8983: } ! 8984: ! 8985: static void ! 8986: verror_with_line (line, msg, args) 1.1 root 8987: int line; 8988: char *msg; 1.1.1.8 ! root 8989: va_list args; 1.1 root 8990: { 8991: int i; 8992: FILE_BUF *ip = NULL; 8993: 8994: print_containing_files (); 8995: 8996: for (i = indepth; i >= 0; i--) 8997: if (instack[i].fname != NULL) { 8998: ip = &instack[i]; 8999: break; 9000: } 9001: 9002: if (ip != NULL) 9003: fprintf (stderr, "%s:%d: ", ip->nominal_fname, line); 1.1.1.8 ! root 9004: vfprintf (stderr, msg, args); 1.1 root 9005: fprintf (stderr, "\n"); 9006: errors++; 9007: } 9008: 1.1.1.5 root 9009: static void 1.1.1.8 ! root 9010: #if defined (__STDC__) && defined (HAVE_VPRINTF) ! 9011: warning_with_line (int line, PRINTF_ALIST (msg)) ! 9012: #else ! 9013: warning_with_line (line, PRINTF_ALIST (msg)) ! 9014: int line; ! 9015: PRINTF_DCL (msg) ! 9016: #endif ! 9017: { ! 9018: va_list args; ! 9019: ! 9020: VA_START (args, msg); ! 9021: vwarning_with_line (line, msg, args); ! 9022: va_end (args); ! 9023: } ! 9024: ! 9025: static void ! 9026: vwarning_with_line (line, msg, args) 1.1.1.5 root 9027: int line; 9028: char *msg; 1.1.1.8 ! root 9029: va_list args; 1.1.1.5 root 9030: { 9031: int i; 9032: FILE_BUF *ip = NULL; 9033: 9034: if (inhibit_warnings) 9035: return; 9036: 9037: if (warnings_are_errors) 9038: errors++; 9039: 9040: print_containing_files (); 9041: 9042: for (i = indepth; i >= 0; i--) 9043: if (instack[i].fname != NULL) { 9044: ip = &instack[i]; 9045: break; 9046: } 9047: 9048: if (ip != NULL) 1.1.1.8 ! root 9049: fprintf (stderr, line ? "%s:%d: " : "%s: ", ip->nominal_fname, line); 1.1.1.5 root 9050: fprintf (stderr, "warning: "); 1.1.1.8 ! root 9051: vfprintf (stderr, msg, args); 1.1.1.5 root 9052: fprintf (stderr, "\n"); 9053: } 9054: 1.1 root 9055: /* print an error message and maybe count it. */ 9056: 9057: void 1.1.1.8 ! root 9058: pedwarn (PRINTF_ALIST (msg)) ! 9059: PRINTF_DCL (msg) 1.1 root 9060: { 1.1.1.8 ! root 9061: va_list args; ! 9062: ! 9063: VA_START (args, msg); 1.1 root 9064: if (pedantic_errors) 1.1.1.8 ! root 9065: verror (msg, args); 1.1 root 9066: else 1.1.1.8 ! root 9067: vwarning (msg, args); ! 9068: va_end (args); 1.1 root 9069: } 9070: 1.1.1.5 root 9071: void 1.1.1.8 ! root 9072: #if defined (__STDC__) && defined (HAVE_VPRINTF) ! 9073: pedwarn_with_line (int line, PRINTF_ALIST (msg)) ! 9074: #else ! 9075: pedwarn_with_line (line, PRINTF_ALIST (msg)) 1.1.1.5 root 9076: int line; 1.1.1.8 ! root 9077: PRINTF_DCL (msg) ! 9078: #endif 1.1.1.5 root 9079: { 1.1.1.8 ! root 9080: va_list args; ! 9081: ! 9082: VA_START (args, msg); 1.1.1.5 root 9083: if (pedantic_errors) 1.1.1.8 ! root 9084: verror_with_line (line, msg, args); 1.1.1.5 root 9085: else 1.1.1.8 ! root 9086: vwarning_with_line (line, msg, args); ! 9087: va_end (args); 1.1.1.5 root 9088: } 9089: 1.1 root 9090: /* Report a warning (or an error if pedantic_errors) 9091: giving specified file name and line number, not current. */ 9092: 9093: static void 1.1.1.8 ! root 9094: #if defined (__STDC__) && defined (HAVE_VPRINTF) ! 9095: pedwarn_with_file_and_line (char *file, int line, PRINTF_ALIST (msg)) ! 9096: #else ! 9097: pedwarn_with_file_and_line (file, line, PRINTF_ALIST (msg)) 1.1 root 9098: char *file; 9099: int line; 1.1.1.8 ! root 9100: PRINTF_DCL (msg) ! 9101: #endif 1.1 root 9102: { 1.1.1.8 ! root 9103: va_list args; ! 9104: 1.1 root 9105: if (!pedantic_errors && inhibit_warnings) 9106: return; 9107: if (file != NULL) 9108: fprintf (stderr, "%s:%d: ", file, line); 1.1.1.5 root 9109: if (pedantic_errors) 1.1 root 9110: errors++; 9111: if (!pedantic_errors) 9112: fprintf (stderr, "warning: "); 1.1.1.8 ! root 9113: VA_START (args, msg); ! 9114: vfprintf (stderr, msg, args); ! 9115: va_end (args); 1.1 root 9116: fprintf (stderr, "\n"); 9117: } 9118: 9119: /* Print the file names and line numbers of the #include 1.1.1.8 ! root 9120: directives which led to the current file. */ 1.1 root 9121: 9122: static void 9123: print_containing_files () 9124: { 9125: FILE_BUF *ip = NULL; 9126: int i; 9127: int first = 1; 9128: 9129: /* If stack of files hasn't changed since we last printed 9130: this info, don't repeat it. */ 9131: if (last_error_tick == input_file_stack_tick) 9132: return; 9133: 9134: for (i = indepth; i >= 0; i--) 9135: if (instack[i].fname != NULL) { 9136: ip = &instack[i]; 9137: break; 9138: } 9139: 9140: /* Give up if we don't find a source file. */ 9141: if (ip == NULL) 9142: return; 9143: 9144: /* Find the other, outer source files. */ 9145: for (i--; i >= 0; i--) 9146: if (instack[i].fname != NULL) { 9147: ip = &instack[i]; 9148: if (first) { 9149: first = 0; 9150: fprintf (stderr, "In file included"); 9151: } else { 1.1.1.6 root 9152: fprintf (stderr, ",\n "); 1.1 root 9153: } 9154: 9155: fprintf (stderr, " from %s:%d", ip->nominal_fname, ip->lineno); 9156: } 9157: if (! first) 9158: fprintf (stderr, ":\n"); 9159: 9160: /* Record we have printed the status as of this time. */ 9161: last_error_tick = input_file_stack_tick; 9162: } 9163: 9164: /* Return the line at which an error occurred. 9165: The error is not necessarily associated with the current spot 9166: in the input stack, so LINE says where. LINE will have been 9167: copied from ip->lineno for the current input level. 9168: If the current level is for a file, we return LINE. 9169: But if the current level is not for a file, LINE is meaningless. 9170: In that case, we return the lineno of the innermost file. */ 9171: 9172: static int 9173: line_for_error (line) 9174: int line; 9175: { 9176: int i; 9177: int line1 = line; 9178: 9179: for (i = indepth; i >= 0; ) { 9180: if (instack[i].fname != 0) 9181: return line1; 9182: i--; 9183: if (i < 0) 9184: return 0; 9185: line1 = instack[i].lineno; 9186: } 9187: abort (); 9188: /*NOTREACHED*/ 9189: return 0; 9190: } 9191: 9192: /* 9193: * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger. 9194: * 9195: * As things stand, nothing is ever placed in the output buffer to be 9196: * removed again except when it's KNOWN to be part of an identifier, 9197: * so flushing and moving down everything left, instead of expanding, 9198: * should work ok. 9199: */ 9200: 9201: /* You might think void was cleaner for the return type, 9202: but that would get type mismatch in check_expand in strict ANSI. */ 9203: static int 9204: grow_outbuf (obuf, needed) 9205: register FILE_BUF *obuf; 9206: register int needed; 9207: { 9208: register U_CHAR *p; 9209: int minsize; 9210: 9211: if (obuf->length - (obuf->bufp - obuf->buf) > needed) 9212: return 0; 9213: 9214: /* Make it at least twice as big as it is now. */ 9215: obuf->length *= 2; 9216: /* Make it have at least 150% of the free space we will need. */ 9217: minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf); 9218: if (minsize > obuf->length) 9219: obuf->length = minsize; 9220: 9221: if ((p = (U_CHAR *) xrealloc (obuf->buf, obuf->length)) == NULL) 9222: memory_full (); 9223: 9224: obuf->bufp = p + (obuf->bufp - obuf->buf); 9225: obuf->buf = p; 9226: 9227: return 0; 9228: } 9229: 9230: /* Symbol table for macro names and special symbols */ 9231: 9232: /* 9233: * install a name in the main hash table, even if it is already there. 9234: * name stops with first non alphanumeric, except leading '#'. 9235: * caller must check against redefinition if that is desired. 9236: * delete_macro () removes things installed by install () in fifo order. 9237: * this is important because of the `defined' special symbol used 9238: * in #if, and also if pushdef/popdef directives are ever implemented. 9239: * 9240: * If LEN is >= 0, it is the length of the name. 9241: * Otherwise, compute the length by scanning the entire name. 9242: * 9243: * If HASH is >= 0, it is the precomputed hash code. 9244: * Otherwise, compute the hash code. 9245: */ 9246: static HASHNODE * 1.1.1.8 ! root 9247: install (name, len, type, value, hash) 1.1 root 9248: U_CHAR *name; 9249: int len; 9250: enum node_type type; 1.1.1.4 root 9251: char *value; 1.1 root 9252: int hash; 9253: { 9254: register HASHNODE *hp; 9255: register int i, bucket; 9256: register U_CHAR *p, *q; 9257: 9258: if (len < 0) { 9259: p = name; 9260: while (is_idchar[*p]) 9261: p++; 9262: len = p - name; 9263: } 9264: 9265: if (hash < 0) 9266: hash = hashf (name, len, HASHSIZE); 9267: 9268: i = sizeof (HASHNODE) + len + 1; 9269: hp = (HASHNODE *) xmalloc (i); 9270: bucket = hash; 9271: hp->bucket_hdr = &hashtab[bucket]; 9272: hp->next = hashtab[bucket]; 9273: hashtab[bucket] = hp; 9274: hp->prev = NULL; 9275: if (hp->next != NULL) 9276: hp->next->prev = hp; 9277: hp->type = type; 9278: hp->length = len; 1.1.1.8 ! root 9279: hp->value.cpval = value; 1.1 root 9280: hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE); 9281: p = hp->name; 9282: q = name; 9283: for (i = 0; i < len; i++) 9284: *p++ = *q++; 9285: hp->name[len] = 0; 9286: return hp; 9287: } 9288: 9289: /* 9290: * find the most recent hash node for name name (ending with first 9291: * non-identifier char) installed by install 9292: * 9293: * If LEN is >= 0, it is the length of the name. 9294: * Otherwise, compute the length by scanning the entire name. 9295: * 9296: * If HASH is >= 0, it is the precomputed hash code. 9297: * Otherwise, compute the hash code. 9298: */ 9299: HASHNODE * 9300: lookup (name, len, hash) 9301: U_CHAR *name; 9302: int len; 9303: int hash; 9304: { 9305: register U_CHAR *bp; 9306: register HASHNODE *bucket; 9307: 9308: if (len < 0) { 9309: for (bp = name; is_idchar[*bp]; bp++) ; 9310: len = bp - name; 9311: } 9312: 9313: if (hash < 0) 9314: hash = hashf (name, len, HASHSIZE); 9315: 9316: bucket = hashtab[hash]; 9317: while (bucket) { 1.1.1.8 ! root 9318: if (bucket->length == len && bcmp (bucket->name, name, len) == 0) 1.1 root 9319: return bucket; 9320: bucket = bucket->next; 9321: } 9322: return NULL; 9323: } 9324: 9325: /* 9326: * Delete a hash node. Some weirdness to free junk from macros. 9327: * More such weirdness will have to be added if you define more hash 9328: * types that need it. 9329: */ 9330: 9331: /* Note that the DEFINITION of a macro is removed from the hash table 9332: but its storage is not freed. This would be a storage leak 9333: except that it is not reasonable to keep undefining and redefining 9334: large numbers of macros many times. 9335: In any case, this is necessary, because a macro can be #undef'd 9336: in the middle of reading the arguments to a call to it. 9337: If #undef freed the DEFINITION, that would crash. */ 9338: 9339: static void 9340: delete_macro (hp) 9341: HASHNODE *hp; 9342: { 9343: 9344: if (hp->prev != NULL) 9345: hp->prev->next = hp->next; 9346: if (hp->next != NULL) 9347: hp->next->prev = hp->prev; 9348: 9349: /* make sure that the bucket chain header that 9350: the deleted guy was on points to the right thing afterwards. */ 9351: if (hp == *hp->bucket_hdr) 9352: *hp->bucket_hdr = hp->next; 9353: 9354: #if 0 9355: if (hp->type == T_MACRO) { 9356: DEFINITION *d = hp->value.defn; 9357: struct reflist *ap, *nextap; 9358: 9359: for (ap = d->pattern; ap != NULL; ap = nextap) { 9360: nextap = ap->next; 9361: free (ap); 9362: } 9363: free (d); 9364: } 9365: #endif 9366: free (hp); 9367: } 9368: 9369: /* 9370: * return hash function on name. must be compatible with the one 9371: * computed a step at a time, elsewhere 9372: */ 9373: static int 9374: hashf (name, len, hashsize) 9375: register U_CHAR *name; 9376: register int len; 9377: int hashsize; 9378: { 9379: register int r = 0; 9380: 9381: while (len--) 9382: r = HASHSTEP (r, *name++); 9383: 9384: return MAKE_POS (r) % hashsize; 9385: } 9386: 9387: 9388: /* Dump the definition of a single macro HP to OF. */ 9389: static void 9390: dump_single_macro (hp, of) 9391: register HASHNODE *hp; 9392: FILE *of; 9393: { 9394: register DEFINITION *defn = hp->value.defn; 9395: struct reflist *ap; 9396: int offset; 9397: int concat; 9398: 9399: 9400: /* Print the definition of the macro HP. */ 9401: 9402: fprintf (of, "#define %s", hp->name); 9403: 9404: if (defn->nargs >= 0) { 9405: int i; 9406: 9407: fprintf (of, "("); 9408: for (i = 0; i < defn->nargs; i++) { 9409: dump_arg_n (defn, i, of); 9410: if (i + 1 < defn->nargs) 9411: fprintf (of, ", "); 9412: } 9413: fprintf (of, ")"); 9414: } 9415: 9416: fprintf (of, " "); 9417: 9418: offset = 0; 9419: concat = 0; 9420: for (ap = defn->pattern; ap != NULL; ap = ap->next) { 9421: dump_defn_1 (defn->expansion, offset, ap->nchars, of); 9422: offset += ap->nchars; 1.1.1.7 root 9423: if (!traditional) { 9424: if (ap->nchars != 0) 9425: concat = 0; 1.1.1.8 ! root 9426: if (ap->stringify) { ! 9427: switch (ap->stringify) { ! 9428: case SHARP_TOKEN: fprintf (of, "#"); break; ! 9429: case WHITE_SHARP_TOKEN: fprintf (of, "# "); break; ! 9430: case PERCENT_COLON_TOKEN: fprintf (of, "%%:"); break; ! 9431: case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%%: "); break; ! 9432: default: abort (); ! 9433: } ! 9434: } ! 9435: if (ap->raw_before != 0) { ! 9436: if (concat) { ! 9437: switch (ap->raw_before) { ! 9438: case WHITE_SHARP_TOKEN: ! 9439: case WHITE_PERCENT_COLON_TOKEN: ! 9440: fprintf (of, " "); ! 9441: break; ! 9442: default: ! 9443: break; ! 9444: } ! 9445: } else { ! 9446: switch (ap->raw_before) { ! 9447: case SHARP_TOKEN: fprintf (of, "##"); break; ! 9448: case WHITE_SHARP_TOKEN: fprintf (of, "## "); break; ! 9449: case PERCENT_COLON_TOKEN: fprintf (of, "%%:%%:"); break; ! 9450: case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%%:%%: "); break; ! 9451: default: abort (); ! 9452: } ! 9453: } ! 9454: } 1.1.1.7 root 9455: concat = 0; 9456: } 1.1 root 9457: dump_arg_n (defn, ap->argno, of); 1.1.1.8 ! root 9458: if (!traditional && ap->raw_after != 0) { ! 9459: switch (ap->raw_after) { ! 9460: case SHARP_TOKEN: fprintf (of, "##"); break; ! 9461: case WHITE_SHARP_TOKEN: fprintf (of, " ##"); break; ! 9462: case PERCENT_COLON_TOKEN: fprintf (of, "%%:%%:"); break; ! 9463: case WHITE_PERCENT_COLON_TOKEN: fprintf (of, " %%:%%:"); break; ! 9464: default: abort (); ! 9465: } 1.1 root 9466: concat = 1; 9467: } 9468: } 9469: dump_defn_1 (defn->expansion, offset, defn->length - offset, of); 9470: fprintf (of, "\n"); 9471: } 9472: 9473: /* Dump all macro definitions as #defines to stdout. */ 9474: 9475: static void 9476: dump_all_macros () 9477: { 9478: int bucket; 9479: 9480: for (bucket = 0; bucket < HASHSIZE; bucket++) { 9481: register HASHNODE *hp; 9482: 9483: for (hp = hashtab[bucket]; hp; hp= hp->next) { 9484: if (hp->type == T_MACRO) 9485: dump_single_macro (hp, stdout); 9486: } 9487: } 9488: } 9489: 9490: /* Output to OF a substring of a macro definition. 9491: BASE is the beginning of the definition. 9492: Output characters START thru LENGTH. 1.1.1.7 root 9493: Unless traditional, discard newlines outside of strings, thus 1.1 root 9494: converting funny-space markers to ordinary spaces. */ 9495: 9496: static void 9497: dump_defn_1 (base, start, length, of) 9498: U_CHAR *base; 9499: int start; 9500: int length; 9501: FILE *of; 9502: { 9503: U_CHAR *p = base + start; 9504: U_CHAR *limit = base + start + length; 9505: 1.1.1.7 root 9506: if (traditional) 9507: fwrite (p, sizeof (*p), length, of); 9508: else { 9509: while (p < limit) { 9510: if (*p == '\"' || *p =='\'') { 9511: U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR, 9512: NULL_PTR, NULL_PTR); 9513: fwrite (p, sizeof (*p), p1 - p, of); 9514: p = p1; 9515: } else { 9516: if (*p != '\n') 9517: putc (*p, of); 9518: p++; 9519: } 1.1 root 9520: } 9521: } 9522: } 9523: 9524: /* Print the name of argument number ARGNUM of macro definition DEFN 9525: to OF. 9526: Recall that DEFN->args.argnames contains all the arg names 9527: concatenated in reverse order with comma-space in between. */ 9528: 9529: static void 9530: dump_arg_n (defn, argnum, of) 9531: DEFINITION *defn; 9532: int argnum; 9533: FILE *of; 9534: { 9535: register U_CHAR *p = defn->args.argnames; 9536: while (argnum + 1 < defn->nargs) { 1.1.1.8 ! root 9537: p = (U_CHAR *) index ((char *) p, ' ') + 1; 1.1 root 9538: argnum++; 9539: } 9540: 9541: while (*p && *p != ',') { 9542: putc (*p, of); 9543: p++; 9544: } 9545: } 9546: 9547: /* Initialize syntactic classifications of characters. */ 9548: 9549: static void 9550: initialize_char_syntax () 9551: { 9552: register int i; 9553: 9554: /* 9555: * Set up is_idchar and is_idstart tables. These should be 9556: * faster than saying (is_alpha (c) || c == '_'), etc. 9557: * Set up these things before calling any routines tthat 9558: * refer to them. 9559: */ 9560: for (i = 'a'; i <= 'z'; i++) { 9561: is_idchar[i - 'a' + 'A'] = 1; 9562: is_idchar[i] = 1; 9563: is_idstart[i - 'a' + 'A'] = 1; 9564: is_idstart[i] = 1; 9565: } 9566: for (i = '0'; i <= '9'; i++) 9567: is_idchar[i] = 1; 9568: is_idchar['_'] = 1; 9569: is_idstart['_'] = 1; 9570: is_idchar['$'] = dollars_in_ident; 9571: is_idstart['$'] = dollars_in_ident; 9572: 9573: /* horizontal space table */ 9574: is_hor_space[' '] = 1; 9575: is_hor_space['\t'] = 1; 9576: is_hor_space['\v'] = 1; 9577: is_hor_space['\f'] = 1; 9578: is_hor_space['\r'] = 1; 9579: 9580: is_space[' '] = 1; 9581: is_space['\t'] = 1; 9582: is_space['\v'] = 1; 9583: is_space['\f'] = 1; 9584: is_space['\n'] = 1; 9585: is_space['\r'] = 1; 1.1.1.8 ! root 9586: ! 9587: char_name['\v'] = "vertical tab"; ! 9588: char_name['\f'] = "formfeed"; ! 9589: char_name['\r'] = "carriage return"; 1.1 root 9590: } 9591: 9592: /* Initialize the built-in macros. */ 9593: 9594: static void 9595: initialize_builtins (inp, outp) 9596: FILE_BUF *inp; 9597: FILE_BUF *outp; 9598: { 1.1.1.8 ! root 9599: install ((U_CHAR *) "__LINE__", -1, T_SPECLINE, NULL_PTR, -1); ! 9600: install ((U_CHAR *) "__DATE__", -1, T_DATE, NULL_PTR, -1); ! 9601: install ((U_CHAR *) "__FILE__", -1, T_FILE, NULL_PTR, -1); ! 9602: install ((U_CHAR *) "__BASE_FILE__", -1, T_BASE_FILE, NULL_PTR, -1); ! 9603: install ((U_CHAR *) "__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, NULL_PTR, -1); ! 9604: install ((U_CHAR *) "__VERSION__", -1, T_VERSION, NULL_PTR, -1); 1.1.1.5 root 9605: #ifndef NO_BUILTIN_SIZE_TYPE 1.1.1.8 ! root 9606: install ((U_CHAR *) "__SIZE_TYPE__", -1, T_SIZE_TYPE, NULL_PTR, -1); 1.1.1.5 root 9607: #endif 9608: #ifndef NO_BUILTIN_PTRDIFF_TYPE 1.1.1.8 ! root 9609: install ((U_CHAR *) "__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, NULL_PTR, -1); 1.1.1.5 root 9610: #endif 1.1.1.8 ! root 9611: install ((U_CHAR *) "__WCHAR_TYPE__", -1, T_WCHAR_TYPE, NULL_PTR, -1); ! 9612: install ((U_CHAR *) "__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE, ! 9613: NULL_PTR, -1); ! 9614: install ((U_CHAR *) "__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE, ! 9615: NULL_PTR, -1); ! 9616: install ((U_CHAR *) "__IMMEDIATE_PREFIX__", -1, T_IMMEDIATE_PREFIX_TYPE, ! 9617: NULL_PTR, -1); ! 9618: install ((U_CHAR *) "__TIME__", -1, T_TIME, NULL_PTR, -1); ! 9619: if (!traditional) { ! 9620: install ((U_CHAR *) "__STDC__", -1, T_CONST, "1", -1); ! 9621: install ((U_CHAR *) "__STDC_VERSION__", -1, T_CONST, "199409L", -1); ! 9622: } 1.1 root 9623: if (objc) 1.1.1.8 ! root 9624: install ((U_CHAR *) "__OBJC__", -1, T_CONST, "1", -1); 1.1 root 9625: /* This is supplied using a -D by the compiler driver 9626: so that it is present only when truly compiling with GNU C. */ 1.1.1.8 ! root 9627: /* install ((U_CHAR *) "__GNUC__", -1, T_CONST, "2", -1); */ 1.1 root 9628: 9629: if (debug_output) 9630: { 9631: char directive[2048]; 1.1.1.8 ! root 9632: U_CHAR *udirective = (U_CHAR *) directive; 1.1 root 9633: register struct directive *dp = &directive_table[0]; 1.1.1.3 root 9634: struct tm *timebuf = timestamp (); 1.1 root 9635: 1.1.1.3 root 9636: sprintf (directive, " __BASE_FILE__ \"%s\"\n", 1.1 root 9637: instack[0].nominal_fname); 1.1.1.8 ! root 9638: output_line_directive (inp, outp, 0, same_file); ! 9639: pass_thru_directive (udirective, &udirective[strlen (directive)], ! 9640: outp, dp); 1.1 root 9641: 1.1.1.3 root 9642: sprintf (directive, " __VERSION__ \"%s\"\n", version_string); 1.1.1.8 ! root 9643: output_line_directive (inp, outp, 0, same_file); ! 9644: pass_thru_directive (udirective, &udirective[strlen (directive)], ! 9645: outp, dp); 1.1 root 9646: 1.1.1.6 root 9647: #ifndef NO_BUILTIN_SIZE_TYPE 1.1.1.3 root 9648: sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE); 1.1.1.8 ! root 9649: output_line_directive (inp, outp, 0, same_file); ! 9650: pass_thru_directive (udirective, &udirective[strlen (directive)], ! 9651: outp, dp); 1.1.1.6 root 9652: #endif 1.1 root 9653: 1.1.1.6 root 9654: #ifndef NO_BUILTIN_PTRDIFF_TYPE 1.1.1.3 root 9655: sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE); 1.1.1.8 ! root 9656: output_line_directive (inp, outp, 0, same_file); ! 9657: pass_thru_directive (udirective, &udirective[strlen (directive)], ! 9658: outp, dp); 1.1.1.6 root 9659: #endif 1.1 root 9660: 1.1.1.7 root 9661: sprintf (directive, " __WCHAR_TYPE__ %s\n", wchar_type); 1.1.1.8 ! root 9662: output_line_directive (inp, outp, 0, same_file); ! 9663: pass_thru_directive (udirective, &udirective[strlen (directive)], ! 9664: outp, dp); 1.1 root 9665: 1.1.1.3 root 9666: sprintf (directive, " __DATE__ \"%s %2d %4d\"\n", 1.1 root 9667: monthnames[timebuf->tm_mon], 9668: timebuf->tm_mday, timebuf->tm_year + 1900); 1.1.1.8 ! root 9669: output_line_directive (inp, outp, 0, same_file); ! 9670: pass_thru_directive (udirective, &udirective[strlen (directive)], ! 9671: outp, dp); 1.1 root 9672: 1.1.1.3 root 9673: sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n", 1.1 root 9674: timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec); 1.1.1.8 ! root 9675: output_line_directive (inp, outp, 0, same_file); ! 9676: pass_thru_directive (udirective, &udirective[strlen (directive)], ! 9677: outp, dp); 1.1 root 9678: 9679: if (!traditional) 9680: { 9681: sprintf (directive, " __STDC__ 1"); 1.1.1.8 ! root 9682: output_line_directive (inp, outp, 0, same_file); ! 9683: pass_thru_directive (udirective, &udirective[strlen (directive)], 1.1 root 9684: outp, dp); 9685: } 9686: if (objc) 9687: { 9688: sprintf (directive, " __OBJC__ 1"); 1.1.1.8 ! root 9689: output_line_directive (inp, outp, 0, same_file); ! 9690: pass_thru_directive (udirective, &udirective[strlen (directive)], 1.1 root 9691: outp, dp); 9692: } 9693: } 9694: } 9695: 9696: /* 9697: * process a given definition string, for initialization 9698: * If STR is just an identifier, define it with value 1. 9699: * If STR has anything after the identifier, then it should 9700: * be identifier=definition. 9701: */ 9702: 9703: static void 9704: make_definition (str, op) 1.1.1.8 ! root 9705: char *str; 1.1 root 9706: FILE_BUF *op; 9707: { 9708: FILE_BUF *ip; 9709: struct directive *kt; 9710: U_CHAR *buf, *p; 9711: 1.1.1.8 ! root 9712: p = buf = (U_CHAR *) str; 1.1 root 9713: if (!is_idstart[*p]) { 9714: error ("malformed option `-D %s'", str); 9715: return; 9716: } 9717: while (is_idchar[*++p]) 9718: ; 1.1.1.7 root 9719: if (*p == '(') { 9720: while (is_idchar[*++p] || *p == ',' || is_hor_space[*p]) 9721: ; 9722: if (*p++ != ')') 1.1.1.8 ! root 9723: p = (U_CHAR *) str; /* Error */ 1.1.1.7 root 9724: } 1.1 root 9725: if (*p == 0) { 9726: buf = (U_CHAR *) alloca (p - buf + 4); 9727: strcpy ((char *)buf, str); 9728: strcat ((char *)buf, " 1"); 9729: } else if (*p != '=') { 9730: error ("malformed option `-D %s'", str); 9731: return; 9732: } else { 9733: U_CHAR *q; 9734: /* Copy the entire option so we can modify it. */ 9735: buf = (U_CHAR *) alloca (2 * strlen (str) + 1); 1.1.1.8 ! root 9736: strncpy ((char *) buf, str, p - (U_CHAR *) str); 1.1 root 9737: /* Change the = to a space. */ 1.1.1.8 ! root 9738: buf[p - (U_CHAR *) str] = ' '; 1.1 root 9739: /* Scan for any backslash-newline and remove it. */ 9740: p++; 1.1.1.8 ! root 9741: q = &buf[p - (U_CHAR *) str]; 1.1 root 9742: while (*p) { 1.1.1.7 root 9743: if (*p == '\"' || *p == '\'') { 9744: int unterminated = 0; 1.1.1.8 ! root 9745: U_CHAR *p1 = skip_quoted_string (p, p + strlen ((char *) p), 0, 1.1.1.7 root 9746: NULL_PTR, NULL_PTR, &unterminated); 9747: if (unterminated) 9748: return; 9749: while (p != p1) 9750: if (*p == '\\' && p[1] == '\n') 9751: p += 2; 9752: else 9753: *q++ = *p++; 9754: } else if (*p == '\\' && p[1] == '\n') 1.1 root 9755: p += 2; 9756: /* Change newline chars into newline-markers. */ 9757: else if (*p == '\n') 9758: { 9759: *q++ = '\n'; 9760: *q++ = '\n'; 9761: p++; 9762: } 9763: else 9764: *q++ = *p++; 9765: } 9766: *q = 0; 9767: } 9768: 9769: ip = &instack[++indepth]; 9770: ip->nominal_fname = ip->fname = "*Initialization*"; 9771: 9772: ip->buf = ip->bufp = buf; 1.1.1.8 ! root 9773: ip->length = strlen ((char *) buf); 1.1 root 9774: ip->lineno = 1; 9775: ip->macro = 0; 9776: ip->free_ptr = 0; 9777: ip->if_stack = if_stack; 9778: ip->system_header_p = 0; 9779: 9780: for (kt = directive_table; kt->type != T_DEFINE; kt++) 9781: ; 9782: 1.1.1.5 root 9783: /* Pass NULL instead of OP, since this is a "predefined" macro. */ 1.1.1.8 ! root 9784: do_define (buf, buf + strlen ((char *) buf), NULL_PTR, kt); 1.1 root 9785: --indepth; 9786: } 9787: 9788: /* JF, this does the work for the -U option */ 9789: 9790: static void 9791: make_undef (str, op) 1.1.1.8 ! root 9792: char *str; 1.1 root 9793: FILE_BUF *op; 9794: { 9795: FILE_BUF *ip; 9796: struct directive *kt; 9797: 9798: ip = &instack[++indepth]; 9799: ip->nominal_fname = ip->fname = "*undef*"; 9800: 1.1.1.8 ! root 9801: ip->buf = ip->bufp = (U_CHAR *) str; 1.1 root 9802: ip->length = strlen (str); 9803: ip->lineno = 1; 9804: ip->macro = 0; 9805: ip->free_ptr = 0; 9806: ip->if_stack = if_stack; 9807: ip->system_header_p = 0; 9808: 9809: for (kt = directive_table; kt->type != T_UNDEF; kt++) 9810: ; 9811: 1.1.1.8 ! root 9812: do_undef ((U_CHAR *) str, (U_CHAR *) str + strlen (str), op, kt); 1.1 root 9813: --indepth; 9814: } 9815: 9816: /* Process the string STR as if it appeared as the body of a #assert. 9817: OPTION is the option name for which STR was the argument. */ 9818: 9819: static void 9820: make_assertion (option, str) 9821: char *option; 1.1.1.8 ! root 9822: char *str; 1.1 root 9823: { 9824: FILE_BUF *ip; 9825: struct directive *kt; 9826: U_CHAR *buf, *p, *q; 9827: 9828: /* Copy the entire option so we can modify it. */ 9829: buf = (U_CHAR *) alloca (strlen (str) + 1); 9830: strcpy ((char *) buf, str); 9831: /* Scan for any backslash-newline and remove it. */ 9832: p = q = buf; 9833: while (*p) { 9834: if (*p == '\\' && p[1] == '\n') 9835: p += 2; 9836: else 9837: *q++ = *p++; 9838: } 9839: *q = 0; 9840: 9841: p = buf; 9842: if (!is_idstart[*p]) { 9843: error ("malformed option `%s %s'", option, str); 9844: return; 9845: } 9846: while (is_idchar[*++p]) 9847: ; 1.1.1.8 ! root 9848: SKIP_WHITE_SPACE (p); 1.1 root 9849: if (! (*p == 0 || *p == '(')) { 9850: error ("malformed option `%s %s'", option, str); 9851: return; 9852: } 9853: 9854: ip = &instack[++indepth]; 9855: ip->nominal_fname = ip->fname = "*Initialization*"; 9856: 9857: ip->buf = ip->bufp = buf; 1.1.1.8 ! root 9858: ip->length = strlen ((char *) buf); 1.1 root 9859: ip->lineno = 1; 9860: ip->macro = 0; 9861: ip->free_ptr = 0; 9862: ip->if_stack = if_stack; 9863: ip->system_header_p = 0; 9864: 9865: for (kt = directive_table; kt->type != T_ASSERT; kt++) 9866: ; 9867: 9868: /* pass NULL as output ptr to do_define since we KNOW it never 9869: does any output.... */ 1.1.1.8 ! root 9870: do_assert (buf, buf + strlen ((char *) buf) , NULL_PTR, kt); 1.1 root 9871: --indepth; 9872: } 9873: 1.1.1.4 root 9874: /* Append a chain of `struct file_name_list's 9875: to the end of the main include chain. 9876: FIRST is the beginning of the chain to append, and LAST is the end. */ 9877: 9878: static void 9879: append_include_chain (first, last) 9880: struct file_name_list *first, *last; 9881: { 9882: struct file_name_list *dir; 9883: 9884: if (!first || !last) 9885: return; 9886: 9887: if (include == 0) 9888: include = first; 9889: else 9890: last_include->next = first; 9891: 9892: if (first_bracket_include == 0) 9893: first_bracket_include = first; 9894: 9895: for (dir = first; ; dir = dir->next) { 9896: int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE; 9897: if (len > max_include_len) 9898: max_include_len = len; 9899: if (dir == last) 9900: break; 9901: } 9902: 9903: last->next = NULL; 9904: last_include = last; 9905: } 9906: 1.1 root 9907: /* Add output to `deps_buffer' for the -M switch. 9908: STRING points to the text to be output. 1.1.1.8 ! root 9909: SPACER is ':' for targets, ' ' for dependencies. */ 1.1 root 9910: 9911: static void 1.1.1.7 root 9912: deps_output (string, spacer) 1.1 root 9913: char *string; 1.1.1.7 root 9914: int spacer; 1.1 root 9915: { 1.1.1.7 root 9916: int size = strlen (string); 9917: 1.1 root 9918: if (size == 0) 1.1.1.7 root 9919: return; 1.1 root 9920: 9921: #ifndef MAX_OUTPUT_COLUMNS 1.1.1.7 root 9922: #define MAX_OUTPUT_COLUMNS 72 1.1 root 9923: #endif 1.1.1.8 ! root 9924: if (MAX_OUTPUT_COLUMNS - 1 /*spacer*/ - 2 /*` \'*/ < deps_column + size ! 9925: && 1 < deps_column) { ! 9926: bcopy (" \\\n ", &deps_buffer[deps_size], 4); ! 9927: deps_size += 4; ! 9928: deps_column = 1; ! 9929: if (spacer == ' ') ! 9930: spacer = 0; 1.1 root 9931: } 9932: 1.1.1.7 root 9933: if (deps_size + size + 8 > deps_allocated_size) { 9934: deps_allocated_size = (deps_size + size + 50) * 2; 1.1.1.8 ! root 9935: deps_buffer = xrealloc (deps_buffer, deps_allocated_size); 1.1 root 9936: } 1.1.1.8 ! root 9937: if (spacer == ' ') { 1.1.1.7 root 9938: deps_buffer[deps_size++] = ' '; 1.1.1.8 ! root 9939: deps_column++; ! 9940: } 1.1 root 9941: bcopy (string, &deps_buffer[deps_size], size); 9942: deps_size += size; 9943: deps_column += size; 1.1.1.8 ! root 9944: if (spacer == ':') { 1.1.1.7 root 9945: deps_buffer[deps_size++] = ':'; 1.1.1.8 ! root 9946: deps_column++; ! 9947: } 1.1 root 9948: deps_buffer[deps_size] = 0; 9949: } 9950: 9951: static void 1.1.1.8 ! root 9952: fatal (PRINTF_ALIST (msg)) ! 9953: PRINTF_DCL (msg) 1.1 root 9954: { 1.1.1.8 ! root 9955: va_list args; ! 9956: 1.1 root 9957: fprintf (stderr, "%s: ", progname); 1.1.1.8 ! root 9958: VA_START (args, msg); ! 9959: vfprintf (stderr, msg, args); ! 9960: va_end (args); 1.1 root 9961: fprintf (stderr, "\n"); 1.1.1.8 ! root 9962: exit (FATAL_EXIT_CODE); 1.1 root 9963: } 9964: 9965: /* More 'friendly' abort that prints the line and file. 9966: config.h can #define abort fancy_abort if you like that sort of thing. */ 9967: 9968: void 9969: fancy_abort () 9970: { 9971: fatal ("Internal gcc abort."); 9972: } 9973: 9974: static void 9975: perror_with_name (name) 9976: char *name; 9977: { 9978: fprintf (stderr, "%s: ", progname); 1.1.1.7 root 9979: fprintf (stderr, "%s: %s\n", name, my_strerror (errno)); 1.1 root 9980: errors++; 9981: } 9982: 9983: static void 9984: pfatal_with_name (name) 9985: char *name; 9986: { 9987: perror_with_name (name); 9988: #ifdef VMS 9989: exit (vaxc$errno); 9990: #else 1.1.1.8 ! root 9991: exit (FATAL_EXIT_CODE); 1.1 root 9992: #endif 9993: } 9994: 1.1.1.5 root 9995: /* Handler for SIGPIPE. */ 9996: 9997: static void 9998: pipe_closed (signo) 9999: /* If this is missing, some compilers complain. */ 10000: int signo; 10001: { 10002: fatal ("output pipe has been closed"); 10003: } 1.1 root 10004: 10005: static void 10006: memory_full () 10007: { 10008: fatal ("Memory exhausted."); 10009: } 10010: 10011: 1.1.1.8 ! root 10012: GENERIC_PTR 1.1 root 10013: xmalloc (size) 1.1.1.8 ! root 10014: size_t size; 1.1 root 10015: { 1.1.1.8 ! root 10016: register GENERIC_PTR ptr = (GENERIC_PTR) malloc (size); ! 10017: if (!ptr) ! 10018: memory_full (); ! 10019: return ptr; 1.1 root 10020: } 10021: 1.1.1.8 ! root 10022: static GENERIC_PTR 1.1 root 10023: xrealloc (old, size) 1.1.1.8 ! root 10024: GENERIC_PTR old; ! 10025: size_t size; 1.1 root 10026: { 1.1.1.8 ! root 10027: register GENERIC_PTR ptr = (GENERIC_PTR) realloc (old, size); ! 10028: if (!ptr) ! 10029: memory_full (); ! 10030: return ptr; 1.1 root 10031: } 10032: 1.1.1.8 ! root 10033: static GENERIC_PTR 1.1 root 10034: xcalloc (number, size) 1.1.1.8 ! root 10035: size_t number, size; 1.1 root 10036: { 1.1.1.8 ! root 10037: register size_t total = number * size; ! 10038: register GENERIC_PTR ptr = (GENERIC_PTR) malloc (total); ! 10039: if (!ptr) ! 10040: memory_full (); ! 10041: bzero (ptr, total); ! 10042: return ptr; 1.1 root 10043: } 10044: 10045: static char * 10046: savestring (input) 10047: char *input; 10048: { 1.1.1.8 ! root 10049: size_t size = strlen (input); 1.1 root 10050: char *output = xmalloc (size + 1); 10051: strcpy (output, input); 10052: return output; 10053: } 10054: 10055: /* Get the file-mode and data size of the file open on FD 10056: and store them in *MODE_POINTER and *SIZE_POINTER. */ 10057: 10058: static int 10059: file_size_and_mode (fd, mode_pointer, size_pointer) 10060: int fd; 10061: int *mode_pointer; 10062: long int *size_pointer; 10063: { 10064: struct stat sbuf; 10065: 10066: if (fstat (fd, &sbuf) < 0) return (-1); 10067: if (mode_pointer) *mode_pointer = sbuf.st_mode; 10068: if (size_pointer) *size_pointer = sbuf.st_size; 10069: return 0; 10070: } 10071: 10072: #ifdef VMS 10073: 10074: /* Under VMS we need to fix up the "include" specification 10075: filename so that everything following the 1st slash is 10076: changed into its correct VMS file specification. */ 10077: 10078: static void 10079: hack_vms_include_specification (fname) 10080: char *fname; 10081: { 10082: register char *cp, *cp1, *cp2; 10083: int f, check_filename_before_returning, no_prefix_seen; 10084: char Local[512]; 10085: 10086: check_filename_before_returning = 0; 10087: no_prefix_seen = 0; 10088: 10089: /* Ignore leading "./"s */ 10090: while (fname[0] == '.' && fname[1] == '/') { 10091: strcpy (fname, fname+2); 10092: no_prefix_seen = 1; /* mark this for later */ 10093: } 10094: /* Look for the boundary between the VMS and UNIX filespecs */ 10095: cp = rindex (fname, ']'); /* Look for end of dirspec. */ 10096: if (cp == 0) cp = rindex (fname, '>'); /* ... Ditto */ 10097: if (cp == 0) cp = rindex (fname, ':'); /* Look for end of devspec. */ 10098: if (cp) { 10099: cp++; 10100: } else { 10101: cp = index (fname, '/'); /* Look for the "/" */ 10102: } 10103: 1.1.1.7 root 10104: /* 10105: * Check if we have a vax-c style '#include filename' 10106: * and add the missing .h 10107: */ 10108: if (cp == 0) { 10109: if (index(fname,'.') == 0) 10110: strcat(fname, ".h"); 10111: } else { 10112: if (index(cp,'.') == 0) 10113: strcat(cp, ".h"); 10114: } 10115: 1.1 root 10116: cp2 = Local; /* initialize */ 10117: 10118: /* We are trying to do a number of things here. First of all, we are 10119: trying to hammer the filenames into a standard format, such that later 10120: processing can handle them. 10121: 10122: If the file name contains something like [dir.], then it recognizes this 10123: as a root, and strips the ".]". Later processing will add whatever is 10124: needed to get things working properly. 10125: 10126: If no device is specified, then the first directory name is taken to be 10127: a device name (or a rooted logical). */ 10128: 10129: /* See if we found that 1st slash */ 10130: if (cp == 0) return; /* Nothing to do!!! */ 10131: if (*cp != '/') return; /* Nothing to do!!! */ 10132: /* Point to the UNIX filename part (which needs to be fixed!) */ 10133: cp1 = cp+1; 10134: /* If the directory spec is not rooted, we can just copy 10135: the UNIX filename part and we are done */ 10136: if (((cp - fname) > 1) && ((cp[-1] == ']') || (cp[-1] == '>'))) { 10137: if (cp[-2] != '.') { 10138: /* 1.1.1.2 root 10139: * The VMS part ends in a `]', and the preceding character is not a `.'. 1.1 root 10140: * We strip the `]', and then splice the two parts of the name in the 10141: * usual way. Given the default locations for include files in cccp.c, 10142: * we will only use this code if the user specifies alternate locations 10143: * with the /include (-I) switch on the command line. */ 10144: cp -= 1; /* Strip "]" */ 10145: cp1--; /* backspace */ 10146: } else { 10147: /* 10148: * The VMS part has a ".]" at the end, and this will not do. Later 10149: * processing will add a second directory spec, and this would be a syntax 10150: * error. Thus we strip the ".]", and thus merge the directory specs. 10151: * We also backspace cp1, so that it points to a '/'. This inhibits the 10152: * generation of the 000000 root directory spec (which does not belong here 10153: * in this case). 10154: */ 10155: cp -= 2; /* Strip ".]" */ 10156: cp1--; }; /* backspace */ 10157: } else { 10158: 10159: /* We drop in here if there is no VMS style directory specification yet. 10160: * If there is no device specification either, we make the first dir a 10161: * device and try that. If we do not do this, then we will be essentially 10162: * searching the users default directory (as if they did a #include "asdf.h"). 10163: * 10164: * Then all we need to do is to push a '[' into the output string. Later 10165: * processing will fill this in, and close the bracket. 10166: */ 1.1.1.5 root 10167: if (cp[-1] != ':') *cp2++ = ':'; /* dev not in spec. take first dir */ 1.1 root 10168: *cp2++ = '['; /* Open the directory specification */ 10169: } 10170: 10171: /* at this point we assume that we have the device spec, and (at least 10172: the opening "[" for a directory specification. We may have directories 10173: specified already */ 10174: 10175: /* If there are no other slashes then the filename will be 10176: in the "root" directory. Otherwise, we need to add 10177: directory specifications. */ 10178: if (index (cp1, '/') == 0) { 10179: /* Just add "000000]" as the directory string */ 10180: strcpy (cp2, "000000]"); 10181: cp2 += strlen (cp2); 10182: check_filename_before_returning = 1; /* we might need to fool with this later */ 10183: } else { 10184: /* As long as there are still subdirectories to add, do them. */ 10185: while (index (cp1, '/') != 0) { 10186: /* If this token is "." we can ignore it */ 10187: if ((cp1[0] == '.') && (cp1[1] == '/')) { 10188: cp1 += 2; 10189: continue; 10190: } 10191: /* Add a subdirectory spec. Do not duplicate "." */ 10192: if (cp2[-1] != '.' && cp2[-1] != '[' && cp2[-1] != '<') 10193: *cp2++ = '.'; 10194: /* If this is ".." then the spec becomes "-" */ 10195: if ((cp1[0] == '.') && (cp1[1] == '.') && (cp[2] == '/')) { 10196: /* Add "-" and skip the ".." */ 10197: *cp2++ = '-'; 10198: cp1 += 3; 10199: continue; 10200: } 10201: /* Copy the subdirectory */ 10202: while (*cp1 != '/') *cp2++= *cp1++; 10203: cp1++; /* Skip the "/" */ 10204: } 10205: /* Close the directory specification */ 1.1.1.5 root 10206: if (cp2[-1] == '.') /* no trailing periods */ 1.1 root 10207: cp2--; 10208: *cp2++ = ']'; 10209: } 10210: /* Now add the filename */ 10211: while (*cp1) *cp2++ = *cp1++; 10212: *cp2 = 0; 10213: /* Now append it to the original VMS spec. */ 10214: strcpy (cp, Local); 10215: 10216: /* If we put a [000000] in the filename, try to open it first. If this fails, 10217: remove the [000000], and return that name. This provides flexibility 10218: to the user in that they can use both rooted and non-rooted logical names 10219: to point to the location of the file. */ 10220: 10221: if (check_filename_before_returning && no_prefix_seen) { 10222: f = open (fname, O_RDONLY, 0666); 10223: if (f >= 0) { 10224: /* The file name is OK as it is, so return it as is. */ 10225: close (f); 10226: return; 10227: } 10228: /* The filename did not work. Try to remove the [000000] from the name, 10229: and return it. */ 10230: cp = index (fname, '['); 10231: cp2 = index (fname, ']') + 1; 10232: strcpy (cp, cp2); /* this gets rid of it */ 10233: } 10234: return; 10235: } 10236: #endif /* VMS */ 10237: 10238: #ifdef VMS 10239: 10240: /* These are the read/write replacement routines for 10241: VAX-11 "C". They make read/write behave enough 10242: like their UNIX counterparts that CCCP will work */ 10243: 10244: static int 10245: read (fd, buf, size) 10246: int fd; 10247: char *buf; 10248: int size; 10249: { 10250: #undef read /* Get back the REAL read routine */ 10251: register int i; 10252: register int total = 0; 10253: 10254: /* Read until the buffer is exhausted */ 10255: while (size > 0) { 10256: /* Limit each read to 32KB */ 10257: i = (size > (32*1024)) ? (32*1024) : size; 10258: i = read (fd, buf, i); 10259: if (i <= 0) { 10260: if (i == 0) return (total); 1.1.1.5 root 10261: return (i); 1.1 root 10262: } 10263: /* Account for this read */ 10264: total += i; 10265: buf += i; 10266: size -= i; 10267: } 10268: return (total); 10269: } 10270: 10271: static int 10272: write (fd, buf, size) 10273: int fd; 10274: char *buf; 10275: int size; 10276: { 10277: #undef write /* Get back the REAL write routine */ 10278: int i; 10279: int j; 10280: 10281: /* Limit individual writes to 32Kb */ 10282: i = size; 10283: while (i > 0) { 10284: j = (i > (32*1024)) ? (32*1024) : i; 10285: if (write (fd, buf, j) < 0) return (-1); 10286: /* Account for the data written */ 10287: buf += j; 10288: i -= j; 10289: } 10290: return (size); 10291: } 10292: 10293: /* The following wrapper functions supply additional arguments to the VMS 10294: I/O routines to optimize performance with file handling. The arguments 10295: are: 10296: "mbc=16" - Set multi-block count to 16 (use a 8192 byte buffer). 10297: "deq=64" - When extending the file, extend it in chunks of 32Kbytes. 10298: "fop=tef"- Truncate unused portions of file when closing file. 10299: "shr=nil"- Disallow file sharing while file is open. 10300: */ 10301: 10302: static FILE * 10303: freopen (fname, type, oldfile) 10304: char *fname; 10305: char *type; 10306: FILE *oldfile; 10307: { 10308: #undef freopen /* Get back the REAL fopen routine */ 10309: if (strcmp (type, "w") == 0) 10310: return freopen (fname, type, oldfile, "mbc=16", "deq=64", "fop=tef", "shr=nil"); 10311: return freopen (fname, type, oldfile, "mbc=16"); 10312: } 10313: 10314: static FILE * 10315: fopen (fname, type) 10316: char *fname; 10317: char *type; 10318: { 10319: #undef fopen /* Get back the REAL fopen routine */ 1.1.1.8 ! root 10320: /* The gcc-vms-1.42 distribution's header files prototype fopen with two ! 10321: fixed arguments, which matches ANSI's specification but not VAXCRTL's ! 10322: pre-ANSI implementation. This hack circumvents the mismatch problem. */ ! 10323: FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen; ! 10324: ! 10325: if (*type == 'w') ! 10326: return (*vmslib_fopen) (fname, type, "mbc=32", ! 10327: "deq=64", "fop=tef", "shr=nil"); ! 10328: else ! 10329: return (*vmslib_fopen) (fname, type, "mbc=32"); 1.1 root 10330: } 10331: 10332: static int 10333: open (fname, flags, prot) 10334: char *fname; 10335: int flags; 10336: int prot; 10337: { 10338: #undef open /* Get back the REAL open routine */ 10339: return open (fname, flags, prot, "mbc=16", "deq=64", "fop=tef"); 10340: } 10341: 1.1.1.4 root 10342: /* Avoid run-time library bug, where copying M out of N+M characters with 10343: N >= 65535 results in VAXCRTL's strncat falling into an infinite loop. 1.1.1.8 ! root 10344: gcc-cpp exercises this particular bug. [Fixed in V5.5-2's VAXCRTL.] */ 1.1.1.4 root 10345: 10346: static char * 10347: strncat (dst, src, cnt) 10348: char *dst; 10349: const char *src; 10350: unsigned cnt; 10351: { 10352: register char *d = dst, *s = (char *) src; 10353: register int n = cnt; /* convert to _signed_ type */ 10354: 10355: while (*d) d++; /* advance to end */ 10356: while (--n >= 0) 10357: if (!(*d++ = *s++)) break; 10358: if (n < 0) *d = '\0'; 10359: return dst; 10360: } 1.1.1.8 ! root 10361: ! 10362: /* more VMS hackery */ ! 10363: #include <fab.h> ! 10364: #include <nam.h> ! 10365: ! 10366: extern unsigned long sys$parse(), sys$search(); ! 10367: ! 10368: /* Work around another library bug. If a file is located via a searchlist, ! 10369: and if the device it's on is not the same device as the one specified ! 10370: in the first element of that searchlist, then both stat() and fstat() ! 10371: will fail to return info about it. `errno' will be set to EVMSERR, and ! 10372: `vaxc$errno' will be set to SS$_NORMAL due yet another bug in stat()! ! 10373: We can get around this by fully parsing the filename and then passing ! 10374: that absolute name to stat(). ! 10375: ! 10376: Without this fix, we can end up failing to find header files, which is ! 10377: bad enough, but then compounding the problem by reporting the reason for ! 10378: failure as "normal successful completion." */ ! 10379: ! 10380: #undef fstat /* get back to library version */ ! 10381: ! 10382: static int ! 10383: VMS_fstat (fd, statbuf) ! 10384: int fd; ! 10385: struct stat *statbuf; ! 10386: { ! 10387: int result = fstat (fd, statbuf); ! 10388: ! 10389: if (result < 0) ! 10390: { ! 10391: FILE *fp; ! 10392: char nambuf[NAM$C_MAXRSS+1]; ! 10393: ! 10394: if ((fp = fdopen (fd, "r")) != 0 && fgetname (fp, nambuf) != 0) ! 10395: result = VMS_stat (nambuf, statbuf); ! 10396: /* No fclose(fp) here; that would close(fd) as well. */ ! 10397: } ! 10398: ! 10399: return result; ! 10400: } ! 10401: ! 10402: static int ! 10403: VMS_stat (name, statbuf) ! 10404: const char *name; ! 10405: struct stat *statbuf; ! 10406: { ! 10407: int result = stat (name, statbuf); ! 10408: ! 10409: if (result < 0) ! 10410: { ! 10411: struct FAB fab; ! 10412: struct NAM nam; ! 10413: char exp_nam[NAM$C_MAXRSS+1], /* expanded name buffer for sys$parse */ ! 10414: res_nam[NAM$C_MAXRSS+1]; /* resultant name buffer for sys$search */ ! 10415: ! 10416: fab = cc$rms_fab; ! 10417: fab.fab$l_fna = (char *) name; ! 10418: fab.fab$b_fns = (unsigned char) strlen (name); ! 10419: fab.fab$l_nam = (void *) &nam; ! 10420: nam = cc$rms_nam; ! 10421: nam.nam$l_esa = exp_nam, nam.nam$b_ess = sizeof exp_nam - 1; ! 10422: nam.nam$l_rsa = res_nam, nam.nam$b_rss = sizeof res_nam - 1; ! 10423: nam.nam$b_nop = NAM$M_PWD | NAM$M_NOCONCEAL; ! 10424: if (sys$parse (&fab) & 1) ! 10425: { ! 10426: if (sys$search (&fab) & 1) ! 10427: { ! 10428: res_nam[nam.nam$b_rsl] = '\0'; ! 10429: result = stat (res_nam, statbuf); ! 10430: } ! 10431: /* Clean up searchlist context cached by the system. */ ! 10432: nam.nam$b_nop = NAM$M_SYNCHK; ! 10433: fab.fab$l_fna = 0, fab.fab$b_fns = 0; ! 10434: (void) sys$parse (&fab); ! 10435: } ! 10436: } ! 10437: ! 10438: return result; ! 10439: } 1.1 root 10440: #endif /* VMS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.