#!/bin/sh
PATH=$PATH:/bin:/usr/bin:/usr/pkg/bin
#
# This script has deviated so much from "fc" that it is now easier to
# maintain it as its own file instead of a patch.  Some improvements
# over "fc" are:
#
# -O    for optimization
# -fPIC for PIC support
# -Wxxx for gcc warnings
# -Wl,  for additional linker arguments
# -pg   for profiled code
# -r8   promote REAL and COMPLEX to DOUBLE REAL and DOUBLE COMPLEX
# -s    to strip executible 
# -v    for verbose output
# -compatibility_version, -install_name, -current_version    for libtool on darwin gcc
# 
# Also only pass -m* to the C compiler not f2c.
# 
# Unknown options are passed on to the C compiler and C preprocessor.
# 
#USAGESTART
# f77-style shell script to compile and load fortran, C, and assembly codes
#
#	usage:	f2c-f77 [options] files [-l library]
#
#	Options:
#
#		-arch		Compile for the specified architecture (Darwin)
#
#		-isysroot	Change root directory for headers and libraries
#
#		-framework	Tells the linker to search for a framework
#
#		-c		Do not call linker, leave relocatables in *.o.
#
#		-C		Check that subscripts are in bounds.
#
#		-D def		passed to C compiler (for .c files)
#				or to cpp (for .F files)
#
#		-fPIC		turn on the -fPIC flag to the c compiler
#
#		-g		produce debugging information.
#
#		-I includepath	passed to C compiler (for .c files)
#				or to cpp (for .F files), and to f2c
#
#		-l library	(passed to ld).
#
#		-L includepath	passed to ld.  Library include path
#
#		-m xxx		passed to the C compiler as -mxxx
#
#		-Ntnnn		allow nnn entries in table t
#
#		-o objfile	Override default executable name a.out.
#
#		-pg		pass -pg (generate profile information) to the c
#				compiler.
#
#		-O		turn on the -O flag to the c compiler
#
#		-O1		turn on the -O1 flag to the c compiler
#
#		-O2		turn on the -O2 flag to the c compiler
#
#		-O3		turn on the -O3 flag to the c compiler
#
#		-P		emit .P files
#
#		-r8		promote REAL to DOUBLE PRECISION,
#				COMPLEX to DOUBLE COMPLEX
#
#		-s		Strip the symbol table from the executable file
#
#		-S		leave assembler output on file.s
#
#		-u		complain about undeclared variables
#
#		-U def				passed to C compiler (for .c files) or to
#				cpp (for .F files) to remove def
#
#		-v		be verbose.  Output is produced on the standard
#				error output.
#
#		-w		omit all warning messages
#
#		-w66		omit Fortran 66 compatibility warning messages
#
#		-Wxxx		turn on the -Wxxx flag to the c compiler
#
#		-Wl,		Pass options to the linker.  For example, 
#				-Wl,-R/usr/X11R6/lib
#				passes "-R/usr/X11R6/lib" to the linker
#
#		files		FORTRAN source files ending in .f
#				FORTRAN with cpp preprocessor directives
#					ending in .F 
#				C source files ending in .c
#				Assembly language files ending in .s 
#				efl source files ending in .e 
#				RATFOR files ending in .r 
#				Object files ending in .o
#				Shared libraries ending in .so
#
#				f2c prototype files ending in .P ; such
#				files only affect subsequent files.

# if no input arguments, then spit out the help stuff from the beginning
# of this file.
if [ $# = 0 ]; then
 cat $0 | awk '$1 == "#USAGESTART", $1 == ""' | tail +2 | sed 's/#//g'
fi

# Quote args to make them safe in the shell.
#
# After building up a quoted list, use it by evaling it inside
# double quotes, like this:
#    eval "set -- $quotedlist"
# or like this:
#    eval "\$command $quotedlist \$filename"
shell_quote()
{
	local result=''
	local arg
	for arg in "$@" ; do
		# Append a space if necessary
		result="${result}${result:+ }"
		# Convert each embedded ' to '\'',
		# then insert ' at the beginning of the first line,
		# and append ' at the end of the last line.
		result="${result}$(printf "%s\n" "$arg" | \
			sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/")"
		# For shells that don't understand $(...), try the following:
		#result="${result}`printf \"%s\\n\" \"\$arg\" | \
		#	sed -e \"s/'/'\\\\\\\\''/g\" -e \"1s/^/'/\" -e \"\\\$s/\\\$/'/\"`"
    done
    printf "%s\n" "$result"
}

