#!/bin/sh
# Yaf77 - Yet another f77-style shell script to compile and load fortran, 
# C, and assembly codes
# This file is a part of the Yaf77 package.
# Copyleft 95-97 Evgeny Stambulchik <fnevgeny@plasma-gate.weizmann.ac.il>

PATH=/bin:/usr/bin:/usr/local/bin
PROG=`basename $0`
VERSION=Yaf77-1.6

set -o noclobber

CPP=${CPP:-/lib/cpp}
F2C=${F2C:-/usr/bin/f2c}
CC=${CC_f2c:-/usr/bin/gcc}
AS=${AS:-/usr/bin/as} 
CPPFLAGS=
F2CFLAGS=${F2CFLAGS:='-A -Nn802'}
CFLAGS=
# Linux w/ gcc >= 2.7.2.1:
OPTBUGFLAG=''
# Linux w/ gcc < 2.7.2.1:
#OPTBUGFLAG='-fno-strength-reduce'
# HP:
# OPTBUGFLAG=
AFLAGS=
LDFLAGS=
LIBFLAGS=
LIBF77EXT='-lF77ext'
# Linux:
F2CLIBS='-lf2c -lm'
# HP:
# F2CLIBS='-lF77 -lI77 -lm'
TMP=/tmp

s=/tmp/stderr_$$
t=/tmp/f77_$$
rc=0
cOPT=1
trap "rm -f $s ; exit \$rc" 0

