#! /bin/ksh
#----------------------------------------------------------------------------
#
#   install     Rebuilds and installs Libero on UNIX systems
#   Syntax:     Korn shell
#
#   Written:    95/03/10  Pieter Hintjens <ph@imatix.com>
#   Revised:    96/12/27
#
#   Requires:   awk, egrep, cut, echo, test, cc, cp.
#
#   This script builds the 'lr' executable, and installs the necessary
#   files into a specified bin directory.  If the script fails for any
#   reason - eg. incompatible shell - then you can build Libero by hand
#   using these commands:
#
#   $ cc lr.c lr????.c -o lr
#   $ cp lr lrmesg.txt lr.ini lrschema.* lrskelet.* <directory>
#
#   The sources must be compiled in ANSI mode.
#
#   FSM Code Generator.  Copyright (c) 1991-97 iMatix.
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#-  INSTALL - generated script; do not modify directly. See INSTALL.l
#-  Generated by LIBERO 2.20 on 28 Dec, 1996,      .
#-  Schema used: lrschema.ksh
#----------------------------------------------------------------------------

#-- Symbolic constants and event numbers ------------------------------------


CCNAME="cc"                             #   Default C compiler name
#CCNAME="gcc"                           #   If using GNU C

CATALOG=install.cat                     #   List of files in product
DEFAULTDIR=/usr/local/bin               #   Default install directory
VERSION=2.20                            #   Product version

terminate_event=255
binary_event=1
build_event=2
cleanup_event=3
current_event=4
delete_event=5
error_event=6
install_event=7
ok_event=8
quit_event=9
source_event=10
LR_STATE_after_init=1
LR_STATE_have_package=2
LR_STATE_before_action=3
LR_STATE_have_install_directory=4
LR_STATE_have_delete_directory=5
LR_STATE_defaults=6
LR_defaults_state=6

#-- Public dialog variables -------------------------------------------------

the_next_event=0                        #   Next event from module
the_exception_event=0                   #   Exception event from module
feedback=0                              #   Return code from this function
exception_raised=FALSE                  #   TRUE if exception raised
script_name=""                          #   Name of script including path

#-- Variables used by dialog interpreter ------------------------------------

LR_event=0                              #   Event for state transition
LR_state=0                              #   Current dialog state
LR_savest=0                             #   Saved dialog state
LR_index=0                              #   Index into vector table
LR_vecptr=0                             #   Index into module vector

#-- Static areas ------------------------------------------------------------

LR_nextst1="0 0 0 0 0 0 0 2 0 0"
LR_nextst2="3 0 0 0 0 2 0 0 0 3"
LR_nextst3="0 4 2 0 5 2 4 0 0 0"
LR_nextst4="0 0 0 2 0 4 0 2 0 0"
LR_nextst5="0 0 0 0 0 5 0 2 0 0"
LR_nextst6="0 0 0 0 0 6 0 0 6 0"

LR_action1="0 0 0 0 0 0 0 1 0 0"
LR_action2="3 0 0 0 0 4 0 0 0 2"
LR_action3="0 5 7 0 6 8 6 0 0 0"
LR_action4="0 0 0 8 0 6 0 9 0 0"
LR_action5="0 0 0 0 0 6 0 10 0 0"
LR_action6="0 0 0 0 0 4 0 0 11 0"

LR_vector1="14 13 255"
LR_vector2="8 255"
LR_vector3="6 255"
LR_vector4="11 12 255"
LR_vector5="1 4 10 7 255"
LR_vector6="7 255"
LR_vector7="3 13 255"
LR_vector8="13 255"
LR_vector9="2 9 13 255"
LR_vector10="2 5 13 255"
LR_vector11="12 255"

LR_module1=check_all_files_exist
LR_module2=check_directory_writable
LR_module3=clean_up_directory
LR_module4=compile_all_subroutines
LR_module5=delete_product_files
LR_module6=get_binary_install_action
LR_module7=get_directory_name
LR_module8=get_source_install_action
LR_module9=install_product_files
LR_module10=link_main_programs
LR_module11=return_error_feedback
LR_module12=terminate_the_program
LR_module13=what_package_do_we_have
LR_module14=what_system_are_we_on

##########################   INITIALISE THE PROGRAM   #########################

function initialise_the_program
{
    echo ""
    echo "Libero installation script                       Version $VERSION"
    echo "-------------------------------------------------------------"
    echo "This script installs or de-installs Libero on your UNIX system."
    echo "If you are going to install into a system binary directory you"
    echo "will need write-access to the system directory.  You can also"
    echo "run Libero from the current directory."

    if test -f $CATALOG; then
        the_next_event=$ok_event
    else
        echo "install: $CATALOG not found - cannot continue"
        the_next_event=$error_event
    fi
}


##########################   WHAT SYSTEM ARE WE ON   ##########################