tmpd=${TMPDIR:-/tmp}
mytmp=${tmpd}/f2c_$$
mkdir -m 0700 $mytmp
if test $? -ne 0 ; then
	echo "ERROR:  Could not create temporary directory ${mytmp}"
	echo "Either you do not have write permission to ${tmpd} or"
	echo "${mytmp} already exists"
	exit 1
fi
s=${mytmp}/stderr
t=${mytmp}/f77.o
CC=${CC_f2c:-'gcc '}
EFL=${EFL:-efl}
EFLFLAGS=${EFLFLAGS:-'system=portable deltastno=10'}
RATFOR=${RATFOR:-ratfor}
RFLAGS=${RFLAGS:-'-6&'}
F2C=${F2C:-/usr/pkg/bin/f2c}
F2CFLAGS=${F2CFLAGS:='-Aw8 -Nn802 -Nx400'}
S2DBLFLAG="-R"
CPP=${CPP:-'cpp '}
rc=0
trap "rm -fr $s $t $mytmp ; exit \$rc" 0
OUTF=a.out
cOPT=1
ARGS=
CPPFLAGS=
CFLAGS=-I/usr/pkg/include 
LIBS=
FLIBS="-Wl,-R/usr/pkg/lib -L/usr/pkg/lib -lf2c -lm"
VERBOSE=no

while
	test -n "$1"
do
	case "$1"
	in
	-c)	cOPT=0
		shift
		;;

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

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

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

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

	-I)	CFLAGS="$CFLAGS $(shell_quote "-I$2")"
		CPPFLAGS="$CPPFLAGS $(shell_quote "-I$2")"
		F2CFLAGS="$F2CFLAGS $(shell_quote "-I$2")"
		shift 2
		;;

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

        -l*)    LIBS="$LIBS $(shell_quote "$1")"
                shift 1
                ;;

        -L*)    LIBS="$LIBS $(shell_quote "$1")"
                shift 1
                ;;

	-m)	CFLAGS="$CFLAGS $(shell_quote "-m$2")"
		CPPFLAGS="$CPPFLAGS $(shell_quote "-m$2")"
		shift 2
		;;

        -m*)    CFLAGS="$CFLAGS $(shell_quote "$1")"
		CPPFLAGS="$CPPFLAGS $(shell_quote "$1")"
                shift 1
                ;;

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

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

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

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

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

	-r8)    S2DBLFLAG="-r8"
		shift
		;;

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

	-S)	CFLAGS="$CFLAGS -S"
		cOPT=0
		shift
		;;

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

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

	-v)	VERBOSE=yes
		shift
		;;

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

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

	-Wl*)	CFLAGS="$CFLAGS $(shell_quote "$1")"
		shift
		;;

	-W*)	CFLAGS="$CFLAGS $(shell_quote "$1")"
		shift
		;;

	-install_name)
		CFLAGS="$CFLAGS $1 $(shell_quote "$2")"
		shift 2;
		;;

	-compatibility_version)
		CFLAGS="$CFLAGS $1 $(shell_quote "$2")"
		shift 2;
		;;

	-current_version)
		CFLAGS="$CFLAGS $1 $(shell_quote "$2")"
		shift 2;
		;;

	-arch)	CFLAGS="$CFLAGS $1 $2"
		shift 2
		;;

	-isysroot) CFLAGS="$CFLAGS $1 $(shell_quote "$2")"
		shift 2
		;;

	-framework) CFLAGS="$CFLAGS $1 $(shell_quote "$2")"
		shift 2
		;;

	-*)	CFLAGS="$CFLAGS $(shell_quote "$1")"
		CPPFLAGS="$CPPFLAGS $(shell_quote "$1")"
		if test $VERBOSE = "yes"; then
			echo "Warning:  Passing unknown option $1 on to the c compiler"
		fi
		shift
		;;

	*)
		ARGS="$ARGS $(shell_quote "$1")"
		shift
		;;
	esac
done

if test $cOPT = 0; then
  if test "$OUTF" != "a.out"; then
    CFLAGS="$CFLAGS -o $(shell_quote "$OUTF")"
  fi
fi

# set the flag that controls if REAL's are promoted to 
# DOUBLE PRECISION or not
F2CFLAGS="$F2CFLAGS $S2DBLFLAGS"

eval "set -- $ARGS"

# strip off lines which just are for the linker in cases where
# we are not linkng.  Otherwise we produce gcc warnings
# like:
#
# cc: -R/usr/pkg/lib: linker input file unused because linking not done
#
# which messes up the autoconf tests for fortran libraries.
 
