#!/bin/sh
#
# config ---	Script to configure the Portable Forth Environment
#		automatically. Applicable on UNIX systems.
#
# Unix users: please execute `config' like this
#
#	config [ CC="your preferred C-compiler" ] [ --prefix=directory ]
#
# If no compiler is specified the script prefers gcc if available, else
# assumes cc is a good name for a compiler.
# Then check if the two files generated by this script:
#
#	makefile
#	config.h
#
# describe your system adequately.
#
# Users of non-Unix systems probably can't execute this script.
# If I did it for them :-) they find the result in the files
#
#	../<sys>/makefile
#	../<sys>/config.h
#
# where <sys> is your system.
# Simply move them here then type `make' if you have make...
#
# (duz 26Apr94)
#


until [ $# -eq 0 ]
do
  case $1 in
    CC=*)
	CC=`echo $1 | cut -d'=' -f2` ;;
    PREFIX=*|--prefix=*)
	PREFIX=`echo $1 | cut -d'=' -f2` ;;
    *)
	break ;;
  esac
  shift
done

if [ $# -eq 0 ]
then
  system=`uname`
  makefile=makefile
  config_h=config.h
else
  system=$1
  makefile=makefile.$1
  config_h=config.$1
fi

echo "Configuring pfe for $system." >&2

if [ -z "$CC" ]
then
  if gcc -v >/dev/null 0>&1
  then
    echo "Found gcc, using it."
    CC=gcc
  else
    echo "Please ignore a warning about gcc not found!" >&2
    CC=cc
  fi
fi


#########################################################################
# Create the makefile:							#
#########################################################################

if [ -f $makefile ]
then
  echo "Keeping makefile in makefile.old." >&2
  mv $makefile makefile.old
fi

echo "Creating $makefile" >&2
exec 1>$makefile

cat << EOF
#
# makefile ---	makefile for portable Forth environment.
#		This file was generated automatically
#		  `date`
#		on machine
#		  `uname -a`
#		by script
#		  $0
#

EOF

case $system in
  "template")
	echo "# A comment indicating the type of system detected."
	echo "SYSTEM	= Identifying id for a -Did option"
	echo "CC	= C-Compiler to use"
	echo "OPTS	= Additional compiler options"
	echo "OPTIM	= Optimization flags for your C-compiler"
	echo "DEBUG	= Compiler flags to enable debugging"
	echo "STRIP	= Linker flags to strip symbol table from executable"
	echo "LFLAGS	= Any other linker flags neccessary"
	echo "LIBS	= Additional libraries beyond -lm and -lc"
	echo "TERM_O	= Terminal driver object file"
	echo "SYS_O	= System dependent extensions object file"
    ;;
  Linux)
	echo "# Linux version."
	echo "SYSTEM	= Linux"
	echo "# specifying -ansi -pedantic disables global register variables"
    case `uname --machine` in
      i486)
	echo "CC	= gcc -m486 -pipe -Wall# -ansi -pedantic"
	;;
      *)
	echo "CC	= gcc -Wall# -ansi -pedantic"
	;;
    esac
	echo "OPTIM	= -O2 -fomit-frame-pointer -DUSE_REGS"
	echo "DEBUG	= -g -O"
	echo "STRIP	= -s"
	echo "LFLAGS	= "
	echo "#OPTS	= -I/usr/include/ncurses"
	echo "#LIBS	= -lncurses"
	echo "OPTS	= -DUSE_TERMCAP"
	echo "LIBS	= -ltermcap"
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
    ;;
  FreeBSD)
	echo "# FreeBSD version."
	echo "SYSTEM	= FreeBSD"
	echo "CC	= gcc -m486 -pipe -Wall"
	echo "OPTS	= -D_BSD -DUSE_TERMCAP"
	echo "OPTIM	= -O2 -fomit-frame-pointer -DUSE_REGS"
	echo "DEBUG	= -g"
	echo "STRIP	= -s"
	echo "LFLAGS	= -static"
	echo "LIBS	= -ltermcap"
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
    ;;
  EMX)
	echo "# EMX version."
	echo "SYSTEM	= EMX"
	echo "CC	= gcc -m486 -Wall"
	echo "OPTS	= "
	echo "OPTIM	= -O2 -fomit-frame-pointer -DUSE_REGS"
	echo "DEBUG	= -g"
	echo "STRIP	= -s"
	echo "LFLAGS	= "
	echo "LIBS	= -lvideo"
	echo "TERM_O	= term-emx.o"
	echo "SYS_O	= emx.o"
    ;;
  AIX)
    case `uname -m` in
      i?86)
	echo "# AIX 1 version."
	echo "SYSTEM	= AIX1"
	echo "CC	= gcc -pipe"
	echo "OPTS	= -DHAVE_SELECT"
	echo "OPTIM	= -O2 -fomit-frame-pointer -DUSE_REGS"
	echo "DEBUG	= -g -O"
	echo "STRIP	= -s"
	echo "LFLAGS	= "
	echo "LIBS	= -lcurses"
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
        ;;
      *)
	echo "# AIX 3 version."
 	echo "SYSTEM	= AIX3"
	if [ $CC = gcc ]
	then
	  echo "CC	= gcc -pipe -Wall"
	  echo "OPTS	= -DUSE_REGS"
	  echo "OPTIM	= -O2"
	  echo "DEBUG	= -g -O"
	else
	  echo "CC	= cc"
	  echo "OPTS	= "
	  echo "OPTIM	= -O3"
	  echo "DEBUG	= -g"
	fi
	echo "STRIP	= -s"
	echo "LFLAGS	= "
	echo "LIBS	= -lcurses"
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
	;;
    esac
    ;;
  HP-UX)
	echo "# HP-UX version."
	echo "SYSTEM	= HPUX"
    if [ $CC = gcc ]
    then
	echo "CC	= gcc -pipe -Wall"
	echo "OPTS	= -D_HPUX_SOURCE -DUSE_TERMCAP -DUSE_REGS"
	echo "OPTIM	= -O2 -fomit-frame-pointer"
	echo "DEBUG	= -g -O"
    else
	echo "CC	= c89 -Aa"
	echo "OPTS	= -D_HPUX_SOURCE -DUSE_TERMCAP"
	echo "# Most HP-UX have broken cc -O, try later if your's is ok."
	echo "OPTIM	= +O1"
	echo "DEBUG	= -g"
    fi
	echo "STRIP	= -s"
	echo "LFLAGS	= -L/lib/pa1.1"
	echo "LIBS	= -lcurses"
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
    ;;
  SunOS)
	echo '# SunOS/Solaris version.'
	echo 'SYSTEM	= SunOS'
    if [ $CC = gcc ]
    then
	echo 'CC	= gcc -pipe -Wall'
	echo 'OPTS	= -D_BSD #-DUSE_REGS'
	echo 'OPTIM	= -O2 -fomit-frame-pointer'
	echo 'DEBUG	= -g -O'
    else
	echo 'CC	= CC'
	echo 'OPTS	= -D_BSD'
	echo 'OPTIM	= -O4'
	echo 'DEBUG	= -g'
    fi
	echo 'STRIP	= -s'
	echo 'LFLAGS	= '
	echo 'LIBS	= -ltermcap -lucb'
	echo 'TERM_O	= termcap.o'
	echo 'SYS_O	= unix.o'
    ;;
  ULTRIX)
	echo "# ULTRIX version."
	echo "SYSTEM	= ULTRIX"
    if [ $CC = gcc ]
    then
	echo "CC	= gcc -Wall"
	echo "OPTIM	= -O2 -fomit-frame-pointer -DUSE_REGS"
	echo "DEBUG	= -g -O"
    else
	echo "CC	= cc -std1"
	echo "OPTIM	= -O2"
	echo "DEBUG	= -g"
    fi
	echo "OPTS	= -D_BSD -DUSE_TERMCAP -DHAVE_SELECT"
	echo "STRIP	= -s"
	echo "LFLAGS	= "
	echo "LIBS	= -ltermlib"
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
    ;;
  OSF1)
	echo "# OSF1 version."
	echo "SYSTEM	= OSF1"
    if [ $CC = gcc ]
    then
	echo "CC	= gcc -Wall"
	echo "OPTS	= -D_BSD -DUSE_REGS"
	echo "OPTIM	= -O2 -fomit-frame-pointer"
	echo "DEBUG	= -g -O"
    else
	echo "CC	= cc"
	echo "OPTS	= -D_BSD"
	echo "OPTIM	= -O2"
	echo "DEBUG	= -g"
    fi
	echo "STRIP	= -s"
	echo "LFLAGS	= "
	echo "LIBS	= -ltermlib"
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
    ;;
  *)
	echo 'I don't know your UNIX system. Using defaults.' >&2
	echo 'You'll have to check the files config.h and makefile.' >&2
	echo 'Please read the file install!' >&2
	echo '# Generic UNIX version.'
	echo "SYSTEM	= UNIX"
	#
	# check for gcc:
	#
	if [ -n "$prefergcc" ]
	then
	  echo "CC	= gcc -Wall"
	  #
	  # check gcc version:
	  #
	  gcc -v 2>&1 | grep version | read dummy version
	  case $version in
	    2.*) echo "OPTIM	= -O2 -fomit-frame-pointer" ;;
	    *)   echo "OPTIM	= -O" ;;
	  esac
	else
	  #
	  # assume standard cc:
	  #
	  echo "CC	= cc"
	  echo "OPTIM	= -O"
	fi
	#
	# defaults for all other options:
	#
	echo '# You MUST check file "install" if you need -D_BSD.'
	echo '# Read file "tuning" for the meaning of -DUSE_REGS.'
	echo "OPTS	= # -DBSD -DUSE_REGS"
	echo "DEBUG	= -g"
	echo "STRIP	= -s"
	echo "LFLAGS	= "
	if [ -f /lib/libtermcap.a -o -f /usr/lib/libtermcap.a ]
	then
	  echo "LIBS	= -ltermcap"
	elif [ -f /lib/libtermc.a -o -f /usr/lib/libtermc.a ]
	then
	  echo "LIBS	= -ltermc"
	elif [ -f /lib/libcurses.a -o -f /usr/lib/libcurses.a ]
	then
	  echo "LIBS	= -lcurses"
	else
	  echo "LIBS	= # you'll probably have to insert something here"
	fi
	echo "TERM_O	= termcap.o"
	echo "SYS_O	= unix.o"