function what_system_are_we_on
{
    #   Detect UNIX system type.  This algorithm returns one of these system
    #   names, as far as I know at present:
    #
    #       AIX      APOLLO   A/UX     BSD/OS   HP-UX    IRIX
    #       Linux    NCR      NetBSD   NEXT     OSF1     SCO
    #       Pyramid  SunOS    ULTRIX   Generic
    #

    UTYPE=Generic
    if [ -s /usr/bin/uname       ]; then UTYPE=`/usr/bin/uname`; fi
    if [ -s /bin/uname           ]; then UTYPE=`/bin/uname`; fi

    if [ -s /usr/apollo/bin      ];               then UTYPE=APOLLO;  fi
    if [ -s /usr/bin/ncrm        ];               then UTYPE=NCR;     fi
    if [ -s /usr/bin/swconfig    ];               then UTYPE=SCO;     fi
    if [ -s /usr/lib/NextStep/software_version ]; then UTYPE=NEXT;    fi
    if [ "$UTYPE" = "SMP_DC.OSx" ];               then UTYPE=Pyramid; fi

    #   Set compiler options according to compiler and UNIX system type
    if   [ "$CCNAME" = "gcc"  ]; then
        CCOPTS="-O2 -Wall -pedantic"
    elif [ "$UTYPE" = "AIX"   ]; then
        CCOPTS="-O"
    elif [ "$UTYPE" = "Linux" ]; then
        CCOPTS="-O2 -Wall -pedantic"
    elif [ "$UTYPE" = "HP-UX" ]; then
        CCOPTS="-O -Aa"
    elif [ "$UTYPE" = "SunOS" ]; then
        CCOPTS="-O -vc -Xa"
    else
        CCOPTS=""
    fi

    echo ""
    echo "UNIX=\"$UTYPE\", compiler=\"$CCNAME\", options=\"$CCOPTS\""
    echo "-------------------------------------------------------------"
}


#########################   WHAT PACKAGE DO WE HAVE   #########################

function what_package_do_we_have
{
    if   test -f lr.c; then
        the_next_event=$source_event
    elif test -f lr; then
        the_next_event=$binary_event
    else
        echo "install: could find neither source or binary for Libero"
        the_next_event=$error_event
    fi
}


########################   GET SOURCE INSTALL ACTION   ########################

function get_source_install_action
{
    echo ""
    echo "Choose an action:"
    echo "  (b)uild Libero and optionally install"
    echo "  (i)nstall Libero in target directory"
    echo "  (d)e-install Libero"
    echo "  (c)lean-up current directory"
    echo "  (q)uit"
    echo ""
    echo "Choice:"
    read ACTION

    if   test "$ACTION" = "b"; then
        the_next_event=$build_event
    elif test "$ACTION" = "i"; then
        the_next_event=$install_event
    elif test "$ACTION" = "d"; then
        the_next_event=$delete_event
    elif test "$ACTION" = "c"; then
        the_next_event=$cleanup_event
    elif test "$ACTION" = "q"; then
        the_next_event=$quit_event
    else
        the_next_event=$error_event
    fi
}


########################   GET BINARY INSTALL ACTION   ########################

function get_binary_install_action
{
    echo ""
    echo "Choose an action:"
    echo "  (i)nstall Libero in target directory"
    echo "  (d)e-install Libero"
    echo "  (q)uit"
    echo ""
    echo "Choice:"
    read ACTION

    if   test "$ACTION" = "i"; then
        the_next_event=$install_event
    elif test "$ACTION" = "d"; then
        the_next_event=$delete_event
    elif test "$ACTION" = "q"; then
        the_next_event=$quit_event
    else
        the_next_event=$error_event
    fi
}


##########################   CHECK ALL FILES EXIST   ##########################

function check_all_files_exist
{
    echo "Checking for required files..."
    for FILE in `awk '/^&.*@m/ {print $2}' $CATALOG`; do
        if test ! -f $FILE; then
            echo "install: missing $FILE - " \
                  `egrep "& $FILE " $CATALOG | cut -f2 -d%`
            raise_exception $error_event
        fi
    done
}


#########################   COMPILE ALL SUBROUTINES   #########################

function compile_all_subroutines
{
    rm -f *.o
    for FILE in `awk '/^&.*@c/ {print $2}' $CATALOG`; do
        echo "Compiling $FILE..."
        $CCNAME -c $CCOPTS $FILE
    done
}


############################   LINK MAIN PROGRAMS   ###########################

function link_main_programs
{
    for FILE in `awk '/^&.*@l/ {print $2}' $CATALOG`; do
        echo "Compiling and linking $FILE..."
        test -f $FILE.o && rm $FILE.o
        $CCNAME -o $FILE $CCOPTS $FILE.c *.o
    done
}


############################   GET DIRECTORY NAME   ###########################

