#!/bin/sh

# usage:
#    document [options] file
#    [ plus any legacy usage ]
#
# options:
#    --index
#       Run makeindex on the input file
#
#    --latex
#       Typeset input file assuming it a LaTeX file
#
#    --mode=what
#       In conjunction with --tag=lang, indicates what to do
#       with input files assumed to contain program source code.
#       Valid values are: compile, translate, link.
#
#    --output=outfile
#       Set the output filename.
#
#    --tag=lang
#       Process input files as programs written in language
#       indicated by lang.  Valid values are: boot, lisp.
#
#    --tangle
#    --tangle=chunk
#       Run notangle on the input file assumed to be a pamphlet.
#
#    --use=cmd
#       Use cmd for translation or compilation.
#
#    --weave 
#       Run noweave on the input file assumed to be a pamphlet
#       When combined with --output, also run latex.
#    --
#       Anything that comes after is treated as an argument, even
#       if it looks like an option

## 2007-04-10:
##   After moving to a recent version of MSYS, and GCL-2.6.8pre, I
##   noticed that double-colon ('::' in boottran::boottocl) will be
##   translated to semi-colon (';') as if interpreted for path
##   separator.  I don't who is doing that, and I have no time to
##   investigate it, and even if I do, it would not help much.  
##   Therefore, I've changed the script not to use double-colon.
##      -- Gaby


# set -x

# Flags used to invoke the Lisp compiler in batch mode
quiet="@axiom_quiet_flags@"
eval_flags="@axiom_eval_flags@"

# The flavor of Lisp implementation we're using
lisp_flavor=@axiom_lisp_flavor@

# safety option -- used only when saving image.
enable_checking=@oa_enable_checking@

# Issue a diagnostic message and exit with non-zero status.
error() {
    echo "error: $1"
    exit 1
}

# Issue a diagnostic if an option ($1) requires a argument
# and its value ($2) is empty.
maybe_missing_value_for() {
    if test -z $2; then
	error "missing value for $1"
    fi
}

# Check validity of --tag.  At the moment
# we support only "boot" and "lisp"
check_tag_value() {
    case $1 in
	boot|lisp) 
           tag=$1
           ;;
	*)
	   error "invalid tag $1"
	   ;;
    esac
}

# Validate argument for --mode.  We support only
#  - "compile", for Lisp source file
#  - "translate", for Boot source file
check_mode_value() {
    case $1 in
	compile|translate|link)
           mode=$1
	   ;;
	*)
	   error "invalid mode $1"
	   ;;
    esac
}

# Compile a program written in Lisp to FASL code.
# $1 is the input file name
# $2 is the output file name
compile_lisp_file() {
    case $lisp_flavor in
	gcl|sbcl|clisp|ecl)
	   $command -- --compile $1
	   ;;
	*)
	   error "don't know how to compile with '$lisp_flavor' Lisp"
	   ;;
    esac
    return $?
}

# Build an executable out of (compiled) Lisp files.
make_program() {
    case $lisp_flavor in
	gcl|sbcl|clisp|ecl)
           $command -- --make --output=$output $@
	   ;;
	*)
	   error "don't know how to build program with '$lisp_flavor' Lisp"
	   ;;
    esac
}

# Translate a program written in Boot to Lisp
# $1 designates the translator 
# $2 is the input file
# $3 is a temporary file where we dump compiler diagnostics
translate_boot_file() {
    case $lisp_flavor in
	gcl|sbcl|clisp|ecl)
	   $command -- --translate $1 | tee $2 
	   ;;
	*)
	   error "don't know how to translate with '$lisp_flavor' Lisp"
	   ;;
    esac
    return $?
}

do_index=
do_latex=
do_tangle=
do_weave=
chunk=
file=
output=
tag=
mode=
command=