Yaf77Help()
{
cat << EOHELP

     $VERSION
 Copyleft 1995-98 E. Stambulchik <fnevgeny@plasma-gate.weizmann.ac.il>

usage:
        yaf77 [-options ...] <files>

where options include:
    -c                           no linking, leave relocatables
    -o _file_                    place output in file _file_
    -u                           make the default type of all variables
                                   \`undefined'
    -w                           suppress all warning messages
    -w66                         suppress Fortran 66 compatibility warnings
    -free                        assume free-format input
    -C                           check that subscripts  are  within declared
                                   array bounds
    -N_t_nnn                     allow nnn entries in table _t_
    -r8                          promote REAL to DOUBLE PRECISION, COMPLEX 
                                   to DOUBLE COMPLEX
    -bs|-fno-backslash           do not interpret backslash escapes in
                                   character strings
    -g                           add debugging symbols
    -pg                          compile with profiling support
    -no-F77ext                   do not link against F77ext library
    -I _dir_                     append directory _dir_ to  the list of
                                   directories searched for include files;
                                   affects both #include and INCLUDE statements
    -D _macro_<=definition>      pass macro _macro_ to preprocessor
    -U _macro_                   undefines macro _macro_
    -B _prefix_                  add _prefix_ to search path of C compiler
    -b _machine_                 compile for target _machine_
    -aout                        for Linux dual aout/elf boxes, compile in aout
                                   format; the same as \`-b i486-linuxaout'
    -m386|-m486|-m586|-m686      make specific code optimizations for Intel 
                                   processors 
    -ieee|-mieee-fp              make executables confirm to the IEEE floating  
                                   point standards
    -pipe                        use pipes instead of temporary files during
                                   compilation (after f2c translation done)
    -O0                          do not optimize (default)
    -O|-O1 ... -O9               perform different levels of optimization
    -S                           stop before assembling; leave assembler codes
    -fpic                        generate position-independent code (for
                                   dynamic linking)
    -fPIC                        the same as above, even if branches need
                                   large displacements
    -l_library_                  use the library named _library_ when linking
    -L _dir_                     add directory _dir_ to the list of directories
                                   to be searched for \`-l'
    -s                           strip executable
    -static                      produce statically linked executables
    -f2carg _arg_                pass argument _arg_ to f2c translator
    -ccarg _arg_                 pass argument _arg_ to C compiler
    -asarg _arg_                 pass argument _arg_ to assembler
    -ldarg _arg_                 pass argument _arg_ to linker
    -v                           verbose execution
    -vv                          be more verbose
    -V                           print out version info and exit
    -help                        print out this message
    
files:
    *.f                          FORTRAN source files
    *.F                          FORTRAN sources, to be preprocessed
    *.[c,C]                      C/C++ source files
    *.s                          Assembly language files
    *.[o,a]                      Relocatables and ar archives
    *.[so,sa]*                   Shared libraries
EOHELP
}

case $? in 0);; *) exit 1;; esac
while
	test X"$1" != X
do
	case "$1"
	in
	-c)	cOPT=0
		shift
		;;

	-o)	OUTF="-o $2"
		shift 2
		;;

	-D)	CPPFLAGS="$CPPFLAGS -D$2"
		shift 2
		;;

	-D*)    CPPFLAGS="$CPPFLAGS $1"
		shift
		;;

	-U)	CPPFLAGS="$CPPFLAGS -U$2"
		shift 2
		;;

	-U*)    CPPFLAGS="$CPPFLAGS $1"
		shift
		;;

	-I)	CPPFLAGS="$CPPFLAGS -I$2"
	        F2CFLAGS="$F2CFLAGS -I$2"
		shift 2
		;;

	-I*)    CPPFLAGS="$CPPFLAGS $1"
		F2CFLAGS="$F2CFLAGS $1"
		shift
		;;

	-u)	F2CFLAGS="$F2CFLAGS -u"
		shift
		;;

	-w)	F2CFLAGS="$F2CFLAGS -w"
		shift
		;;

	-w66)   F2CFLAGS="$F2CFLAGS -w66"
		shift
		;;

	-free)	F2CFLAGS="$F2CFLAGS -f"
		shift
		;;

	-N)	F2CFLAGS="$F2CFLAGS $1""$2"
		shift 2
		;;

	-N*)    F2CFLAGS="$F2CFLAGS $1"
		shift 1
		;;

	-C)	F2CFLAGS="$F2CFLAGS $1"
		shift 1
		;;

	-r8)    F2CFLAGS="$F2CFLAGS -r8"
		shift
		;;

	-bs|-fno-backslash)
	        F2CFLAGS="$F2CFLAGS -!bs"
		shift
		;;

	-g)	CFLAGS="$CFLAGS -g"
		F2CFLAGS="$F2CFLAGS -g"
		LDFLAGS="$LDFLAGS -g"
		shift;;

	-pg)	CFLAGS="$CFLAGS -pg"
		LDFLAGS="$LDFLAGS -pg"
		shift;;

	-B)	CFLAGS="$CFLAGS -B$2"
		shift 2
		;;

	-B*)    CFLAGS="$CFLAGS $1"
		shift
		;;

	-O0|-O|-O1)
		CFLAGS="$CFLAGS $1"
		shift
		;;

	-O[2-9])
		CFLAGS="$CFLAGS $1 $OPTBUGFLAG"
		shift
		;;

	-pipe)  CFLAGS="$CFLAGS -pipe"
		shift
		;;

	-m386|-m486)
		CFLAGS="$CFLAGS $1"
		shift
		;;

	-m586)
                CFLAGS="$CFLAGS -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2"
		shift
		;;

	-m686)
                CFLAGS="$CFLAGS -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -malign-double"
		shift
		;;

	-fPIC)  CFLAGS="$CFLAGS -fPIC"
		shift
		;;

	-fpic)  CFLAGS="$CFLAGS -fpic"
		shift
		;;

	-S)	CFLAGS="$CFLAGS -S"
		cOPT=0
		shift
		;;
		
	-b)     CFLAGS="$CFLAGS -b $2"
	        LDFLAGS="$LDFLAGS -b $2"
		shift 2
		;;

	-b*)    CFLAGS="$CFLAGS $1"
	        LDFLAGS="$LDFLAGS $1"
		shift
		;;

	-aout)  CFLAGS="$CFLAGS -b i486-linuxaout"
	        LDFLAGS="$LDFLAGS -b i486-linuxaout"
		shift
		;;

	-ieee|-mieee-fp)
	        LDFLAGS="$LDFLAGS -mieee-fp"
		shift
		;;

	-s)     LDFLAGS="$LDFLAGS -s"
		shift
		;;

	-static) 
	        LDFLAGS="$LDFLAGS -static"
		shift
		;;

	-L)     LIBFLAGS="$LIBFLAGS -L$2"
		shift 2
		case $cOPT in 1) cOPT=2;; esac
		;;

	-L*)    LIBFLAGS="$LIBFLAGS $1"
		shift
		case $cOPT in 1) cOPT=2;; esac
		;;

	-l)	LIBFLAGS="$LIBFLAGS -l$2"
		shift 2
		case $cOPT in 1) cOPT=2;; esac
		;;

        -l*)    LIBFLAGS="$LIBFLAGS $1"
		shift
		case $cOPT in 1) cOPT=2;; esac
		;;

	-f2carg)
                F2CFLAGS="$F2CFLAGS $2"
		shift 2
		;;

	-ccarg) CFLAGS="$CFLAGS $2"
		shift 2
		;;

	-asarg)
		AFLAGS="$AFLAGS $2"
		shift 2
		;;

        -ldarg) LDFLAGS="$LDFLAGS $2"
		shift 2
		;;

	-no-F77ext)
		LIBF77EXT=
		shift 
		;;

	-v)     VERBOSE=1
		shift 
		;;
		
	-vv)    VERBOSE=1
	    	CFLAGS="$CFLAGS -v"
	    	LDFLAGS="$LDFLAGS -v"
		shift 
		;;
		
	-V)     echo "$PROG: version $VERSION"
		exit 
		;;

	-help)  Yaf77Help
		exit 
		;;

	-*)     echo "$PROG: unrecognized option $1; -help lists all accepted options" 1>&2
		shift
		;;

	*.[fFcCs])
		SRCFILES="$SRCFILES $1"
		shift
		;;

	*.o)
		OFILES1="$OFILES1 $1"
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;

	*.a|*.s[a,o]*)
		LIBFLAGS="$LIBFLAGS $1"
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;

	*)  echo "$PROG: don't know what to do with \`$1'" 1>&2
		shift
		;;
	esac
done

INPFILES="$SRCFILES $OFILES1"
LIBFLAGS="$LIBFLAGS $LIBF77EXT $F2CLIBS"

if [ $VERBOSE ]; then
	echo "$PROG:"
	echo "    f2c flags: " $F2CFLAGS
	echo "    c flags: "$CFLAGS
	echo "    as flags: "$AFLAGS
	echo "    ld flags: "$LDFLAGS
	echo "    libraries: "$LIBFLAGS
	echo "    input files: "$INPFILES
fi

if ( [ "$INPFILES" = " " ] ); then
	echo "$PROG: No input files specified."
	echo ""
	rc=1
	exit
fi

if [ $VERBOSE ]; then
	echo "$PROG: Processing source files..."
fi

for srcfile in $SRCFILES
do
	case "$srcfile" in 
	*.[fF])
                case "$srcfile" in
                        *.f)    b=`basename $srcfile .f`
                                C_TMP_=$TMP/_$b.c
                                C_TMP=$TMP/$b.c
                                rm -f $C_TMP_ $C_TMP $t $s
                                $F2C $F2CFLAGS < $srcfile > $C_TMP_ || exit 1
                                rc=$?
                                sed 's/\ ""$/\ "'$b'.f"/' < $C_TMP_ > $C_TMP || exit 1
                                rm -f $C_TMP_
                                ;;
                        *.F)    b=`basename $srcfile .F`
                                C_TMP=$TMP/$b.c
                                C_TMP_=$TMP/_$b.c
                                rm -f $C_TMP_ $C_TMP $t $s
                                $CPP $CPPFLAGS $srcfile > $b.i || exit 1
                                rc=$?
                                case $rc in 0);; *) exit ;; esac
                                $F2C $F2CFLAGS < $b.i > $C_TMP_ || exit 1
                                rc=$?
                                sed 's/\ ""$/\ "'$b'.F"/' < $C_TMP_ > $C_TMP || exit 1
                                rm -f $C_TMP_ $b.i
                                ;;
                esac
                case $rc in 0);; *) exit ;; esac
                case $cOPT in 0)OUTOF=$OUTF;; *);; esac
                $CC -c $CPPFLAGS $CFLAGS $C_TMP $OUTOF 2>$s || exit 1
                rc=$?
                sed '/parameter .* is not referenced/d;/warning: too many parameters/d' $s 1>&2
                case $rc in 0);; *) exit;; esac
                OFILES2="$OFILES2 $b.o"
                rm $C_TMP
                case $cOPT in 1) cOPT=2;; esac
                ;;
	*.c)
		echo $srcfile: 1>&2
		OFILE=`basename $srcfile .c`.o
                $CC -c $CPPFLAGS $CFLAGS $srcfile
		rc=$?; case $rc in 0);; *) exit;; esac
		OFILES2="$OFILES2 $OFILE"
		case $cOPT in 1) cOPT=2;; esac
		;;
	*.s)
		echo $srcfile: 1>&2
		OFILE=`basename $srcfile .s`.o
		$AS -o $OFILE $AFLAGS $srcfile
		rc=$?; case $rc in 0);; *) exit;; esac
		OFILES2="$OFILES2 $OFILE"
		case $cOPT in 1) cOPT=2;; esac
		;;
	esac
done

case $cOPT in 2) $CC $LDFLAGS $OUTF $OFILES1 $OFILES2 $LIBFLAGS 
		 rc=$?
		 case $rc in 0) rm -f $OFILES2 ;; esac
		 ;; 
esac

exit 