esac

echo "PREFIX	= ${PREFIX-/usr/local}"
echo 'PFELIB	= $(PREFIX)/lib/pfe'
echo 'PFEHLP	= $(PFELIB)/help'

echo '

# if you want a final optimized version uncomment these lines:
 CFLAGS =	$(OPTS) $(OPTIM) -D$(SYSTEM) -DPREFIX=\"$(PREFIX)\"
 LDFLAGS =	$(OPTS) $(STRIP) $(LFLAGS)

# if you want a version for C-level debugging uncomment these lines:
# CFLAGS =	$(OPTS) $(DEBUG) -D$(SYSTEM) -DPREFIX=\"$(PREFIX)\"
# LDFLAGS =	$(OPTS) $(DEBUG) $(LFLAGS)


#==============================================================================
# dependencies
#==============================================================================

# object files that should be clean ANSI-C:
ANSOBJ =	core.o block.o double.o xception.o facility.o file.o \
		floating.o locals.o memory.o toolkit.o search.o string.o \
		forth-83.o lpf83.o misc.o showhelp.o debug.o dblsub.o \
		support.o dictnry.o vocs.o lined.o term.o version.o

# object files containing environmental dependencies:
ENVOBJ =	main.o $(TERM_O) 4ed.o signals.o sysdep.o $(SYS_O) shell.o \
		yours.o

