# This script helps for Edit, Compile, Link and Run a GPC-Program
 
usage()
{ echo "Usage:
p [switches] program [ programs parameter list .. ] 
   -o 'options'     = Compiler options,    default: ${CCO}
   -m               = compile units,       default: ${TYPE}
   -b               = batch mode,          default: ${MODE}
  -sd source_dir    = Source directory,    default: ${SRC}
  -ud unit_dir_list = Unit directory list, default: ${USP}
  -od object_dir    = Object directory,    default: ${OBJ}
   -t               = time prefix,         default: ${TIME}
   -h               = help"
  if [ -n "$1" ]; then echo $1 ; fi
  exit $2 ; }

help()
{ echo "------------------------------------------------------"
  echo "   <RET>       # Comile and run"
  echo "   t           # Toggle time prefix"
  echo "   o 'options' # Compiler Options over-write"
  echo "   a 'options' # Compiler Options add to existing"
  echo "   h           # This text"
  echo "   n | q | e   # Exit"
  echo "------------------------------------------------------"
  echo "COMPILE:   ${COMPILE}" ; echo "EXECUTE:   ${EXECUTE}"
  echo "------------------------------------------------------" ; }

prompt()
{ case `uname` in
    Linux|linux) echo -n "$1 ";;
              *) echo "$1 \c";;
          esac
  read INSTR P1
  case ${INSTR} in
    n|q|e) exit 2 ;;
        *) ;;
    esac ; }

init_bin_dirs()
{ if [ -d /afs ]
  then
    SYS=`sys`
    if [ ${TYPE} = main ]
    then
      if [ ! -d ${BIN}/${SYS} ];     then mkdir -p ${BIN}/${SYS};        fi
      if [ -f ${BIN}/${SYS}/${PGM} ];then rm ${BIN}/${SYS}/${PGM};       fi
      if [ -L ${PGM} -o -f ${PGM} ]; then rm ${PGM};                     fi
      ln -s ${BIN}/@sys/${PGM} ${PGM}
    fi
    if [ ! -d ${OBJ}.${SYS} ]; then mkdir -p ${OBJ}.${SYS};              fi
    if [ ! -L ${OBJ} ];        then ln -s `basename ${OBJ}`.@sys ${OBJ}; fi
  else
    if [ ! -d ${OBJ} ];        then mkdir -p ${OBJ};                     fi
  fi ; }

tst()
{ if [ $# = 1 ]; then usage "Missing parameter for switch $1"; fi ; }

# --------- Setting default values --------------------------------------------
MODE=interactive                # interactive,  -b changes MODE to batch
TYPE=main                       # main program, -m changes TYPE to module(unit)
SRC=pascal                      # default dir for pascal source files
USP="pascal:~/sw/module/pascal" # unit source path
OBJ=~/.object.gpc               # object path for files: *.gpi, *.o
BIN=.bin                        # dir for afs binaries, platform dependant
INC="-I`pwd` -I$SRC"            # include directories (current and pascal dir)
CCO="-s --automake"             # default Compiler Comand Options
PGM=""                          # program name without any pre- or suf-fixes
TIME=""                         # default is no time prefix

# --------- Scan all parameters first -----------------------------------------
while [ $# -gt 0 ]
do
  case $1 in
    -o) CCO="$2"; tst "$*"; shift ;; # Compiler options 
    -m) TYPE=module               ;; # Assume a Module to be compiled
    -b) MODE=batch                ;; # Batch mode: No edit, simply compile
   -sd) SRC="$2"; tst "$*"; shift ;; # Source directory
   -ud) USP="$2"; tst "$*"; shift ;; # Unit source path
   -od) OBJ="$2"; tst "$*"; shift ;; # Object directory
    -t) TIME='time'               ;; # Execute with time prefix
    -h) usage '' 99               ;; # Help
     *) PGM=$1 ; shift               # assuming the program/module name
        PAR=$* ; shift $# ;break  ;; # consuming parameter list into PAR
  esac
  shift
done

PASPGM=${SRC}/${PGM}.pas # relative path name of pascal program
if [ "$PGM" = "" ]; then usage "Missing the program name" 13; fi
if [ ! -d ${SRC} ]
then
  case ${MODE} in
    interactive) prompt "Missing directory: ${SRC}, To create it press <RET>";;
    batch)       usage  "Missing directory: ${SRC}" 14 ;;
    esac
  mkdir ${SRC}
