[comp.sources.d] Here's the configuration program for ash

ka@june.cs.washington.edu (Kenneth Almquist) (05/31/89)

The following shell procedure is used to configure ash, which was
recently posted to comp.sources.unix.  Run this shell procedure,
answer the questions it asks, and it will create shell.h for you.
(Of course it may be easier to create shell.h by hand.)  This is
being posted here because it was't written back when I submitted
ash to comp.sources.unix.
				Kenneth Almquist



------------------------------ cut here ------------------------------
: Create shell.h		$#Use_sh_not_csh
: Based on code by Larry Wall.

: Copyright 1989 by Kenneth Almquist.  All rights reserved.
: This file is part of ash, which is distributed under the terms specified
: by the Ash General Public License.  See the file named LICENSE.

: sanity checks
PATH="/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/new:/usr/new/bin:/usr/nbin:$PATH"

if test ! -t 0; then
    echo "Say 'sh config', not 'sh < config'"
    exit 1
fi

echo "Config program for ash."
echo " "

libpth='/usr/lib /usr/local/lib /lib'
rmlist=
include=/usr/include
fastread=

: some greps do not return status, grrr.
echo "grimblepritz" >temp
if grep blurfldyick temp >/dev/null 2>&1 ; then
    contains=contains
elif grep grimblepritz temp >/dev/null 2>&1 ; then
    contains=grep
else
    contains=contains
fi
rm -f temp
: the following should work in any shell
case "$contains" in
contains*)
    echo " "
    echo "AGH!  Grep doesn't return a status.  Attempting remedial action."
    cat >contains <<'EOSS'
grep "$1" "$2" >greptemp && cat greptemp && test -s greptemp
EOSS
    chmod +x contains
    rmlist="$rmlist contains greptemp"
    ;;
esac

: first determine how to suppress newline on echo command
echo "Checking echo to see how to suppress newlines..."
(echo "hi there\c" ; echo " ") >temp
if $contains c temp >/dev/null 2>&1 ; then
    echo "...using -n."
    n='-n'
    c=''
else
    cat <<'EOM'
...using \c
EOM
    n=''
    c='\c'
fi
echo $n "Type carriage return to continue.  Your cursor should be here-->$c"
read ans
rm -f temp