while test $# -gt 0 ; do
    optval=$1

    case $optval in
	--)
	   break
	   ;;
	--*=*)
	   arg=`echo $optval | sed -e 's/^[-a-zA-Z]*=//'`
	   opt=`echo $optval | sed -e 's/=.*$//'`
	   shift;
	   ;;
	--*)
	   opt=$optval
	   arg=
	   shift
	   ;;
	*)
	   break
	   ;;
    esac

    case $opt in
	--weave)
	   do_weave=yes
	   ;;

        --latex)
	   do_latex=yes
           ;;

        --index)
	   do_index=yes
	   # FIXME: --index may be used only with --latex.  Check.
           ;;

	--tangle)
	   do_tangle=yes
	   if test -n "$arg"; then
	       chunk=$arg
	   fi
	   # --tangle may not be combined with any other
	   # options.  FIXME:  Check that. 
	   ;;

	--output)
	   maybe_missing_value_for $opt $arg
	   output=$arg
	   ;;

	--tag)
	   maybe_missing_value_for $opt $arg
	   check_tag_value $arg
	  ;;
	
	--mode)
 	   maybe_missing_value_for $opt $arg
	   check_mode_value $arg
	   ;;
	--use)
	   command=$arg
	   ;;

	--*)
	   echo unrecognized option $opt
	   exit 1
	   ;;
    esac
done

if test x$do_tangle = xyes; then
    # FIXME: Check that the input file name does indeed have
    # a pamphlet extension.
    file=$1
    if [ -z $output ]; then
	output=`basename $file .pamphlet`;
    fi

    # FIXME: Ideally, we should just prepend -R to $chunk
    #        if it is non-null, and say $tangle $chunk $file > $output
    #        Alternatively, we could initialize chunk to '*' and
    #        unconditionally use -R"$chunk".
    if [ -z "$chunk" ]; then
	$TANGLE $file > $output
    else
	$TANGLE -R"$chunk" $file > $output
    fi
    # FIXME: Handle errors.
    exit $?;
fi


if test x$do_weave = xyes; then
    file=`basename $1 .pamphlet`
    $WEAVE -delay $1 > $file.tex
    if test x$do_latex != xyes; then
	exit 0;
    fi
fi

if test x$do_latex = xyes; then
    if [ -z $file ]; then
	file=`basename $1 .tex`
    fi
    latex --interaction nonstopmode $file;
    if [ x$do_index = xyes ]; then
	makeindex $file.idx
    fi
    latex --interaction nonstopmode $file;
    exit $?
fi

# We only support translation of Boot source files, and
# compilation of Lisp source files
case $mode,$tag in
    translate,boot)
       # The bootsys image is currently unable to pass up an
       # exit status that we can hand to the shell.  When an error
       # occurs, bootsys just prints a message and exits as if 
       # everything went well.  To work around that, we have to 
       # capture its output, look for specific patterns, and then
       # return an appropriate exit status.
       # mktemp is used to create a temporary file; for systems that
       # lack support for mktemp, e.g. MinGW/MSYS, we use the common
       # trick of forging a filename based on the pid.
       if test -z "@MKTEMP@"; then
	   tmpfile=document.$$
       else
	   tmpfile=`mktemp document.XXXXXX` || exit 1
       fi
       trap "rm -f $tmpfile" 1 2 15
       translate_boot_file $1 $tmpfile
       grep 'ERROR IN' $tmpfile >/dev/null && { rm $tmpfile; exit 1; }
       rm $tmpfile && exit 0
       ;;

    compile,lisp)
       compile_lisp_file $1 $output
       exit $?
       ;;
    link,lisp)
       make_program $@
       exit $?
       ;;
esac


if [ "$#" = "3" ]; then
 REDIRECT=$2
 FILE=`basename $3 .pamphlet`
 $TANGLE -t8 $FILE.pamphlet >$FILE
 $WEAVE -delay $FILE.pamphlet >$FILE.tex
 latex --interaction nonstopmode $FILE.tex >$REDIRECT
 latex --interaction nonstopmode $FILE.tex >$REDIRECT
 rm -f $FILE~
 rm -f $FILE.pamphlet~
 rm -f $FILE.log
 rm -f $FILE.tex
 rm -f $FILE.toc
 rm -f $FILE.aux
 exit 0
fi
if [ "$#" = "1" ]; then
 FILE=`basename $1 .pamphlet`
 $TANGLE -t8 $FILE.pamphlet >$FILE
 $WEAVE -delay $FILE.pamphlet >$FILE.tex
 latex $FILE.tex 
 latex $FILE.tex
 rm -f $FILE~
 rm -f $FILE.pamphlet~
 rm -f $FILE.log
 rm -f $FILE.tex
 rm -f $FILE.toc
 rm -f $FILE.aux
 exit 0
fi
echo "document [ -o redirect ] pamphlet"

# set +x