OBJECTS =	$(ANSOBJ) $(ENVOBJ)

HEADERS =	forth.h config.h virtual.h options.h const.h types.h macros.h \
		support.h preload.h compiler.h dblsub.h term.h help.h lined.h


all:		pfe helpidx showhelp


pfe:		$(OBJECTS)
		$(CC) $(LDFLAGS) -o pfe $(OBJECTS) $(LIBS) -lm
		rm version.o

$(OBJECTS):	$(HEADERS)

.c.s:
		$(CC) $(CFLAGS) -S $<


clean:
		rm -rf	pfe helpidx showhelp core \
			*.core *.o *.s *.bak *~ '"'#'*'#'"'

new:		clean all

veryclean:	clean
		rm -f config.* makefile*

testit:		pfe
		( cd ..; src/pfe testsuite; cd src )


# Rules for the standalone help programs:

helpidx:	helpidx.o helpsub.o
		$(CC) $(LDFLAGS) -o helpidx helpidx.o helpsub.o

showhelp:	showhlps.o helpsub.o
		$(CC) $(LDFLAGS) -o showhelp showhlps.o helpsub.o

showhlps.o:	showhelp.c $(HEADERS)
		$(CC) $(CFLAGS) -DSTANDALONE -c showhelp.c -o showhlps.o

