[comp.os.minix] cppmake - Part 1 of 2

cechew@bruce.OZ (Earl Chew) (11/09/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  MANIFEST test.cpp makefile.sun makefile.pyr makefile.min
#   makefile.dos makefile.cpp cppmake.man cppmake.doc
# Wrapped by cechew@bruce on Thu Nov  9 20:07:23 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(592 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	This shipping list
X cppmake.c                  2	Source code
X cppmake.doc                1	Formatted documentation
X cppmake.man                1	Manual page source
X makefile.cpp               1	Cppmakefile
X makefile.dos               1	Site dependent makefiles
X makefile.min               1	Site dependent makefiles
X makefile.pyr               1	Site dependent makefiles
X makefile.sun               1	Site dependent makefiles
X test.cpp                   1	Test file
END_OF_FILE
if test 592 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'test.cpp' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'test.cpp'\"
else
echo shar: Extracting \"'test.cpp'\" \(346 characters\)
sed "s/^X//" >'test.cpp' <<'END_OF_FILE'
X#		Test File for CppMake
X# Comment lines are left intact
X
X# As are blank lines
X
X#   	if			1        
X#   	define	BRACKETS	(brackets)
X#		define		\
X	Z(b,a)		b:	a 		@@\
X	echo Making b from a			
X#        endif     
X
X#   			this is a comment  
X
XZ(abc,cppmake.c)
X	echo Th    ##     is word should be joined \
X	with some more things
X#
Xrubbish:
X	BRACKETS
END_OF_FILE
if test 346 -ne `wc -c <'test.cpp'`; then
    echo shar: \"'test.cpp'\" unpacked with wrong size!
fi
# end of 'test.cpp'
fi
if test -f 'makefile.sun' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.sun'\"
else
echo shar: Extracting \"'makefile.sun'\" \(1283 characters\)
sed "s/^X//" >'makefile.sun' <<'END_OF_FILE'
X#sun _SUN
X
X
X
X
X
Xdefine= -DCPPOPT=\"-D_SUN\",\"-D_BSD\" 			-D_BSD -DINTSIGNAL -DCHARMALLOC
Xinclude=
Xlibrary=
Xall= *.c test.* makefile.* *.man *.doc
X
Xeveryone= sun 1 min dos
X
XCFLAGS= $(define) $(include)
X
XLFLAGS= $(library)
X
Xsource= cppmake.c
Xobject= cppmake.o
Xlibraries=
X
X.SUFFIXES:	.o .c
X
X.c.o:
X	cc -c $(CFLAGS) $<
X
Xcppmake:	$(object)
X	cc -o cppmake $(LFLAGS) cppmake.o $(libraries)
X
X$(object):
X
X# Everything
X
Xall:	cppmake.doc cppmake
X
X# Documentation
X
Xcppmake.doc:	cppmake.man
X	nroff -man cppmake.man | col -b > cppmake.doc
X
X# Lint checking
X
Xlint:
X	lint $(define) $(source)
X
X# Test
X
Xtest:
X	( cppmake -v -f test.cpp 2>&1 ) | more
X
X# Packing
X
Xarc:
X	rm -f cppmake.arc
X	arc a cppmake.arc $(all)
X
X# Makefiles
X
Xmakefiles:
X	-for w in $(everyone) ; \
X	do \
X	n=`awk "/^#$$w / "'{ print $$2 }' <makefile.cpp` ; \
X	if test _SUN = $$n ; then \
X	cppmake -o makefile.$$w ; \
X	else \
X	cppmake -U_SUN -D$$n -o makefile.$$w ; \
X	fi ; \
X	done
X
X# Shell Archive
Xshar:
X	ls $(all) | \
X	sed -e 's/^.*\.doc/&	Formatted documentation/' \
X	    -e 's/^.*\.man/&	Manual page source/' \
X	    -e 's/^test\.cpp$$/&	Test file/' \
X	    -e 's/^makefile\.cpp$$/&	Cppmakefile/' \
X	    -e 's/^makefile\.[a-z]*$$/&	Site dependent makefiles/' \
X	    -e 's/^.*\.c$$/&	Source code/' | \
X	makekit -ncppmake. -s30k -oMANIFEST
END_OF_FILE
if test 1283 -ne `wc -c <'makefile.sun'`; then
    echo shar: \"'makefile.sun'\" unpacked with wrong size!
fi
# end of 'makefile.sun'
fi
if test -f 'makefile.pyr' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.pyr'\"
else
echo shar: Extracting \"'makefile.pyr'\" \(1289 characters\)
sed "s/^X//" >'makefile.pyr' <<'END_OF_FILE'
X
X#pyr _PYR
X
X
X
X
Xdefine= -DCPPOPT=\"-D_PYR\",\"-D_BSD\" 			-D_BSD -DINTSIGNAL -DCHARMALLOC
Xinclude=
Xlibrary=
Xall= *.c test.* makefile.* *.man *.doc
X
Xeveryone= sun pyr min dos
X
XCFLAGS= $(define) $(include) -gx
X
XLFLAGS= $(library)
X
Xsource= cppmake.c
Xobject= cppmake.o
Xlibraries=
X
X.SUFFIXES:	.o .c
X
X.c.o:
X	cc -c $(CFLAGS) $<
X
Xcppmake:	$(object)
X	cc -o cppmake $(LFLAGS) cppmake.o $(libraries)
X
X$(object):
X
X# Everything
X
Xall:	cppmake.doc cppmake
X
X# Documentation
X
Xcppmake.doc:	cppmake.man
X	nroff -man cppmake.man | col -b > cppmake.doc
X
X# Lint checking
X
Xlint:
X	lint $(define) $(source)
X
X# Test
X
Xtest:
X	( cppmake -v -f test.cpp 2>&1 ) | more
X
X# Packing
X
Xarc:
X	rm -f cppmake.arc
X	arc a cppmake.arc $(all)
X
X# Makefiles
X
Xmakefiles:
X	-for w in $(everyone) ; \
X	do \
X	n=`awk "/^#$$w / "'{ print $$2 }' <makefile.cpp` ; \
X	if test _PYR = $$n ; then \
X	cppmake -o makefile.$$w ; \
X	else \
X	cppmake -U_PYR -D$$n -o makefile.$$w ; \
X	fi ; \
X	done
X
X# Shell Archive
Xshar:
X	ls $(all) | \
X	sed -e 's/^.*\.doc/&	Formatted documentation/' \
X	    -e 's/^.*\.man/&	Manual page source/' \
X	    -e 's/^test\.cpp$$/&	Test file/' \
X	    -e 's/^makefile\.cpp$$/&	Cppmakefile/' \
X	    -e 's/^makefile\.[a-z]*$$/&	Site dependent makefiles/' \
X	    -e 's/^.*\.c$$/&	Source code/' | \
X	makekit -ncppmake. -s30k -oMANIFEST
END_OF_FILE
if test 1289 -ne `wc -c <'makefile.pyr'`; then
    echo shar: \"'makefile.pyr'\" unpacked with wrong size!
fi
# end of 'makefile.pyr'
fi
if test -f 'makefile.min' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.min'\"
else
echo shar: Extracting \"'makefile.min'\" \(1292 characters\)
sed "s/^X//" >'makefile.min' <<'END_OF_FILE'
X
X
X#min _MINIX
X
X
X
Xdefine= -DCPPOPT=\"-D_MINIX\",\"-D_V7\" 			-D_MINIX -DINTSIGNAL -DCHARMALLOC
Xinclude=
Xlibrary=
Xall= *.c test.* makefile.* *.man *.doc
X
Xeveryone= sun 1 min dos
X
XCFLAGS= $(define) $(include)
X
XLFLAGS= $(library)
X
Xsource= cppmake.c
Xobject= cppmake.s
Xlibraries=
X
X.SUFFIXES:	.s .c
X
X.c.s:
X	cc -c $(CFLAGS) $<
X
Xcppmake:	$(object)
X	cc -o cppmake $(LFLAGS) cppmake.s $(libraries)
X
X$(object):
X
X# Everything
X
Xall:	cppmake.doc cppmake
X
X# Documentation
X
Xcppmake.doc:	cppmake.man
X	nroff -man cppmake.man | col -b > cppmake.doc
X
X# Lint checking
X
Xlint:
X	lint $(define) $(source)
X
X# Test
X
Xtest:
X	( cppmake -v -f test.cpp 2>&1 ) | more
X
X# Packing
X
Xarc:
X	rm -f cppmake.arc
X	arc a cppmake.arc $(all)
X
X# Makefiles
X
Xmakefiles:
X	-for w in $(everyone) ; \
X	do \
X	n=`awk "/^#$$w / "'{ print $$2 }' <makefile.cpp` ; \
X	if test _MINIX = $$n ; then \
X	cppmake -o makefile.$$w ; \
X	else \
X	cppmake -U_MINIX -D$$n -o makefile.$$w ; \
X	fi ; \
X	done
X
X# Shell Archive
Xshar:
X	ls $(all) | \
X	sed -e 's/^.*\.doc/&	Formatted documentation/' \
X	    -e 's/^.*\.man/&	Manual page source/' \
X	    -e 's/^test\.cpp$$/&	Test file/' \
X	    -e 's/^makefile\.cpp$$/&	Cppmakefile/' \
X	    -e 's/^makefile\.[a-z]*$$/&	Site dependent makefiles/' \
X	    -e 's/^.*\.c$$/&	Source code/' | \
X	makekit -ncppmake. -s30k -oMANIFEST
END_OF_FILE
if test 1292 -ne `wc -c <'makefile.min'`; then
    echo shar: \"'makefile.min'\" unpacked with wrong size!
fi
# end of 'makefile.min'
fi
if test -f 'makefile.dos' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.dos'\"
else
echo shar: Extracting \"'makefile.dos'\" \(1347 characters\)
sed "s/^X//" >'makefile.dos' <<'END_OF_FILE'
X
X
X
X#dos _MSDOS
X
X
Xdefine= -DCPPOPT="-D_MSDOS" -D_MSDOS
Xinclude= -Ic:/tc/usr/include;c:/tc/include
Xlibrary= -Lc:/tc/usr/lib;c:/tc/lib
Xall= *.c test.* makefile.* *.man *.doc
X
Xeveryone= sun 1 min dos
X
XCFLAGS= $(define) $(include) -A -w
X
XLFLAGS= $(library)
X
Xsource= cppmake.c
Xobject= cppmake.obj
Xlibraries= libcs.lib
X
X.SUFFIXES:	.obj .c
X
X.c.obj:
X	tcc -c $(CFLAGS) $<
X
Xcppmake.exe:	$(object)
X	tcc -ecppmake $(LFLAGS) cppmake.obj $(libraries)
X
X$(object):
X
X# Everything
X
Xall:	cppmake.doc cppmake.exe
X
X# Documentation
X
Xcppmake.doc:	cppmake.man
X	nroff -man cppmake.man | col -b > cppmake.doc
X
X# Lint checking
X
Xlint:
X	lint $(define) $(source)
X
X# Test
X
Xtest:
X	( cppmake -v -f test.cpp 2>&1 ) | more
X
X# Packing
X
Xarc:
X	rm -f cppmake.arc
X	pkarc a cppmake.arc $(all)
X
X# Makefiles
X
Xmakefiles:
X	-for w in $(everyone) ; \
X	do \
X	n=`awk "/^#$$w / "'{ print $$2 }' <makefile.cpp` ; \
X	if test _MSDOS = $$n ; then \
X	cppmake -o makefile.$$w ; \
X	else \
X	cppmake -U_MSDOS -D$$n -o makefile.$$w ; \
X	fi ; \
X	done
X
X# Shell Archive
Xshar:
X	ls $(all) | \
X	sed -e 's/^.*\.doc/&	Formatted documentation/' \
X	    -e 's/^.*\.man/&	Manual page source/' \
X	    -e 's/^test\.cpp$$/&	Test file/' \
X	    -e 's/^makefile\.cpp$$/&	Cppmakefile/' \
X	    -e 's/^makefile\.[a-z]*$$/&	Site dependent makefiles/' \
X	    -e 's/^.*\.c$$/&	Source code/' | \
X	makekit -ncppmake. -s30k -oMANIFEST
END_OF_FILE
if test 1347 -ne `wc -c <'makefile.dos'`; then
    echo shar: \"'makefile.dos'\" unpacked with wrong size!
fi
# end of 'makefile.dos'
fi
if test -f 'makefile.cpp' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile.cpp'\"
else
echo shar: Extracting \"'makefile.cpp'\" \(2653 characters\)
sed "s/^X//" >'makefile.cpp' <<'END_OF_FILE'
X#ifdef	_SUN
X#undef sun
X#undef _SUN
X#sun _SUN
X#define WHOAMI		_SUN
X#define DEFINES		-DCPPOPT=\"-D_SUN\",\"-D_BSD\" \
X			-D_BSD -DINTSIGNAL -DCHARMALLOC
X#define INCLUDES
X#define LIBRARY
X#define LIBRARIES
X#define CCFLAGS
X#define OBJECT(x)	x.o
X#define AOUT(x)		x
X#define	CC		cc
X#define EXE(x)		-o x
X#define ARC		arc
X#endif
X
X#ifdef	_PYR
X#undef pyr
X#undef _PYR
X#pyr _PYR
X#define WHOAMI		_PYR
X#define DEFINES		-DCPPOPT=\"-D_PYR\",\"-D_BSD\" \
X			-D_BSD -DINTSIGNAL -DCHARMALLOC
X#define INCLUDES
X#define LIBRARY
X#define LIBRARIES
X#define CCFLAGS		-gx
X#define OBJECT(x)	x.o
X#define AOUT(x)		x
X#define	CC		cc
X#define EXE(x)		-o x
X#define ARC		arc
X#endif
X
X#ifdef	_MINIX
X#undef _MINIX
X#min _MINIX
X#define WHOAMI		_MINIX
X#define DEFINES		-DCPPOPT=\"-D_MINIX\",\"-D_V7\" \
X			-D_MINIX -DINTSIGNAL -DCHARMALLOC
X#define LIBRARY
X#define LIBRARIES
X#define INCLUDES
X#define CCFLAGS
X#define OBJECT(x)	x.s
X#define AOUT(x)		x
X#define	CC		cc
X#define EXE(x)		-o x
X#define ARC		arc
X#endif
X
X#ifdef	_MSDOS
X#undef _MSDOS
X#dos _MSDOS
X#define WHOAMI		_MSDOS
X#define DEFINES		-DCPPOPT="-D_MSDOS" -D_MSDOS
X#define LIBRARY		-Lc:/tc/usr/lib;c:/tc/lib
X#define LIBRARIES	libcs.lib
X#define INCLUDES	-Ic:/tc/usr/include;c:/tc/include
X#define CCFLAGS		-A -w
X#define OBJECT(x)	x.obj
X#define AOUT(x)		x.exe
X#define	CC		tcc
X#define EXE(x)		-e##x
X#define ARC		pkarc
X#endif
X
X#define NONAME
X#define NAME	cppmake
X
Xdefine= DEFINES
Xinclude= INCLUDES
Xlibrary= LIBRARY
Xall= *.c test.* makefile.* *.man *.doc
X
Xeveryone= sun pyr min dos
X
XCFLAGS= $(define) $(include) CCFLAGS
X
XLFLAGS= $(library)
X
Xsource= cppmake.c
Xobject= OBJECT(cppmake)
Xlibraries= LIBRARIES
X
X.SUFFIXES:	OBJECT(NONAME) .c
X
X.c##OBJECT(NONAME):
X	CC -c $(CFLAGS) $<
X
XAOUT(cppmake):	$(object)
X	CC EXE(cppmake) $(LFLAGS) OBJECT(cppmake) $(libraries)
X
X$(object):
X
X# Everything
X
Xall:	cppmake.doc AOUT(cppmake)
X
X# Documentation
X
XNAME.doc:	NAME.man
X	nroff -man NAME.man | col -b > NAME.doc
X
X# Lint checking
X
Xlint:
X	lint $(define) $(source)
X
X# Test
X
Xtest:
X	( cppmake -v -f test.cpp 2>&1 ) | more
X
X# Packing
X
Xarc:
X	rm -f NAME.arc
X	ARC a NAME.arc $(all)
X
X# Makefiles
X
Xmakefiles:
X	-for w in $(everyone) ; \
X	do \
X	n=`awk "/^#$$w / "'{ print $$2 }' <CPPMAKEFILE` ; \
X	if test WHOAMI = $$n ; then \
X	cppmake -o makefile.$$w ; \
X	else \
X	cppmake -U##WHOAMI -D$$n -o makefile.$$w ; \
X	fi ; \
X	done
X
X# Shell Archive
Xshar:
X	ls $(all) | \
X	sed -e 's/^.*\.doc/&	Formatted documentation/' \
X	    -e 's/^.*\.man/&	Manual page source/' \
X	    -e 's/^test\.cpp$$/&	Test file/' \
X	    -e 's/^makefile\.cpp$$/&	Cppmakefile/' \
X	    -e 's/^makefile\.[a-z]*$$/&	Site dependent makefiles/' \
X	    -e 's/^.*\.c$$/&	Source code/' | \
X	makekit -n##NAME. -s30k -oMANIFEST
END_OF_FILE
if test 2653 -ne `wc -c <'makefile.cpp'`; then
    echo shar: \"'makefile.cpp'\" unpacked with wrong size!
fi
# end of 'makefile.cpp'
fi
if test -f 'cppmake.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cppmake.man'\"
else
echo shar: Extracting \"'cppmake.man'\" \(4721 characters\)
sed "s/^X//" >'cppmake.man' <<'END_OF_FILE'
X.TH cppmake 1
X.SH NAME
Xcppmake \- Cpp then Make
X.SH SYNOPSIS
X.B cppmake
X[\ \fB\-C\ \fIcpp\ \fR]
X[\ \fB\-D\ \fIdefine\ \fR]
X[\ \fB\-I\ \fIdirectory\ \fR]
X[\ \fB\-M\ \fImake\ \fR]
X[\ \fB\-U\ \fIdefine\ \fR]
X[\ \fB\-f\ \fIcppmakefile\ \fR]
X[\ \fB\-o\ \fIoutfile\ \fR]
X[\ \fB\-v\ \fR]
X[\ make options\ ]
X.sp 1
X.B cppmake
X\fB\-c\fR
X[\ \fB\-C\ \fIcpp\ \fR]
X[\ \fB\-D\ \fIdefine\ \fR]
X[\ \fB\-I\ \fIdirectory\ \fR]
X[\ \fB\-M\ \fImake\ \fR]
X[\ \fB\-U\ \fIdefine\ \fR]
X[\ \fB\-f\ \fIcppmakefile\ \fR]
X[\ \fB\-o\ \fIoutfile\ \fR]
X[\ \fB\-v\ \fR]
X[\ file\ ]
X.SH DESCRIPTION
XIn the first invocation form,
X.B cppmake
Xruns the C preprocessor on the
X.IR cppmakefile .
XBy default,
X.B cppmake
Xlooks for files named
X.I Makefile.cpp
Xthen
X.I makefile.cpp
Xin the current working directory.
XThe output of the preprocessor is then filtered before being passed to
X.B make
Xfor final processing.
X.PP
XIn the second form,
X.B cppmake
Xruns the C preprocessor on the named file to produce
Xa file suitable for inclusion by other
X.IR cppmakefiles .
X.BR make .
X.SH OPTIONS
X.TP 15
X.BI -C cpp
XUse
X.I cpp
Xas the name of the C preprocessor. This option will have
Xprecedence over the environment variable
X.B CPPMAKECPP.
X.TP 15
X.BI -D define
XPass the following symbol definitions to
X.BR cpp .
X.TP 15
X.BI -I directory
XPass the following include directory to
X.BR cpp .
X.TP 15
X.BI -M make
XUse
X.I make
Xas the name of the make program. This option will have
Xprecedence over the environment variable
X.B CPPMAKEMAKE.
X.TP 15
X.BI -U define
XUndefine the following symbol in
X.BR cpp .
X.TP 15
X.B -c
XPreprocess the named file to produce a file that is suitable for inclusion by
Xother
X.IR cppmakefiles .
X.TP 15
X.BI -f cppmakefile
XUse the named file as the input file, otherwise the default names of the
X.I cppmakefile
Xwill be tried, or if the
X.B -c
Xoption is specified,
X.I file
Xwill be used as the name.
X.TP 15
X.BI -o outfile
XPlace the
X.I makefile
Xin the named file and do not invoke make, or if the
X.B -c
Xoption is specified, the generated include file is placed in the named file
Xrather than using the name of the
X.I cppmakefile
Xwith a .i extension.
X.TP 15
X.B -v
XVerbose mode. Lots of (debugging) information will be printed.
X.PP
XThe order in which the arguments are specified is not significant
Xbut if
X.B cppmake
Xis invoked in the first form,
Xthe first argument or unknown option marks the start of the arguments
Xto be passed directly to
X.BR make .
X.SH "ENVIRONMENT VARIABLES"
X.PP
X.TP 15
X.B CPPMAKEMAKE
XThe path to a make program (eg /bin/ndmake). By default,
X.B cppmake
Xwill use whatever program named
X.I make
Xthat can be found in the
X.B PATH
Xenvironment variable.
X.TP 15
X.B CPPMAKECPP
XThe path to a C preprocessor (eg /bin/cpp). By default,
X.B cppmake
Xwill use the program named
X.IR /lib/cpp .
X.SH "OPERATION"
X.PP
X.B Cppmake
Xoperates on
X.IR cppmakefiles .
XThese are
X.I makefiles
Xthat have been augmented with
X.B cpp
Xconstructs. The addition of these constructs, in particular conditional
Xinclusion and macro expansion, allows site dependent makefiles to be combined
Xinto a single
X.IR makefile .
X.PP
X.B Cppmake
Xpreprocesses the
X.I cppmakefile
Xto produce an input file for
X.BR cpp .
XThis step is required since different versions of
X.B cpp
Xtreat whitespace and line continuation differently. This preprocessing phase
Xquotes comment lines, quotes empty lines, retains
X.B cpp
Xdirective lines, quotes whitespace where needed and
Xquotes line continuations (except in
X.B cpp
Xdirectives where line continuations cause lines to be merged). A preamble is
Xinserted into the file. The resultant cpp input file is then passed to
X.B cpp
Xfor processing.  Typical contents of the preamble are:
X.sp 1
X.RS
X#define CPPMAKEMAKE \fImake\fR
X.br
X#define CPPMAKECPP \fI/lib/cpp\fR
X.br
X#define CPPMAKEFILE \fImakefile.cpp\fR
X.br
X#define CPPMAKEMAKEFILE \fI/tmp/makeAA.AAA\fR
X.RE
X.sp 1
X.PD 0
X.TP 22
XCPPMAKEMAKE
XThe name of the make program.
X.TP 22
XCPPMAKECPP
XThe name of the C preprocessor.
X.TP 22
XCPPMAKEFILE
XThe name of the cppmake file.
X.TP 22
XCPPMAKEMAKEFILE
XThe name of the makefile.
X.PD
X.PP
XThe output from
X.B cpp
Xis processed again by
X.BR cppmake .
X.B Cpp
Xline control information is removed.
XQuoted whitespace, comments and empty lines from the preprocessing phase
Xare unquoted.
XOccurrences of ## (including any surrounding
Xwhitespace) are
Xremoved (allowing token concatention). Occurrences of @@
Xare replaced with \\n with any preceding whitespace deleted.
X.PP
XThe processed output from
X.B cpp
Xbecomes the
X.I makefile
Xand is passed to
X.B make
Xfor processing.
X.SH "SEE ALSO"
Xmake(1)
X.br
Ximake(1) [Todd Brunhoff (Tektronix Inc) and Project Athena]
X.SH AUTHOR
XEarl Chew
X.SH "BUGS"
X.PP
XUnknown options mixed with known options causes
X.B cppmake
Xto become confused about which belongs where.
END_OF_FILE
if test 4721 -ne `wc -c <'cppmake.man'`; then
    echo shar: \"'cppmake.man'\" unpacked with wrong size!