fi

COMMON="-L~/.gnu/lib -L/usr/X11R6/lib -lX11
        --unit-path=${USP}
        --object-path=${OBJ}
        --unit-destination-path=${OBJ}
        --gpi-destination-path=${OBJ} ${INC}"

case ${MODE} in
  interactive)
    if [ ! -f $PASPGM ]
      then
        prompt "Program $PASPGM not found, to create press <RET>"
        case ${TYPE} in
         main)  echo "PROGRAM $PGM (input, output); {-*-Mode: fundamental-mode}" > $PASPGM
                echo "BEGIN"                         >> $PASPGM
                echo                                 >> $PASPGM
                echo "END."                          >> $PASPGM ;;

         module)echo "UNIT $PGM; {-*-Mode: fundamental-mode}" > $PASPGM
                echo "INTERFACE"                     >> $PASPGM
                echo "CONST     dummy=0;"            >> $PASPGM
                echo "PROCEDURE proc (i : integer);" >> $PASPGM
                echo ""                              >> $PASPGM
                echo ""                              >> $PASPGM
                echo ""                              >> $PASPGM
                echo "IMPLEMENTATION"                >> $PASPGM
                echo "PROCEDURE proc;"               >> $PASPGM
                echo "BEGIN"                         >> $PASPGM
                echo "  writeln ('This is  proc')"   >> $PASPGM
                echo "END;"                          >> $PASPGM
                echo ""                              >> $PASPGM
                echo "BEGIN"                         >> $PASPGM
                echo "  writeln ('Initialize')"      >> $PASPGM
                echo "END.  {$PGM implementation}"   >> $PASPGM ;;
         esac
      fi

    e ${PASPGM}               # start editing in background
    STATUS_CHANGED=false
    while true
    do
      while true
        do
          case ${TYPE} in
            module) COMPILE="gpc ${CCO} ${COMMON} -o ${OBJ}/${PGM}.o -c ${PASPGM}";;
            main)   COMPILE="gpc ${CCO} ${COMMON} -o ${PGM}             ${PASPGM}"
                    EXECUTE="${TIME} ${PGM} ${PAR}" ;;
            esac
          if [ "${STATUS_CHANGED}" = true ] ; then help ;fi
          prompt "To compile ${PGM} press <RET>"
          if [ "${INSTR}" = "" ]; then STATUS_CHANGED=false ; break ; fi
          case ${INSTR} in
            t) if [ "${TIME}" = "" ]; then TIME="time" ; else TIME='' ; fi ;;
            o) CCO=${P1} ;;
            a) CCO="${CCO} ${P1}";;
            h) ;;
            *) echo "Error, unknown command: ${INSTR} ${P1}" ;;
            esac
          STATUS_CHANGED=true
        done
      grep '{execute:' ${PASPGM} | cut -d: -f2 | cut -d'}' -f1 | while read -r INLINE_CMND
        do eval ${INLINE_CMND} ; done

      init_bin_dirs  # if AFS present make platform dependant bin dir
      ${COMPILE} ; RETURNCODE=$?
      if  [ ${RETURNCODE} = 0 ]
        then
          if [ $TYPE = main ]
          then
            echo "-------- Start: ${EXECUTE} -------------------"
            ${EXECUTE}
            echo "-------- End of $PGM ---- Return code=$? ------"
          fi
        else
          echo "ERROR: Return code of gpc was $?"
        fi
    done  ;;
  batch)
    if [ ! -f ${PASPGM} ] ; then usage "Program $PASPGM not found" 14; fi
    grep '{execute:' ${PASPGM} | cut -d: -f2 | cut -d'}' -f1 | while read -r INLINE_CMND
        do eval ${INLINE_CMND} ; done
    init_bin_dirs  # if AFS present make platform dependant bin dir
    case ${TYPE} in
      module) gpc ${CCO} ${COMMON} -o ${OBJ}/${PGM}.o -c ${PASPGM}; RETURNCODE=$? ;;
      main)   gpc ${CCO} ${COMMON} -o ${PGM}             ${PASPGM}; RETURNCODE=$? ;;
      esac
    exit ${RETURNCODE} ;;
  *)usage "Fatal Error" 15 ;;
esac