helpidx.o:	helpidx.c $(HEADERS)
		$(CC) $(CFLAGS) -DSTANDALONE -c helpidx.c -o helpidx.o

helpsub.o:	helpsub.c $(HEADERS)
		$(CC) $(CFLAGS) -DSTANDALONE -c helpsub.c -o helpsub.o

install:	all
		if [ ! -d $(PFELIB) ]; then mkdir $(PFELIB); fi	;\
		if [ ! -d $(PFEHLP) ]; then mkdir $(PFEHLP); fi	;\
		cp -p helpidx showhelp ../help/*.hlp $(PFEHLP)	;\
		cd $(PFEHLP)					;\
		helpidx -o $(PFEHLP)/index *.hlp
'


#########################################################################
# Create config.h:							#
#########################################################################

case $system in
  EMX) exit 0;;
  # others with fixed config.??
esac

if [ -f $config_h ]
then
  echo "Keeping $config_h in config.old." >&2
  mv $config_h config.old
fi

echo "Creating $config_h" >&2
exec 1>$config_h

cat << EOF
/*
 * config.h --	Automatically generated file, don't change.
 *		This one made
 *		  `date`
 *		on
 *		  `uname -a`
 *		by script
 *		  $0
 */

#ifndef __CONFIG_H
#define __CONFIG_H

EOF

if [ -z "$INCDIR" ]; then INCDIR=/usr/include;	fi
if [ -z "$LIBDIR" ]; then LIBDIR=/usr/lib;	fi

echo '#define HOST_SYSTEM "'`uname`'"'

# determine Cell type, byte sex and alignment restrictions:
###########################################################

if $CC check_c.c -o check_c >&2
then
  ./check_c
  rm check_c
else
  echo compiling test program failed >&2
  echo aborting. >&2
  rm $config_h
  exit 1
fi

# check for fpos_t
##################

if grep fpos_t /usr/include/stdio.h >/dev/null 2>&1
then :
else
  echo "#define fpos_t long"
fi

# assume ISO 8891 character set:
################################

echo "#define ISO_CHARSET"

# check for hyperbolic functions:
#################################

if grep acosh $INCDIR/math.h >/dev/null 2>&1
then
  echo "#define HAVE_AH_TRIG 1"
fi

# check for memmove:
####################

if grep memmove $INCDIR/string.h >/dev/null 2>&1
then
  echo "#define HAVE_MEMMOVE 1"
else
  echo "void memmove (char *, const char *, unsigned);"
fi

# check for stpcpy:
###################
#
#if grep stpcpy $INCDIR/string.h >/dev/null 2>&1
#then :
#else
#  echo "#define stpcpy(DST,SRC) (strcpy(DST,SRC) + strlen(SRC))"
#fi