fi
# end of 'cppmake.man'
fi
if test -f 'cppmake.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cppmake.doc'\"
else
echo shar: Extracting \"'cppmake.doc'\" \(5385 characters\)
sed "s/^X//" >'cppmake.doc' <<'END_OF_FILE'
X
X
X
Xcppmake(1)        Pyramid OSx Operating System         cppmake(1)
X
X
X
XNAME
X     cppmake - Cpp then Make
X
XSYNOPSIS
X     cppmake [ -C cpp ] [ -D define ] [ -I directory ]
X     [ -M make ] [ -U define ] [ -f cppmakefile ] [ -o outfile ]
X     [ -v ] [ make options ]
X
X     cppmake -c [ -C cpp ] [ -D define ] [ -I directory ]
X     [ -M make ] [ -U define ] [ -f cppmakefile ] [ -o outfile ]
X     [ -v ] [ file ]
X
XDESCRIPTION
X     In the first invocation form, cppmake runs the C preproces-
X     sor on the cppmakefile.  By default, cppmake looks for files
X     named Makefile.cpp then makefile.cpp in the current working
X     directory.  The output of the preprocessor is then filtered
X     before being passed to make for final processing.
X
X     In the second form, cppmake runs the C preprocessor on the
X     named file to produce a file suitable for inclusion by other
X     cppmakefiles.  make.
X
XOPTIONS
X     -Ccpp          Use cpp as the name of the C preprocessor.
X                    This option will have precedence over the
X                    environment variable CPPMAKECPP.
X
X     -Ddefine       Pass the following symbol definitions to cpp.
X
X     -Idirectory    Pass the following include directory to cpp.
X
X     -Mmake         Use make as the name of the make program.
X                    This option will have precedence over the
X                    environment variable CPPMAKEMAKE.
X
X     -Udefine       Undefine the following symbol in cpp.
X
X     -c             Preprocess the named file to produce a file
X                    that is suitable for inclusion by other
X                    cppmakefiles.
X
X     -fcppmakefile  Use the named file as the input file, other-
X                    wise the default names of the cppmakefile
X                    will be tried, or if the -c option is speci-
X                    fied, file will be used as the name.
X
X     -ooutfile      Place the makefile in the named file and do
X                    not invoke make, or if the -c option is
X                    specified, the generated include file is
X                    placed in the named file rather than using
X                    the name of the cppmakefile with a .i
X
X
X
XPrinted 11/3/89                                                 1
X
X
X
X
X
X
Xcppmake(1)        Pyramid OSx Operating System         cppmake(1)
X
X
X
X                    extension.
X
X     -v             Verbose mode. Lots of (debugging) information
X                    will be printed.
X
X     The order in which the arguments are specified is not signi-
X     ficant but if cppmake is invoked in the first form, the
X     first argument or unknown option marks the start of the
X     arguments to be passed directly to make.
X
XENVIRONMENT VARIABLES
X     CPPMAKEMAKE    The path to a make program (eg /bin/ndmake).
X                    By default, cppmake will use whatever program
X                    named make that can be found in the PATH
X                    environment variable.
X
X     CPPMAKECPP     The path to a C preprocessor (eg /bin/cpp).
X                    By default, cppmake will use the program
X                    named /lib/cpp.
X
XOPERATION
X     Cppmake operates on cppmakefiles.  These are makefiles that
X     have been augmented with cpp constructs. The addition of
X     these constructs, in particular conditional inclusion and
X     macro expansion, allows site dependent makefiles to be com-
X     bined into a single makefile.
X
X     Cppmake preprocesses the cppmakefile to produce an input
X     file for cpp.  This step is required since different ver-
X     sions of cpp treat whitespace and line continuation dif-
X     ferently. This preprocessing phase quotes comment lines,
X     quotes empty lines, retains cpp directive lines, quotes whi-
X     tespace where needed and quotes line continuations (except
X     in cpp directives where line continuations cause lines to be
X     merged). A preamble is inserted into the file. The resultant
X     cpp input file is then passed to cpp for processing.  Typi-
X     cal contents of the preamble are:
X
X          #define CPPMAKEMAKE make
X          #define CPPMAKECPP /lib/cpp
X          #define CPPMAKEFILE makefile.cpp
X          #define CPPMAKEMAKEFILE /tmp/makeAA.AAA
X
X     CPPMAKEMAKE           The name of the make program.
X     CPPMAKECPP            The name of the C preprocessor.
X     CPPMAKEFILE           The name of the cppmake file.
X     CPPMAKEMAKEFILE       The name of the makefile.
X
X     The output from cpp is processed again by cppmake.  Cpp line
X     control information is removed.  Quoted whitespace, comments
X     and empty lines from the preprocessing phase are unquoted.
X     Occurrences of ## (including any surrounding whitespace) are
X
X
X
XPrinted 11/3/89                                                 2
X
X
X
X
X
X
Xcppmake(1)        Pyramid OSx Operating System         cppmake(1)
X
X
X
X     removed (allowing token concatention). Occurrences of @@ are
X     replaced with \n with any preceding whitespace deleted.
X
X     The processed output from cpp becomes the makefile and is
X     passed to make for processing.
X
XSEE ALSO
X     make(1)
X     imake(1) [Todd Brunhoff (Tektronix Inc) and Project Athena]
X
XAUTHOR
X     Earl Chew
X
XBUGS
X     Unknown options mixed with known options causes cppmake to
X     become confused about which belongs where.
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
XPrinted 11/3/89                                                 3
X
X
X
END_OF_FILE
if test 5385 -ne `wc -c <'cppmake.doc'`; then
    echo shar: \"'cppmake.doc'\" unpacked with wrong size!
