#!/bin/sh
# Usage: clisp-link command [more args]
# where
#   command = link, create-module-set, add-module-set, add-module-sets, run
# For more usage information, see <doc/impnotes.html#modules>.
# Or <http://clisp.cons.org/impnotes.html#modules>.
# Bruno Haible 19.10.1994
# Sam Steingold 2002-08-11

# This could as well be written in Lisp, for portability. But I don't like
# the idea to have one Lisp process running while the next one is built.

usage () {
echo "Usage: $0 [ link | create-module-set | add-module-set | add-module-sets | run ] ..." 1>&2
exit 1
}

link () {
# Make a link from $1 to $2. Try symbolic link, hard link, file copying.
dirname=`echo "$1" | sed -e 's,/[^/]*$,,'`
test -n "$dirname" || dirname='/'
basename=`echo "$1" | sed -e 's,^.*/,,'`
absolute_dirname=`cd "$dirname" ; /bin/pwd`
ln -s "$absolute_dirname"/"$basename" "$2" 2>/dev/null ||
  ln "$1" "$2" 2>/dev/null ||
  cp -p "$1" "$2"
}

echotab () {
cat <<!!
	$1
!!
}

# Print the commands being executed
vecho () {
  echo "$@"
}

verbose () {
  echo "$@"
  "$@"
}

# Remove the comment to Set debugging output on
#set -x

# Exit immediately if some command fails.
set -e

