1# This is a shell archive. Save it in a file, remove anything before 2# this line, and then unpack it by entering "sh file". Note, it may 3# create directories; files and directories will be owned by you and 4# have default permissions. 5# 6# This archive contains: 7# 8# cpp1.c 9# cpp3.c 10# cpp4.c 11# 12echo x - cpp1.c 13sed 's/^X//' >cpp1.c << 'END-of-cpp1.c' 14X/* 15X * CPP main program. 16X * 17X * Edit history 18X * 21-May-84 MM "Field test" release 19X * 23-May-84 MM Some minor hacks. 20X * 30-May-84 ARF Didn't get enough memory for __DATE__ 21X * Added code to read stdin if no input 22X * files are provided. 23X * 29-Jun-84 MM Added ARF's suggestions, Unixifying cpp. 24X * 11-Jul-84 MM "Official" first release (that's what I thought!) 25X * 22-Jul-84 MM/ARF/SCK Fixed line number bugs, added cpp recognition 26X * of #line, fixed problems with #include. 27X * 23-Jul-84 MM More (minor) include hacking, some documentation. 28X * Also, redid cpp's #include files 29X * 25-Jul-84 MM #line filename isn't used for #include searchlist 30X * #line format is <number> <optional name> 31X * 25-Jul-84 ARF/MM Various bugs, mostly serious. Removed homemade doprint 32X * 01-Aug-84 MM Fixed recursion bug, remove extra newlines and 33X * leading whitespace from cpp output. 34X * 02-Aug-84 MM Hacked (i.e. optimized) out blank lines and unneeded 35X * whitespace in general. Cleaned up unget()'s. 36X * 03-Aug-84 Keie Several bug fixes from Ed Keizer, Vrije Universitet. 37X * -- corrected arg. count in -D and pre-defined 38X * macros. Also, allow \n inside macro actual parameter 39X * lists. 40X * 06-Aug-84 MM If debugging, dump the preset vector at startup. 41X * 12-Aug-84 MM/SCK Some small changes from Sam Kendall 42X * 15-Aug-84 Keie/MM cerror, cwarn, etc. take a single string arg. 43X * cierror, etc. take a single int. arg. 44X * changed LINE_PREFIX slightly so it can be 45X * changed in the makefile. 46X * 31-Aug-84 MM USENET net.sources release. 47X * 7-Sep-84 SCH/ado Lint complaints 48X * 10-Sep-84 Keie Char's can't be signed in some implementations 49X * 11-Sep-84 ado Added -C flag, pathological line number fix 50X * 13-Sep-84 ado Added -E flag (does nothing) and "-" file for stdin. 51X * 14-Sep-84 MM Allow # 123 as a synonym for #line 123 52X * 19-Sep-84 MM scanid always reads to token, make sure #line is 53X * written to a new line, even if -C switch given. 54X * Also, cpp - - reads stdin, writes stdout. 55X * 03-Oct-84 ado/MM Several changes to line counting and keepcomments 56X * stuff. Also a rewritten control() hasher -- much 57X * simpler and no less "perfect". Note also changes 58X * in cpp3.c to fix numeric scanning. 59X * 04-Oct-84 MM Added recognition of macro formal parameters if 60X * they are the only thing in a string, per the 61X * draft standard. 62X * 08-Oct-84 MM One more attack on scannumber 63X * 15-Oct-84 MM/ado Added -N to disable predefined symbols. Fixed 64X * linecount if COMMENT_INVISIBLE enabled. 65X * 22-Oct-84 MM Don't evaluate the #if/#ifdef argument if 66X * compilation is supressed. This prevents 67X * unnecessary error messages in sequences such as 68X * #ifdef FOO -- undefined 69X * #if FOO == 10 -- shouldn't print warning 70X * 25-Oct-84 MM Fixed bug in false ifdef supression. On vms, 71X * #include <foo> should open foo.h -- this duplicates 72X * the behavior of Vax-C 73X * 31-Oct-84 ado/MM Parametized $ in indentifiers. Added a better 74X * token concatenator and took out the trial 75X * concatenation code. Also improved #ifdef code 76X * and cleaned up the macro recursion tester. 77X * 2-Nov-84 MM/ado Some bug fixes in token concatenation, also 78X * a variety of minor (uninteresting) hacks. 79X * 6-Nov-84 MM Happy Birthday. Broke into 4 files and added 80X * #if sizeof (basic_types) 81X * 9-Nov-84 MM Added -S* for pointer type sizes 82X * 13-Nov-84 MM Split cpp1.c, added vms defaulting 83X * 23-Nov-84 MM/ado -E supresses error exit, added CPP_INCLUDE, 84X * fixed strncpy bug. 85X * 3-Dec-84 ado/MM Added OLD_PREPROCESSOR 86X * 7-Dec-84 MM Stuff in Nov 12 Draft Standard 87X * 17-Dec-84 george Fixed problems with recursive macros 88X * 17-Dec-84 MM Yet another attack on #if's (f/t)level removed. 89X * 07-Jan-85 ado Init defines before doing command line options 90X * so -Uunix works. 91X */ 92X 93X/*)BUILD 94X $(PROGRAM) = cpp 95X $(FILES) = { cpp1 cpp2 cpp3 cpp4 cpp5 cpp6 } 96X $(INCLUDE) = { cppdef.h cpp.h } 97X $(STACK) = 2000 98X $(TKBOPTIONS) = { 99X STACK = 2000 100X } 101X*/ 102X 103X#ifdef DOCUMENTATION 104X 105Xtitle cpp C Pre-Processor 106Xindex C pre-processor 107X 108Xsynopsis 109X .s.nf 110X cpp [-options] [infile [outfile]] 111X .s.f 112Xdescription 113X 114X CPP reads a C source file, expands macros and include 115X files, and writes an input file for the C compiler. 116X If no file arguments are given, CPP reads from stdin 117X and writes to stdout. If one file argument is given, 118X it will define the input file, while two file arguments 119X define both input and output files. The file name "-" 120X is a synonym for stdin or stdout as appropriate. 121X 122X The following options are supported. Options may 123X be given in either case. 124X .lm +16 125X .p -16 126X -C If set, source-file comments are written 127X to the output file. This allows the output of CPP to be 128X used as the input to a program, such as lint, that expects 129X commands embedded in specially-formatted comments. 130X .p -16 131X -Dname=value Define the name as if the programmer wrote 132X 133X #define name value 134X 135X at the start of the first file. If "=value" is not 136X given, a value of "1" will be used. 137X 138X On non-unix systems, all alphabetic text will be forced 139X to upper-case. 140X .p -16 141X -E Always return "success" to the operating 142X system, even if errors were detected. Note that some fatal 143X errors, such as a missing #include file, will terminate 144X CPP, returning "failure" even if the -E option is given. 145X .p -16 146X -Idirectory Add this directory to the list of 147X directories searched for #include "..." and #include <...> 148X commands. Note that there is no space between the 149X "-I" and the directory string. More than one -I command 150X is permitted. On non-Unix systems "directory" is forced 151X to upper-case. 152X .p -16 153X -N CPP normally predefines some symbols defining 154X the target computer and operating system. If -N is specified, 155X no symbols will be predefined. If -N -N is specified, the 156X "always present" symbols, __LINE__, __FILE__, and __DATE__ 157X are not defined. 158X .p -16 159X -Stext CPP normally assumes that the size of 160X the target computer's basic variable types is the same as the size 161X of these types of the host computer. (This can be overridden 162X when CPP is compiled, however.) The -S option allows dynamic 163X respecification of these values. "text" is a string of 164X numbers, separated by commas, that specifies correct sizes. 165X The sizes must be specified in the exact order: 166X 167X char short int long float double 168X 169X If you specify the option as "-S*text", pointers to these 170X types will be specified. -S* takes one additional argument 171X for pointer to function (e.g. int (*)()) 172X 173X For example, to specify sizes appropriate for a PDP-11, 174X you would write: 175X 176X c s i l f d func 177X -S1,2,2,2,4,8, 178X -S*2,2,2,2,2,2,2 179X 180X Note that all values must be specified. 181X .p -16 182X -Uname Undefine the name as if 183X 184X #undef name 185X 186X were given. On non-Unix systems, "name" will be forced to 187X upper-case. 188X .p -16 189X -Xnumber Enable debugging code. If no value is 190X given, a value of 1 will be used. (For maintenence of 191X CPP only.) 192X .s.lm -16 193X 194XPre-Defined Variables 195X 196X When CPP begins processing, the following variables will 197X have been defined (unless the -N option is specified): 198X .s 199X Target computer (as appropriate): 200X .s 201X pdp11, vax, M68000 m68000 m68k 202X .s 203X Target operating system (as appropriate): 204X .s 205X rsx, rt11, vms, unix 206X .s 207X Target compiler (as appropriate): 208X .s 209X decus, vax11c 210X .s 211X The implementor may add definitions to this list. 212X The default definitions match the definition of the 213X host computer, operating system, and C compiler. 214X .s 215X The following are always available unless undefined (or 216X -N was specified twice): 217X .lm +16 218X .p -12 219X __FILE__ The input (or #include) file being compiled 220X (as a quoted string). 221X .p -12 222X __LINE__ The line number being compiled. 223X .p -12 224X __DATE__ The date and time of compilation as 225X a Unix ctime quoted string (the trailing newline is removed). 226X Thus, 227X .s 228X printf("Bug at line %s,", __LINE__); 229X printf(" source file %s", __FILE__); 230X printf(" compiled on %s", __DATE__); 231X .s.lm -16 232X 233XDraft Proposed Ansi Standard Considerations 234X 235X The current version of the Draft Proposed Standard 236X explicitly states that "readers are requested not to specify 237X or claim conformance to this draft." Readers and users 238X of Decus CPP should not assume that Decus CPP conforms 239X to the standard, or that it will conform to the actual 240X C Language Standard. 241X 242X When CPP is itself compiled, many features of the Draft 243X Proposed Standard that are incompatible with existing 244X preprocessors may be disabled. See the comments in CPP's 245X source for details. 246X 247X The latest version of the Draft Proposed Standard (as reflected 248X in Decus CPP) is dated November 12, 1984. 249X 250X Comments are removed from the input text. The comment 251X is replaced by a single space character. The -C option 252X preserves comments, writing them to the output file. 253X 254X The '$' character is considered to be a letter. This is 255X a permitted extension. 256X 257X The following new features of C are processed by CPP: 258X .s.comment Note: significant spaces, not tabs, .br quotes #if, #elif 259X .br;####_#elif expression (_#else _#if) 260X .br;####'_\xNNN' (Hexadecimal constant) 261X .br;####'_\a' (Ascii BELL) 262X .br;####'_\v' (Ascii Vertical Tab) 263X .br;####_#if defined NAME 1 if defined, 0 if not 264X .br;####_#if defined (NAME) 1 if defined, 0 if not 265X .br;####_#if sizeof (basic type) 266X .br;####unary + 267X .br;####123U, 123LU Unsigned ints and longs. 268X .br;####12.3L Long double numbers 269X .br;####token_#token Token concatenation 270X .br;####_#include token Expands to filename 271X 272X The Draft Proposed Standard has extended C, adding a constant 273X string concatenation operator, where 274X 275X "foo" "bar" 276X 277X is regarded as the single string "foobar". (This does not 278X affect CPP's processing but does permit a limited form of 279X macro argument substitution into strings as will be discussed.) 280X 281X The Standard Committee plans to add token concatenation 282X to #define command lines. One suggested implementation 283X is as follows: the sequence "Token1#Token2" is treated 284X as if the programmer wrote "Token1Token2". This could 285X be used as follows: 286X 287X #line 123 288X #define ATLINE foo#__LINE__ 289X 290X ATLINE would be defined as foo123. 291X 292X Note that "Token2" must either have the format of an 293X identifier or be a string of digits. Thus, the string 294X 295X #define ATLINE foo#1x3 296X 297X generates two tokens: "foo1" and "x3". 298X 299X If the tokens T1 and T2 are concatenated into T3, 300X this implementation operates as follows: 301X 302X 1. Expand T1 if it is a macro. 303X 2. Expand T2 if it is a macro. 304X 3. Join the tokens, forming T3. 305X 4. Expand T3 if it is a macro. 306X 307X A macro formal parameter will be substituted into a string 308X or character constant if it is the only component of that 309X constant: 310X 311X #define VECSIZE 123 312X #define vprint(name, size) \ 313X printf("name" "[" "size" "] = {\n") 314X ... vprint(vector, VECSIZE); 315X 316X expands (effectively) to 317X 318X vprint("vector[123] = {\n"); 319X 320X Note that this will be useful if your C compiler supports 321X the new string concatenation operation noted above. 322X As implemented here, if you write 323X 324X #define string(arg) "arg" 325X ... string("foo") ... 326X 327X This implementation generates "foo", rather than the strictly 328X correct ""foo"" (which will probably generate an error message). 329X This is, strictly speaking, an error in CPP and may be removed 330X from future releases. 331X 332Xerror messages 333X 334X Many. CPP prints warning or error messages if you try to 335X use multiple-byte character constants (non-transportable) 336X if you #undef a symbol that was not defined, or if your 337X program has potentially nested comments. 338X 339Xauthor 340X 341X Martin Minow 342X 343Xbugs 344X 345X The #if expression processor uses signed integers only. 346X I.e, #if 0xFFFFu < 0 may be TRUE. 347X 348X#endif 349X 350X#include <stdio.h> 351X#include <ctype.h> 352X#include "cppdef.h" 353X#include "cpp.h" 354X 355X/* 356X * Commonly used global variables: 357X * line is the current input line number. 358X * wrongline is set in many places when the actual output 359X * line is out of sync with the numbering, e.g, 360X * when expanding a macro with an embedded newline. 361X * 362X * token holds the last identifier scanned (which might 363X * be a candidate for macro expansion). 364X * errors is the running cpp error counter. 365X * infile is the head of a linked list of input files (extended by 366X * #include and macros being expanded). infile always points 367X * to the current file/macro. infile->parent to the includer, 368X * etc. infile->fd is NULL if this input stream is a macro. 369X */ 370Xint line; /* Current line number */ 371Xint wrongline; /* Force #line to compiler */ 372Xchar token[IDMAX + 1]; /* Current input token */ 373Xint errors; /* cpp error counter */ 374XFILEINFO *infile = NULL; /* Current input file */ 375X#if DEBUG 376Xint debug; /* TRUE if debugging now */ 377X#endif 378X/* 379X * This counter is incremented when a macro expansion is initiated. 380X * If it exceeds a built-in value, the expansion stops -- this tests 381X * for a runaway condition: 382X * #define X Y 383X * #define Y X 384X * X 385X * This can be disabled by falsifying rec_recover. (Nothing does this 386X * currently: it is a hook for an eventual invocation flag.) 387X */ 388Xint recursion; /* Infinite recursion counter */ 389Xint rec_recover = TRUE; /* Unwind recursive macros */ 390X 391X/* 392X * instring is set TRUE when a string is scanned. It modifies the 393X * behavior of the "get next character" routine, causing all characters 394X * to be passed to the caller (except <DEF_MAGIC>). Note especially that 395X * comments and \<newline> are not removed from the source. (This 396X * prevents cpp output lines from being arbitrarily long). 397X * 398X * inmacro is set by #define -- it absorbs comments and converts 399X * form-feed and vertical-tab to space, but returns \<newline> 400X * to the caller. Strictly speaking, this is a bug as \<newline> 401X * shouldn't delimit tokens, but we'll worry about that some other 402X * time -- it is more important to prevent infinitly long output lines. 403X * 404X * instring and inmarcor are parameters to the get() routine which 405X * were made global for speed. 406X */ 407Xint instring = FALSE; /* TRUE if scanning string */ 408Xint inmacro = FALSE; /* TRUE if #defining a macro */ 409X 410X/* 411X * work[] and workp are used to store one piece of text in a temporay 412X * buffer. To initialize storage, set workp = work. To store one 413X * character, call save(c); (This will fatally exit if there isn't 414X * room.) To terminate the string, call save(EOS). Note that 415X * the work buffer is used by several subroutines -- be sure your 416X * data won't be overwritten. The extra byte in the allocation is 417X * needed for string formal replacement. 418X */ 419Xchar work[NWORK + 1]; /* Work buffer */ 420Xchar *workp; /* Work buffer pointer */ 421X 422X/* 423X * keepcomments is set TRUE by the -C option. If TRUE, comments 424X * are written directly to the output stream. This is needed if 425X * the output from cpp is to be passed to lint (which uses commands 426X * embedded in comments). cflag contains the permanent state of the 427X * -C flag. keepcomments is always falsified when processing #control 428X * commands and when compilation is supressed by a false #if 429X * 430X * If eflag is set, CPP returns "success" even if non-fatal errors 431X * were detected. 432X * 433X * If nflag is non-zero, no symbols are predefined except __LINE__. 434X * __FILE__, and __DATE__. If nflag > 1, absolutely no symbols 435X * are predefined. 436X */ 437Xint keepcomments = FALSE; /* Write out comments flag */ 438Xint cflag = FALSE; /* -C option (keep comments) */ 439Xint eflag = FALSE; /* -E option (never fail) */ 440Xint nflag = 0; /* -N option (no predefines) */ 441X 442X/* 443X * ifstack[] holds information about nested #if's. It is always 444X * accessed via *ifptr. The information is as follows: 445X * WAS_COMPILING state of compiling flag at outer level. 446X * ELSE_SEEN set TRUE when #else seen to prevent 2nd #else. 447X * TRUE_SEEN set TRUE when #if or #elif succeeds 448X * ifstack[0] holds the compiling flag. It is TRUE if compilation 449X * is currently enabled. Note that this must be initialized TRUE. 450X */ 451Xchar ifstack[BLK_NEST] = { TRUE }; /* #if information */ 452Xchar *ifptr = ifstack; /* -> current ifstack[] */ 453X 454X/* 455X * incdir[] stores the -i directories (and the system-specific 456X * #include <...> directories. 457X */ 458Xchar *incdir[NINCLUDE]; /* -i directories */ 459Xchar **incend = incdir; /* -> free space in incdir[] */ 460X 461X/* 462X * This is the table used to predefine target machine and operating 463X * system designators. It may need hacking for specific circumstances. 464X * Note: it is not clear that this is part of the Ansi Standard. 465X * The -N option supresses preset definitions. 466X */ 467Xchar *preset[] = { /* names defined at cpp start */ 468X#ifdef MACHINE 469X MACHINE, 470X#endif 471X#ifdef SYSTEM 472X SYSTEM, 473X#endif 474X#ifdef COMPILER 475X COMPILER, 476X#endif 477X#if DEBUG 478X "decus_cpp", /* Ourselves! */ 479X#endif 480X NULL /* Must be last */ 481X}; 482X 483X/* 484X * The value of these predefined symbols must be recomputed whenever 485X * they are evaluated. The order must not be changed. 486X */ 487Xchar *magic[] = { /* Note: order is important */ 488X "__LINE__", 489X "__FILE__", 490X NULL /* Must be last */ 491X}; 492X 493Xmain(argc, argv) 494Xint argc; 495Xchar *argv[]; 496X{ 497X register int i; 498X 499X#if HOST == SYS_VMS 500X argc = getredirection(argc, argv); /* vms >file and <file */ 501X#endif 502X initdefines(); /* O.S. specific def's */ 503X i = dooptions(argc, argv); /* Command line -flags */ 504X switch (i) { 505X case 3: 506X /* 507X * Get output file, "-" means use stdout. 508X */ 509X if (!streq(argv[2], "-")) { 510X#if HOST == SYS_VMS 511X /* 512X * On vms, reopen stdout with "vanilla rms" attributes. 513X */ 514X if ((i = creat(argv[2], 0, "rat=cr", "rfm=var")) == -1 515X || dup2(i, fileno(stdout)) == -1) { 516X#else 517X if (freopen(argv[2], "w", stdout) == NULL) { 518X#endif 519X perror(argv[2]); 520X cerror("Can't open output file \"%s\"", argv[2]); 521X exit(IO_ERROR); 522X } 523X } /* Continue by opening input */ 524X case 2: /* One file -> stdin */ 525X /* 526X * Open input file, "-" means use stdin. 527X */ 528X if (!streq(argv[1], "-")) { 529X if (freopen(argv[1], "r", stdin) == NULL) { 530X perror(argv[1]); 531X cerror("Can't open input file \"%s\"", argv[1]); 532X exit(IO_ERROR); 533X } 534X strcpy(work, argv[1]); /* Remember input filename */ 535X break; 536X } /* Else, just get stdin */ 537X case 0: /* No args? */ 538X case 1: /* No files, stdin -> stdout */ 539X#if HOST == SYS_UNIX 540X work[0] = EOS; /* Unix can't find stdin name */ 541X#else 542X fgetname(stdin, work); /* Vax-11C, Decus C know name */ 543X#endif 544X break; 545X 546X default: 547X exit(IO_ERROR); /* Can't happen */ 548X } 549X setincdirs(); /* Setup -I include directories */ 550X addfile(stdin, work); /* "open" main input file */ 551X#if DEBUG 552X if (debug > 0) 553X dumpdef("preset #define symbols"); 554X#endif 555X cppmain(); /* Process main file */ 556X if ((i = (ifptr - &ifstack[0])) != 0) { 557X#if OLD_PREPROCESSOR 558X ciwarn("Inside #ifdef block at end of input, depth = %d", i); 559X#else 560X cierror("Inside #ifdef block at end of input, depth = %d", i); 561X#endif 562X } 563X fclose(stdout); 564X if (errors > 0) { 565X fprintf(stderr, (errors == 1) 566X ? "%d error in preprocessor\n" 567X : "%d errors in preprocessor\n", errors); 568X if (!eflag) 569X exit(IO_ERROR); 570X } 571X exit(IO_NORMAL); /* No errors or -E option set */ 572X} 573X 574XFILE_LOCAL 575Xcppmain() 576X/* 577X * Main process for cpp -- copies tokens from the current input 578X * stream (main file, include file, or a macro) to the output 579X * file. 580X */ 581X{ 582X register int c; /* Current character */ 583X register int counter; /* newlines and spaces */ 584X extern int output(); /* Output one character */ 585X 586X /* 587X * Explicitly output a #line at the start of cpp output so 588X * that lint (etc.) knows the name of the original source 589X * file. If we don't do this explicitly, we may get 590X * the name of the first #include file instead. 591X */ 592X sharp(); 593X /* 594X * This loop is started "from the top" at the beginning of each line 595X * wrongline is set TRUE in many places if it is necessary to write 596X * a #line record. (But we don't write them when expanding macros.) 597X * 598X * The counter variable has two different uses: at 599X * the start of a line, it counts the number of blank lines that 600X * have been skipped over. These are then either output via 601X * #line records or by outputting explicit blank lines. 602X * When expanding tokens within a line, the counter remembers 603X * whether a blank/tab has been output. These are dropped 604X * at the end of the line, and replaced by a single blank 605X * within lines. 606X */ 607X for (;;) { 608X counter = 0; /* Count empty lines */ 609X for (;;) { /* For each line, ... */ 610X while (type[(c = get())] == SPA) /* Skip leading blanks */ 611X ; /* in this line. */ 612X if (c == '\n') /* If line's all blank, */ 613X ++counter; /* Do nothing now */ 614X else if (c == '#') { /* Is 1st non-space '#' */ 615X keepcomments = FALSE; /* Don't pass comments */ 616X counter = control(counter); /* Yes, do a #command */ 617X keepcomments = (cflag && compiling); 618X } 619X else if (c == EOF_CHAR) /* At end of file? */ 620X break; 621X else if (!compiling) { /* #ifdef false? */ 622X skipnl(); /* Skip to newline */ 623X counter++; /* Count it, too. */ 624X } 625X else { 626X break; /* Actual token */ 627X } 628X } 629X if (c == EOF_CHAR) /* Exit process at */ 630X break; /* End of file */ 631X /* 632X * If the loop didn't terminate because of end of file, we 633X * know there is a token to compile. First, clean up after 634X * absorbing newlines. counter has the number we skipped. 635X */ 636X if ((wrongline && infile->fp != NULL) || counter > 4) 637X sharp(); /* Output # line number */ 638X else { /* If just a few, stuff */ 639X while (--counter >= 0) /* them out ourselves */ 640X putchar('\n'); 641X } 642X /* 643X * Process each token on this line. 644X */ 645X unget(); /* Reread the char. */ 646X for (;;) { /* For the whole line, */ 647X do { /* Token concat. loop */ 648X for (counter = 0; (type[(c = get())] == SPA);) { 649X#if COMMENT_INVISIBLE 650X if (c != COM_SEP) 651X counter++; 652X#else 653X counter++; /* Skip over blanks */ 654X#endif 655X } 656X if (c == EOF_CHAR || c == '\n') 657X goto end_line; /* Exit line loop */ 658X else if (counter > 0) /* If we got any spaces */ 659X putchar(' '); /* Output one space */ 660X c = macroid(c); /* Grab the token */ 661X } while (type[c] == LET && catenate()); 662X if (c == EOF_CHAR || c == '\n') /* From macro exp error */ 663X goto end_line; /* Exit line loop */ 664X switch (type[c]) { 665X case LET: 666X fputs(token, stdout); /* Quite ordinary token */ 667X break; 668X 669X 670X case DIG: /* Output a number */ 671X case DOT: /* Dot may begin floats */ 672X scannumber(c, output); 673X break; 674X 675X case QUO: /* char or string const */ 676X scanstring(c, output); /* Copy it to output */ 677X break; 678X 679X default: /* Some other character */ 680X cput(c); /* Just output it */ 681X break; 682X } /* Switch ends */ 683X } /* Line for loop */ 684Xend_line: if (c == '\n') { /* Compiling at EOL? */ 685X putchar('\n'); /* Output newline, if */ 686X if (infile->fp == NULL) /* Expanding a macro, */ 687X wrongline = TRUE; /* Output # line later */ 688X } 689X } /* Continue until EOF */ 690X} 691X 692Xoutput(c) 693Xint c; 694X/* 695X * Output one character to stdout -- output() is passed as an 696X * argument to scanstring() 697X */ 698X{ 699X#if COMMENT_INVISIBLE 700X if (c != TOK_SEP && c != COM_SEP) 701X#else 702X if (c != TOK_SEP) 703X#endif 704X putchar(c); 705X} 706X 707Xstatic char *sharpfilename = NULL; 708X 709XFILE_LOCAL 710Xsharp() 711X/* 712X * Output a line number line. 713X */ 714X{ 715X register char *name; 716X 717X if (keepcomments) /* Make sure # comes on */ 718X putchar('\n'); /* a fresh, new line. */ 719X printf("#%s %d", LINE_PREFIX, line); 720X if (infile->fp != NULL) { 721X name = (infile->progname != NULL) 722X ? infile->progname : infile->filename; 723X if (sharpfilename == NULL 724X || sharpfilename != NULL && !streq(name, sharpfilename)) { 725X if (sharpfilename != NULL) 726X free(sharpfilename); 727X sharpfilename = savestring(name); 728X printf(" \"%s\"", name); 729X } 730X } 731X putchar('\n'); 732X wrongline = FALSE; 733X} 734END-of-cpp1.c 735echo x - cpp3.c 736sed 's/^X//' >cpp3.c << 'END-of-cpp3.c' 737X/* 738X * C P P 3 . C 739X * 740X * File open and command line options 741X * 742X * Edit history 743X * 13-Nov-84 MM Split from cpp1.c 744X */ 745X 746X#include <stdio.h> 747X#include <ctype.h> 748X#include "cppdef.h" 749X#include "cpp.h" 750X#if DEBUG && (HOST == SYS_VMS || HOST == SYS_UNIX) 751X#include <signal.h> 752Xextern int abort(); /* For debugging */ 753X#endif 754X 755Xint 756Xopenfile(filename) 757Xchar *filename; 758X/* 759X * Open a file, add it to the linked list of open files. 760X * This is called only from openfile() above. 761X */ 762X{ 763X register FILE *fp; 764X 765X if ((fp = fopen(filename, "r")) == NULL) { 766X#if DEBUG 767X perror(filename); 768X#endif 769X return (FALSE); 770X } 771X#if DEBUG 772X if (debug) 773X fprintf(stderr, "Reading from \"%s\"\n", filename); 774X#endif 775X addfile(fp, filename); 776X return (TRUE); 777X} 778X 779Xaddfile(fp, filename) 780XFILE *fp; /* Open file pointer */ 781Xchar *filename; /* Name of the file */ 782X/* 783X * Initialize tables for this open file. This is called from openfile() 784X * above (for #include files), and from the entry to cpp to open the main 785X * input file. It calls a common routine, getfile() to build the FILEINFO 786X * structure which is used to read characters. (getfile() is also called 787X * to setup a macro replacement.) 788X */ 789X{ 790X register FILEINFO *file; 791X extern FILEINFO *getfile(); 792X 793X file = getfile(NBUFF, filename); 794X file->fp = fp; /* Better remember FILE * */ 795X file->buffer[0] = EOS; /* Initialize for first read */ 796X line = 1; /* Working on line 1 now */ 797X wrongline = TRUE; /* Force out initial #line */ 798X} 799X 800Xsetincdirs() 801X/* 802X * Append system-specific directories to the include directory list. 803X * Called only when cpp is started. 804X */ 805X{ 806X 807X#ifdef CPP_INCLUDE 808X *incend++ = CPP_INCLUDE; 809X#define IS_INCLUDE 1 810X#else 811X#define IS_INCLUDE 0 812X#endif 813X 814X#if HOST == SYS_UNIX 815X *incend++ = "/usr/include"; 816X#define MAXINCLUDE (NINCLUDE - 1 - IS_INCLUDE) 817X#endif 818X 819X#if HOST == SYS_VMS 820X extern char *getenv(); 821X 822X if (getenv("C$LIBRARY") != NULL) 823X *incend++ = "C$LIBRARY:"; 824X *incend++ = "SYS$LIBRARY:"; 825X#define MAXINCLUDE (NINCLUDE - 2 - IS_INCLUDE) 826X#endif 827X 828X#if HOST == SYS_RSX 829X extern int $$rsts; /* TRUE on RSTS/E */ 830X extern int $$pos; /* TRUE on PRO-350 P/OS */ 831X extern int $$vms; /* TRUE on VMS compat. */ 832X 833X if ($$pos) { /* P/OS? */ 834X *incend++ = "SY:[ZZDECUSC]"; /* C #includes */ 835X *incend++ = "LB:[1,5]"; /* RSX library */ 836X } 837X else if ($$rsts) { /* RSTS/E? */ 838X *incend++ = "SY:@"; /* User-defined account */ 839X *incend++ = "C:"; /* Decus-C library */ 840X *incend++ = "LB:[1,1]"; /* RSX library */ 841X } 842X else if ($$vms) { /* VMS compatibility? */ 843X *incend++ = "C:"; 844X } 845X else { /* Plain old RSX/IAS */ 846X *incend++ = "LB:[1,1]"; 847X } 848X#define MAXINCLUDE (NINCLUDE - 3 - IS_INCLUDE) 849X#endif 850X 851X#if HOST == SYS_RT11 852X extern int $$rsts; /* RSTS/E emulation? */ 853X 854X if ($$rsts) 855X *incend++ = "SY:@"; /* User-defined account */ 856X *incend++ = "C:"; /* Decus-C library disk */ 857X *incend++ = "SY:"; /* System (boot) disk */ 858X#define MAXINCLUDE (NINCLUDE - 3 - IS_INCLUDE) 859X#endif 860X} 861X 862Xint 863Xdooptions(argc, argv) 864Xint argc; 865Xchar *argv[]; 866X/* 867X * dooptions is called to process command line arguments (-Detc). 868X * It is called only at cpp startup. 869X */ 870X{ 871X register char *ap; 872X register DEFBUF *dp; 873X register int c; 874X int i, j; 875X char *arg; 876X SIZES *sizp; /* For -S */ 877X int size; /* For -S */ 878X int isdatum; /* FALSE for -S* */ 879X int endtest; /* For -S */ 880X 881X for (i = j = 1; i < argc; i++) { 882X arg = ap = argv[i]; 883X if (*ap++ != '-' || *ap == EOS) 884X argv[j++] = argv[i]; 885X else { 886X c = *ap++; /* Option byte */ 887X if (islower(c)) /* Normalize case */ 888X c = toupper(c); 889X switch (c) { /* Command character */ 890X case 'C': /* Keep comments */ 891X cflag = TRUE; 892X keepcomments = TRUE; 893X break; 894X 895X case 'D': /* Define symbol */ 896X#if HOST != SYS_UNIX 897X zap_uc(ap); /* Force define to U.C. */ 898X#endif 899X /* 900X * If the option is just "-Dfoo", make it -Dfoo=1 901X */ 902X while (*ap != EOS && *ap != '=') 903X ap++; 904X if (*ap == EOS) 905X ap = "1"; 906X else 907X *ap++ = EOS; 908X /* 909X * Now, save the word and its definition. 910X */ 911X dp = defendel(argv[i] + 2, FALSE); 912X dp->repl = savestring(ap); 913X dp->nargs = DEF_NOARGS; 914X break; 915X 916X case 'E': /* Ignore non-fatal */ 917X eflag = TRUE; /* errors. */ 918X break; 919X 920X case 'I': /* Include directory */ 921X if (incend >= &incdir[MAXINCLUDE]) 922X cfatal("Too many include directories", NULLST); 923X *incend++ = ap; 924X break; 925X 926X case 'N': /* No predefineds */ 927X nflag++; /* Repeat to undefine */ 928X break; /* __LINE__, etc. */ 929X 930X case 'S': 931X sizp = size_table; 932X if (isdatum = (*ap != '*')) /* If it's just -S, */ 933X endtest = T_FPTR; /* Stop here */ 934X else { /* But if it's -S* */ 935X ap++; /* Step over '*' */ 936X endtest = 0; /* Stop at end marker */ 937X } 938X while (sizp->bits != endtest && *ap != EOS) { 939X if (!isdigit(*ap)) { /* Skip to next digit */ 940X ap++; 941X continue; 942X } 943X size = 0; /* Compile the value */ 944X while (isdigit(*ap)) { 945X size *= 10; 946X size += (*ap++ - '0'); 947X } 948X if (isdatum) 949X sizp->size = size; /* Datum size */ 950X else 951X sizp->psize = size; /* Pointer size */ 952X sizp++; 953X } 954X if (sizp->bits != endtest) 955X cwarn("-S, too few values specified in %s", argv[i]); 956X else if (*ap != EOS) 957X cwarn("-S, too many values, \"%s\" unused", ap); 958X break; 959X 960X case 'U': /* Undefine symbol */ 961X#if HOST != SYS_UNIX 962X zap_uc(ap); 963X#endif 964X if (defendel(ap, TRUE) == NULL) 965X cwarn("\"%s\" wasn't defined", ap); 966X break; 967X 968X#if DEBUG 969X case 'X': /* Debug */ 970X debug = (isdigit(*ap)) ? atoi(ap) : 1; 971X#if (HOST == SYS_VMS || HOST == SYS_UNIX) 972X signal(SIGINT, abort); /* Trap "interrupt" */ 973X#endif 974X fprintf(stderr, "Debug set to %d\n", debug); 975X break; 976X#endif 977X 978X default: /* What is this one? */ 979X cwarn("Unknown option \"%s\"", arg); 980X fprintf(stderr, "The following options are valid:\n\ 981X -C\t\t\tWrite source file comments to output\n\ 982X -Dsymbol=value\tDefine a symbol with the given (optional) value\n\ 983X -Idirectory\t\tAdd a directory to the #include search list\n\ 984X -N\t\t\tDon't predefine target-specific names\n\ 985X -Stext\t\tSpecify sizes for #if sizeof\n\ 986X -Usymbol\t\tUndefine symbol\n"); 987X#if DEBUG 988X fprintf(stderr, " -Xvalue\t\tSet internal debug flag\n"); 989X#endif 990X break; 991X } /* Switch on all options */ 992X } /* If it's a -option */ 993X } /* For all arguments */ 994X if (j > 3) { 995X cerror( 996X "Too many file arguments. Usage: cpp [input [output]]", 997X NULLST); 998X } 999X return (j); /* Return new argc */ 1000X} 1001X 1002X#if HOST != SYS_UNIX 1003XFILE_LOCAL 1004Xzap_uc(ap) 1005Xregister char *ap; 1006X/* 1007X * Dec operating systems mangle upper-lower case in command lines. 1008X * This routine forces the -D and -U arguments to uppercase. 1009X * It is called only on cpp startup by dooptions(). 1010X */ 1011X{ 1012X while (*ap != EOS) { 1013X /* 1014X * Don't use islower() here so it works with Multinational 1015X */ 1016X if (*ap >= 'a' && *ap <= 'z') 1017X *ap = toupper(*ap); 1018X ap++; 1019X } 1020X} 1021X#endif 1022X 1023Xinitdefines() 1024X/* 1025X * Initialize the built-in #define's. There are two flavors: 1026X * #define decus 1 (static definitions) 1027X * #define __FILE__ ?? (dynamic, evaluated by magic) 1028X * Called only on cpp startup. 1029X * 1030X * Note: the built-in static definitions are supressed by the -N option. 1031X * __LINE__, __FILE__, and __DATE__ are always present. 1032X */ 1033X{ 1034X register char **pp; 1035X register char *tp; 1036X register DEFBUF *dp; 1037X int i; 1038X long tvec; 1039X extern char *ctime(); 1040X 1041X /* 1042X * Predefine the built-in symbols. Allow the 1043X * implementor to pre-define a symbol as "" to 1044X * eliminate it. 1045X */ 1046X if (nflag == 0) { 1047X for (pp = preset; *pp != NULL; pp++) { 1048X if (*pp[0] != EOS) { 1049X dp = defendel(*pp, FALSE); 1050X dp->repl = savestring("1"); 1051X dp->nargs = DEF_NOARGS; 1052X } 1053X } 1054X } 1055X /* 1056X * The magic pre-defines (__FILE__ and __LINE__ are 1057X * initialized with negative argument counts. expand() 1058X * notices this and calls the appropriate routine. 1059X * DEF_NOARGS is one greater than the first "magic" definition. 1060X */ 1061X if (nflag < 2) { 1062X for (pp = magic, i = DEF_NOARGS; *pp != NULL; pp++) { 1063X dp = defendel(*pp, FALSE); 1064X dp->nargs = --i; 1065X } 1066X#if OK_DATE 1067X /* 1068X * Define __DATE__ as today's date. 1069X */ 1070X dp = defendel("__DATE__", FALSE); 1071X dp->repl = tp = getmem(27); 1072X dp->nargs = DEF_NOARGS; 1073X time(&tvec); 1074X *tp++ = '"'; 1075X strcpy(tp, ctime(&tvec)); 1076X tp[24] = '"'; /* Overwrite newline */ 1077X#endif 1078X } 1079X} 1080X 1081X#if HOST == SYS_VMS 1082X/* 1083X * getredirection() is intended to aid in porting C programs 1084X * to VMS (Vax-11 C) which does not support '>' and '<' 1085X * I/O redirection. With suitable modification, it may 1086X * useful for other portability problems as well. 1087X */ 1088X 1089Xint 1090Xgetredirection(argc, argv) 1091Xint argc; 1092Xchar **argv; 1093X/* 1094X * Process vms redirection arg's. Exit if any error is seen. 1095X * If getredirection() processes an argument, it is erased 1096X * from the vector. getredirection() returns a new argc value. 1097X * 1098X * Warning: do not try to simplify the code for vms. The code 1099X * presupposes that getredirection() is called before any data is 1100X * read from stdin or written to stdout. 1101X * 1102X * Normal usage is as follows: 1103X * 1104X * main(argc, argv) 1105X * int argc; 1106X * char *argv[]; 1107X * { 1108X * argc = getredirection(argc, argv); 1109X * } 1110X */ 1111X{ 1112X register char *ap; /* Argument pointer */ 1113X int i; /* argv[] index */ 1114X int j; /* Output index */ 1115X int file; /* File_descriptor */ 1116X extern int errno; /* Last vms i/o error */ 1117X 1118X for (j = i = 1; i < argc; i++) { /* Do all arguments */ 1119X switch (*(ap = argv[i])) { 1120X case '<': /* <file */ 1121X if (freopen(++ap, "r", stdin) == NULL) { 1122X perror(ap); /* Can't find file */ 1123X exit(errno); /* Is a fatal error */ 1124X } 1125X break; 1126X 1127X case '>': /* >file or >>file */ 1128X if (*++ap == '>') { /* >>file */ 1129X /* 1130X * If the file exists, and is writable by us, 1131X * call freopen to append to the file (using the 1132X * file's current attributes). Otherwise, create 1133X * a new file with "vanilla" attributes as if the 1134X * argument was given as ">filename". 1135X * access(name, 2) returns zero if we can write on 1136X * the specified file. 1137X */ 1138X if (access(++ap, 2) == 0) { 1139X if (freopen(ap, "a", stdout) != NULL) 1140X break; /* Exit case statement */ 1141X perror(ap); /* Error, can't append */ 1142X exit(errno); /* After access test */ 1143X } /* If file accessable */ 1144X } 1145X /* 1146X * On vms, we want to create the file using "standard" 1147X * record attributes. creat(...) creates the file 1148X * using the caller's default protection mask and 1149X * "variable length, implied carriage return" 1150X * attributes. dup2() associates the file with stdout. 1151X */ 1152X if ((file = creat(ap, 0, "rat=cr", "rfm=var")) == -1 1153X || dup2(file, fileno(stdout)) == -1) { 1154X perror(ap); /* Can't create file */ 1155X exit(errno); /* is a fatal error */ 1156X } /* If '>' creation */ 1157X break; /* Exit case test */ 1158X 1159X default: 1160X argv[j++] = ap; /* Not a redirector */ 1161X break; /* Exit case test */ 1162X } 1163X } /* For all arguments */ 1164X argv[j] = NULL; /* Terminate argv[] */ 1165X return (j); /* Return new argc */ 1166X} 1167X#endif 1168X 1169X 1170X 1171END-of-cpp3.c 1172echo x - cpp4.c 1173sed 's/^X//' >cpp4.c << 'END-of-cpp4.c' 1174X/* 1175X * C P P 4 . C 1176X * M a c r o D e f i n i t i o n s 1177X * 1178X * Edit History 1179X * 31-Aug-84 MM USENET net.sources release 1180X * 04-Oct-84 MM __LINE__ and __FILE__ must call ungetstring() 1181X * so they work correctly with token concatenation. 1182X * Added string formal recognition. 1183X * 25-Oct-84 MM "Short-circuit" evaluate #if's so that we 1184X * don't print unnecessary error messages for 1185X * #if !defined(FOO) && FOO != 0 && 10 / FOO ... 1186X * 31-Oct-84 ado/MM Added token concatenation 1187X * 6-Nov-84 MM Split off eval stuff 1188X */ 1189X 1190X#include <stdio.h> 1191X#include <ctype.h> 1192X#include "cppdef.h" 1193X#include "cpp.h" 1194X/* 1195X * parm[], parmp, and parlist[] are used to store #define() argument 1196X * lists. nargs contains the actual number of parameters stored. 1197X */ 1198Xstatic char parm[NPARMWORK + 1]; /* define param work buffer */ 1199Xstatic char *parmp; /* Free space in parm */ 1200Xstatic char *parlist[LASTPARM]; /* -> start of each parameter */ 1201Xstatic int nargs; /* Parameters for this macro */ 1202X 1203Xdodefine() 1204X/* 1205X * Called from control when a #define is scanned. This module 1206X * parses formal parameters and the replacement string. When 1207X * the formal parameter name is encountered in the replacement 1208X * string, it is replaced by a character in the range 128 to 1209X * 128+NPARAM (this allows up to 32 parameters within the 1210X * Dec Multinational range). If cpp is ported to an EBCDIC 1211X * machine, you will have to make other arrangements. 1212X * 1213X * There is some special case code to distinguish 1214X * #define foo bar 1215X * from #define foo() bar 1216X * 1217X * Also, we make sure that 1218X * #define foo foo 1219X * expands to "foo" but doesn't put cpp into an infinite loop. 1220X * 1221X * A warning message is printed if you redefine a symbol to a 1222X * different text. I.e, 1223X * #define foo 123 1224X * #define foo 123 1225X * is ok, but 1226X * #define foo 123 1227X * #define foo +123 1228X * is not. 1229X * 1230X * The following subroutines are called from define(): 1231X * checkparm called when a token is scanned. It checks through the 1232X * array of formal parameters. If a match is found, the 1233X * token is replaced by a control byte which will be used 1234X * to locate the parameter when the macro is expanded. 1235X * textput puts a string in the macro work area (parm[]), updating 1236X * parmp to point to the first free byte in parm[]. 1237X * textput() tests for work buffer overflow. 1238X * charput puts a single character in the macro work area (parm[]) 1239X * in a manner analogous to textput(). 1240X */ 1241X{ 1242X register int c; 1243X register DEFBUF *dp; /* -> new definition */ 1244X int isredefine; /* TRUE if redefined */ 1245X char *old; /* Remember redefined */ 1246X extern int save(); /* Save char in work[] */ 1247X 1248X if (type[(c = skipws())] != LET) 1249X goto bad_define; 1250X isredefine = FALSE; /* Set if redefining */ 1251X if ((dp = lookid(c)) == NULL) /* If not known now */ 1252X dp = defendel(token, FALSE); /* Save the name */ 1253X else { /* It's known: */ 1254X isredefine = TRUE; /* Remember this fact */ 1255X old = dp->repl; /* Remember replacement */ 1256X dp->repl = NULL; /* No replacement now */ 1257X } 1258X parlist[0] = parmp = parm; /* Setup parm buffer */ 1259X if ((c = get()) == '(') { /* With arguments? */ 1260X nargs = 0; /* Init formals counter */ 1261X do { /* Collect formal parms */ 1262X if (nargs >= LASTPARM) 1263X cfatal("Too many arguments for macro", NULLST); 1264X else if ((c = skipws()) == ')') 1265X break; /* Got them all */ 1266X else if (type[c] != LET) /* Bad formal syntax */ 1267X goto bad_define; 1268X scanid(c); /* Get the formal param */ 1269X parlist[nargs++] = parmp; /* Save its start */ 1270X textput(token); /* Save text in parm[] */ 1271X } while ((c = skipws()) == ','); /* Get another argument */ 1272X if (c != ')') /* Must end at ) */ 1273X goto bad_define; 1274X c = ' '; /* Will skip to body */ 1275X } 1276X else { 1277X /* 1278X * DEF_NOARGS is needed to distinguish between 1279X * "#define foo" and "#define foo()". 1280X */ 1281X nargs = DEF_NOARGS; /* No () parameters */ 1282X } 1283X if (type[c] == SPA) /* At whitespace? */ 1284X c = skipws(); /* Not any more. */ 1285X workp = work; /* Replacement put here */ 1286X inmacro = TRUE; /* Keep \<newline> now */ 1287X while (c != EOF_CHAR && c != '\n') { /* Compile macro body */ 1288X#if OK_CONCAT 1289X if (c == '#') { /* Token concatenation? */ 1290X while (workp > work && type[workp[-1]] == SPA) 1291X --workp; /* Erase leading spaces */ 1292X save(TOK_SEP); /* Stuff a delimiter */ 1293X c = skipws(); /* Eat whitespace */ 1294X if (type[c] == LET) /* Another token here? */ 1295X ; /* Stuff it normally */ 1296X else if (type[c] == DIG) { /* Digit string after? */ 1297X while (type[c] == DIG) { /* Stuff the digits */ 1298X save(c); 1299X c = get(); 1300X } 1301X save(TOK_SEP); /* Delimit 2nd token */ 1302X } 1303X else { 1304X ciwarn("Strange character after # (%d.)", c); 1305X } 1306X continue; 1307X } 1308X#endif 1309X switch (type[c]) { 1310X case LET: 1311X checkparm(c, dp); /* Might be a formal */ 1312X break; 1313X 1314X case DIG: /* Number in mac. body */ 1315X case DOT: /* Maybe a float number */ 1316X scannumber(c, save); /* Scan it off */ 1317X break; 1318X 1319X case QUO: /* String in mac. body */ 1320X#if STRING_FORMAL 1321X stparmscan(c, dp); /* Do string magic */ 1322X#else 1323X stparmscan(c); 1324X#endif 1325X break; 1326X 1327X case BSH: /* Backslash */ 1328X save('\\'); 1329X if ((c = get()) == '\n') 1330X wrongline = TRUE; 1331X save(c); 1332X break; 1333X 1334X case SPA: /* Absorb whitespace */ 1335X /* 1336X * Note: the "end of comment" marker is passed on 1337X * to allow comments to separate tokens. 1338X */ 1339X if (workp[-1] == ' ') /* Absorb multiple */ 1340X break; /* spaces */ 1341X else if (c == '\t') 1342X c = ' '; /* Normalize tabs */ 1343X /* Fall through to store character */ 1344X default: /* Other character */ 1345X save(c); 1346X break; 1347X } 1348X c = get(); 1349X } 1350X inmacro = FALSE; /* Stop newline hack */ 1351X unget(); /* For control check */ 1352X if (workp > work && workp[-1] == ' ') /* Drop trailing blank */ 1353X workp--; 1354X *workp = EOS; /* Terminate work */ 1355X dp->repl = savestring(work); /* Save the string */ 1356X dp->nargs = nargs; /* Save arg count */ 1357X#if DEBUG 1358X if (debug) 1359X dumpadef("macro definition", dp); 1360X#endif 1361X if (isredefine) { /* Error if redefined */ 1362X if ((old != NULL && dp->repl != NULL && !streq(old, dp->repl)) 1363X || (old == NULL && dp->repl != NULL) 1364X || (old != NULL && dp->repl == NULL)) { 1365X cerror("Redefining defined variable \"%s\"", dp->name); 1366X } 1367X if (old != NULL) /* We don't need the */ 1368X free(old); /* old definition now. */ 1369X } 1370X return; 1371X 1372Xbad_define: 1373X cerror("#define syntax error", NULLST); 1374X inmacro = FALSE; /* Stop <newline> hack */ 1375X} 1376X 1377Xcheckparm(c, dp) 1378Xregister int c; 1379XDEFBUF *dp; 1380X/* 1381X * Replace this param if it's defined. Note that the macro name is a 1382X * possible replacement token. We stuff DEF_MAGIC in front of the token 1383X * which is treated as a LETTER by the token scanner and eaten by 1384X * the output routine. This prevents the macro expander from 1385X * looping if someone writes "#define foo foo". 1386X */ 1387X{ 1388X register int i; 1389X register char *cp; 1390X 1391X scanid(c); /* Get parm to token[] */ 1392X for (i = 0; i < nargs; i++) { /* For each argument */ 1393X if (streq(parlist[i], token)) { /* If it's known */ 1394X save(i + MAC_PARM); /* Save a magic cookie */ 1395X return; /* And exit the search */ 1396X } 1397X } 1398X if (streq(dp->name, token)) /* Macro name in body? */ 1399X save(DEF_MAGIC); /* Save magic marker */ 1400X for (cp = token; *cp != EOS;) /* And save */ 1401X save(*cp++); /* The token itself */ 1402X} 1403X 1404X#if STRING_FORMAL 1405Xstparmscan(delim, dp) 1406Xint delim; 1407Xregister DEFBUF *dp; 1408X/* 1409X * Scan the string (starting with the given delimiter). 1410X * The token is replaced if it is the only text in this string or 1411X * character constant. The algorithm follows checkparm() above. 1412X * Note that scanstring() has approved of the string. 1413X */ 1414X{ 1415X register int c; 1416X 1417X /* 1418X * Warning -- this code hasn't been tested for a while. 1419X * It exists only to preserve compatibility with earlier 1420X * implementations of cpp. It is not part of the Draft 1421X * ANSI Standard C language. 1422X */ 1423X save(delim); 1424X instring = TRUE; 1425X while ((c = get()) != delim 1426X && c != '\n' 1427X && c != EOF_CHAR) { 1428X if (type[c] == LET) /* Maybe formal parm */ 1429X checkparm(c, dp); 1430X else { 1431X save(c); 1432X if (c == '\\') 1433X save(get()); 1434X } 1435X } 1436X instring = FALSE; 1437X if (c != delim) 1438X cerror("Unterminated string in macro body", NULLST); 1439X save(c); 1440X} 1441X#else 1442Xstparmscan(delim) 1443Xint delim; 1444X/* 1445X * Normal string parameter scan. 1446X */ 1447X{ 1448X register char *wp; 1449X register int i; 1450X extern int save(); 1451X 1452X wp = workp; /* Here's where it starts */ 1453X if (!scanstring(delim, save)) 1454X return; /* Exit on scanstring error */ 1455X workp[-1] = EOS; /* Erase trailing quote */ 1456X wp++; /* -> first string content byte */ 1457X for (i = 0; i < nargs; i++) { 1458X if (streq(parlist[i], wp)) { 1459X *wp++ = MAC_PARM + PAR_MAC; /* Stuff a magic marker */ 1460X *wp++ = (i + MAC_PARM); /* Make a formal marker */ 1461X *wp = wp[-3]; /* Add on closing quote */ 1462X workp = wp + 1; /* Reset string end */ 1463X return; 1464X } 1465X } 1466X workp[-1] = wp[-1]; /* Nope, reset end quote. */ 1467X} 1468X#endif 1469X 1470Xdoundef() 1471X/* 1472X * Remove the symbol from the defined list. 1473X * Called from the #control processor. 1474X */ 1475X{ 1476X register int c; 1477X 1478X if (type[(c = skipws())] != LET) 1479X cerror("Illegal #undef argument", NULLST); 1480X else { 1481X scanid(c); /* Get name to token[] */ 1482X if (defendel(token, TRUE) == NULL) { 1483X cwarn("Symbol \"%s\" not defined in #undef", token); 1484X } 1485X } 1486X} 1487X 1488Xtextput(text) 1489Xchar *text; 1490X/* 1491X * Put the string in the parm[] buffer. 1492X */ 1493X{ 1494X register int size; 1495X 1496X size = strlen(text) + 1; 1497X if ((parmp + size) >= &parm[NPARMWORK]) 1498X cfatal("Macro work area overflow", NULLST); 1499X else { 1500X strcpy(parmp, text); 1501X parmp += size; 1502X } 1503X} 1504X 1505Xcharput(c) 1506Xregister int c; 1507X/* 1508X * Put the byte in the parm[] buffer. 1509X */ 1510X{ 1511X if (parmp >= &parm[NPARMWORK]) 1512X cfatal("Macro work area overflow", NULLST); 1513X else { 1514X *parmp++ = c; 1515X } 1516X} 1517X 1518X/* 1519X * M a c r o E x p a n s i o n 1520X */ 1521X 1522Xstatic DEFBUF *macro; /* Catches start of infinite macro */ 1523X 1524Xexpand(tokenp) 1525Xregister DEFBUF *tokenp; 1526X/* 1527X * Expand a macro. Called from the cpp mainline routine (via subroutine 1528X * macroid()) when a token is found in the symbol table. It calls 1529X * expcollect() to parse actual parameters, checking for the correct number. 1530X * It then creates a "file" containing a single line containing the 1531X * macro with actual parameters inserted appropriately. This is 1532X * "pushed back" onto the input stream. (When the get() routine runs 1533X * off the end of the macro line, it will dismiss the macro itself.) 1534X */ 1535X{ 1536X register int c; 1537X register FILEINFO *file; 1538X extern FILEINFO *getfile(); 1539X 1540X#if DEBUG 1541X if (debug) 1542X dumpadef("expand entry", tokenp); 1543X#endif 1544X /* 1545X * If no macro is pending, save the name of this macro 1546X * for an eventual error message. 1547X */ 1548X if (recursion++ == 0) 1549X macro = tokenp; 1550X else if (recursion == RECURSION_LIMIT) { 1551X cerror("Recursive macro definition of \"%s\"", tokenp->name); 1552X fprintf(stderr, "(Defined by \"%s\")\n", macro->name); 1553X if (rec_recover) { 1554X do { 1555X c = get(); 1556X } while (infile != NULL && infile->fp == NULL); 1557X unget(); 1558X recursion = 0; 1559X return; 1560X } 1561X } 1562X /* 1563X * Here's a macro to expand. 1564X */ 1565X nargs = 0; /* Formals counter */ 1566X parmp = parm; /* Setup parm buffer */ 1567X switch (tokenp->nargs) { 1568X case (-2): /* __LINE__ */ 1569X sprintf(work, "%d", line); 1570X ungetstring(work); 1571X break; 1572X 1573X case (-3): /* __FILE__ */ 1574X for (file = infile; file != NULL; file = file->parent) { 1575X if (file->fp != NULL) { 1576X sprintf(work, "\"%s\"", (file->progname != NULL) 1577X ? file->progname : file->filename); 1578X ungetstring(work); 1579X break; 1580X } 1581X } 1582X break; 1583X 1584X default: 1585X /* 1586X * Nothing funny about this macro. 1587X */ 1588X if (tokenp->nargs < 0) 1589X cfatal("Bug: Illegal __ macro \"%s\"", tokenp->name); 1590X while ((c = skipws()) == '\n') /* Look for (, skipping */ 1591X wrongline = TRUE; /* spaces and newlines */ 1592X if (c != '(') { 1593X /* 1594X * If the programmer writes 1595X * #define foo() ... 1596X * ... 1597X * foo [no ()] 1598X * just write foo to the output stream. 1599X */ 1600X unget(); 1601X cwarn("Macro \"%s\" needs arguments", tokenp->name); 1602X fputs(tokenp->name, stdout); 1603X return; 1604X } 1605X else if (expcollect()) { /* Collect arguments */ 1606X if (tokenp->nargs != nargs) { /* Should be an error? */ 1607X cwarn("Wrong number of macro arguments for \"%s\"", 1608X tokenp->name); 1609X } 1610X#if DEBUG 1611X if (debug) 1612X dumpparm("expand"); 1613X#endif 1614X } /* Collect arguments */ 1615X case DEF_NOARGS: /* No parameters just stuffs */ 1616X expstuff(tokenp); /* Do actual parameters */ 1617X } /* nargs switch */ 1618X} 1619X 1620XFILE_LOCAL int 1621Xexpcollect() 1622X/* 1623X * Collect the actual parameters for this macro. TRUE if ok. 1624X */ 1625X{ 1626X register int c; 1627X register int paren; /* For embedded ()'s */ 1628X extern int charput(); 1629X 1630X for (;;) { 1631X paren = 0; /* Collect next arg. */ 1632X while ((c = skipws()) == '\n') /* Skip over whitespace */ 1633X wrongline = TRUE; /* and newlines. */ 1634X if (c == ')') { /* At end of all args? */ 1635X /* 1636X * Note that there is a guard byte in parm[] 1637X * so we don't have to check for overflow here. 1638X */ 1639X *parmp = EOS; /* Make sure terminated */ 1640X break; /* Exit collection loop */ 1641X } 1642X else if (nargs >= LASTPARM) 1643X cfatal("Too many arguments in macro expansion", NULLST); 1644X parlist[nargs++] = parmp; /* At start of new arg */ 1645X for (;; c = cget()) { /* Collect arg's bytes */ 1646X if (c == EOF_CHAR) { 1647X cerror("end of file within macro argument", NULLST); 1648X return (FALSE); /* Sorry. */ 1649X } 1650X else if (c == '\\') { /* Quote next character */ 1651X charput(c); /* Save the \ for later */ 1652X charput(cget()); /* Save the next char. */ 1653X continue; /* And go get another */ 1654X } 1655X else if (type[c] == QUO) { /* Start of string? */ 1656X scanstring(c, charput); /* Scan it off */ 1657X continue; /* Go get next char */ 1658X } 1659X else if (c == '(') /* Worry about balance */ 1660X paren++; /* To know about commas */ 1661X else if (c == ')') { /* Other side too */ 1662X if (paren == 0) { /* At the end? */ 1663X unget(); /* Look at it later */ 1664X break; /* Exit arg getter. */ 1665X } 1666X paren--; /* More to come. */ 1667X } 1668X else if (c == ',' && paren == 0) /* Comma delimits args */ 1669X break; 1670X else if (c == '\n') /* Newline inside arg? */ 1671X wrongline = TRUE; /* We'll need a #line */ 1672X charput(c); /* Store this one */ 1673X } /* Collect an argument */ 1674X charput(EOS); /* Terminate argument */ 1675X#if DEBUG 1676X if (debug) 1677X printf("parm[%d] = \"%s\"\n", nargs, parlist[nargs - 1]); 1678X#endif 1679X } /* Collect all args. */ 1680X return (TRUE); /* Normal return */ 1681X} 1682X 1683XFILE_LOCAL 1684Xexpstuff(tokenp) 1685XDEFBUF *tokenp; /* Current macro being expanded */ 1686X/* 1687X * Stuff the macro body, replacing formal parameters by actual parameters. 1688X */ 1689X{ 1690X register int c; /* Current character */ 1691X register char *inp; /* -> repl string */ 1692X register char *defp; /* -> macro output buff */ 1693X int size; /* Actual parm. size */ 1694X char *defend; /* -> output buff end */ 1695X int string_magic; /* String formal hack */ 1696X FILEINFO *file; /* Funny #include */ 1697X extern FILEINFO *getfile(); 1698X 1699X file = getfile(NBUFF, tokenp->name); 1700X inp = tokenp->repl; /* -> macro replacement */ 1701X defp = file->buffer; /* -> output buffer */ 1702X defend = defp + (NBUFF - 1); /* Note its end */ 1703X if (inp != NULL) { 1704X while ((c = (*inp++ & 0xFF)) != EOS) { 1705X if (c >= MAC_PARM && c <= (MAC_PARM + PAR_MAC)) { 1706X string_magic = (c == (MAC_PARM + PAR_MAC)); 1707X if (string_magic) 1708X c = (*inp++ & 0xFF); 1709X /* 1710X * Replace formal parameter by actual parameter string. 1711X */ 1712X if ((c -= MAC_PARM) < nargs) { 1713X size = strlen(parlist[c]); 1714X if ((defp + size) >= defend) 1715X goto nospace; 1716X /* 1717X * Erase the extra set of quotes. 1718X */ 1719X if (string_magic && defp[-1] == parlist[c][0]) { 1720X strcpy(defp-1, parlist[c]); 1721X defp += (size - 2); 1722X } 1723X else { 1724X strcpy(defp, parlist[c]); 1725X defp += size; 1726X } 1727X } 1728X } 1729X else if (defp >= defend) { 1730Xnospace: cfatal("Out of space in macro \"%s\" arg expansion", 1731X tokenp->name); 1732X } 1733X else { 1734X *defp++ = c; 1735X } 1736X } 1737X } 1738X *defp = EOS; 1739X#if DEBUG 1740X if (debug > 1) 1741X printf("macroline: \"%s\"\n", file->buffer); 1742X#endif 1743X} 1744X 1745X#if DEBUG 1746Xdumpparm(why) 1747Xchar *why; 1748X/* 1749X * Dump parameter list. 1750X */ 1751X{ 1752X register int i; 1753X 1754X printf("dump of %d parameters (%d bytes total) %s\n", 1755X nargs, parmp - parm, why); 1756X for (i = 0; i < nargs; i++) { 1757X printf("parm[%d] (%d) = \"%s\"\n", 1758X i + 1, strlen(parlist[i]), parlist[i]); 1759X } 1760X} 1761X#endif 1762END-of-cpp4.c 1763exit 1764