function get_directory_name
{
    echo "Enter the install directory:"
    echo "  (Enter)$DEFAULTDIR"
    echo "  (.)$PWD"
    echo "  (q)uit"
    echo ""
    echo "Choice:"
    read INSTALLDIR

    if test "$INSTALLDIR" = ""; then
        INSTALLDIR=$DEFAULTDIR
        the_next_event=$ok_event

    elif test "$INSTALLDIR" = "."; then
        echo "install: leaving files in current directory"
        the_next_event=$current_event

    elif test "$INSTALLDIR" = "q"; then
        the_next_event=$quit_event

    elif test -d "$INSTALLDIR"; then
        the_next_event=$ok_event

    else
        echo "install: $INSTALLDIR is not a directory"
        the_next_event=$error_event
    fi
}


#########################   CHECK DIRECTORY WRITABLE   ########################

function check_directory_writable
{
    if test ! -w "$INSTALLDIR"; then
        echo "install: you do not have write access for $INSTALLDIR"
        raise_exception $error_event
    fi
}


############################   CLEAN UP DIRECTORY   ###########################

function clean_up_directory
{
    for FILE in `awk '/^&.*@d/ {print $2}' $CATALOG`; do
        echo "Deleting $FILE: " \
             `egrep "& $FILE " $CATALOG | cut -f2 -d%`
        test -f $FILE && rm -f $FILE
    done
}


##########################   INSTALL PRODUCT FILES   ##########################

function install_product_files
{
    echo "Installing files into $INSTALLDIR..."
    for FILE in `awk '/^&.*@i/ {print $2}' $CATALOG`; do
        echo "$FILE: " \
             `egrep "& $FILE " $CATALOG | cut -f2 -d%`
        cp $FILE $INSTALLDIR
        chmod a+r $FILE
    done

    for FILE in `awk '/^&.*@x/ {print $2}' $CATALOG`; do
        echo "$FILE: " \
             `egrep "& $FILE " $CATALOG | cut -f2 -d%`
        cp $FILE $INSTALLDIR
        chmod a+rx $FILE
    done
}


###########################   DELETE PRODUCT FILES   ##########################

function delete_product_files
{
    echo "Deleting files from $INSTALLDIR..."
    for FILE in `awk '/^&.*@[ix]/ {print $2}' $CATALOG`; do
        if test ! -f $INSTALLDIR/$FILE; then
            echo "install: $INSTALLDIR/$FILE does not exist - skipping"
        else
            echo "$FILE: " \
                 `egrep "& $FILE " $CATALOG | cut -f2 -d%`
            rm -f $INSTALLDIR/$FILE
        fi
    done
}


##########################   RETURN ERROR FEEDBACK   ##########################

function return_error_feedback
{
    echo "install: aborted"
    echo ""
    feedback=1
}


############################   GET EXTERNAL EVENT   ###########################

function get_external_event
{
    return
}


##########################   TERMINATE THE PROGRAM    #########################

function terminate_the_program
{
    the_next_event=$terminate_event
}

function LR_idx {                       #   Extract one item from array
    shift $1
    return $1
}

function raise_exception {
    exception_raised=TRUE
    test "$1" != "" && the_exception_event=$1
}

###################################   MAIN   ##################################

LR_state=1
script_name=$0
initialise_the_program $*
while [ $the_next_event != $terminate_event ]; do
    LR_event=$the_next_event
    if [ $LR_event -gt 10 -o $LR_event -lt 1 \
    -o `expr $LR_event : ".*"` -gt 3 ]; then
        echo State $LR_state - event $LR_event is out of range
        exit 1
    fi
    eval "LR_idx $LR_event \$LR_action$LR_state"; LR_index=$?
    LR_savest=$LR_state

    #   If no action for this event, try the defaults state
    if [ $LR_index -eq 0 ]; then
        LR_state=$LR_defaults_state
        eval "LR_idx $LR_event \$LR_action$LR_state"; LR_index=$?
        if [ $LR_index -eq 0 ]; then
            echo State $LR_state - event $LR_event is not accepted
            exit 1
        fi
    fi

    the_next_event=0
    the_exception_event=0
    exception_raised=FALSE

    #   Execute module list for state transition
    LR_vecptr=1
    while true; do
        eval "LR_idx $LR_vecptr \$LR_vector$LR_index"; LR_modnbr=$?
        if [ $LR_modnbr -eq 255 -o $exception_raised = TRUE ]; then
            break
        fi
        eval "\$LR_module$LR_modnbr"    #   Execute the module of code
        let LR_vecptr=$LR_vecptr+1
    done

    #   Handle exception if any was raised
    if [ $exception_raised = TRUE ]; then
        if [ $the_exception_event -ne 0 ]; then
            LR_event=$the_exception_event
        fi
        the_next_event=$LR_event
    else
        eval "LR_idx $LR_event \$LR_nextst$LR_state"; LR_state=$?
    fi
    if [ $LR_state -eq $LR_defaults_state ]; then
        LR_state=$LR_savest
    fi
    if [ $the_next_event -eq 0 ]; then
        get_external_event
        if [ $the_next_event -eq 0 ]; then
            echo No event set after event $LR_event in state $LR_state
            exit 1
        fi
    fi
done
exit $feedback
