#!/usr/bin/env bash

# rd
#  This script is intended to compile a single ".red" file letting
# the user specify either that the CSL or PSL version should be updated
# and with options moticated by those one might pass to a C compiler.

# ----------------------------------------------------------------------
# $Id: rd 4588 2018-04-28 11:07:48Z arthurcnorman $
# ----------------------------------------------------------------------
# Copyright (c) 2009 Thomas Sturm
# ----------------------------------------------------------------------
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#    * Redistributions of source code must retain the relevant
#      copyright notice, this list of conditions and the following
#      disclaimer.
#    * Redistributions in binary form must reproduce the above
#      copyright notice, this list of conditions and the following
#      disclaimer in the documentation and/or other materials provided
#      with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 

# I want this script to be one I can launch from anywhere, but at least
# some of its sub-scripts will not be so generous. So find out where it
# lives so that other locations can be found relative to that. 
here="$0";while test -L "$here";do here=`ls -ld "$here" | sed 's/.*-> //'`;done
me="$here"
here=`cd \`dirname "$here"\` ; pwd -P`
here=`dirname "$here"`
# Because "rd" lives in the scripts sub-directory of the man Reduce sources
# trunk, here will now be the absolute path to the trunk. 

awk1='BEGIN {
    in_rlint=0
    v=ENVIRON["verbose"]
    d=ENVIRON["debug"]
    w=ENVIRON["warn"]
}
(d == 1) {
    print
    next
}
(/not be open/) {
    print
    exit 1
}
($1=="procedure") {
    split($2,arr,"(")
    p=arr["1"]
}
($2=="procedure") {
    split($3,arr,"(")
    p=arr["1"]
}
(v == 1 && !in_rlint && /MAKESHVMSG/) {
    sub(/^.*MAKESHVMSG /,"")
    print
}
(!in_rlint && /MAKESHMSG/) {
    sub(/^.*MAKESHMSG /,"")
    print
}
/^Cont/ {
    exit 1
}
/called with [0-9]* instead of [0-9]* arguments/ {
    print
    exit 1
}
/SREMAKE_START_RLINT/ {
    in_rlint=1
}
/SREMAKE_COMPILE/ {
    exit 2
}
($1=="module") {
    mod = substr($2,1,length($2)-1)
}
/\*\*\* Not Used \*\*\*/ {
    next
}
/^ *\*\*\*/ && $4 != "nested" {
    $1="***"
    printf("%s (",$0)
    if (p != "") {printf("procedure %s ",p)}
    if (mod != "") {printf("in module %s",mod)}
    printf(")\n")
}'

awk2='BEGIN {
    havecr=1
    linlen=0
    v=ENVIRON["verbose"]
    d=ENVIRON["debug"]
    lisp=ENVIRON["lisp"]
    w=ENVIRON["warn"]
}
(d == 1 || (v == 1 && lisp == "psl")) {
    print
    next
}
(v == 1 && $1 == "+++") {
    linlen += length($2)+1
    if (linlen > 80) {
	printf("\n")
	linlen=length($2)
    }
    printf("%s ",$2)
    fflush(stdout)
    havecr=0
    next
}
(w == 0) && /local variable .* not used/ {
    next
}
($1 == "***") {
    if (!havecr) printf("\n")
    sub(/\.\.\./,sprintf("for %s",lisp))
    print
    havecr=1
    linlen=0
}
END {
    if (!havecr) printf("\n")
}'

forceremake=nil
export lisp
lisps=""
export verbose=0
export warn=0
export debug=0
export syntaxonly=0
force=0

for count in 1 2 3 4 5 6 7 8; do
    if [ "$1" = "-B" ]; then
	forceremake=t
	shift
    fi
    
    if [ "$1" = "-v" ]; then
	verbose=1
	shift
    fi

    if [ "$1" = "-d" ]; then
	debug=1
	shift
    fi

    if [ "$1" = "-Wall" ]; then
	warn=1
	shift
    fi

    if [ "$1" = "-fsyntax-only" ]; then
	syntaxonly=1
	shift
    fi

    if [ "$1" = "-force" ]; then  # compilation w/o syntax-check
	force=1
	shift
    fi

    if [ "$1" = "-csl" ]; then
#	if [ x$lisp = xpsl ] ; then
#	    echo "$(basename $me): must specify only one lisp"
#	    exit 99
#	fi
	lisps="$lisps csl"
	shift
    fi

    if [ "$1" = "-psl" ]; then
#	if [ x$lisp = xcsl ] ; then
#	    echo "$(basename $me): must specify only one lisp"
#	    exit 99
#	fi
	lisps="$lisps psl"
	shift
    fi
done

if [ "x$lisps" = x ]; then
    echo "$(basename $me): must specify lisp"
    exit 99
fi

unset RLDEFLANG  # for redlog

MACHINE=$($here/scripts/findhost.sh $($here/config.guess))

for lisp in $lisps; do

if [ $debug -eq 1 ] ; then
    echo "here =    $here"
    echo "me =      $me"
    echo "lisp =    $lisp"
    echo "MACHINE = $MACHINE"
fi

if [ "$lisp" = "csl" ]; then
    IMG="$here/cslbuild/$MACHINE/csl/reduce.img"
    REDUCE="$here/cslbuild/$MACHINE/csl/reduce -w -o $IMG"
    if [ $debug -eq 1 ] ; then
	echo "IMG =     $IMG"
	echo "REDUCE =  $REDUCE"
    fi
elif [ "$lisp" = "psl" ]; then
    IMG="$here/pslbuild/$MACHINE/red/reduce.img"
    REDUCE="$here/pslbuild/$MACHINE/psl/bpsl -td 48000000 -f $IMG"
    export fasl="$here/pslbuild/$MACHINE/red"
    if [ $debug -eq 1 ] ; then
	echo "IMG =     $IMG"
	echo "REDUCE =  $REDUCE"
	echo "fasl =    $fasl"
    fi
fi

for m in $* ; do
    
    if [ x$force = x0 ] ; then

	($REDUCE 2<&1 | \
            grep -v "Function .yesp. has been redefined" | \
            grep -v "local variable" | \
	    grep -v "already defined as operator" | \
	    grep -v "module2!-to!-file" | \
	    grep -v "savedef" | \
	    grep -v "native_code" | \
	    awk "$awk1") <<EOF
off output$
lisp;
infile("$here/packages/rd/rd.red")$
%load!-package 'rd;
rd_init "$here";
y := '$m;
if not ($forceremake or makep y) then up!-to!-date!-exit y;
rlint!-msg y;
prin2t "SREMAKE_START_RLINT";
rlint y;
prin2t "SREMAKE_COMPILE";
bye;
EOF

	status=$?

	if [ x$syntaxonly = x1 ] ; then exit 0 ; fi

	if [ $status -eq 1 ] ; then exit $status ; fi

	if [ $status -ne 2 ] ; then exit $status ; fi

    fi
    
    ($REDUCE 2>&1 | \
	grep -iv "REDUCE" | \
	grep -v "Quitting" | \
	grep -v "Request to set constant bitsperword" | \
	grep -v "olderfaslp" | \
	grep -v "module2!-to!-file" | \
	grep -v "savedef" | \
	grep -v "native_code" | \
	grep -iv "init *code" | \
	grep -v "^ *$" | \
	grep -v "^[0-9]*[*:] *$" | \
	grep -v "^Loading image file" | \
	awk "$awk2") <<EOF
off output$
lisp;
infile("$here/packages/rd/rd.red")$
%load!-package 'rd;
rd_init "$here";
if $forceremake then on1 'rd_force;
make '$m;
bye;
EOF

done

done