# Check number of arguments. Need at least one argument.
if [ $# = 0 ] ; then
  usage
fi

# Where is the link kit?
if [ -n "$CLISP_LINKKIT" ] ; then
  linkkitdir="$CLISP_LINKKIT"
else
  linkkitdir=./linkkit
fi
LISPRUN="lisp.run";
if [ ! -r "$linkkitdir"/modules.d -o ! -r "$linkkitdir"/modules.c -o ! -r "$linkkitdir"/clisp.h ] ; then
  echo "$0: No link kit found in $CLISP_LINKKIT" 1>&2
  exit 1
fi
absolute_linkkitdir=`cd "$linkkitdir" ; /bin/pwd`

# Dispatch according to the first argument.
case "$1" in

  link)
    # This is actually obsolete because it is easier done by a simple
    # "make" w.r.t. to the distmakefile.
    # Usage: clisp-link link dir
    if [ $# != 2 ] ; then
      echo "Usage: $0 link dir" 1>&2
      exit 1
    fi
    dir="$2"
    # What to do if we abort.
    trap 'rm -f "$dir"/${LISPRUN} "$dir"/w${LISPRUN}' 1 2 15
    # Read the variables CC, CPPFLAGS, CFLAGS, CLFLAGS, LIBS, X_LIBS, RANLIB, FILES
    . "$dir"/makevars
    vecho "$0: Entering directory \`$dir'"
    # Generate new modules.o, compiled from modules.c, includes modules.h
    (cd "$dir" ; link "$absolute_linkkitdir"/modules.c modules.c ; verbose ${CC} ${CPPFLAGS} ${CFLAGS} -I"$absolute_linkkitdir" -c modules.c ; rm -f modules.c)
    # Generate new ${LISPRUN}
    (cd "$dir" ; verbose ${CC} ${CFLAGS} ${CLFLAGS} modules.o ${LIBS} -o ${LISPRUN})
    vecho "$0: Leaving directory \`$dir'"
    # Done.
    trap '' 1 2 15
    ;;

  create-module-set)
    # Usage: clisp-link create-module-set moduledir {file}*
    case $# in
      0 | 1) echo "Usage: $0 create-module-set moduledir file ..." 1>&2
             exit 1 ;;
    esac
    moduledir="$2"
    shift
    shift
    files="$*"
    if [ -r "$moduledir" ] ; then
      if [ -d "$moduledir" ] ; then
        echo "$0: $moduledir already exists" 1>&2
        exit 1
      else
        echo "$0: $moduledir is not a directory" 1>&2
        exit 1
      fi
    fi
    mkdir "$moduledir"
    modulename=`echo "$moduledir" | sed -e 's,^.*/,,'`
    files_c=''
    files_o=''
    for file in $files; do
      file=`echo "$file" | sed -e 's,\.c$,,'`.c
      filename=`echo "$file" | sed -e 's,^.*/,,'`
      case "$file" in
        /*) relative_file="$file" ;;
        *)  case "$moduledir" in
              /*) relative_file="$file" ;;
              *)  relative_file=`echo "$moduledir"/ | sed -e 's,[^/][^/]*/*/,../,g'`"$file" ;;
            esac ;;
      esac
      ln -s "$relative_file" "$moduledir"/"$filename" || ln "$file" "$moduledir"/"$filename" || cp -p "$file" "$moduledir"/"$filename"
      files_c="$files_c"' '"$filename"
      files_o="$files_o"' '`echo "$filename" | sed -e 's,\.c$,,'`.o
    done
    if false; then
      # No Makefile
      (echo "file_list=''"
       for fc in $files_c; do
         fo=`echo "$fc" | sed -e 's,\.c$,,'`.o
         echo 'if test -r '"$fc"'; then'
         echo "  if test '"'!'"' -f $fo || test $fo -ot $fc; then"
         echo '    ${CC} ${CPPFLAGS} ${CFLAGS} -I"$absolute_linkkitdir" -c '"$fc"
         echo '  fi'
         echo '  file_list="$file_list"'"' $fo'"
         echo 'fi'
       done
       echo 'NEW_FILES="$file_list"'
       echo 'NEW_LIBS="$file_list"'
       echo "TO_LOAD=''"
      ) > "$moduledir"/link.sh
    else
      # With Makefile
      (echo "# Makefile for CLISP module set $modulename"
       echo
       echo "CC ="
       echo "CPPFLAGS ="
       echo "CFLAGS ="
       echo "INCLUDES="
       echo
       echo "CLISP ="
       echo
       echo "SHELL = /bin/sh"
       echo
       for fc in $files_c; do
         fo=`echo "$fc" | sed -e 's,\.c$,,'`.o
         echo "$fo : $fc"
         echotab '$(CC) $(CPPFLAGS) $(CFLAGS) -I$(INCLUDES) -c '"$fc"
         echo
       done
       echo "clisp-module :$files_o"
       echo
      ) > "$moduledir"/Makefile
      (echo "file_list=''"
       echo "mod_list=''"
       for fc in $files_c; do
         fo=`echo "$fc" | sed -e 's,\.c$,,'`.o
         mod=`echo "$fc" | sed -e 's,\.c$,,' | sed -e 's,[^A-Za-z0-9_],_,g'`
         # The last sed command must agree with foreign1.lisp:to-module-name.
         echo 'if test -r '"$fc"'; then'
         echo '  file_list="$file_list"'"' $fo'"
         echo '  mod_list="$mod_list"'"' $mod'"
         echo 'fi'
       done
       echo 'make clisp-module CC="${CC}" CPPFLAGS="${CPPFLAGS}" CFLAGS="${CFLAGS}" INCLUDES="$absolute_linkkitdir"'
       echo 'NEW_FILES="$file_list"'
       echo 'NEW_LIBS="$file_list"'
       echo 'NEW_MODULES="$mod_list"'
       echo "TO_LOAD=''"
      ) > "$moduledir"/link.sh
    fi
    ;;

  add-module-set)
    # Usage: clisp-link add-module-set moduledir source-dir destination-dir
    if [ $# != 4 ] ; then
      echo "Usage: $0 add-module-set moduledir source-dir destination-dir" 1>&2
      exit 1
    fi
    moduledir="$2"
    sourcedir="$3"
    destinationdir="$4"
    if [ ! -d "$moduledir" ] ; then
      echo "$0: $moduledir is not a directory" 1>&2
      exit 1
    fi
    if [ ! -d "$sourcedir" ] ; then
      echo "$0: $sourcedir is not a directory" 1>&2
      exit 1
    fi
    if [ -r "$destinationdir" ] ; then
      if [ -d "$destinationdir" ] ; then
        echo "$0: $destinationdir already exists" 1>&2
        exit 1
      else
        echo "$0: $destinationdir is not a directory" 1>&2
        exit 1
      fi
    fi
    mkdir "$destinationdir"
    absolute_currentdir=`/bin/pwd`
    absolute_sourcedir=`cd "$sourcedir" ; /bin/pwd`
    absolute_destinationdir=`cd "$destinationdir" ; /bin/pwd`
    installbasedir=`dirname "$sourcedir"`
    # What to do if we abort.
    trap 'rm -rf "$absolute_destinationdir"' 1 2 15
    if [ "$absolute_sourcedir" = "$absolute_destinationdir" ] ; then
      echo "$0: directories $sourcedir and $destinationdir may not be the same" 1>&2
      exit 1
    fi
    if [ ! -r "$sourcedir"/lisp.a -o ! -x "$sourcedir"/${LISPRUN} -o ! -r "$sourcedir"/lispinit.mem -o ! -r "$sourcedir"/modules.h -o ! -r "$sourcedir"/modules.o -o ! -r "$sourcedir"/makevars ] ; then
      echo "$0: directory $sourcedir does not contain a clisp linking set" 1>&2
      exit 1
    fi
    if [ ! -r "$moduledir/link.sh" ] ; then
      echo "$0: directory $moduledir does not contain a clisp module" 1>&2
      exit 1
    fi
    modulename=`echo "$moduledir" | sed -e 's,^.*/,,'`
    # Read the variables CC, CPPFLAGS, CFLAGS, CLFLAGS, LIBS, X_LIBS, RANLIB, FILES
    . "$sourcedir"/makevars
    # Prepare the module directory and read the variables NEW_FILES, NEW_LIBS
    NEW_FILES=''
    NEW_LIBS=''
    NEW_MODULES=''
    TO_PRELOAD=''
    TO_LOAD=''
    cd "$moduledir"
    . ./link.sh
    cd "$absolute_currentdir"
    # Generate new modules.h
    (cat "$sourcedir"/modules.h
     for mod in $NEW_MODULES ; do
       echo 'MODULE('"$mod"')'
     done) > "$destinationdir"/modules.h
    # Generate new lisp.a
    for f in ${FILES}; do
      link "$sourcedir"/$f "$destinationdir"/$f
    done
    # Generate other libraries
    for f in ${NEW_FILES}; do
      link "$moduledir"/$f "$destinationdir"/$f
    done
    # Update the LIBS and FILES variables
    LIBS=${NEW_LIBS}' '${LIBS}
    FILES=${FILES}' '${NEW_FILES}
    # Generate new modules.o, compiled from modules.c, includes new modules.h
    (cd "$destinationdir" ; link "$absolute_linkkitdir"/modules.c modules.c ; verbose ${CC} ${CPPFLAGS} ${CFLAGS} -I"$absolute_linkkitdir" -c modules.c ; rm -f modules.c)
    # Generate new ${LISPRUN}
    (cd "$destinationdir" ; verbose ${CC} ${CFLAGS} ${CLFLAGS} modules.o ${LIBS} -o ${LISPRUN})
    if [ -n "$TO_PRELOAD" ] ; then
      # Generate new preliminary lispinit.mem
      to_preload=''
      for f in $TO_PRELOAD; do
        to_preload="$to_preload $moduledir/$f"
      done
      verbose "$sourcedir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem -norc -q -i $to_preload -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
      lispinitdir="$destinationdir"
    else
      lispinitdir="$sourcedir"
    fi
    # Generate new lispinit.mem
    to_load=''
    for f in $TO_LOAD; do
      to_load="$to_load $moduledir/$f"
    done
    verbose "$destinationdir"/${LISPRUN} -B "$installbasedir" -M "$lispinitdir"/lispinit.mem -norc -q -i $to_load -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
    # Generate new makevars
    sed_escape_commas='s/,/\\,/g'
    LIBS_escaped=`echo "$LIBS" | sed -e "$sed_escape_commas"`
    sed -e "s,^LIBS=.*\$,LIBS='${LIBS_escaped}'," -e "s,^FILES=.*\$,FILES='${FILES}'," < "$sourcedir"/makevars > "$destinationdir"/makevars
    # Done.
    trap '' 1 2 15
    ;;

  add-module-sets)
    # This is functionally the same as multiple add-module-set commands,
    # but is faster and requires less disk space.
    # Usage: clisp-link add-module-sets source-dir destination-dir moduledir...
    if [ $# -lt 3 ] ; then
      echo "Usage: $0 add-module-sets source-dir destination-dir moduledir..." 1>&2
      exit 1
    fi
    sourcedir="$2"
    destinationdir="$3"
    shift
    shift
    shift
    moduledirs="$@"
    if [ ! -d "$sourcedir" ] ; then
      echo "$0: $sourcedir is not a directory" 1>&2
      exit 1
    fi
    if [ -r "$destinationdir" ] ; then
      if [ -d "$destinationdir" ] ; then
        echo "$0: $destinationdir already exists" 1>&2
        exit 1
      else
        echo "$0: $destinationdir is not a directory" 1>&2
        exit 1
      fi
    fi
    for moduledir in $moduledirs; do
      if [ ! -d "$moduledir" ] ; then
        echo "$0: $moduledir is not a directory" 1>&2
        exit 1
      fi
    done
    mkdir "$destinationdir"
    absolute_currentdir=`/bin/pwd`
    absolute_sourcedir=`cd "$sourcedir" ; /bin/pwd`
    absolute_destinationdir=`cd "$destinationdir" ; /bin/pwd`
    installbasedir=`dirname "$sourcedir"`
    # What to do if we abort.
    trap 'rm -rf "$absolute_destinationdir"' 1 2 15
    if [ "$absolute_sourcedir" = "$absolute_destinationdir" ] ; then
      echo "$0: directories $sourcedir and $destinationdir may not be the same" 1>&2
      exit 1
    fi
    if [ ! -r "$sourcedir"/lisp.a -o ! -x "$sourcedir"/${LISPRUN} -o ! -r "$sourcedir"/lispinit.mem -o ! -r "$sourcedir"/modules.h -o ! -r "$sourcedir"/modules.o -o ! -r "$sourcedir"/makevars ] ; then
      echo "$0: directory $sourcedir does not contain a clisp linking set" 1>&2
      exit 1
    fi
    for moduledir in $moduledirs; do
      if [ ! -r "$moduledir/link.sh" ] ; then
        echo "$0: directory $moduledir does not contain a clisp module" 1>&2
        exit 1
      fi
    done
    # Read the variables CC, CPPFLAGS, CFLAGS, CLFLAGS, LIBS, X_LIBS, RANLIB, FILES
    . "$sourcedir"/makevars
    if [ -z "$moduledirs" ] ; then
      # Just make links from $destinationdir to $sourcedir
      for f in ${LISPRUN} lispinit.mem modules.h modules.o makevars ${FILES}; do
        link "$sourcedir"/$f "$destinationdir"/$f
      done
    else
      # Prepare the module directories and read their variables
      allmodulevars=''
      for moduledir in $moduledirs; do
        modulename=`echo "$moduledir" | sed -e 's,^.*/,,'`
        # Prepare the module directory and read the variables NEW_FILES, NEW_LIBS
        NEW_FILES=''
        NEW_LIBS=''
        NEW_MODULES=''
        TO_PRELOAD=''
        TO_LOAD=''
        cd "$moduledir"
        . ./link.sh
        cd "$absolute_currentdir"
        # This is a crazy way to build doubly nested lists.
        allmodulevars="$allmodulevars""@@SEP1@@""moduledir=\""`echo "$moduledir" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
        allmodulevars="$allmodulevars""@@SEP2@@""modulename=\""`echo "$modulename" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
        allmodulevars="$allmodulevars""@@SEP2@@""NEW_FILES=\""`echo "$NEW_FILES" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
        allmodulevars="$allmodulevars""@@SEP2@@""NEW_LIBS=\""`echo "$NEW_LIBS" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
        allmodulevars="$allmodulevars""@@SEP2@@""NEW_MODULES=\""`echo "$NEW_MODULES" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
        allmodulevars="$allmodulevars""@@SEP2@@""TO_PRELOAD=\""`echo "$TO_PRELOAD" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
        allmodulevars="$allmodulevars""@@SEP2@@""TO_LOAD=\""`echo "$TO_LOAD" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
      done
      # Generate new modules.h
      (cat "$sourcedir"/modules.h
       for modulevars in `echo $allmodulevars | sed -e 's,@@SEP1@@, ,g'`; do
         for assignment in `echo $modulevars | sed -e 's,@@SEP2@@, ,g'`; do
           eval `echo $assignment | sed -e 's,@@SEP3@@, ,g'`
         done
         for mod in $NEW_MODULES ; do
           echo 'MODULE('"$mod"')'
         done
       done) > "$destinationdir"/modules.h
      # Generate new lisp.a
      for f in ${FILES}; do
        link "$sourcedir"/$f "$destinationdir"/$f
      done
      PRELOAD=''
      LOAD=''
      for modulevars in `echo $allmodulevars | sed -e 's,@@SEP1@@, ,g'`; do
        for assignment in `echo $modulevars | sed -e 's,@@SEP2@@, ,g'`; do
          eval `echo $assignment | sed -e 's,@@SEP3@@, ,g'`
        done
        # Generate other libraries
        for f in ${NEW_FILES}; do
          link "$moduledir"/$f "$destinationdir"/$f
        done
        # Update the LIBS and FILES variables
        LIBS=${NEW_LIBS}' '${LIBS}
        FILES=${FILES}' '${NEW_FILES}
        for f in $TO_PRELOAD; do
          PRELOAD=${PRELOAD}' '"$moduledir/$f"
        done
        for f in $TO_LOAD; do
          LOAD=${LOAD}' '"$moduledir/$f"
        done
      done
      # Generate new modules.o, compiled from modules.c, includes new modules.h
      (cd "$destinationdir" ; link "$absolute_linkkitdir"/modules.c modules.c ; verbose ${CC} ${CPPFLAGS} ${CFLAGS} -I"$absolute_linkkitdir" -c modules.c ; rm -f modules.c)
      # Generate new ${LISPRUN}
      (cd "$destinationdir" ; verbose ${CC} ${CFLAGS} ${CLFLAGS} modules.o ${LIBS} -o ${LISPRUN})
      if [ -n "$PRELOAD" ] ; then
        # Generate new preliminary lispinit.mem
        verbose "$sourcedir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem -norc -q -i ${PRELOAD} -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
      fi
      # Generate new lispinit.mem
      if [ -n "$PRELOAD" ] ; then
        verbose "$destinationdir"/${LISPRUN} -B "$installbasedir" -M "$destinationdir"/lispinit.mem -norc -q -i ${LOAD} -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
      else
        verbose "$destinationdir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem -norc -q -i ${LOAD} -x "(saveinitmem \"$destinationdir/lispinit.mem\")"
      fi
      # Generate new makevars
      sed_escape_commas='s/,/\\,/g'
      LIBS_escaped=`echo "$LIBS" | sed -e "$sed_escape_commas"`
      sed -e "s,^LIBS=.*\$,LIBS='${LIBS_escaped}'," -e "s,^FILES=.*\$,FILES='${FILES}'," < "$sourcedir"/makevars > "$destinationdir"/makevars
    fi
    # Done.
    trap '' 1 2 15
    ;;

  run)
    # This is functionally the same as an add-module-sets command, followed
    # by running the resulting linking set, but is faster and requires less
    # disk space if dynamic loading is available.
    # Usage: clisp-link run source-dir moduledir...
    if [ $# -lt 2 ] ; then
      echo "Usage: $0 run source-dir moduledir..." 1>&2
      exit 1
    fi
    sourcedir="$2"
    installbasedir=`dirname "$sourcedir"`
    shift
    shift
    if test -n ""; then
      moduledirs="$@"
      if [ ! -d "$sourcedir" ] ; then
        echo "$0: $sourcedir is not a directory" 1>&2
        exit 1
      fi
      for moduledir in $moduledirs; do
        if [ ! -d "$moduledir" ] ; then
          echo "$0: $moduledir is not a directory" 1>&2
          exit 1
        fi
      done
      absolute_currentdir=`/bin/pwd`
      if [ ! -r "$sourcedir"/lisp.a -o ! -x "$sourcedir"/${LISPRUN} -o ! -r "$sourcedir"/lispinit.mem -o ! -r "$sourcedir"/modules.h -o ! -r "$sourcedir"/modules.o -o ! -r "$sourcedir"/makevars ] ; then
        echo "$0: directory $sourcedir does not contain a clisp linking set" 1>&2
        exit 1
      fi
      for moduledir in $moduledirs; do
        if [ ! -r "$moduledir/link.sh" ] ; then
          echo "$0: directory $moduledir does not contain a clisp module" 1>&2
          exit 1
        fi
      done
      # Read the variables CC, CPPFLAGS, CFLAGS, CLFLAGS, LIBS, X_LIBS, RANLIB, FILES
      . "$sourcedir"/makevars
      if [ -z "$moduledirs" ] ; then
        "$sourcedir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem
      else
        # Prepare the module directories and read their variables
        allmodulevars=''
        for moduledir in $moduledirs; do
          modulename=`echo "$moduledir" | sed -e 's,^.*/,,'`
          # Prepare the module directory and read the variables NEW_FILES, NEW_LIBS
          NEW_FILES=''
          NEW_LIBS=''
          NEW_MODULES=''
          TO_PRELOAD=''
          TO_LOAD=''
          cd "$moduledir"
          . ./link.sh
          cd "$absolute_currentdir"
          # This is a crazy way to build doubly nested lists.
          allmodulevars="$allmodulevars""@@SEP1@@""moduledir=\""`echo "$moduledir" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
          allmodulevars="$allmodulevars""@@SEP2@@""modulename=\""`echo "$modulename" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
          allmodulevars="$allmodulevars""@@SEP2@@""NEW_FILES=\""`echo "$NEW_FILES" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
          allmodulevars="$allmodulevars""@@SEP2@@""NEW_LIBS=\""`echo "$NEW_LIBS" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
          allmodulevars="$allmodulevars""@@SEP2@@""NEW_MODULES=\""`echo "$NEW_MODULES" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
          allmodulevars="$allmodulevars""@@SEP2@@""TO_PRELOAD=\""`echo "$TO_PRELOAD" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
          allmodulevars="$allmodulevars""@@SEP2@@""TO_LOAD=\""`echo "$TO_LOAD" | sed -e 's,",\\\\",g' -e 's, ,@@SEP3@@,g'`"\""
        done
        PRELOAD=''
        LINKLIBS=''
        MODULES=''
        LOAD=''
        for modulevars in `echo $allmodulevars | sed -e 's,@@SEP1@@, ,g'`; do
          for assignment in `echo $modulevars | sed -e 's,@@SEP2@@, ,g'`; do
            eval `echo $assignment | sed -e 's,@@SEP3@@, ,g'`
          done
          for f in $TO_PRELOAD; do
            PRELOAD=${PRELOAD}' '"$moduledir/$f"
          done
          NEW_LIBS_ABS=''
          for f in ${NEW_LIBS}; do
            case "$f" in
              -* | /*) NEW_LIBS_ABS="$NEW_LIBS_ABS $f" ;;
              *) NEW_LIBS_ABS="$NEW_LIBS_ABS $moduledir/$f" ;;
            esac
          done
          LINKLIBS=${NEW_LIBS_ABS}' '${LINKLIBS}
          for mod in $NEW_MODULES; do
            MODULES=${MODULES}' '"$mod"
          done
          for f in $TO_LOAD; do
            LOAD=${LOAD}' '"$moduledir/$f"
          done
        done
        tmpsharedlib="${TMPDIR-/tmp}/clisplink$$.so"
        tmpinitlisp="${TMPDIR-/tmp}/clisplink$$.lisp"
        # What to do if we abort.
        trap 'rm -f "$tmpsharedlib" "$tmpinitlisp"' 0 1 2 15
        # Create an initialization file with a couple of load forms.
        (for f in $PRELOAD; do echo "(load \"${f}\")"; done
         echo "(system::dynload-modules \"$tmpsharedlib\" (quote ("
         for mod in $MODULES; do echo "  \"${mod}\""; done
         echo ")))"
         for f in $LOAD; do echo "(load \"${f}\")"; done ) > "$tmpinitlisp"
        # Create a shared library.
        lib="$tmpsharedlib"; libs="$LINKLIBS"; verbose 
        # Run clisp, attach the shared library and load the Lisp stuff.
        "$sourcedir"/${LISPRUN} -B "$installbasedir" -M "$sourcedir"/lispinit.mem -i "$tmpinitlisp"
        rm -f "$tmpsharedlib" "$tmpinitlisp"
        trap '' 0 1 2 15
      fi
    else
      destinationdir="${TMPDIR-/tmp}/clisplink$$"
      # What to do if we abort.
      trap 'rm -rf "$destinationdir"' 0 1 2 15
      "$0" add-module-sets "$sourcedir" "$destinationdir" "$@" && "$destinationdir"/${LISPRUN} -B "$installbasedir" -M "$destinationdir"/lispinit.mem
      rm -rf "$destinationdir"
      trap '' 0 1 2 15
    fi
    ;;

  *) usage;;
esac