# check for strdup:
###################

if grep strdup $INCDIR/string.h >/dev/null 2>&1
then
  echo "#define HAVE_STRDUP 1"
else
  echo "char *strdup (const char *);"
fi

# check for strerror:
#####################

if grep strerror $INCDIR/string.h >/dev/null 2>&1
then :
else
  if grep sys_errlist $INCDIR/stdio.h >/dev/null 2>&1
  then :
  else
    echo "extern char *sys_errlist [];"
  fi
  echo "#define strerror(x) sys_errlist [x]"
fi

# check for pow10
#################

if grep pow10 $INCDIR/math.h >/dev/null 2>&1
then :
else
  echo "#define pow10(X) pow (10.0, (X))"
fi

# check for sys_siglist[]:
##########################

if grep '_sys_siglist' $INCDIR/signal.h >/dev/null 2>&1
then
  echo "#define HAVE_SYS_SIGLIST 1"
  echo "#define sys_siglist _sys_siglist"
elif grep 'sys_siglist' $INCDIR/signal.h >/dev/null 2>&1
then
  echo "#define HAVE_SYS_SIGLIST 1"
fi

# check for incorrect sprintf:
##############################

if grep 'int.*sprintf' $INCDIR/stdio.h >/dev/null 2>&1
then :
else
  echo "#define WRONG_SPRINTF"
fi

# check for atexit:
###################

if grep atexit $INCDIR/stdlib.h >/dev/null 2>&1
then
  echo "#define eXit(X) exit(X)"
else
  echo "typedef void (*atexit_fp) (void);"
  echo "int atexit (atexit_fp);"
  echo "void eXit (int);"
fi

# check for raise:
##################

if grep raise $INCDIR/signal.h $INCDIR/sys/signal.h >/dev/null 2>&1
then
  echo "#define HAVE_RAISE 1"
else
  echo "#define raise(X) kill (getpid (), X)"
fi

# check for siglongjmp:
#######################
#
# if grep siglongjmp $INCDIR/setjmp.h >/dev/null 2>&1
# then
#   echo "#define HAVE_SIGLONGJMP 1"
# else
#   echo "#define sigjmp_buf jmp_buf"
#   echo "#define sigsetjmp(BUF) setjmp (BUF)"
#   echo "#define siglongjmp(BUF,N) longjmp (BUF,N)"
# fi

# check for remove:
###################

if grep remove $INCDIR/stdio.h >/dev/null 2>&1
then
  echo "#define HAVE_REMOVE 1"
else
  echo "#define remove unlink"
fi

# check for rename:
###################

if grep rename $INCDIR/stdio.h >/dev/null 2>&1
then
  echo "#define HAVE_RENAME 1"
else
  echo "int rename (const char *, const char *);"
fi

# check for kind of terminal stuff:
###################################

if [ -f $INCDIR/termios.h ]
then
  echo "#define HAVE_TERMIOS_H 1"
fi

if [ -f $INCDIR/termio.h ]
then
  echo "#define HAVE_TERMIO_H 1"
fi

if [ -f $INCDIR/termcap.h ]
then
  echo "#define HAVE_TERMCAP_H 1"
  for i in $LIBDIR/*termcap*
  do
    if [ $i != "$LIBDIR/*termcap*" ]
    then
      echo "#define HAVE_TERMCAP 1"
      break
    fi
  done
fi

# Time related:
###############

if [ -f $INCDIR/unistd.h ]
then
  if grep usleep $INCDIR/unistd.h >/dev/null 2>&1
  then
    echo "#define HAVE_USLEEP 1"
  fi
  if grep select $INCDIR/unistd.h $INCDIR/time.h \
		 $INCDIR/sys/time.h >/dev/null 2>&1
  then
    echo "#define HAVE_SELECT 1"
  fi
fi

if [ -f $INCDIR/poll.h -o -f $INCDIR/sys/poll.h ]
then
  echo "#define HAVE_POLL 1"
fi


echo "#endif"


echo "config finished" >&2
exit 0
