V7M/src/cmd/cpp/README

Files in this directory form the C preprocessor, which handles '#include'
files and macro definition and expansion for the C compiler.
This new version was written by John F. Reiser and is from 5 to 12
times faster than the old.

To create the executable file 'cpp' in the current directory:
	make

To install the preprocessor 'cpp' so it will be used by the C compiler:
	: backup the existing version
	cp /lib/cpp /lib/ocpp
	: install the new version
	cp cpp /lib/cpp

Documentation clarifications:
	Symbols defined on the command line by "-Dfoo" are defined as "1",
		i.e., as if they had been defined by "#define foo 1" or "-Dfoo=1".
	An unescaped linefeed (the single character "\n") terminates a
		character constant or quoted string.
	An escaped linefeed (the two-character sequence "\\\n") may be
		used in the body of a '#define' statement to continue
		the definition onto the next line.  The escaped linefeed is
		not included in the macro body.
	Comments are uniformly removed.  They are also ignored, except
		that a comment terminates a token.
		Thus "foo/* la di da */bar" may expand 'foo' and 'bar' but
		will never expand 'foobar'.  If neither 'foo' nor 'bar' is a
		macro then the output is "foobar", even if 'foobar'
		is defined as something else.  The file
			#define foo(a,b)b/**/a
			foo(1,2)
		produces "21" because the comment causes a break which enables
		the recognition of 'b' and 'a' as formals in the string "b/**/a".
	Macro formals are recognized even inside character constants
		and quoted strings.  The output from
			#define foo(a) '\a'
			foo(bar)
		is the seven characters " '\\bar'".
	Macros are not expanded while processing a '#define' or '#undef'.
		Thus
			#define foo bletch
			#define bar foo
			#undef foo
			bar
		produces "foo".
	Macros are not expanded during the scan which determines the actual
		parameters to another macro call.  Thus
			#define foo(a,b)b a
			#define bar hi
			foo(bar,
			#define bar bye
			)
		produces " bye" (and warns about the redefinition of 'bar').

There are some differences between the new and the old preprocessor.
Bugs fixed:
	"1.e4" is recognized as a floating-point number, rather than as an
		opportunity to expand the possible macro name "e4".
	Any kind and amount of white space (space, tab, linefeed, vertical tab,
		formfeed, carriage return) is allowed between a macro name and
		the left parenthesis which introduces its actual parameters.
	The comma operator is legal in preprocessor '#if' statements.
	Macros with parameters are legal in preprocessor '#if' statements.
	Single-character character constants are legal in preprocessor '#if' statements.
	Linefeeds are put out in the proper place when a multiline comment
		is not passed through to the output.
	The following example expands to "# # #" :
		#define foo #
		foo foo foo
	Recursion in macro definitions is strictly obeyed (to the extent that
		space is available).  In particular,
			#define a a
			a
		causes an infinite loop with very little output.  The tail recursion
			#define a <b
			#define b >a
			a
		causes the string "<>" to be output infinitely many times.  The
		non-tail recursion
			#define a b>
			#define b a<
			a
		complains "too much pushback", dumps the pushback, and continues
		(again, infinitely).
	
Stylistic choice:
	Nothing (not even linefeeds) is output while a false '#if', '#ifdef',
		or '#ifndef' is in effect.  Thus when all conditions become true
		a line of the form "# 12345 foo.c" is output.
	Error and warning messages always appear on standard error (file
		descriptor 2).
	Mismatch between the number of formals and actuals in a macro call
		produces only a warning, and not an error.  Excess actuals
		are ignored; missing actuals are turned into null strings.

Incompatibility:
	The virgule '/' in "a=/*b" is interpreted as the first character of
		the pair "/*" which introduces a comment, rather than as the
		second character of the divide-and-replace operator "=/".
		This incompatibility reflects the recent change in the C language
		which made "a/=*b" the legal way to write such a statement
		if the meaning "a=a/ *b" is intended.