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