CFLAGS_NOLINK=`echo $CFLAGS |  sed -e 's; '\''-Wl,[^ ]*; ;g' -e 's; -Wl,[^ ]*; ;g'`

if test $VERBOSE = "yes"; then
  F2CVER=`$F2C < /dev/null | awk '/.*version/ {print $6" "$7}'`
  echo "f2c-f77:"
  echo "F2C= $F2C, $F2CVER"
  echo "CC= $CC"
  echo "CFLAGS= $CFLAGS"
  echo "CFLAGS_NOLINK= $CFLAGS_NOLINK"
  echo "CPPFLAGS= $CPPFLAGS"
  echo "FLIBS= $FLIBS"
  echo "LD_RUN_PATH= /usr/pkg/lib"
fi

while
	test -n "$1"
do
	case "$1"
	in
	*.[fF])
		case "$1" in *.f) f=".f";; *.F) f=".F";; esac
		case "$1" in
			*.f)	b=`basename $1 .f`
				if test $VERBOSE = "yes"; then
					echo "$F2C $F2CFLAGS $1"
				fi
				eval "\$F2C $F2CFLAGS \$1"
				rc=$?
				;;
			*.F)	b=`basename $1 .F`
				eval "\$CPP $CPPFLAGS \$1" >$b.i
				rc=$?
				case $rc in 0)
					if test $VERBOSE="yes"; then
						echo "$F2C $F2CFLAGS <$b.i >$b.c"
					fi
					eval "\$F2C $F2CFLAGS" <$b.i >$b.c
					rc=$?
					;;esac
				rm $b.i
				;;
			esac
		case $rc in 0);; *) exit;; esac
                eval "\$CC -c $CFLAGS_NOLINK \$b.c" 2>$s
		rc=$?
		sed '/parameter .* is not referenced/d;/warning: too many parameters/d' $s 1>&2
		case $rc in 0);; *) exit;; esac
		OFILES="$OFILES $b.o"
		rm $b.c
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;
	*.e)
		b=`basename $1 .e`
		eval "\$EFL $EFLFLAGS \$1" >$b.f
		case $? in 0);; *) rc=$?; exit;; esac
		eval "\$F2C $F2CFLAGS \$b.f"
		case $? in 0);; *) rc=$?; exit;; esac
                eval "\$CC -c $CFLAGS_NOLINK \$b.c"
		case $? in 0);; *) rc=$?; exit;; esac
		OFILES="$OFILES $b.o"
		rm $b.[cf]
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;
	*.r)
		b=`basename $1 .r`
		eval "\$RATFOR $RFLAGS \$1" >$b.f
		case $? in 0);; *) rc=$?; exit;; esac
		eval "\$F2C $F2CFLAGS \$b.f"
		case $? in 0);; *) rc=$?; exit;; esac
		eval "\$CC -c $CFLAGS_NOLINK \$b.c"
		case $? in 0);; *) rc=$?; exit;; esac
		OFILES="$OFILES $b.o"
		rm $b.[cf]
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;
	*.s)
		echo $1: 1>&2
		OFILE=`basename $1 .s`.o
		eval "\${AS:-as} -o \$OFILE $AFLAGS \$1"
		case $? in 0);; *) rc=$?; exit;; esac
		OFILES="$OFILES $OFILE"
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;
	*.c)
		echo $1: 1>&2
		OFILE=`basename $1 .c`.o
                eval "\$CC -c $CPPFLAGS $CFLAGS_NOLINK \$1"
		rc=$?; case $rc in 0);; *) rc=$?; exit;; esac
		OFILES="$OFILES $OFILE"
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;
	*.o)
		OFILES="$OFILES $1"
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;
	*.so)
		OFILES="$OFILES $1"
		case $cOPT in 1) cOPT=2;; esac
		shift
		;;
	-l)
		OFILES="$OFILES -l$2"
		shift 2
		case $cOPT in 1) cOPT=2;; esac
		;;
	-l*)
		OFILES="$OFILES $1"
		shift
		case $cOPT in 1) cOPT=2;; esac
		;;
	-o)
		OUTF=$2; shift 2;;
	*.P)
		F2CFLAGS="$F2CFLAGS $(shell_quote "$1")"
		shift
		;;
	*)
		OFILES="$OFILES $1"
		shift
		case $cOPT in 1) cOPT=2;; esac
		;;
	esac
done

case $cOPT 
in 
  2) eval "\$CC $CFLAGS -o \$OUTF $OFILES $LIBS $FLIBS"
     ;; 
esac

rc=$?
exit $rc