fi
# end of 'cppmake.doc'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Earl Chew, Dept of Computer Science, Monash University, Australia 3168
ARPA: cechew%bruce.cs.monash.oz.au@uunet.uu.net  ACS : cechew@bruce.oz
----------------------------------------------------------------------

rsalz@bbn.com (Rich Salz) (11/14/89)

cppmake is pretty neat, but this is small and does something very similar.
It was posted to comp.sources.misc about one to two years ago:

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  emake.c
# Wrapped by rsalz@papaya.bbn.com on Mon Nov 13 13:33:25 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'emake.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'emake.c'\"
else
echo shar: Extracting \"'emake.c'\" \(5787 characters\)
sed "s/^X//" >'emake.c' <<'END_OF_FILE'
X/*
X**  EMAKE
X**  Run /lib/cpp over Dmakefile (if necessary), then call make.
X**  There is a prolog file, the Dmakefile, and the epilog file;
X**  see the List variable to set these.
X**
X**  This creates a makefile called MakeAuto, so you don't have to
X**  spend all that silly time in cpp if the Dmakefile hasn't changed.
X*/
X#include <stdio.h>
X#include <errno.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/file.h>
X
X#ifdef	WAIT_UNION
X#include <sys/wait.h>
X#define WAITVALUE(W)		((W).w_retcode)
Xtypedef union wait WAITER;
X#else
X#define WAITVALUE(W)		((W) >> 8)
Xtypedef int WAITER;
X#endif	/* WAIT_UNION */
X
X
X/*
X**  Handy shorthands.
X*/
X#define STDOUT		1
X#define STDERR		2
X#define WHITE(c)	((c) == ' ' || (c) == '\t')
X#define ENDOF(x)	(sizeof x / sizeof x[0])
X
X
X/*
X**  Datatype and variable to hold the list of CPP directives that we should
X**  pass through (make's comment character is '#', which clashes).
X*/
Xtypedef struct {
X    char	Value[8];
X    int		Length;
X} ALIST;
X
XALIST	  Directives[] = {
X    { "include",	 7 },
X    { "define",		 6 },
X    { "ifndef",		 6 },
X    { "ifdef",		 5 },
X    { "undef",		 5 },
X    { "endif",		 5 },
X    { "else",		 4 },
X    { "line",		 4 },
X    { "if",		 2 },
X};
X
X/* Other globals. */
Xchar	 INCLUDE_DIR[] = "-I/usr/cronus/include";
Xchar	 TempInput[]  = "MakeIXXXXXX";	/* CPP input file		*/
Xchar	 TempOutput[] = "MakeOXXXXXX";	/* CPP output file		*/
Xchar	 DMAKEFILE[] = "Dmakefile";	/* Emake's makefile		*/
Xchar	 MAKEFILE[] = "MakeAuto";	/* Generated makefile		*/
Xchar	*List[] = {			/* Sources for emake		*/
X    "/usr/cronus/clib/dmakedefs",
X    DMAKEFILE,
X    "/usr/cronus/clib/dtargets",
X    NULL
X};
X
X/* Linked in later. */
Xextern int	 errno;
Xextern char	*mktemp();
Xextern char	*malloc();
X
X
X/*
X**  Print error message, clean up, and die.
X*/
Xstatic void
XQuit(s)
X    char	*s;
X{
X    perror(s);
X#ifndef	DEBUG
X    if (unlink(TempInput) < 0 && errno != ENOENT)
X	perror("Error in unlink#1 in QUIT cleanup");
X    if (unlink(TempOutput) < 0 && errno != ENOENT)
X	perror("Error in unlink#2 in QUIT cleanup");
X#endif	/* DEBUG */
X    _exit(1);
X}
X
X
X/*
X**  Pre-process the input files, building the make control file.
X*/
Xstatic void
XPrepare(Cargv)
X    char		**Cargv;
X{
X    register ALIST	 *D;
X    register FILE	 *F;
X    register FILE	 *In;
X    register char	 *p;
X    register int	  i;
X    register int	  j;
X    WAITER		  W;
X    char		**Name;
X    char		  buff[BUFSIZ];
X
X    /* Create tempfile for CPP input. */
X    if ((F = fopen(TempInput, "w")) == NULL)
X	Quit(TempInput);
X
X    /* Write each input file to the temporary output. */
X    for (Name = List; *Name; Name++) {
X	if ((In = fopen(*Name, "r")) == NULL)
X	    Quit(*Name);
X
X	/* Read input, eliding #foo lines if foo is not a cpp directive. */
X	fputs("# line 0 \"", F);
X	fputs(*Name, F);
X	fputs("\"\n", F);
X	while (fgets(buff, sizeof buff, In))
X	    if (buff[0] != '#')
X		fputs(buff, F);
X	    else {
X		for (p = &buff[1]; *p && WHITE(*p); p++)
X		    p++;
X		i = strlen(p);
X		for (D = Directives; D < ENDOF(Directives); D++)
X		    if (i > D->Length
X		     && strncmp(p, D->Value, D->Length) == 0
X		     && WHITE(p[D->Length])) {
X			fputs(buff, F);
X			break;
X		    }
X	    }
X
X	fclose(In);
X    }
X    fclose(F);
X
X    /* Create a file to hold the cpp output. */
X    i = open(TempOutput, O_WRONLY | O_TRUNC | O_CREAT, 0666);
X
X    /* Call the pre-processor. */
X    if ((j = fork()) == 0) {
X	/* On some systems, dup and dup2 don't do the right thing. */
X	if (close(STDOUT) < 0 || dup(i) != STDOUT)
X	    perror("Error in CPP redirection");
X	execv(Cargv[0], Cargv);
X	perror(Cargv[0]);
X	_exit(1);
X    }
X
X    /* Wait for it. */
X    while (wait(&W) != j)
X	;
X    if (WAITVAL(W))
X	Quit("CPP failure");
X
X    /* Copy cpp output to MAKEFILE, eliding all "#" lines. */
X    close(i);
X    if ((In = fopen(TempOutput, "r")) == NULL)
X	Quit("Can't open output temporary");
X    if ((F = fopen(MAKEFILE, "w")) == NULL)
X	Quit("Can't open final output file");
X    fputs("## HANDS OFF THIS FILE--IT WAS AUTOMATICALLY CREATED!\n", F);
X    while (fgets(buff, sizeof buff, In))
X	if (buff[0] != '#')
X	    for (p = buff; *p && *p != '\n'; p++)
X		if (!WHITE(*p)) {
X		    fputs(buff, F);
X		    break;
X		}
X    fclose(In);
X    fclose(F);
X    if (unlink(TempInput) < 0 || unlink(TempOutput) < 0)
X	perror("Error in cleaning up temp files");
X}
X
X
Xmain(ac, av)
X    int			  ac;
X    register char	 *av[];
X{
X    register char	**Margv;
X    register char	**Cargv;
X    register char	 *p;
X    register int	  Mcount;
X    register int	  Ccount;
X    register int	  Force;
X    struct stat		  Sb1;
X    struct stat		  Sb2;
X
X    /* Is it all there? */
X    if (stat(DMAKEFILE, &Sb1) < 0)
X	Quit("Required file Dmakefile is missing");
X
X    /* Is Dmakefile newer than MakeFile? */
X    Force = stat(MAKEFILE, &Sb2) < 0 || Sb1.st_mtime >= Sb2.st_mtime;
X
X    /* Build argument list stubs. */
X    Margv = (char **)malloc((unsigned int)(ac + 4) * sizeof (char *));
X    Margv[0] = "make";
X    Margv[1] = "-f";
X    Margv[2] = MAKEFILE;
X    Cargv = (char **)malloc((unsigned int)(ac + 3) * sizeof (char *));
X    Cargv[0] = "/lib/cpp";
X    Cargv[1] = INCLUDE_DIR;
X
X    /* Create spool files. */
X    mktemp(TempInput);
X    mktemp(TempOutput);
X
X    /* Scan arg list, moving "-Dxxx" to cpp, all other stuff to make. */
X    for (Mcount = 3, Ccount = 2; p = *++av; )
X	if (p[0] == '-' && (p[1] == 'D' || p[1] == 'U' || p[1] == 'I')) {
X	    Force++;
X	    Cargv[Ccount++] = p;
X	}
X	else
X	    Margv[Mcount++] = p;
X    Cargv[Ccount++] = TempInput;
X    Cargv[Ccount] = NULL;
X    Margv[Mcount] = NULL;
X
X    /* Rebuild MAKEFILE if necessary. */
X    if (Force) {
X	write(STDERR, "Rebuilding...", sizeof "Rebuilding..." - 1);
X	Prepare(Cargv);
X	write(STDERR, " done\n", sizeof " done\n" - 1);
X    }
X
X    /* Now have make do the real work. */
X    execvp(Margv[0], Margv);
X    Quit(Margv[0]);
X}
END_OF_FILE
if test 5787 -ne `wc -c <'emake.c'`; then
    echo shar: \"'emake.c'\" unpacked with wrong size!
fi
# end of 'emake.c'
fi
echo shar: End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.