[comp.sources.unix] v16i035: Larry Wall's Configure generator, etc., Part02/07

rsalz@bbn.com (Rich Salz) (10/15/88)

Submitted-by: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall)
Posting-number: Volume 16, Issue 35
Archive-name: dist/part02

#! /bin/sh

# Make a new directory for the dist sources, cd to it, and run kits 1
# thru 7 through sh.  When all 7 kits have been run, read README.

echo "This is dist 2.0 kit 2 (of 7).  If kit 2 is complete, the line"
echo '"'"End of kit 2 (of 7)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
mkdir mcon mcon/U pat pl 2>/dev/null
echo Extracting pat/patcil.SH
sed >pat/patcil.SH <<'!STUFFY!FUNK!' -e 's/X//'
Xcase $CONFIG in 
X'') if test ! -f config.sh; then
X	ln ../config.sh . || \
X	ln ../../config.sh . || \
X	ln ../../../config.sh . || \
X	(echo "Can't find config.sh."; exit 1)
X    fi
X    . ./config.sh
X    ;;
Xesac
X: This forces SH files to create target in same directory as SH file.
X: This is so that make depend always knows where to find SH derivatives.
Xcase "$0" in
X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
Xesac
Xecho "Extracting patcil (with variable substitutions)"
X$cat >patcil <<!GROK!THIS!
X#!/usr/bin/perl -i~
X        eval "exec /usr/bin/perl -S \$0 \$*"
X                if \$running_under_some_shell;
X
X# $Header: patcil.SH,v 2.0 88/06/29 00:21:39 lwall Locked $
X#
X# $Log:	patcil.SH,v $
X# Revision 2.0  88/06/29  00:21:39  lwall
X# Baseline.
X# 
X# 
X
X\$defeditor = '$defeditor';
X!GROK!THIS!
X
X: In the following dollars and backticks do not need the extra backslash.
Xcat >>patcil <<'!NO!SUBS!'
Xdie "patcil [files]\n" unless $#ARGV >= 0;
X
X$RCSEXT = ',v' unless $RCSEXT;
X
Xsystem 'mkdir', 'RCS' unless -d 'RCS';
X
Xchop($pwd = `pwd`) unless -f '.package';
Xuntil (-f '.package') {
X    die "No .package file!  Run packinit.\n" unless $pwd;
X    chdir '..' || die "Can't cd ..";
X    $pwd =~ s|(.*)/(.*)|$1|;
X    $prefix = $2 . '/' . $prefix;
X}
Xif ($prefix) {
X    for (@ARGV) {
X	s/^/$prefix/ unless m|^[-/]|;
X    }
X}
Xdo readpackage();
X
Xif (-f 'patchlevel.h') {
X    open(PL,"patchlevel.h") || die "Can't open patchlevel.h\n";
X    while (<PL>) {
X        $bnum = $1 if /^#define\s+PATCHLEVEL\s+(\d+)/;
X    }
X    die "Malformed patchlevel.h file.\n" if $bnum eq '';
X    ++$bnum;
X}
Xelse {
X    $bnum=1;
X}
X
Xopen(LOGS,">>bugs/.logs$bnum");		# remember logs for patmake
X
Xwhile ($ARGV[0] =~ /^-/) {
X    $_ = shift;
X    last if /--/;
X    if ($_ eq '-p') {
X	$patching++;
X    }
X    elsif ($_ eq '-q') {
X	push(@sw,$_);
X    }
X    elsif ($_ eq '-f') {
X	push(@sw,$_);
X    }
X    elsif ($_ eq '-b') {
X	$batch++;
X    }
X    elsif ($_ eq '-a') {
X	$all++;
X    }
X    elsif ($_ eq '-s') {
X	$strip++;
X    }
X    else {
X	die "Unrecognized switch: $_\n";
X    }
X}
X
Xif ($all) {
X    open(MANI,"MANIFEST.new") || die "No MANIFEST.new found.\n";
X    @ARGV = ();
X    while (<MANI>) {
X        chop;
X	($_) = split(' ');
X        push(@ARGV,$_);
X    }
X    close MANI;
X}
X
X@filelist = @ARGV;
X
Xsub CLEANUP {
X    print "Warning: restore $ARGV\n";
X    exit 1;
X}
X
Xif ($strip) {
X    open(TTY,">/dev/tty");
X    select(TTY);
X    $| = 1;
X    select(stdout);
X    $SIG{'INT'} = 'CLEANUP';
X    while (<>) {
X	if (/^(.*)\$Log[:\$]/) {
X	    $comment = $1;
X	    $len = length($comment);
X	    print;
X	    $lastnl = 1;
X	    logline: while (<>) {
X		$c = substr($_,0,$len);
X		last logline unless $c eq $comment;
X		$_ = substr($_,$len,999);
X		if ($lastnl) {
X		    unless (/^Revision\s+\d/) {
X			$_ = $comment . $_;
X			last logline;
X		    }
X		    $lastnl = 0;
X		}
X		else {
X		    if ($_ eq "\n") {
X			$lastnl = 1;
X		    }
X		}
X	    }
X	}
X    }
X    continue {
X	print;
X	if ($ARGV ne $oldargv) {
X	    print TTY "Stripping $ARGV...\n";
X	    $oldargv = $ARGV;
X	}
X    }
X    $SIG{'INT'} = 'DEFAULT';
X    close TTY;
X}
X
Xif ($batch) {
X    $flist=do rcsargs(@filelist);
X    @flist=split(' ',$flist);
X    system 'rcs', '-u', @flist;
X    system 'rcs', "-l$revbranch", @flist;
X    system 'ci', '-l', "-r$revbranch", @sw, @flist;
X    exit 0;
X}
X
Xopen(MANI,"MANIFEST.new") || die "Can't open MANIFEST.new.\n";
Xwhile (<MANI>) {
X    ($file) = split(' ');
X    $inmani{$file} = 1;
X}
Xclose MANI;
X
Xfile: foreach $file (@filelist) {
X    $files = do rcsargs($file);
X    @files = split(' ',$files);
X    $file = $files[1] if $file =~ /\.$RCSEXT$/;
X    unless ($inmani{$file}) {
X	print "$file does not appear to be in your MANIFEST.new--add? [y] ";
X	$ans = <stdin>;
X	if ($ans !~ /^n/i) {
X	    print "MANIFEST.new comment? ";
X	    $ans = <stdin>;
X	    `echo '$file	$ans' >>MANIFEST.new`;
X	}
X    }
X    $revs=0;
X    $rlog = `rlog -r$baserev -r$revbranch $files 2>&1`;
X    ($total) = ($rlog =~ /total revisions: (\d+)/);
X    ($revs) = ($rlog =~ /selected revisions: (\d+)/);
X    $comment = do rcscomment($file);
X    if (!$revs) {
X	if ($total) {				# new trunk revision
X	    if ($rlog !~ /locks:\s*;/) {
X		system 'rcs', '-u', @files;	# unlock branch
X	    }
X	    system 'rcs', '-l', @files;		# lock trunk
X	}
X	else {
X	    system 'rcs', '-i', "-c$comment", @files if $comment ne '';
X	}
X	if ($patching && !$total) {	# check in null as trunk revision
X	    rename($file, "$file.xxx");
X	    `cp /dev/null $file` unless -f "$file.xxx";
X	    if (system 'ci', "-l$baserev", @sw, @files) {
X		print "Trying again...\n";
X		system 'ci', "-r$baserev", @sw, @files;
X		system 'rcs', '-u', @files unless $?;
X		system 'co', "-l$baserev", @files unless $?;
X	    }
X	    system 'rcs', "-Nlastpat:$baserev", @files;
X	    rename("$file.xxx", $file);
X	    $mess = do getlog($file);
X	    next file if $mess eq 'nope';
X	    if (system 'ci', "-l$revbranch", @sw, @files) {
X		print "Unlocking and trying again...\n";
X		system 'rcs', '-u', @files;
X		system 'ci', "-l$revbranch", @sw, @files unless $?;
X	    }
X	}
X	else {
X	    $mess = do getlog($file);
X	    next file if $mess eq 'nope';
X	    if (do feed($mess, 'ci', "-l$baserev", @sw, @files)) {
X		print "Trying again...\n";
X		do feed($mess, 'ci', "-r$baserev", @sw, @files);
X		system 'rcs', '-u', @files unless $?;
X		system 'co', "-l$baserev", @files unless $?;
X	    }
X	    system 'rcs', "-Nlastpat:$baserev", @files;
X	}
X    }
X    elsif ($revs == 1) {
X	$mess = do getlog($file);
X	next file if $mess eq 'nope';
X	if (do feed($mess, 'ci', @sw, "-l$revbranch", @files)) {
X	    print "Unlocking and trying again...\n";
X	    system 'rcs', '-u', @files;
X	    do feed($mess, 'ci', @sw, "-l$revbranch", @files) unless $?;
X	}
X    }
X    else {
X	$mess = do getlog($file);
X	next file if $mess eq 'nope';
X	if (do feed($mess, 'ci', @sw, "-l$revbranch", @files)) {
X	    print "Trying again with separate checkout...\n";
X	    do feed($mess, 'ci', @sw, "-r$revbranch", @files);
X	    system 'rcs', "-l$revbranch", @files unless $?;
X	    system 'co', "-l$revbranch", @files unless $?;
X	}
X    }
X}
Xunlink ".rlog$$";
X
Xsub feed {
X    local($mess) = shift(@_);
X    open(FORK,"|-") || exec @_;
X    print FORK $mess;
X    close FORK;
X    $?;
X}
X
Xsub getlog {
X    local($file) = @_;
X    local($mess) = '';
X    local($prefix) = "patch$bnum: ";
X    local($prompt) = $comment;
X    $prompt = '>> ' unless $prompt;
X    $prefix = '' unless $revs;
X    print "Type log message for $file (finish with ., CR for previous):\n";
X    try: for (;;) {
X	line: for (print "$prompt$prefix";;print "$prompt$prefix") {
X	    if ($always) {
X		print "\n";
X		$line = '';
X	    }
X	    else {
X		$line = <stdin>;
X	    }
X	    if ($line =~ /^\.?$/) {
X		if ($mess) {
X		    last line;
X		}
X		else {
X		    $line = 'p';
X		}
X	    }
X	    if ($line =~ /^[h?]$/) {
X		print "
XCR or .	Terminate log message.
Xp	Append previous message.
Xl	List what I have so far.
Xv or e	Call editor.
XV or E	Call editor with a diff listing.
Xx	Toggle patch# prefix.
Xn	Forget this file.
Xa	Always use this message.
Xr	Print out the rlog for this file.
Xh or ?	This help message.
X
X";
X		next line;
X	    }
X	    if ($line =~ /^[VE]$/) {
X		$mess .= "\n" . `rcsdiff -c -rlastpat $files`;
X	    }
X	    if ($line =~ /^[VEve]$/) {
X		$mess = do edit($mess);
X		next line;
X	    }
X	    if ($line =~ /^r$/) {
X		system "rlog $files";
X		next line;
X	    }
X	    if ($line =~ /^a$/) {
X		$always++ if $mess || $prevmess;
X		next line;
X	    }
X	    if ($line =~ /^n$/) {
X		$mess = 'nope';
X		last line;
X	    }
X	    if ($line =~ /^l$/) {
X		foreach $line (split(/\n/,$mess)) {
X		    print $prompt,$line,"\n";
X		}
X		next line;
X	    }
X	    if ($line =~ /^p$/) {
X		$mess .= $prevmess;
X		foreach $line (split(/\n/,$prevmess)) {
X		    print $prompt,$line,"\n";
X		}
X		next line;
X	    }
X	    if ($line =~ /^x$/) {
X		$prefix = $prefix ? '' : "patch$bnum: ";
X		next line;
X	    }
X	    $mess .= $prefix . $line;
X	    if (length($mess) > 511) {
X		print "You'll have to trim to less than 512 chars...\n";
X		sleep(3);
X		$mess = do edit($mess);
X	    }
X	}
X	$mess = $prevmess if $mess eq '';
X	if (!$mess) {
X	    print "No previous message, try again.\n";
X	    next try;
X	}
X	if (length($mess) > 511) {
X	    print "Sorry, that's too long; rcs won't take it.  Try again...\n";
X	    next try;
X	}
X	last try;
X    }
X    print LOGS $mess unless $mess eq 'nope';
X    $prevmess = $mess unless $mess eq 'nope';
X}
X
Xsub geteditor {
X    local($editor) = $ENV{'VISUAL'};
X    $editor = $ENV{'EDITOR'} unless $editor;
X    $editor = $defeditor unless $editor;
X    $editor = 'vi' unless $editor;
X    $editor;
X}
X
Xsub edit {
X    $editor = do geteditor() unless $editor;
X    local($text) = join("\n", @_);
X    open(TMP,">/tmp/cil$$") || die "Can't create /tmp/cil$$";
X    print TMP $text;
X    close TMP;
X    system $editor, "/tmp/cil$$";
X    $text = `cat /tmp/cil$$`;
X    unlink "/tmp/cil$$";
X    $text;
X}
X
X!NO!SUBS!
Xcat ../pl/package.pl >>patcil
Xcat ../pl/rcsargs.pl >>patcil
Xcat ../pl/comment.pl >>patcil
Xchmod +x patcil
X$eunicefix patcil
!STUFFY!FUNK!
echo Extracting mcon/metaconfig.man
sed >mcon/metaconfig.man <<'!STUFFY!FUNK!' -e 's/X//'
X.rn '' }`
X''' $Header: metaconfig.man,v 2.0 88/06/28 23:18:51 lwall Locked $
X''' 
X''' $Log:	metaconfig.man,v $
X''' Revision 2.0  88/06/28  23:18:51  lwall
X''' Baseline.
X''' 
X''' 
X.de Sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.de Sp
X.if t .sp .5v
X.if n .sp
X..
X'''
X'''     Set up \*(-- to give an unbreakable dash;
X'''     string Tr holds user defined translation string.
X'''     Bell System Logo is used as a dummy character.
X'''
X.ie n \{\
X.tr \(*W-\*(Tr
X.ds -- \(*W-
X.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
X.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
X.ds L" ""
X.ds R" ""
X.ds L' '
X.ds R' '
X'br\}
X.el\{\
X.ds -- \(em\|
X.tr \*(Tr
X.ds L" ``
X.ds R" ''
X.ds L' `
X.ds R' '
X'br\}
X.de Sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.de Sp
X.if t .sp .5v
X.if n .sp
X..
X.de Ip
X.br
X.ie \\n.$>=3 .ne \\$3
X.el .ne 3
X.IP "\\$1" \\$2
X..
X.TH METACONFIG 1 LOCAL
X.SH NAME
Xmetaconfig - a Configure script generator
X.SH SYNOPSIS
X.B metaconfig
X[options] 
X.SH DESCRIPTION
X.I Metaconfig
Xis a program that writes Configure scripts.
XIf you don't know what a Configure script is, you probably aren't
Xinterested in
X.IR metaconfig .
X.PP
X.I Metaconfig
Xoperates from set of
X.I units
Xwhich define everything that metaconfig knows about portability.
XEach unit is self-contained, and does not have to be registered anywhere
Xother than by inclusion in either the public U directory or your private
XU directory.
XIf the dist package (of which metaconfig is a part) is installed in LIB,
Xthen the public U directory is LIB/dist/mcon/U.
XYour private U directory, if you have one,
Xis in the top level directory of your package.
XBefore you can run metaconfig you must do a several things:
X.Ip 1) 4 4
XCreate a .package file in the package's top level directory by running packinit.
XThis program will ask you about your package and remember what you tell
Xit so that all the dist programs can be smart.
X.Ip 2) 4 4
XConsult the Glossary (in LIB/dist/mcon) and write your shell scripts and
XC programs in terms of the symbols that metaconfig knows how to define.
XYou don't need to tell metaconfig which symbols you used, since metaconfig
Xwill figure that out for you.
X.Ip 3) 4 4
XGenerate any .SH scripts needed to write Makefiles or shell scripts that
Xwill depend on values defined by Configure.
XThere is a program called makeSH that will help you do this.
X.Ip 4) 4 4
XCreate a MANIFEST.new file in your top level directory that lists all the
Xfiles in your package.
XThe filename should be the first field on each line.
XAfter some whitespace you can add a comment which will end up in MANIFEST.
X.Ip 5) 4 4
XCopy any .U files that you want to modify to your private U directory.
XAny .U files in your private U directory will be used in preference to
Xthe one in the public U directory.
XFor example, one way to force inclusion of any unit is to copy the End.U
Xfile to your .U directory and add the name of the unit you want as
Xa dependency on the end of the ?MAKE: line.
XCertain units can ONLY be forced in this way, namely those of the form
XWarn_*.U and Chk_*.U.
XYou can also customize certain default Configure variables by copying
XMyinit.U to your package's private U directory and setting the variables in
Xthat unit.
X.PP
XNow you are ready to run metaconfig.
X.PP
XIf you are testing a new unit, and your source files haven't changed,
Xyou may use the
X.B \-w
Xswitch to suppress the scan of your programs.
XIn this case, metaconfig uses the Wanted file from the previous run
Xof metaconfig.
X.PP
XThe
X.B \-v
Xswitch makes metaconfig a little more verbose.
XThe
X.B \-V
Xswitch makes metaconfig a LOT more verbose.
X.PP
XIn order to create new units, do the following:
X.Ip 1) 4 4
XCopy a similar unit to a new .U file.
XThe name you choose should be the name of a variable generated by the unit.
XIt should be 12 or less characters to prevent filename chopping.
XActually, it should probably be 10 or less so that those who want to use RCS
Xcan have a .U,v on the end without chopping.
XMetaconfig uses the case of the first letter to determine if any variable is
Xactually produced by this unit, so don't Capitalize your unit
Xname if it is supposed to produce a shell variable.
X.Ip 2) 4 4
XEdit the new .U file to do what you want.
XThe first ?MAKE: line indicates the dependencies; before the final list
Xcolon all the variables this unit defines, and after the final colon
Xall the variables (or other units) on which this unit depends.
XIt is very important that these lists be accurate.
XIMPORTANT: The first symbol after ?MAKE: *must* be the name of the file
X(without the .U).
X.Ip 3) 4 4
XTo the extent possible, parameterize your unit based on shell
Xvariable defined on ?INIT: lines.
XThis will move the variable definitions up to the Init.U unit,
Xwhere they can be overridden by definitions in Myinit.U, which is
Xincluded after Init.U.
X.Ip 4) 4 4
XAdd the definition of any C symbols desired as ?H: lines.
XA line beginning with ?H:?%1: in the .U file will be added to the eventual
Xconfig.h file if and only if metaconfig decides that the first symbol
Xon the ?MAKE: line is needed.
XThe %1 stands for that first symbol, which happens to be the name of
Xthe file too (without .U).
XAlways put a comment on each ?H: line in case one of the variable
Xsubstitutions earlier on the line starts a comment without finishing it.
XAny shell variable starting with d_ may do this, so beware.
X.Ip 5) 4 4
XAdd glossary definitions as ?S: lines for shell variables and ?C:
Xlines for C preprocessor variables.
XSee a current unit for examples.
XIt is VERY important to start each entry with a left justified symbol
Xname, and end each entry with with a ?C:. or ?S:. line.  The algorithm
Xthat translates C preprocessor symbol entries for the Glossary into
Xcomments for config.h depends on this.
X.Ip 6) 4 4
XMake sure the order of all your ? lines is right.  The correct order is:
X.nf
X
X	?RCS: and ?X: lines		-- basically just comments
X	?MAKE: lines			-- metaconfig dependencies
X	?C: and ?S: lines		-- Glossary definitions
X	?H: lines			-- config.h definitions
X
X	?INIT: lines can go anywhere.
X
X.fi
X.Ip 7) 4 4
XPut the unit into the public or private U directory as appropriate.
X.Ip 8) 4 4
XRerun metaconfig.
X.Ip 9) 4 4
XSend unit to lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) for inclusion
Xin the master copy, if you think it's of general interest.
X.PP
XIn order to add a new program to be located:
X.Ip 1) 4 4
XEdit Loc.U, and add the name of the program both to the ?MAKE: line
X(between the two colons) and to either loclist or trylist (depending
Xon whether the program is mandatory or not).
X.Ip 2) 4 4
XRerun metaconfig.
X.Ip 3) 4 4
XSend Loc.U to me for inclusion in the master copy, if you think it's
Xof general interest.
X.PP
XNotes for writing .U files:
X.Ip * 4 4
XAlways use "rm -f" because there are systems where rm is interactive by
Xdefault.
X.Ip * 4 4
XAlways use echo " " (with a space) because of Eunice systems.
X.Ip * 4 4
XUse only programs that came with V7, so that you know everyone has them.
X.Ip * 4 4
XUse $contains when you want to grep conditionally, since not all
Xgreps return a reasonable status.
XBe sure to redirect the output to /dev/null.
X.Ip * 4 4
XUse "if test" rather than "if [...]" since not every sh knows the
Xlatter construct.
X.Ip * 4 4
XUse the myread script for inputs so that they can do shell escapes
Xand default evaluation.  The general form is
X.nf
X
X	case "$grimble" in
X	'') dflt=452;;
X	*) dflt="$grimble";;
X	esac
X	rp="How many grimbles do you have? [$dflt]"
X	echo $n "$rp $c"
X	. myread
X	grimble="$ans"
X.fi
X.Ip * 4 4
XAlways try to determine whether a feature is present in the most
Xspecific way--don't say "if bsd" when you can grep libc.  There
Xare many hybrid systems out there, and each feature should stand
Xor fall by itself.
X.Ip * 4 4
XAlways try to determine whether a feature is present in the most
Xgeneral way, so that other packages can use your unit.
X.Ip * 4 4
XWhen in doubt, set a default and ask.  Don't assume anything.
X.Ip * 4 4
XIf you think the user is wrong, allow for the fact that he may be right.
XFor instance, he could be running Configure on a different system than
Xhe is going to use the final product on.
X.PP
XMetaconfig reserves the following names in your directory, and if you use such
Xa name it may get clobbered or have other unforeseen effects:
X.nf
X
X	.MT/*
X	Configure
X	Wanted
X	UU/*
X
X.fi
XAdditionally, Configure may clobber these names in the directory it is run in:
X.nf
X
X	UU/*
X	config.sh
X	config.h
X.fi
X.SH AUTHOR
XLarry Wall <lwall@jpl-devvax.jpl.nasa.gov>
X.SH ENVIRONMENT
XNo environment variables are used by
X.IR metaconfig .
X.SH FILES
XLIB/dist/mcon/U/*.U
X.br
XLIB/dist/mcon/Glossary
X.br
X    where LIB is something like /usr/lib or /usr/local/lib.
X.SH SEE ALSO
Xpat(1)
X.br
XmakeSH(1)
X.br
Xmakedist(1)
X.SH DIAGNOSTICS
X.SH BUGS
XUnits are sometimes included unnecessarily if one of its symbols is
Xaccidentally mentioned, e.g. in a comment.
XBetter too many units than too few, however.
X.rn }` ''
!STUFFY!FUNK!
echo Extracting MANIFEST
sed >MANIFEST <<'!STUFFY!FUNK!' -e 's/X//'
XAfter all the dist kits are run you should have the following files:
X
XFilename		Kit Description
X--------		--- -----------
XConfigure                1 Portability tool.
XMANIFEST                 2 This list of files.
XMakefile                 4 A makefile to run subsidiary makefiles.
XREADME                   1 Basic instructions.
Xconfig.h.SH              3 Produces config.h.
Xkit/Makefile.SH          4 Builds kit builder.
Xkit/README               1 Instructions on makedist.
Xkit/makeSH               5 Does most of turning a script into an SH file.
Xkit/makeSH.man           5 Manual page for same.
Xkit/makedist.SH          3 Makes a set of kits in the current directory.
Xkit/makedist.man         4 Manual page for same.
Xmcon/Makefile.SH         5 Builds metaconfig.
Xmcon/README              1 Instructions on using metaconfig.
Xmcon/U/AAAAA.U           7 Does magic before Head.U.
Xmcon/U/Chk_whoami.U      7 A unit which checks for conflicts.
Xmcon/U/Config_h.U        5 Makes config.h.SH--bizarrity here.
Xmcon/U/Config_sh.U       6 Makes config.sh.
Xmcon/U/Cppsym.U          4 Makes program to test for cpp symbols.
Xmcon/U/End.U             6 "End of configuration questions"
Xmcon/U/Filexp.U          5 Makes program to do tilde expansion.
Xmcon/U/Finish.U          4 A unit which always goes last.
Xmcon/U/Guess.U           3 Hazard guesses as to overall philosophy.
Xmcon/U/Head.U            5 First unit, does "#!/bin/sh" et al.
Xmcon/U/Init.U            6 Magically gathers ?Init: lines from other units.
Xmcon/U/Instruct.U        4 Prints instructions.
Xmcon/U/Loc.U             2 Look for common programs.
Xmcon/U/Log.U             5 Some stupid redefinitions to keep RCS happy.
Xmcon/U/Myinit.U          7 For copying to private U directories.
Xmcon/U/Myread.U          6 Makes program to do read with shell escape.
Xmcon/U/Null.U            7 Zeroes out variables.  Probably unnecessary.
Xmcon/U/Oldconfig.U       6 Looks for old config.sh file.
Xmcon/U/Warn_v7EXT.U      6 V7 has some ideosyncracies.
Xmcon/U/Warn_v7ND.U       6 V7 has no O_NDELAY read.
Xmcon/U/active.U          5 Find the news active file.
Xmcon/U/bin.U             6 Find where to install public executables.
Xmcon/U/cc.U              5 Find special compilers and options.
Xmcon/U/contains.U        6 Makes status-returning grep.
Xmcon/U/cppstdin.U          0
Xmcon/U/d_bcopy.U         6 Do we have bcopy() or memcpy()?
Xmcon/U/d_charsprf.U      5 How is sprintf() defined?
Xmcon/U/d_crypt.U         6 Does crypt() exist?
Xmcon/U/d_dosuid.U        4 Do they want setuid emulation?
Xmcon/U/d_fchmod.U        6 Do we have fchmod()?
Xmcon/U/d_fchown.U        6 Do we have fchown()?
Xmcon/U/d_fcntl.U         6 Do we have fcntl()?
Xmcon/U/d_flexfnam.U      5 Long filenames?
Xmcon/U/d_ftime.U         6 Do we have ftime()?
Xmcon/U/d_getgrps.U       6 Do we have getgroups()?
Xmcon/U/d_gethname.U      3 What is the C function to get host name?
Xmcon/U/d_getpwent.U      6 How is passwd info gotten?
Xmcon/U/d_havetlib.U      4 Where is termlib?
Xmcon/U/d_hidnet.U        4 Do hiddennet stuff?
Xmcon/U/d_index.U         5 index() vs strchr().
Xmcon/U/d_internet.U      5 Use internet addresses?
Xmcon/U/d_ioctl.U         6 Does sys/ioctl.h exist?
Xmcon/U/d_killpg.U        6 Do we have killpg()?
Xmcon/U/d_memcpy.U        6 Do we have memcpy()?
Xmcon/U/d_news.U          4 What kind of NeWS is here?
Xmcon/U/d_newsadm.U       5 Who is news administrator?
Xmcon/U/d_nolnbuf.U       4 Is stdout line buffered?
Xmcon/U/d_normsig.U       5 signal() vs sigset().
Xmcon/U/d_portable.U      5 How portable do we want to be?
Xmcon/U/d_raster.U        6 Is this a Raster Tech machine?
Xmcon/U/d_rdchk.U         6 Is rdchk() there to check for input?
Xmcon/U/d_rename.U        6 Do we have rename()?
Xmcon/U/d_scorfl.U        5 Keep scoreboards by full name?
Xmcon/U/d_setegid.U       6 Do we have setegid()?
Xmcon/U/d_seteuid.U       6 Do we have seteuid()?
Xmcon/U/d_setrgid.U       6 Do we have setrgid()?
Xmcon/U/d_setruid.U       6 Do we have setruid()?
Xmcon/U/d_sgndchr.U       6 Are chars signed?
Xmcon/U/d_speedopt.U      5 Optimize speed vs memory?
Xmcon/U/d_statblks.U      6 Does stat know about blksize and blocks?
Xmcon/U/d_stdstdio.U      6 How standard is stdio?
Xmcon/U/d_strcspn.U       6 Do we have strcspn()?
Xmcon/U/d_strctcpy.U      6 Do we do struct copies?
Xmcon/U/d_symlink.U       6 Does symlink() exist?
Xmcon/U/d_termio.U        5 Termio vs sgtty.
Xmcon/U/d_tminsys.U       6 Is struct tm in <sys/time.h>?
Xmcon/U/d_usendir.U       4 Use our own ndir routines?
Xmcon/U/d_vfork.U         6 vfork() vs fork().
Xmcon/U/d_voidsig.U       6 How is signal() declared?
Xmcon/U/d_whoami.U        6 Is there a whoami.h file?
Xmcon/U/defeditor.U       6 Find default editor.
Xmcon/U/filexp.U          6 Finds location of filexp made by Filexp.U.
Xmcon/U/fpu.U             5 What kind of Sun fpu is in use?
Xmcon/U/gidtype.U         5 What is the type of gids?
Xmcon/U/hostname.U        3 How to determine hostname from shell.
Xmcon/U/libc.U            4 Where is libc?
Xmcon/U/libnm.U           6 New math library?
Xmcon/U/locdist.U         3 Find distribution names for news.
Xmcon/U/maildir.U         6 Where is mail spooled.
Xmcon/U/mailer.U          5 What delivers mail?
Xmcon/U/mailfile.U        1 What filename in maildir?
Xmcon/U/mallocsrc.U       5 Use malloc included in kit?
Xmcon/U/mansrc.U          5 Where to put manual pages source.
Xmcon/U/mboxchar.U        5 How to determine if file is mailbox.
Xmcon/U/models.U          2 Large vs small, split I&D, etc.
Xmcon/U/n.U               6 How to suppress newline with echo.
Xmcon/U/nametype.U        3 How to get user's fullname.
Xmcon/U/newslevel.U       5 What version of news are we running?
Xmcon/U/newslib.U         4 Where is the news library?
Xmcon/U/newsspool.U       5 Where is news spooled?
Xmcon/U/orgname.U         5 What is the organizaton name?
Xmcon/U/package.U         7 Gets package name from .package magically.
Xmcon/U/pager.U           5 What's the pager, more or less?
Xmcon/U/prefshell.U       5 Preferred user shell.
Xmcon/U/privlib.U         5 Where is the private library?
Xmcon/U/randbits.U        5 How many bits in rand()?
Xmcon/U/registers.U       4 How many register declarations to use.
Xmcon/U/rootid.U          6 Root user id.
Xmcon/U/spitshell.U       5 Shell comment stripper, maybe.
Xmcon/U/startsh.U         6 How to guarantee sh startup.
Xmcon/U/stdchar.U         6 Are chars unsigned in stdio?
Xmcon/U/sunscanf.U        6 Is this Sun's version of scanf()?
Xmcon/U/uidtype.U         6 What is the type of uids?
Xmcon/U/voidflags.U       3 How supported is void?
Xmcon/makegloss           3 Extracts Glossary from Unit files.
Xmcon/metaconfig.SH       1 Writes Configure scripts for you.
Xmcon/metaconfig.man      2 Manual page for same.
Xpackinit.SH              2 Creates a .package file describing your package.
Xpat/Makefile.SH          4 Builds patch generator.
Xpat/README               1 Directions for patch generator.
Xpat/mailagent            4 A sample mail agent.
Xpat/mailpatch            4 A sample automatic patch mailer.
Xpat/pat.SH               4 Check in, do diffs, make patch, send it.
Xpat/pat.man              2 Manual page for same.
Xpat/patbase.SH           4 To set the base for future differences.
Xpat/patchlevel.h         7 A prototype patchlevel.h file.
Xpat/patcil.SH            2 Check in the latest changes.
Xpat/patdiff.SH           3 Find the differences since patbase.
Xpat/patftp.SH            4 Puts patches in ftp pub directory.
Xpat/patindex             7 Generate an index of patches sent out.
Xpat/patmake.SH           3 Put together a patch file.
Xpat/patpost.SH           3 Sends patches via news.
Xpat/patsend.SH           4 Sends patches via mail.
Xpatchlevel.h             3 The current patchlevel for dist.
Xpl/comment.pl            6 Perl library to find comment in front of $Log.
Xpl/fullname.pl           6 Perl library to get full name.
Xpl/logname.pl            2 Perl library to get login name.
Xpl/package.pl            6 Perl library to read .package.
Xpl/rangeargs.pl          6 Perl library to expand number lists.
Xpl/rcsargs.pl            6 Perl library to expand rcs filename lists.
!STUFFY!FUNK!
echo Extracting packinit.SH
sed >packinit.SH <<'!STUFFY!FUNK!' -e 's/X//'
Xcase $CONFIG in
X'')
X    if test ! -f config.sh; then
X	ln ../config.sh . || \
X	ln ../../config.sh . || \
X	ln ../../../config.sh . || \
X	(echo "Can't find config.sh."; exit 1)
X    fi
X    . ./config.sh
X    ;;
Xesac
X: This forces SH files to create target in same directory as SH file.
X: This is so that make depend always knows where to find SH derivatives.
Xcase "$0" in
X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
Xesac
Xecho "Extracting packinit (with variable substitutions)"
Xcat >packinit <<!GROK!THIS!
X#!/usr/bin/perl
X	eval "exec /usr/bin/perl -S \$0 \$*"
X		if \$running_under_some_shell;
X
X# $Header: packinit.SH,v 2.0 88/06/28 23:18:55 lwall Locked $
X#
X# $Log:	packinit.SH,v $
X# Revision 2.0  88/06/28  23:18:55  lwall
X# Baseline.
X# 
X
X\$orgname='$orgname';
X\$hostname='$hostname';
X\$mydomain='$mydomain';
X\$nametype='$nametype';
X!GROK!THIS!
X
X: In the following dollars and backticks do not need the extra backslash.
Xcat >>packinit <<'!NO!SUBS!'
X
Xprint '
XThis program designates the current directory as the top level directory
Xof a package on which you want to use the programs metaconfig, makedist,
Xor the patch generation programs.  It will not damage the current directory
Xin any way except to create a .package file.
X
X';
X
X$mypackver=1;
Xif (-f '.package') {
X    do readpackage();
X    if ($packver > $mypackver) {
X	die "This .package file was produced by a newer packinit than I am.\n".
X	    "Please find a packinit of version $packver or greater.\n";
X    }
X}
X
X# Now set up to do reads with possible shell escape.
Xsub myread {
X    ($rp,$dflt) = @_;
X    $rp .= " [$dflt]";
X    print "$rp ";
X    $ans='!';
X    while ($ans =~ /^!/) {
X	$ans = <stdin>;
X	chop($ans);
X	if ($ans eq '!') {
X	    system '/bin/sh';
X	    print "\n$rp ";
X	}
X	elsif ($ans =~ s/^!//) {
X	    system '/bin/sh', '-c', $ans;
X	    print "\n$rp ";
X	}
X    }
X    $ans = $dflt if $ans eq '';
X    $ans;
X}
X
X$dflt = $package;
X($dflt) = (`pwd` =~ m|.*/(.*)|) unless $package;
X
Xprint " 
XYour package will be known by some name, which should be a single word.
XGenerally it is the name of the chief executable program.
X
X";
X$package = do myread("What is the name of your package? ",$dflt);
X
Xif ($baserev ne '') {
X    $dflt=$baserev;
X}
Xelse {
X    print "\n";
X    $dflt='';
X    print "Checking RCS files for current version...";
X    @rcs = <RCS/*,v *,v>;
X    $rcs = shift(@rcs);
X    if (! -f $rcs) {
X	$rcs = shift(@rcs);
X	if (! -f $1) {
X	    print "I don't see any RCS files there (yet).";
X	    $dflt='1.1';
X	}
X    }
X    $revs=0;
X    if ($dflt eq '') {
X	$rlog = `rlog $rcs`;
X	($dflt) = ($rlog =~ /\nhead:\s*(\d+\.\d+)/);
X	$rlog = `rlog -r$dflt.1- -r$dflt.2- -r$dflt.3- -r$dflt.4- $rcs`;
X	($revs) = ($rlog =~ /selected revisions:\s*([\d.]+)/);
X	$dflt='1.1' if $dflt eq '';
X    }
X
X    print "
XTo use the patch generating portion of the system, you must have RCS.  You
Xmust begin with a freshly checked-in trunk revision (n.n) and choose a branch
Xnumber for patches.  The trunk revision upon which the patch branch is based
Xis called the base revision.
X
X";
X
X    if ($revs > 1) {
X	print
X"(The current revision ($dflt) has branches--you may have to check in a new
Xtrunk revision, or use patbase to mark the base revisions.)\n";
X	($first,$second) = split(/\./,$dflt);
X	++$second;
X	$dflt="$first.$second";
X    }
X}
X
Xprint "\n";
X$foo = do myread("What is or will be the base revision number? ", $dflt);
Xif ($baserev ne $foo) {
X    $baserev = $foo;
X    $ftpdir = '';		# invalidate ftp directory on version change
X}
X
Xprint "\n";
X
X$dflt = ($patchbranch ne '' ? $patchbranch : 1);
X$patchbranch =
X    do myread("What branch number do you want to use for patches? ", $dflt);
X
Xprint "\n";
X$dflt = ($mydiff eq '' ? 'n' : 'y');
X$ans = do myread(
X    "Do you want to use your own diff (rather than rcsdiff -c) for patches? ",
X    $dflt);
Xif ($ans =~ /^n/i) {
X    $mydiff='';
X}
Xelse {
X    $dflt = $mydiff || 'diff -c';
X    $mydiff = do myread("What diff command do you want to use? ", $dflt);
X}
X
Xprint "
XOver the lifetime of the $package package, people will want to request
Xdistribution kits and patches.  In particular, automatically generated
Xpatches will say where to get previous patches from.
X
X";
X$logname = do getlogname();
X$dflt = $maintname || do getfullname($logname);
X$maintname = do myread("Who should requests be sent to (full name)? ", $dflt);
X
Xprint "
XNow you need to give a one-line network mailing address for $maintname.
XIt does not need to be parseable by machine, but can be of the form:
X
X	{name1,name2,name3}!myhost!myname
X
X	or
X
X	myname@myhost.domain
X
X";
X$dflt = $maintloc || "$logname@$hostname$mydomain";
X$maintloc = do myread("What is the network mailing address? ", $dflt);
X
Xprint "\n";
X$dflt = ($ftpsite ? 'y' : 'n');
X$ans = do myread(
X    "Will you put patches where they can be acquired by anonymous FTP? ",$dflt);
Xif ($ans =~ /^n/i) {
X    $ftpsite='';
X}
Xelse {
X    print "\n";
X    $dflt = $ftpsite;
X    ($dflt = $maintloc) =~ s/.*@([^\s,()]*).*/$1/ unless $dflt;
X    $ftpsite = do myread("What is the Internet sitename for that? ",$dflt);
X}
X
Xprint "\n";
X$dflt = $orgname || $ENV{'ORGANIZATION'};
X$orgname = do myread("Organization: ",$dflt);
X
Xprint "\n";
X$dflt = $newsgroups || 'comp.sources.bugs';
X$newsgroups = do myread("Newsgroup(s) to post patches to: ", $dflt);
X
Xprint "\n";
X$dflt = $recipients || 'source-archives@mirror.TMC.COM';
X$recipients = do myread("Recipient(s) to send patches to: ",$dflt);
X
Xprint "\n";
Xif ($ftpsite) {
X    $dflt = $ftpdir || "/usr/spool/ftp/pub/$package.$baserev/patches";
X    $ftpdir = do myread("FTP directory to copy patches to: ",$dflt);
X}
Xelse {
X    $ftpdir = '';
X}
X
Xprint "\nCreating .package...\n";
Xopen(PACKAGE, '>.package') || die "Can't create .package";
Xprint PACKAGE
X": basic variables
Xpackage=$package
Xbaserev=$baserev
Xpatchbranch=$patchbranch
Xmydiff='$mydiff'
Xmaintname='$maintname'
Xmaintloc='$maintloc'
Xftpsite='$ftpsite'
Xorgname='$orgname'
Xnewsgroups='$newsgroups'
Xrecipients='$recipients'
Xftpdir='$ftpdir'
X
X: derivative variables--do not change
Xrevbranch=\"\$baserev.\$patchbranch\"
Xpackver='$mypackver'
X";
X
X!NO!SUBS!
Xcat pl/package.pl >>packinit
Xcat pl/logname.pl >>packinit
Xcat pl/fullname.pl >>packinit
Xchmod 755 packinit
X$eunicefix packinit
!STUFFY!FUNK!
echo Extracting pat/pat.man
sed >pat/pat.man <<'!STUFFY!FUNK!' -e 's/X//'
X.rn '' }`
X''' $Header: pat.man,v 2.0 88/06/28 23:19:20 lwall Locked $
X''' 
X''' $Log:	pat.man,v $
X''' Revision 2.0  88/06/28  23:19:20  lwall
X''' Baseline.
X''' 
X''' 
X.de Sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.de Sp
X.if t .sp .5v
X.if n .sp
X..
X'''
X'''     Set up \*(-- to give an unbreakable dash;
X'''     string Tr holds user defined translation string.
X'''
X.ie n \{\
X.tr \(*W-\*(Tr
X.ds -- \(*W-
X.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
X.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
X.ds L" ""
X.ds R" ""
X.ds L' '
X.ds R' '
X'br\}
X.el\{\
X.ds -- \(em\|
X.tr \*(Tr
X.ds L" ``
X.ds R" ''
X.ds L' `
X.ds R' '
X'br\}
X.TH PAT 1 LOCAL
X.SH NAME
Xpat,patcil,patdiff,patbase,patmake,patsend,patpost,patftp - patch generator
X.SH SYNOPSIS
X.B pat
X[options] [filelist]
X.br
X.B patcil
X[options] [filelist]
X.br
X.B patdiff
X[options] [filelist]
X.br
X.B patbase
X[options] [filelist]
X.br
X.B patmake
X[patch#]
X.br
X.B patsend
X[patchlist] [recipients]
X.br
X.B patpost
X[patchlist] [newsgroups]
X.br
X.B patftp
X[patchlist]
X.SH DESCRIPTION
X.I Pat
Xand its associated programs generate patches for any package that has been
Xstored under RCS.
XThese programs hide many of the details of RCS that get in your way when
Xconstructing and maintaining a package.
XAll you need to do to create a new patch is to edit your files, run pat,
Xand furnish some descriptions to RCS and in the generated patch file.
XDetails such as how to initialize a new RCS file, what the comment string should
Xbe, how create a new branch,
Xhow to deal with subdirectories, how to do diffs and how to
Xorganize the patch file are handled automatically.
X.PP
XBefore using any of the pat programs you must initialize your package by
Xrunning packinit in the top-level directory of your package.
XThis produces a .package file that all of the dist programs make use of.
X.PP
XIn any of the programs that want a filelist, if you specify
X.B \-a
Xinstead,
Xall files in MANIFEST.new will be processed.
XIn any of the programs that want a patchlist, a null patchlist means the
Xcurrent patch.
XYou may use hyphens, commas and spaces to delimit patch numbers.
XIf the right side of a hyphen is the null string, the current patchlevel
Xis assumed as the maximum value.
X.PP
XPat itself is a wrapper program that calls patcil, patdiff, and patmake.
XUsually you can just invoke pat and ignore all the others.
XIf you specify
X.B \-n
Xinstead of a filelist, pat will find all files that are
Xnewer than patchlevel.h, put you into an editor to trim down the list,
Xthen use that file list.
X.PP
XPatcil is used to do a ci -l on any listed files.
X(It is assumed that you always want to keep your files checked out.)
XIn addition to the
X.B \-a
Xswitch, there is a
X.B \-b
Xswitch which does a quick checkin of
Xa set of files.
XInstead of calling rcs on each file, it calls rcs on the whole list of
Xfiles.
XThis is useful for checking in a trunk revision.
XWhen you are checking in a new trunk revision you might also want to use
Xthe
X.B \-s
Xflag which will strip out old RCS Log entries from the previous revision
Xso that you can start over fresh.
XYou probably should also use a
X.B \-f
Xwhich is passed through to the ci to force unchanged files to be checked in.
XTo check in a new trunk revision, I say
X.nf
X
X	patcil -s -f -a
X
X.fi
X.PP
XPatcil will ask for the log entry instead of letting ci do it, and has a little
Xprompter built in that lets you manipulate the message in various ways.
XType h for a listing of what you can do.
XOne of the nicest things is that you can pop up into an editor, optionally
Xwith a diff listing of the changes since the last patch, in case you've
Xforgotten what you changed.
XIf you type a CR as the first thing, it includes the
Xprevious log message.
XExit the prompter with a CR.
X.PP
XThere are two different ways to use patcil.
XYou can either call patcil yourself, or let pat call it for you.
XIt doesn't matter how many times you call patcil before running pat, since
Xpatdiff knows what the last patch base is to compare with.
XPatcil can be called in any of your directories; the other programs must
Xbe called in your top-level directory (or in bugs, when meaningful).
X.PP
XPatbase can be used to reset the patch base to the current version when
Xyou've scrapped the previous patch sequence and are making a new distribution
Xkit.
XWhat it really does is an rcs -Nlastpat:REV, where REV is the current
Xrevision.
XIf patdiff blows up and you want to set the patch base back to some previous
Xversion, you have to call rcs -Nlastpat:REV yourself.
X.PP
XPatdiff actually does the diffs that go into the patch, comparing whatever
Xversion -Nlastpat points to with the most recently checked in version.
XIt then updates -Nlastpat to point to the current version.
XIt leaves the diff sitting in the bugs subdirectory for patmake to pick up.
XIt can either use rcsdiff, or a diff command of your choice specified when
Xyou run packinit, in case your diff is better than rcsdiff.
X.PP
XPatmake combines all the pieces of the patch into one file and invokes
Xan editor so you can add the subject and description.
XIt throws all your log messages in as Subjects and as Description, under
Xthe assumption
Xthat it's easier to delete what you don't want than to remember everything
Xyou did.
XYou'll also want to expand each item in the Description so they don't just
Xrepeat the Subject lines.
X.PP
XPatsend, patpost and patftp are used to distribute your patches to the world.
XPatsend mails a set of patches to a set of recipients.
XPatpost posts a set of patches to a set of newsgroups.
XPatftp merely copies the patch into your public ftp directory.
X.SH ENVIRONMENT
XNo environment variables are used by
X.IR metaconfig .
X.SH FILES
Xbugs/*
X.SH SEE ALSO
Xmetaconfig(1)
X.br
Xmakedist(1)
X.SH DIAGNOSTICS
X.SH CAVEATS
X.SH BUGS
XMost of this should be built into RCS.
X.rn }` ''
!STUFFY!FUNK!
echo Extracting mcon/U/models.U
sed >mcon/U/models.U <<'!STUFFY!FUNK!' -e 's/X//'
X?RCS:$Header: models.U,v 2.0 88/06/28 23:17:24 lwall Locked $
X?RCS: $Log:	models.U,v $
X?RCS: Revision 2.0  88/06/28  23:17:24  lwall
X?RCS: Baseline.
X?RCS: 
X?MAKE:models split small medium large huge ccflags ldflags: test cat echo n c Myread Cppsym
X?MAKE:	-pick add $@ %*
X?S:models:
X?S:	This variable contains the list of memory models supported by this
X?S:	system.  Possible component values are none, split, unsplit, small,
X?S:	medium, large, and huge.  The component values are space separated.
X?S:.
X?S:split:
X?S:	This variable contains a flag which will tell the C compiler and loader
X?S:	to produce a program that will run in separate I and D space, for those
X?S:	machines that support separation of instruction and data space.  It is
X?S:	up to the Makefile to use this.
X?S:.
X?S:small:
X?S:	This variable contains a flag which will tell the C compiler and loader
X?S:	to produce a program running with a small memory model.  It is up to
X?S:	the Makefile to use this.
X?S:.
X?S:medium:
X?S:	This variable contains a flag which will tell the C compiler and loader
X?S:	to produce a program running with a medium memory model.  If the
X?S:	medium model is not supported, contains the flag to produce large
X?S:	model programs.  It is up to the Makefile to use this.
X?S:.
X?S:large:
X?S:	This variable contains a flag which will tell the C compiler and loader
X?S:	to produce a program running with a large memory model.  It is up to
X?S:	the Makefile to use this.
X?S:.
X?S:huge:
X?S:	This variable contains a flag which will tell the C compiler and loader
X?S:	to produce a program running with a huge memory model.  If the
X?S:	huge model is not supported, contains the flag to produce large
X?S:	model programs.  It is up to the Makefile to use this.
X?S:.
X?S:ccflags:
X?S:	This variable contains any additional C compiler flags desired by
X?S:	the user.  It is up to the Makefile to use this.
X?S:.
X?S:ldflags:
X?S:	This variable contains any additional C loader flags desired by
X?S:	the user.  It is up to the Makefile to use this.
X?S:.
X: see what memory models we can support
Xcase "$models" in
X'')
X    if Cppsym pdp11; then
X	dflt='unsplit split'
X    else
X	ans=`loc . X /lib/small /lib/large /usr/lib/small /usr/lib/large /lib/medium /usr/lib/medium /lib/huge`
X	case "$ans" in
X	X) dflt='none';;
X	*)  if $test -d /lib/small || $test -d /usr/lib/small; then
X		dflt='small'
X	    else
X		dflt=''
X	    fi
X	    if $test -d /lib/medium || $test -d /usr/lib/medium; then
X		dflt="$dflt medium"
X	    fi
X	    if $test -d /lib/large || $test -d /usr/lib/large; then
X		dflt="$dflt large"
X	    fi
X	    if $test -d /lib/huge || $test -d /usr/lib/huge; then
X		dflt="$dflt huge"
X	    fi
X	esac
X    fi
X    ;;
X*)  dflt="$models" ;;
Xesac
X$cat <<EOM
X 
XSome systems have different model sizes.  On most systems they are called
Xsmall, medium, large, and huge.  On the PDP11 they are called unsplit and
Xsplit.  If your system doesn't support different memory models, say "none".
XIf you wish to force everything to one memory model, say "none" here and
Xput the appropriate flags later when it asks you for other cc and ld flags.
XVenix systems may wish to put "none" and let the compiler figure things out.
X(In the following question multiple model names should be space separated.)
X
XEOM
Xrp="Which models are supported? [$dflt]"
X$echo $n "$rp $c"
X. myread
Xmodels="$ans"
X
Xcase "$models" in
Xnone)
X    small=''
X    medium=''
X    large=''
X    huge=''
X    unsplit=''
X    split=''
X    ;;
X*split)
X    case "$split" in
X    '') 
X	if $contains '\-i' $mansrc/ld.1 >/dev/null 2>&1 || \
X	   $contains '\-i' $mansrc/cc.1 >/dev/null 2>&1; then
X	    dflt='-i'
X	else
X	    dflt='none'
X	fi
X	;;
X    *) dflt="$split";;
X    esac
X    rp="What flag indicates separate I and D space? [$dflt]"
X    $echo $n "$rp $c"
X    . myread
X    case "$ans" in
X    none) ans='';;
X    esac
X    split="$ans"
X    unsplit=''
X    ;;
X*large*|*small*|*medium*|*huge*)
X    case "$model" in
X    *large*)
X	case "$large" in
X	'') dflt='-Ml';;
X	*) dflt="$large";;
X	esac
X	rp="What flag indicates large model? [$dflt]"
X	$echo $n "$rp $c"
X	. myread
X	case "$ans" in
X	none) ans='';
X	esac
X	large="$ans"
X	;;
X    *) large='';;
X    esac
X    case "$model" in
X    *huge*)
X	case "$huge" in
X	'') dflt='-Mh';;
X	*) dflt="$huge";;
X	esac
X	rp="What flag indicates huge model? [$dflt]"
X	$echo $n "$rp $c"
X	. myread
X	case "$ans" in
X	none) ans='';
X	esac
X	huge="$ans"
X	;;
X    *) huge="$large";;
X    esac
X    case "$model" in
X    *medium*)
X	case "$medium" in
X	'') dflt='-Mm';;
X	*) dflt="$medium";;
X	esac
X	rp="What flag indicates medium model? [$dflt]"
X	$echo $n "$rp $c"
X	. myread
X	case "$ans" in
X	none) ans='';
X	esac
X	medium="$ans"
X	;;
X    *) medium="$large";;
X    esac
X    case "$model" in
X    *small*)
X	case "$small" in
X	'') dflt='none';;
X	*) dflt="$small";;
X	esac
X	rp="What flag indicates small model? [$dflt]"
X	$echo $n "$rp $c"
X	. myread
X	case "$ans" in
X	none) ans='';
X	esac
X	small="$ans"
X	;;
X    *) small='';;
X    esac
X    ;;
X*)
X    echo "Unrecognized memory models--you may have to edit Makefile.SH"
X    ;;
Xesac
X
Xcase "$ccflags" in
X'') dflt='none';;
X*) dflt="$ccflags";;
Xesac
Xecho " "
Xrp="Any additional cc flags? [$dflt]"
X$echo $n "$rp $c"
X. myread
Xcase "$ans" in
Xnone) ans='';
Xesac
Xccflags="$ans"
X
Xcase "$ldflags" in
X'') if venix; then
X	dflt='-i -z'
X    else
X	dflt='none'
X    fi
X    ;;
X*) dflt="$ldflags";;
Xesac
Xecho " "
Xrp="Any additional ld flags? [$dflt]"
X$echo $n "$rp $c"
X. myread
Xcase "$ans" in
Xnone) ans='';
Xesac
Xldflags="$ans"
X
!STUFFY!FUNK!
echo Extracting mcon/U/Loc.U
sed >mcon/U/Loc.U <<'!STUFFY!FUNK!' -e 's/X//'
X?RCS:$Header: Loc.U,v 2.0 88/06/28 23:13:25 lwall Locked $
X?X: 
X?X: This unit produces a shell script "loc" which can be used to find out
X?X: where in a list of directories something is.  It then uses loc to
X?X: determine the location of commonly used programs.  It leaves loc sitting
X?X: around for other Configure units to use, but arranges for its demise
X?X: at the end of Configure.
X?X: 
X?X: To add a new program to find, add it both to the ?MAKE: line and to either
X?X: the loclist or trylist variable.
X?X: 
X?RCS: $Log:	Loc.U,v $
X?RCS: Revision 2.0  88/06/28  23:13:25  lwall
X?RCS: Baseline.
X?RCS: 
X?MAKE:Loc loclist expr sed echo cat rm mv cp tail tr mkdir sort uniq grep trylist test inews egrep more pg Mcc vi mailx mail cpp: startsh eunicefix n c Myread Oldconfig
X?MAKE:	-pick weed $@ %*
X?INIT:pth="/usr/ucb /bin /usr/bin /usr/local /usr/local/bin /usr/lbin /etc /usr/lib /lib"
X: find out where common programs are
Xecho " "
Xecho "Locating common programs..."
Xcat <<EOSC >loc
X$startsh
Xcase \$# in
X0) exit 1;;
Xesac
Xthing=\$1
Xshift
Xdflt=\$1
Xshift
Xfor dir in \$*; do
X    case "\$thing" in
X    .)
X	if test -d \$dir/\$thing; then
X	    echo \$dir
X	    exit 0
X	fi
X	;;
X    *)
X	if test -f \$dir/\$thing; then
X	    echo \$dir/\$thing
X	    exit 0
X	elif test -f \$dir/\$thing.exe; then
X	    : on Eunice apparently
X	    echo \$dir/\$thing
X	    exit 0
X	fi
X	;;
X    esac
Xdone
Xecho \$dflt
Xexit 1
XEOSC
Xchmod +x loc
X$eunicefix loc
Xloclist="
X?expr:expr
X?sed:sed
X?echo:echo
X?cat:cat
X?rm:rm
X?mv:mv
X?cp:cp
X?tail:tail
X?tr:tr
X?mkdir:mkdir
X?sort:sort
X?uniq:uniq
X?grep:grep
X"
Xtrylist="
X?test:test
X?inews:inews
X?egrep:egrep
X?more:more
X?pg:pg
X?Mcc:Mcc
X?vi:vi
X?mailx:mailx
X?mail:mail
X?cpp:cpp
X"
Xfor file in $loclist; do
X    xxx=`loc $file $file $pth`
X    eval $file=$xxx
X    eval _$file=$xxx
X    case "$xxx" in
X    /*)
X	echo $file is in $xxx.
X	;;
X    *)
X	echo "I don't know where $file is.  I hope it's in everyone's PATH."
X	;;
X    esac
Xdone
Xecho " "
Xecho "Don't worry if any of the following aren't found..."
Xans=offhand
Xfor file in $trylist; do
X    xxx=`loc $file $file $pth`
X    eval $file=$xxx
X    eval _$file=$xxx
X    case "$xxx" in
X    /*)
X	echo $file is in $xxx.
X	;;
X    *)
X	echo "I don't see $file out there, $ans."
X	ans=either
X	;;
X    esac
Xdone
Xcase "$egrep" in
Xegrep)
X    echo "Substituting grep for egrep."
X    egrep=$grep
X    ;;
Xesac
Xcase "$test" in
Xtest)
X    echo "Hopefully test is built into your sh."
X    ;;
X/bin/test)
X    echo " "
X    dflt=n
X    rp="Is your "'"'"test"'"'" built into sh? [$dflt] (OK to guess)"
X?X: we don't know how $echo treats $n and $c yet, so use builtin
X    echo $n "$rp $c"
X    . myread
X    case "$ans" in
X    y*) test=test ;;
X    esac
X    ;;
X*)
X    test=test
X    ;;
Xesac
Xcase "$echo" in
Xecho)
X    echo "Hopefully echo is built into your sh."
X    ;;
X/bin/echo)
X    echo " "
X    echo "Checking compatibility between /bin/echo and builtin echo (if any)..."
X    $echo $n "hi there$c" >foo1
X    echo $n "hi there$c" >foo2
X    if cmp foo1 foo2 >/dev/null 2>&1; then
X	echo "They are compatible.  In fact, they may be identical."
X    else
X	case "$n" in
X	'-n') n='' c='\c' ans='\c' ;;
X	*) n='-n' c='' ans='-n' ;;
X	esac
X	cat <<FOO
XThey are not compatible!  You are probably running ksh on a non-USG system.
XI'll have to use /bin/echo instead of the builtin, since Bourne shell doesn't
Xhave echo built in and we may have to run some Bourne shell scripts.  That
Xmeans I'll have to use $ans to suppress newlines now.  Life is ridiculous.
X
XFOO
X	rp="Your cursor should be here-->"
X	$echo $n "$rp$c"
X	. myread
X    fi
X    $rm -f foo1 foo2
X    ;;
X*)
X    : cross your fingers
X    echo=echo
X    ;;
Xesac
Xrmlist="$rmlist loc"
X
!STUFFY!FUNK!
echo Extracting pl/logname.pl
sed >pl/logname.pl <<'!STUFFY!FUNK!' -e 's/X//'
Xsub getlogname {
X    local($logname) = $ENV{'USER'};
X    $logname = $ENV{'LOGNAME'} unless $logname;
X    chop($logname = `who am i`) unless $logname;
X    $logname =~ s/\s.*//;
X    $logname =~ s/.*!//;
X    $logname;
X}
X
!STUFFY!FUNK!
echo Extracting mcon/U/cppstdin.U
sed >mcon/U/cppstdin.U <<'!STUFFY!FUNK!' -e 's/X//'
X?RCS:$Header: cppstdin.U,v 1.0.1.1 88/01/21 22:53:18 lwall Exp $
X?RCS: $Log:	cppstdin.U,v $
X?RCS: Revision 1.0.1.1  88/01/21  22:53:18  lwall
X?RCS: Now assumes input to cpp will be via stdin.  cppminus is '-' if necessary.
X?RCS: 
X?RCS: Revision 1.0  87/05/22  12:30:23  lwall
X?RCS: Initial revision
X?RCS: 
X?MAKE:cppstdin cppminus: contains echo n c Myread Oldconfig Loc cpp
X?MAKE:	-pick add $@ %*
X?S:cppstdin:
X?S:	This variable contains the command which will invoke the C
X?S:	preprocessor on standard input and put the output to stdout.
X?S:	It is primarily used by other Configure units that ask about
X?S:	preprocessor symbols.
X?S:.
X?S:cppminus:
X?S:	This variable contains the second part of the string which will invoke
X?S:	the C preprocessor on the standard input and produce to standard
X?S:	output.  This variable will have the value "-" if cppstdin needs a minus
X?S:	to specify standard input, otherwise the value is "".
X?S:.
X?C:CPPSTDIN:
X?C:	This symbol contains the first part of the string which will invoke
X?C:	the C preprocessor on the standard input and produce to standard
X?C:	output.	 Typical value of "cc -E" or "/lib/cpp".
X?C:.
X?C:CPPMINUS:
X?C:	This symbol contains the second part of the string which will invoke
X?C:	the C preprocessor on the standard input and produce to standard
X?C:	output.  This symbol will have the value "-" if CPPSTDIN needs a minus
X?C:	to specify standard input, otherwise the value is "".
X?C:.
X?H:?%1:#define CPPSTDIN "$cppstdin"
X?H:?%1:#define CPPMINUS "$cppminus"
X?H:?%1:
X: see how we invoke the C preprocessor
Xecho " "
Xecho "Now, how can we feed standard input to your C preprocessor..."
Xcat <<'EOT' >testcpp.c
X#define ABC abc
X#define XYZ xyz
XABC.XYZ
XEOT
Xecho 'Maybe "'$cpp'" will work...'
X$cpp <testcpp.c >testcpp.out 2>&1
Xif $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X    echo "Yup, it does."
X    cppstdin="$cpp"
X    cppminus='';
Xelse
X    echo 'Nope, maybe "'$cpp' -" will work...'
X    $cpp - <testcpp.c >testcpp.out 2>&1
X    if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X	echo "Yup, it does."
X	cppstdin="$cpp"
X	cppminus='-';
X    else
X	echo 'No such luck...maybe "cc -E" will work...'
X	cc -E <testcpp.c >testcpp.out 2>&1
X	if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X	    echo "It works!"
X	    cppstdin='cc -E'
X	    cppminus='';
X	else
X	    echo 'Nixed again...maybe "cc -E -" will work...'
X	    cc -E - <testcpp.c >testcpp.out 2>&1
X	    if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X		echo "Hooray, it works!  I was beginning to wonder."
X		cppstdin='cc -E'
X		cppminus='-';
X	    else
X		echo 'Nope...maybe "cc -P" will work...'
X		cc -P <testcpp.c >testcpp.out 2>&1
X		if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X		    echo "Yup, that does."
X		    cppstdin='cc -P'
X		    cppminus='';
X		else
X		    echo 'Nope...maybe "cc -P -" will work...'
X		    cc -P - <testcpp.c >testcpp.out 2>&1
X		    if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X			echo "Yup, that does."
X			cppstdin='cc -P'
X			cppminus='-';
X		    else
X			echo 'Hmm...perhaps you already told me...'
X			case "$cppstdin" in
X			'') ;;
X			*) $cppstdin $cppminus <testcpp.c >testcpp.out 2>&1;;
X			esac
X			if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X			    echo "Hooray, you did!  I was beginning to wonder."
X			else
X			    echo 'Uh-uh.  Time to get fancy...'
X			    echo 'Trying (cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
X			    cppstdin='(cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
X			    cppminus='';
X			    $cppstdin <testcpp.c >testcpp.out 2>&1
X			    if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X				echo "Eureka!."
X			    else
X				dflt=blurfl
X				$echo $n "No dice.  I can't find a C preprocessor.  Name one: $c"
X				rp='Name a C preprocessor:'
X				. myread
X				cppstdin="$ans"
X				$cppstdin <testcpp.c >testcpp.out 2>&1
X				if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
X				    echo "OK, that will do."
X				else
X				    echo "Sorry, I can't get that to work.  Go find one."
X				    exit 1
X				fi
X			    fi
X			fi
X		    fi
X		fi
X	    fi
X	fi
X    fi
Xfi
Xrm -f testcpp.c testcpp.out
X
!STUFFY!FUNK!
echo ""
echo "End of kit 2 (of 7)"
cat /dev/null >kit2isdone
run=''
config=''
for iskit in 1 2 3 4 5 6 7; do
    if test -f kit${iskit}isdone; then
	run="$run $iskit"
    else
	todo="$todo $iskit"
    fi
done
case $todo in
    '')
	echo "You have run all your kits.  Please read README and then type Configure."
	chmod 755 Configure
	;;
    *)  echo "You have run$run."
	echo "You still need to run$todo."
	;;
esac
: Someone might mail this, so...
exit

-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.