: now set up to do reads with possible shell escape and default assignment
cat <<EOSC >myread
case "\$fastread" in
yes) ans=''; echo " " ;;
*) ans='!';;
esac
while expr "X\$ans" : "X!" >/dev/null; do
    read ans
    case "\$ans" in
    !)
	sh
	echo " "
	echo $n "\$rp $c"
	;;
    !*)
	set \`expr "X\$ans" : "X!\(.*\)\$"\`
	sh -c "\$*"
	echo " "
	echo $n "\$rp $c"
	;;
    esac
done
rp='Your answer:'
case "\$ans" in
'') ans="\$dflt";;
esac
EOSC

: general instructions
cat <<EOH
 
This installation shell script will examine your system and ask you questions
to determine how ash should be installed.  If you get stuck on a question,
you may use a ! shell escape to start a subshell or execute a command.  Many
of the questions will have default answers in square brackets--typing carriage
return will give you the default.

If this shell script doesn't work for some reason, you will have to create
shell.h by hand.  This isn't too hard to do; sample versions of shell.h for
for Berkeley UNIX and System V are included in the distribution.  Also, if
you make a mistake in answering a question, you can edit shell.h after this
procedure finishes.

EOH
rp="[Type carriage return to continue]"
echo $n "$rp $c"
. ./myread

: get list of predefined functions in a handy place
echo " "
if test -f /lib/libc.a; then
    echo "Your C library is in /lib/libc.a.  You're normal."
    libc=/lib/libc.a
else
    libc=
    for dir in $libpth ; do
	if test -f $dir/libc.a ; then
	    libc=$dir/libc.a
	    break
	fi
	if test -f $dir/clib ; then
	    libc=$dir/clib
	    break
	fi
	if test -f $dir/libc ; then
	    libc=$dir/libc
	    break
	fi
    done
    if test $libc ; then
	echo "Your C library is in $libc, of all places."
    else
	cat <<EOM
 
I can't seem to find your C library.  I've looked in the following places:

	$libpth

None of these seems to contain your C library.  What is the full name
EOM
	dflt=None
	echo $n "of your C library? $c"
	rp='C library full name?'
	. ./myread
	libc="$ans"
    fi
fi
echo " "
echo $n "Extracting names from $libc for later perusal...$c"
nm $libc 2>/dev/null >libc.tmp
sed -n -e 's/^.* [AT] _//p' -e 's/^.* [AT] //p' <libc.tmp >libc.list
if $contains '^printf$' libc.list >/dev/null 2>&1; then
    echo "done"
else
    sed -n -e 's/^.* D _//p' -e 's/^.* D //p' <libc.tmp >libc.list
    $contains '^printf$' libc.list >/dev/null 2>&1 || \
       sed -n -e 's/^_//' \
	      -e 's/^\([a-zA-Z_0-9]*\).*xtern.*text.*/\1/p' <libc.tmp >libc.list
    if $contains '^printf$' libc.list >/dev/null 2>&1; then
	echo "done"
    else
	echo " "
	echo "nm didn't seem to work right."
	echo "Trying ar instead..."
	if ar t $libc > libc.tmp; then
	    sed -e 's/\.o$//' < libc.tmp > libc.list
	    echo "Ok."
	else
	    echo "ar didn't seem to work right."
	    echo "Maybe this is a Cray...trying bld instead..."
	    if bld t $libc | sed -e 's/.*\///' -e 's/\.o:.*$//' > libc.list; then
		echo "Ok."
	    else
	    	echo "That didn't work either.  Giving up."
	    	exit 1
	    fi
	fi
    fi
fi
rmlist="$rmlist libc.tmp libc.list"

: Locate the /usr/include directory
if test ! -d "$include" ; then
    echo " "
    echo "Hey, $include doesn't exist on this system!"
    echo "I need to know the location of your header files to figure out what type"
    echo "of system you are on."
    while test true ; do
	dflt=None
	rp='Where do include files reside on this system?'
	echo $n "$rp $c"
	. ./myread
	include="$ans"
	if test ! -d "$ans" ; then
	    echo "$ans does not exist."
	elif test ! -f "$ans/stdio.h" ; then
	    echo "$ans is a pretty pathetic excuse for an include directory"
	    echo $n "since it doesn't include stdio.h.  Use it anyway? [n] $c"
	    dflt=n
	    rp="Include files are in $ans? [$dflt]"
	    . ./myread
	    if test "X$ans" = Xy -o "X$ans" = Xyes ; then
		break
	    fi
	else
	    break
	fi
    done
fi

: make some quick guesses about what we are up against
echo " "
echo $n "Hmm...  $c"
if test -f $include/sys/socket.h -a \( -f /usr/bin/ranlib -o -f /usr/ucb/ranlib \) ; then
    echo "Looks kind of like a BSD system, but we'll see..."
    systype=bsd
elif $contains '^fcntl$' libc.list >/dev/null 2>&1 ; then
    echo "Looks kind of like a USG system, but we'll see..."
    systype=sys5
else
    echo "Looks kind of like a version 7 system, but we'll see..."
    systype=v7
fi
if $contains '^vmssystem$' libc.list >/dev/null 2>&1 ; then
    cat <<'EOI'
You appear to be running Eunice.  Lucky you.  I haven't tested ash
under Eunice; let me know if it works.
EOI
    eunicefix=unixtovms
    eunice=yes
: it so happens the Eunice I know will not run shell scripts in Unix format
else
    echo " "
    echo "Congratulations.  You aren't running Eunice."
    eunicefix=':'
    eunice=no
fi
if test -f /xenix; then
    echo "Actually, this looks more like a XENIX system..."
    xenix=yes
else
    echo " "
    echo "It's not Xenix..."
    xenix=no
fi
if test -f /venix; then
    echo "Actually, this looks more like a VENIX system..."
    venix=yes
else
    echo " "
    if test "$xenix" = yes; then
	: null
    else
	echo "Nor is it Venix."
    fi
    venix=yes
fi

: Now determine the C compiler.  Default is gcc if present.
dflt=cc
for dir in `echo $PATH | tr : ' '` ; do
    if test -f "$dir/gcc" ; then
	dflt=gcc
    fi
done
echo " "
rp="What is the name of your C compiler? [$dflt]"
echo $n "$rp $c"
. ./myread
cc=$ans

echo " "
if $contains SIGTSTP $include/sys/signal.h >/dev/null 2>&1 ; then
    echo "I see you have Berkeley job control."
    jobs=1
elif $contains SIGTSTP $include/signal.h >/dev/null 2>&1 ; then
    echo "I see you have Berkeley job control."
    jobs=1
else
    echo "You don't seem to have Berkeley job control.  Too bad."
    jobs=0
fi

: see if symlink exists
echo " "
if $contains '^symlink$' libc.list >/dev/null 2>&1; then
    echo 'Your system has symbolic links.'
    symlinks=1
else
    echo 'No symbolic links on your system.'
    symlinks=0
fi

: test for system V directory routines
echo " "
if test -f $include/dirent.h ; then
    echo 'You appear to have the System V directory access routines.'
    dirent=1
elif test "$systype" = bsd ; then
    echo 'I assume you have the Berkeley directory access routines.'
    dirent=0
else
    echo "Your system doesn't contain directory access routines, which is"
    echo "fine if you have Version 7 format directories."
    dirent=0
fi

: Tell user whether atty will be supported
echo " "
if test "$systype" = bsd ; then
    echo "Since you are on a BSD system, I'll compile in support for atty."
    atty=1
else
    echo "Since atty only works on BSD systems, I assume you don't want it."
    atty=0
fi

if test $symlinks = 1 -a -d /u ; then
    echo " "
    echo "You appear to have the /u directory on your system."
    if test ! -d /u/root ; then
	echo "However, there is no entry for root.  If you have questions"
	echo "about the /u directory, read the DIFFERENCES file."
    fi
    udir=0
else
    if test $symlinks = 1 ; then
	cat <<\!

By convention, the home directory of a user is referred to using the
name /u/user.  Since you have symbolic links on your system, you can
create /u and place symbolic links in it pointing to the home directories
of the users of the system.  However, ash does contain code to replace
/u/user with the name of the home directory of the user, and you can use
this code instead of creating /u if you want to.
!
	dflt=n
    else
	cat <<\!

By convention, the home directory of a user is referred to using the
name /u/user.  Unfortunately, the /u directory is typically implemented
using symbolic links, which your system appears not to have.  To support
systems like yours, ash contains code to replace /u/user with the name
of the home directory of the user.
!
	dflt=y
    fi
    udir=unset
    while test $udir = unset ; do
	rp="Do you want ash to include this code? [$dflt]"
	echo $n "$rp $c"
	. ./myread
	case "$ans" in
	y*)  udir=1 ;;
	n*)  udir=0 ;;
	*)   echo "Please answer 'y' or 'n'" ;;
	esac
    done
fi

echo " "
echo "Now let's test out your C compiler..."

cat > ctemp1.c <<\!
main() {
#ifdef __STDC__
	exit(0);
#else
	exit(1);
#endif
}

verylongname1() {
	return 1;
}
!
cat > ctemp2.c <<\!
verylongname2() {
	return 2;
}
!
if $cc -c ctemp1.c ctemp2.c ; then
    :
else
    echo "What's with your compiler?  I'm giving up!"
    rm -f myread $rmlist
    exit 1
fi
if $cc -o ctemp ctemp1.o ctemp2.o >/dev/null 2>&1 ; then
    echo 'Good, your C compiler understands long names.'
    shortnames=0
else
    cat <<\!
Your C compiler	appears to truncate external identifiers, so we will
have to make sure all global identifiers are unique when truncated to
six characters.
!
    shortnames=1
    $cc -o ctemp ctemp1.o
fi

: if not ansi C, check for volatile support
if ./ctemp ; then
    echo "Your C compiler claims to be ANSI, so I'll assume it understands volatile"
    volatile=ansi
else
    cat > ctemp2.c <<\!
main() {
    volatile int x;
    x = 0;
    return x;
}
!
    echo " "
    if $cc -c ctemp2.c >/dev/null 2>&1 ; then
	echo "Your C compiler accepts the volatile keyword even though it's not ANSI."
	volatile=yes
    else
	echo "Your C compiler doesn't have (and presumably doesn't need) the"
	echo "volatile keyword."
	volatile=no
    fi
fi
rm -f ctemp1.c ctemp2.c ctemp1.o ctemp2.o ctemp

echo " "
if test "`(cd //; pwd)`" = / ; then
    echo "You appear to have a fairly normal UNIX file system."
else
    cat <<\!
Your file system appears to interpred // at the start of a file name
differently from a single slash at the start of the file name, which
will probably cause the pwd command to malfunction.  This problem hasn't
been fixed because the writer of ash (Kenneth Almquist) doesn't have
access to any systems that behave this way.  You can probably get a
version of pwd for your system in return for a description of how your
system interprets file names and a promise to test out the code.  In
!
    echo $n "the mean time, type return to continue...$c"
    rp="Type return to continue:"
    . myread
fi


: Now create shell.h
echo " "
echo $n "Creating shell.h...$c"

cat > shell.h <<\!
/*
 * Copyright (C) 1989 by Kenneth Almquist.  All rights reserved.
 * This file is part of ash, which is distributed under the terms specified
 * by the Ash General Public License.  See the file named LICENSE.
 */

/*
 * The follow should be set to reflect the type of system you have:
 *	JOBS -> 1 if you have Berkeley job control, 0 otherwise.
 *	SYMLINKS -> 1 if your system includes symbolic links, 0 otherwise.
 *	DIRENT -> 1 if your system has the SVR3 directory(3X) routines.
 *	UDIR -> 1 if you want the shell to simulate the /u directory.
 *	ATTY -> 1 to include code for atty(1).
 *	SHORTNAMES -> 1 if your linker cannot handle long names.
 *	define BSD if you are running 4.2 BSD or later.
 *	define SYSV if you are running under System V.
 *	define DEBUG to turn on debugging.
 *
 * When debugging is on, debugging info will be written to $HOME/trace and
 * a quit signal will generate a core dump.
 */


!
echo "#define JOBS $jobs" >>shell.h
echo "#define SYMLINKS $symlinks" >>shell.h
echo "#define DIRENT $dirent" >>shell.h
echo "#define UDIR $udir" >>shell.h
echo "#define ATTY $atty" >>shell.h
echo "#define SHORTNAMES $shortnames" >>shell.h
if test $systype = bsd ; then
    echo "#define BSD" >>shell.h
else
    echo "/* #define BSD */" >>shell.h
fi
if test $systype = sys5 ; then
    echo "#define SYSV" >>shell.h
else
    echo "/* #define SYSV */" >>shell.h
fi
cat >> shell.h <<\!
/* #define DEBUG */



#if SHORTNAMES
#include "shortnames.h"
#endif


#ifdef __STDC__
typedef void *pointer;
#ifndef NULL
#define NULL (void *)0
#endif
#else /* not __STDC__ */
#define const
!
if test $volatile = yes ; then
    echo "/* #define volatile */" >>shell.h
else
    echo "#define volatile" >>shell.h
fi
cat >> shell.h <<\!
typedef char *pointer;
#ifndef NULL
#define NULL 0
#endif
#endif /* __STDC__ */
#ifdef __GNUC__ /* Gcc lets us declare that functions don't return */
#define noreturn volatile
#else
#define noreturn
#endif
#define STATIC	/* empty */
#define MKINIT	/* empty */

extern char nullstr[1];		/* null string */


#ifdef DEBUG
#define TRACE(param)	trace param
#else
#define TRACE(param)
#endif
!
echo done

: Now update the makefile
echo " "
echo "Editing makefile to reflect your choice of C compiler..."

chmod u+w makefile
ed - makefile <<!
/^CC=/s/=.*/=$cc/p
w
q
!
echo done

echo " "
echo "Edit shell.h by hand if you want to make any changes."
echo "Then run make."

rm -f myread $rmlist