]> granicus.if.org Git - nethack/commitdiff
more obsolete files: DECUS C's preprocessor
authorPatR <rankin@nethack.org>
Fri, 4 Feb 2022 22:34:46 +0000 (14:34 -0800)
committerPatR <rankin@nethack.org>
Fri, 4 Feb 2022 22:34:46 +0000 (14:34 -0800)
Get rid sys/share/cpp[123].shr, the pre-ANSI C preprocessor that was
included in the source distribution for use on systems with ancient
C compilers whose preprocessor that couldn't cope with nethack's large
number of macros.

sys/unix/.gitattributes
sys/unix/cpp1.shr [deleted file]
sys/unix/cpp2.shr [deleted file]
sys/unix/cpp3.shr [deleted file]

index 6ddd7d79f8ce25abcfd85c34f9940d5857d69cb4..23a2412fd039e6e12c0b016411c82768106a3e09 100644 (file)
@@ -6,4 +6,4 @@ depend.awk NHSUBST
 sysconf NHSUBST
 *shr NH_header=no
 * NH_filestag=(file%s_for_UNIX_versions)
-cpp?.shr NH_filestag=(file%s_for_replacement_cpp,_only_needed_by_some_ancient_UNIX_systems)
+
diff --git a/sys/unix/cpp1.shr b/sys/unix/cpp1.shr
deleted file mode 100644 (file)
index f2b133d..0000000
+++ /dev/null
@@ -1,1783 +0,0 @@
-# This is a shell archive.  Save it in a file, remove anything before
-# this line, and then unpack it by entering "sh file".  Note, it may
-# create directories; files and directories will be owned by you and
-# have default permissions.
-#
-# This archive contains:
-#
-#      makefile.txt
-#      readme.txt
-#      cpp.mem
-#      cpp.h
-#      cppdef.h
-#      cpp2.c
-#
-echo x - makefile.txt
-sed 's/^X//' >makefile.txt << 'END-of-makefile.txt'
-X#
-X# The redefinition of strchr() and strrchr() are needed for
-X# Ultrix-32, Unix 4.2 bsd (and maybe some other Unices).
-X#
-XBSDDEFINE = -Dstrchr=index -Dstrrchr=rindex
-X#
-X# On certain systems, such as Unix System III, you may need to define
-X# $(LINTFLAGS) in the make command line to set system-specific lint flags.
-X#
-X# This Makefile assumes cpp will replace the "standard" preprocessor.
-X# Delete the reference to -DLINE_PREFIX=\"\" if cpp is used stand-alone.
-X# LINEFIX is a sed script filter that reinserts #line -- used for testing
-X# if LINE_PREFIX is set to "".   Note that we must stand on our heads to
-X# match the # and a line had better not begin with $.  By the way, what
-X# we really want is
-X#     LINEFIX = | sed "s/^#/#line/"
-X#
-XCPPDEFINE = -DLINE_PREFIX=\"\"
-XLINEFIX = | sed "s/^[^ !\"%-~]/&line/"
-X#
-X# Define OLD_PREPROCESSOR non-zero to make a preprocessor which is
-X# "as compatible as possible" with the standard Unix V7 or Ultrix
-X# preprocessors.  This is needed to rebuild 4.2bsd, for example, as
-X# the preprocessor is used to modify assembler code, rather than C.
-X# This is not recommended for current development.  OLD_PREPROCESSOR
-X# forces the following definitions:
-X#   OK_DOLLAR         FALSE   $ is not allowed in variables
-X#   OK_CONCAT         FALSE   # cannot concatenate tokens
-X#   COMMENT_INVISIBLE TRUE    old-style comment concatenation
-X#   STRING_FORMAL     TRUE    old-style string expansion
-X#
-XOLDDEFINE = -DOLD_PREPROCESSOR=1
-X#
-X# DEFINES collects all -D arguments for cc and lint:
-X# Change DEFINES = $(BSDDEFINE) $(CPPDEFINE) $(OLDDEFINE)
-X# for an old-style preprocessor.
-X#
-X# DEFINES = $(BSDDEFINE) $(CPPDEFINE)
-XDEFINES = $(CPPDEFINE)
-X
-XCFLAGS = -O $(DEFINES)
-X
-X#
-X# ** compile cpp
-X#
-XSRCS = cpp1.c cpp2.c cpp3.c cpp4.c cpp5.c cpp6.c
-XOBJS = cpp1.o cpp2.o cpp3.o cpp4.o cpp5.o cpp6.o
-Xcpp: $(OBJS)
-X      $(CC) $(CFLAGS) $(OBJS) -o cpp
-X
-X#
-X# ** Test cpp by preprocessing itself, compiling the result,
-X# ** repeating the process and diff'ing the result.  Note: this
-X# ** is not a good test of cpp, but a simple verification.
-X# ** The diff's should not report any changes.
-X# ** Note that a sed script may be executed for each compile
-X#
-Xtest:
-X      cpp cpp1.c $(LINEFIX) >old.tmp1.c
-X      cpp cpp2.c $(LINEFIX) >old.tmp2.c
-X      cpp cpp3.c $(LINEFIX) >old.tmp3.c
-X      cpp cpp4.c $(LINEFIX) >old.tmp4.c
-X      cpp cpp5.c $(LINEFIX) >old.tmp5.c
-X      cpp cpp6.c $(LINEFIX) >old.tmp6.c
-X      $(CC) $(CFLAGS) old.tmp[123456].c
-X      a.out cpp1.c >new.tmp1.c
-X      a.out cpp2.c >new.tmp2.c
-X      a.out cpp3.c >new.tmp3.c
-X      a.out cpp4.c >new.tmp4.c
-X      a.out cpp5.c >new.tmp5.c
-X      a.out cpp6.c >new.tmp6.c
-X      diff old.tmp1.c new.tmp1.c
-X      diff old.tmp2.c new.tmp2.c
-X      diff old.tmp3.c new.tmp3.c
-X      diff old.tmp4.c new.tmp4.c
-X      diff old.tmp5.c new.tmp5.c
-X      diff old.tmp6.c new.tmp6.c
-X      rm a.out old.tmp[123456].* new.tmp[123456].*
-X
-X#
-X# A somewhat more extensive test is provided by the "clock"
-X# program (which is not distributed).  Substitute your favorite
-X# macro-rich program here.
-X#
-Xclock:        clock.c cpp
-X      cpp clock.c $(LINEFIX) >temp.cpp.c
-X      cc temp.cpp.c -lcurses -ltermcap -o clock
-X      rm temp.cpp.c
-X
-X#
-X# ** Lint the code
-X#
-X
-Xlint: $(SRCS)
-X      lint $(LINTFLAGS) $(DEFINES) $(SRCS)
-X
-X#
-X# ** Remove unneeded files
-X#
-Xclean:
-X      rm -f $(OBJS) cpp
-X
-X#
-X# ** Rebuild the archive files needed to distribute cpp
-X# ** Uses the Decus C archive utility.
-X#
-X
-Xarchc:        archc.c
-X      $(CC) $(CFLAGS) archc.c -o archc
-X
-Xarchx:        archx.c
-X      $(CC) $(CFLAGS) archx.c -o archx
-X
-Xarchive: archc
-X      archc readme.txt cpp.mem archx.c archc.c cpp.rno makefile.txt \
-X              cpp*.h >cpp1.arc
-X      archc cpp1.c cpp2.c cpp3.c >cpp2.arc
-X      archc cpp4.c cpp5.c cpp6.c >cpp3.arc
-X
-X#
-X# Object module dependencies
-X#
-X
-Xcpp1.o        :       cpp1.c cpp.h cppdef.h
-X
-Xcpp2.o        :       cpp2.c cpp.h cppdef.h
-X
-Xcpp3.o        :       cpp3.c cpp.h cppdef.h
-X
-Xcpp4.o        :       cpp4.c cpp.h cppdef.h
-X
-Xcpp5.o        :       cpp5.c cpp.h cppdef.h
-X
-Xcpp6.o        :       cpp6.c cpp.h cppdef.h
-X
-X
-END-of-makefile.txt
-echo x - readme.txt
-sed 's/^X//' >readme.txt << 'END-of-readme.txt'
-X
-XDecus cpp is a public-domain implementation of the C preprocessor.
-XIt runs on VMS native (Vax C), VMS compatibilty mode (Decus C),
-XRSX-11M, RSTS/E, P/OS, and RT11, as well as on several varieties
-Xof Unix, including Ultrix.  Decus cpp attempts to implement features
-Xin the Draft ANSI Standard for the C language.  It should be noted,
-Xhowever, that this standard is under active development:  the current
-Xdraft of the standard explicitly states that "readers are requested
-Xnot to specify or claim conformance to this draft."  Thus readers
-Xand users of Decus cpp should not assume that it conforms to the
-Xdraft standard, or that it will conform to the actual C language
-Xstandard.
-X
-XThese notes describe how to extract the cpp source files, configure it
-Xfor your needs, and mention a few design decisions that may be of interest
-Xto maintainers.
-X
-X                      Installation
-X
-XBecause the primary development of cpp was not on Unix, it
-Xis distributed using the Decus C archive program (quite similar
-Xto the archiver published in Kernighan and Plauger's Software
-XTools).  To extract the files from the net.sources distribution,
-Xsave this message as cpp1.arc and the other two distribution
-Xfiles as cpp2.arc and cpp3.arc.  Then, using your favorite editor,
-Xlocate the archx.c program, just following the line beginning with
-X"-h- archx.c" -- the format of the distribution is just:
-X
-X    -h- readme.txt
-X      ... this file
-X    -h- cpp.mem
-X      ... description of cpp
-X    -h- archx.c
-X      ... archx.c program -- extracts archives
-X    -h- archc.c
-X      ... archc.c program -- creates archives
-X
-XCompile archx.c -- it shouldn't require any special editing.
-XThen run it as follows:
-X
-X    archx *.arc
-X
-XYou do not need to remove mail headers from the saved messages.
-X
-XYou should then read through cppdef.h to make sure the HOST and
-XTARGET (and other implementation-specific) definitions are set
-Xcorrectly for your machine, editing them as needed.
-X
-XYou may then copy makefile.txt to Makefile, editing it as needed
-Xfor your particular system.  On Unix, cpp should be compiled
-Xby make without further difficulty.  On other operating systems,
-Xyou should compile the six source modules, linking them together.
-XNote that, on Decus C based systems, you must extend the default
-Xstack allocation.  The Decus C build utility will create the
-Xappropriate command file.
-X
-X                      Support Notes
-X
-XThe USENET distribution kit was designed to keep all submissions around
-X50,000 bytes:
-X
-Xcpp1.arc:
-X      readme.txt      This file
-X      cpp.mem         Documentation page (see below)
-X      archx.c         Archive extraction program
-X      archc.c         Archive construction program
-X      cpp.rno         Source for cpp.mem (see below)
-X      makefile.txt    Unix makefile -- copy to Makefile
-X      cpp.h           Main header file (structure def's and globals)
-X      cppdef.h        Configuration file (host and target definitions)
-X
-Xcpp2.arc:
-X      cpp1.c          Mainline code, documentation master sources
-X      cpp2.c          most #control processing
-X      cpp3.c          filename stuff and command line parsing
-Xcpp3.arc:
-X      cpp4.c          #define processor
-X      cpp5.c          #if <expr> processor
-X      cpp6.c          Support code (symbol table and I/O routines)
-X      
-XCpp intentionally does not rely on the presence of a full-scale
-Xmacro preprocessor, it does require the simple parameter substitution
-Xpreprocessor capabilities of Unix V6 and Decus C.  If your C
-Xlanguage lacks full preprocessing, you should make sure "nomacargs"
-Xis #define'd in cpp.h.  (This is done automatically by the Decus C
-Xcompiler.)
-X
-XThe documentation (manual page) for cpp is included as cpp.mem
-Xand cpp.rno.  Cpp.rno is in Dec Runoff format, built by a Decus C
-Xutility (getrno) from original source which is embedded in cpp1.c.
-XTo my knowledge, there is no equivalent program that creates
-Xthe nroff source appropriate for Unix.
-X
-XI would be happy to receive fixes to any problems you encounter.
-XAs I do not maintain distribution kit base-levels, bare-bones
-Xdiff listings without sufficient context are not very useful.
-XIt is unlikely that I can find time to help you with other
-Xdifficulties.
-X
-X                      Acknowledgements
-X
-XI received a great deal of help from many people in debugging cpp.
-XAlan Feuer and Sam Kendall used "state of the art" run-time code
-Xcheckers to locate several errors.  Ed Keiser found problems when
-Xcpp was used on machines with different int and pointer sizes.
-XDave Conroy helped with the initial debugging, while Arthur Olsen
-Xand George Rosenberg found (and solved) several problems in the
-Xfirst USENET release.
-X
-XMartin Minow
-Xdecvax!minow
-X
-END-of-readme.txt
-echo x - cpp.mem
-sed 's/^X//' >cpp.mem << 'END-of-cpp.mem'
-X
-X
-X
-X
-X        1.0  C Pre-Processor
-X
-X
-X
-X                                    *******
-X                                    * cpp *
-X                                    *******
-X
-X
-X
-X        NAME:   cpp -- C Pre-Processor
-X
-X        SYNOPSIS:
-X
-X                cpp [-options] [infile [outfile]]
-X
-X        DESCRIPTION:
-X
-X                CPP reads a C source file, expands  macros  and  include
-X                files,  and writes an input file for the C compiler.  If
-X                no file arguments are given, CPP reads  from  stdin  and
-X                writes  to  stdout.   If  one file argument is given, it
-X                will define the input file,  while  two  file  arguments
-X                define  both  input and output files.  The file name "-"
-X                is a synonym for stdin or stdout as appropriate.
-X
-X                The following options are  supported.   Options  may  be
-X                given in either case.
-X
-X                -C              If set, source-file comments are written
-X                                to  the  output  file.   This allows the
-X                                output of CPP to be used as the input to
-X                                a  program,  such  as lint, that expects
-X                                commands embedded in specially-formatted
-X                                comments.
-X
-X                -Dname=value    Define the name  as  if  the  programmer
-X                                wrote
-X
-X                                    #define name value
-X
-X                                at the start  of  the  first  file.   If
-X                                "=value"  is  not  given, a value of "1"
-X                                will be used.
-X
-X                                On non-unix systems, all alphabetic text
-X                                will be forced to upper-case.
-X
-X                -E              Always return "success" to the operating
-X                                system,  even  if  errors were detected.
-X                                Note that some fatal errors, such  as  a
-X                                missing  #include  file,  will terminate
-X                                CPP, returning "failure" even if the  -E
-X                                option is given.
-X\f                                                                          Page 2
-X        cpp     C Pre-Processor
-X
-X
-X                -Idirectory     Add  this  directory  to  the  list   of
-X                                directories  searched for #include "..."
-X                                and #include <...> commands.  Note  that
-X                                there  is  no space between the "-I" and
-X                                the directory string.  More than one  -I
-X                                command   is   permitted.   On  non-Unix
-X                                systems   "directory"   is   forced   to
-X                                upper-case.
-X
-X                -N              CPP  normally  predefines  some  symbols
-X                                defining   the   target   computer   and
-X                                operating system.  If -N  is  specified,
-X                                no symbols will be predefined.  If -N -N
-X                                is  specified,  the   "always   present"
-X                                symbols,    __LINE__,    __FILE__,   and
-X                                __DATE__ are not defined.
-X
-X                -Stext          CPP normally assumes that  the  size  of
-X                                the  target  computer's  basic  variable
-X                                types is the same as the size  of  these
-X                                types  of  the host computer.  (This can
-X                                be  overridden  when  CPP  is  compiled,
-X                                however.)  The  -S option allows dynamic
-X                                respecification of these values.  "text"
-X                                is  a  string  of  numbers, separated by
-X                                commas, that  specifies  correct  sizes.
-X                                The sizes must be specified in the exact
-X                                order:
-X
-X                                    char short int long float double
-X
-X                                If you specify the option as  "-S*text",
-X                                pointers   to   these   types   will  be
-X                                specified.   -S*  takes  one  additional
-X                                argument  for  pointer to function (e.g.
-X                                int (*)())
-X
-X                                For   example,    to    specify    sizes
-X                                appropriate  for  a  PDP-11,  you  would
-X                                write:
-X
-X                                       c s i l f d func
-X                                     -S1,2,2,2,4,8,
-X                                    -S*2,2,2,2,2,2,2
-X
-X                                Note that all values must be specified.
-X
-X                -Uname          Undefine the name as if
-X
-X                                    #undef name
-X
-X                                were given.  On non-Unix systems, "name"
-X                                will be forced to upper-case.
-X\f                                                                          Page 3
-X        cpp     C Pre-Processor
-X
-X
-X                -Xnumber        Enable debugging code.  If no  value  is
-X                                given,  a value of 1 will be used.  (For
-X                                maintenence of CPP only.)
-X
-X
-X        PRE-DEFINED VARIABLES:
-X
-X                When CPP begins processing, the following variables will
-X                have been defined (unless the -N option is specified):
-X
-X                Target computer (as appropriate):
-X
-X                    pdp11, vax, M68000 m68000 m68k
-X
-X                Target operating system (as appropriate):
-X
-X                    rsx, rt11, vms, unix
-X
-X                Target compiler (as appropriate):
-X
-X                    decus, vax11c
-X
-X                The implementor may add definitions to this  list.   The
-X                default  definitions  match  the  definition of the host
-X                computer, operating system, and C compiler.
-X
-X                The following are always available unless undefined  (or
-X                -N was specified twice):
-X
-X                    __FILE__    The  input  (or  #include)  file   being
-X                                compiled (as a quoted string).
-X
-X                    __LINE__    The line number being compiled.
-X
-X                    __DATE__    The date and time of  compilation  as  a
-X                                Unix  ctime  quoted string (the trailing
-X                                newline is removed).  Thus,
-X
-X                                    printf("Bug at line %s,", __LINE__);
-X                                    printf(" source file %s", __FILE__);
-X                                    printf(" compiled on %s", __DATE__);
-X
-X
-X        DRAFT PROPOSED ANSI STANDARD CONSIDERATIONS:
-X
-X                The current  version  of  the  Draft  Proposed  Standard
-X                explicitly  states  that  "readers  are requested not to
-X                specify or claim conformance to this draft." Readers and
-X                users  of  Decus  CPP  should  not assume that Decus CPP
-X                conforms to the standard, or that it will conform to the
-X                actual C Language Standard.
-X
-X                When CPP is itself compiled, many features of the  Draft
-X                Proposed  Standard  that  are incompatible with existing
-X\f                                                                          Page 4
-X        cpp     C Pre-Processor
-X
-X
-X                preprocessors may be  disabled.   See  the  comments  in
-X                CPP's source for details.
-X
-X                The latest version of the Draft  Proposed  Standard  (as
-X                reflected in Decus CPP) is dated November 12, 1984.
-X
-X                Comments are removed from the input text.   The  comment
-X                is  replaced by a single space character.  The -C option
-X                preserves comments, writing them to the output file.
-X
-X                The '$' character is considered to be a letter.  This is
-X                a permitted extension.
-X
-X                The following new features of C are processed by CPP:
-X
-X                    #elif expression (#else #if)
-X                    '\xNNN' (Hexadecimal constant)
-X                    '\a' (Ascii BELL)
-X                    '\v' (Ascii Vertical Tab)
-X                    #if defined NAME 1 if defined, 0 if not
-X                    #if defined (NAME) 1 if defined, 0 if not
-X                    #if sizeof (basic type)
-X                    unary +
-X                    123U, 123LU Unsigned ints and longs.
-X                    12.3L Long double numbers
-X                    token#token Token concatenation
-X                    #include token Expands to filename
-X
-X                The Draft Proposed Standard has  extended  C,  adding  a
-X                constant string concatenation operator, where
-X
-X                    "foo" "bar"
-X
-X                is regarded as the single string "foobar".   (This  does
-X                not  affect  CPP's  processing but does permit a limited
-X                form of macro argument substitution into strings as will
-X                be discussed.)
-X
-X                The Standard Committee plans to add token  concatenation
-X                to  #define command lines.  One suggested implementation
-X                is as follows:  the sequence "Token1#Token2" is  treated
-X                as  if  the programmer wrote "Token1Token2".  This could
-X                be used as follows:
-X
-X                    #line 123
-X                    #define ATLINE foo#__LINE__
-X
-X                ATLINE would be defined as foo123.
-X
-X                Note that "Token2" must either have  the  format  of  an
-X                identifier or be a string of digits.  Thus, the string
-X
-X                    #define ATLINE foo#1x3
-X\f                                                                          Page 5
-X        cpp     C Pre-Processor
-X
-X
-X                generates two tokens:  "foo1" and "x3".
-X
-X                If the tokens T1 and T2 are concatenated into  T3,  this
-X                implementation operates as follows:
-X
-X                  1. Expand T1 if it is a macro.
-X                  2. Expand T2 if it is a macro.
-X                  3. Join the tokens, forming T3.
-X                  4. Expand T3 if it is a macro.
-X
-X                A macro formal parameter  will  be  substituted  into  a
-X                string or character constant if it is the only component
-X                of that constant:
-X
-X                    #define VECSIZE 123
-X                    #define vprint(name, size) \
-X                      printf("name" "[" "size" "] = {\n")
-X                      ... vprint(vector, VECSIZE);
-X
-X                expands (effectively) to
-X
-X                      vprint("vector[123] = {\n");
-X
-X                Note that  this  will  be  useful  if  your  C  compiler
-X                supports  the  new  string concatenation operation noted
-X                above.  As implemented here, if you write
-X
-X                    #define string(arg) "arg"
-X                      ... string("foo") ...
-X
-X                This implementation generates  "foo",  rather  than  the
-X                strictly  correct  ""foo"" (which will probably generate
-X                an error message).  This is, strictly speaking, an error
-X                in CPP and may be removed from future releases.
-X
-X        ERROR MESSAGES:
-X
-X                Many.  CPP prints warning or error messages if  you  try
-X                to     use     multiple-byte     character     constants
-X                (non-transportable) if you #undef a symbol that was  not
-X                defined,  or  if  your  program  has  potentially nested
-X                comments.
-X
-X        AUTHOR:
-X
-X                Martin Minow
-X
-X        BUGS:
-X
-X                The #if expression processor uses signed integers  only.
-X                I.e, #if 0xFFFFu < 0 may be TRUE.
-X
-END-of-cpp.mem
-echo x - cpp.h
-sed 's/^X//' >cpp.h << 'END-of-cpp.h'
-X
-X/*
-X *    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
-X *
-X * In general, definitions in this file should not be changed.
-X */
-X
-X#ifndef       TRUE
-X#define       TRUE            1
-X#define       FALSE           0
-X#endif
-X#ifndef       EOS
-X/*
-X * This is predefined in Decus C
-X */
-X#define       EOS             '\0'            /* End of string                */
-X#endif
-X#define       EOF_CHAR        0               /* Returned by get() on eof     */
-X#define NULLST                ((char *) NULL) /* Pointer to nowhere (linted)  */
-X#define       DEF_NOARGS      (-1)            /* #define foo vs #define foo() */
-X
-X/*
-X * The following may need to change if the host system doesn't use ASCII.
-X */
-X#define       DEF_MAGIC       0x1D            /* Magic for #defines           */
-X#define       TOK_SEP         0x1E            /* Token concatenation delim.   */
-X#define COM_SEP               0x1F            /* Magic comment separator      */
-X
-X/*
-X * Note -- in Ascii, the following will map macro formals onto DEL + the
-X * C1 control character region (decimal 128 .. (128 + PAR_MAC)) which will
-X * be ok as long as PAR_MAC is less than 33).  Note that the last PAR_MAC
-X * value is reserved for string substitution.
-X */
-X
-X#define       MAC_PARM        0x7F            /* Macro formals start here     */
-X#if PAR_MAC >= 33
-X      assertion fails -- PAR_MAC isn't less than 33
-X#endif
-X#define       LASTPARM        (PAR_MAC - 1)
-X
-X/*
-X * Character type codes.
-X */
-X
-X#define       INV             0               /* Invalid, must be zero        */
-X#define       OP_EOE          INV             /* End of expression            */
-X#define       DIG             1               /* Digit                        */
-X#define       LET             2               /* Identifier start             */
-X#define       FIRST_BINOP     OP_ADD
-X#define       OP_ADD          3
-X#define       OP_SUB          4
-X#define       OP_MUL          5
-X#define       OP_DIV          6
-X#define       OP_MOD          7
-X#define       OP_ASL          8
-X#define       OP_ASR          9
-X#define       OP_AND          10              /* &, not &&                    */
-X#define       OP_OR           11              /* |, not ||                    */
-X#define       OP_XOR          12
-X#define       OP_EQ           13
-X#define       OP_NE           14
-X#define       OP_LT           15
-X#define       OP_LE           16
-X#define       OP_GE           17
-X#define       OP_GT           18
-X#define       OP_ANA          19              /* &&                           */
-X#define       OP_ORO          20              /* ||                           */
-X#define       OP_QUE          21              /* ?                            */
-X#define       OP_COL          22              /* :                            */
-X#define       OP_CMA          23              /* , (relevant?)                */
-X#define       LAST_BINOP      OP_CMA          /* Last binary operand          */
-X/*
-X * The following are unary.
-X */
-X#define       FIRST_UNOP      OP_PLU          /* First Unary operand          */
-X#define       OP_PLU          24              /* + (draft ANSI standard)      */
-X#define       OP_NEG          25              /* -                            */
-X#define       OP_COM          26              /* ~                            */
-X#define       OP_NOT          27              /* !                            */
-X#define       LAST_UNOP       OP_NOT
-X#define       OP_LPA          28              /* (                            */
-X#define       OP_RPA          29              /* )                            */
-X#define       OP_END          30              /* End of expression marker     */
-X#define       OP_MAX          (OP_END + 1)    /* Number of operators          */
-X#define       OP_FAIL         (OP_END + 1)    /* For error returns            */
-X
-X/*
-X * The following are for lexical scanning only.
-X */
-X
-X#define       QUO             65              /* Both flavors of quotation    */
-X#define       DOT             66              /* . might start a number       */
-X#define       SPA             67              /* Space and tab                */
-X#define       BSH             68              /* Just a backslash             */
-X#define       END             69              /* EOF                          */
-X
-X/*
-X * These bits are set in ifstack[]
-X */
-X#define       WAS_COMPILING   1               /* TRUE if compile set at entry */
-X#define       ELSE_SEEN       2               /* TRUE when #else processed    */
-X#define       TRUE_SEEN       4               /* TRUE when #if TRUE processed */
-X
-X/*
-X * Define bits for the basic types and their adjectives
-X */
-X
-X#define       T_CHAR            1
-X#define       T_INT             2
-X#define       T_FLOAT           4
-X#define       T_DOUBLE          8
-X#define       T_SHORT          16
-X#define       T_LONG           32
-X#define       T_SIGNED         64
-X#define       T_UNSIGNED      128
-X#define       T_PTR           256             /* Pointer                      */
-X#define       T_FPTR          512             /* Pointer to functions         */
-X\f
-X/*
-X * The DEFBUF structure stores information about #defined
-X * macros.  Note that the defbuf->repl information is always
-X * in malloc storage.
-X */
-X
-Xtypedef struct defbuf {
-X      struct defbuf   *link;          /* Next define in chain */
-X      char            *repl;          /* -> replacement       */
-X      int             hash;           /* Symbol table hash    */
-X      int             nargs;          /* For define(args)     */
-X      char            name[1];        /* #define name         */
-X} DEFBUF;
-X
-X/*
-X * The FILEINFO structure stores information about open files
-X * and macros being expanded.
-X */
-X
-Xtypedef struct fileinfo {
-X      char            *bptr;          /* Buffer pointer       */
-X      int             line;           /* for include or macro */
-X      FILE            *fp;            /* File if non-null     */
-X      struct fileinfo *parent;        /* Link to includer     */
-X      char            *filename;      /* File/macro name      */
-X      char            *progname;      /* From #line statement */
-X      unsigned int    unrecur;        /* For macro recursion  */
-X      char            buffer[1];      /* current input line   */
-X} FILEINFO;
-X
-X/*
-X * The SIZES structure is used to store the values for #if sizeof
-X */
-X
-Xtypedef struct sizes {
-X    short     bits;                   /* If this bit is set,          */
-X    short     size;                   /* this is the datum size value */
-X    short     psize;                  /* this is the pointer size     */
-X} SIZES;
-X/*
-X * nomacarg is a built-in #define on Decus C.
-X */
-X
-X#ifdef        nomacarg
-X#define       cput            output          /* cput concatenates tokens     */
-X#else
-X#if COMMENT_INVISIBLE
-X#define       cput(c)         { if (c != TOK_SEP && c != COM_SEP) putchar(c); }
-X#else
-X#define       cput(c)         { if (c != TOK_SEP) putchar(c); }
-X#endif
-X#endif
-X
-X#ifndef       nomacarg
-X#define       streq(s1, s2)   (strcmp(s1, s2) == 0)
-X#endif
-X
-X/*
-X * Error codes.  VMS uses system definitions.
-X * Decus C codes are defined in stdio.h.
-X * Others are cooked to order.
-X */
-X
-X#if HOST == SYS_VMS
-X#include              <ssdef.h>
-X#include              <stsdef.h>
-X#define       IO_NORMAL       (SS$_NORMAL | STS$M_INHIB_MSG)
-X#define       IO_ERROR        SS$_ABORT
-X#endif
-X/*
-X * Note: IO_NORMAL and IO_ERROR are defined in the Decus C stdio.h file
-X */
-X#ifndef       IO_NORMAL
-X#define       IO_NORMAL       0
-X#endif
-X#ifndef       IO_ERROR
-X#define       IO_ERROR        1
-X#endif
-X
-X/*
-X * Externs
-X */
-X
-Xextern int    line;                   /* Current line number          */
-Xextern int    wrongline;              /* Force #line to cc pass 1     */
-Xextern char   type[];                 /* Character classifier         */
-Xextern char   token[IDMAX + 1];       /* Current input token          */
-Xextern int    instring;               /* TRUE if scanning string      */
-Xextern int    inmacro;                /* TRUE if scanning #define     */
-Xextern int    errors;                 /* Error counter                */
-Xextern int    recursion;              /* Macro depth counter          */
-Xextern char   ifstack[BLK_NEST];      /* #if information              */
-X#define       compiling ifstack[0]
-Xextern char   *ifptr;                 /* -> current ifstack item      */
-Xextern char   *incdir[NINCLUDE];      /* -i directories               */
-Xextern char   **incend;               /* -> active end of incdir      */
-Xextern int    cflag;                  /* -C option (keep comments)    */
-Xextern int    eflag;                  /* -E option (ignore errors)    */
-Xextern int    nflag;                  /* -N option (no pre-defines)   */
-Xextern int    rec_recover;            /* unwind recursive macros      */
-Xextern char   *preset[];              /* Standard predefined symbols  */
-Xextern char   *magic[];               /* Magic predefined symbols     */
-Xextern FILEINFO       *infile;                /* Current input file           */
-Xextern char   work[NWORK + 1];        /* #define scratch              */
-Xextern char   *workp;                 /* Free space in work           */
-X#if   DEBUG
-Xextern int    debug;                  /* Debug level                  */
-X#endif
-Xextern int    keepcomments;           /* Don't remove comments if set */
-Xextern SIZES  size_table[];           /* For #if sizeof sizes         */
-Xextern char   *getmem();              /* Get memory or die.           */
-Xextern DEFBUF *lookid();              /* Look for a #define'd thing   */
-Xextern DEFBUF *defendel();            /* Symbol table enter/delete    */
-Xextern char   *savestring();          /* Stuff string in malloc mem.  */
-Xextern char   *strcpy();
-Xextern char   *strcat();
-Xextern char   *strrchr();
-Xextern char   *strchr();
-Xextern long   time();
-X/* extern char        *sprintf();             /* Lint needs this              */
-END-of-cpp.h
-echo x - cppdef.h
-sed 's/^X//' >cppdef.h << 'END-of-cppdef.h'
-X/*
-X *               S y s t e m   D e p e n d e n t
-X *            D e f i n i t i o n s    f o r   C P P
-X *
-X * Definitions in this file may be edited to configure CPP for particular
-X * host operating systems and target configurations.
-X *
-X * NOTE: cpp assumes it is compiled by a compiler that supports macros
-X * with arguments.  If this is not the case (as for Decus C), #define
-X * nomacarg -- and provide function equivalents for all macros.
-X *
-X * cpp also assumes the host and target implement the Ascii character set.
-X * If this is not the case, you will have to do some editing here and there.
-X */
-X
-X/*
-X * This redundant definition of TRUE and FALSE works around
-X * a limitation of Decus C.
-X */
-X#ifndef       TRUE
-X#define       TRUE                    1
-X#define       FALSE                   0
-X#endif
-X
-X/*
-X * Define the HOST operating system.  This is needed so that
-X * cpp can use appropriate filename conventions.
-X */
-X#define       SYS_UNKNOWN             0
-X#define       SYS_UNIX                1
-X#define       SYS_VMS                 2
-X#define       SYS_RSX                 3
-X#define       SYS_RT11                4
-X#define       SYS_LATTICE             5
-X#define       SYS_ONYX                6
-X#define       SYS_68000               7
-X#define SYS_GCOS              8
-X#define SYS_IBM                       9
-X#define SYS_OS                        10
-X#define SYS_TSS                       11
-X
-X#ifndef       HOST
-X#ifdef        unix
-X#define       HOST                    SYS_UNIX
-X#else
-X#ifdef        vms
-X#define       HOST                    SYS_VMS
-X#else
-X#ifdef        rsx
-X#define       HOST                    SYS_RSX
-X#else
-X#ifdef        rt11
-X#define       HOST                    SYS_RT11
-X#else
-X#ifdef dmert
-X#define HOST                  SYS_DMERT
-X#else
-X#ifdef gcos
-X#define HOST                  SYS_GCOS
-X#else
-X#ifdef ibm
-X#define HOST                  SYS_IBM
-X#else
-X#ifdef os
-X#define HOST                  SYS_OS
-X#else
-X#ifdef tss                    
-X#define HOST                  SYS_TSS
-X#endif
-X#endif
-X#endif
-X#endif
-X#endif
-X#endif
-X#endif
-X#endif
-X#endif
-X
-X#ifndef       HOST
-X#define       HOST                    SYS_UNKNOWN
-X#endif
-X
-X/*
-X * We assume that the target is the same as the host system
-X */
-X#ifndef       TARGET
-X#define       TARGET                  HOST
-X#endif
-X
-X/*
-X * In order to predefine machine-dependent constants,
-X * several strings are defined here:
-X *
-X * MACHINE    defines the target cpu (by name)
-X * SYSTEM     defines the target operating system
-X * COMPILER   defines the target compiler
-X *
-X *    The above may be #defined as "" if they are not wanted.
-X *    They should not be #defined as NULL.
-X *
-X * LINE_PREFIX        defines the # output line prefix, if not "line"
-X *            This should be defined as "" if cpp is to replace
-X *            the "standard" C pre-processor.
-X *
-X * FILE_LOCAL marks functions which are referenced only in the
-X *            file they reside.  Some C compilers allow these
-X *            to be marked "static" even though they are referenced
-X *            by "extern" statements elsewhere.
-X *
-X * OK_DOLLAR  Should be set TRUE if $ is a valid alphabetic character
-X *            in identifiers (default), or zero if $ is invalid.
-X *            Default is TRUE.
-X *
-X * OK_CONCAT  Should be set TRUE if # may be used to concatenate
-X *            tokens in macros (per the Ansi Draft Standard) or
-X *            FALSE for old-style # processing (needed if cpp is
-X *            to process assembler source code).
-X *
-X * OK_DATE    Predefines the compilation date if set TRUE.
-X *            Not permitted by the Nov. 12, 1984 Draft Standard.
-X *
-X * S_CHAR etc.        Define the sizeof the basic TARGET machine word types.
-X *            By default, sizes are set to the values for the HOST
-X *            computer.  If this is inappropriate, see the code in
-X *            cpp3.c for details on what to change.  Also, if you
-X *            have a machine where sizeof (signed int) differs from
-X *            sizeof (unsigned int), you will have to edit code and
-X *            tables in cpp3.c (and extend the -S option definition.)
-X *
-X * CPP_LIBRARY        May be defined if you have a site-specific include directory
-X *            which is to be searched *before* the operating-system
-X *            specific directories.
-X */
-X
-X#if TARGET == SYS_LATTICE
-X/*
-X * We assume the operating system is pcdos for the IBM-PC.
-X * We also assume the small model (just like the PDP-11)
-X */
-X#define MACHINE                       "i8086"
-X#define       SYSTEM                  "pcdos"
-X#endif
-X
-X#if TARGET == SYS_ONYX
-X#define       MACHINE                 "z8000"
-X#define       SYSTEM                  "unix"
-X#endif
-X
-X#if TARGET == SYS_VMS
-X#define       MACHINE                 "vax"
-X#define       SYSTEM                  "vms"
-X#define       COMPILER                "vax11c"
-X#endif
-X
-X#if TARGET == SYS_RSX
-X#define       MACHINE                 "pdp11"
-X#define       SYSTEM                  "rsx"
-X#define       COMPILER                "decus"
-X#endif
-X
-X#if TARGET == SYS_RT11
-X#define       MACHINE                 "pdp11"
-X#define       SYSTEM                  "rt11"
-X#define       COMPILER                "decus"
-X#endif
-X
-X#if TARGET == SYS_68000
-X/*
-X * All three machine designators have been seen in various systems.
-X * Warning -- compilers differ as to sizeof (int).  cpp3 assumes that
-X * sizeof (int) == 2
-X */
-X#define       MACHINE                 "M68000", "m68000", "m68k"
-X#define       SYSTEM                  "unix"
-X#endif
-X
-X#if   TARGET == SYS_UNIX
-X#define       SYSTEM                  "unix"
-X#ifdef        pdp11
-X#define       MACHINE                 "pdp11"
-X#endif
-X#ifdef        vax
-X#define       MACHINE                 "vax"
-X#endif
-X#ifdef u370
-X#define MACHINE                       "u370"
-X#endif
-X#ifdef interdata
-X#define MACHINE                       "interdata"
-X#endif
-X#ifdef u3b
-X#define MACHINE                       "u3b"
-X#endif
-X#ifdef u3b5   
-X#define MACHINE                       "u3b5"
-X#endif
-X#ifdef u3b2
-X#define MACHINE                       "u3b2"
-X#endif
-X#ifdef u3b20d
-X#define MACHINE                       "u3b20d"
-X#endif
-X#endif
-X#endif
-X
-X/*
-X * defaults
-X */
-X
-X#ifndef MSG_PREFIX
-X#define MSG_PREFIX            "cpp: "
-X#endif
-X
-X#ifndef LINE_PREFIX
-X#ifdef        decus
-X#define       LINE_PREFIX             ""
-X#else
-X#define LINE_PREFIX           "line"
-X#endif
-X#endif
-X\f
-X/*
-X * OLD_PREPROCESSOR forces the definition of OK_DOLLAR, OK_CONCAT,
-X * COMMENT_INVISIBLE, and STRING_FORMAL to values appropriate for
-X * an old-style preprocessor.
-X */
-X 
-X#ifndef       OLD_PREPROCESSOR
-X#define       OLD_PREPROCESSOR        FALSE
-X#endif
-X
-X#if   OLD_PREPROCESSOR
-X#define       OK_DOLLAR               FALSE
-X#define       OK_CONCAT               FALSE
-X#define       COMMENT_INVISIBLE       TRUE
-X#define       STRING_FORMAL           TRUE
-X#endif
-X
-X/*
-X * RECURSION_LIMIT may be set to -1 to disable the macro recursion test.
-X */
-X#ifndef       RECURSION_LIMIT
-X#define       RECURSION_LIMIT 1000
-X#endif
-X
-X/*
-X * BITS_CHAR may be defined to set the number of bits per character.
-X * it is needed only for multi-byte character constants.
-X */
-X#ifndef       BITS_CHAR
-X#define       BITS_CHAR               8
-X#endif
-X
-X/*
-X * BIG_ENDIAN is set TRUE on machines (such as the IBM 360 series)
-X * where 'ab' stores 'a' in the high-bits and 'b' in the low-bits.
-X * It is set FALSE on machines (such as the PDP-11 and Vax-11)
-X * where 'ab' stores 'a' in the low-bits and 'b' in the high-bits.
-X * (Or is it the other way around?) -- Warning: BIG_ENDIAN code is untested.
-X */
-X#ifndef       BIG_ENDIAN
-X#define       BIG_ENDIAN              FALSE
-X#endif
-X
-X/*
-X * COMMENT_INVISIBLE may be defined to allow "old-style" comment
-X * processing, whereby the comment becomes a zero-length token
-X * delimiter.  This permitted tokens to be concatenated in macro
-X * expansions.  This was removed from the Draft Ansi Standard.
-X */
-X#ifndef       COMMENT_INVISIBLE
-X#define       COMMENT_INVISIBLE       FALSE
-X#endif
-X
-X/*
-X * STRING_FORMAL may be defined to allow recognition of macro parameters
-X * anywhere in replacement strings.  This was removed from the Draft Ansi
-X * Standard and a limited recognition capability added.
-X */
-X#ifndef       STRING_FORMAL
-X#define       STRING_FORMAL           FALSE
-X#endif
-X
-X/*
-X * OK_DOLLAR enables use of $ as a valid "letter" in identifiers.
-X * This is a permitted extension to the Ansi Standard and is required
-X * for e.g., VMS, RSX-11M, etc.   It should be set FALSE if cpp is
-X * used to preprocess assembler source on Unix systems.  OLD_PREPROCESSOR
-X * sets OK_DOLLAR FALSE for that reason.
-X */
-X#ifndef       OK_DOLLAR
-X#define       OK_DOLLAR               TRUE
-X#endif
-X
-X/*
-X * OK_CONCAT enables (one possible implementation of) token concatenation.
-X * If cpp is used to preprocess Unix assembler source, this should be
-X * set FALSE as the concatenation character, #, is used by the assembler.
-X */
-X#ifndef       OK_CONCAT
-X#define       OK_CONCAT               TRUE
-X#endif
-X
-X/*
-X * OK_DATE may be enabled to predefine today's date as a string
-X * at the start of each compilation.  This is apparently not permitted
-X * by the Draft Ansi Standard.
-X */
-X#ifndef       OK_DATE
-X#define       OK_DATE         TRUE
-X#endif
-X\f
-X/*
-X * Some common definitions.
-X */
-X
-X#ifndef       DEBUG
-X#define       DEBUG                   FALSE
-X#endif
-X
-X/*
-X * The following definitions are used to allocate memory for
-X * work buffers.  In general, they should not be modified
-X * by implementors.
-X *
-X * PAR_MAC    The maximum number of #define parameters (31 per Standard)
-X *            Note: we need another one for strings.
-X * IDMAX      The longest identifier, 31 per Ansi Standard
-X * NBUFF      Input buffer size
-X * NWORK      Work buffer size -- the longest macro
-X *            must fit here after expansion.
-X * NEXP               The nesting depth of #if expressions
-X * NINCLUDE   The number of directories that may be specified
-X *            on a per-system basis, or by the -I option.
-X * BLK_NEST   The number of nested #if's permitted.
-X */
-X
-X#define       IDMAX                    31
-X#define       PAR_MAC            (31 + 1)
-X#define       NBUFF                  1024
-X#define       NWORK                  1024
-X#define       NEXP                    128
-X#define       NINCLUDE                  7
-X#define       NPARMWORK               (NWORK * 2)
-X#define       BLK_NEST                32
-X
-X/*
-X * Some special constants.  These may need to be changed if cpp
-X * is ported to a wierd machine.
-X *
-X * NOTE: if cpp is run on a non-ascii machine, ALERT and VT may
-X * need to be changed.  They are used to implement the proposed
-X * ANSI standard C control characters '\a' and '\v' only.
-X * DEL is used to tag macro tokens to prevent #define foo foo
-X * from looping.  Note that we don't try to prevent more elaborate
-X * #define loops from occurring.
-X */
-X
-X#ifndef       ALERT
-X#define       ALERT                   '\007'          /* '\a' is "Bell"       */
-X#endif
-X
-X#ifndef       VT
-X#define       VT                      '\013'          /* Vertical Tab CTRL/K  */
-X#endif
-X
-X
-X#ifndef       FILE_LOCAL
-X#ifdef        decus
-X#define       FILE_LOCAL              static
-X#else
-X#ifdef        vax11c
-X#define       FILE_LOCAL              static
-X#else
-X#define       FILE_LOCAL                              /* Others are global    */
-X#endif
-X#endif
-X#endif
-X
-END-of-cppdef.h
-echo x - cpp2.c
-sed 's/^X//' >cpp2.c << 'END-of-cpp2.c'
-X/*
-X *                            C P P 2 . C
-X *
-X *                       Process #control lines
-X *
-X * Edit history
-X * 13-Nov-84  MM      Split from cpp1.c
-X */
-X
-X#include      <stdio.h>
-X#include      <ctype.h>
-X#include      "cppdef.h"
-X#include      "cpp.h"
-X#if HOST == SYS_VMS
-X/*
-X * Include the rms stuff.  (We can't just include rms.h as it uses the
-X * VaxC-specific library include syntax that Decus CPP doesn't support.
-X * By including things by hand, we can CPP ourself.)
-X */
-X#include      <nam.h>
-X#include      <fab.h>
-X#include      <rab.h>
-X#include      <rmsdef.h>
-X#endif
-X
-X/*
-X * Generate (by hand-inspection) a set of unique values for each control
-X * operator.  Note that this is not guaranteed to work for non-Ascii
-X * machines.  CPP won't compile if there are hash conflicts.
-X */
-X
-X#define       L_assert        ('a' + ('s' << 1))
-X#define       L_define        ('d' + ('f' << 1))
-X#define       L_elif          ('e' + ('i' << 1))
-X#define       L_else          ('e' + ('s' << 1))
-X#define       L_endif         ('e' + ('d' << 1))
-X#define L_ident               ('i' + ('e' << 1))
-X#define       L_if            ('i' + (EOS << 1))
-X#define       L_ifdef         ('i' + ('d' << 1))
-X#define       L_ifndef        ('i' + ('n' << 1))
-X#define       L_include       ('i' + ('c' << 1))
-X#define       L_line          ('l' + ('n' << 1))
-X#define       L_nogood        (EOS + (EOS << 1))      /* To catch #i          */
-X#define       L_pragma        ('p' + ('a' << 1))
-X#define       L_sccs          ('s' + ('c' << 1))
-X#define L_undef               ('u' + ('d' << 1))
-X#if DEBUG
-X#define       L_debug         ('d' + ('b' << 1))      /* #debug               */
-X#define       L_nodebug       ('n' + ('d' << 1))      /* #nodebug             */
-X#endif
-X
-Xint
-Xcontrol(counter)
-Xint           counter;        /* Pending newline counter              */
-X/*
-X * Process #control lines.  Simple commands are processed inline,
-X * while complex commands have their own subroutines.
-X *
-X * The counter is used to force out a newline before #line, and
-X * #pragma commands.  This prevents these commands from ending up at
-X * the end of the previous line if cpp is invoked with the -C option.
-X */
-X{
-X      register int            c;
-X      register char           *tp;
-X      register int            hash;
-X      char                    *ep;
-X
-X      c = skipws();
-X      if (c == '\n' || c == EOF_CHAR)
-X          return (counter + 1);
-X      if (!isdigit(c))
-X          scanid(c);                  /* Get #word to token[]         */
-X      else {
-X          unget();                    /* Hack -- allow #123 as a      */
-X          strcpy(token, "line");      /* synonym for #line 123        */
-X      }
-X      hash = (token[1] == EOS) ? L_nogood : (token[0] + (token[2] << 1));
-X      switch (hash) {
-X      case L_assert:  tp = "assert";          break;
-X      case L_define:  tp = "define";          break;
-X      case L_elif:    tp = "elif";            break;
-X      case L_else:    tp = "else";            break;
-X      case L_endif:   tp = "endif";           break;
-X      case L_ident:   tp = "ident";           break;
-X      case L_if:      tp = "if";              break;
-X      case L_ifdef:   tp = "ifdef";           break;
-X      case L_ifndef:  tp = "ifndef";          break;
-X      case L_include: tp = "include";         break;
-X      case L_line:    tp = "line";            break;
-X      case L_pragma:  tp = "pragma";          break;
-X      case L_sccs:    tp = "sccs";            break;
-X      case L_undef:   tp = "undef";           break;
-X#if DEBUG
-X      case L_debug:   tp = "debug";           break;
-X      case L_nodebug: tp = "nodebug";         break;
-X#endif
-X      default:        hash = L_nogood;
-X      case L_nogood:  tp = "";                break;
-X      }
-X      if (!streq(tp, token))
-X          hash = L_nogood;
-X      /*
-X       * hash is set to a unique value corresponding to the
-X       * control keyword (or L_nogood if we think it's nonsense).
-X       */
-X      if (infile->fp == NULL)
-X          cwarn("Control line \"%s\" within macro expansion", token);
-X      if (!compiling) {                       /* Not compiling now    */
-X          switch (hash) {
-X          case L_if:                          /* These can't turn     */
-X          case L_ifdef:                       /*  compilation on, but */
-X          case L_ifndef:                      /*   we must nest #if's */
-X              if (++ifptr >= &ifstack[BLK_NEST])
-X                  goto if_nest_err;
-X              *ifptr = 0;                     /* !WAS_COMPILING       */
-X          case L_line:                        /* Many                 */
-X          /*
-X           * Are pragma's always processed?
-X           */
-X          case L_ident:
-X          case L_sccs:
-X          case L_pragma:                      /*  options             */
-X          case L_include:                     /*   are uninteresting  */
-X          case L_define:                      /*    if we             */
-X          case L_undef:                       /*     aren't           */
-X          case L_assert:                      /*      compiling.      */
-Xdump_line:    skipnl();                       /* Ignore rest of line  */
-X              return (counter + 1);
-X          }
-X      }
-X      /*
-X       * Make sure that #line and #pragma are output on a fresh line.
-X       */
-X      if (counter > 0 && (hash == L_line || hash == L_pragma)) {
-X          putchar('\n');
-X          counter--;
-X      }
-X      switch (hash) {
-X      case L_line:
-X          /*
-X           * Parse the line to update the line number and "progname"
-X           * field and line number for the next input line.
-X           * Set wrongline to force it out later.
-X           */
-X          c = skipws();
-X          workp = work;                       /* Save name in work    */
-X          while (c != '\n' && c != EOF_CHAR) {
-X              save(c);
-X              c = get();
-X          }
-X          unget();
-X          save(EOS);
-X          /*
-X           * Split #line argument into <line-number> and <name>
-X           * We subtract 1 as we want the number of the next line.
-X           */
-X          line = atoi(work) - 1;              /* Reset line number    */
-X          for (tp = work; isdigit(*tp) || type[*tp] == SPA; tp++)
-X              ;                               /* Skip over digits     */
-X          if (*tp != EOS) {                   /* Got a filename, so:  */
-X              if (*tp == '"' && (ep = strrchr(tp + 1, '"')) != NULL) {
-X                  tp++;                       /* Skip over left quote */
-X                  *ep = EOS;                  /* And ignore right one */
-X              }
-X              if (infile->progname != NULL)   /* Give up the old name */
-X                  free(infile->progname);     /* if it's allocated.   */
-X              infile->progname = savestring(tp);
-X          }
-X          wrongline = TRUE;                   /* Force output later   */
-X          break;
-X
-X      case L_include:
-X          doinclude();
-X          break;
-X
-X      case L_define:
-X          dodefine();
-X          break;
-X
-X      case L_undef:
-X          doundef();
-X          break;
-X
-X      case L_else:
-X          if (ifptr == &ifstack[0])
-X              goto nest_err;
-X          else if ((*ifptr & ELSE_SEEN) != 0)
-X              goto else_seen_err;
-X          *ifptr |= ELSE_SEEN;
-X          if ((*ifptr & WAS_COMPILING) != 0) {
-X              if (compiling || (*ifptr & TRUE_SEEN) != 0)
-X                  compiling = FALSE;
-X              else {
-X                  compiling = TRUE;
-X              }
-X          }
-X          break;
-X
-X      case L_elif:
-X          if (ifptr == &ifstack[0])
-X              goto nest_err;
-X          else if ((*ifptr & ELSE_SEEN) != 0) {
-Xelse_seen_err:        cerror("#%s may not follow #else", token);
-X              goto dump_line;
-X          }
-X          if ((*ifptr & (WAS_COMPILING | TRUE_SEEN)) != WAS_COMPILING) {
-X              compiling = FALSE;              /* Done compiling stuff */
-X              goto dump_line;                 /* Skip this clause     */
-X          }
-X          doif(L_if);
-X          break;
-X
-X      case L_if:
-X      case L_ifdef:
-X      case L_ifndef:
-X          if (++ifptr >= &ifstack[BLK_NEST])
-Xif_nest_err:  cfatal("Too many nested #%s statements", token);
-X          *ifptr = WAS_COMPILING;
-X          doif(hash);
-X          break;
-X
-X      case L_endif:
-X          if (ifptr == &ifstack[0]) {
-Xnest_err:     cerror("#%s must be in an #if", token);
-X              goto dump_line;
-X          }
-X          if (!compiling && (*ifptr & WAS_COMPILING) != 0)
-X              wrongline = TRUE;
-X          compiling = ((*ifptr & WAS_COMPILING) != 0);
-X          --ifptr;
-X          break;
-X
-X      case L_assert:
-X          if (eval() == 0)
-X              cerror("Preprocessor assertion failure", NULLST);
-X          break;
-X
-X      case L_ident:
-X      case L_sccs:
-X          goto dump_line;
-X          break;
-X
-X      case L_pragma:
-X          /*
-X           * #pragma is provided to pass "options" to later
-X           * passes of the compiler.  cpp doesn't have any yet.
-X           */
-X          printf("#pragma ");
-X          while ((c = get()) != '\n' && c != EOF_CHAR)
-X              cput(c);
-X          unget();
-X          break;
-X 
-X#if DEBUG
-X      case L_debug:
-X          if (debug == 0)
-X              dumpdef("debug set on");
-X          debug++;
-X          break;
-X
-X      case L_nodebug:
-X          debug--;
-X          break;
-X#endif
-X
-X      default:
-X          /*
-X           * Undefined #control keyword.
-X           * Note: the correct behavior may be to warn and
-X           * pass the line to a subsequent compiler pass.
-X           * This would allow #asm or similar extensions.
-X           */
-X          cerror("Illegal # command \"%s\"", token);
-X          break;
-X      }
-X      if (hash != L_include) {
-X#if OLD_PREPROCESSOR || !VERBOSE
-X          /*
-X           * Ignore the rest of the #control line so you can write
-X           *          #if     foo
-X           *          #endif  foo
-X           */
-X          goto dump_line;                     /* Take common exit     */
-X#else
-X          if (skipws() != '\n') {
-X              cwarn("Unexpected text in #control line ignored", NULLST);
-X              skipnl();
-X          }
-X#endif
-X      }
-X      return (counter + 1);
-X}
-X\f
-XFILE_LOCAL
-Xdoif(hash)
-Xint           hash;
-X/*
-X * Process an #if, #ifdef, or #ifndef.  The latter two are straightforward,
-X * while #if needs a subroutine of its own to evaluate the expression.
-X *
-X * doif() is called only if compiling is TRUE.  If false, compilation
-X * is always supressed, so we don't need to evaluate anything.  This
-X * supresses unnecessary warnings.
-X */
-X{
-X      register int            c;
-X      register int            found;
-X
-X      if ((c = skipws()) == '\n' || c == EOF_CHAR) {
-X          unget();
-X          goto badif;
-X      }
-X      if (hash == L_if) {
-X          unget();
-X          found = (eval() != 0);      /* Evaluate expr, != 0 is  TRUE */
-X          hash = L_ifdef;             /* #if is now like #ifdef       */
-X      }
-X      else {
-X          if (type[c] != LET)         /* Next non-blank isn't letter  */
-X              goto badif;             /* ... is an error              */
-X          found = (lookid(c) != NULL); /* Look for it in symbol table */
-X      }
-X      if (found == (hash == L_ifdef)) {
-X          compiling = TRUE;
-X          *ifptr |= TRUE_SEEN;
-X      }
-X      else {
-X          compiling = FALSE;
-X      }
-X      return;
-X
-Xbadif:        cerror("#if, #ifdef, or #ifndef without an argument", NULLST);
-X#if !OLD_PREPROCESSOR
-X      skipnl();                               /* Prevent an extra     */
-X      unget();                                /* Error message        */
-X#endif
-X      return;
-X}
-X\f
-XFILE_LOCAL
-Xdoinclude()
-X/*
-X * Process the #include control line.
-X * There are three variations:
-X *    #include "file"         search somewhere relative to the
-X *                            current source file, if not found,
-X *                            treat as #include <file>.
-X *    #include <file>         Search in an implementation-dependent
-X *                            list of places.
-X *    #include token          Expand the token, it must be one of
-X *                            "file" or <file>, process as such.
-X *
-X * Note: the November 12 draft forbids '>' in the #include <file> format.
-X * This restriction is unnecessary and not implemented.
-X */
-X{
-X      register int            c;
-X      register int            delim;
-X#if HOST == SYS_VMS
-X      char                    def_filename[NAM$C_MAXRSS + 1];
-X#endif
-X
-X      delim = macroid(skipws());
-X      if (delim != '<' && delim != '"')
-X          goto incerr;
-X      if (delim == '<')
-X          delim = '>';
-X      workp = work;
-X      instring = TRUE;                /* Accept all characters        */
-X      while ((c = get()) != '\n' && c != delim && c != EOF_CHAR)
-X          save(c);                    /* Put it away.                 */
-X      skipnl(); 
-X      /*
-X       * The draft is unclear if the following should be done.
-X       */
-X
-X      while (--workp >= work && (type[*workp] == SPA))
-X          ;                           /* Trim blanks from filename    */
-X
-X/*
-X *    if (*workp != delim)
-X *        goto incerr; 
-X */
-X      *(workp + 1) = EOS;                     /* Terminate filename   */
-X      instring = FALSE;
-X#if HOST == SYS_VMS
-X      /*
-X       * Assume the default .h filetype.
-X       */
-X      if (!vmsparse(work, ".H", def_filename)) {
-X          perror(work);               /* Oops.                        */
-X          goto incerr;
-X      }
-X      else if (openinclude(def_filename, (delim == '"')))
-X          return;
-X#else
-X      if (openinclude(work, (delim == '"')))
-X          return;
-X#endif
-X      /*
-X       * No sense continuing if #include file isn't there.
-X       */
-X      cfatal("Cannot open include file \"%s\"", work);
-X
-Xincerr:       cerror("#include syntax error", NULLST);
-X      return;
-X}
-X\f
-XFILE_LOCAL int
-Xopeninclude(filename, searchlocal)
-Xchar          *filename;              /* Input file name              */
-Xint           searchlocal;            /* TRUE if #include "file"      */
-X/*
-X * Actually open an include file.  This routine is only called from
-X * doinclude() above, but was written as a separate subroutine for
-X * programmer convenience.  It searches the list of directories
-X * and actually opens the file, linking it into the list of
-X * active files.  Returns TRUE if the file was opened, FALSE
-X * if openinclude() fails.  No error message is printed.
-X */
-X{
-X      register char           **incptr;
-X#if HOST == SYS_VMS
-X#if NWORK < (NAM$C_MAXRSS + 1)
-X    << error, NWORK isn't greater than NAM$C_MAXRSS >>
-X#endif
-X#endif
-X      char                    tmpname[NWORK]; /* Filename work area   */
-X
-X      if (searchlocal) {
-X          /*
-X           * Look in local directory first
-X           */
-X#if HOST == SYS_UNIX
-X          /*
-X           * Try to open filename relative to the directory of the current
-X           * source file (as opposed to the current directory). (ARF, SCK).
-X           */
-X          if (filename[0] != '/'
-X           && hasdirectory(infile->filename, tmpname))
-X              strcat(tmpname, filename);
-X          else {
-X              strcpy(tmpname, filename);
-X          }
-X#else
-X          if (!hasdirectory(filename, tmpname)
-X           && hasdirectory(infile->filename, tmpname))
-X              strcat(tmpname, filename);
-X          else {
-X              strcpy(tmpname, filename);
-X          }
-X#endif
-X          if (openfile(tmpname))
-X              return (TRUE);
-X      }
-X      /*
-X       * Look in any directories specified by -I command line
-X       * arguments, then in the builtin search list.
-X       */
-X      for (incptr = incdir; incptr < incend; incptr++) {
-X          if (strlen(*incptr) + strlen(filename) >= (NWORK - 1))
-X              cfatal("Filename work buffer overflow", NULLST);
-X          else {
-X#if HOST == SYS_UNIX
-X              if (filename[0] == '/')
-X                  strcpy(tmpname, filename);
-X              else {
-X                  sprintf(tmpname, "%s/%s", *incptr, filename);
-X              }
-X#else
-X              if (!hasdirectory(filename, tmpname))
-X                  sprintf(tmpname, "%s%s", *incptr, filename);
-X#endif
-X              if (openfile(tmpname))
-X                  return (TRUE);
-X          }
-X      }
-X      return (FALSE);
-X}
-X\f
-XFILE_LOCAL int
-Xhasdirectory(source, result)
-Xchar          *source;        /* Directory to examine                 */
-Xchar          *result;        /* Put directory stuff here             */
-X/*
-X * If a device or directory is found in the source filename string, the
-X * node/device/directory part of the string is copied to result and
-X * hasdirectory returns TRUE.  Else, nothing is copied and it returns FALSE.
-X */
-X{
-X#if HOST == SYS_UNIX
-X      register char           *tp;
-X
-X      if ((tp = strrchr(source, '/')) == NULL)
-X          return (FALSE);
-X      else {
-X          strncpy(result, source, tp - source + 1);
-X          result[tp - source + 1] = EOS;
-X          return (TRUE);
-X      }
-X#else
-X#if HOST == SYS_VMS
-X      if (vmsparse(source, NULLST, result)
-X       && result[0] != EOS)
-X          return (TRUE);
-X      else {
-X          return (FALSE);
-X      }
-X#else
-X      /*
-X       * Random DEC operating system (RSX, RT11, RSTS/E)
-X       */
-X      register char           *tp;
-X
-X      if ((tp = strrchr(source, ']')) == NULL
-X       && (tp = strrchr(source, ':')) == NULL)
-X          return (FALSE);
-X      else {
-X          strncpy(result, source, tp - source + 1);
-X          result[tp - source + 1] = EOS;
-X          return (TRUE);
-X      }
-X#endif
-X#endif
-X}
-X\f
-X#if HOST == SYS_VMS
-X
-X/*
-X * EXP_DEV is set if a device was specified, EXP_DIR if a directory
-X * is specified.  (Both set indicate a file-logical, but EXP_DEV
-X * would be set by itself if you are reading, say, SYS$INPUT:)
-X */
-X#define DEVDIR (NAM$M_EXP_DEV | NAM$M_EXP_DIR)
-X
-XFILE_LOCAL int
-Xvmsparse(source, defstring, result)
-Xchar          *source;
-Xchar          *defstring;     /* non-NULL -> default string.          */
-Xchar          *result;        /* Size is at least NAM$C_MAXRSS + 1    */
-X/*
-X * Parse the source string, applying the default (properly, using
-X * the system parse routine), storing it in result.
-X * TRUE if it parsed, FALSE on error.
-X *
-X * If defstring is NULL, there are no defaults and result gets
-X * (just) the node::[directory] part of the string (possibly "")
-X */
-X{
-X      struct FAB      fab = cc$rms_fab;       /* File access block    */
-X      struct NAM      nam = cc$rms_nam;       /* File name block      */
-X      char            fullname[NAM$C_MAXRSS + 1];
-X      register char   *rp;                    /* Result pointer       */
-X
-X      fab.fab$l_nam = &nam;                   /* fab -> nam           */
-X      fab.fab$l_fna = source;                 /* Source filename      */
-X      fab.fab$b_fns = strlen(source);         /* Size of source       */
-X      fab.fab$l_dna = defstring;              /* Default string       */
-X      if (defstring != NULLST)
-X          fab.fab$b_dns = strlen(defstring);  /* Size of default      */
-X      nam.nam$l_esa = fullname;               /* Expanded filename    */
-X      nam.nam$b_ess = NAM$C_MAXRSS;           /* Expanded name size   */
-X      if (sys$parse(&fab) == RMS$_NORMAL) {   /* Parse away           */
-X          fullname[nam.nam$b_esl] = EOS;      /* Terminate string     */
-X          result[0] = EOS;                    /* Just in case         */
-X          rp = &result[0];
-X          /*
-X           * Remove stuff added implicitly, accepting node names and
-X           * dev:[directory] strings (but not process-permanent files).
-X           */
-X          if ((nam.nam$l_fnb & NAM$M_PPF) == 0) {
-X              if ((nam.nam$l_fnb & NAM$M_NODE) != 0) {
-X                  strncpy(result, nam.nam$l_node, nam.nam$b_node);
-X                  rp += nam.nam$b_node;
-X                  *rp = EOS;
-X              }
-X              if ((nam.nam$l_fnb & DEVDIR) == DEVDIR) {
-X                  strncpy(rp, nam.nam$l_dev, nam.nam$b_dev + nam.nam$b_dir);
-X                  rp += nam.nam$b_dev + nam.nam$b_dir;
-X                  *rp = EOS;
-X              }
-X          }
-X          if (defstring != NULLST) {
-X              strncpy(rp, nam.nam$l_name, nam.nam$b_name + nam.nam$b_type);
-X              rp += nam.nam$b_name + nam.nam$b_type;
-X              *rp = EOS;
-X              if ((nam.nam$l_fnb & NAM$M_EXP_VER) != 0) {
-X                  strncpy(rp, nam.nam$l_ver, nam.nam$b_ver);
-X                  rp[nam.nam$b_ver] = EOS;
-X              }
-X          }
-X          return (TRUE);
-X      }
-X      return (FALSE);
-X}
-X#endif
-X
-END-of-cpp2.c
-exit
diff --git a/sys/unix/cpp2.shr b/sys/unix/cpp2.shr
deleted file mode 100644 (file)
index ccadfc0..0000000
+++ /dev/null
@@ -1,1763 +0,0 @@
-# This is a shell archive.  Save it in a file, remove anything before
-# this line, and then unpack it by entering "sh file".  Note, it may
-# create directories; files and directories will be owned by you and
-# have default permissions.
-#
-# This archive contains:
-#
-#      cpp1.c
-#      cpp3.c
-#      cpp4.c
-#
-echo x - cpp1.c
-sed 's/^X//' >cpp1.c << 'END-of-cpp1.c'
-X/*
-X * CPP main program.
-X *
-X * Edit history
-X * 21-May-84  MM      "Field test" release
-X * 23-May-84  MM      Some minor hacks.
-X * 30-May-84  ARF     Didn't get enough memory for __DATE__
-X *                    Added code to read stdin if no input
-X *                    files are provided.
-X * 29-Jun-84  MM      Added ARF's suggestions, Unixifying cpp.
-X * 11-Jul-84  MM      "Official" first release (that's what I thought!)
-X * 22-Jul-84  MM/ARF/SCK Fixed line number bugs, added cpp recognition
-X *                    of #line, fixed problems with #include.
-X * 23-Jul-84  MM      More (minor) include hacking, some documentation.
-X *                    Also, redid cpp's #include files
-X * 25-Jul-84  MM      #line filename isn't used for #include searchlist
-X *                    #line format is <number> <optional name>
-X * 25-Jul-84  ARF/MM  Various bugs, mostly serious.  Removed homemade doprint
-X * 01-Aug-84  MM      Fixed recursion bug, remove extra newlines and
-X *                    leading whitespace from cpp output.
-X * 02-Aug-84  MM      Hacked (i.e. optimized) out blank lines and unneeded
-X *                    whitespace in general.  Cleaned up unget()'s.
-X * 03-Aug-84  Keie    Several bug fixes from Ed Keizer, Vrije Universitet.
-X *                    -- corrected arg. count in -D and pre-defined
-X *                    macros.  Also, allow \n inside macro actual parameter
-X *                    lists.
-X * 06-Aug-84  MM      If debugging, dump the preset vector at startup.
-X * 12-Aug-84  MM/SCK  Some small changes from Sam Kendall
-X * 15-Aug-84  Keie/MM cerror, cwarn, etc. take a single string arg.
-X *                    cierror, etc. take a single int. arg.
-X *                    changed LINE_PREFIX slightly so it can be
-X *                    changed in the makefile.
-X * 31-Aug-84  MM      USENET net.sources release.
-X *  7-Sep-84  SCH/ado Lint complaints
-X * 10-Sep-84  Keie    Char's can't be signed in some implementations
-X * 11-Sep-84  ado     Added -C flag, pathological line number fix
-X * 13-Sep-84  ado     Added -E flag (does nothing) and "-" file for stdin.
-X * 14-Sep-84  MM      Allow # 123 as a synonym for #line 123
-X * 19-Sep-84  MM      scanid always reads to token, make sure #line is
-X *                    written to a new line, even if -C switch given.
-X *                    Also, cpp - - reads stdin, writes stdout.
-X * 03-Oct-84  ado/MM  Several changes to line counting and keepcomments
-X *                    stuff.  Also a rewritten control() hasher -- much
-X *                    simpler and no less "perfect". Note also changes
-X *                    in cpp3.c to fix numeric scanning.
-X * 04-Oct-84  MM      Added recognition of macro formal parameters if
-X *                    they are the only thing in a string, per the
-X *                    draft standard.
-X * 08-Oct-84  MM      One more attack on scannumber
-X * 15-Oct-84  MM/ado  Added -N to disable predefined symbols.  Fixed
-X *                    linecount if COMMENT_INVISIBLE enabled.
-X * 22-Oct-84  MM      Don't evaluate the #if/#ifdef argument if
-X *                    compilation is supressed.  This prevents
-X *                    unnecessary error messages in sequences such as
-X *                        #ifdef FOO          -- undefined
-X *                        #if FOO == 10       -- shouldn't print warning
-X * 25-Oct-84  MM      Fixed bug in false ifdef supression.  On vms,
-X *                    #include <foo> should open foo.h -- this duplicates
-X *                    the behavior of Vax-C
-X * 31-Oct-84  ado/MM  Parametized $ in indentifiers.  Added a better
-X *                    token concatenator and took out the trial
-X *                    concatenation code.  Also improved #ifdef code
-X *                    and cleaned up the macro recursion tester.
-X *  2-Nov-84  MM/ado  Some bug fixes in token concatenation, also
-X *                    a variety of minor (uninteresting) hacks.
-X *  6-Nov-84  MM      Happy Birthday.  Broke into 4 files and added
-X *                    #if sizeof (basic_types)
-X *  9-Nov-84  MM      Added -S* for pointer type sizes
-X * 13-Nov-84  MM      Split cpp1.c, added vms defaulting
-X * 23-Nov-84  MM/ado  -E supresses error exit, added CPP_INCLUDE,
-X *                    fixed strncpy bug.
-X *  3-Dec-84  ado/MM  Added OLD_PREPROCESSOR
-X *  7-Dec-84  MM      Stuff in Nov 12 Draft Standard
-X * 17-Dec-84  george  Fixed problems with recursive macros
-X * 17-Dec-84  MM      Yet another attack on #if's (f/t)level removed.
-X * 07-Jan-85  ado     Init defines before doing command line options
-X *                    so -Uunix works.
-X */
-X
-X/*)BUILD
-X      $(PROGRAM)      = cpp
-X      $(FILES)        = { cpp1 cpp2 cpp3 cpp4 cpp5 cpp6 }
-X      $(INCLUDE)      = { cppdef.h cpp.h }
-X      $(STACK)        = 2000
-X      $(TKBOPTIONS)   = {
-X              STACK   = 2000
-X      }
-X*/
-X
-X#ifdef        DOCUMENTATION
-X
-Xtitle cpp             C Pre-Processor
-Xindex                 C pre-processor
-X
-Xsynopsis
-X      .s.nf
-X      cpp [-options] [infile [outfile]]
-X      .s.f
-Xdescription
-X
-X      CPP reads a C source file, expands macros and include
-X      files, and writes an input file for the C compiler.
-X      If no file arguments are given, CPP reads from stdin
-X      and writes to stdout.  If one file argument is given,
-X      it will define the input file, while two file arguments
-X      define both input and output files.  The file name "-"
-X      is a synonym for stdin or stdout as appropriate.
-X
-X      The following options are supported.  Options may
-X      be given in either case.
-X      .lm +16
-X      .p -16
-X      -C              If set, source-file comments are written
-X      to the output file.  This allows the output of CPP to be
-X      used as the input to a program, such as lint, that expects
-X      commands embedded in specially-formatted comments.
-X      .p -16
-X      -Dname=value    Define the name as if the programmer wrote
-X
-X          #define name value
-X
-X      at the start of the first file.  If "=value" is not
-X      given, a value of "1" will be used.
-X
-X      On non-unix systems, all alphabetic text will be forced
-X      to upper-case.
-X      .p -16
-X      -E              Always return "success" to the operating
-X      system, even if errors were detected.  Note that some fatal
-X      errors, such as a missing #include file, will terminate
-X      CPP, returning "failure" even if the -E option is given.
-X      .p -16
-X      -Idirectory     Add this directory to the list of
-X      directories searched for #include "..." and #include <...>
-X      commands.  Note that there is no space between the
-X      "-I" and the directory string.  More than one -I command
-X      is permitted.  On non-Unix systems "directory" is forced
-X      to upper-case.
-X      .p -16
-X      -N              CPP normally predefines some symbols defining
-X      the target computer and operating system.  If -N is specified,
-X      no symbols will be predefined.  If -N -N is specified, the
-X      "always present" symbols, __LINE__, __FILE__, and __DATE__
-X      are not defined.
-X      .p -16
-X      -Stext          CPP normally assumes that the size of
-X      the target computer's basic variable types is the same as the size
-X      of these types of the host computer.  (This can be overridden
-X      when CPP is compiled, however.)  The -S option allows dynamic
-X      respecification of these values.  "text" is a string of
-X      numbers, separated by commas, that specifies correct sizes.
-X      The sizes must be specified in the exact order:
-X
-X          char short int long float double
-X
-X      If you specify the option as "-S*text", pointers to these
-X      types will be specified.  -S* takes one additional argument
-X      for pointer to function (e.g. int (*)())
-X
-X      For example, to specify sizes appropriate for a PDP-11,
-X      you would write:
-X
-X             c s i l f d func
-X           -S1,2,2,2,4,8,
-X          -S*2,2,2,2,2,2,2
-X
-X      Note that all values must be specified.
-X      .p -16
-X      -Uname          Undefine the name as if
-X
-X          #undef name
-X
-X      were given.  On non-Unix systems, "name" will be forced to
-X      upper-case.
-X      .p -16
-X      -Xnumber        Enable debugging code.  If no value is
-X      given, a value of 1 will be used.  (For maintenence of
-X      CPP only.)
-X      .s.lm -16
-X
-XPre-Defined Variables
-X
-X      When CPP begins processing, the following variables will
-X      have been defined (unless the -N option is specified):
-X      .s
-X      Target computer (as appropriate):
-X      .s
-X          pdp11, vax, M68000 m68000 m68k
-X      .s
-X      Target operating system (as appropriate):
-X      .s
-X          rsx, rt11, vms, unix
-X      .s
-X      Target compiler (as appropriate):
-X      .s
-X          decus, vax11c
-X      .s
-X      The implementor may add definitions to this list.
-X      The default definitions match the definition of the
-X      host computer, operating system, and C compiler.
-X      .s
-X      The following are always available unless undefined (or
-X      -N was specified twice):
-X      .lm +16
-X      .p -12
-X      __FILE__        The input (or #include) file being compiled
-X      (as a quoted string).
-X      .p -12
-X      __LINE__        The line number being compiled.
-X      .p -12
-X      __DATE__        The date and time of compilation as
-X      a Unix ctime quoted string (the trailing newline is removed).
-X      Thus,
-X      .s
-X          printf("Bug at line %s,", __LINE__);
-X          printf(" source file %s", __FILE__);
-X          printf(" compiled on %s", __DATE__);
-X      .s.lm -16
-X
-XDraft Proposed Ansi Standard Considerations
-X
-X      The current version of the Draft Proposed Standard
-X      explicitly states that "readers are requested not to specify
-X      or claim conformance to this draft."  Readers and users
-X      of Decus CPP should not assume that Decus CPP conforms
-X      to the standard, or that it will conform to the actual
-X      C Language Standard.
-X
-X      When CPP is itself compiled, many features of the Draft
-X      Proposed Standard that are incompatible with existing
-X      preprocessors may be disabled.  See the comments in CPP's
-X      source for details.
-X
-X      The latest version of the Draft Proposed Standard (as reflected
-X      in Decus CPP) is dated November 12, 1984.
-X
-X      Comments are removed from the input text.  The comment
-X      is replaced by a single space character.  The -C option
-X      preserves comments, writing them to the output file.
-X
-X      The '$' character is considered to be a letter.  This is
-X      a permitted extension.
-X
-X      The following new features of C are processed by CPP:
-X      .s.comment Note: significant spaces, not tabs, .br quotes #if, #elif
-X      .br;####_#elif expression    (_#else _#if)
-X      .br;####'_\xNNN'             (Hexadecimal constant)
-X      .br;####'_\a'                (Ascii BELL)
-X      .br;####'_\v'                (Ascii Vertical Tab)
-X      .br;####_#if defined NAME    1 if defined, 0 if not
-X      .br;####_#if defined (NAME)  1 if defined, 0 if not  
-X      .br;####_#if sizeof (basic type)
-X      .br;####unary +
-X      .br;####123U, 123LU          Unsigned ints and longs.
-X      .br;####12.3L                Long double numbers
-X      .br;####token_#token         Token concatenation
-X      .br;####_#include token      Expands to filename
-X
-X      The Draft Proposed Standard has extended C, adding a constant
-X      string concatenation operator, where
-X
-X          "foo" "bar"
-X
-X      is regarded as the single string "foobar".  (This does not
-X      affect CPP's processing but does permit a limited form of
-X      macro argument substitution into strings as will be discussed.)
-X
-X      The Standard Committee plans to add token concatenation
-X      to #define command lines.  One suggested implementation
-X      is as follows:  the sequence "Token1#Token2" is treated
-X      as if the programmer wrote "Token1Token2".  This could
-X      be used as follows:
-X
-X          #line 123
-X          #define ATLINE foo#__LINE__
-X
-X      ATLINE would be defined as foo123.
-X
-X      Note that "Token2" must either have the format of an
-X      identifier or be a string of digits.  Thus, the string
-X
-X          #define ATLINE foo#1x3
-X
-X      generates two tokens: "foo1" and "x3".
-X
-X      If the tokens T1 and T2 are concatenated into T3,
-X      this implementation operates as follows:
-X
-X        1. Expand T1 if it is a macro.
-X        2. Expand T2 if it is a macro.
-X        3. Join the tokens, forming T3.
-X        4. Expand T3 if it is a macro.
-X
-X      A macro formal parameter will be substituted into a string
-X      or character constant if it is the only component of that
-X      constant:
-X
-X          #define VECSIZE 123
-X          #define vprint(name, size) \
-X            printf("name" "[" "size" "] = {\n")
-X            ... vprint(vector, VECSIZE);
-X
-X      expands (effectively) to
-X
-X            vprint("vector[123] = {\n");
-X
-X      Note that this will be useful if your C compiler supports
-X      the new string concatenation operation noted above.
-X      As implemented here, if you write
-X
-X          #define string(arg) "arg"
-X            ... string("foo") ...
-X
-X      This implementation generates "foo", rather than the strictly
-X      correct ""foo"" (which will probably generate an error message).
-X      This is, strictly speaking, an error in CPP and may be removed
-X      from future releases.
-X
-Xerror messages
-X
-X      Many.  CPP prints warning or error messages if you try to
-X      use multiple-byte character constants (non-transportable)
-X      if you #undef a symbol that was not defined, or if your
-X      program has potentially nested comments.
-X
-Xauthor
-X
-X      Martin Minow
-X
-Xbugs
-X
-X      The #if expression processor uses signed integers only.
-X      I.e, #if 0xFFFFu < 0 may be TRUE.
-X
-X#endif
-X\f
-X#include      <stdio.h>
-X#include      <ctype.h>
-X#include      "cppdef.h"
-X#include      "cpp.h"
-X
-X/*
-X * Commonly used global variables:
-X * line               is the current input line number.
-X * wrongline  is set in many places when the actual output
-X *            line is out of sync with the numbering, e.g,
-X *            when expanding a macro with an embedded newline.
-X *
-X * token      holds the last identifier scanned (which might
-X *            be a candidate for macro expansion).
-X * errors     is the running cpp error counter.
-X * infile     is the head of a linked list of input files (extended by
-X *            #include and macros being expanded).  infile always points
-X *            to the current file/macro.  infile->parent to the includer,
-X *            etc.  infile->fd is NULL if this input stream is a macro.
-X */
-Xint           line;                   /* Current line number          */
-Xint           wrongline;              /* Force #line to compiler      */
-Xchar          token[IDMAX + 1];       /* Current input token          */
-Xint           errors;                 /* cpp error counter            */
-XFILEINFO      *infile = NULL;         /* Current input file           */
-X#if DEBUG
-Xint           debug;                  /* TRUE if debugging now        */
-X#endif
-X/*
-X * This counter is incremented when a macro expansion is initiated.
-X * If it exceeds a built-in value, the expansion stops -- this tests
-X * for a runaway condition:
-X *    #define X Y
-X *    #define Y X
-X *    X
-X * This can be disabled by falsifying rec_recover.  (Nothing does this
-X * currently: it is a hook for an eventual invocation flag.)
-X */
-Xint           recursion;              /* Infinite recursion counter   */
-Xint           rec_recover = TRUE;     /* Unwind recursive macros      */
-X
-X/*
-X * instring is set TRUE when a string is scanned.  It modifies the
-X * behavior of the "get next character" routine, causing all characters
-X * to be passed to the caller (except <DEF_MAGIC>).  Note especially that
-X * comments and \<newline> are not removed from the source.  (This
-X * prevents cpp output lines from being arbitrarily long).
-X *
-X * inmacro is set by #define -- it absorbs comments and converts
-X * form-feed and vertical-tab to space, but returns \<newline>
-X * to the caller.  Strictly speaking, this is a bug as \<newline>
-X * shouldn't delimit tokens, but we'll worry about that some other
-X * time -- it is more important to prevent infinitly long output lines.
-X *
-X * instring and inmarcor are parameters to the get() routine which
-X * were made global for speed.
-X */
-Xint           instring = FALSE;       /* TRUE if scanning string      */
-Xint           inmacro = FALSE;        /* TRUE if #defining a macro    */
-X
-X/*
-X * work[] and workp are used to store one piece of text in a temporay
-X * buffer.  To initialize storage, set workp = work.  To store one
-X * character, call save(c);  (This will fatally exit if there isn't
-X * room.)  To terminate the string, call save(EOS).  Note that
-X * the work buffer is used by several subroutines -- be sure your
-X * data won't be overwritten.  The extra byte in the allocation is
-X * needed for string formal replacement.
-X */
-Xchar          work[NWORK + 1];        /* Work buffer                  */
-Xchar          *workp;                 /* Work buffer pointer          */
-X
-X/*
-X * keepcomments is set TRUE by the -C option.  If TRUE, comments
-X * are written directly to the output stream.  This is needed if
-X * the output from cpp is to be passed to lint (which uses commands
-X * embedded in comments).  cflag contains the permanent state of the
-X * -C flag.  keepcomments is always falsified when processing #control
-X * commands and when compilation is supressed by a false #if
-X *
-X * If eflag is set, CPP returns "success" even if non-fatal errors
-X * were detected.
-X *
-X * If nflag is non-zero, no symbols are predefined except __LINE__.
-X * __FILE__, and __DATE__.  If nflag > 1, absolutely no symbols
-X * are predefined.
-X */
-Xint           keepcomments = FALSE;   /* Write out comments flag      */
-Xint           cflag = FALSE;          /* -C option (keep comments)    */
-Xint           eflag = FALSE;          /* -E option (never fail)       */
-Xint           nflag = 0;              /* -N option (no predefines)    */
-X
-X/*
-X * ifstack[] holds information about nested #if's.  It is always
-X * accessed via *ifptr.  The information is as follows:
-X *    WAS_COMPILING   state of compiling flag at outer level.
-X *    ELSE_SEEN       set TRUE when #else seen to prevent 2nd #else.
-X *    TRUE_SEEN       set TRUE when #if or #elif succeeds
-X * ifstack[0] holds the compiling flag.  It is TRUE if compilation
-X * is currently enabled.  Note that this must be initialized TRUE.
-X */
-Xchar          ifstack[BLK_NEST] = { TRUE };   /* #if information      */
-Xchar          *ifptr = ifstack;               /* -> current ifstack[] */
-X
-X/*
-X * incdir[] stores the -i directories (and the system-specific
-X * #include <...> directories.
-X */
-Xchar  *incdir[NINCLUDE];              /* -i directories               */
-Xchar  **incend = incdir;              /* -> free space in incdir[]    */
-X
-X/*
-X * This is the table used to predefine target machine and operating
-X * system designators.  It may need hacking for specific circumstances.
-X * Note: it is not clear that this is part of the Ansi Standard.
-X * The -N option supresses preset definitions.
-X */
-Xchar  *preset[] = {                   /* names defined at cpp start   */
-X#ifdef        MACHINE
-X      MACHINE,
-X#endif
-X#ifdef        SYSTEM
-X      SYSTEM,
-X#endif
-X#ifdef        COMPILER
-X      COMPILER,
-X#endif
-X#if   DEBUG
-X      "decus_cpp",                    /* Ourselves!                   */
-X#endif
-X      NULL                            /* Must be last                 */
-X};
-X
-X/*
-X * The value of these predefined symbols must be recomputed whenever
-X * they are evaluated.  The order must not be changed.
-X */
-Xchar  *magic[] = {                    /* Note: order is important     */
-X      "__LINE__",
-X      "__FILE__",
-X      NULL                            /* Must be last                 */
-X};
-X\f
-Xmain(argc, argv)
-Xint           argc;
-Xchar          *argv[];
-X{
-X      register int    i;
-X
-X#if HOST == SYS_VMS
-X      argc = getredirection(argc, argv);      /* vms >file and <file  */
-X#endif
-X      initdefines();                          /* O.S. specific def's  */
-X      i = dooptions(argc, argv);              /* Command line -flags  */
-X      switch (i) {
-X      case 3:
-X          /*
-X           * Get output file, "-" means use stdout.
-X           */
-X          if (!streq(argv[2], "-")) {
-X#if HOST == SYS_VMS
-X              /*
-X               * On vms, reopen stdout with "vanilla rms" attributes.
-X               */
-X              if ((i = creat(argv[2], 0, "rat=cr", "rfm=var")) == -1
-X               || dup2(i, fileno(stdout)) == -1) {
-X#else
-X              if (freopen(argv[2], "w", stdout) == NULL) {
-X#endif
-X                  perror(argv[2]);
-X                  cerror("Can't open output file \"%s\"", argv[2]);
-X                  exit(IO_ERROR);
-X              }
-X          }                           /* Continue by opening input    */
-X      case 2:                         /* One file -> stdin            */
-X          /*
-X           * Open input file, "-" means use stdin.
-X           */
-X          if (!streq(argv[1], "-")) {
-X              if (freopen(argv[1], "r", stdin) == NULL) {
-X                  perror(argv[1]);
-X                  cerror("Can't open input file \"%s\"", argv[1]);
-X                  exit(IO_ERROR);
-X              }
-X              strcpy(work, argv[1]);  /* Remember input filename      */
-X              break;
-X          }                           /* Else, just get stdin         */
-X      case 0:                         /* No args?                     */
-X      case 1:                         /* No files, stdin -> stdout    */
-X#if HOST == SYS_UNIX
-X          work[0] = EOS;              /* Unix can't find stdin name   */
-X#else
-X          fgetname(stdin, work);      /* Vax-11C, Decus C know name   */
-X#endif
-X          break;
-X
-X      default:
-X          exit(IO_ERROR);             /* Can't happen                 */
-X      }
-X      setincdirs();                   /* Setup -I include directories */
-X      addfile(stdin, work);           /* "open" main input file       */
-X#if DEBUG
-X      if (debug > 0)
-X          dumpdef("preset #define symbols");
-X#endif
-X      cppmain();                      /* Process main file            */
-X      if ((i = (ifptr - &ifstack[0])) != 0) {
-X#if OLD_PREPROCESSOR
-X          ciwarn("Inside #ifdef block at end of input, depth = %d", i);
-X#else
-X          cierror("Inside #ifdef block at end of input, depth = %d", i);
-X#endif
-X      }
-X      fclose(stdout);
-X      if (errors > 0) {
-X          fprintf(stderr, (errors == 1)
-X              ? "%d error in preprocessor\n"
-X              : "%d errors in preprocessor\n", errors);
-X          if (!eflag)
-X              exit(IO_ERROR);
-X      }
-X      exit(IO_NORMAL);                /* No errors or -E option set   */
-X}
-X\f
-XFILE_LOCAL
-Xcppmain()
-X/*
-X * Main process for cpp -- copies tokens from the current input
-X * stream (main file, include file, or a macro) to the output
-X * file.
-X */
-X{
-X      register int            c;              /* Current character    */
-X      register int            counter;        /* newlines and spaces  */
-X      extern int              output();       /* Output one character */
-X
-X      /*
-X       * Explicitly output a #line at the start of cpp output so
-X       * that lint (etc.) knows the name of the original source
-X       * file.  If we don't do this explicitly, we may get
-X       * the name of the first #include file instead.
-X       */
-X      sharp();
-X      /*
-X       * This loop is started "from the top" at the beginning of each line
-X       * wrongline is set TRUE in many places if it is necessary to write
-X       * a #line record.  (But we don't write them when expanding macros.)
-X       *
-X       * The counter variable has two different uses:  at
-X       * the start of a line, it counts the number of blank lines that
-X       * have been skipped over.  These are then either output via
-X       * #line records or by outputting explicit blank lines.
-X       * When expanding tokens within a line, the counter remembers
-X       * whether a blank/tab has been output.  These are dropped
-X       * at the end of the line, and replaced by a single blank
-X       * within lines.
-X       */
-X      for (;;) {
-X          counter = 0;                        /* Count empty lines    */
-X          for (;;) {                          /* For each line, ...   */
-X              while (type[(c = get())] == SPA) /* Skip leading blanks */
-X                  ;                           /* in this line.        */
-X              if (c == '\n')                  /* If line's all blank, */
-X                  ++counter;                  /* Do nothing now       */
-X              else if (c == '#') {            /* Is 1st non-space '#' */
-X                  keepcomments = FALSE;       /* Don't pass comments  */
-X                  counter = control(counter); /* Yes, do a #command   */
-X                  keepcomments = (cflag && compiling);
-X              }
-X              else if (c == EOF_CHAR)         /* At end of file?      */
-X                  break;
-X              else if (!compiling) {          /* #ifdef false?        */
-X                  skipnl();                   /* Skip to newline      */
-X                  counter++;                  /* Count it, too.       */
-X              }
-X              else {
-X                  break;                      /* Actual token         */
-X              }
-X          }
-X          if (c == EOF_CHAR)                  /* Exit process at      */
-X              break;                          /* End of file          */
-X          /*
-X           * If the loop didn't terminate because of end of file, we
-X           * know there is a token to compile.  First, clean up after
-X           * absorbing newlines.  counter has the number we skipped.
-X           */
-X          if ((wrongline && infile->fp != NULL) || counter > 4)
-X              sharp();                        /* Output # line number */
-X          else {                              /* If just a few, stuff */
-X              while (--counter >= 0)          /* them out ourselves   */
-X                  putchar('\n');
-X          }
-X          /*
-X           * Process each token on this line.
-X           */
-X          unget();                            /* Reread the char.     */
-X          for (;;) {                          /* For the whole line,  */
-X              do {                            /* Token concat. loop   */
-X                  for (counter = 0; (type[(c = get())] == SPA);) {
-X#if COMMENT_INVISIBLE
-X                      if (c != COM_SEP)
-X                          counter++;
-X#else
-X                      counter++;              /* Skip over blanks     */
-X#endif
-X                  }
-X                  if (c == EOF_CHAR || c == '\n')
-X                      goto end_line;          /* Exit line loop       */
-X                  else if (counter > 0)       /* If we got any spaces */
-X                      putchar(' ');           /* Output one space     */
-X                  c = macroid(c);             /* Grab the token       */
-X              } while (type[c] == LET && catenate());
-X              if (c == EOF_CHAR || c == '\n') /* From macro exp error */
-X                  goto end_line;              /* Exit line loop       */
-X              switch (type[c]) {
-X              case LET:
-X                  fputs(token, stdout);       /* Quite ordinary token */
-X                  break;
-X
-X
-X              case DIG:                       /* Output a number      */
-X              case DOT:                       /* Dot may begin floats */
-X                  scannumber(c, output);
-X                  break;
-X
-X              case QUO:                       /* char or string const */
-X                  scanstring(c, output);      /* Copy it to output    */
-X                  break;
-X
-X              default:                        /* Some other character */
-X                  cput(c);                    /* Just output it       */
-X                  break;
-X              }                               /* Switch ends          */
-X          }                                   /* Line for loop        */
-Xend_line:   if (c == '\n') {                  /* Compiling at EOL?    */
-X              putchar('\n');                  /* Output newline, if   */
-X              if (infile->fp == NULL)         /* Expanding a macro,   */
-X                  wrongline = TRUE;           /* Output # line later  */
-X          }
-X      }                                       /* Continue until EOF   */
-X}
-X\f
-Xoutput(c)
-Xint           c;
-X/*
-X * Output one character to stdout -- output() is passed as an
-X * argument to scanstring()
-X */
-X{
-X#if COMMENT_INVISIBLE
-X      if (c != TOK_SEP && c != COM_SEP)
-X#else
-X      if (c != TOK_SEP)
-X#endif
-X          putchar(c);
-X}
-X
-Xstatic char   *sharpfilename = NULL;
-X
-XFILE_LOCAL
-Xsharp()
-X/*
-X * Output a line number line.
-X */
-X{
-X      register char           *name;
-X
-X      if (keepcomments)                       /* Make sure # comes on */
-X          putchar('\n');                      /* a fresh, new line.   */
-X      printf("#%s %d", LINE_PREFIX, line);
-X      if (infile->fp != NULL) {
-X          name = (infile->progname != NULL)
-X              ? infile->progname : infile->filename;
-X          if (sharpfilename == NULL
-X           || sharpfilename != NULL && !streq(name, sharpfilename)) {
-X              if (sharpfilename != NULL)
-X                  free(sharpfilename);
-X              sharpfilename = savestring(name);
-X              printf(" \"%s\"", name);
-X           }
-X      }
-X      putchar('\n');
-X      wrongline = FALSE;
-X}
-END-of-cpp1.c
-echo x - cpp3.c
-sed 's/^X//' >cpp3.c << 'END-of-cpp3.c'
-X/*
-X *                            C P P 3 . C
-X *
-X *                File open and command line options
-X *
-X * Edit history
-X * 13-Nov-84  MM      Split from cpp1.c
-X */
-X
-X#include      <stdio.h>
-X#include      <ctype.h>
-X#include      "cppdef.h"
-X#include      "cpp.h"
-X#if DEBUG && (HOST == SYS_VMS || HOST == SYS_UNIX)
-X#include      <signal.h>
-Xextern int    abort();                /* For debugging                */
-X#endif
-X
-Xint
-Xopenfile(filename)
-Xchar          *filename;
-X/*
-X * Open a file, add it to the linked list of open files.
-X * This is called only from openfile() above.
-X */
-X{
-X      register FILE           *fp;
-X
-X      if ((fp = fopen(filename, "r")) == NULL) {
-X#if DEBUG
-X          perror(filename);
-X#endif
-X          return (FALSE);
-X      }
-X#if DEBUG
-X      if (debug)
-X          fprintf(stderr, "Reading from \"%s\"\n", filename);
-X#endif
-X      addfile(fp, filename);
-X      return (TRUE);
-X}
-X
-Xaddfile(fp, filename)
-XFILE          *fp;                    /* Open file pointer            */
-Xchar          *filename;              /* Name of the file             */
-X/*
-X * Initialize tables for this open file.  This is called from openfile()
-X * above (for #include files), and from the entry to cpp to open the main
-X * input file.  It calls a common routine, getfile() to build the FILEINFO
-X * structure which is used to read characters.  (getfile() is also called
-X * to setup a macro replacement.)
-X */
-X{
-X      register FILEINFO       *file;
-X      extern FILEINFO         *getfile();
-X
-X      file = getfile(NBUFF, filename);
-X      file->fp = fp;                  /* Better remember FILE *       */
-X      file->buffer[0] = EOS;          /* Initialize for first read    */
-X      line = 1;                       /* Working on line 1 now        */
-X      wrongline = TRUE;               /* Force out initial #line      */
-X}
-X\f
-Xsetincdirs()
-X/*
-X * Append system-specific directories to the include directory list.
-X * Called only when cpp is started.
-X */
-X{
-X
-X#ifdef        CPP_INCLUDE
-X      *incend++ = CPP_INCLUDE;
-X#define       IS_INCLUDE      1
-X#else
-X#define       IS_INCLUDE      0
-X#endif
-X
-X#if HOST == SYS_UNIX
-X      *incend++ = "/usr/include";
-X#define       MAXINCLUDE      (NINCLUDE - 1 - IS_INCLUDE)
-X#endif
-X
-X#if HOST == SYS_VMS
-X      extern char     *getenv();
-X
-X      if (getenv("C$LIBRARY") != NULL)
-X          *incend++ = "C$LIBRARY:";
-X      *incend++ = "SYS$LIBRARY:";
-X#define       MAXINCLUDE      (NINCLUDE - 2 - IS_INCLUDE)
-X#endif
-X
-X#if HOST == SYS_RSX
-X      extern int      $$rsts;                 /* TRUE on RSTS/E       */
-X      extern int      $$pos;                  /* TRUE on PRO-350 P/OS */
-X      extern int      $$vms;                  /* TRUE on VMS compat.  */
-X
-X      if ($$pos) {                            /* P/OS?                */
-X          *incend++ = "SY:[ZZDECUSC]";        /* C #includes          */
-X          *incend++ = "LB:[1,5]";             /* RSX library          */
-X      }
-X      else if ($$rsts) {                      /* RSTS/E?              */
-X          *incend++ = "SY:@";                 /* User-defined account */
-X          *incend++ = "C:";                   /* Decus-C library      */
-X          *incend++ = "LB:[1,1]";             /* RSX library          */
-X      }
-X      else if ($$vms) {                       /* VMS compatibility?   */
-X          *incend++ = "C:";
-X      }
-X      else {                                  /* Plain old RSX/IAS    */
-X          *incend++ = "LB:[1,1]";
-X      }
-X#define       MAXINCLUDE      (NINCLUDE - 3 - IS_INCLUDE)
-X#endif
-X
-X#if HOST == SYS_RT11
-X      extern int      $$rsts;                 /* RSTS/E emulation?    */
-X
-X      if ($$rsts)
-X          *incend++ = "SY:@";                 /* User-defined account */
-X      *incend++ = "C:";                       /* Decus-C library disk */
-X      *incend++ = "SY:";                      /* System (boot) disk   */
-X#define       MAXINCLUDE      (NINCLUDE - 3 - IS_INCLUDE)
-X#endif
-X}
-X\f
-Xint
-Xdooptions(argc, argv)
-Xint           argc;
-Xchar          *argv[];
-X/*
-X * dooptions is called to process command line arguments (-Detc).
-X * It is called only at cpp startup.
-X */
-X{
-X      register char           *ap;
-X      register DEFBUF         *dp;
-X      register int            c;
-X      int                     i, j;
-X      char                    *arg;
-X      SIZES                   *sizp;          /* For -S               */
-X      int                     size;           /* For -S               */
-X      int                     isdatum;        /* FALSE for -S*        */
-X      int                     endtest;        /* For -S               */
-X
-X      for (i = j = 1; i < argc; i++) {
-X          arg = ap = argv[i];
-X          if (*ap++ != '-' || *ap == EOS)
-X              argv[j++] = argv[i];
-X          else {
-X              c = *ap++;                      /* Option byte          */
-X              if (islower(c))                 /* Normalize case       */
-X                  c = toupper(c);
-X              switch (c) {                    /* Command character    */
-X              case 'C':                       /* Keep comments        */
-X                  cflag = TRUE;
-X                  keepcomments = TRUE;
-X                  break;
-X
-X              case 'D':                       /* Define symbol        */
-X#if HOST != SYS_UNIX
-X                  zap_uc(ap);                 /* Force define to U.C. */
-X#endif
-X                  /*
-X                   * If the option is just "-Dfoo", make it -Dfoo=1
-X                   */
-X                  while (*ap != EOS && *ap != '=')
-X                      ap++;
-X                  if (*ap == EOS)
-X                      ap = "1";
-X                  else
-X                      *ap++ = EOS;
-X                  /*
-X                   * Now, save the word and its definition.
-X                   */
-X                  dp = defendel(argv[i] + 2, FALSE);
-X                  dp->repl = savestring(ap);
-X                  dp->nargs = DEF_NOARGS;
-X                  break;
-X
-X              case 'E':                       /* Ignore non-fatal     */
-X                  eflag = TRUE;               /* errors.              */
-X                  break;
-X
-X              case 'I':                       /* Include directory    */
-X                  if (incend >= &incdir[MAXINCLUDE])
-X                      cfatal("Too many include directories", NULLST);
-X                  *incend++ = ap;
-X                  break;
-X
-X              case 'N':                       /* No predefineds       */
-X                  nflag++;                    /* Repeat to undefine   */
-X                  break;                      /* __LINE__, etc.       */
-X
-X              case 'S':
-X                  sizp = size_table;
-X                  if (isdatum = (*ap != '*')) /* If it's just -S,     */
-X                      endtest = T_FPTR;       /* Stop here            */
-X                  else {                      /* But if it's -S*      */
-X                      ap++;                   /* Step over '*'        */
-X                      endtest = 0;            /* Stop at end marker   */
-X                  }
-X                  while (sizp->bits != endtest && *ap != EOS) {
-X                      if (!isdigit(*ap)) {    /* Skip to next digit   */
-X                          ap++;
-X                          continue;
-X                      }
-X                      size = 0;               /* Compile the value    */
-X                      while (isdigit(*ap)) {
-X                          size *= 10;
-X                          size += (*ap++ - '0');
-X                      }
-X                      if (isdatum)
-X                          sizp->size = size;  /* Datum size           */
-X                      else
-X                          sizp->psize = size; /* Pointer size         */
-X                      sizp++;
-X                  }
-X                  if (sizp->bits != endtest)
-X                      cwarn("-S, too few values specified in %s", argv[i]);
-X                  else if (*ap != EOS)
-X                      cwarn("-S, too many values, \"%s\" unused", ap);
-X                  break;
-X
-X              case 'U':                       /* Undefine symbol      */
-X#if HOST != SYS_UNIX
-X                  zap_uc(ap);
-X#endif
-X                  if (defendel(ap, TRUE) == NULL)
-X                      cwarn("\"%s\" wasn't defined", ap);
-X                  break;
-X
-X#if DEBUG
-X              case 'X':                       /* Debug                */
-X                  debug = (isdigit(*ap)) ? atoi(ap) : 1;
-X#if (HOST == SYS_VMS || HOST == SYS_UNIX)
-X                  signal(SIGINT, abort);      /* Trap "interrupt"     */
-X#endif
-X                  fprintf(stderr, "Debug set to %d\n", debug);
-X                  break;
-X#endif
-X
-X              default:                        /* What is this one?    */
-X                  cwarn("Unknown option \"%s\"", arg);
-X                  fprintf(stderr, "The following options are valid:\n\
-X  -C\t\t\tWrite source file comments to output\n\
-X  -Dsymbol=value\tDefine a symbol with the given (optional) value\n\
-X  -Idirectory\t\tAdd a directory to the #include search list\n\
-X  -N\t\t\tDon't predefine target-specific names\n\
-X  -Stext\t\tSpecify sizes for #if sizeof\n\
-X  -Usymbol\t\tUndefine symbol\n");
-X#if DEBUG
-X                  fprintf(stderr, "  -Xvalue\t\tSet internal debug flag\n");
-X#endif
-X                  break;
-X              }                       /* Switch on all options        */
-X          }                           /* If it's a -option            */
-X      }                               /* For all arguments            */
-X      if (j > 3) {
-X          cerror(
-X              "Too many file arguments.  Usage: cpp [input [output]]",
-X              NULLST);
-X      }
-X      return (j);                     /* Return new argc              */
-X}
-X\f
-X#if HOST != SYS_UNIX
-XFILE_LOCAL
-Xzap_uc(ap)
-Xregister char *ap;
-X/*
-X * Dec operating systems mangle upper-lower case in command lines.
-X * This routine forces the -D and -U arguments to uppercase.
-X * It is called only on cpp startup by dooptions().
-X */
-X{
-X      while (*ap != EOS) {
-X          /*
-X           * Don't use islower() here so it works with Multinational
-X           */
-X          if (*ap >= 'a' && *ap <= 'z')
-X              *ap = toupper(*ap);
-X          ap++;
-X      }
-X}
-X#endif
-X
-Xinitdefines()
-X/*
-X * Initialize the built-in #define's.  There are two flavors:
-X *    #define decus   1               (static definitions)
-X *    #define __FILE__ ??             (dynamic, evaluated by magic)
-X * Called only on cpp startup.
-X *
-X * Note: the built-in static definitions are supressed by the -N option.
-X * __LINE__, __FILE__, and __DATE__ are always present.
-X */
-X{
-X      register char           **pp;
-X      register char           *tp;
-X      register DEFBUF         *dp;
-X      int                     i;
-X      long                    tvec;
-X      extern char             *ctime();
-X
-X      /*
-X       * Predefine the built-in symbols.  Allow the
-X       * implementor to pre-define a symbol as "" to
-X       * eliminate it.
-X       */
-X      if (nflag == 0) {
-X          for (pp = preset; *pp != NULL; pp++) {
-X              if (*pp[0] != EOS) {
-X                  dp = defendel(*pp, FALSE);
-X                  dp->repl = savestring("1");
-X                  dp->nargs = DEF_NOARGS;
-X              }
-X          }
-X      }
-X      /*
-X       * The magic pre-defines (__FILE__ and __LINE__ are
-X       * initialized with negative argument counts.  expand()
-X       * notices this and calls the appropriate routine.
-X       * DEF_NOARGS is one greater than the first "magic" definition.
-X       */
-X      if (nflag < 2) {
-X          for (pp = magic, i = DEF_NOARGS; *pp != NULL; pp++) {
-X              dp = defendel(*pp, FALSE);
-X              dp->nargs = --i;
-X          }
-X#if OK_DATE
-X          /*
-X           * Define __DATE__ as today's date.
-X           */
-X          dp = defendel("__DATE__", FALSE);
-X          dp->repl = tp = getmem(27);
-X          dp->nargs = DEF_NOARGS;
-X          time(&tvec);
-X          *tp++ = '"';
-X          strcpy(tp, ctime(&tvec));
-X          tp[24] = '"';                       /* Overwrite newline    */
-X#endif
-X      }
-X}
-X\f
-X#if HOST == SYS_VMS
-X/*
-X * getredirection() is intended to aid in porting C programs
-X * to VMS (Vax-11 C) which does not support '>' and '<'
-X * I/O redirection.  With suitable modification, it may
-X * useful for other portability problems as well.
-X */
-X
-Xint
-Xgetredirection(argc, argv)
-Xint           argc;
-Xchar          **argv;
-X/*
-X * Process vms redirection arg's.  Exit if any error is seen.
-X * If getredirection() processes an argument, it is erased
-X * from the vector.  getredirection() returns a new argc value.
-X *
-X * Warning: do not try to simplify the code for vms.  The code
-X * presupposes that getredirection() is called before any data is
-X * read from stdin or written to stdout.
-X *
-X * Normal usage is as follows:
-X *
-X *    main(argc, argv)
-X *    int             argc;
-X *    char            *argv[];
-X *    {
-X *            argc = getredirection(argc, argv);
-X *    }
-X */
-X{
-X      register char           *ap;    /* Argument pointer     */
-X      int                     i;      /* argv[] index         */
-X      int                     j;      /* Output index         */
-X      int                     file;   /* File_descriptor      */
-X      extern int              errno;  /* Last vms i/o error   */
-X
-X      for (j = i = 1; i < argc; i++) {   /* Do all arguments  */
-X          switch (*(ap = argv[i])) {
-X          case '<':                   /* <file                */
-X              if (freopen(++ap, "r", stdin) == NULL) {
-X                  perror(ap);         /* Can't find file      */
-X                  exit(errno);        /* Is a fatal error     */
-X              }
-X              break;
-X
-X          case '>':                   /* >file or >>file      */
-X              if (*++ap == '>') {     /* >>file               */
-X                  /*
-X                   * If the file exists, and is writable by us,
-X                   * call freopen to append to the file (using the
-X                   * file's current attributes).  Otherwise, create
-X                   * a new file with "vanilla" attributes as if the
-X                   * argument was given as ">filename".
-X                   * access(name, 2) returns zero if we can write on
-X                   * the specified file.
-X                   */
-X                  if (access(++ap, 2) == 0) {
-X                      if (freopen(ap, "a", stdout) != NULL)
-X                          break;      /* Exit case statement  */
-X                      perror(ap);     /* Error, can't append  */
-X                      exit(errno);    /* After access test    */
-X                  }                   /* If file accessable   */
-X              }
-X              /*
-X               * On vms, we want to create the file using "standard"
-X               * record attributes.  creat(...) creates the file
-X               * using the caller's default protection mask and
-X               * "variable length, implied carriage return"
-X               * attributes. dup2() associates the file with stdout.
-X               */
-X              if ((file = creat(ap, 0, "rat=cr", "rfm=var")) == -1
-X               || dup2(file, fileno(stdout)) == -1) {
-X                  perror(ap);         /* Can't create file    */
-X                  exit(errno);        /* is a fatal error     */
-X              }                       /* If '>' creation      */
-X              break;                  /* Exit case test       */
-X
-X          default:
-X              argv[j++] = ap;         /* Not a redirector     */
-X              break;                  /* Exit case test       */
-X          }
-X      }                               /* For all arguments    */
-X      argv[j] = NULL;                 /* Terminate argv[]     */
-X      return (j);                     /* Return new argc      */
-X}
-X#endif
-X
-X
-X
-END-of-cpp3.c
-echo x - cpp4.c
-sed 's/^X//' >cpp4.c << 'END-of-cpp4.c'
-X/*
-X *                        C P P 4 . C
-X *            M a c r o  D e f i n i t i o n s
-X *
-X * Edit History
-X * 31-Aug-84  MM      USENET net.sources release
-X * 04-Oct-84  MM      __LINE__ and __FILE__ must call ungetstring()
-X *                    so they work correctly with token concatenation.
-X *                    Added string formal recognition.
-X * 25-Oct-84  MM      "Short-circuit" evaluate #if's so that we
-X *                    don't print unnecessary error messages for
-X *                    #if !defined(FOO) && FOO != 0 && 10 / FOO ...
-X * 31-Oct-84  ado/MM  Added token concatenation
-X *  6-Nov-84  MM      Split off eval stuff
-X */
-X
-X#include      <stdio.h>
-X#include      <ctype.h>
-X#include      "cppdef.h"
-X#include      "cpp.h"
-X/*
-X * parm[], parmp, and parlist[] are used to store #define() argument
-X * lists.  nargs contains the actual number of parameters stored.
-X */
-Xstatic char   parm[NPARMWORK + 1];    /* define param work buffer     */
-Xstatic char   *parmp;                 /* Free space in parm           */
-Xstatic char   *parlist[LASTPARM];     /* -> start of each parameter   */
-Xstatic int    nargs;                  /* Parameters for this macro    */
-X
-Xdodefine()
-X/*
-X * Called from control when a #define is scanned.  This module
-X * parses formal parameters and the replacement string.  When
-X * the formal parameter name is encountered in the replacement
-X * string, it is replaced by a character in the range 128 to
-X * 128+NPARAM (this allows up to 32 parameters within the
-X * Dec Multinational range).  If cpp is ported to an EBCDIC
-X * machine, you will have to make other arrangements.
-X *
-X * There is some special case code to distinguish
-X *    #define foo     bar
-X * from       #define foo()   bar
-X *
-X * Also, we make sure that
-X *    #define foo     foo
-X * expands to "foo" but doesn't put cpp into an infinite loop.
-X *
-X * A warning message is printed if you redefine a symbol to a
-X * different text.  I.e,
-X *    #define foo     123
-X *    #define foo     123
-X * is ok, but
-X *    #define foo     123
-X *    #define foo     +123
-X * is not.
-X *
-X * The following subroutines are called from define():
-X * checkparm  called when a token is scanned.  It checks through the
-X *            array of formal parameters.  If a match is found, the
-X *            token is replaced by a control byte which will be used
-X *            to locate the parameter when the macro is expanded.
-X * textput    puts a string in the macro work area (parm[]), updating
-X *            parmp to point to the first free byte in parm[].
-X *            textput() tests for work buffer overflow.
-X * charput    puts a single character in the macro work area (parm[])
-X *            in a manner analogous to textput().
-X */
-X{
-X      register int            c;
-X      register DEFBUF         *dp;            /* -> new definition    */
-X      int                     isredefine;     /* TRUE if redefined    */
-X      char                    *old;           /* Remember redefined   */
-X      extern int              save();         /* Save char in work[]  */
-X
-X      if (type[(c = skipws())] != LET)
-X          goto bad_define;
-X      isredefine = FALSE;                     /* Set if redefining    */
-X      if ((dp = lookid(c)) == NULL)           /* If not known now     */
-X          dp = defendel(token, FALSE);        /* Save the name        */
-X      else {                                  /* It's known:          */
-X          isredefine = TRUE;                  /* Remember this fact   */
-X          old = dp->repl;                     /* Remember replacement */
-X          dp->repl = NULL;                    /* No replacement now   */
-X      }
-X      parlist[0] = parmp = parm;              /* Setup parm buffer    */
-X      if ((c = get()) == '(') {               /* With arguments?      */
-X          nargs = 0;                          /* Init formals counter */
-X          do {                                /* Collect formal parms */
-X              if (nargs >= LASTPARM)
-X                  cfatal("Too many arguments for macro", NULLST);
-X              else if ((c = skipws()) == ')')
-X                  break;                      /* Got them all         */
-X              else if (type[c] != LET)        /* Bad formal syntax    */
-X                  goto bad_define;
-X              scanid(c);                      /* Get the formal param */
-X              parlist[nargs++] = parmp;       /* Save its start       */
-X              textput(token);                 /* Save text in parm[]  */
-X          } while ((c = skipws()) == ',');    /* Get another argument */
-X          if (c != ')')                       /* Must end at )        */
-X              goto bad_define;
-X          c = ' ';                            /* Will skip to body    */
-X      }
-X      else {
-X          /*
-X           * DEF_NOARGS is needed to distinguish between
-X           * "#define foo" and "#define foo()".
-X           */
-X          nargs = DEF_NOARGS;                 /* No () parameters     */
-X      }
-X      if (type[c] == SPA)                     /* At whitespace?       */
-X          c = skipws();                       /* Not any more.        */
-X      workp = work;                           /* Replacement put here */
-X      inmacro = TRUE;                         /* Keep \<newline> now  */
-X      while (c != EOF_CHAR && c != '\n') {    /* Compile macro body   */
-X#if OK_CONCAT
-X          if (c == '#') {                     /* Token concatenation? */
-X              while (workp > work && type[workp[-1]] == SPA)
-X                  --workp;                    /* Erase leading spaces */
-X              save(TOK_SEP);                  /* Stuff a delimiter    */
-X              c = skipws();                   /* Eat whitespace       */
-X              if (type[c] == LET)             /* Another token here?  */
-X                  ;                           /* Stuff it normally    */
-X              else if (type[c] == DIG) {      /* Digit string after?  */
-X                  while (type[c] == DIG) {    /* Stuff the digits     */
-X                      save(c);
-X                      c = get();
-X                  }
-X                  save(TOK_SEP);              /* Delimit 2nd token    */
-X              }
-X              else {
-X                  ciwarn("Strange character after # (%d.)", c);
-X              }
-X              continue;
-X          }
-X#endif
-X          switch (type[c]) {
-X          case LET:
-X              checkparm(c, dp);               /* Might be a formal    */
-X              break;
-X
-X          case DIG:                           /* Number in mac. body  */
-X          case DOT:                           /* Maybe a float number */
-X              scannumber(c, save);            /* Scan it off          */
-X              break;
-X
-X          case QUO:                           /* String in mac. body  */
-X#if STRING_FORMAL
-X              stparmscan(c, dp);              /* Do string magic      */
-X#else
-X              stparmscan(c);
-X#endif
-X              break;
-X
-X          case BSH:                           /* Backslash            */
-X              save('\\');
-X              if ((c = get()) == '\n')
-X                  wrongline = TRUE;
-X              save(c);
-X              break;
-X
-X          case SPA:                           /* Absorb whitespace    */
-X              /*
-X               * Note: the "end of comment" marker is passed on
-X               * to allow comments to separate tokens.
-X               */
-X              if (workp[-1] == ' ')           /* Absorb multiple      */
-X                  break;                      /* spaces               */
-X              else if (c == '\t')
-X                  c = ' ';                    /* Normalize tabs       */
-X              /* Fall through to store character                      */
-X          default:                            /* Other character      */
-X              save(c);
-X              break;
-X          }
-X          c = get();
-X      }
-X      inmacro = FALSE;                        /* Stop newline hack    */
-X      unget();                                /* For control check    */
-X      if (workp > work && workp[-1] == ' ')   /* Drop trailing blank  */
-X          workp--;
-X      *workp = EOS;                           /* Terminate work       */
-X      dp->repl = savestring(work);            /* Save the string      */
-X      dp->nargs = nargs;                      /* Save arg count       */
-X#if DEBUG
-X      if (debug)
-X          dumpadef("macro definition", dp);
-X#endif
-X      if (isredefine) {                       /* Error if redefined   */
-X          if ((old != NULL && dp->repl != NULL && !streq(old, dp->repl))
-X           || (old == NULL && dp->repl != NULL)
-X           || (old != NULL && dp->repl == NULL)) {
-X              cerror("Redefining defined variable \"%s\"", dp->name);
-X          }
-X          if (old != NULL)                    /* We don't need the    */
-X              free(old);                      /* old definition now.  */
-X      }        
-X      return;
-X
-Xbad_define:
-X      cerror("#define syntax error", NULLST);
-X      inmacro = FALSE;                        /* Stop <newline> hack  */
-X}
-X\f
-Xcheckparm(c, dp)
-Xregister int  c;
-XDEFBUF                *dp;
-X/*
-X * Replace this param if it's defined.  Note that the macro name is a
-X * possible replacement token.  We stuff DEF_MAGIC in front of the token
-X * which is treated as a LETTER by the token scanner and eaten by
-X * the output routine.  This prevents the macro expander from
-X * looping if someone writes "#define foo foo".
-X */
-X{
-X      register int            i;
-X      register char           *cp;
-X
-X      scanid(c);                              /* Get parm to token[]  */
-X      for (i = 0; i < nargs; i++) {           /* For each argument    */
-X          if (streq(parlist[i], token)) {     /* If it's known        */
-X              save(i + MAC_PARM);             /* Save a magic cookie  */
-X              return;                         /* And exit the search  */
-X          }
-X      }
-X      if (streq(dp->name, token))             /* Macro name in body?  */
-X          save(DEF_MAGIC);                    /* Save magic marker    */
-X      for (cp = token; *cp != EOS;)           /* And save             */
-X          save(*cp++);                        /* The token itself     */
-X}
-X\f
-X#if STRING_FORMAL
-Xstparmscan(delim, dp)
-Xint           delim;
-Xregister DEFBUF       *dp;
-X/*
-X * Scan the string (starting with the given delimiter).
-X * The token is replaced if it is the only text in this string or
-X * character constant.  The algorithm follows checkparm() above.
-X * Note that scanstring() has approved of the string.
-X */
-X{
-X      register int            c;
-X
-X      /*
-X       * Warning -- this code hasn't been tested for a while.
-X       * It exists only to preserve compatibility with earlier
-X       * implementations of cpp.  It is not part of the Draft
-X       * ANSI Standard C language.
-X       */
-X      save(delim);
-X      instring = TRUE;
-X      while ((c = get()) != delim
-X           && c != '\n'
-X           && c != EOF_CHAR) {
-X          if (type[c] == LET)                 /* Maybe formal parm    */
-X              checkparm(c, dp);
-X          else {
-X              save(c);
-X              if (c == '\\')
-X                  save(get());
-X          }
-X      }
-X      instring = FALSE;
-X      if (c != delim)
-X          cerror("Unterminated string in macro body", NULLST);
-X      save(c);
-X}
-X#else
-Xstparmscan(delim)
-Xint           delim;
-X/*
-X * Normal string parameter scan.
-X */
-X{
-X      register char           *wp;
-X      register int            i;
-X      extern int              save();
-X
-X      wp = workp;                     /* Here's where it starts       */
-X      if (!scanstring(delim, save))
-X          return;                     /* Exit on scanstring error     */
-X      workp[-1] = EOS;                /* Erase trailing quote         */
-X      wp++;                           /* -> first string content byte */ 
-X      for (i = 0; i < nargs; i++) {
-X          if (streq(parlist[i], wp)) {
-X              *wp++ = MAC_PARM + PAR_MAC;     /* Stuff a magic marker */
-X              *wp++ = (i + MAC_PARM);         /* Make a formal marker */
-X              *wp = wp[-3];                   /* Add on closing quote */
-X              workp = wp + 1;                 /* Reset string end     */
-X              return;
-X          }
-X      }
-X      workp[-1] = wp[-1];             /* Nope, reset end quote.       */
-X}
-X#endif
-X\f
-Xdoundef()
-X/*
-X * Remove the symbol from the defined list.
-X * Called from the #control processor.
-X */
-X{
-X      register int            c;
-X
-X      if (type[(c = skipws())] != LET)
-X          cerror("Illegal #undef argument", NULLST);
-X      else {
-X          scanid(c);                          /* Get name to token[]  */
-X          if (defendel(token, TRUE) == NULL) {
-X              cwarn("Symbol \"%s\" not defined in #undef", token);
-X          }
-X      }
-X}
-X
-Xtextput(text)
-Xchar          *text;
-X/*
-X * Put the string in the parm[] buffer.
-X */
-X{
-X      register int    size;
-X
-X      size = strlen(text) + 1;
-X      if ((parmp + size) >= &parm[NPARMWORK])
-X          cfatal("Macro work area overflow", NULLST);
-X      else {
-X          strcpy(parmp, text);
-X          parmp += size;
-X      }
-X}
-X
-Xcharput(c)
-Xregister int  c;
-X/*
-X * Put the byte in the parm[] buffer.
-X */
-X{
-X      if (parmp >= &parm[NPARMWORK])
-X          cfatal("Macro work area overflow", NULLST);
-X      else {
-X          *parmp++ = c;
-X      }
-X}
-X\f
-X/*
-X *            M a c r o   E x p a n s i o n
-X */
-X
-Xstatic DEFBUF *macro;         /* Catches start of infinite macro      */
-X
-Xexpand(tokenp)
-Xregister DEFBUF       *tokenp;
-X/*
-X * Expand a macro.  Called from the cpp mainline routine (via subroutine
-X * macroid()) when a token is found in the symbol table.  It calls
-X * expcollect() to parse actual parameters, checking for the correct number.
-X * It then creates a "file" containing a single line containing the
-X * macro with actual parameters inserted appropriately.  This is
-X * "pushed back" onto the input stream.  (When the get() routine runs
-X * off the end of the macro line, it will dismiss the macro itself.)
-X */
-X{
-X      register int            c;
-X      register FILEINFO       *file;
-X      extern FILEINFO         *getfile();
-X
-X#if DEBUG
-X      if (debug)
-X          dumpadef("expand entry", tokenp);
-X#endif
-X      /*
-X       * If no macro is pending, save the name of this macro
-X       * for an eventual error message.
-X       */
-X      if (recursion++ == 0)
-X          macro = tokenp;
-X      else if (recursion == RECURSION_LIMIT) {
-X          cerror("Recursive macro definition of \"%s\"", tokenp->name);
-X          fprintf(stderr, "(Defined by \"%s\")\n", macro->name);
-X          if (rec_recover) {
-X              do {
-X                  c = get();
-X              } while (infile != NULL && infile->fp == NULL);
-X              unget();
-X              recursion = 0;
-X              return;
-X          }
-X      }
-X      /*
-X       * Here's a macro to expand.
-X       */
-X      nargs = 0;                              /* Formals counter      */
-X      parmp = parm;                           /* Setup parm buffer    */
-X      switch (tokenp->nargs) {
-X      case (-2):                              /* __LINE__             */
-X          sprintf(work, "%d", line);
-X          ungetstring(work);
-X          break;
-X
-X      case (-3):                              /* __FILE__             */
-X          for (file = infile; file != NULL; file = file->parent) {
-X              if (file->fp != NULL) {
-X                  sprintf(work, "\"%s\"", (file->progname != NULL)
-X                      ? file->progname : file->filename);
-X                  ungetstring(work);
-X                  break;
-X              }
-X          }
-X          break;
-X
-X      default:
-X          /*
-X           * Nothing funny about this macro.
-X           */
-X          if (tokenp->nargs < 0)
-X              cfatal("Bug: Illegal __ macro \"%s\"", tokenp->name);
-X          while ((c = skipws()) == '\n')      /* Look for (, skipping */
-X              wrongline = TRUE;               /* spaces and newlines  */
-X          if (c != '(') {
-X              /*
-X               * If the programmer writes
-X               *      #define foo() ...
-X               *      ...
-X               *      foo [no ()]
-X               * just write foo to the output stream.
-X               */
-X              unget();
-X              cwarn("Macro \"%s\" needs arguments", tokenp->name);
-X              fputs(tokenp->name, stdout);
-X              return;
-X          }
-X          else if (expcollect()) {            /* Collect arguments    */
-X              if (tokenp->nargs != nargs) {   /* Should be an error?  */
-X                  cwarn("Wrong number of macro arguments for \"%s\"",
-X                      tokenp->name);
-X              }
-X#if DEBUG
-X              if (debug)
-X                  dumpparm("expand");
-X#endif
-X          }                           /* Collect arguments            */
-X      case DEF_NOARGS:                /* No parameters just stuffs    */
-X          expstuff(tokenp);           /* Do actual parameters         */
-X      }                               /* nargs switch                 */
-X}
-X\f
-XFILE_LOCAL int
-Xexpcollect()
-X/*
-X * Collect the actual parameters for this macro.  TRUE if ok.
-X */
-X{
-X      register int    c;
-X      register int    paren;                  /* For embedded ()'s    */
-X      extern int      charput();
-X
-X      for (;;) {
-X          paren = 0;                          /* Collect next arg.    */
-X          while ((c = skipws()) == '\n')      /* Skip over whitespace */
-X              wrongline = TRUE;               /* and newlines.        */
-X          if (c == ')') {                     /* At end of all args?  */
-X              /*
-X               * Note that there is a guard byte in parm[]
-X               * so we don't have to check for overflow here.
-X               */
-X              *parmp = EOS;                   /* Make sure terminated */
-X              break;                          /* Exit collection loop */
-X          }
-X          else if (nargs >= LASTPARM)
-X              cfatal("Too many arguments in macro expansion", NULLST);
-X          parlist[nargs++] = parmp;           /* At start of new arg  */
-X          for (;; c = cget()) {               /* Collect arg's bytes  */
-X              if (c == EOF_CHAR) {
-X                  cerror("end of file within macro argument", NULLST);
-X                  return (FALSE);             /* Sorry.               */
-X              }
-X              else if (c == '\\') {           /* Quote next character */
-X                  charput(c);                 /* Save the \ for later */
-X                  charput(cget());            /* Save the next char.  */
-X                  continue;                   /* And go get another   */
-X              }
-X              else if (type[c] == QUO) {      /* Start of string?     */
-X                  scanstring(c, charput);     /* Scan it off          */
-X                  continue;                   /* Go get next char     */
-X              }
-X              else if (c == '(')              /* Worry about balance  */
-X                  paren++;                    /* To know about commas */
-X              else if (c == ')') {            /* Other side too       */
-X                  if (paren == 0) {           /* At the end?          */
-X                      unget();                /* Look at it later     */
-X                      break;                  /* Exit arg getter.     */
-X                  }
-X                  paren--;                    /* More to come.        */
-X              }
-X              else if (c == ',' && paren == 0) /* Comma delimits args */
-X                  break;
-X              else if (c == '\n')             /* Newline inside arg?  */
-X                  wrongline = TRUE;           /* We'll need a #line   */
-X              charput(c);                     /* Store this one       */
-X          }                                   /* Collect an argument  */
-X          charput(EOS);                       /* Terminate argument   */
-X#if DEBUG
-X          if (debug)
-X              printf("parm[%d] = \"%s\"\n", nargs, parlist[nargs - 1]);
-X#endif
-X      }                                       /* Collect all args.    */
-X      return (TRUE);                          /* Normal return        */
-X}
-X\f
-XFILE_LOCAL
-Xexpstuff(tokenp)
-XDEFBUF                *tokenp;                /* Current macro being expanded */
-X/*
-X * Stuff the macro body, replacing formal parameters by actual parameters.
-X */
-X{
-X      register int    c;                      /* Current character    */
-X      register char   *inp;                   /* -> repl string       */
-X      register char   *defp;                  /* -> macro output buff */
-X      int             size;                   /* Actual parm. size    */
-X      char            *defend;                /* -> output buff end   */
-X      int             string_magic;           /* String formal hack   */
-X      FILEINFO        *file;                  /* Funny #include       */
-X      extern FILEINFO *getfile();
-X
-X      file = getfile(NBUFF, tokenp->name);
-X      inp = tokenp->repl;                     /* -> macro replacement */
-X      defp = file->buffer;                    /* -> output buffer     */
-X      defend = defp + (NBUFF - 1);            /* Note its end         */
-X      if (inp != NULL) {
-X          while ((c = (*inp++ & 0xFF)) != EOS) {
-X              if (c >= MAC_PARM && c <= (MAC_PARM + PAR_MAC)) {
-X                  string_magic = (c == (MAC_PARM + PAR_MAC));
-X                  if (string_magic)
-X                      c = (*inp++ & 0xFF);
-X                  /*
-X                   * Replace formal parameter by actual parameter string.
-X                   */
-X                  if ((c -= MAC_PARM) < nargs) {
-X                      size = strlen(parlist[c]);
-X                      if ((defp + size) >= defend)
-X                          goto nospace;
-X                      /*
-X                       * Erase the extra set of quotes.
-X                       */
-X                      if (string_magic && defp[-1] == parlist[c][0]) {
-X                          strcpy(defp-1, parlist[c]);
-X                          defp += (size - 2);
-X                      }
-X                      else {
-X                          strcpy(defp, parlist[c]);
-X                          defp += size;
-X                      }
-X                  }
-X              }
-X              else if (defp >= defend) {
-Xnospace:          cfatal("Out of space in macro \"%s\" arg expansion",
-X                      tokenp->name);
-X              }
-X              else {
-X                  *defp++ = c;
-X              }
-X          }
-X      }
-X      *defp = EOS;
-X#if DEBUG
-X      if (debug > 1)
-X          printf("macroline: \"%s\"\n", file->buffer);
-X#endif
-X}
-X\f
-X#if DEBUG
-Xdumpparm(why)
-Xchar          *why;
-X/*
-X * Dump parameter list.
-X */
-X{
-X      register int    i;
-X
-X      printf("dump of %d parameters (%d bytes total) %s\n",
-X          nargs, parmp - parm, why);
-X      for (i = 0; i < nargs; i++) {
-X          printf("parm[%d] (%d) = \"%s\"\n",
-X              i + 1, strlen(parlist[i]), parlist[i]);
-X      }
-X}
-X#endif
-END-of-cpp4.c
-exit
diff --git a/sys/unix/cpp3.shr b/sys/unix/cpp3.shr
deleted file mode 100644 (file)
index d437d36..0000000
+++ /dev/null
@@ -1,1901 +0,0 @@
-# This is a shell archive.  Save it in a file, remove anything before
-# this line, and then unpack it by entering "sh file".  Note, it may
-# create directories; files and directories will be owned by you and
-# have default permissions.
-#
-# This archive contains:
-#
-#      cpp5.c
-#      cpp6.c
-#
-echo x - cpp5.c
-sed 's/^X//' >cpp5.c << 'END-of-cpp5.c'
-X/*
-X *                        C P P 5 . C
-X *            E x p r e s s i o n   E v a l u a t i o n
-X *
-X * Edit History
-X * 31-Aug-84  MM      USENET net.sources release
-X * 04-Oct-84  MM      __LINE__ and __FILE__ must call ungetstring()
-X *                    so they work correctly with token concatenation.
-X *                    Added string formal recognition.
-X * 25-Oct-84  MM      "Short-circuit" evaluate #if's so that we
-X *                    don't print unnecessary error messages for
-X *                    #if !defined(FOO) && FOO != 0 && 10 / FOO ...
-X * 31-Oct-84  ado/MM  Added token concatenation
-X *  6-Nov-84  MM      Split from #define stuff, added sizeof stuff
-X * 19-Nov-84  ado     #if error returns TRUE for (sigh) compatibility
-X */
-X
-X#include      <stdio.h>
-X#include      <ctype.h>
-X#include      "cppdef.h"
-X#include      "cpp.h"
-X
-X/*
-X * Evaluate an #if expression.
-X */
-X
-Xstatic char   *opname[] = {           /* For debug and error messages */
-X"end of expression", "val", "id",
-X  "+",   "-",  "*",  "/",  "%",
-X  "<<", ">>",  "&",  "|",  "^",
-X  "==", "!=",  "<", "<=", ">=",  ">",
-X  "&&", "||",  "?",  ":",  ",",
-X  "unary +", "unary -", "~", "!",  "(",  ")", "(none)",
-X};
-X
-X/*
-X * opdope[] has the operator precedence:
-X *     Bits
-X *      7     Unused (so the value is always positive)
-X *    6-2     Precedence (000x .. 017x)
-X *    1-0     Binary op. flags:
-X *        01  The binop flag should be set/cleared when this op is seen.
-X *        10  The new value of the binop flag.
-X * Note:  Expected, New binop
-X * constant   0       1       Binop, end, or ) should follow constants
-X * End of line        1       0       End may not be preceeded by an operator
-X * binary     1       0       Binary op follows a value, value follows.
-X * unary      0       0       Unary op doesn't follow a value, value follows
-X *   (                0       0       Doesn't follow value, value or unop follows
-X *   )                1       1       Follows value.  Op follows.
-X */
-X
-Xstatic char   opdope[OP_MAX] = {
-X  0001,                                       /* End of expression            */
-X  0002,                                       /* Digit                        */
-X  0000,                                       /* Letter (identifier)          */
-X  0141, 0141, 0151, 0151, 0151,               /* ADD, SUB, MUL, DIV, MOD      */
-X  0131, 0131, 0101, 0071, 0071,               /* ASL, ASR, AND,  OR, XOR      */
-X  0111, 0111, 0121, 0121, 0121,       0121,   /*  EQ,  NE,  LT,  LE,  GE,  GT */
-X  0061, 0051, 0041, 0041, 0031,               /* ANA, ORO, QUE, COL, CMA      */
-X/*
-X * Unary op's follow
-X */
-X  0160, 0160, 0160, 0160,             /* NEG, PLU, COM, NOT           */
-X  0170, 0013, 0023,                   /* LPA, RPA, END                */
-X};
-X/*
-X * OP_QUE and OP_RPA have alternate precedences:
-X */
-X#define       OP_RPA_PREC     0013
-X#define OP_QUE_PREC   0034
-X
-X/*
-X * S_ANDOR and S_QUEST signal "short-circuit" boolean evaluation, so that
-X *    #if FOO != 0 && 10 / FOO ...
-X * doesn't generate an error message.  They are stored in optab.skip.
-X */
-X#define S_ANDOR               2
-X#define S_QUEST               1
-X
-Xtypedef struct optab {
-X    char      op;                     /* Operator                     */
-X    char      prec;                   /* Its precedence               */
-X    char      skip;                   /* Short-circuit: TRUE to skip  */
-X} OPTAB;
-Xstatic int    evalue;                 /* Current value from evallex() */
-X
-X#ifdef        nomacargs
-XFILE_LOCAL int
-Xisbinary(op)
-Xregister int  op;
-X{
-X      return (op >= FIRST_BINOP && op <= LAST_BINOP);
-X}
-X
-XFILE_LOCAL int
-Xisunary(op)
-Xregister int  op;
-X{
-X      return (op >= FIRST_UNOP && op <= LAST_UNOP);
-X}
-X#else
-X#define       isbinary(op)    (op >= FIRST_BINOP && op <= LAST_BINOP)
-X#define       isunary(op)     (op >= FIRST_UNOP  && op <= LAST_UNOP)
-X#endif
-X\f
-X/*
-X * The following definitions are used to specify basic variable sizes.
-X */
-X
-X#ifndef       S_CHAR
-X#define       S_CHAR          (sizeof (char))
-X#endif
-X#ifndef       S_SINT
-X#define       S_SINT          (sizeof (short int))
-X#endif
-X#ifndef       S_INT
-X#define       S_INT           (sizeof (int))
-X#endif
-X#ifndef       S_LINT
-X#define       S_LINT          (sizeof (long int))
-X#endif
-X#ifndef       S_FLOAT
-X#define       S_FLOAT         (sizeof (float))
-X#endif
-X#ifndef       S_DOUBLE
-X#define       S_DOUBLE        (sizeof (double))
-X#endif
-X#ifndef       S_PCHAR
-X#define       S_PCHAR         (sizeof (char *))
-X#endif
-X#ifndef       S_PSINT
-X#define       S_PSINT         (sizeof (short int *))
-X#endif
-X#ifndef       S_PINT
-X#define       S_PINT          (sizeof (int *))
-X#endif
-X#ifndef       S_PLINT
-X#define       S_PLINT         (sizeof (long int *))
-X#endif
-X#ifndef       S_PFLOAT
-X#define       S_PFLOAT        (sizeof (float *))
-X#endif
-X#ifndef       S_PDOUBLE
-X#define       S_PDOUBLE       (sizeof (double *))
-X#endif
-X#ifndef       S_PFPTR
-X#define S_PFPTR               (sizeof (int (*)()))
-X#endif
-X\f
-Xtypedef struct types {
-X    short     type;                   /* This is the bit if           */
-X    char      *name;                  /* this is the token word       */
-X} TYPES;
-X
-Xstatic TYPES basic_types[] = {
-X      { T_CHAR,       "char",         },
-X      { T_INT,        "int",          },
-X      { T_FLOAT,      "float",        },
-X      { T_DOUBLE,     "double",       },
-X      { T_SHORT,      "short",        },
-X      { T_LONG,       "long",         },
-X      { T_SIGNED,     "signed",       },
-X      { T_UNSIGNED,   "unsigned",     },
-X      { 0,            NULL,           },      /* Signal end           */
-X};
-X
-X/*
-X * Test_table[] is used to test for illegal combinations.
-X */
-Xstatic short test_table[] = {
-X      T_FLOAT | T_DOUBLE | T_LONG | T_SHORT,
-X      T_FLOAT | T_DOUBLE | T_CHAR | T_INT,
-X      T_FLOAT | T_DOUBLE | T_SIGNED | T_UNSIGNED,
-X      T_LONG  | T_SHORT  | T_CHAR,
-X      0                                               /* end marker   */
-X};
-X
-X/*
-X * The order of this table is important -- it is also referenced by
-X * the command line processor to allow run-time overriding of the
-X * built-in size values.  The order must not be changed:
-X *    char, short, int, long, float, double (func pointer)
-X */
-XSIZES size_table[] = {
-X    { T_CHAR, S_CHAR,         S_PCHAR         },      /* char         */
-X    { T_SHORT,        S_SINT,         S_PSINT         },      /* short int    */
-X    { T_INT,  S_INT,          S_PINT          },      /* int          */
-X    { T_LONG, S_LINT,         S_PLINT         },      /* long         */
-X    { T_FLOAT,        S_FLOAT,        S_PFLOAT        },      /* float        */
-X    { T_DOUBLE,       S_DOUBLE,       S_PDOUBLE       },      /* double       */
-X    { T_FPTR, 0,              S_PFPTR         },      /* int (*())    */
-X    { 0,      0,              0               },      /* End of table */
-X};
-X\f
-Xint
-Xeval()
-X/*
-X * Evaluate an expression.  Straight-forward operator precedence.
-X * This is called from control() on encountering an #if statement.
-X * It calls the following routines:
-X * evallex    Lexical analyser -- returns the type and value of
-X *            the next input token.
-X * evaleval   Evaluate the current operator, given the values on
-X *            the value stack.  Returns a pointer to the (new)
-X *            value stack.
-X * For compatiblity with older cpp's, this return returns 1 (TRUE)
-X * if a syntax error is detected.
-X */
-X{
-X      register int    op;             /* Current operator             */
-X      register int    *valp;          /* -> value vector              */
-X      register OPTAB  *opp;           /* Operator stack               */
-X      int             prec;           /* Op precedence                */
-X      int             binop;          /* Set if binary op. needed     */
-X      int             op1;            /* Operand from stack           */
-X      int             skip;           /* For short-circuit testing    */
-X      int             value[NEXP];    /* Value stack                  */
-X      OPTAB           opstack[NEXP];  /* Operand stack                */
-X      extern int      *evaleval();    /* Does actual evaluation       */
-X
-X      valp = value;
-X      opp = opstack;
-X      opp->op = OP_END;               /* Mark bottom of stack         */
-X      opp->prec = opdope[OP_END];     /* And its precedence           */
-X      opp->skip = 0;                  /* Not skipping now             */
-X      binop = 0;
-Xagain:        ;
-X#ifdef        DEBUG_EVAL
-X      printf("In #if at again: skip = %d, binop = %d, line is: %s",
-X          opp->skip, binop, infile->bptr);
-X#endif
-X      if ((op = evallex(opp->skip)) == OP_SUB && binop == 0)
-X          op = OP_NEG;                        /* Unary minus          */
-X      else if (op == OP_ADD && binop == 0)
-X          op = OP_PLU;                        /* Unary plus           */
-X      else if (op == OP_FAIL)
-X          return (1);                         /* Error in evallex     */
-X#ifdef        DEBUG_EVAL
-X      printf("op = %s, opdope = %03o, binop = %d, skip = %d\n",
-X          opname[op], opdope[op], binop, opp->skip);
-X#endif
-X      if (op == DIG) {                        /* Value?               */
-X          if (binop != 0) {
-X              cerror("misplaced constant in #if", NULLST);
-X              return (1);
-X          }
-X          else if (valp >= &value[NEXP-1]) {
-X              cerror("#if value stack overflow", NULLST);
-X              return (1);
-X          }
-X          else {
-X#ifdef        DEBUG_EVAL
-X              printf("pushing %d onto value stack[%d]\n",
-X                  evalue, valp - value);
-X#endif
-X              *valp++ = evalue;
-X              binop = 1;
-X          }
-X          goto again;
-X      }
-X      else if (op > OP_END) {
-X          cerror("Illegal #if line", NULLST);
-X          return (1);
-X      }
-X      prec = opdope[op];
-X      if (binop != (prec & 1)) {
-X          cerror("Operator %s in incorrect context", opname[op]);
-X          return (1);
-X      }
-X      binop = (prec & 2) >> 1;
-X      for (;;) {
-X#ifdef        DEBUG_EVAL
-X          printf("op %s, prec %d., stacked op %s, prec %d, skip %d\n",
-X              opname[op], prec, opname[opp->op], opp->prec, opp->skip);
-X#endif
-X          if (prec > opp->prec) {
-X              if (op == OP_LPA)
-X                  prec = OP_RPA_PREC;
-X              else if (op == OP_QUE)
-X                  prec = OP_QUE_PREC;
-X              op1 = opp->skip;                /* Save skip for test   */
-X              /*
-X               * Push operator onto op. stack.
-X               */
-X              opp++;
-X              if (opp >= &opstack[NEXP]) {
-X                  cerror("expression stack overflow at op \"%s\"",
-X                      opname[op]);
-X                  return (1);
-X              }
-X              opp->op = op;
-X              opp->prec = prec;
-X              skip = (valp[-1] != 0);         /* Short-circuit tester */
-X              /*
-X               * Do the short-circuit stuff here.  Short-circuiting
-X               * stops automagically when operators are evaluated.
-X               */
-X              if ((op == OP_ANA && !skip)
-X               || (op == OP_ORO && skip))
-X                  opp->skip = S_ANDOR;        /* And/or skip starts   */
-X              else if (op == OP_QUE)          /* Start of ?: operator */
-X                  opp->skip = (op1 & S_ANDOR) | ((!skip) ? S_QUEST : 0);
-X              else if (op == OP_COL) {        /* : inverts S_QUEST    */
-X                  opp->skip = (op1 & S_ANDOR)
-X                            | (((op1 & S_QUEST) != 0) ? 0 : S_QUEST);
-X              }
-X              else {                          /* Other ops leave      */
-X                  opp->skip = op1;            /*  skipping unchanged. */
-X              }
-X#ifdef        DEBUG_EVAL
-X              printf("stacking %s, valp[-1] == %d at %s",
-X                  opname[op], valp[-1], infile->bptr);
-X              dumpstack(opstack, opp, value, valp);
-X#endif
-X              goto again;
-X          }
-X          /*
-X           * Pop operator from op. stack and evaluate it.
-X           * End of stack and '(' are specials.
-X           */
-X          skip = opp->skip;                   /* Remember skip value  */
-X          switch ((op1 = opp->op)) {          /* Look at stacked op   */
-X          case OP_END:                        /* Stack end marker     */
-X              if (op == OP_EOE)
-X                  return (valp[-1]);          /* Finished ok.         */
-X              goto again;                     /* Read another op.     */
-X
-X          case OP_LPA:                        /* ( on stack           */
-X              if (op != OP_RPA) {             /* Matches ) on input   */
-X                  cerror("unbalanced paren's, op is \"%s\"", opname[op]);
-X                  return (1);
-X              }
-X              opp--;                          /* Unstack it           */
-X              /* goto again;                  -- Fall through         */
-X
-X          case OP_QUE:
-X              goto again;                     /* Evaluate true expr.  */
-X
-X          case OP_COL:                        /* : on stack.          */
-X              opp--;                          /* Unstack :            */
-X              if (opp->op != OP_QUE) {        /* Matches ? on stack?  */
-X                  cerror("Misplaced '?' or ':', previous operator is %s",
-X                      opname[opp->op]);
-X                  return (1);
-X              }
-X              /*
-X               * Evaluate op1.
-X               */
-X          default:                            /* Others:              */
-X              opp--;                          /* Unstack the operator */
-X#ifdef        DEBUG_EVAL
-X              printf("Stack before evaluation of %s\n", opname[op1]);
-X              dumpstack(opstack, opp, value, valp);
-X#endif
-X              valp = evaleval(valp, op1, skip);
-X#ifdef        DEBUG_EVAL
-X              printf("Stack after evaluation\n");
-X              dumpstack(opstack, opp, value, valp);
-X#endif
-X          }                                   /* op1 switch end       */
-X      }                                       /* Stack unwind loop    */
-X}
-X\f
-XFILE_LOCAL int
-Xevallex(skip)
-Xint           skip;           /* TRUE if short-circuit evaluation     */
-X/*
-X * Return next eval operator or value.  Called from eval().  It
-X * calls a special-purpose routines for 'char' strings and
-X * numeric values:
-X * evalchar   called to evaluate 'x'
-X * evalnum    called to evaluate numbers.
-X */
-X{
-X      register int    c, c1, t;
-X
-Xagain:  do {                                  /* Collect the token    */
-X          c = skipws();
-X          if ((c = macroid(c)) == EOF_CHAR || c == '\n') {
-X              unget();
-X              return (OP_EOE);                /* End of expression    */
-X          }
-X      } while ((t = type[c]) == LET && catenate());
-X      if (t == INV) {                         /* Total nonsense       */
-X          if (!skip) {
-X              if (isascii(c) && isprint(c))
-X                  cierror("illegal character '%c' in #if", c);
-X              else
-X                  cierror("illegal character (%d decimal) in #if", c);
-X          }
-X          return (OP_FAIL);
-X      }
-X      else if (t == QUO) {                    /* ' or "               */
-X          if (c == '\'') {                    /* Character constant   */
-X              evalue = evalchar(skip);        /* Somewhat messy       */
-X#ifdef        DEBUG_EVAL
-X              printf("evalchar returns %d.\n", evalue);
-X#endif
-X              return (DIG);                   /* Return a value       */
-X          }
-X          cerror("Can't use a string in an #if", NULLST);
-X          return (OP_FAIL);
-X      }
-X      else if (t == LET) {                    /* ID must be a macro   */
-X          if (streq(token, "defined")) {      /* Or defined name      */
-X              c1 = c = skipws();
-X              if (c == '(')                   /* Allow defined(name)  */
-X                  c = skipws();
-X              if (type[c] == LET) {
-X                  evalue = (lookid(c) != NULL);
-X                  if (c1 != '('               /* Need to balance      */
-X                   || skipws() == ')')        /* Did we balance?      */
-X                      return (DIG);           /* Parsed ok            */
-X              }
-X              cerror("Bad #if ... defined() syntax", NULLST);
-X              return (OP_FAIL);
-X          }
-X          else if (streq(token, "sizeof"))    /* New sizeof hackery   */
-X              return (dosizeof());            /* Gets own routine     */
-X          /*
-X           * The Draft ANSI C Standard says that an undefined symbol
-X           * in an #if has the value zero.  We are a bit pickier,
-X           * warning except where the programmer was careful to write
-X           *          #if defined(foo) ? foo : 0
-X           */
-X#ifdef VERBOSE
-X           if (!skip)
-X              cwarn("undefined symbol \"%s\" in #if, 0 used", token);
-X#endif
-X          evalue = 0;
-X          return (DIG);
-X      }
-X      else if (t == DIG) {                    /* Numbers are harder   */
-X          evalue = evalnum(c);
-X#ifdef        DEBUG_EVAL
-X          printf("evalnum returns %d.\n", evalue);
-X#endif
-X      }
-X      else if (strchr("!=<>&|\\", c) != NULL) {
-X          /*
-X           * Process a possible multi-byte lexeme.
-X           */
-X          c1 = cget();                        /* Peek at next char    */
-X          switch (c) {
-X          case '!':
-X              if (c1 == '=')
-X                  return (OP_NE);
-X              break;
-X
-X          case '=':
-X              if (c1 != '=') {                /* Can't say a=b in #if */
-X                  unget();
-X                  cerror("= not allowed in #if", NULLST);
-X                  return (OP_FAIL);
-X              }
-X              return (OP_EQ);
-X
-X          case '>':
-X          case '<':
-X              if (c1 == c)
-X                  return ((c == '<') ? OP_ASL : OP_ASR);
-X              else if (c1 == '=')
-X                  return ((c == '<') ? OP_LE  : OP_GE);
-X              break;
-X
-X          case '|':
-X          case '&':
-X              if (c1 == c)
-X                  return ((c == '|') ? OP_ORO : OP_ANA);
-X              break;
-X
-X          case '\\':
-X              if (c1 == '\n')                 /* Multi-line if        */
-X                  goto again;
-X              cerror("Unexpected \\ in #if", NULLST);
-X              return (OP_FAIL);
-X          }
-X          unget();
-X      }
-X      return (t);
-X}
-X\f
-XFILE_LOCAL int
-Xdosizeof()
-X/*
-X * Process the sizeof (basic type) operation in an #if string.
-X * Sets evalue to the size and returns
-X *    DIG             success
-X *    OP_FAIL         bad parse or something.
-X */
-X{
-X      register int    c;
-X      register TYPES  *tp;
-X      register SIZES  *sizp;
-X      register short  *testp;
-X      short           typecode;
-X
-X      if ((c = skipws()) != '(')
-X          goto nogood;
-X      /*
-X       * Scan off the tokens.
-X       */
-X      typecode = 0;
-X      while ((c = skipws())) {
-X          if ((c = macroid(c)) == EOF_CHAR || c == '\n')
-X              goto nogood;                    /* End of line is a bug */
-X          else if (c == '(') {                /* thing (*)() func ptr */
-X              if (skipws() == '*'
-X               && skipws() == ')') {          /* We found (*)         */
-X                  if (skipws() != '(')        /* Let () be optional   */
-X                      unget();
-X                  else if (skipws() != ')')
-X                      goto nogood;
-X                  typecode |= T_FPTR;         /* Function pointer     */
-X              }
-X              else {                          /* Junk is a bug        */
-X                  goto nogood;
-X              }
-X          }
-X          else if (type[c] != LET)            /* Exit if not a type   */
-X              break;
-X          else if (!catenate()) {             /* Maybe combine tokens */
-X              /*
-X               * Look for this unexpandable token in basic_types.
-X               * The code accepts "int long" as well as "long int"
-X               * which is a minor bug as bugs go (and one shared with
-X               * a lot of C compilers).
-X               */
-X              for (tp = basic_types; tp->name != NULLST; tp++) {
-X                  if (streq(token, tp->name))
-X                      break;
-X              }
-X              if (tp->name == NULLST) {
-X                  cerror("#if sizeof, unknown type \"%s\"", token);
-X                  return (OP_FAIL);
-X              }
-X              typecode |= tp->type;           /* Or in the type bit   */
-X          }
-X      }
-X      /*
-X       * We are at the end of the type scan.  Chew off '*' if necessary.
-X       */
-X      if (c == '*') {
-X          typecode |= T_PTR;
-X          c = skipws();
-X      }
-X      if (c == ')') {                         /* Last syntax check    */
-X          for (testp = test_table; *testp != 0; testp++) {
-X              if (!bittest(typecode & *testp)) {
-X                  cerror("#if ... sizeof: illegal type combination", NULLST);
-X                  return (OP_FAIL);
-X              }
-X          }
-X          /*
-X           * We assume that all function pointers are the same size:
-X           *          sizeof (int (*)()) == sizeof (float (*)())
-X           * We assume that signed and unsigned don't change the size:
-X           *          sizeof (signed int) == (sizeof unsigned int)
-X           */
-X          if ((typecode & T_FPTR) != 0)       /* Function pointer     */
-X              typecode = T_FPTR | T_PTR;
-X          else {                              /* Var or var * datum   */
-X              typecode &= ~(T_SIGNED | T_UNSIGNED);
-X              if ((typecode & (T_SHORT | T_LONG)) != 0)
-X                  typecode &= ~T_INT;
-X          }
-X          if ((typecode & ~T_PTR) == 0) {
-X              cerror("#if sizeof() error, no type specified", NULLST);
-X              return (OP_FAIL);
-X          }
-X          /*
-X           * Exactly one bit (and possibly T_PTR) may be set.
-X           */
-X          for (sizp = size_table; sizp->bits != 0; sizp++) {
-X              if ((typecode & ~T_PTR) == sizp->bits) {
-X                  evalue = ((typecode & T_PTR) != 0)
-X                      ? sizp->psize : sizp->size;
-X                  return (DIG);
-X              }
-X          }                                   /* We shouldn't fail    */
-X          cierror("#if ... sizeof: bug, unknown type code 0x%x", typecode);
-X          return (OP_FAIL);
-X      }
-X
-Xnogood:       unget();
-X      cerror("#if ... sizeof() syntax error", NULLST);
-X      return (OP_FAIL);
-X}
-X
-XFILE_LOCAL int
-Xbittest(value)
-X/*
-X * TRUE if value is zero or exactly one bit is set in value.
-X */
-X{
-X#if (4096 & ~(-4096)) == 0
-X      return ((value & ~(-value)) == 0);
-X#else
-X      /*
-X       * Do it the hard way (for non 2's complement machines)
-X       */
-X      return (value == 0 || value ^ (value - 1) == (value * 2 - 1));
-X#endif
-X}
-X\f
-XFILE_LOCAL int
-Xevalnum(c)
-Xregister int  c;
-X/*
-X * Expand number for #if lexical analysis.  Note: evalnum recognizes
-X * the unsigned suffix, but only returns a signed int value.
-X */
-X{
-X      register int    value;
-X      register int    base;
-X      register int    c1;
-X
-X      if (c != '0')
-X          base = 10;
-X      else if ((c = cget()) == 'x' || c == 'X') {
-X              base = 16;
-X              c = cget();
-X      }
-X      else base = 8;
-X      value = 0;
-X      for (;;) {
-X          c1 = c;
-X          if (isascii(c) && isupper(c1))
-X              c1 = tolower(c1);
-X          if (c1 >= 'a')
-X              c1 -= ('a' - 10);
-X          else c1 -= '0';
-X          if (c1 < 0 || c1 >= base)
-X              break;
-X          value *= base;
-X          value += c1;
-X          c = cget();
-X      }
-X      if (c == 'u' || c == 'U')       /* Unsigned nonsense            */
-X          c = cget();
-X      unget();
-X      return (value);
-X}
-X\f
-XFILE_LOCAL int
-Xevalchar(skip)
-Xint           skip;           /* TRUE if short-circuit evaluation     */
-X/*
-X * Get a character constant
-X */
-X{
-X      register int    c;
-X      register int    value;
-X      register int    count;
-X
-X      instring = TRUE;
-X      if ((c = cget()) == '\\') {
-X          switch ((c = cget())) {
-X          case 'a':                           /* New in Standard      */
-X#if ('a' == '\a' || '\a' == ALERT)
-X              value = ALERT;                  /* Use predefined value */
-X#else
-X              value = '\a';                   /* Use compiler's value */
-X#endif
-X              break;
-X
-X          case 'b':
-X              value = '\b';
-X              break;
-X
-X          case 'f':
-X              value = '\f';
-X              break;
-X
-X          case 'n':
-X              value = '\n';
-X              break;
-X
-X          case 'r':
-X              value = '\r';
-X              break;
-X
-X          case 't':
-X              value = '\t';
-X              break;
-X
-X          case 'v':                           /* New in Standard      */
-X#if ('v' == '\v' || '\v' == VT)
-X              value = VT;                     /* Use predefined value */
-X#else
-X              value = '\v';                   /* Use compiler's value */
-X#endif
-X              break;
-X
-X          case 'x':                           /* '\xFF'               */
-X              count = 3;
-X              value = 0;
-X              while ((((c = get()) >= '0' && c <= '9')
-X                   || (c >= 'a' && c <= 'f')
-X                   || (c >= 'A' && c <= 'F'))
-X                  && (--count >= 0)) {
-X                      value *= 16;
-X                      value += (c <= '9') ? (c - '0') : ((c & 0xF) + 9);
-X              }
-X              unget();
-X              break;
-X
-X          default:
-X              if (c >= '0' && c <= '7') {
-X                  count = 3;
-X                  value = 0;
-X                  while (c >= '0' && c <= '7' && --count >= 0) {
-X                      value *= 8;
-X                      value += (c - '0');
-X                      c = get();
-X                  }
-X                  unget();
-X              }
-X              else value = c;
-X              break;
-X          }
-X      }
-X      else if (c == '\'')
-X          value = 0;
-X      else value = c;
-X      /*
-X       * We warn on multi-byte constants and try to hack
-X       * (big|little)endian machines.
-X       */
-X#if BIG_ENDIAN
-X      count = 0;
-X#endif
-X      while ((c = get()) != '\'' && c != EOF_CHAR && c != '\n') {
-X          if (!skip)
-X              ciwarn("multi-byte constant '%c' isn't portable", c);
-X#if BIG_ENDIAN
-X          count += BITS_CHAR;
-X          value += (c << count);
-X#else
-X          value <<= BITS_CHAR;
-X          value += c;
-X#endif
-X      }
-X      instring = FALSE;
-X      return (value);
-X}
-X\f
-XFILE_LOCAL int *
-Xevaleval(valp, op, skip)
-Xregister int  *valp;
-Xint           op;
-Xint           skip;           /* TRUE if short-circuit evaluation     */
-X/*
-X * Apply the argument operator to the data on the value stack.
-X * One or two values are popped from the value stack and the result
-X * is pushed onto the value stack.
-X *
-X * OP_COL is a special case.
-X *
-X * evaleval() returns the new pointer to the top of the value stack.
-X */
-X{
-X      register int    v1, v2;
-X
-X      if (isbinary(op))
-X          v2 = *--valp;
-X      v1 = *--valp;
-X#ifdef        DEBUG_EVAL
-X      printf("%s op %s", (isbinary(op)) ? "binary" : "unary",
-X          opname[op]);
-X      if (isbinary(op))
-X          printf(", v2 = %d.", v2);
-X      printf(", v1 = %d.\n", v1);
-X#endif
-X      switch (op) {
-X      case OP_EOE:
-X           break;
-X
-X      case OP_ADD:
-X          v1 += v2;
-X          break;
-X
-X      case OP_SUB:
-X          v1 -= v2;
-X          break;
-X
-X      case OP_MUL:
-X          v1 *= v2;
-X          break;
-X
-X      case OP_DIV:
-X      case OP_MOD:
-X          if (v2 == 0) {
-X              if (!skip) {
-X                  cwarn("%s by zero in #if, zero result assumed",
-X                      (op == OP_DIV) ? "divide" : "mod");
-X              }
-X              v1 = 0;
-X          }
-X          else if (op == OP_DIV)
-X              v1 /= v2;
-X          else
-X              v1 %= v2;
-X          break;
-X
-X      case OP_ASL:
-X          v1 <<= v2;
-X          break;
-X
-X      case OP_ASR:
-X          v1 >>= v2;
-X          break;
-X
-X      case OP_AND:
-X          v1 &= v2;
-X          break;
-X
-X      case OP_OR:
-X          v1 |= v2;
-X          break;
-X
-X      case OP_XOR:
-X          v1 ^= v2;
-X          break;
-X
-X      case OP_EQ:
-X          v1 = (v1 == v2);
-X          break;
-X
-X      case OP_NE:
-X          v1 = (v1 != v2);
-X          break;
-X
-X      case OP_LT:
-X          v1 = (v1 < v2);
-X          break;
-X
-X      case OP_LE:
-X          v1 = (v1 <= v2);
-X          break;
-X
-X      case OP_GE:
-X          v1 = (v1 >= v2);
-X          break;
-X
-X      case OP_GT:
-X          v1 = (v1 > v2);
-X          break;
-X
-X      case OP_ANA:
-X          v1 = (v1 && v2);
-X          break;
-X
-X      case OP_ORO:
-X          v1 = (v1 || v2);
-X          break;
-X
-X      case OP_COL:
-X          /*
-X           * v1 has the "true" value, v2 the "false" value.
-X           * The top of the value stack has the test.
-X           */
-X          v1 = (*--valp) ? v1 : v2;
-X          break;
-X
-X      case OP_NEG:
-X          v1 = (-v1);
-X          break;
-X
-X      case OP_PLU:
-X          break;
-X
-X      case OP_COM:
-X          v1 = ~v1;
-X          break;
-X
-X      case OP_NOT:
-X          v1 = !v1;
-X          break;
-X
-X      default:
-X          cierror("#if bug, operand = %d.", op);
-X          v1 = 0;
-X      }
-X      *valp++ = v1;
-X      return (valp);
-X}
-X\f
-X#ifdef        DEBUG_EVAL
-Xdumpstack(opstack, opp, value, valp)
-XOPTAB         opstack[NEXP];  /* Operand stack                */
-Xregister OPTAB        *opp;           /* Operator stack               */
-Xint           value[NEXP];    /* Value stack                  */
-Xregister int  *valp;          /* -> value vector              */
-X{
-X      printf("index op prec skip name -- op stack at %s", infile->bptr);
-X      while (opp > opstack) {
-X          printf(" [%2d] %2d  %03o    %d %s\n", opp - opstack,
-X              opp->op, opp->prec, opp->skip, opname[opp->op]);
-X          opp--;
-X      }
-X      while (--valp >= value) {
-X          printf("value[%d] = %d\n", (valp - value), *valp);
-X      }
-X}
-X#endif
-X
-END-of-cpp5.c
-echo x - cpp6.c
-sed 's/^X//' >cpp6.c << 'END-of-cpp6.c'
-X/*
-X *                        C P P 6 . C
-X *            S u p p o r t   R o u t i n e s
-X *
-X * Edit History
-X * 25-May-84 MM               Added 8-bit support to type table.
-X * 30-May-84 ARF      sharp() should output filename in quotes
-X * 02-Aug-84 MM               Newline and #line hacking.  sharp() now in cpp1.c
-X * 31-Aug-84 MM               USENET net.sources release
-X * 11-Sep-84 ado/MM   Keepcomments, also line number pathological
-X * 12-Sep-84 ado/MM   bug if comment changes to space and we unget later.
-X * 03-Oct-84 gkr/MM   Fixed scannumber bug for '.e' (as in struct.element).
-X * 04-Oct-84 MM               Added ungetstring() for token concatenation
-X * 08-Oct-84 MM               Yet another attack on number scanning
-X * 31-Oct-84 ado      Parameterized $ in identifiers
-X *  2-Nov-84 MM               Token concatenation is messier than I thought
-X *  6-Dec-84 MM               \<nl> is everywhere invisible.
-X */
-X
-X#include      <stdio.h>
-X#include      <ctype.h>
-X#include      "cppdef.h"
-X#include      "cpp.h"
-X
-X/*
-X * skipnl()   skips over input text to the end of the line.
-X * skipws()   skips over "whitespace" (spaces or tabs), but
-X *            not skip over the end of the line.  It skips over
-X *            TOK_SEP, however (though that shouldn't happen).
-X * scanid()   reads the next token (C identifier) into token[].
-X *            The caller has already read the first character of
-X *            the identifier.  Unlike macroid(), the token is
-X *            never expanded.
-X * macroid()  reads the next token (C identifier) into token[].
-X *            If it is a #defined macro, it is expanded, and
-X *            macroid() returns TRUE, otherwise, FALSE.
-X * catenate() Does the dirty work of token concatenation, TRUE if it did.
-X * scanstring()       Reads a string from the input stream, calling
-X *            a user-supplied function for each character.
-X *            This function may be output() to write the
-X *            string to the output file, or save() to save
-X *            the string in the work buffer.
-X * scannumber()       Reads a C numeric constant from the input stream,
-X *            calling the user-supplied function for each
-X *            character.  (output() or save() as noted above.)
-X * save()     Save one character in the work[] buffer.
-X * savestring()       Saves a string in malloc() memory.
-X * getfile()  Initialize a new FILEINFO structure, called when
-X *            #include opens a new file, or a macro is to be
-X *            expanded.
-X * getmem()   Get a specified number of bytes from malloc memory.
-X * output()   Write one character to stdout (calling putchar) --
-X *            implemented as a function so its address may be
-X *            passed to scanstring() and scannumber().
-X * lookid()   Scans the next token (identifier) from the input
-X *            stream.  Looks for it in the #defined symbol table.
-X *            Returns a pointer to the definition, if found, or NULL
-X *            if not present.  The identifier is stored in token[].
-X * defnedel() Define enter/delete subroutine.  Updates the
-X *            symbol table.
-X * get()      Read the next byte from the current input stream,
-X *            handling end of (macro/file) input and embedded
-X *            comments appropriately.  Note that the global
-X *            instring is -- essentially -- a parameter to get().
-X * cget()     Like get(), but skip over TOK_SEP.
-X * unget()    Push last gotten character back on the input stream.
-X * cerror(), cwarn(), cfatal(), cierror(), ciwarn()
-X *            These routines format an print messages to the user.
-X *            cerror & cwarn take a format and a single string argument.
-X *            cierror & ciwarn take a format and a single int (char) argument.
-X *            cfatal takes a format and a single string argument.
-X */
-X\f
-X/*
-X * This table must be rewritten for a non-Ascii machine.
-X *
-X * Note that several "non-visible" characters have special meaning:
-X * Hex 1D DEF_MAGIC -- a flag to prevent #define recursion.
-X * Hex 1E TOK_SEP   -- a delimiter for token concatenation
-X * Hex 1F COM_SEP   -- a zero-width whitespace for comment concatenation
-X */
-X#if TOK_SEP != 0x1E || COM_SEP != 0x1F || DEF_MAGIC != 0x1D
-X      << error type table isn't correct >>
-X#endif
-X
-X#if OK_DOLLAR
-X#define       DOL     LET
-X#else
-X#define       DOL     000
-X#endif
-X
-Xchar type[256] = {            /* Character type codes    Hex          */
-X   END,   000,   000,   000,   000,   000,   000,   000, /* 00                */
-X   000,   SPA,   000,   000,   000,   000,   000,   000, /* 08                */
-X   000,   000,   000,   000,   000,   000,   000,   000, /* 10                */
-X   000,   000,   000,   000,   000,   LET,   000,   SPA, /* 18                */
-X   SPA,OP_NOT,   QUO,   000,   DOL,OP_MOD,OP_AND,   QUO, /* 20  !"#$%&'       */
-XOP_LPA,OP_RPA,OP_MUL,OP_ADD,   000,OP_SUB,   DOT,OP_DIV, /* 28 ()*+,-./       */
-X   DIG,   DIG,   DIG,   DIG,   DIG,   DIG,   DIG,   DIG, /* 30 01234567       */
-X   DIG,   DIG,OP_COL,   000, OP_LT, OP_EQ, OP_GT,OP_QUE, /* 38 89:;<=>?       */
-X   000,   LET,   LET,   LET,   LET,   LET,   LET,   LET, /* 40 @ABCDEFG       */
-X   LET,   LET,   LET,   LET,   LET,   LET,   LET,   LET, /* 48 HIJKLMNO       */
-X   LET,   LET,   LET,   LET,   LET,   LET,   LET,   LET, /* 50 PQRSTUVW       */
-X   LET,   LET,   LET,   000,   BSH,   000,OP_XOR,   LET, /* 58 XYZ[\]^_       */
-X   000,   LET,   LET,   LET,   LET,   LET,   LET,   LET, /* 60 `abcdefg       */
-X   LET,   LET,   LET,   LET,   LET,   LET,   LET,   LET, /* 68 hijklmno       */
-X   LET,   LET,   LET,   LET,   LET,   LET,   LET,   LET, /* 70 pqrstuvw       */
-X   LET,   LET,   LET,   000, OP_OR,   000,OP_NOT,   000, /* 78 xyz{|}~        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X   000,   000,   000,   000,   000,   000,   000,   000, /*   80 .. FF        */
-X};
-X\f
-Xskipnl()
-X/*
-X * Skip to the end of the current input line.
-X */
-X{
-X      register int            c;
-X
-X      do {                            /* Skip to newline      */
-X          c = get();
-X      } while (c != '\n' && c != EOF_CHAR);
-X}
-X
-Xint
-Xskipws()
-X/*
-X * Skip over whitespace
-X */
-X{
-X      register int            c;
-X
-X      do {                            /* Skip whitespace      */
-X          c = get();
-X#if COMMENT_INVISIBLE
-X      } while (type[c] == SPA || c == COM_SEP);
-X#else
-X      } while (type[c] == SPA);
-X#endif
-X      return (c);
-X}
-X\f
-Xscanid(c)
-Xregister int  c;                              /* First char of id     */
-X/*
-X * Get the next token (an id) into the token buffer.
-X * Note: this code is duplicated in lookid().
-X * Change one, change both.
-X */
-X{
-X      register char   *bp;
-X
-X      if (c == DEF_MAGIC)                     /* Eat the magic token  */
-X          c = get();                          /* undefiner.           */
-X      bp = token;
-X      do {
-X          if (bp < &token[IDMAX])             /* token dim is IDMAX+1 */
-X              *bp++ = c;
-X          c = get();
-X      } while (type[c] == LET || type[c] == DIG);
-X      unget();
-X      *bp = EOS;
-X}
-X
-Xint
-Xmacroid(c)
-Xregister int          c;
-X/*
-X * If c is a letter, scan the id.  if it's #defined, expand it and scan
-X * the next character and try again.
-X *
-X * Else, return the character.  If type[c] is a LET, the token is in token.
-X */
-X{
-X      register DEFBUF *dp;
-X
-X      if (infile != NULL && infile->fp != NULL)
-X          recursion = 0;
-X      while (type[c] == LET && (dp = lookid(c)) != NULL) {
-X          expand(dp);
-X          c = get();
-X      }
-X      return (c);
-X}
-X\f
-Xint
-Xcatenate()
-X/*
-X * A token was just read (via macroid).
-X * If the next character is TOK_SEP, concatenate the next token
-X * return TRUE -- which should recall macroid after refreshing
-X * macroid's argument.  If it is not TOK_SEP, unget() the character
-X * and return FALSE.
-X */
-X{
-X      register int            c;
-X      register char           *token1;
-X
-X#if OK_CONCAT
-X      if (get() != TOK_SEP) {                 /* Token concatenation  */
-X          unget();
-X          return (FALSE);
-X      }
-X      else {
-X          token1 = savestring(token);         /* Save first token     */
-X          c = macroid(get());                 /* Scan next token      */
-X          switch(type[c]) {                   /* What was it?         */
-X          case LET:                           /* An identifier, ...   */
-X              if (strlen(token1) + strlen(token) >= NWORK)
-X                  cfatal("work buffer overflow doing %s #", token1);
-X              sprintf(work, "%s%s", token1, token);
-X              break;
-X
-X          case DIG:                           /* A digit string       */
-X              strcpy(work, token1);
-X              workp = work + strlen(work);
-X              do {
-X                  save(c);
-X              } while ((c = get()) != TOK_SEP);
-X              /*
-X               * The trailing TOK_SEP is no longer needed.
-X               */
-X              save(EOS);
-X              break;
-X
-X          default:                            /* An error, ...        */
-X              if (isprint(c))
-X                  cierror("Strange character '%c' after #", c);
-X              else
-X                  cierror("Strange character (%d.) after #", c);
-X              strcpy(work, token1);
-X              unget();
-X              break;
-X          }
-X          /*
-X           * work has the concatenated token and token1 has
-X           * the first token (no longer needed).  Unget the
-X           * new (concatenated) token after freeing token1.
-X           * Finally, setup to read the new token.
-X           */
-X          free(token1);                       /* Free up memory       */
-X          ungetstring(work);                  /* Unget the new thing, */
-X          return (TRUE);
-X      }
-X#else
-X      return (FALSE);                         /* Not supported        */
-X#endif
-X}
-X\f
-Xint
-Xscanstring(delim, outfun)
-Xregister int  delim;                  /* ' or "                       */
-Xint           (*outfun)();            /* Output function              */
-X/*
-X * Scan off a string.  Warning if terminated by newline or EOF.
-X * outfun() outputs the character -- to a buffer if in a macro.
-X * TRUE if ok, FALSE if error.
-X */
-X{
-X      register int            c;
-X
-X      instring = TRUE;                /* Don't strip comments         */
-X      (*outfun)(delim);
-X      while ((c = get()) != delim
-X           && c != '\n'
-X           && c != EOF_CHAR) {
-X          (*outfun)(c);
-X          if (c == '\\')
-X              (*outfun)(get());
-X      }
-X      instring = FALSE;
-X      if (c == delim) {
-X          (*outfun)(c);
-X          return (TRUE);
-X      }
-X      else {
-X          cerror("Unterminated string", NULLST);
-X          unget();
-X          return (FALSE);
-X      }
-X}
-X\f
-Xscannumber(c, outfun)
-Xregister int  c;                              /* First char of number */
-Xregister int  (*outfun)();                    /* Output/store func    */
-X/*
-X * Process a number.  We know that c is from 0 to 9 or dot.
-X * Algorithm from Dave Conroy's Decus C.
-X */
-X{
-X      register int    radix;                  /* 8, 10, or 16         */
-X      int             expseen;                /* 'e' seen in floater  */
-X      int             signseen;               /* '+' or '-' seen      */
-X      int             octal89;                /* For bad octal test   */
-X      int             dotflag;                /* TRUE if '.' was seen */
-X
-X      expseen = FALSE;                        /* No exponent seen yet */
-X      signseen = TRUE;                        /* No +/- allowed yet   */
-X      octal89 = FALSE;                        /* No bad octal yet     */
-X      radix = 10;                             /* Assume decimal       */
-X      if ((dotflag = (c == '.')) != FALSE) {  /* . something?         */
-X          (*outfun)('.');                     /* Always out the dot   */
-X          if (type[(c = get())] != DIG) {     /* If not a float numb, */
-X              unget();                        /* Rescan strange char  */
-X              return;                         /* All done for now     */
-X          }
-X      }                                       /* End of float test    */
-X      else if (c == '0') {                    /* Octal or hex?        */
-X          (*outfun)(c);                       /* Stuff initial zero   */
-X          radix = 8;                          /* Assume it's octal    */
-X          c = get();                          /* Look for an 'x'      */
-X          if (c == 'x' || c == 'X') {         /* Did we get one?      */
-X              radix = 16;                     /* Remember new radix   */
-X              (*outfun)(c);                   /* Stuff the 'x'        */
-X              c = get();                      /* Get next character   */
-X          }
-X      }
-X      for (;;) {                              /* Process curr. char.  */
-X          /*
-X           * Note that this algorithm accepts "012e4" and "03.4"
-X           * as legitimate floating-point numbers.
-X           */
-X          if (radix != 16 && (c == 'e' || c == 'E')) {
-X              if (expseen)                    /* Already saw 'E'?     */
-X                  break;                      /* Exit loop, bad nbr.  */
-X              expseen = TRUE;                 /* Set exponent seen    */
-X              signseen = FALSE;               /* We can read '+' now  */
-X              radix = 10;                     /* Decimal exponent     */
-X          }
-X          else if (radix != 16 && c == '.') {
-X              if (dotflag)                    /* Saw dot already?     */
-X                  break;                      /* Exit loop, two dots  */
-X              dotflag = TRUE;                 /* Remember the dot     */
-X              radix = 10;                     /* Decimal fraction     */
-X          }
-X          else if (c == '+' || c == '-') {    /* 1.0e+10              */
-X              if (signseen)                   /* Sign in wrong place? */
-X                  break;                      /* Exit loop, not nbr.  */
-X              /* signseen = TRUE; */          /* Remember we saw it   */
-X          }
-X          else {                              /* Check the digit      */
-X              switch (c) {
-X              case '8': case '9':             /* Sometimes wrong      */
-X                  octal89 = TRUE;             /* Do check later       */
-X              case '0': case '1': case '2': case '3':
-X              case '4': case '5': case '6': case '7':
-X                  break;                      /* Always ok            */
-X
-X              case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-X              case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-X                  if (radix == 16)            /* Alpha's are ok only  */
-X                      break;                  /* if reading hex.      */
-X              default:                        /* At number end        */
-X                  goto done;                  /* Break from for loop  */
-X              }                               /* End of switch        */
-X          }                                   /* End general case     */
-X          (*outfun)(c);                       /* Accept the character */
-X          signseen = TRUE;                    /* Don't read sign now  */
-X          c = get();                          /* Read another char    */
-X      }                                       /* End of scan loop     */
-X      /*
-X       * When we break out of the scan loop, c contains the first
-X       * character (maybe) not in the number.  If the number is an
-X       * integer, allow a trailing 'L' for long and/or a trailing 'U'
-X       * for unsigned.  If not those, push the trailing character back
-X       * on the input stream.  Floating point numbers accept a trailing
-X       * 'L' for "long double".
-X       */
-Xdone: if (dotflag || expseen) {               /* Floating point?      */
-X          if (c == 'l' || c == 'L') {
-X              (*outfun)(c);
-X              c = get();                      /* Ungotten later       */
-X          }
-X      }
-X      else {                                  /* Else it's an integer */
-X          /*
-X           * We know that dotflag and expseen are both zero, now:
-X           * dotflag signals "saw 'L'", and
-X           * expseen signals "saw 'U'".
-X           */
-X          for (;;) {
-X              switch (c) {
-X              case 'l':
-X              case 'L':
-X                  if (dotflag)
-X                      goto nomore;
-X                  dotflag = TRUE;
-X                  break;
-X
-X              case 'u':
-X              case 'U':
-X                  if (expseen)
-X                      goto nomore;
-X                  expseen = TRUE;
-X                  break;
-X
-X              default:
-X                  goto nomore;
-X              }
-X              (*outfun)(c);                   /* Got 'L' or 'U'.      */
-X              c = get();                      /* Look at next, too.   */
-X          }
-X      }
-Xnomore:       unget();                                /* Not part of a number */
-X      if (octal89 && radix == 8)
-X          cwarn("Illegal digit in octal number", NULLST);
-X}
-X\f
-Xsave(c)
-Xregister int  c;
-X{
-X      if (workp >= &work[NWORK])
-X          cfatal("Work buffer overflow", NULLST);
-X      else *workp++ = c;
-X}
-X
-Xchar *
-Xsavestring(text)
-Xchar          *text;
-X/*
-X * Store a string into free memory.
-X */
-X{
-X      register char   *result;
-X
-X      result = getmem(strlen(text) + 1);
-X      strcpy(result, text);
-X      return (result);
-X}
-X
-XFILEINFO      *
-Xgetfile(bufsize, name)
-Xint           bufsize;                /* Line or define buffer size   */
-Xchar          *name;                  /* File or macro name string    */
-X/*
-X * Common FILEINFO buffer initialization for a new file or macro.
-X */
-X{
-X      register FILEINFO       *file;
-X      register int            size;
-X
-X      size = strlen(name);                    /* File/macro name      */
-X      file = (FILEINFO *) getmem(sizeof (FILEINFO) + bufsize + size);
-X      file->parent = infile;                  /* Chain files together */
-X      file->fp = NULL;                        /* No file yet          */
-X      file->filename = savestring(name);      /* Save file/macro name */
-X      file->progname = NULL;                  /* No #line seen yet    */
-X      file->unrecur = 0;                      /* No macro fixup       */
-X      file->bptr = file->buffer;              /* Initialize line ptr  */
-X      file->buffer[0] = EOS;                  /* Force first read     */
-X      file->line = 0;                         /* (Not used just yet)  */
-X      if (infile != NULL)                     /* If #include file     */
-X          infile->line = line;                /* Save current line    */
-X      infile = file;                          /* New current file     */
-X      line = 1;                               /* Note first line      */
-X      return (file);                          /* All done.            */
-X}
-X
-Xchar *
-Xgetmem(size)
-Xint           size;
-X/*
-X * Get a block of free memory.
-X */
-X{
-X      register char   *result;
-X      extern char     *malloc();
-X
-X      if ((result = malloc((unsigned) size)) == NULL)
-X          cfatal("Out of memory", NULLST);
-X      return (result);
-X}
-X\f
-X/*
-X *                    C P P   S y m b o l   T a b l e s
-X */
-X
-X/*
-X * SBSIZE defines the number of hash-table slots for the symbol table.
-X * It must be a power of 2.
-X */
-X#ifndef       SBSIZE
-X#define       SBSIZE  64
-X#endif
-X#define       SBMASK  (SBSIZE - 1)
-X#if (SBSIZE ^ SBMASK) != ((SBSIZE * 2) - 1)
-X      << error, SBSIZE must be a power of 2 >>
-X#endif
-X
-Xstatic DEFBUF *symtab[SBSIZE];        /* Symbol table queue headers   */
-X
-XDEFBUF *
-Xlookid(c)
-Xint   c;                              /* First character of token     */
-X/*
-X * Look for the next token in the symbol table.  Returns token in "token".
-X * If found, returns the table pointer;  Else returns NULL.
-X */
-X{
-X      register int            nhash;
-X      register DEFBUF         *dp;
-X      register char           *np;
-X      int                     temp;
-X      int                     isrecurse;      /* For #define foo foo  */
-X
-X      np = token;
-X      nhash = 0;
-X      if ((isrecurse = (c == DEF_MAGIC)))     /* If recursive macro   */
-X          c = get();                          /* hack, skip DEF_MAGIC */
-X      do {
-X          if (np < &token[IDMAX]) {           /* token dim is IDMAX+1 */
-X              *np++ = c;                      /* Store token byte     */
-X              nhash += c;                     /* Update hash value    */
-X          }
-X          c = get();                          /* And get another byte */
-X      } while (type[c] == LET || type[c] == DIG);
-X      unget();                                /* Rescan terminator    */
-X      *np = EOS;                              /* Terminate token      */
-X      if (isrecurse)                          /* Recursive definition */
-X          return (NULL);                      /* undefined just now   */
-X      nhash += (np - token);                  /* Fix hash value       */
-X      dp = symtab[nhash & SBMASK];            /* Starting bucket      */
-X      while (dp != (DEFBUF *) NULL) {         /* Search symbol table  */
-X          if (dp->hash == nhash               /* Fast precheck        */
-X           && (temp = strcmp(dp->name, token)) >= 0)
-X              break;
-X          dp = dp->link;                      /* Nope, try next one   */
-X      }
-X      return ((temp == 0) ? dp : NULL);
-X}
-X\f
-XDEFBUF *
-Xdefendel(name, delete)
-Xchar          *name;
-Xint           delete;                 /* TRUE to delete a symbol      */
-X/*
-X * Enter this name in the lookup table (delete = FALSE)
-X * or delete this name (delete = TRUE).
-X * Returns a pointer to the define block (delete = FALSE)
-X * Returns NULL if the symbol wasn't defined (delete = TRUE).
-X */
-X{
-X      register DEFBUF         *dp;
-X      register DEFBUF         **prevp;
-X      register char           *np;
-X      int                     nhash;
-X      int                     temp;
-X      int                     size;
-X
-X      for (nhash = 0, np = name; *np != EOS;)
-X          nhash += *np++;
-X      size = (np - name);
-X      nhash += size;
-X      prevp = &symtab[nhash & SBMASK];
-X      while ((dp = *prevp) != (DEFBUF *) NULL) {
-X          if (dp->hash == nhash
-X           && (temp = strcmp(dp->name, name)) >= 0) {
-X              if (temp > 0)
-X                  dp = NULL;                  /* Not found            */
-X              else {
-X                  *prevp = dp->link;          /* Found, unlink and    */
-X                  if (dp->repl != NULL)       /* Free the replacement */
-X                      free(dp->repl);         /* if any, and then     */
-X                  free((char *) dp);          /* Free the symbol      */
-X              }
-X              break;
-X          }
-X          prevp = &dp->link;
-X      }
-X      if (!delete) {
-X          dp = (DEFBUF *) getmem(sizeof (DEFBUF) + size);
-X          dp->link = *prevp;
-X          *prevp = dp;
-X          dp->hash = nhash;
-X          dp->repl = NULL;
-X          dp->nargs = 0;
-X          strcpy(dp->name, name);
-X      }
-X      return (dp);
-X}
-X\f
-X#if DEBUG
-X
-Xdumpdef(why)
-Xchar          *why;
-X{
-X      register DEFBUF         *dp;
-X      register DEFBUF         **syp;
-X
-X      printf("CPP symbol table dump %s\n", why);
-X      for (syp = symtab; syp < &symtab[SBSIZE]; syp++) {
-X          if ((dp = *syp) != (DEFBUF *) NULL) {
-X              printf("symtab[%d]\n", (syp - symtab));
-X              do {
-X                  dumpadef((char *) NULL, dp);
-X              } while ((dp = dp->link) != (DEFBUF *) NULL);
-X          }
-X      }
-X}
-X
-Xdumpadef(why, dp)
-Xchar          *why;                   /* Notation                     */
-Xregister DEFBUF       *dp;
-X{
-X      register char           *cp;
-X      register int            c;
-X
-X      printf(" \"%s\" [%d]", dp->name, dp->nargs);
-X      if (why != NULL)
-X          printf(" (%s)", why);
-X      if (dp->repl != NULL) {
-X          printf(" => ");
-X          for (cp = dp->repl; (c = *cp++ & 0xFF) != EOS;) {
-X              if (c >= MAC_PARM && c <= (MAC_PARM + PAR_MAC))
-X                  printf("<%d>", c - MAC_PARM);
-X              else if (isprint(c) || c == '\n' || c == '\t')
-X                  putchar(c);
-X              else if (c < ' ')
-X                  printf("<^%c>", c + '@');
-X              else
-X                  printf("<\\0%o>", c);
-X          }
-X      }
-X      else {
-X          printf(", no replacement.");
-X      }
-X      putchar('\n');
-X}
-X#endif
-X\f
-X/*
-X *                    G E T
-X */
-X
-Xint
-Xget()
-X/*
-X * Return the next character from a macro or the current file.
-X * Handle end of file from #include files.
-X */
-X{
-X      register int            c;
-X      register FILEINFO       *file;
-X      register int            popped;         /* Recursion fixup      */
-X
-X      popped = 0;
-Xget_from_file:
-X      if ((file = infile) == NULL)
-X          return (EOF_CHAR);
-Xnewline:
-X#if 0
-X      printf("get(%s), recursion %d, line %d, bptr = %d, buffer \"%s\"\n",
-X          file->filename, recursion, line,
-X          file->bptr - file->buffer, file->buffer);
-X#endif
-X      /*
-X       * Read a character from the current input line or macro.
-X       * At EOS, either finish the current macro (freeing temp.
-X       * storage) or read another line from the current input file.
-X       * At EOF, exit the current file (#include) or, at EOF from
-X       * the cpp input file, return EOF_CHAR to finish processing.
-X       */
-X      if ((c = *file->bptr++ & 0xFF) == EOS) {
-X          /*
-X           * Nothing in current line or macro.  Get next line (if
-X           * input from a file), or do end of file/macro processing.
-X           * In the latter case, jump back to restart from the top.
-X           */
-X          if (file->fp == NULL) {             /* NULL if macro        */
-X              popped++;
-X              recursion -= file->unrecur;
-X              if (recursion < 0)
-X                  recursion = 0;
-X              infile = file->parent;          /* Unwind file chain    */
-X          }
-X          else {                              /* Else get from a file */
-X              if ((file->bptr = fgets(file->buffer, NBUFF, file->fp))
-X                      != NULL) {
-X#if DEBUG
-X                  if (debug > 1) {            /* Dump it to stdout    */
-X                      printf("\n#line %d (%s), %s",
-X                          line, file->filename, file->buffer);
-X                  }
-X#endif
-X                  goto newline;               /* process the line     */
-X              }
-X              else {
-X                  fclose(file->fp);           /* Close finished file  */
-X                  if ((infile = file->parent) != NULL) {
-X                      /*
-X                       * There is an "ungotten" newline in the current
-X                       * infile buffer (set there by doinclude() in
-X                       * cpp1.c).  Thus, we know that the mainline code
-X                       * is skipping over blank lines and will do a
-X                       * #line at its convenience.
-X                       */
-X                      wrongline = TRUE;       /* Need a #line now     */
-X                  }
-X              }
-X          }
-X          /*
-X           * Free up space used by the (finished) file or macro and
-X           * restart input from the parent file/macro, if any.
-X           */
-X          free(file->filename);               /* Free name and        */
-X          if (file->progname != NULL)         /* if a #line was seen, */
-X              free(file->progname);           /* free it, too.        */
-X          free((char *) file);                /* Free file space      */
-X          if (infile == NULL)                 /* If at end of file    */
-X              return (EOF_CHAR);              /* Return end of file   */
-X          line = infile->line;                /* Reset line number    */
-X          goto get_from_file;                 /* Get from the top.    */
-X      }
-X      /*
-X       * Common processing for the new character.
-X       */
-X      if (c == DEF_MAGIC && file->fp != NULL) /* Don't allow delete   */
-X          goto newline;                       /* from a file          */
-X      if (file->parent != NULL) {             /* Macro or #include    */
-X          if (popped != 0)
-X              file->parent->unrecur += popped;
-X          else {
-X              recursion -= file->parent->unrecur;
-X              if (recursion < 0)
-X                  recursion = 0;
-X              file->parent->unrecur = 0;
-X          }
-X      }
-X      if (c == '\n')                          /* Maintain current     */
-X          ++line;                             /* line counter         */
-X      if (instring)                           /* Strings just return  */
-X          return (c);                         /* the character.       */
-X      else if (c == '/') {                    /* Comment?             */
-X          instring = TRUE;                    /* So get() won't loop  */
-X          if ((c = get()) != '*') {           /* Next byte '*'?       */
-X              instring = FALSE;               /* Nope, no comment     */
-X              unget();                        /* Push the char. back  */
-X              return ('/');                   /* Return the slash     */
-X          }
-X          if (keepcomments) {                 /* If writing comments  */
-X              putchar('/');                   /* Write out the        */
-X              putchar('*');                   /*   initializer        */
-X          }
-X          for (;;) {                          /* Eat a comment        */
-X              c = get();
-Xtest:         if (keepcomments && c != EOF_CHAR)
-X                  cput(c);
-X              switch (c) {
-X              case EOF_CHAR:
-X                  cerror("EOF in comment", NULLST);
-X                  return (EOF_CHAR);
-X
-X              case '/':
-X                  if ((c = get()) != '*')     /* Don't let comments   */
-X                      goto test;              /* Nest.                */
-X#ifdef VERBOSE
-X                  cwarn("Nested comments", NULLST);
-X#endif
-X                                              /* Fall into * stuff    */
-X              case '*':
-X                  if ((c = get()) != '/')     /* If comment doesn't   */
-X                      goto test;              /* end, look at next    */
-X                  instring = FALSE;           /* End of comment,      */
-X                  if (keepcomments) {         /* Put out the comment  */
-X                      cput(c);                /* terminator, too      */
-X                  }
-X                  /*
-X                   * A comment is syntactically "whitespace" --
-X                   * however, there are certain strange sequences
-X                   * such as
-X                   *          #define foo(x)  (something)
-X                   *                  foo|* comment *|(123)
-X                   *       these are '/' ^           ^
-X                   * where just returning space (or COM_SEP) will cause
-X                   * problems.  This can be "fixed" by overwriting the
-X                   * '/' in the input line buffer with ' ' (or COM_SEP)
-X                   * but that may mess up an error message.
-X                   * So, we peek ahead -- if the next character is
-X                   * "whitespace" we just get another character, if not,
-X                   * we modify the buffer.  All in the name of purity.
-X                   */
-X                  if (*file->bptr == '\n'
-X                   || type[*file->bptr & 0xFF] == SPA)
-X                      goto newline;
-X#if COMMENT_INVISIBLE
-X                  /*
-X                   * Return magic (old-fashioned) syntactic space.
-X                   */
-X                  return ((file->bptr[-1] = COM_SEP));
-X#else
-X                  return ((file->bptr[-1] = ' '));
-X#endif
-X
-X              case '\n':                      /* we'll need a #line   */
-X                  if (!keepcomments)
-X                      wrongline = TRUE;       /* later...             */
-X              default:                        /* Anything else is     */
-X                  break;                      /* Just a character     */
-X              }                               /* End switch           */
-X          }                                   /* End comment loop     */
-X      }                                       /* End if in comment    */
-X      else if (!inmacro && c == '\\') {       /* If backslash, peek   */
-X          if ((c = get()) == '\n') {          /* for a <nl>.  If so,  */
-X              wrongline = TRUE;
-X              goto newline;
-X          }
-X          else {                              /* Backslash anything   */
-X              unget();                        /* Get it later         */
-X              return ('\\');                  /* Return the backslash */
-X          }
-X      }
-X      else if (c == '\f' || c == VT)          /* Form Feed, Vertical  */
-X          c = ' ';                            /* Tab are whitespace   */
-X      return (c);                             /* Just return the char */
-X}
-X\f
-Xunget()
-X/*
-X * Backup the pointer to reread the last character.  Fatal error
-X * (code bug) if we backup too far.  unget() may be called,
-X * without problems, at end of file.  Only one character may
-X * be ungotten.  If you need to unget more, call ungetstring().
-X */
-X{
-X      register FILEINFO       *file;
-X
-X      if ((file = infile) == NULL)
-X          return;                     /* Unget after EOF              */
-X      if (--file->bptr < file->buffer)
-X          cfatal("Too much pushback", NULLST);
-X      if (*file->bptr == '\n')        /* Ungetting a newline?         */
-X          --line;                     /* Unget the line number, too   */
-X}
-X
-Xungetstring(text)
-Xchar          *text;
-X/*
-X * Push a string back on the input stream.  This is done by treating
-X * the text as if it were a macro.
-X */
-X{
-X      register FILEINFO       *file;
-X      extern FILEINFO         *getfile();
-X
-X      file = getfile(strlen(text) + 1, "");
-X      strcpy(file->buffer, text);
-X}
-X
-Xint
-Xcget()
-X/*
-X * Get one character, absorb "funny space" after comments or
-X * token concatenation
-X */
-X{
-X      register int    c;
-X
-X      do {
-X          c = get();
-X#if COMMENT_INVISIBLE
-X      } while (c == TOK_SEP || c == COM_SEP);
-X#else
-X      } while (c == TOK_SEP);
-X#endif
-X      return (c);
-X}
-X\f
-X/*
-X * Error messages and other hacks.  The first byte of severity
-X * is 'S' for string arguments and 'I' for int arguments.  This
-X * is needed for portability with machines that have int's that
-X * are shorter than  char *'s.
-X */
-X
-Xstatic
-Xdomsg(severity, format, arg)
-Xchar          *severity;              /* "Error", "Warning", "Fatal"  */
-Xchar          *format;                /* Format for the error message */
-Xchar          *arg;                   /* Something for the message    */
-X/*
-X * Print filenames, macro names, and line numbers for error messages.
-X */
-X{
-X      register char           *tp;
-X      register FILEINFO       *file;
-X
-X      fprintf(stderr, "%sline %d, %s: ", MSG_PREFIX, line, &severity[1]);
-X      if (*severity == 'S')
-X          fprintf(stderr, format, arg);
-X      else
-X          fprintf(stderr, format, (int) arg);
-X      putc('\n', stderr);
-X      if ((file = infile) == NULL)
-X          return;                             /* At end of file       */
-X      if (file->fp != NULL) {
-X          tp = file->buffer;                  /* Print current file   */
-X          fprintf(stderr, "%s", tp);          /* name, making sure    */
-X          if (tp[strlen(tp) - 1] != '\n')     /* there's a newline    */
-X              putc('\n', stderr);
-X      }
-X      while ((file = file->parent) != NULL) { /* Print #includes, too */
-X          if (file->fp == NULL)
-X              fprintf(stderr, "from macro %s\n", file->filename);
-X          else {
-X              tp = file->buffer;
-X              fprintf(stderr, "from file %s, line %d:\n%s",
-X                  (file->progname != NULL)
-X                      ? file->progname : file->filename,
-X                  file->line, tp);
-X              if (tp[strlen(tp) - 1] != '\n')
-X                  putc('\n', stderr);
-X          }
-X      }
-X}
-X
-Xcerror(format, sarg)
-Xchar          *format;
-Xchar          *sarg;          /* Single string argument               */
-X/*
-X * Print a normal error message, string argument.
-X */
-X{
-X      domsg("SError", format, sarg);
-X      errors++;
-X}
-X
-Xcierror(format, narg)
-Xchar          *format;
-Xint           narg;           /* Single numeric argument              */
-X/*
-X * Print a normal error message, numeric argument.
-X */
-X{
-X      domsg("IError", format, (char *) narg);
-X      errors++;
-X}
-X
-Xcfatal(format, sarg)
-Xchar          *format;
-Xchar          *sarg;                  /* Single string argument       */
-X/*
-X * A real disaster
-X */
-X{
-X      domsg("SFatal error", format, sarg);
-X      exit(IO_ERROR);
-X}
-X
-Xcwarn(format, sarg)
-Xchar          *format;
-Xchar          *sarg;                  /* Single string argument       */
-X/*
-X * A non-fatal error, string argument.
-X */
-X{
-X      domsg("SWarning", format, sarg);
-X}
-X
-Xciwarn(format, narg)
-Xchar          *format;
-Xint           narg;                   /* Single numeric argument      */
-X/*
-X * A non-fatal error, numeric argument.
-X */
-X{
-X      domsg("IWarning", format, (char *) narg);
-X}
-X
-X
-X
-END-of-cpp6.c
-exit