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# makefile.txt 9# readme.txt 10# cpp.mem 11# cpp.h 12# cppdef.h 13# cpp2.c 14# 15echo x - makefile.txt 16sed 's/^X//' >makefile.txt << 'END-of-makefile.txt' 17X# 18X# The redefinition of strchr() and strrchr() are needed for 19X# Ultrix-32, Unix 4.2 bsd (and maybe some other Unices). 20X# 21XBSDDEFINE = -Dstrchr=index -Dstrrchr=rindex 22X# 23X# On certain systems, such as Unix System III, you may need to define 24X# $(LINTFLAGS) in the make command line to set system-specific lint flags. 25X# 26X# This Makefile assumes cpp will replace the "standard" preprocessor. 27X# Delete the reference to -DLINE_PREFIX=\"\" if cpp is used stand-alone. 28X# LINEFIX is a sed script filter that reinserts #line -- used for testing 29X# if LINE_PREFIX is set to "". Note that we must stand on our heads to 30X# match the # and a line had better not begin with $. By the way, what 31X# we really want is 32X# LINEFIX = | sed "s/^#/#line/" 33X# 34XCPPDEFINE = -DLINE_PREFIX=\"\" 35XLINEFIX = | sed "s/^[^ !\"%-~]/&line/" 36X# 37X# Define OLD_PREPROCESSOR non-zero to make a preprocessor which is 38X# "as compatible as possible" with the standard Unix V7 or Ultrix 39X# preprocessors. This is needed to rebuild 4.2bsd, for example, as 40X# the preprocessor is used to modify assembler code, rather than C. 41X# This is not recommended for current development. OLD_PREPROCESSOR 42X# forces the following definitions: 43X# OK_DOLLAR FALSE $ is not allowed in variables 44X# OK_CONCAT FALSE # cannot concatenate tokens 45X# COMMENT_INVISIBLE TRUE old-style comment concatenation 46X# STRING_FORMAL TRUE old-style string expansion 47X# 48XOLDDEFINE = -DOLD_PREPROCESSOR=1 49X# 50X# DEFINES collects all -D arguments for cc and lint: 51X# Change DEFINES = $(BSDDEFINE) $(CPPDEFINE) $(OLDDEFINE) 52X# for an old-style preprocessor. 53X# 54X# DEFINES = $(BSDDEFINE) $(CPPDEFINE) 55XDEFINES = $(CPPDEFINE) 56X 57XCFLAGS = -O $(DEFINES) 58X 59X# 60X# ** compile cpp 61X# 62XSRCS = cpp1.c cpp2.c cpp3.c cpp4.c cpp5.c cpp6.c 63XOBJS = cpp1.o cpp2.o cpp3.o cpp4.o cpp5.o cpp6.o 64Xcpp: $(OBJS) 65X $(CC) $(CFLAGS) $(OBJS) -o cpp 66X 67X# 68X# ** Test cpp by preprocessing itself, compiling the result, 69X# ** repeating the process and diff'ing the result. Note: this 70X# ** is not a good test of cpp, but a simple verification. 71X# ** The diff's should not report any changes. 72X# ** Note that a sed script may be executed for each compile 73X# 74Xtest: 75X cpp cpp1.c $(LINEFIX) >old.tmp1.c 76X cpp cpp2.c $(LINEFIX) >old.tmp2.c 77X cpp cpp3.c $(LINEFIX) >old.tmp3.c 78X cpp cpp4.c $(LINEFIX) >old.tmp4.c 79X cpp cpp5.c $(LINEFIX) >old.tmp5.c 80X cpp cpp6.c $(LINEFIX) >old.tmp6.c 81X $(CC) $(CFLAGS) old.tmp[123456].c 82X a.out cpp1.c >new.tmp1.c 83X a.out cpp2.c >new.tmp2.c 84X a.out cpp3.c >new.tmp3.c 85X a.out cpp4.c >new.tmp4.c 86X a.out cpp5.c >new.tmp5.c 87X a.out cpp6.c >new.tmp6.c 88X diff old.tmp1.c new.tmp1.c 89X diff old.tmp2.c new.tmp2.c 90X diff old.tmp3.c new.tmp3.c 91X diff old.tmp4.c new.tmp4.c 92X diff old.tmp5.c new.tmp5.c 93X diff old.tmp6.c new.tmp6.c 94X rm a.out old.tmp[123456].* new.tmp[123456].* 95X 96X# 97X# A somewhat more extensive test is provided by the "clock" 98X# program (which is not distributed). Substitute your favorite 99X# macro-rich program here. 100X# 101Xclock: clock.c cpp 102X cpp clock.c $(LINEFIX) >temp.cpp.c 103X cc temp.cpp.c -lcurses -ltermcap -o clock 104X rm temp.cpp.c 105X 106X# 107X# ** Lint the code 108X# 109X 110Xlint: $(SRCS) 111X lint $(LINTFLAGS) $(DEFINES) $(SRCS) 112X 113X# 114X# ** Remove unneeded files 115X# 116Xclean: 117X rm -f $(OBJS) cpp 118X 119X# 120X# ** Rebuild the archive files needed to distribute cpp 121X# ** Uses the Decus C archive utility. 122X# 123X 124Xarchc: archc.c 125X $(CC) $(CFLAGS) archc.c -o archc 126X 127Xarchx: archx.c 128X $(CC) $(CFLAGS) archx.c -o archx 129X 130Xarchive: archc 131X archc readme.txt cpp.mem archx.c archc.c cpp.rno makefile.txt \ 132X cpp*.h >cpp1.arc 133X archc cpp1.c cpp2.c cpp3.c >cpp2.arc 134X archc cpp4.c cpp5.c cpp6.c >cpp3.arc 135X 136X# 137X# Object module dependencies 138X# 139X 140Xcpp1.o : cpp1.c cpp.h cppdef.h 141X 142Xcpp2.o : cpp2.c cpp.h cppdef.h 143X 144Xcpp3.o : cpp3.c cpp.h cppdef.h 145X 146Xcpp4.o : cpp4.c cpp.h cppdef.h 147X 148Xcpp5.o : cpp5.c cpp.h cppdef.h 149X 150Xcpp6.o : cpp6.c cpp.h cppdef.h 151X 152X 153END-of-makefile.txt 154echo x - readme.txt 155sed 's/^X//' >readme.txt << 'END-of-readme.txt' 156X 157XDecus cpp is a public-domain implementation of the C preprocessor. 158XIt runs on VMS native (Vax C), VMS compatibilty mode (Decus C), 159XRSX-11M, RSTS/E, P/OS, and RT11, as well as on several varieties 160Xof Unix, including Ultrix. Decus cpp attempts to implement features 161Xin the Draft ANSI Standard for the C language. It should be noted, 162Xhowever, that this standard is under active development: the current 163Xdraft of the standard explicitly states that "readers are requested 164Xnot to specify or claim conformance to this draft." Thus readers 165Xand users of Decus cpp should not assume that it conforms to the 166Xdraft standard, or that it will conform to the actual C language 167Xstandard. 168X 169XThese notes describe how to extract the cpp source files, configure it 170Xfor your needs, and mention a few design decisions that may be of interest 171Xto maintainers. 172X 173X Installation 174X 175XBecause the primary development of cpp was not on Unix, it 176Xis distributed using the Decus C archive program (quite similar 177Xto the archiver published in Kernighan and Plauger's Software 178XTools). To extract the files from the net.sources distribution, 179Xsave this message as cpp1.arc and the other two distribution 180Xfiles as cpp2.arc and cpp3.arc. Then, using your favorite editor, 181Xlocate the archx.c program, just following the line beginning with 182X"-h- archx.c" -- the format of the distribution is just: 183X 184X -h- readme.txt 185X ... this file 186X -h- cpp.mem 187X ... description of cpp 188X -h- archx.c 189X ... archx.c program -- extracts archives 190X -h- archc.c 191X ... archc.c program -- creates archives 192X 193XCompile archx.c -- it shouldn't require any special editing. 194XThen run it as follows: 195X 196X archx *.arc 197X 198XYou do not need to remove mail headers from the saved messages. 199X 200XYou should then read through cppdef.h to make sure the HOST and 201XTARGET (and other implementation-specific) definitions are set 202Xcorrectly for your machine, editing them as needed. 203X 204XYou may then copy makefile.txt to Makefile, editing it as needed 205Xfor your particular system. On Unix, cpp should be compiled 206Xby make without further difficulty. On other operating systems, 207Xyou should compile the six source modules, linking them together. 208XNote that, on Decus C based systems, you must extend the default 209Xstack allocation. The Decus C build utility will create the 210Xappropriate command file. 211X 212X Support Notes 213X 214XThe USENET distribution kit was designed to keep all submissions around 215X50,000 bytes: 216X 217Xcpp1.arc: 218X readme.txt This file 219X cpp.mem Documentation page (see below) 220X archx.c Archive extraction program 221X archc.c Archive construction program 222X cpp.rno Source for cpp.mem (see below) 223X makefile.txt Unix makefile -- copy to Makefile 224X cpp.h Main header file (structure def's and globals) 225X cppdef.h Configuration file (host and target definitions) 226X 227Xcpp2.arc: 228X cpp1.c Mainline code, documentation master sources 229X cpp2.c most #control processing 230X cpp3.c filename stuff and command line parsing 231Xcpp3.arc: 232X cpp4.c #define processor 233X cpp5.c #if <expr> processor 234X cpp6.c Support code (symbol table and I/O routines) 235X 236XCpp intentionally does not rely on the presence of a full-scale 237Xmacro preprocessor, it does require the simple parameter substitution 238Xpreprocessor capabilities of Unix V6 and Decus C. If your C 239Xlanguage lacks full preprocessing, you should make sure "nomacargs" 240Xis #define'd in cpp.h. (This is done automatically by the Decus C 241Xcompiler.) 242X 243XThe documentation (manual page) for cpp is included as cpp.mem 244Xand cpp.rno. Cpp.rno is in Dec Runoff format, built by a Decus C 245Xutility (getrno) from original source which is embedded in cpp1.c. 246XTo my knowledge, there is no equivalent program that creates 247Xthe nroff source appropriate for Unix. 248X 249XI would be happy to receive fixes to any problems you encounter. 250XAs I do not maintain distribution kit base-levels, bare-bones 251Xdiff listings without sufficient context are not very useful. 252XIt is unlikely that I can find time to help you with other 253Xdifficulties. 254X 255X Acknowledgements 256X 257XI received a great deal of help from many people in debugging cpp. 258XAlan Feuer and Sam Kendall used "state of the art" run-time code 259Xcheckers to locate several errors. Ed Keiser found problems when 260Xcpp was used on machines with different int and pointer sizes. 261XDave Conroy helped with the initial debugging, while Arthur Olsen 262Xand George Rosenberg found (and solved) several problems in the 263Xfirst USENET release. 264X 265XMartin Minow 266Xdecvax!minow 267X 268END-of-readme.txt 269echo x - cpp.mem 270sed 's/^X//' >cpp.mem << 'END-of-cpp.mem' 271X 272X 273X 274X 275X 1.0 C Pre-Processor 276X 277X 278X 279X ******* 280X * cpp * 281X ******* 282X 283X 284X 285X NAME: cpp -- C Pre-Processor 286X 287X SYNOPSIS: 288X 289X cpp [-options] [infile [outfile]] 290X 291X DESCRIPTION: 292X 293X CPP reads a C source file, expands macros and include 294X files, and writes an input file for the C compiler. If 295X no file arguments are given, CPP reads from stdin and 296X writes to stdout. If one file argument is given, it 297X will define the input file, while two file arguments 298X define both input and output files. The file name "-" 299X is a synonym for stdin or stdout as appropriate. 300X 301X The following options are supported. Options may be 302X given in either case. 303X 304X -C If set, source-file comments are written 305X to the output file. This allows the 306X output of CPP to be used as the input to 307X a program, such as lint, that expects 308X commands embedded in specially-formatted 309X comments. 310X 311X -Dname=value Define the name as if the programmer 312X wrote 313X 314X #define name value 315X 316X at the start of the first file. If 317X "=value" is not given, a value of "1" 318X will be used. 319X 320X On non-unix systems, all alphabetic text 321X will be forced to upper-case. 322X 323X -E Always return "success" to the operating 324X system, even if errors were detected. 325X Note that some fatal errors, such as a 326X missing #include file, will terminate 327X CPP, returning "failure" even if the -E 328X option is given. 329X Page 2 330X cpp C Pre-Processor 331X 332X 333X -Idirectory Add this directory to the list of 334X directories searched for #include "..." 335X and #include <...> commands. Note that 336X there is no space between the "-I" and 337X the directory string. More than one -I 338X command is permitted. On non-Unix 339X systems "directory" is forced to 340X upper-case. 341X 342X -N CPP normally predefines some symbols 343X defining the target computer and 344X operating system. If -N is specified, 345X no symbols will be predefined. If -N -N 346X is specified, the "always present" 347X symbols, __LINE__, __FILE__, and 348X __DATE__ are not defined. 349X 350X -Stext CPP normally assumes that the size of 351X the target computer's basic variable 352X types is the same as the size of these 353X types of the host computer. (This can 354X be overridden when CPP is compiled, 355X however.) The -S option allows dynamic 356X respecification of these values. "text" 357X is a string of numbers, separated by 358X commas, that specifies correct sizes. 359X The sizes must be specified in the exact 360X order: 361X 362X char short int long float double 363X 364X If you specify the option as "-S*text", 365X pointers to these types will be 366X specified. -S* takes one additional 367X argument for pointer to function (e.g. 368X int (*)()) 369X 370X For example, to specify sizes 371X appropriate for a PDP-11, you would 372X write: 373X 374X c s i l f d func 375X -S1,2,2,2,4,8, 376X -S*2,2,2,2,2,2,2 377X 378X Note that all values must be specified. 379X 380X -Uname Undefine the name as if 381X 382X #undef name 383X 384X were given. On non-Unix systems, "name" 385X will be forced to upper-case. 386X Page 3 387X cpp C Pre-Processor 388X 389X 390X -Xnumber Enable debugging code. If no value is 391X given, a value of 1 will be used. (For 392X maintenence of CPP only.) 393X 394X 395X PRE-DEFINED VARIABLES: 396X 397X When CPP begins processing, the following variables will 398X have been defined (unless the -N option is specified): 399X 400X Target computer (as appropriate): 401X 402X pdp11, vax, M68000 m68000 m68k 403X 404X Target operating system (as appropriate): 405X 406X rsx, rt11, vms, unix 407X 408X Target compiler (as appropriate): 409X 410X decus, vax11c 411X 412X The implementor may add definitions to this list. The 413X default definitions match the definition of the host 414X computer, operating system, and C compiler. 415X 416X The following are always available unless undefined (or 417X -N was specified twice): 418X 419X __FILE__ The input (or #include) file being 420X compiled (as a quoted string). 421X 422X __LINE__ The line number being compiled. 423X 424X __DATE__ The date and time of compilation as a 425X Unix ctime quoted string (the trailing 426X newline is removed). Thus, 427X 428X printf("Bug at line %s,", __LINE__); 429X printf(" source file %s", __FILE__); 430X printf(" compiled on %s", __DATE__); 431X 432X 433X DRAFT PROPOSED ANSI STANDARD CONSIDERATIONS: 434X 435X The current version of the Draft Proposed Standard 436X explicitly states that "readers are requested not to 437X specify or claim conformance to this draft." Readers and 438X users of Decus CPP should not assume that Decus CPP 439X conforms to the standard, or that it will conform to the 440X actual C Language Standard. 441X 442X When CPP is itself compiled, many features of the Draft 443X Proposed Standard that are incompatible with existing 444X Page 4 445X cpp C Pre-Processor 446X 447X 448X preprocessors may be disabled. See the comments in 449X CPP's source for details. 450X 451X The latest version of the Draft Proposed Standard (as 452X reflected in Decus CPP) is dated November 12, 1984. 453X 454X Comments are removed from the input text. The comment 455X is replaced by a single space character. The -C option 456X preserves comments, writing them to the output file. 457X 458X The '$' character is considered to be a letter. This is 459X a permitted extension. 460X 461X The following new features of C are processed by CPP: 462X 463X #elif expression (#else #if) 464X '\xNNN' (Hexadecimal constant) 465X '\a' (Ascii BELL) 466X '\v' (Ascii Vertical Tab) 467X #if defined NAME 1 if defined, 0 if not 468X #if defined (NAME) 1 if defined, 0 if not 469X #if sizeof (basic type) 470X unary + 471X 123U, 123LU Unsigned ints and longs. 472X 12.3L Long double numbers 473X token#token Token concatenation 474X #include token Expands to filename 475X 476X The Draft Proposed Standard has extended C, adding a 477X constant string concatenation operator, where 478X 479X "foo" "bar" 480X 481X is regarded as the single string "foobar". (This does 482X not affect CPP's processing but does permit a limited 483X form of macro argument substitution into strings as will 484X be discussed.) 485X 486X The Standard Committee plans to add token concatenation 487X to #define command lines. One suggested implementation 488X is as follows: the sequence "Token1#Token2" is treated 489X as if the programmer wrote "Token1Token2". This could 490X be used as follows: 491X 492X #line 123 493X #define ATLINE foo#__LINE__ 494X 495X ATLINE would be defined as foo123. 496X 497X Note that "Token2" must either have the format of an 498X identifier or be a string of digits. Thus, the string 499X 500X #define ATLINE foo#1x3 501X Page 5 502X cpp C Pre-Processor 503X 504X 505X generates two tokens: "foo1" and "x3". 506X 507X If the tokens T1 and T2 are concatenated into T3, this 508X implementation operates as follows: 509X 510X 1. Expand T1 if it is a macro. 511X 2. Expand T2 if it is a macro. 512X 3. Join the tokens, forming T3. 513X 4. Expand T3 if it is a macro. 514X 515X A macro formal parameter will be substituted into a 516X string or character constant if it is the only component 517X of that constant: 518X 519X #define VECSIZE 123 520X #define vprint(name, size) \ 521X printf("name" "[" "size" "] = {\n") 522X ... vprint(vector, VECSIZE); 523X 524X expands (effectively) to 525X 526X vprint("vector[123] = {\n"); 527X 528X Note that this will be useful if your C compiler 529X supports the new string concatenation operation noted 530X above. As implemented here, if you write 531X 532X #define string(arg) "arg" 533X ... string("foo") ... 534X 535X This implementation generates "foo", rather than the 536X strictly correct ""foo"" (which will probably generate 537X an error message). This is, strictly speaking, an error 538X in CPP and may be removed from future releases. 539X 540X ERROR MESSAGES: 541X 542X Many. CPP prints warning or error messages if you try 543X to use multiple-byte character constants 544X (non-transportable) if you #undef a symbol that was not 545X defined, or if your program has potentially nested 546X comments. 547X 548X AUTHOR: 549X 550X Martin Minow 551X 552X BUGS: 553X 554X The #if expression processor uses signed integers only. 555X I.e, #if 0xFFFFu < 0 may be TRUE. 556X 557END-of-cpp.mem 558echo x - cpp.h 559sed 's/^X//' >cpp.h << 'END-of-cpp.h' 560X 561X/* 562X * I n t e r n a l D e f i n i t i o n s f o r C P P 563X * 564X * In general, definitions in this file should not be changed. 565X */ 566X 567X#ifndef TRUE 568X#define TRUE 1 569X#define FALSE 0 570X#endif 571X#ifndef EOS 572X/* 573X * This is predefined in Decus C 574X */ 575X#define EOS '\0' /* End of string */ 576X#endif 577X#define EOF_CHAR 0 /* Returned by get() on eof */ 578X#define NULLST ((char *) NULL) /* Pointer to nowhere (linted) */ 579X#define DEF_NOARGS (-1) /* #define foo vs #define foo() */ 580X 581X/* 582X * The following may need to change if the host system doesn't use ASCII. 583X */ 584X#define DEF_MAGIC 0x1D /* Magic for #defines */ 585X#define TOK_SEP 0x1E /* Token concatenation delim. */ 586X#define COM_SEP 0x1F /* Magic comment separator */ 587X 588X/* 589X * Note -- in Ascii, the following will map macro formals onto DEL + the 590X * C1 control character region (decimal 128 .. (128 + PAR_MAC)) which will 591X * be ok as long as PAR_MAC is less than 33). Note that the last PAR_MAC 592X * value is reserved for string substitution. 593X */ 594X 595X#define MAC_PARM 0x7F /* Macro formals start here */ 596X#if PAR_MAC >= 33 597X assertion fails -- PAR_MAC isn't less than 33 598X#endif 599X#define LASTPARM (PAR_MAC - 1) 600X 601X/* 602X * Character type codes. 603X */ 604X 605X#define INV 0 /* Invalid, must be zero */ 606X#define OP_EOE INV /* End of expression */ 607X#define DIG 1 /* Digit */ 608X#define LET 2 /* Identifier start */ 609X#define FIRST_BINOP OP_ADD 610X#define OP_ADD 3 611X#define OP_SUB 4 612X#define OP_MUL 5 613X#define OP_DIV 6 614X#define OP_MOD 7 615X#define OP_ASL 8 616X#define OP_ASR 9 617X#define OP_AND 10 /* &, not && */ 618X#define OP_OR 11 /* |, not || */ 619X#define OP_XOR 12 620X#define OP_EQ 13 621X#define OP_NE 14 622X#define OP_LT 15 623X#define OP_LE 16 624X#define OP_GE 17 625X#define OP_GT 18 626X#define OP_ANA 19 /* && */ 627X#define OP_ORO 20 /* || */ 628X#define OP_QUE 21 /* ? */ 629X#define OP_COL 22 /* : */ 630X#define OP_CMA 23 /* , (relevant?) */ 631X#define LAST_BINOP OP_CMA /* Last binary operand */ 632X/* 633X * The following are unary. 634X */ 635X#define FIRST_UNOP OP_PLU /* First Unary operand */ 636X#define OP_PLU 24 /* + (draft ANSI standard) */ 637X#define OP_NEG 25 /* - */ 638X#define OP_COM 26 /* ~ */ 639X#define OP_NOT 27 /* ! */ 640X#define LAST_UNOP OP_NOT 641X#define OP_LPA 28 /* ( */ 642X#define OP_RPA 29 /* ) */ 643X#define OP_END 30 /* End of expression marker */ 644X#define OP_MAX (OP_END + 1) /* Number of operators */ 645X#define OP_FAIL (OP_END + 1) /* For error returns */ 646X 647X/* 648X * The following are for lexical scanning only. 649X */ 650X 651X#define QUO 65 /* Both flavors of quotation */ 652X#define DOT 66 /* . might start a number */ 653X#define SPA 67 /* Space and tab */ 654X#define BSH 68 /* Just a backslash */ 655X#define END 69 /* EOF */ 656X 657X/* 658X * These bits are set in ifstack[] 659X */ 660X#define WAS_COMPILING 1 /* TRUE if compile set at entry */ 661X#define ELSE_SEEN 2 /* TRUE when #else processed */ 662X#define TRUE_SEEN 4 /* TRUE when #if TRUE processed */ 663X 664X/* 665X * Define bits for the basic types and their adjectives 666X */ 667X 668X#define T_CHAR 1 669X#define T_INT 2 670X#define T_FLOAT 4 671X#define T_DOUBLE 8 672X#define T_SHORT 16 673X#define T_LONG 32 674X#define T_SIGNED 64 675X#define T_UNSIGNED 128 676X#define T_PTR 256 /* Pointer */ 677X#define T_FPTR 512 /* Pointer to functions */ 678X 679X/* 680X * The DEFBUF structure stores information about #defined 681X * macros. Note that the defbuf->repl information is always 682X * in malloc storage. 683X */ 684X 685Xtypedef struct defbuf { 686X struct defbuf *link; /* Next define in chain */ 687X char *repl; /* -> replacement */ 688X int hash; /* Symbol table hash */ 689X int nargs; /* For define(args) */ 690X char name[1]; /* #define name */ 691X} DEFBUF; 692X 693X/* 694X * The FILEINFO structure stores information about open files 695X * and macros being expanded. 696X */ 697X 698Xtypedef struct fileinfo { 699X char *bptr; /* Buffer pointer */ 700X int line; /* for include or macro */ 701X FILE *fp; /* File if non-null */ 702X struct fileinfo *parent; /* Link to includer */ 703X char *filename; /* File/macro name */ 704X char *progname; /* From #line statement */ 705X unsigned int unrecur; /* For macro recursion */ 706X char buffer[1]; /* current input line */ 707X} FILEINFO; 708X 709X/* 710X * The SIZES structure is used to store the values for #if sizeof 711X */ 712X 713Xtypedef struct sizes { 714X short bits; /* If this bit is set, */ 715X short size; /* this is the datum size value */ 716X short psize; /* this is the pointer size */ 717X} SIZES; 718X/* 719X * nomacarg is a built-in #define on Decus C. 720X */ 721X 722X#ifdef nomacarg 723X#define cput output /* cput concatenates tokens */ 724X#else 725X#if COMMENT_INVISIBLE 726X#define cput(c) { if (c != TOK_SEP && c != COM_SEP) putchar(c); } 727X#else 728X#define cput(c) { if (c != TOK_SEP) putchar(c); } 729X#endif 730X#endif 731X 732X#ifndef nomacarg 733X#define streq(s1, s2) (strcmp(s1, s2) == 0) 734X#endif 735X 736X/* 737X * Error codes. VMS uses system definitions. 738X * Decus C codes are defined in stdio.h. 739X * Others are cooked to order. 740X */ 741X 742X#if HOST == SYS_VMS 743X#include <ssdef.h> 744X#include <stsdef.h> 745X#define IO_NORMAL (SS$_NORMAL | STS$M_INHIB_MSG) 746X#define IO_ERROR SS$_ABORT 747X#endif 748X/* 749X * Note: IO_NORMAL and IO_ERROR are defined in the Decus C stdio.h file 750X */ 751X#ifndef IO_NORMAL 752X#define IO_NORMAL 0 753X#endif 754X#ifndef IO_ERROR 755X#define IO_ERROR 1 756X#endif 757X 758X/* 759X * Externs 760X */ 761X 762Xextern int line; /* Current line number */ 763Xextern int wrongline; /* Force #line to cc pass 1 */ 764Xextern char type[]; /* Character classifier */ 765Xextern char token[IDMAX + 1]; /* Current input token */ 766Xextern int instring; /* TRUE if scanning string */ 767Xextern int inmacro; /* TRUE if scanning #define */ 768Xextern int errors; /* Error counter */ 769Xextern int recursion; /* Macro depth counter */ 770Xextern char ifstack[BLK_NEST]; /* #if information */ 771X#define compiling ifstack[0] 772Xextern char *ifptr; /* -> current ifstack item */ 773Xextern char *incdir[NINCLUDE]; /* -i directories */ 774Xextern char **incend; /* -> active end of incdir */ 775Xextern int cflag; /* -C option (keep comments) */ 776Xextern int eflag; /* -E option (ignore errors) */ 777Xextern int nflag; /* -N option (no pre-defines) */ 778Xextern int rec_recover; /* unwind recursive macros */ 779Xextern char *preset[]; /* Standard predefined symbols */ 780Xextern char *magic[]; /* Magic predefined symbols */ 781Xextern FILEINFO *infile; /* Current input file */ 782Xextern char work[NWORK + 1]; /* #define scratch */ 783Xextern char *workp; /* Free space in work */ 784X#if DEBUG 785Xextern int debug; /* Debug level */ 786X#endif 787Xextern int keepcomments; /* Don't remove comments if set */ 788Xextern SIZES size_table[]; /* For #if sizeof sizes */ 789Xextern char *getmem(); /* Get memory or die. */ 790Xextern DEFBUF *lookid(); /* Look for a #define'd thing */ 791Xextern DEFBUF *defendel(); /* Symbol table enter/delete */ 792Xextern char *savestring(); /* Stuff string in malloc mem. */ 793Xextern char *strcpy(); 794Xextern char *strcat(); 795Xextern char *strrchr(); 796Xextern char *strchr(); 797Xextern long time(); 798X/* extern char *sprintf(); /* Lint needs this */ 799END-of-cpp.h 800echo x - cppdef.h 801sed 's/^X//' >cppdef.h << 'END-of-cppdef.h' 802X/* 803X * S y s t e m D e p e n d e n t 804X * D e f i n i t i o n s f o r C P P 805X * 806X * Definitions in this file may be edited to configure CPP for particular 807X * host operating systems and target configurations. 808X * 809X * NOTE: cpp assumes it is compiled by a compiler that supports macros 810X * with arguments. If this is not the case (as for Decus C), #define 811X * nomacarg -- and provide function equivalents for all macros. 812X * 813X * cpp also assumes the host and target implement the Ascii character set. 814X * If this is not the case, you will have to do some editing here and there. 815X */ 816X 817X/* 818X * This redundant definition of TRUE and FALSE works around 819X * a limitation of Decus C. 820X */ 821X#ifndef TRUE 822X#define TRUE 1 823X#define FALSE 0 824X#endif 825X 826X/* 827X * Define the HOST operating system. This is needed so that 828X * cpp can use appropriate filename conventions. 829X */ 830X#define SYS_UNKNOWN 0 831X#define SYS_UNIX 1 832X#define SYS_VMS 2 833X#define SYS_RSX 3 834X#define SYS_RT11 4 835X#define SYS_LATTICE 5 836X#define SYS_ONYX 6 837X#define SYS_68000 7 838X#define SYS_GCOS 8 839X#define SYS_IBM 9 840X#define SYS_OS 10 841X#define SYS_TSS 11 842X 843X#ifndef HOST 844X#ifdef unix 845X#define HOST SYS_UNIX 846X#else 847X#ifdef vms 848X#define HOST SYS_VMS 849X#else 850X#ifdef rsx 851X#define HOST SYS_RSX 852X#else 853X#ifdef rt11 854X#define HOST SYS_RT11 855X#else 856X#ifdef dmert 857X#define HOST SYS_DMERT 858X#else 859X#ifdef gcos 860X#define HOST SYS_GCOS 861X#else 862X#ifdef ibm 863X#define HOST SYS_IBM 864X#else 865X#ifdef os 866X#define HOST SYS_OS 867X#else 868X#ifdef tss 869X#define HOST SYS_TSS 870X#endif 871X#endif 872X#endif 873X#endif 874X#endif 875X#endif 876X#endif 877X#endif 878X#endif 879X 880X#ifndef HOST 881X#define HOST SYS_UNKNOWN 882X#endif 883X 884X/* 885X * We assume that the target is the same as the host system 886X */ 887X#ifndef TARGET 888X#define TARGET HOST 889X#endif 890X 891X/* 892X * In order to predefine machine-dependent constants, 893X * several strings are defined here: 894X * 895X * MACHINE defines the target cpu (by name) 896X * SYSTEM defines the target operating system 897X * COMPILER defines the target compiler 898X * 899X * The above may be #defined as "" if they are not wanted. 900X * They should not be #defined as NULL. 901X * 902X * LINE_PREFIX defines the # output line prefix, if not "line" 903X * This should be defined as "" if cpp is to replace 904X * the "standard" C pre-processor. 905X * 906X * FILE_LOCAL marks functions which are referenced only in the 907X * file they reside. Some C compilers allow these 908X * to be marked "static" even though they are referenced 909X * by "extern" statements elsewhere. 910X * 911X * OK_DOLLAR Should be set TRUE if $ is a valid alphabetic character 912X * in identifiers (default), or zero if $ is invalid. 913X * Default is TRUE. 914X * 915X * OK_CONCAT Should be set TRUE if # may be used to concatenate 916X * tokens in macros (per the Ansi Draft Standard) or 917X * FALSE for old-style # processing (needed if cpp is 918X * to process assembler source code). 919X * 920X * OK_DATE Predefines the compilation date if set TRUE. 921X * Not permitted by the Nov. 12, 1984 Draft Standard. 922X * 923X * S_CHAR etc. Define the sizeof the basic TARGET machine word types. 924X * By default, sizes are set to the values for the HOST 925X * computer. If this is inappropriate, see the code in 926X * cpp3.c for details on what to change. Also, if you 927X * have a machine where sizeof (signed int) differs from 928X * sizeof (unsigned int), you will have to edit code and 929X * tables in cpp3.c (and extend the -S option definition.) 930X * 931X * CPP_LIBRARY May be defined if you have a site-specific include directory 932X * which is to be searched *before* the operating-system 933X * specific directories. 934X */ 935X 936X#if TARGET == SYS_LATTICE 937X/* 938X * We assume the operating system is pcdos for the IBM-PC. 939X * We also assume the small model (just like the PDP-11) 940X */ 941X#define MACHINE "i8086" 942X#define SYSTEM "pcdos" 943X#endif 944X 945X#if TARGET == SYS_ONYX 946X#define MACHINE "z8000" 947X#define SYSTEM "unix" 948X#endif 949X 950X#if TARGET == SYS_VMS 951X#define MACHINE "vax" 952X#define SYSTEM "vms" 953X#define COMPILER "vax11c" 954X#endif 955X 956X#if TARGET == SYS_RSX 957X#define MACHINE "pdp11" 958X#define SYSTEM "rsx" 959X#define COMPILER "decus" 960X#endif 961X 962X#if TARGET == SYS_RT11 963X#define MACHINE "pdp11" 964X#define SYSTEM "rt11" 965X#define COMPILER "decus" 966X#endif 967X 968X#if TARGET == SYS_68000 969X/* 970X * All three machine designators have been seen in various systems. 971X * Warning -- compilers differ as to sizeof (int). cpp3 assumes that 972X * sizeof (int) == 2 973X */ 974X#define MACHINE "M68000", "m68000", "m68k" 975X#define SYSTEM "unix" 976X#endif 977X 978X#if TARGET == SYS_UNIX 979X#define SYSTEM "unix" 980X#ifdef pdp11 981X#define MACHINE "pdp11" 982X#endif 983X#ifdef vax 984X#define MACHINE "vax" 985X#endif 986X#ifdef u370 987X#define MACHINE "u370" 988X#endif 989X#ifdef interdata 990X#define MACHINE "interdata" 991X#endif 992X#ifdef u3b 993X#define MACHINE "u3b" 994X#endif 995X#ifdef u3b5 996X#define MACHINE "u3b5" 997X#endif 998X#ifdef u3b2 999X#define MACHINE "u3b2" 1000X#endif 1001X#ifdef u3b20d 1002X#define MACHINE "u3b20d" 1003X#endif 1004X#endif 1005X#endif 1006X 1007X/* 1008X * defaults 1009X */ 1010X 1011X#ifndef MSG_PREFIX 1012X#define MSG_PREFIX "cpp: " 1013X#endif 1014X 1015X#ifndef LINE_PREFIX 1016X#ifdef decus 1017X#define LINE_PREFIX "" 1018X#else 1019X#define LINE_PREFIX "line" 1020X#endif 1021X#endif 1022X 1023X/* 1024X * OLD_PREPROCESSOR forces the definition of OK_DOLLAR, OK_CONCAT, 1025X * COMMENT_INVISIBLE, and STRING_FORMAL to values appropriate for 1026X * an old-style preprocessor. 1027X */ 1028X 1029X#ifndef OLD_PREPROCESSOR 1030X#define OLD_PREPROCESSOR FALSE 1031X#endif 1032X 1033X#if OLD_PREPROCESSOR 1034X#define OK_DOLLAR FALSE 1035X#define OK_CONCAT FALSE 1036X#define COMMENT_INVISIBLE TRUE 1037X#define STRING_FORMAL TRUE 1038X#endif 1039X 1040X/* 1041X * RECURSION_LIMIT may be set to -1 to disable the macro recursion test. 1042X */ 1043X#ifndef RECURSION_LIMIT 1044X#define RECURSION_LIMIT 1000 1045X#endif 1046X 1047X/* 1048X * BITS_CHAR may be defined to set the number of bits per character. 1049X * it is needed only for multi-byte character constants. 1050X */ 1051X#ifndef BITS_CHAR 1052X#define BITS_CHAR 8 1053X#endif 1054X 1055X/* 1056X * BIG_ENDIAN is set TRUE on machines (such as the IBM 360 series) 1057X * where 'ab' stores 'a' in the high-bits and 'b' in the low-bits. 1058X * It is set FALSE on machines (such as the PDP-11 and Vax-11) 1059X * where 'ab' stores 'a' in the low-bits and 'b' in the high-bits. 1060X * (Or is it the other way around?) -- Warning: BIG_ENDIAN code is untested. 1061X */ 1062X#ifndef BIG_ENDIAN 1063X#define BIG_ENDIAN FALSE 1064X#endif 1065X 1066X/* 1067X * COMMENT_INVISIBLE may be defined to allow "old-style" comment 1068X * processing, whereby the comment becomes a zero-length token 1069X * delimiter. This permitted tokens to be concatenated in macro 1070X * expansions. This was removed from the Draft Ansi Standard. 1071X */ 1072X#ifndef COMMENT_INVISIBLE 1073X#define COMMENT_INVISIBLE FALSE 1074X#endif 1075X 1076X/* 1077X * STRING_FORMAL may be defined to allow recognition of macro parameters 1078X * anywhere in replacement strings. This was removed from the Draft Ansi 1079X * Standard and a limited recognition capability added. 1080X */ 1081X#ifndef STRING_FORMAL 1082X#define STRING_FORMAL FALSE 1083X#endif 1084X 1085X/* 1086X * OK_DOLLAR enables use of $ as a valid "letter" in identifiers. 1087X * This is a permitted extension to the Ansi Standard and is required 1088X * for e.g., VMS, RSX-11M, etc. It should be set FALSE if cpp is 1089X * used to preprocess assembler source on Unix systems. OLD_PREPROCESSOR 1090X * sets OK_DOLLAR FALSE for that reason. 1091X */ 1092X#ifndef OK_DOLLAR 1093X#define OK_DOLLAR TRUE 1094X#endif 1095X 1096X/* 1097X * OK_CONCAT enables (one possible implementation of) token concatenation. 1098X * If cpp is used to preprocess Unix assembler source, this should be 1099X * set FALSE as the concatenation character, #, is used by the assembler. 1100X */ 1101X#ifndef OK_CONCAT 1102X#define OK_CONCAT TRUE 1103X#endif 1104X 1105X/* 1106X * OK_DATE may be enabled to predefine today's date as a string 1107X * at the start of each compilation. This is apparently not permitted 1108X * by the Draft Ansi Standard. 1109X */ 1110X#ifndef OK_DATE 1111X#define OK_DATE TRUE 1112X#endif 1113X 1114X/* 1115X * Some common definitions. 1116X */ 1117X 1118X#ifndef DEBUG 1119X#define DEBUG FALSE 1120X#endif 1121X 1122X/* 1123X * The following definitions are used to allocate memory for 1124X * work buffers. In general, they should not be modified 1125X * by implementors. 1126X * 1127X * PAR_MAC The maximum number of #define parameters (31 per Standard) 1128X * Note: we need another one for strings. 1129X * IDMAX The longest identifier, 31 per Ansi Standard 1130X * NBUFF Input buffer size 1131X * NWORK Work buffer size -- the longest macro 1132X * must fit here after expansion. 1133X * NEXP The nesting depth of #if expressions 1134X * NINCLUDE The number of directories that may be specified 1135X * on a per-system basis, or by the -I option. 1136X * BLK_NEST The number of nested #if's permitted. 1137X */ 1138X 1139X#define IDMAX 31 1140X#define PAR_MAC (31 + 1) 1141X#define NBUFF 1024 1142X#define NWORK 1024 1143X#define NEXP 128 1144X#define NINCLUDE 7 1145X#define NPARMWORK (NWORK * 2) 1146X#define BLK_NEST 32 1147X 1148X/* 1149X * Some special constants. These may need to be changed if cpp 1150X * is ported to a wierd machine. 1151X * 1152X * NOTE: if cpp is run on a non-ascii machine, ALERT and VT may 1153X * need to be changed. They are used to implement the proposed 1154X * ANSI standard C control characters '\a' and '\v' only. 1155X * DEL is used to tag macro tokens to prevent #define foo foo 1156X * from looping. Note that we don't try to prevent more elaborate 1157X * #define loops from occurring. 1158X */ 1159X 1160X#ifndef ALERT 1161X#define ALERT '\007' /* '\a' is "Bell" */ 1162X#endif 1163X 1164X#ifndef VT 1165X#define VT '\013' /* Vertical Tab CTRL/K */ 1166X#endif 1167X 1168X 1169X#ifndef FILE_LOCAL 1170X#ifdef decus 1171X#define FILE_LOCAL static 1172X#else 1173X#ifdef vax11c 1174X#define FILE_LOCAL static 1175X#else 1176X#define FILE_LOCAL /* Others are global */ 1177X#endif 1178X#endif 1179X#endif 1180X 1181END-of-cppdef.h 1182echo x - cpp2.c 1183sed 's/^X//' >cpp2.c << 'END-of-cpp2.c' 1184X/* 1185X * C P P 2 . C 1186X * 1187X * Process #control lines 1188X * 1189X * Edit history 1190X * 13-Nov-84 MM Split from cpp1.c 1191X */ 1192X 1193X#include <stdio.h> 1194X#include <ctype.h> 1195X#include "cppdef.h" 1196X#include "cpp.h" 1197X#if HOST == SYS_VMS 1198X/* 1199X * Include the rms stuff. (We can't just include rms.h as it uses the 1200X * VaxC-specific library include syntax that Decus CPP doesn't support. 1201X * By including things by hand, we can CPP ourself.) 1202X */ 1203X#include <nam.h> 1204X#include <fab.h> 1205X#include <rab.h> 1206X#include <rmsdef.h> 1207X#endif 1208X 1209X/* 1210X * Generate (by hand-inspection) a set of unique values for each control 1211X * operator. Note that this is not guaranteed to work for non-Ascii 1212X * machines. CPP won't compile if there are hash conflicts. 1213X */ 1214X 1215X#define L_assert ('a' + ('s' << 1)) 1216X#define L_define ('d' + ('f' << 1)) 1217X#define L_elif ('e' + ('i' << 1)) 1218X#define L_else ('e' + ('s' << 1)) 1219X#define L_endif ('e' + ('d' << 1)) 1220X#define L_ident ('i' + ('e' << 1)) 1221X#define L_if ('i' + (EOS << 1)) 1222X#define L_ifdef ('i' + ('d' << 1)) 1223X#define L_ifndef ('i' + ('n' << 1)) 1224X#define L_include ('i' + ('c' << 1)) 1225X#define L_line ('l' + ('n' << 1)) 1226X#define L_nogood (EOS + (EOS << 1)) /* To catch #i */ 1227X#define L_pragma ('p' + ('a' << 1)) 1228X#define L_sccs ('s' + ('c' << 1)) 1229X#define L_undef ('u' + ('d' << 1)) 1230X#if DEBUG 1231X#define L_debug ('d' + ('b' << 1)) /* #debug */ 1232X#define L_nodebug ('n' + ('d' << 1)) /* #nodebug */ 1233X#endif 1234X 1235Xint 1236Xcontrol(counter) 1237Xint counter; /* Pending newline counter */ 1238X/* 1239X * Process #control lines. Simple commands are processed inline, 1240X * while complex commands have their own subroutines. 1241X * 1242X * The counter is used to force out a newline before #line, and 1243X * #pragma commands. This prevents these commands from ending up at 1244X * the end of the previous line if cpp is invoked with the -C option. 1245X */ 1246X{ 1247X register int c; 1248X register char *tp; 1249X register int hash; 1250X char *ep; 1251X 1252X c = skipws(); 1253X if (c == '\n' || c == EOF_CHAR) 1254X return (counter + 1); 1255X if (!isdigit(c)) 1256X scanid(c); /* Get #word to token[] */ 1257X else { 1258X unget(); /* Hack -- allow #123 as a */ 1259X strcpy(token, "line"); /* synonym for #line 123 */ 1260X } 1261X hash = (token[1] == EOS) ? L_nogood : (token[0] + (token[2] << 1)); 1262X switch (hash) { 1263X case L_assert: tp = "assert"; break; 1264X case L_define: tp = "define"; break; 1265X case L_elif: tp = "elif"; break; 1266X case L_else: tp = "else"; break; 1267X case L_endif: tp = "endif"; break; 1268X case L_ident: tp = "ident"; break; 1269X case L_if: tp = "if"; break; 1270X case L_ifdef: tp = "ifdef"; break; 1271X case L_ifndef: tp = "ifndef"; break; 1272X case L_include: tp = "include"; break; 1273X case L_line: tp = "line"; break; 1274X case L_pragma: tp = "pragma"; break; 1275X case L_sccs: tp = "sccs"; break; 1276X case L_undef: tp = "undef"; break; 1277X#if DEBUG 1278X case L_debug: tp = "debug"; break; 1279X case L_nodebug: tp = "nodebug"; break; 1280X#endif 1281X default: hash = L_nogood; 1282X case L_nogood: tp = ""; break; 1283X } 1284X if (!streq(tp, token)) 1285X hash = L_nogood; 1286X /* 1287X * hash is set to a unique value corresponding to the 1288X * control keyword (or L_nogood if we think it's nonsense). 1289X */ 1290X if (infile->fp == NULL) 1291X cwarn("Control line \"%s\" within macro expansion", token); 1292X if (!compiling) { /* Not compiling now */ 1293X switch (hash) { 1294X case L_if: /* These can't turn */ 1295X case L_ifdef: /* compilation on, but */ 1296X case L_ifndef: /* we must nest #if's */ 1297X if (++ifptr >= &ifstack[BLK_NEST]) 1298X goto if_nest_err; 1299X *ifptr = 0; /* !WAS_COMPILING */ 1300X case L_line: /* Many */ 1301X /* 1302X * Are pragma's always processed? 1303X */ 1304X case L_ident: 1305X case L_sccs: 1306X case L_pragma: /* options */ 1307X case L_include: /* are uninteresting */ 1308X case L_define: /* if we */ 1309X case L_undef: /* aren't */ 1310X case L_assert: /* compiling. */ 1311Xdump_line: skipnl(); /* Ignore rest of line */ 1312X return (counter + 1); 1313X } 1314X } 1315X /* 1316X * Make sure that #line and #pragma are output on a fresh line. 1317X */ 1318X if (counter > 0 && (hash == L_line || hash == L_pragma)) { 1319X putchar('\n'); 1320X counter--; 1321X } 1322X switch (hash) { 1323X case L_line: 1324X /* 1325X * Parse the line to update the line number and "progname" 1326X * field and line number for the next input line. 1327X * Set wrongline to force it out later. 1328X */ 1329X c = skipws(); 1330X workp = work; /* Save name in work */ 1331X while (c != '\n' && c != EOF_CHAR) { 1332X save(c); 1333X c = get(); 1334X } 1335X unget(); 1336X save(EOS); 1337X /* 1338X * Split #line argument into <line-number> and <name> 1339X * We subtract 1 as we want the number of the next line. 1340X */ 1341X line = atoi(work) - 1; /* Reset line number */ 1342X for (tp = work; isdigit(*tp) || type[*tp] == SPA; tp++) 1343X ; /* Skip over digits */ 1344X if (*tp != EOS) { /* Got a filename, so: */ 1345X if (*tp == '"' && (ep = strrchr(tp + 1, '"')) != NULL) { 1346X tp++; /* Skip over left quote */ 1347X *ep = EOS; /* And ignore right one */ 1348X } 1349X if (infile->progname != NULL) /* Give up the old name */ 1350X free(infile->progname); /* if it's allocated. */ 1351X infile->progname = savestring(tp); 1352X } 1353X wrongline = TRUE; /* Force output later */ 1354X break; 1355X 1356X case L_include: 1357X doinclude(); 1358X break; 1359X 1360X case L_define: 1361X dodefine(); 1362X break; 1363X 1364X case L_undef: 1365X doundef(); 1366X break; 1367X 1368X case L_else: 1369X if (ifptr == &ifstack[0]) 1370X goto nest_err; 1371X else if ((*ifptr & ELSE_SEEN) != 0) 1372X goto else_seen_err; 1373X *ifptr |= ELSE_SEEN; 1374X if ((*ifptr & WAS_COMPILING) != 0) { 1375X if (compiling || (*ifptr & TRUE_SEEN) != 0) 1376X compiling = FALSE; 1377X else { 1378X compiling = TRUE; 1379X } 1380X } 1381X break; 1382X 1383X case L_elif: 1384X if (ifptr == &ifstack[0]) 1385X goto nest_err; 1386X else if ((*ifptr & ELSE_SEEN) != 0) { 1387Xelse_seen_err: cerror("#%s may not follow #else", token); 1388X goto dump_line; 1389X } 1390X if ((*ifptr & (WAS_COMPILING | TRUE_SEEN)) != WAS_COMPILING) { 1391X compiling = FALSE; /* Done compiling stuff */ 1392X goto dump_line; /* Skip this clause */ 1393X } 1394X doif(L_if); 1395X break; 1396X 1397X case L_if: 1398X case L_ifdef: 1399X case L_ifndef: 1400X if (++ifptr >= &ifstack[BLK_NEST]) 1401Xif_nest_err: cfatal("Too many nested #%s statements", token); 1402X *ifptr = WAS_COMPILING; 1403X doif(hash); 1404X break; 1405X 1406X case L_endif: 1407X if (ifptr == &ifstack[0]) { 1408Xnest_err: cerror("#%s must be in an #if", token); 1409X goto dump_line; 1410X } 1411X if (!compiling && (*ifptr & WAS_COMPILING) != 0) 1412X wrongline = TRUE; 1413X compiling = ((*ifptr & WAS_COMPILING) != 0); 1414X --ifptr; 1415X break; 1416X 1417X case L_assert: 1418X if (eval() == 0) 1419X cerror("Preprocessor assertion failure", NULLST); 1420X break; 1421X 1422X case L_ident: 1423X case L_sccs: 1424X goto dump_line; 1425X break; 1426X 1427X case L_pragma: 1428X /* 1429X * #pragma is provided to pass "options" to later 1430X * passes of the compiler. cpp doesn't have any yet. 1431X */ 1432X printf("#pragma "); 1433X while ((c = get()) != '\n' && c != EOF_CHAR) 1434X cput(c); 1435X unget(); 1436X break; 1437X 1438X#if DEBUG 1439X case L_debug: 1440X if (debug == 0) 1441X dumpdef("debug set on"); 1442X debug++; 1443X break; 1444X 1445X case L_nodebug: 1446X debug--; 1447X break; 1448X#endif 1449X 1450X default: 1451X /* 1452X * Undefined #control keyword. 1453X * Note: the correct behavior may be to warn and 1454X * pass the line to a subsequent compiler pass. 1455X * This would allow #asm or similar extensions. 1456X */ 1457X cerror("Illegal # command \"%s\"", token); 1458X break; 1459X } 1460X if (hash != L_include) { 1461X#if OLD_PREPROCESSOR || !VERBOSE 1462X /* 1463X * Ignore the rest of the #control line so you can write 1464X * #if foo 1465X * #endif foo 1466X */ 1467X goto dump_line; /* Take common exit */ 1468X#else 1469X if (skipws() != '\n') { 1470X cwarn("Unexpected text in #control line ignored", NULLST); 1471X skipnl(); 1472X } 1473X#endif 1474X } 1475X return (counter + 1); 1476X} 1477X 1478XFILE_LOCAL 1479Xdoif(hash) 1480Xint hash; 1481X/* 1482X * Process an #if, #ifdef, or #ifndef. The latter two are straightforward, 1483X * while #if needs a subroutine of its own to evaluate the expression. 1484X * 1485X * doif() is called only if compiling is TRUE. If false, compilation 1486X * is always supressed, so we don't need to evaluate anything. This 1487X * supresses unnecessary warnings. 1488X */ 1489X{ 1490X register int c; 1491X register int found; 1492X 1493X if ((c = skipws()) == '\n' || c == EOF_CHAR) { 1494X unget(); 1495X goto badif; 1496X } 1497X if (hash == L_if) { 1498X unget(); 1499X found = (eval() != 0); /* Evaluate expr, != 0 is TRUE */ 1500X hash = L_ifdef; /* #if is now like #ifdef */ 1501X } 1502X else { 1503X if (type[c] != LET) /* Next non-blank isn't letter */ 1504X goto badif; /* ... is an error */ 1505X found = (lookid(c) != NULL); /* Look for it in symbol table */ 1506X } 1507X if (found == (hash == L_ifdef)) { 1508X compiling = TRUE; 1509X *ifptr |= TRUE_SEEN; 1510X } 1511X else { 1512X compiling = FALSE; 1513X } 1514X return; 1515X 1516Xbadif: cerror("#if, #ifdef, or #ifndef without an argument", NULLST); 1517X#if !OLD_PREPROCESSOR 1518X skipnl(); /* Prevent an extra */ 1519X unget(); /* Error message */ 1520X#endif 1521X return; 1522X} 1523X 1524XFILE_LOCAL 1525Xdoinclude() 1526X/* 1527X * Process the #include control line. 1528X * There are three variations: 1529X * #include "file" search somewhere relative to the 1530X * current source file, if not found, 1531X * treat as #include <file>. 1532X * #include <file> Search in an implementation-dependent 1533X * list of places. 1534X * #include token Expand the token, it must be one of 1535X * "file" or <file>, process as such. 1536X * 1537X * Note: the November 12 draft forbids '>' in the #include <file> format. 1538X * This restriction is unnecessary and not implemented. 1539X */ 1540X{ 1541X register int c; 1542X register int delim; 1543X#if HOST == SYS_VMS 1544X char def_filename[NAM$C_MAXRSS + 1]; 1545X#endif 1546X 1547X delim = macroid(skipws()); 1548X if (delim != '<' && delim != '"') 1549X goto incerr; 1550X if (delim == '<') 1551X delim = '>'; 1552X workp = work; 1553X instring = TRUE; /* Accept all characters */ 1554X while ((c = get()) != '\n' && c != delim && c != EOF_CHAR) 1555X save(c); /* Put it away. */ 1556X skipnl(); 1557X /* 1558X * The draft is unclear if the following should be done. 1559X */ 1560X 1561X while (--workp >= work && (type[*workp] == SPA)) 1562X ; /* Trim blanks from filename */ 1563X 1564X/* 1565X * if (*workp != delim) 1566X * goto incerr; 1567X */ 1568X *(workp + 1) = EOS; /* Terminate filename */ 1569X instring = FALSE; 1570X#if HOST == SYS_VMS 1571X /* 1572X * Assume the default .h filetype. 1573X */ 1574X if (!vmsparse(work, ".H", def_filename)) { 1575X perror(work); /* Oops. */ 1576X goto incerr; 1577X } 1578X else if (openinclude(def_filename, (delim == '"'))) 1579X return; 1580X#else 1581X if (openinclude(work, (delim == '"'))) 1582X return; 1583X#endif 1584X /* 1585X * No sense continuing if #include file isn't there. 1586X */ 1587X cfatal("Cannot open include file \"%s\"", work); 1588X 1589Xincerr: cerror("#include syntax error", NULLST); 1590X return; 1591X} 1592X 1593XFILE_LOCAL int 1594Xopeninclude(filename, searchlocal) 1595Xchar *filename; /* Input file name */ 1596Xint searchlocal; /* TRUE if #include "file" */ 1597X/* 1598X * Actually open an include file. This routine is only called from 1599X * doinclude() above, but was written as a separate subroutine for 1600X * programmer convenience. It searches the list of directories 1601X * and actually opens the file, linking it into the list of 1602X * active files. Returns TRUE if the file was opened, FALSE 1603X * if openinclude() fails. No error message is printed. 1604X */ 1605X{ 1606X register char **incptr; 1607X#if HOST == SYS_VMS 1608X#if NWORK < (NAM$C_MAXRSS + 1) 1609X << error, NWORK isn't greater than NAM$C_MAXRSS >> 1610X#endif 1611X#endif 1612X char tmpname[NWORK]; /* Filename work area */ 1613X 1614X if (searchlocal) { 1615X /* 1616X * Look in local directory first 1617X */ 1618X#if HOST == SYS_UNIX 1619X /* 1620X * Try to open filename relative to the directory of the current 1621X * source file (as opposed to the current directory). (ARF, SCK). 1622X */ 1623X if (filename[0] != '/' 1624X && hasdirectory(infile->filename, tmpname)) 1625X strcat(tmpname, filename); 1626X else { 1627X strcpy(tmpname, filename); 1628X } 1629X#else 1630X if (!hasdirectory(filename, tmpname) 1631X && hasdirectory(infile->filename, tmpname)) 1632X strcat(tmpname, filename); 1633X else { 1634X strcpy(tmpname, filename); 1635X } 1636X#endif 1637X if (openfile(tmpname)) 1638X return (TRUE); 1639X } 1640X /* 1641X * Look in any directories specified by -I command line 1642X * arguments, then in the builtin search list. 1643X */ 1644X for (incptr = incdir; incptr < incend; incptr++) { 1645X if (strlen(*incptr) + strlen(filename) >= (NWORK - 1)) 1646X cfatal("Filename work buffer overflow", NULLST); 1647X else { 1648X#if HOST == SYS_UNIX 1649X if (filename[0] == '/') 1650X strcpy(tmpname, filename); 1651X else { 1652X sprintf(tmpname, "%s/%s", *incptr, filename); 1653X } 1654X#else 1655X if (!hasdirectory(filename, tmpname)) 1656X sprintf(tmpname, "%s%s", *incptr, filename); 1657X#endif 1658X if (openfile(tmpname)) 1659X return (TRUE); 1660X } 1661X } 1662X return (FALSE); 1663X} 1664X 1665XFILE_LOCAL int 1666Xhasdirectory(source, result) 1667Xchar *source; /* Directory to examine */ 1668Xchar *result; /* Put directory stuff here */ 1669X/* 1670X * If a device or directory is found in the source filename string, the 1671X * node/device/directory part of the string is copied to result and 1672X * hasdirectory returns TRUE. Else, nothing is copied and it returns FALSE. 1673X */ 1674X{ 1675X#if HOST == SYS_UNIX 1676X register char *tp; 1677X 1678X if ((tp = strrchr(source, '/')) == NULL) 1679X return (FALSE); 1680X else { 1681X strncpy(result, source, tp - source + 1); 1682X result[tp - source + 1] = EOS; 1683X return (TRUE); 1684X } 1685X#else 1686X#if HOST == SYS_VMS 1687X if (vmsparse(source, NULLST, result) 1688X && result[0] != EOS) 1689X return (TRUE); 1690X else { 1691X return (FALSE); 1692X } 1693X#else 1694X /* 1695X * Random DEC operating system (RSX, RT11, RSTS/E) 1696X */ 1697X register char *tp; 1698X 1699X if ((tp = strrchr(source, ']')) == NULL 1700X && (tp = strrchr(source, ':')) == NULL) 1701X return (FALSE); 1702X else { 1703X strncpy(result, source, tp - source + 1); 1704X result[tp - source + 1] = EOS; 1705X return (TRUE); 1706X } 1707X#endif 1708X#endif 1709X} 1710X 1711X#if HOST == SYS_VMS 1712X 1713X/* 1714X * EXP_DEV is set if a device was specified, EXP_DIR if a directory 1715X * is specified. (Both set indicate a file-logical, but EXP_DEV 1716X * would be set by itself if you are reading, say, SYS$INPUT:) 1717X */ 1718X#define DEVDIR (NAM$M_EXP_DEV | NAM$M_EXP_DIR) 1719X 1720XFILE_LOCAL int 1721Xvmsparse(source, defstring, result) 1722Xchar *source; 1723Xchar *defstring; /* non-NULL -> default string. */ 1724Xchar *result; /* Size is at least NAM$C_MAXRSS + 1 */ 1725X/* 1726X * Parse the source string, applying the default (properly, using 1727X * the system parse routine), storing it in result. 1728X * TRUE if it parsed, FALSE on error. 1729X * 1730X * If defstring is NULL, there are no defaults and result gets 1731X * (just) the node::[directory] part of the string (possibly "") 1732X */ 1733X{ 1734X struct FAB fab = cc$rms_fab; /* File access block */ 1735X struct NAM nam = cc$rms_nam; /* File name block */ 1736X char fullname[NAM$C_MAXRSS + 1]; 1737X register char *rp; /* Result pointer */ 1738X 1739X fab.fab$l_nam = &nam; /* fab -> nam */ 1740X fab.fab$l_fna = source; /* Source filename */ 1741X fab.fab$b_fns = strlen(source); /* Size of source */ 1742X fab.fab$l_dna = defstring; /* Default string */ 1743X if (defstring != NULLST) 1744X fab.fab$b_dns = strlen(defstring); /* Size of default */ 1745X nam.nam$l_esa = fullname; /* Expanded filename */ 1746X nam.nam$b_ess = NAM$C_MAXRSS; /* Expanded name size */ 1747X if (sys$parse(&fab) == RMS$_NORMAL) { /* Parse away */ 1748X fullname[nam.nam$b_esl] = EOS; /* Terminate string */ 1749X result[0] = EOS; /* Just in case */ 1750X rp = &result[0]; 1751X /* 1752X * Remove stuff added implicitly, accepting node names and 1753X * dev:[directory] strings (but not process-permanent files). 1754X */ 1755X if ((nam.nam$l_fnb & NAM$M_PPF) == 0) { 1756X if ((nam.nam$l_fnb & NAM$M_NODE) != 0) { 1757X strncpy(result, nam.nam$l_node, nam.nam$b_node); 1758X rp += nam.nam$b_node; 1759X *rp = EOS; 1760X } 1761X if ((nam.nam$l_fnb & DEVDIR) == DEVDIR) { 1762X strncpy(rp, nam.nam$l_dev, nam.nam$b_dev + nam.nam$b_dir); 1763X rp += nam.nam$b_dev + nam.nam$b_dir; 1764X *rp = EOS; 1765X } 1766X } 1767X if (defstring != NULLST) { 1768X strncpy(rp, nam.nam$l_name, nam.nam$b_name + nam.nam$b_type); 1769X rp += nam.nam$b_name + nam.nam$b_type; 1770X *rp = EOS; 1771X if ((nam.nam$l_fnb & NAM$M_EXP_VER) != 0) { 1772X strncpy(rp, nam.nam$l_ver, nam.nam$b_ver); 1773X rp[nam.nam$b_ver] = EOS; 1774X } 1775X } 1776X return (TRUE); 1777X } 1778X return (FALSE); 1779X} 1780X#endif 1781X 1782END-of-cpp2.c 1783exit 1784