home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume16
/
nethack31
/
part02
< prev
next >
Wrap
Internet Message Format
|
1993-02-01
|
60KB
Path: uunet!news.tek.com!master!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v16i002: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part02/108
Message-ID: <4285@master.CNA.TEK.COM>
Date: 28 Jan 93 19:10:21 GMT
Sender: news@master.CNA.TEK.COM
Lines: 1861
Approved: billr@saab.CNA.TEK.COM
Xref: uunet comp.sources.games:1558
Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
Posting-number: Volume 16, Issue 2
Archive-name: nethack31/Part02
Supersedes: nethack3p9: Volume 10, Issue 46-102
Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 108)."
# Contents: sys/amiga/ask.uu sys/unix/cpp1.shr
# Wrapped by billr@saab on Wed Jan 27 16:08:45 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'sys/amiga/ask.uu' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sys/amiga/ask.uu'\"
else
echo shar: Extracting \"'sys/amiga/ask.uu'\" \(603 characters\)
sed "s/^X//" >'sys/amiga/ask.uu' <<'END_OF_FILE'
Xbegin 777 ask.pw
XM4&]W97)7:6YD;W=S('8R+C5C(*DQ.3@W+"`Q.3@X(&)Y($E.3U9!5%)/3DE#
XM4RP@24Y#+B`@("`@("`@("`@("`@("`@("`@("`@```"K`````E```#_````
XM`0`````!``````9A<VLN8P```````````0`"$```(`!```4`!?____\`````
XM`"C^X````````````````````````0`@0%@```````5!<VM?```!`$L`50(,
XM`!(`!0`%_____P````$````````)``0`'``*`````P`!`"XQ9```````()`(
XM`````````````0`AFPC_____`P``!0`N,70````````````=````'0`+````
XM"P```````````P`!```"``$``````"&:R``````````$*#\I``````H````!
XM`"&?\``AH```(G]``";"```FPA``)LUP`````0`````!``````$``````0``
XM```!``````$``0`!```L``4``````"XQZ``````````:5&AI<R!I<R!T:&4@
X.475E<W1I;VX@87)E80`L
X`
Xend
END_OF_FILE
if test 603 -ne `wc -c <'sys/amiga/ask.uu'`; then
echo shar: \"'sys/amiga/ask.uu'\" unpacked with wrong size!
fi
# end of 'sys/amiga/ask.uu'
fi
if test -f 'sys/unix/cpp1.shr' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sys/unix/cpp1.shr'\"
else
echo shar: Extracting \"'sys/unix/cpp1.shr'\" \(54690 characters\)
sed "s/^X//" >'sys/unix/cpp1.shr' <<'END_OF_FILE'
X#!/bin/sh
X# This is a shell archive. Save it in a file, remove anything before
X# this line, and then unpack it by entering "sh file". Note, it may
X# create directories; files and directories will be owned by you and
X# have default permissions.
X#
X# This archive contains:
X#
X# makefile.txt
X# readme.txt
X# cpp.mem
X# cpp.h
X# cppdef.h
X# cpp2.c
X#
Xecho x - makefile.txt
Xsed 's/^X//' >makefile.txt << 'END-of-makefile.txt'
XX#
XX# The redefinition of strchr() and strrchr() are needed for
XX# Ultrix-32, Unix 4.2 bsd (and maybe some other Unices).
XX#
XXBSDDEFINE = -Dstrchr=index -Dstrrchr=rindex
XX#
XX# On certain systems, such as Unix System III, you may need to define
XX# $(LINTFLAGS) in the make command line to set system-specific lint flags.
XX#
XX# This Makefile assumes cpp will replace the "standard" preprocessor.
XX# Delete the reference to -DLINE_PREFIX=\"\" if cpp is used stand-alone.
XX# LINEFIX is a sed script filter that reinserts #line -- used for testing
XX# if LINE_PREFIX is set to "". Note that we must stand on our heads to
XX# match the # and a line had better not begin with $. By the way, what
XX# we really want is
XX# LINEFIX = | sed "s/^#/#line/"
XX#
XXCPPDEFINE = -DLINE_PREFIX=\"\"
XXLINEFIX = | sed "s/^[^ !\"%-~]/&line/"
XX#
XX# Define OLD_PREPROCESSOR non-zero to make a preprocessor which is
XX# "as compatible as possible" with the standard Unix V7 or Ultrix
XX# preprocessors. This is needed to rebuild 4.2bsd, for example, as
XX# the preprocessor is used to modify assembler code, rather than C.
XX# This is not recommended for current development. OLD_PREPROCESSOR
XX# forces the following definitions:
XX# OK_DOLLAR FALSE $ is not allowed in variables
XX# OK_CONCAT FALSE # cannot concatenate tokens
XX# COMMENT_INVISIBLE TRUE old-style comment concatenation
XX# STRING_FORMAL TRUE old-style string expansion
XX#
XXOLDDEFINE = -DOLD_PREPROCESSOR=1
XX#
XX# DEFINES collects all -D arguments for cc and lint:
XX# Change DEFINES = $(BSDDEFINE) $(CPPDEFINE) $(OLDDEFINE)
XX# for an old-style preprocessor.
XX#
XX# DEFINES = $(BSDDEFINE) $(CPPDEFINE)
XXDEFINES = $(CPPDEFINE)
XX
XXCFLAGS = -O $(DEFINES)
XX
XX#
XX# ** compile cpp
XX#
XXSRCS = cpp1.c cpp2.c cpp3.c cpp4.c cpp5.c cpp6.c
XXOBJS = cpp1.o cpp2.o cpp3.o cpp4.o cpp5.o cpp6.o
XXcpp: $(OBJS)
XX $(CC) $(CFLAGS) $(OBJS) -o cpp
XX
XX#
XX# ** Test cpp by preprocessing itself, compiling the result,
XX# ** repeating the process and diff'ing the result. Note: this
XX# ** is not a good test of cpp, but a simple verification.
XX# ** The diff's should not report any changes.
XX# ** Note that a sed script may be executed for each compile
XX#
XXtest:
XX cpp cpp1.c $(LINEFIX) >old.tmp1.c
XX cpp cpp2.c $(LINEFIX) >old.tmp2.c
XX cpp cpp3.c $(LINEFIX) >old.tmp3.c
XX cpp cpp4.c $(LINEFIX) >old.tmp4.c
XX cpp cpp5.c $(LINEFIX) >old.tmp5.c
XX cpp cpp6.c $(LINEFIX) >old.tmp6.c
XX $(CC) $(CFLAGS) old.tmp[123456].c
XX a.out cpp1.c >new.tmp1.c
XX a.out cpp2.c >new.tmp2.c
XX a.out cpp3.c >new.tmp3.c
XX a.out cpp4.c >new.tmp4.c
XX a.out cpp5.c >new.tmp5.c
XX a.out cpp6.c >new.tmp6.c
XX diff old.tmp1.c new.tmp1.c
XX diff old.tmp2.c new.tmp2.c
XX diff old.tmp3.c new.tmp3.c
XX diff old.tmp4.c new.tmp4.c
XX diff old.tmp5.c new.tmp5.c
XX diff old.tmp6.c new.tmp6.c
XX rm a.out old.tmp[123456].* new.tmp[123456].*
XX
XX#
XX# A somewhat more extensive test is provided by the "clock"
XX# program (which is not distributed). Substitute your favorite
XX# macro-rich program here.
XX#
XXclock: clock.c cpp
XX cpp clock.c $(LINEFIX) >temp.cpp.c
XX cc temp.cpp.c -lcurses -ltermcap -o clock
XX rm temp.cpp.c
XX
XX#
XX# ** Lint the code
XX#
XX
XXlint: $(SRCS)
XX lint $(LINTFLAGS) $(DEFINES) $(SRCS)
XX
XX#
XX# ** Remove unneeded files
XX#
XXclean:
XX rm -f $(OBJS) cpp
XX
XX#
XX# ** Rebuild the archive files needed to distribute cpp
XX# ** Uses the Decus C archive utility.
XX#
XX
XXarchc: archc.c
XX $(CC) $(CFLAGS) archc.c -o archc
XX
XXarchx: archx.c
XX $(CC) $(CFLAGS) archx.c -o archx
XX
XXarchive: archc
XX archc readme.txt cpp.mem archx.c archc.c cpp.rno makefile.txt \
XX cpp*.h >cpp1.arc
XX archc cpp1.c cpp2.c cpp3.c >cpp2.arc
XX archc cpp4.c cpp5.c cpp6.c >cpp3.arc
XX
XX#
XX# Object module dependencies
XX#
XX
XXcpp1.o : cpp1.c cpp.h cppdef.h
XX
XXcpp2.o : cpp2.c cpp.h cppdef.h
XX
XXcpp3.o : cpp3.c cpp.h cppdef.h
XX
XXcpp4.o : cpp4.c cpp.h cppdef.h
XX
XXcpp5.o : cpp5.c cpp.h cppdef.h
XX
XXcpp6.o : cpp6.c cpp.h cppdef.h
XX
XX
XEND-of-makefile.txt
Xecho x - readme.txt
Xsed 's/^X//' >readme.txt << 'END-of-readme.txt'
XX
XXDecus cpp is a public-domain implementation of the C preprocessor.
XXIt runs on VMS native (Vax C), VMS compatibilty mode (Decus C),
XXRSX-11M, RSTS/E, P/OS, and RT11, as well as on several varieties
XXof Unix, including Ultrix. Decus cpp attempts to implement features
XXin the Draft ANSI Standard for the C language. It should be noted,
XXhowever, that this standard is under active development: the current
XXdraft of the standard explicitly states that "readers are requested
XXnot to specify or claim conformance to this draft." Thus readers
XXand users of Decus cpp should not assume that it conforms to the
XXdraft standard, or that it will conform to the actual C language
XXstandard.
XX
XXThese notes describe how to extract the cpp source files, configure it
XXfor your needs, and mention a few design decisions that may be of interest
XXto maintainers.
XX
XX Installation
XX
XXBecause the primary development of cpp was not on Unix, it
XXis distributed using the Decus C archive program (quite similar
XXto the archiver published in Kernighan and Plauger's Software
XXTools). To extract the files from the net.sources distribution,
XXsave this message as cpp1.arc and the other two distribution
XXfiles as cpp2.arc and cpp3.arc. Then, using your favorite editor,
XXlocate the archx.c program, just following the line beginning with
XX"-h- archx.c" -- the format of the distribution is just:
XX
XX -h- readme.txt
XX ... this file
XX -h- cpp.mem
XX ... description of cpp
XX -h- archx.c
XX ... archx.c program -- extracts archives
XX -h- archc.c
XX ... archc.c program -- creates archives
XX
XXCompile archx.c -- it shouldn't require any special editing.
XXThen run it as follows:
XX
XX archx *.arc
XX
XXYou do not need to remove mail headers from the saved messages.
XX
XXYou should then read through cppdef.h to make sure the HOST and
XXTARGET (and other implementation-specific) definitions are set
XXcorrectly for your machine, editing them as needed.
XX
XXYou may then copy makefile.txt to Makefile, editing it as needed
XXfor your particular system. On Unix, cpp should be compiled
XXby make without further difficulty. On other operating systems,
XXyou should compile the six source modules, linking them together.
XXNote that, on Decus C based systems, you must extend the default
XXstack allocation. The Decus C build utility will create the
XXappropriate command file.
XX
XX Support Notes
XX
XXThe USENET distribution kit was designed to keep all submissions around
XX50,000 bytes:
XX
XXcpp1.arc:
XX readme.txt This file
XX cpp.mem Documentation page (see below)
XX archx.c Archive extraction program
XX archc.c Archive construction program
XX cpp.rno Source for cpp.mem (see below)
XX makefile.txt Unix makefile -- copy to Makefile
XX cpp.h Main header file (structure def's and globals)
XX cppdef.h Configuration file (host and target definitions)
XX
XXcpp2.arc:
XX cpp1.c Mainline code, documentation master sources
XX cpp2.c most #control processing
XX cpp3.c filename stuff and command line parsing
XXcpp3.arc:
XX cpp4.c #define processor
XX cpp5.c #if <expr> processor
XX cpp6.c Support code (symbol table and I/O routines)
XX
XXCpp intentionally does not rely on the presence of a full-scale
XXmacro preprocessor, it does require the simple parameter substitution
XXpreprocessor capabilities of Unix V6 and Decus C. If your C
XXlanguage lacks full preprocessing, you should make sure "nomacargs"
XXis #define'd in cpp.h. (This is done automatically by the Decus C
XXcompiler.)
XX
XXThe documentation (manual page) for cpp is included as cpp.mem
XXand cpp.rno. Cpp.rno is in Dec Runoff format, built by a Decus C
XXutility (getrno) from original source which is embedded in cpp1.c.
XXTo my knowledge, there is no equivalent program that creates
XXthe nroff source appropriate for Unix.
XX
XXI would be happy to receive fixes to any problems you encounter.
XXAs I do not maintain distribution kit base-levels, bare-bones
XXdiff listings without sufficient context are not very useful.
XXIt is unlikely that I can find time to help you with other
XXdifficulties.
XX
XX Acknowledgements
XX
XXI received a great deal of help from many people in debugging cpp.
XXAlan Feuer and Sam Kendall used "state of the art" run-time code
XXcheckers to locate several errors. Ed Keiser found problems when
XXcpp was used on machines with different int and pointer sizes.
XXDave Conroy helped with the initial debugging, while Arthur Olsen
XXand George Rosenberg found (and solved) several problems in the
XXfirst USENET release.
XX
XXMartin Minow
XXdecvax!minow
XX
XEND-of-readme.txt
Xecho x - cpp.mem
Xsed 's/^X//' >cpp.mem << 'END-of-cpp.mem'
XX
XX
XX
XX
XX 1.0 C Pre-Processor
XX
XX
XX
XX *******
XX * cpp *
XX *******
XX
XX
XX
XX NAME: cpp -- C Pre-Processor
XX
XX SYNOPSIS:
XX
XX cpp [-options] [infile [outfile]]
XX
XX DESCRIPTION:
XX
XX CPP reads a C source file, expands macros and include
XX files, and writes an input file for the C compiler. If
XX no file arguments are given, CPP reads from stdin and
XX writes to stdout. If one file argument is given, it
XX will define the input file, while two file arguments
XX define both input and output files. The file name "-"
XX is a synonym for stdin or stdout as appropriate.
XX
XX The following options are supported. Options may be
XX given in either case.
XX
XX -C If set, source-file comments are written
XX to the output file. This allows the
XX output of CPP to be used as the input to
XX a program, such as lint, that expects
XX commands embedded in specially-formatted
XX comments.
XX
XX -Dname=value Define the name as if the programmer
XX wrote
XX
XX #define name value
XX
XX at the start of the first file. If
XX "=value" is not given, a value of "1"
XX will be used.
XX
XX On non-unix systems, all alphabetic text
XX will be forced to upper-case.
XX
XX -E Always return "success" to the operating
XX system, even if errors were detected.
XX Note that some fatal errors, such as a
XX missing #include file, will terminate
XX CPP, returning "failure" even if the -E
XX option is given.
XX Page 2
XX cpp C Pre-Processor
XX
XX
XX -Idirectory Add this directory to the list of
XX directories searched for #include "..."
XX and #include <...> commands. Note that
XX there is no space between the "-I" and
XX the directory string. More than one -I
XX command is permitted. On non-Unix
XX systems "directory" is forced to
XX upper-case.
XX
XX -N CPP normally predefines some symbols
XX defining the target computer and
XX operating system. If -N is specified,
XX no symbols will be predefined. If -N -N
XX is specified, the "always present"
XX symbols, __LINE__, __FILE__, and
XX __DATE__ are not defined.
XX
XX -Stext CPP normally assumes that the size of
XX the target computer's basic variable
XX types is the same as the size of these
XX types of the host computer. (This can
XX be overridden when CPP is compiled,
XX however.) The -S option allows dynamic
XX respecification of these values. "text"
XX is a string of numbers, separated by
XX commas, that specifies correct sizes.
XX The sizes must be specified in the exact
XX order:
XX
XX char short int long float double
XX
XX If you specify the option as "-S*text",
XX pointers to these types will be
XX specified. -S* takes one additional
XX argument for pointer to function (e.g.
XX int (*)())
XX
XX For example, to specify sizes
XX appropriate for a PDP-11, you would
XX write:
XX
XX c s i l f d func
XX -S1,2,2,2,4,8,
XX -S*2,2,2,2,2,2,2
XX
XX Note that all values must be specified.
XX
XX -Uname Undefine the name as if
XX
XX #undef name
XX
XX were given. On non-Unix systems, "name"
XX will be forced to upper-case.
XX Page 3
XX cpp C Pre-Processor
XX
XX
XX -Xnumber Enable debugging code. If no value is
XX given, a value of 1 will be used. (For
XX maintenence of CPP only.)
XX
XX
XX PRE-DEFINED VARIABLES:
XX
XX When CPP begins processing, the following variables will
XX have been defined (unless the -N option is specified):
XX
XX Target computer (as appropriate):
XX
XX pdp11, vax, M68000 m68000 m68k
XX
XX Target operating system (as appropriate):
XX
XX rsx, rt11, vms, unix
XX
XX Target compiler (as appropriate):
XX
XX decus, vax11c
XX
XX The implementor may add definitions to this list. The
XX default definitions match the definition of the host
XX computer, operating system, and C compiler.
XX
XX The following are always available unless undefined (or
XX -N was specified twice):
XX
XX __FILE__ The input (or #include) file being
XX compiled (as a quoted string).
XX
XX __LINE__ The line number being compiled.
XX
XX __DATE__ The date and time of compilation as a
XX Unix ctime quoted string (the trailing
XX newline is removed). Thus,
XX
XX printf("Bug at line %s,", __LINE__);
XX printf(" source file %s", __FILE__);
XX printf(" compiled on %s", __DATE__);
XX
XX
XX DRAFT PROPOSED ANSI STANDARD CONSIDERATIONS:
XX
XX The current version of the Draft Proposed Standard
XX explicitly states that "readers are requested not to
XX specify or claim conformance to this draft." Readers and
XX users of Decus CPP should not assume that Decus CPP
XX conforms to the standard, or that it will conform to the
XX actual C Language Standard.
XX
XX When CPP is itself compiled, many features of the Draft
XX Proposed Standard that are incompatible with existing
XX Page 4
XX cpp C Pre-Processor
XX
XX
XX preprocessors may be disabled. See the comments in
XX CPP's source for details.
XX
XX The latest version of the Draft Proposed Standard (as
XX reflected in Decus CPP) is dated November 12, 1984.
XX
XX Comments are removed from the input text. The comment
XX is replaced by a single space character. The -C option
XX preserves comments, writing them to the output file.
XX
XX The '$' character is considered to be a letter. This is
XX a permitted extension.
XX
XX The following new features of C are processed by CPP:
XX
XX #elif expression (#else #if)
XX '\xNNN' (Hexadecimal constant)
XX '\a' (Ascii BELL)
XX '\v' (Ascii Vertical Tab)
XX #if defined NAME 1 if defined, 0 if not
XX #if defined (NAME) 1 if defined, 0 if not
XX #if sizeof (basic type)
XX unary +
XX 123U, 123LU Unsigned ints and longs.
XX 12.3L Long double numbers
XX token#token Token concatenation
XX #include token Expands to filename
XX
XX The Draft Proposed Standard has extended C, adding a
XX constant string concatenation operator, where
XX
XX "foo" "bar"
XX
XX is regarded as the single string "foobar". (This does
XX not affect CPP's processing but does permit a limited
XX form of macro argument substitution into strings as will
XX be discussed.)
XX
XX The Standard Committee plans to add token concatenation
XX to #define command lines. One suggested implementation
XX is as follows: the sequence "Token1#Token2" is treated
XX as if the programmer wrote "Token1Token2". This could
XX be used as follows:
XX
XX #line 123
XX #define ATLINE foo#__LINE__
XX
XX ATLINE would be defined as foo123.
XX
XX Note that "Token2" must either have the format of an
XX identifier or be a string of digits. Thus, the string
XX
XX #define ATLINE foo#1x3
XX Page 5
XX cpp C Pre-Processor
XX
XX
XX generates two tokens: "foo1" and "x3".
XX
XX If the tokens T1 and T2 are concatenated into T3, this
XX implementation operates as follows:
XX
XX 1. Expand T1 if it is a macro.
XX 2. Expand T2 if it is a macro.
XX 3. Join the tokens, forming T3.
XX 4. Expand T3 if it is a macro.
XX
XX A macro formal parameter will be substituted into a
XX string or character constant if it is the only component
XX of that constant:
XX
XX #define VECSIZE 123
XX #define vprint(name, size) \
XX printf("name" "[" "size" "] = {\n")
XX ... vprint(vector, VECSIZE);
XX
XX expands (effectively) to
XX
XX vprint("vector[123] = {\n");
XX
XX Note that this will be useful if your C compiler
XX supports the new string concatenation operation noted
XX above. As implemented here, if you write
XX
XX #define string(arg) "arg"
XX ... string("foo") ...
XX
XX This implementation generates "foo", rather than the
XX strictly correct ""foo"" (which will probably generate
XX an error message). This is, strictly speaking, an error
XX in CPP and may be removed from future releases.
XX
XX ERROR MESSAGES:
XX
XX Many. CPP prints warning or error messages if you try
XX to use multiple-byte character constants
XX (non-transportable) if you #undef a symbol that was not
XX defined, or if your program has potentially nested
XX comments.
XX
XX AUTHOR:
XX
XX Martin Minow
XX
XX BUGS:
XX
XX The #if expression processor uses signed integers only.
XX I.e, #if 0xFFFFu < 0 may be TRUE.
XX
XEND-of-cpp.mem
Xecho x - cpp.h
Xsed 's/^X//' >cpp.h << 'END-of-cpp.h'
XX
XX/*
XX * 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
XX *
XX * In general, definitions in this file should not be changed.
XX */
XX
XX#ifndef TRUE
XX#define TRUE 1
XX#define FALSE 0
XX#endif
XX#ifndef EOS
XX/*
XX * This is predefined in Decus C
XX */
XX#define EOS '\0' /* End of string */
XX#endif
XX#define EOF_CHAR 0 /* Returned by get() on eof */
XX#define NULLST ((char *) NULL) /* Pointer to nowhere (linted) */
XX#define DEF_NOARGS (-1) /* #define foo vs #define foo() */
XX
XX/*
XX * The following may need to change if the host system doesn't use ASCII.
XX */
XX#define DEF_MAGIC 0x1D /* Magic for #defines */
XX#define TOK_SEP 0x1E /* Token concatenation delim. */
XX#define COM_SEP 0x1F /* Magic comment separator */
XX
XX/*
XX * Note -- in Ascii, the following will map macro formals onto DEL + the
XX * C1 control character region (decimal 128 .. (128 + PAR_MAC)) which will
XX * be ok as long as PAR_MAC is less than 33). Note that the last PAR_MAC
XX * value is reserved for string substitution.
XX */
XX
XX#define MAC_PARM 0x7F /* Macro formals start here */
XX#if PAR_MAC >= 33
XX assertion fails -- PAR_MAC isn't less than 33
XX#endif
XX#define LASTPARM (PAR_MAC - 1)
XX
XX/*
XX * Character type codes.
XX */
XX
XX#define INV 0 /* Invalid, must be zero */
XX#define OP_EOE INV /* End of expression */
XX#define DIG 1 /* Digit */
XX#define LET 2 /* Identifier start */
XX#define FIRST_BINOP OP_ADD
XX#define OP_ADD 3
XX#define OP_SUB 4
XX#define OP_MUL 5
XX#define OP_DIV 6
XX#define OP_MOD 7
XX#define OP_ASL 8
XX#define OP_ASR 9
XX#define OP_AND 10 /* &, not && */
XX#define OP_OR 11 /* |, not || */
XX#define OP_XOR 12
XX#define OP_EQ 13
XX#define OP_NE 14
XX#define OP_LT 15
XX#define OP_LE 16
XX#define OP_GE 17
XX#define OP_GT 18
XX#define OP_ANA 19 /* && */
XX#define OP_ORO 20 /* || */
XX#define OP_QUE 21 /* ? */
XX#define OP_COL 22 /* : */
XX#define OP_CMA 23 /* , (relevant?) */
XX#define LAST_BINOP OP_CMA /* Last binary operand */
XX/*
XX * The following are unary.
XX */
XX#define FIRST_UNOP OP_PLU /* First Unary operand */
XX#define OP_PLU 24 /* + (draft ANSI standard) */
XX#define OP_NEG 25 /* - */
XX#define OP_COM 26 /* ~ */
XX#define OP_NOT 27 /* ! */
XX#define LAST_UNOP OP_NOT
XX#define OP_LPA 28 /* ( */
XX#define OP_RPA 29 /* ) */
XX#define OP_END 30 /* End of expression marker */
XX#define OP_MAX (OP_END + 1) /* Number of operators */
XX#define OP_FAIL (OP_END + 1) /* For error returns */
XX
XX/*
XX * The following are for lexical scanning only.
XX */
XX
XX#define QUO 65 /* Both flavors of quotation */
XX#define DOT 66 /* . might start a number */
XX#define SPA 67 /* Space and tab */
XX#define BSH 68 /* Just a backslash */
XX#define END 69 /* EOF */
XX
XX/*
XX * These bits are set in ifstack[]
XX */
XX#define WAS_COMPILING 1 /* TRUE if compile set at entry */
XX#define ELSE_SEEN 2 /* TRUE when #else processed */
XX#define TRUE_SEEN 4 /* TRUE when #if TRUE processed */
XX
XX/*
XX * Define bits for the basic types and their adjectives
XX */
XX
XX#define T_CHAR 1
XX#define T_INT 2
XX#define T_FLOAT 4
XX#define T_DOUBLE 8
XX#define T_SHORT 16
XX#define T_LONG 32
XX#define T_SIGNED 64
XX#define T_UNSIGNED 128
XX#define T_PTR 256 /* Pointer */
XX#define T_FPTR 512 /* Pointer to functions */
XX
XX/*
XX * The DEFBUF structure stores information about #defined
XX * macros. Note that the defbuf->repl information is always
XX * in malloc storage.
XX */
XX
XXtypedef struct defbuf {
XX struct defbuf *link; /* Next define in chain */
XX char *repl; /* -> replacement */
XX int hash; /* Symbol table hash */
XX int nargs; /* For define(args) */
XX char name[1]; /* #define name */
XX} DEFBUF;
XX
XX/*
XX * The FILEINFO structure stores information about open files
XX * and macros being expanded.
XX */
XX
XXtypedef struct fileinfo {
XX char *bptr; /* Buffer pointer */
XX int line; /* for include or macro */
XX FILE *fp; /* File if non-null */
XX struct fileinfo *parent; /* Link to includer */
XX char *filename; /* File/macro name */
XX char *progname; /* From #line statement */
XX unsigned int unrecur; /* For macro recursion */
XX char buffer[1]; /* current input line */
XX} FILEINFO;
XX
XX/*
XX * The SIZES structure is used to store the values for #if sizeof
XX */
XX
XXtypedef struct sizes {
XX short bits; /* If this bit is set, */
XX short size; /* this is the datum size value */
XX short psize; /* this is the pointer size */
XX} SIZES;
XX/*
XX * nomacarg is a built-in #define on Decus C.
XX */
XX
XX#ifdef nomacarg
XX#define cput output /* cput concatenates tokens */
XX#else
XX#if COMMENT_INVISIBLE
XX#define cput(c) { if (c != TOK_SEP && c != COM_SEP) putchar(c); }
XX#else
XX#define cput(c) { if (c != TOK_SEP) putchar(c); }
XX#endif
XX#endif
XX
XX#ifndef nomacarg
XX#define streq(s1, s2) (strcmp(s1, s2) == 0)
XX#endif
XX
XX/*
XX * Error codes. VMS uses system definitions.
XX * Decus C codes are defined in stdio.h.
XX * Others are cooked to order.
XX */
XX
XX#if HOST == SYS_VMS
XX#include <ssdef.h>
XX#include <stsdef.h>
XX#define IO_NORMAL (SS$_NORMAL | STS$M_INHIB_MSG)
XX#define IO_ERROR SS$_ABORT
XX#endif
XX/*
XX * Note: IO_NORMAL and IO_ERROR are defined in the Decus C stdio.h file
XX */
XX#ifndef IO_NORMAL
XX#define IO_NORMAL 0
XX#endif
XX#ifndef IO_ERROR
XX#define IO_ERROR 1
XX#endif
XX
XX/*
XX * Externs
XX */
XX
XXextern int line; /* Current line number */
XXextern int wrongline; /* Force #line to cc pass 1 */
XXextern char type[]; /* Character classifier */
XXextern char token[IDMAX + 1]; /* Current input token */
XXextern int instring; /* TRUE if scanning string */
XXextern int inmacro; /* TRUE if scanning #define */
XXextern int errors; /* Error counter */
XXextern int recursion; /* Macro depth counter */
XXextern char ifstack[BLK_NEST]; /* #if information */
XX#define compiling ifstack[0]
XXextern char *ifptr; /* -> current ifstack item */
XXextern char *incdir[NINCLUDE]; /* -i directories */
XXextern char **incend; /* -> active end of incdir */
XXextern int cflag; /* -C option (keep comments) */
XXextern int eflag; /* -E option (ignore errors) */
XXextern int nflag; /* -N option (no pre-defines) */
XXextern int rec_recover; /* unwind recursive macros */
XXextern char *preset[]; /* Standard predefined symbols */
XXextern char *magic[]; /* Magic predefined symbols */
XXextern FILEINFO *infile; /* Current input file */
XXextern char work[NWORK + 1]; /* #define scratch */
XXextern char *workp; /* Free space in work */
XX#if DEBUG
XXextern int debug; /* Debug level */
XX#endif
XXextern int keepcomments; /* Don't remove comments if set */
XXextern SIZES size_table[]; /* For #if sizeof sizes */
XXextern char *getmem(); /* Get memory or die. */
XXextern DEFBUF *lookid(); /* Look for a #define'd thing */
XXextern DEFBUF *defendel(); /* Symbol table enter/delete */
XXextern char *savestring(); /* Stuff string in malloc mem. */
XXextern char *strcpy();
XXextern char *strcat();
XXextern char *strrchr();
XXextern char *strchr();
XXextern long time();
XX/* extern char *sprintf(); /* Lint needs this */
XEND-of-cpp.h
Xecho x - cppdef.h
Xsed 's/^X//' >cppdef.h << 'END-of-cppdef.h'
XX/*
XX * S y s t e m D e p e n d e n t
XX * D e f i n i t i o n s f o r C P P
XX *
XX * Definitions in this file may be edited to configure CPP for particular
XX * host operating systems and target configurations.
XX *
XX * NOTE: cpp assumes it is compiled by a compiler that supports macros
XX * with arguments. If this is not the case (as for Decus C), #define
XX * nomacarg -- and provide function equivalents for all macros.
XX *
XX * cpp also assumes the host and target implement the Ascii character set.
XX * If this is not the case, you will have to do some editing here and there.
XX */
XX
XX/*
XX * This redundant definition of TRUE and FALSE works around
XX * a limitation of Decus C.
XX */
XX#ifndef TRUE
XX#define TRUE 1
XX#define FALSE 0
XX#endif
XX
XX/*
XX * Define the HOST operating system. This is needed so that
XX * cpp can use appropriate filename conventions.
XX */
XX#define SYS_UNKNOWN 0
XX#define SYS_UNIX 1
XX#define SYS_VMS 2
XX#define SYS_RSX 3
XX#define SYS_RT11 4
XX#define SYS_LATTICE 5
XX#define SYS_ONYX 6
XX#define SYS_68000 7
XX#define SYS_GCOS 8
XX#define SYS_IBM 9
XX#define SYS_OS 10
XX#define SYS_TSS 11
XX
XX#ifndef HOST
XX#ifdef unix
XX#define HOST SYS_UNIX
XX#else
XX#ifdef vms
XX#define HOST SYS_VMS
XX#else
XX#ifdef rsx
XX#define HOST SYS_RSX
XX#else
XX#ifdef rt11
XX#define HOST SYS_RT11
XX#else
XX#ifdef dmert
XX#define HOST SYS_DMERT
XX#else
XX#ifdef gcos
XX#define HOST SYS_GCOS
XX#else
XX#ifdef ibm
XX#define HOST SYS_IBM
XX#else
XX#ifdef os
XX#define HOST SYS_OS
XX#else
XX#ifdef tss
XX#define HOST SYS_TSS
XX#endif
XX#endif
XX#endif
XX#endif
XX#endif
XX#endif
XX#endif
XX#endif
XX#endif
XX
XX#ifndef HOST
XX#define HOST SYS_UNKNOWN
XX#endif
XX
XX/*
XX * We assume that the target is the same as the host system
XX */
XX#ifndef TARGET
XX#define TARGET HOST
XX#endif
XX
XX/*
XX * In order to predefine machine-dependent constants,
XX * several strings are defined here:
XX *
XX * MACHINE defines the target cpu (by name)
XX * SYSTEM defines the target operating system
XX * COMPILER defines the target compiler
XX *
XX * The above may be #defined as "" if they are not wanted.
XX * They should not be #defined as NULL.
XX *
XX * LINE_PREFIX defines the # output line prefix, if not "line"
XX * This should be defined as "" if cpp is to replace
XX * the "standard" C pre-processor.
XX *
XX * FILE_LOCAL marks functions which are referenced only in the
XX * file they reside. Some C compilers allow these
XX * to be marked "static" even though they are referenced
XX * by "extern" statements elsewhere.
XX *
XX * OK_DOLLAR Should be set TRUE if $ is a valid alphabetic character
XX * in identifiers (default), or zero if $ is invalid.
XX * Default is TRUE.
XX *
XX * OK_CONCAT Should be set TRUE if # may be used to concatenate
XX * tokens in macros (per the Ansi Draft Standard) or
XX * FALSE for old-style # processing (needed if cpp is
XX * to process assembler source code).
XX *
XX * OK_DATE Predefines the compilation date if set TRUE.
XX * Not permitted by the Nov. 12, 1984 Draft Standard.
XX *
XX * S_CHAR etc. Define the sizeof the basic TARGET machine word types.
XX * By default, sizes are set to the values for the HOST
XX * computer. If this is inappropriate, see the code in
XX * cpp3.c for details on what to change. Also, if you
XX * have a machine where sizeof (signed int) differs from
XX * sizeof (unsigned int), you will have to edit code and
XX * tables in cpp3.c (and extend the -S option definition.)
XX *
XX * CPP_LIBRARY May be defined if you have a site-specific include directory
XX * which is to be searched *before* the operating-system
XX * specific directories.
XX */
XX
XX#if TARGET == SYS_LATTICE
XX/*
XX * We assume the operating system is pcdos for the IBM-PC.
XX * We also assume the small model (just like the PDP-11)
XX */
XX#define MACHINE "i8086"
XX#define SYSTEM "pcdos"
XX#endif
XX
XX#if TARGET == SYS_ONYX
XX#define MACHINE "z8000"
XX#define SYSTEM "unix"
XX#endif
XX
XX#if TARGET == SYS_VMS
XX#define MACHINE "vax"
XX#define SYSTEM "vms"
XX#define COMPILER "vax11c"
XX#endif
XX
XX#if TARGET == SYS_RSX
XX#define MACHINE "pdp11"
XX#define SYSTEM "rsx"
XX#define COMPILER "decus"
XX#endif
XX
XX#if TARGET == SYS_RT11
XX#define MACHINE "pdp11"
XX#define SYSTEM "rt11"
XX#define COMPILER "decus"
XX#endif
XX
XX#if TARGET == SYS_68000
XX/*
XX * All three machine designators have been seen in various systems.
XX * Warning -- compilers differ as to sizeof (int). cpp3 assumes that
XX * sizeof (int) == 2
XX */
XX#define MACHINE "M68000", "m68000", "m68k"
XX#define SYSTEM "unix"
XX#endif
XX
XX#if TARGET == SYS_UNIX
XX#define SYSTEM "unix"
XX#ifdef pdp11
XX#define MACHINE "pdp11"
XX#endif
XX#ifdef vax
XX#define MACHINE "vax"
XX#endif
XX#ifdef u370
XX#define MACHINE "u370"
XX#endif
XX#ifdef interdata
XX#define MACHINE "interdata"
XX#endif
XX#ifdef u3b
XX#define MACHINE "u3b"
XX#endif
XX#ifdef u3b5
XX#define MACHINE "u3b5"
XX#endif
XX#ifdef u3b2
XX#define MACHINE "u3b2"
XX#endif
XX#ifdef u3b20d
XX#define MACHINE "u3b20d"
XX#endif
XX#endif
XX#endif
XX
XX/*
XX * defaults
XX */
XX
XX#ifndef MSG_PREFIX
XX#define MSG_PREFIX "cpp: "
XX#endif
XX
XX#ifndef LINE_PREFIX
XX#ifdef decus
XX#define LINE_PREFIX ""
XX#else
XX#define LINE_PREFIX "line"
XX#endif
XX#endif
XX
XX/*
XX * OLD_PREPROCESSOR forces the definition of OK_DOLLAR, OK_CONCAT,
XX * COMMENT_INVISIBLE, and STRING_FORMAL to values appropriate for
XX * an old-style preprocessor.
XX */
XX
XX#ifndef OLD_PREPROCESSOR
XX#define OLD_PREPROCESSOR FALSE
XX#endif
XX
XX#if OLD_PREPROCESSOR
XX#define OK_DOLLAR FALSE
XX#define OK_CONCAT FALSE
XX#define COMMENT_INVISIBLE TRUE
XX#define STRING_FORMAL TRUE
XX#endif
XX
XX/*
XX * RECURSION_LIMIT may be set to -1 to disable the macro recursion test.
XX */
XX#ifndef RECURSION_LIMIT
XX#define RECURSION_LIMIT 1000
XX#endif
XX
XX/*
XX * BITS_CHAR may be defined to set the number of bits per character.
XX * it is needed only for multi-byte character constants.
XX */
XX#ifndef BITS_CHAR
XX#define BITS_CHAR 8
XX#endif
XX
XX/*
XX * BIG_ENDIAN is set TRUE on machines (such as the IBM 360 series)
XX * where 'ab' stores 'a' in the high-bits and 'b' in the low-bits.
XX * It is set FALSE on machines (such as the PDP-11 and Vax-11)
XX * where 'ab' stores 'a' in the low-bits and 'b' in the high-bits.
XX * (Or is it the other way around?) -- Warning: BIG_ENDIAN code is untested.
XX */
XX#ifndef BIG_ENDIAN
XX#define BIG_ENDIAN FALSE
XX#endif
XX
XX/*
XX * COMMENT_INVISIBLE may be defined to allow "old-style" comment
XX * processing, whereby the comment becomes a zero-length token
XX * delimiter. This permitted tokens to be concatenated in macro
XX * expansions. This was removed from the Draft Ansi Standard.
XX */
XX#ifndef COMMENT_INVISIBLE
XX#define COMMENT_INVISIBLE FALSE
XX#endif
XX
XX/*
XX * STRING_FORMAL may be defined to allow recognition of macro parameters
XX * anywhere in replacement strings. This was removed from the Draft Ansi
XX * Standard and a limited recognition capability added.
XX */
XX#ifndef STRING_FORMAL
XX#define STRING_FORMAL FALSE
XX#endif
XX
XX/*
XX * OK_DOLLAR enables use of $ as a valid "letter" in identifiers.
XX * This is a permitted extension to the Ansi Standard and is required
XX * for e.g., VMS, RSX-11M, etc. It should be set FALSE if cpp is
XX * used to preprocess assembler source on Unix systems. OLD_PREPROCESSOR
XX * sets OK_DOLLAR FALSE for that reason.
XX */
XX#ifndef OK_DOLLAR
XX#define OK_DOLLAR TRUE
XX#endif
XX
XX/*
XX * OK_CONCAT enables (one possible implementation of) token concatenation.
XX * If cpp is used to preprocess Unix assembler source, this should be
XX * set FALSE as the concatenation character, #, is used by the assembler.
XX */
XX#ifndef OK_CONCAT
XX#define OK_CONCAT TRUE
XX#endif
XX
XX/*
XX * OK_DATE may be enabled to predefine today's date as a string
XX * at the start of each compilation. This is apparently not permitted
XX * by the Draft Ansi Standard.
XX */
XX#ifndef OK_DATE
XX#define OK_DATE TRUE
XX#endif
XX
XX/*
XX * Some common definitions.
XX */
XX
XX#ifndef DEBUG
XX#define DEBUG FALSE
XX#endif
XX
XX/*
XX * The following definitions are used to allocate memory for
XX * work buffers. In general, they should not be modified
XX * by implementors.
XX *
XX * PAR_MAC The maximum number of #define parameters (31 per Standard)
XX * Note: we need another one for strings.
XX * IDMAX The longest identifier, 31 per Ansi Standard
XX * NBUFF Input buffer size
XX * NWORK Work buffer size -- the longest macro
XX * must fit here after expansion.
XX * NEXP The nesting depth of #if expressions
XX * NINCLUDE The number of directories that may be specified
XX * on a per-system basis, or by the -I option.
XX * BLK_NEST The number of nested #if's permitted.
XX */
XX
XX#define IDMAX 31
XX#define PAR_MAC (31 + 1)
XX#define NBUFF 1024
XX#define NWORK 1024
XX#define NEXP 128
XX#define NINCLUDE 7
XX#define NPARMWORK (NWORK * 2)
XX#define BLK_NEST 32
XX
XX/*
XX * Some special constants. These may need to be changed if cpp
XX * is ported to a wierd machine.
XX *
XX * NOTE: if cpp is run on a non-ascii machine, ALERT and VT may
XX * need to be changed. They are used to implement the proposed
XX * ANSI standard C control characters '\a' and '\v' only.
XX * DEL is used to tag macro tokens to prevent #define foo foo
XX * from looping. Note that we don't try to prevent more elaborate
XX * #define loops from occurring.
XX */
XX
XX#ifndef ALERT
XX#define ALERT '\007' /* '\a' is "Bell" */
XX#endif
XX
XX#ifndef VT
XX#define VT '\013' /* Vertical Tab CTRL/K */
XX#endif
XX
XX
XX#ifndef FILE_LOCAL
XX#ifdef decus
XX#define FILE_LOCAL static
XX#else
XX#ifdef vax11c
XX#define FILE_LOCAL static
XX#else
XX#define FILE_LOCAL /* Others are global */
XX#endif
XX#endif
XX#endif
XX
XEND-of-cppdef.h
Xecho x - cpp2.c
Xsed 's/^X//' >cpp2.c << 'END-of-cpp2.c'
XX/*
XX * C P P 2 . C
XX *
XX * Process #control lines
XX *
XX * Edit history
XX * 13-Nov-84 MM Split from cpp1.c
XX */
XX
XX#include <stdio.h>
XX#include <ctype.h>
XX#include "cppdef.h"
XX#include "cpp.h"
XX#if HOST == SYS_VMS
XX/*
XX * Include the rms stuff. (We can't just include rms.h as it uses the
XX * VaxC-specific library include syntax that Decus CPP doesn't support.
XX * By including things by hand, we can CPP ourself.)
XX */
XX#include <nam.h>
XX#include <fab.h>
XX#include <rab.h>
XX#include <rmsdef.h>
XX#endif
XX
XX/*
XX * Generate (by hand-inspection) a set of unique values for each control
XX * operator. Note that this is not guaranteed to work for non-Ascii
XX * machines. CPP won't compile if there are hash conflicts.
XX */
XX
XX#define L_assert ('a' + ('s' << 1))
XX#define L_define ('d' + ('f' << 1))
XX#define L_elif ('e' + ('i' << 1))
XX#define L_else ('e' + ('s' << 1))
XX#define L_endif ('e' + ('d' << 1))
XX#define L_ident ('i' + ('e' << 1))
XX#define L_if ('i' + (EOS << 1))
XX#define L_ifdef ('i' + ('d' << 1))
XX#define L_ifndef ('i' + ('n' << 1))
XX#define L_include ('i' + ('c' << 1))
XX#define L_line ('l' + ('n' << 1))
XX#define L_nogood (EOS + (EOS << 1)) /* To catch #i */
XX#define L_pragma ('p' + ('a' << 1))
XX#define L_sccs ('s' + ('c' << 1))
XX#define L_undef ('u' + ('d' << 1))
XX#if DEBUG
XX#define L_debug ('d' + ('b' << 1)) /* #debug */
XX#define L_nodebug ('n' + ('d' << 1)) /* #nodebug */
XX#endif
XX
XXint
XXcontrol(counter)
XXint counter; /* Pending newline counter */
XX/*
XX * Process #control lines. Simple commands are processed inline,
XX * while complex commands have their own subroutines.
XX *
XX * The counter is used to force out a newline before #line, and
XX * #pragma commands. This prevents these commands from ending up at
XX * the end of the previous line if cpp is invoked with the -C option.
XX */
XX{
XX register int c;
XX register char *tp;
XX register int hash;
XX char *ep;
XX
XX c = skipws();
XX if (c == '\n' || c == EOF_CHAR)
XX return (counter + 1);
XX if (!isdigit(c))
XX scanid(c); /* Get #word to token[] */
XX else {
XX unget(); /* Hack -- allow #123 as a */
XX strcpy(token, "line"); /* synonym for #line 123 */
XX }
XX hash = (token[1] == EOS) ? L_nogood : (token[0] + (token[2] << 1));
XX switch (hash) {
XX case L_assert: tp = "assert"; break;
XX case L_define: tp = "define"; break;
XX case L_elif: tp = "elif"; break;
XX case L_else: tp = "else"; break;
XX case L_endif: tp = "endif"; break;
XX case L_ident: tp = "ident"; break;
XX case L_if: tp = "if"; break;
XX case L_ifdef: tp = "ifdef"; break;
XX case L_ifndef: tp = "ifndef"; break;
XX case L_include: tp = "include"; break;
XX case L_line: tp = "line"; break;
XX case L_pragma: tp = "pragma"; break;
XX case L_sccs: tp = "sccs"; break;
XX case L_undef: tp = "undef"; break;
XX#if DEBUG
XX case L_debug: tp = "debug"; break;
XX case L_nodebug: tp = "nodebug"; break;
XX#endif
XX default: hash = L_nogood;
XX case L_nogood: tp = ""; break;
XX }
XX if (!streq(tp, token))
XX hash = L_nogood;
XX /*
XX * hash is set to a unique value corresponding to the
XX * control keyword (or L_nogood if we think it's nonsense).
XX */
XX if (infile->fp == NULL)
XX cwarn("Control line \"%s\" within macro expansion", token);
XX if (!compiling) { /* Not compiling now */
XX switch (hash) {
XX case L_if: /* These can't turn */
XX case L_ifdef: /* compilation on, but */
XX case L_ifndef: /* we must nest #if's */
XX if (++ifptr >= &ifstack[BLK_NEST])
XX goto if_nest_err;
XX *ifptr = 0; /* !WAS_COMPILING */
XX case L_line: /* Many */
XX /*
XX * Are pragma's always processed?
XX */
XX case L_ident:
XX case L_sccs:
XX case L_pragma: /* options */
XX case L_include: /* are uninteresting */
XX case L_define: /* if we */
XX case L_undef: /* aren't */
XX case L_assert: /* compiling. */
XXdump_line: skipnl(); /* Ignore rest of line */
XX return (counter + 1);
XX }
XX }
XX /*
XX * Make sure that #line and #pragma are output on a fresh line.
XX */
XX if (counter > 0 && (hash == L_line || hash == L_pragma)) {
XX putchar('\n');
XX counter--;
XX }
XX switch (hash) {
XX case L_line:
XX /*
XX * Parse the line to update the line number and "progname"
XX * field and line number for the next input line.
XX * Set wrongline to force it out later.
XX */
XX c = skipws();
XX workp = work; /* Save name in work */
XX while (c != '\n' && c != EOF_CHAR) {
XX save(c);
XX c = get();
XX }
XX unget();
XX save(EOS);
XX /*
XX * Split #line argument into <line-number> and <name>
XX * We subtract 1 as we want the number of the next line.
XX */
XX line = atoi(work) - 1; /* Reset line number */
XX for (tp = work; isdigit(*tp) || type[*tp] == SPA; tp++)
XX ; /* Skip over digits */
XX if (*tp != EOS) { /* Got a filename, so: */
XX if (*tp == '"' && (ep = strrchr(tp + 1, '"')) != NULL) {
XX tp++; /* Skip over left quote */
XX *ep = EOS; /* And ignore right one */
XX }
XX if (infile->progname != NULL) /* Give up the old name */
XX free(infile->progname); /* if it's allocated. */
XX infile->progname = savestring(tp);
XX }
XX wrongline = TRUE; /* Force output later */
XX break;
XX
XX case L_include:
XX doinclude();
XX break;
XX
XX case L_define:
XX dodefine();
XX break;
XX
XX case L_undef:
XX doundef();
XX break;
XX
XX case L_else:
XX if (ifptr == &ifstack[0])
XX goto nest_err;
XX else if ((*ifptr & ELSE_SEEN) != 0)
XX goto else_seen_err;
XX *ifptr |= ELSE_SEEN;
XX if ((*ifptr & WAS_COMPILING) != 0) {
XX if (compiling || (*ifptr & TRUE_SEEN) != 0)
XX compiling = FALSE;
XX else {
XX compiling = TRUE;
XX }
XX }
XX break;
XX
XX case L_elif:
XX if (ifptr == &ifstack[0])
XX goto nest_err;
XX else if ((*ifptr & ELSE_SEEN) != 0) {
XXelse_seen_err: cerror("#%s may not follow #else", token);
XX goto dump_line;
XX }
XX if ((*ifptr & (WAS_COMPILING | TRUE_SEEN)) != WAS_COMPILING) {
XX compiling = FALSE; /* Done compiling stuff */
XX goto dump_line; /* Skip this clause */
XX }
XX doif(L_if);
XX break;
XX
XX case L_if:
XX case L_ifdef:
XX case L_ifndef:
XX if (++ifptr >= &ifstack[BLK_NEST])
XXif_nest_err: cfatal("Too many nested #%s statements", token);
XX *ifptr = WAS_COMPILING;
XX doif(hash);
XX break;
XX
XX case L_endif:
XX if (ifptr == &ifstack[0]) {
XXnest_err: cerror("#%s must be in an #if", token);
XX goto dump_line;
XX }
XX if (!compiling && (*ifptr & WAS_COMPILING) != 0)
XX wrongline = TRUE;
XX compiling = ((*ifptr & WAS_COMPILING) != 0);
XX --ifptr;
XX break;
XX
XX case L_assert:
XX if (eval() == 0)
XX cerror("Preprocessor assertion failure", NULLST);
XX break;
XX
XX case L_ident:
XX case L_sccs:
XX goto dump_line;
XX break;
XX
XX case L_pragma:
XX /*
XX * #pragma is provided to pass "options" to later
XX * passes of the compiler. cpp doesn't have any yet.
XX */
XX printf("#pragma ");
XX while ((c = get()) != '\n' && c != EOF_CHAR)
XX cput(c);
XX unget();
XX break;
XX
XX#if DEBUG
XX case L_debug:
XX if (debug == 0)
XX dumpdef("debug set on");
XX debug++;
XX break;
XX
XX case L_nodebug:
XX debug--;
XX break;
XX#endif
XX
XX default:
XX /*
XX * Undefined #control keyword.
XX * Note: the correct behavior may be to warn and
XX * pass the line to a subsequent compiler pass.
XX * This would allow #asm or similar extensions.
XX */
XX cerror("Illegal # command \"%s\"", token);
XX break;
XX }
XX if (hash != L_include) {
XX#if OLD_PREPROCESSOR || !VERBOSE
XX /*
XX * Ignore the rest of the #control line so you can write
XX * #if foo
XX * #endif foo
XX */
XX goto dump_line; /* Take common exit */
XX#else
XX if (skipws() != '\n') {
XX cwarn("Unexpected text in #control line ignored", NULLST);
XX skipnl();
XX }
XX#endif
XX }
XX return (counter + 1);
XX}
XX
XXFILE_LOCAL
XXdoif(hash)
XXint hash;
XX/*
XX * Process an #if, #ifdef, or #ifndef. The latter two are straightforward,
XX * while #if needs a subroutine of its own to evaluate the expression.
XX *
XX * doif() is called only if compiling is TRUE. If false, compilation
XX * is always supressed, so we don't need to evaluate anything. This
XX * supresses unnecessary warnings.
XX */
XX{
XX register int c;
XX register int found;
XX
XX if ((c = skipws()) == '\n' || c == EOF_CHAR) {
XX unget();
XX goto badif;
XX }
XX if (hash == L_if) {
XX unget();
XX found = (eval() != 0); /* Evaluate expr, != 0 is TRUE */
XX hash = L_ifdef; /* #if is now like #ifdef */
XX }
XX else {
XX if (type[c] != LET) /* Next non-blank isn't letter */
XX goto badif; /* ... is an error */
XX found = (lookid(c) != NULL); /* Look for it in symbol table */
XX }
XX if (found == (hash == L_ifdef)) {
XX compiling = TRUE;
XX *ifptr |= TRUE_SEEN;
XX }
XX else {
XX compiling = FALSE;
XX }
XX return;
XX
XXbadif: cerror("#if, #ifdef, or #ifndef without an argument", NULLST);
XX#if !OLD_PREPROCESSOR
XX skipnl(); /* Prevent an extra */
XX unget(); /* Error message */
XX#endif
XX return;
XX}
XX
XXFILE_LOCAL
XXdoinclude()
XX/*
XX * Process the #include control line.
XX * There are three variations:
XX * #include "file" search somewhere relative to the
XX * current source file, if not found,
XX * treat as #include <file>.
XX * #include <file> Search in an implementation-dependent
XX * list of places.
XX * #include token Expand the token, it must be one of
XX * "file" or <file>, process as such.
XX *
XX * Note: the November 12 draft forbids '>' in the #include <file> format.
XX * This restriction is unnecessary and not implemented.
XX */
XX{
XX register int c;
XX register int delim;
XX#if HOST == SYS_VMS
XX char def_filename[NAM$C_MAXRSS + 1];
XX#endif
XX
XX delim = macroid(skipws());
XX if (delim != '<' && delim != '"')
XX goto incerr;
XX if (delim == '<')
XX delim = '>';
XX workp = work;
XX instring = TRUE; /* Accept all characters */
XX while ((c = get()) != '\n' && c != delim && c != EOF_CHAR)
XX save(c); /* Put it away. */
XX skipnl();
XX /*
XX * The draft is unclear if the following should be done.
XX */
XX
XX while (--workp >= work && (type[*workp] == SPA))
XX ; /* Trim blanks from filename */
XX
XX/*
XX * if (*workp != delim)
XX * goto incerr;
XX */
XX *(workp + 1) = EOS; /* Terminate filename */
XX instring = FALSE;
XX#if HOST == SYS_VMS
XX /*
XX * Assume the default .h filetype.
XX */
XX if (!vmsparse(work, ".H", def_filename)) {
XX perror(work); /* Oops. */
XX goto incerr;
XX }
XX else if (openinclude(def_filename, (delim == '"')))
XX return;
XX#else
XX if (openinclude(work, (delim == '"')))
XX return;
XX#endif
XX /*
XX * No sense continuing if #include file isn't there.
XX */
XX cfatal("Cannot open include file \"%s\"", work);
XX
XXincerr: cerror("#include syntax error", NULLST);
XX return;
XX}
XX
XXFILE_LOCAL int
XXopeninclude(filename, searchlocal)
XXchar *filename; /* Input file name */
XXint searchlocal; /* TRUE if #include "file" */
XX/*
XX * Actually open an include file. This routine is only called from
XX * doinclude() above, but was written as a separate subroutine for
XX * programmer convenience. It searches the list of directories
XX * and actually opens the file, linking it into the list of
XX * active files. Returns TRUE if the file was opened, FALSE
XX * if openinclude() fails. No error message is printed.
XX */
XX{
XX register char **incptr;
XX#if HOST == SYS_VMS
XX#if NWORK < (NAM$C_MAXRSS + 1)
XX << error, NWORK isn't greater than NAM$C_MAXRSS >>
XX#endif
XX#endif
XX char tmpname[NWORK]; /* Filename work area */
XX
XX if (searchlocal) {
XX /*
XX * Look in local directory first
XX */
XX#if HOST == SYS_UNIX
XX /*
XX * Try to open filename relative to the directory of the current
XX * source file (as opposed to the current directory). (ARF, SCK).
XX */
XX if (filename[0] != '/'
XX && hasdirectory(infile->filename, tmpname))
XX strcat(tmpname, filename);
XX else {
XX strcpy(tmpname, filename);
XX }
XX#else
XX if (!hasdirectory(filename, tmpname)
XX && hasdirectory(infile->filename, tmpname))
XX strcat(tmpname, filename);
XX else {
XX strcpy(tmpname, filename);
XX }
XX#endif
XX if (openfile(tmpname))
XX return (TRUE);
XX }
XX /*
XX * Look in any directories specified by -I command line
XX * arguments, then in the builtin search list.
XX */
XX for (incptr = incdir; incptr < incend; incptr++) {
XX if (strlen(*incptr) + strlen(filename) >= (NWORK - 1))
XX cfatal("Filename work buffer overflow", NULLST);
XX else {
XX#if HOST == SYS_UNIX
XX if (filename[0] == '/')
XX strcpy(tmpname, filename);
XX else {
XX sprintf(tmpname, "%s/%s", *incptr, filename);
XX }
XX#else
XX if (!hasdirectory(filename, tmpname))
XX sprintf(tmpname, "%s%s", *incptr, filename);
XX#endif
XX if (openfile(tmpname))
XX return (TRUE);
XX }
XX }
XX return (FALSE);
XX}
XX
XXFILE_LOCAL int
XXhasdirectory(source, result)
XXchar *source; /* Directory to examine */
XXchar *result; /* Put directory stuff here */
XX/*
XX * If a device or directory is found in the source filename string, the
XX * node/device/directory part of the string is copied to result and
XX * hasdirectory returns TRUE. Else, nothing is copied and it returns FALSE.
XX */
XX{
XX#if HOST == SYS_UNIX
XX register char *tp;
XX
XX if ((tp = strrchr(source, '/')) == NULL)
XX return (FALSE);
XX else {
XX strncpy(result, source, tp - source + 1);
XX result[tp - source + 1] = EOS;
XX return (TRUE);
XX }
XX#else
XX#if HOST == SYS_VMS
XX if (vmsparse(source, NULLST, result)
XX && result[0] != EOS)
XX return (TRUE);
XX else {
XX return (FALSE);
XX }
XX#else
XX /*
XX * Random DEC operating system (RSX, RT11, RSTS/E)
XX */
XX register char *tp;
XX
XX if ((tp = strrchr(source, ']')) == NULL
XX && (tp = strrchr(source, ':')) == NULL)
XX return (FALSE);
XX else {
XX strncpy(result, source, tp - source + 1);
XX result[tp - source + 1] = EOS;
XX return (TRUE);
XX }
XX#endif
XX#endif
XX}
XX
XX#if HOST == SYS_VMS
XX
XX/*
XX * EXP_DEV is set if a device was specified, EXP_DIR if a directory
XX * is specified. (Both set indicate a file-logical, but EXP_DEV
XX * would be set by itself if you are reading, say, SYS$INPUT:)
XX */
XX#define DEVDIR (NAM$M_EXP_DEV | NAM$M_EXP_DIR)
XX
XXFILE_LOCAL int
XXvmsparse(source, defstring, result)
XXchar *source;
XXchar *defstring; /* non-NULL -> default string. */
XXchar *result; /* Size is at least NAM$C_MAXRSS + 1 */
XX/*
XX * Parse the source string, applying the default (properly, using
XX * the system parse routine), storing it in result.
XX * TRUE if it parsed, FALSE on error.
XX *
XX * If defstring is NULL, there are no defaults and result gets
XX * (just) the node::[directory] part of the string (possibly "")
XX */
XX{
XX struct FAB fab = cc$rms_fab; /* File access block */
XX struct NAM nam = cc$rms_nam; /* File name block */
XX char fullname[NAM$C_MAXRSS + 1];
XX register char *rp; /* Result pointer */
XX
XX fab.fab$l_nam = &nam; /* fab -> nam */
XX fab.fab$l_fna = source; /* Source filename */
XX fab.fab$b_fns = strlen(source); /* Size of source */
XX fab.fab$l_dna = defstring; /* Default string */
XX if (defstring != NULLST)
XX fab.fab$b_dns = strlen(defstring); /* Size of default */
XX nam.nam$l_esa = fullname; /* Expanded filename */
XX nam.nam$b_ess = NAM$C_MAXRSS; /* Expanded name size */
XX if (sys$parse(&fab) == RMS$_NORMAL) { /* Parse away */
XX fullname[nam.nam$b_esl] = EOS; /* Terminate string */
XX result[0] = EOS; /* Just in case */
XX rp = &result[0];
XX /*
XX * Remove stuff added implicitly, accepting node names and
XX * dev:[directory] strings (but not process-permanent files).
XX */
XX if ((nam.nam$l_fnb & NAM$M_PPF) == 0) {
XX if ((nam.nam$l_fnb & NAM$M_NODE) != 0) {
XX strncpy(result, nam.nam$l_node, nam.nam$b_node);
XX rp += nam.nam$b_node;
XX *rp = EOS;
XX }
XX if ((nam.nam$l_fnb & DEVDIR) == DEVDIR) {
XX strncpy(rp, nam.nam$l_dev, nam.nam$b_dev + nam.nam$b_dir);
XX rp += nam.nam$b_dev + nam.nam$b_dir;
XX *rp = EOS;
XX }
XX }
XX if (defstring != NULLST) {
XX strncpy(rp, nam.nam$l_name, nam.nam$b_name + nam.nam$b_type);
XX rp += nam.nam$b_name + nam.nam$b_type;
XX *rp = EOS;
XX if ((nam.nam$l_fnb & NAM$M_EXP_VER) != 0) {
XX strncpy(rp, nam.nam$l_ver, nam.nam$b_ver);
XX rp[nam.nam$b_ver] = EOS;
XX }
XX }
XX return (TRUE);
XX }
XX return (FALSE);
XX}
XX#endif
XX
XEND-of-cpp2.c
Xexit
X
END_OF_FILE
if test 54690 -ne `wc -c <'sys/unix/cpp1.shr'`; then
echo shar: \"'sys/unix/cpp1.shr'\" unpacked with wrong size!
fi
# end of 'sys/unix/cpp1.shr'
fi
echo shar: End of archive 2 \(of 108\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
101 102 103 104 105 106 107 108 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 108 archives.
echo "Now execute 'rebuild.sh'"
rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0