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