#! /bin/sh
# Build code for a test problem into an algorithm or tool program.

if [ -z "$NLPDIR" ]
then
# set the directory containing test problems
  NLPDIR=`/usr/bin/find ${HOME} -xdev -name NGC -type d 2> /dev/null`
  if [ -z "NLPDIR" ]
  then
    NLPDIR=`pwd`
  fi
fi
if [ -z "$PGMDIR" ]
then
# set the directory containing partially-linked programs
  PGMDIR=${HOME}/bin/obj
fi
if [ -z "$SRCDIR" ]
then
# set the directory containing source components
  SRCDIR=${HOME}/src/lib
fi

# check that the requested program exists
rc=1
if [ $# -eq 2 ]
then
  file $PGMDIR/$2.o 2> /dev/null | grep ELF.*relocatable > /dev/null
  rc=$?
fi
if [ $rc -ne 0 ]
then
  echo "usage: prepare problem[.f|.gp|.qp|.lp] program"
  echo "       where program is one of the following:"
  for pgm in $PGMDIR/*.o
  do
    basename $pgm | sed -e "s/.o$//" | sed -e"s/^/       /"
  done
  exit 1 
fi

# make sure the executable doesn't wind up in the user's bin
forbid=$HOME/bin
if [ "`pwd`" = "$forbid" ]
then
  echo "can't prepare in $forbid"
  exit 3
fi

echo "using problem directory $NLPDIR" #------------------------------------

# identify a unique filename defining the problem
echo $1 | egrep "\.f$|\.gp$|\.qp$|\.lp$" > /dev/null
if [ $? -eq 0 ]
then
   if [ -s $NLPDIR/$1 ]
   then
      kind=`echo $1 | fnext`
      prob=`basename $1 $kind | sed -e"s/\.$//"`
   else
      echo "no definition file found for problem $1 in $NLPDIR"
      exit 1
   fi
else
   hits=`/bin/ls $NLPDIR/$1.* 2> /dev/null`
   nhits=`echo $hits | wc -w`
   if [ $nhits -eq 1 ]
   then
      kind=`basename $hits | fnext`
      prob=$1
   fi
   if [ $nhits -eq 0 ]
   then
      echo "no definition file found for problem $1"
      exit 1
   fi 
   if [ $nhits -gt 1 ]
   then
      echo "Which one?"
      echo $hits | tr ' ' '\n'
      exit 1
   fi
fi
fyle="$NLPDIR/$prob.$kind"
if [ ! -s $fyle ]
then
   echo "problem definition file $fyle is empty."
   exit 1
fi

# copy the code for FCN, GRD, and HSN into the local problem definition
rm -f problem.f
if [ "$kind" = "f" ]
then
   cp $fyle problem.f
   cat problem.f | grep -v ^C | grep "SUBROUTINE SETUP" > /dev/null
   if [ $? -eq 0 ]
   then
      echo "found a SETUP routine"
      pkc=2
   else
      pkc=1
   fi
fi
if [ "$kind" = "gp" ]
then
   pkc=3
   cat ${SRCDIR}/fcngp.f > problem.f
   cat ${SRCDIR}/grdgp.f >> problem.f
   cat ${SRCDIR}/hsngp.f >> problem.f
fi
if [ "$kind" = "qp" ]
then
   pkc=4
   cat ${SRCDIR}/fcnqp.f > problem.f
   cat ${SRCDIR}/grdqp.f >> problem.f
   cat ${SRCDIR}/hsnqp.f >> problem.f
fi
if [ "$kind" = "lp" ]
then
   pkc=5
   cat ${SRCDIR}/fcnlp.f > problem.f
   cat ${SRCDIR}/grdlp.f >> problem.f
fi
chmod +w problem.f

# provide a dummy SETUP routine if none is already present
if [ $pkc -ne 2 ]
then
   echo "      SUBROUTINE SETUP(RC)" >> problem.f
   echo "      INTEGER*4 RC" >> problem.f
   echo "      RC=-1" >> problem.f
   echo "      RETURN" >> problem.f
   echo "      END" >> problem.f
fi

# provide a skeleton BLOCK DATA routine if none is already present
cat problem.f | grep -v ^C | grep "BLOCK DATA NGC" > /dev/null
if [ $? -ne 0 ]
then
   echo "      BLOCK DATA NGC" >> problem.f
   echo "      COMMON /NGC1/ SW1,NBR,PROBID,FNABBR" >> problem.f
   echo "        LOGICAL*4 SW1(3)/.FALSE.,.FALSE.,.TRUE./" >> problem.f
   echo "        CHARACTER*8 PROBID(6),FNABBR/'$prob'/" >> problem.f
   echo "      COMMON /NGC2/ SW2,PKC,FLAGS,DEFFIL,NLPDIR" >> problem.f
   echo "        LOGICAL*4 SW2(4)/.TRUE.,.FALSE.,.TRUE.,.TRUE./" >> problem.f
   echo "        INTEGER*4 PKC/$pkc/" >> problem.f
   echo "        INTEGER*4 FLAGS(3)" >> problem.f
   echo "        CHARACTER*48 DEFFIL/'$prob.$kind'/" >> problem.f
   echo "        CHARACTER*48 NLPDIR/'$NLPDIR'/" >> problem.f
   echo "      COMMON /NGC4/ SW4,FRBN,XRBN" >> problem.f
   echo "        LOGICAL*4 SW4(2)/.FALSE.,.FALSE./" >> problem.f
   echo "        REAL*8 FRBN/Z'7FF0000000000000'/" >> problem.f
   echo "        REAL*8 XRBN(50)/50*Z'7FFFFFFFFFFFFFFF'/" >> problem.f
   echo "      END" >> problem.f
fi

echo "using program directory $PGMDIR" #-------------------------------------

# compile the problem definition
rm -f /tmp/warnings
fcompile problem.f > /tmp/warnings 2>&1
if [ $? -ne 0 ]
then
  echo "problem definition compilation failed"
  more /tmp/warnings
  exit 3
fi

# remove any previous executable in case linking the new one fails
/bin/rm -rf $2

# link the problem definition to the program
rm -f /tmp/warnings
flink $PGMDIR/$2.o problem.o > /tmp/warnings 2>&1
if [ $? -eq 0 ]
then
   mv a.out $2
   echo "linking of $2 succeeded"
else
   echo "program linking failed"
   more /tmp/warnings
   exit 2
fi
exit 0
