# cl-launch 4.1.4.1 shell wrapper
#   Find and execute the most appropriate supported Lisp implementation
#   to evaluate software prepared with cl-launch.
#
# This file was automatically generated and contains parts of CL-Launch
#
# Please send your improvements to the author:
# fare at tunes dot org < http://www.cliki.net/Fare%20Rideau >.
#
# cl-launch is available under the terms of the bugroff license.
#       http://tunes.org/legalese/bugroff.html
# You may at your leisure use the MIT license instead < http://opensource.org/licenses/MIT >
#
# This software can be used in conjunction with any other software:
# the result may consist in pieces of the two software glued together in
# a same file, but even then these pieces remain well distinguished, and are
# each available under its own copyright and licensing terms, as applicable.
# The parts that come from the other software are subject to the terms of use
# and distribution relative to said software, which may well be
# more restrictive than the terms of this software (according to lawyers
# and the armed henchmen they got the taxpayers to pay to enforce their laws).
# The bits of code generated by cl-launch, however, remain available
# under the terms of their own license, and you may service them as you wish:
# manually, using cl-launch --update or whichever means you prefer.
# That said, if you believe in any of that intellectual property scam,
# you may be subject to the terms of my End-Seller License:
#       http://www.livejournal.com/users/fare/21806.html
#
ECHOn () { printf '%s' "$*" ;}
simple_term_p () {
  case "$1" in *[!a-zA-Z0-9-+_,.:=%/]*) return 1 ;; *) return 0 ;; esac
}
if [ -n "$BASH_VERSION$ZSH_VERSION" ] ; then
  kwote0 () { a="${1//\\/\\\\}" ; a="${a//\`/\\\`}" ; a="${a//\$/\\\$}" ; printf %s "${a//\"/\\\"}" ;}
else
  kwote0 () { ECHOn "$1" | sed -e "s/\([\\\\\"\$\`]\)/\\\\\\1/g" ;}
fi
kwote () { if simple_term_p "$1" ; then ECHOn "$1" ; else kwote0 "$1" ; fi ;}
load_form_0 () { echo "(cl:load $1 :verbose nil :print nil)" ;}
load_form () { load_form_0 "\"$(kwote "$1")\"" ;}
ECHO () { printf '%s\n' "$*" ;}
DBG () { ECHO "$*" >& 2 ;}
abort () { ERR="$1" ; shift ; DBG "$*" ; exit "$ERR" ;}
ABORT () { abort 42 "$*" ;}
DO_LISP=do_exec_lisp
HASH_BANG_FORM='(set-dispatch-macro-character #\# #\! (lambda(stream char arg)(declare(ignore char arg))(values(read-line stream))))'
PACKAGE_FORM="#.(progn(defpackage :uiop/image (:use :cl))())#.(progn(declaim (special uiop/image::*command-line-arguments*))())"
MAYBE_PACKAGE_FORM=
PROGN="(progn"
NGORP=")"

#implementation_foo () {
#  implementation "${foo:-foo}" || return 1
#  OPTIONS=${FOO_OPTIONS:- --option-to-hush-the-banner --option-to-avoid-user-init-script}
#  EVAL=--option-to-pass-a-form-to-Lisp
#  ENDARGS="--option-to-end-Lisp-arguments-and-start-user-arguments"
#  IMAGE_ARG="--option-to-specify-an-image" # "EXECUTABLE_IMAGE" if instead of foo --core x.core you just ./x.core
#  EXEC_LISP=exec_lisp # or some other thing
#  BIN_ARG=FOO # name of the variable with which to override Lisp binary location
#  OPTIONS_ARG=FOO_OPTIONS # name of the variable used above
#  [ -z "$CL_LAUNCH_DEBUG" ] && OPTIONS="${OPTIONS} --option-to-disable-debugger"
#}
implementation_abcl () {
  implementation "${ABCL:-abcl}" || return 1
  OPTIONS="${ABCL_OPTIONS:- --noinform --noinit}" # --nosystem
  EVAL=--eval
  ENDARGS="--"
  IMAGE_ARG=NOT_SUPPORTED_YET
  EXEC_LISP=exec_lisp
  BIN_ARG=ABCL
  OPTIONS_ARG=ABCL_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} --batch" # -backtrace-on-error ???
  fi
}
__implementation_allegro () {
  OPTIONS="${ALLEGRO_OPTIONS:- -QQ -qq}"
  EVAL=-e
  ENDARGS=--
  IMAGE_ARG=-I
  EXEC_LISP=exec_lisp
  BIN_ARG=ALLEGRO
  OPTIONS_ARG=ALLEGRO_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} -batch -backtrace-on-error"
  fi
  HASH_BANG_FORM="(setf *readtable* (copy-readtable))${HASH_BANG_FORM}"
}
implementation_allegro () {
  implementation "${ALLEGRO:-alisp}" || return 1
  __implementation_allegro
}
implementation_allegromodern () {
  implementation "${ALLEGROMODERN:-mlisp}" || return 1
  __implementation_allegro
}

implementation_ccl () {
  # ClozureCL, nee OpenMCL, forked from MCL, formerly Macintosh Common Lisp, nee Coral Common Lisp
  implementation "${CCL:-ccl}" || return 1
  OPTIONS="${CCL_OPTIONS:- --no-init --quiet}"
  EVAL=--eval # -e
  # IMAGE_ARG=--image-name # -I
  IMAGE_ARG=EXECUTABLE_IMAGE # depends on our using :prepend-kernel t
  ENDARGS=--
  # (finish-output) is essential for ccl, that won't do it by default,
  # unlike the other lisp implementations tested.
  EXEC_LISP=exec_lisp
  # exec_lisp will work great for 1.1 and later.
  # For earlier versions, use exec_lisp_arg instead:
  # 1.0 doesn't support --, and the latest 1.1-pre060826 snapshot has a bug
  # whereby it doesn't stop at -- when looking for a -I or --image-file argument.
  STANDALONE_EXECUTABLE=t
  BIN_ARG=CCL
  OPTIONS_ARG=CCL_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} --batch"
  fi
}
implementation_clisp () {
  implementation "${CLISP:-clisp}" || return 1
  OPTIONS="${CLISP_OPTIONS:- -norc --quiet --quiet}"
  EVAL=-x
  LOAD=-i
  ENDARGS="--"
  # if the first argument begins with - there might be problems,
  # so we avoid that and take the cdr or ext:*args*
  # IMAGE_ARG=-M # for use without :executable t
  IMAGE_ARG="EXECUTABLE_IMAGE" # we don't use this by default
  STANDALONE_EXECUTABLE=t # will mostly work as of clisp 2.48, but with a (in)security backdoor.
  # For details, see the thread at http://sourceforge.net/forum/message.php?msg_id=5532730
  EXEC_LISP=exec_lisp
  BIN_ARG=CLISP
  OPTIONS_ARG=CLISP_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} -on-error exit"
  else
    OPTIONS="${OPTIONS} -on-error debug"
  fi
}
implementation_cmucl () {
  implementation "${CMUCL:-cmucl}" || return 1
  OPTIONS="${CMUCL_OPTIONS:- -quiet -noinit}"
  EVAL=-eval
  ENDARGS=--
  #IMAGE_ARG=-core
  IMAGE_ARG="EXECUTABLE_IMAGE"
  STANDALONE_EXECUTABLE=t
  EXEC_LISP=exec_lisp # depends on a recent CMUCL. Works with 20B.
  BIN_ARG=CMUCL
  OPTIONS_ARG=CMUCL_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} -batch"
  fi
}
implementation_ecl () {
  implementation "${ECL:-ecl}" || return 1
  OPTIONS="${ECL_OPTIONS:- -q -norc}"
  EVAL=-eval
  ENDARGS=--
  #IMAGE_ARG="-q -load" # for :fasl
  IMAGE_ARG="EXECUTABLE_IMAGE" # for :program
  STANDALONE_EXECUTABLE=t
  BIN_ARG=ECL
  OPTIONS_ARG=ECL_OPTIONS
  EXEC_LISP=exec_lisp
  if [ -n "$CL_LAUNCH_DEBUG" ] ; then
    PROGN="(handler-bind((error'invoke-debugger))(progn(set'si::*break-enable*'t)"
    NGORP="))"
  fi
}
implementation_ecl_bytecodes () {
  implementation_ecl
  OPTIONS="${ECL_OPTIONS:- -q -norc}"
  OPTIONS="${OPTIONS} -eval (ext::install-bytecodes-compiler)"
  EVAL=-eval
  ENDARGS=--
  #IMAGE_ARG="-q -load" # for :fasl
  IMAGE_ARG="EXECUTABLE_IMAGE" # for :program
  STANDALONE_EXECUTABLE=t
  BIN_ARG=ECL
  OPTIONS_ARG=ECL_OPTIONS
  EXEC_LISP=exec_lisp
  if [ -n "$CL_LAUNCH_DEBUG" ] ; then
    PROGN="(handler-bind((error'invoke-debugger))(progn(set'si::*break-enable*'t)"
    NGORP="))"
  fi
}
implementation_mkcl () { ### Untested
  implementation "${MKCL:-mkcl}" || return 1
  OPTIONS="${MKCL_OPTIONS:- -q -norc}"
  EVAL=-eval
  ENDARGS=--
  #IMAGE_ARG="-q -load" # for :fasl
  IMAGE_ARG="EXECUTABLE_IMAGE" # for :program
  STANDALONE_EXECUTABLE=t
  BIN_ARG=ECL
  OPTIONS_ARG=ECL_OPTIONS
  EXEC_LISP=exec_lisp
  if [ -n "$CL_LAUNCH_DEBUG" ] ; then
    PROGN="(handler-bind((error'invoke-debugger))(progn(set'si::*break-enable*'t)" ## Check this one!
    NGORP="))"
  fi
}
implementation_gcl () {
  implementation "${GCL:-gcl}" || return 1
  OPTIONS="${GCL_OPTIONS}"
  EVAL=-eval
  ENDARGS=-- # -f ?n
  IMAGE_ARG=EXECUTABLE_IMAGE
  BIN_ARG=GCL
  OPTIONS_ARG=GCL_OPTIONS
  export GCL_ANSI=t
  EXEC_LISP=exec_lisp
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} -batch"
  fi
}
implementation_lispworks () { ### NOT EXTENSIVELY TESTED
  # http://www.lispworks.com/documentation/lw70/LW/html/lw-203.htm
  USE_CLBUILD= implementation "${LISPWORKS:-lispworks-console}" || return 1
  OPTIONS="${LISPWORKS_OPTIONS:- -siteinit - -init -}" #
  # As of 7.0.0, LispWorks (still) fails to stop processing arguments with "--" or any marker.
  # Therefore we can't "just" tuck arguments at the end of a command-line, and instead we use
  # exec_lisp_file to create a script that initializes arguments and pass that to LispWorks.
  # Since we don't use -eval, we use -build instead of -load to load the script. LispWorks
  # calls all the -eval and -load in order, then the -siteinit, -init and finally -build.
  # It's OK that we use -build, because using it eschews starting the graphical environment
  # and initialization files even on a graphical image, and quits at the end;
  # that should be redundant with the fact that even if using -load, cl-launch should quit
  # before LispWorks gets to start a graphical environment, anyway.
  EVAL=-eval # LOAD=-load EXEC_LISP=exec_lisp ENDARGS="--" ### FAIL by lack of ENDARGS
  LOAD=-build EXEC_LISP=exec_lisp_file ENDARGS=
  IMAGE_ARG="EXECUTABLE_IMAGE" # we don't use this by default
  STANDALONE_EXECUTABLE=t
  BIN_ARG=LISPWORKS
  OPTIONS_ARG=LISPWORKS_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    : # OPTIONS="${OPTIONS} ..."
  else
    : # OPTIONS="${OPTIONS} ..."
  fi
  export LWLICENSE=$(dirname $LISP_BIN)/lwlicense
}
implementation_sbcl () {
  implementation "${SBCL:-sbcl}" || return 1
  OPTIONS="${SBCL_OPTIONS:- --noinform --userinit /dev/null}"
  # We purposefully specify --userinit /dev/null but NOT --sysinit /dev/null
  EVAL=--eval # SBCL's eval can only handle one form per argument.
  ENDARGS=--end-toplevel-options
  IMAGE_ARG="EXECUTABLE_IMAGE" # we use executable images
  # if you want to test non-executable images, uncomment the one below,
  # and comment out the :executable t in (defun dump-image ...)
  # -IMAGE_ARG=--core
  STANDALONE_EXECUTABLE=t # requires sbcl 1.0.21.24 or later.
  EXEC_LISP=exec_lisp
  BIN_ARG=SBCL
  OPTIONS_ARG=SBCL_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} --disable-debugger"
  fi
}
implementation_scl () {
  implementation ${SCL:=scl} || return 1
  OPTIONS="${SCL_OPTIONS:- -quiet -noinit}"
  EVAL=-eval
  ENDARGS=--
  IMAGE_ARG=-core
  EXEC_LISP=exec_lisp
  BIN_ARG=SCL
  OPTIONS_ARG=SCL_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    OPTIONS="${OPTIONS} -batch"
  fi
}
implementation_xcl () {
  implementation "${XCL:-xcl}" || return 1
  OPTIONS="${XCL_OPTIONS:- --noinform --no-userinit}" # --no-siteinit
  EVAL=--eval
  ENDARGS="--"
  IMAGE_ARG=NOT_SUPPORTED_YET
  EXEC_LISP=exec_lisp
  BIN_ARG=XCL
  OPTIONS_ARG=XCL_OPTIONS
  if [ -z "$CL_LAUNCH_DEBUG" ] ; then
    : # Not supported yet
  fi
}
prepare_arg_form () {
  ENDARGS= F=
  for arg ; do
    F="$F\"$(kwote "$arg")\""
  done
  MAYBE_PACKAGE_FORM=" $PACKAGE_FORM"
  LAUNCH_FORMS="(setf uiop/image::*command-line-arguments*'($F))${LAUNCH_FORMS}"
}
# Aliases
implementation_alisp () {
  implementation_allegro "$@"
}
implementation_mlisp () {
  implementation_allegromodern "$@"
}
implementation_gclcvs () {
  implementation "${GCLCVS:=gclcvs}" || return 1
  GCL="$GCLCVS"
  implementation_gcl "$@" && BIN_ARG=GCLCVS
}
implementation_lisp () {
  implementation ${CMULISP:=lisp} || return 1
  CMUCL=$CMULISP
  implementation_cmucl "$@"
}
implementation_openmcl () {
  implementation "${OPENMCL:=openmcl}" || return 1
  CCL="$OPENMCL"
  CCL_OPTIONS="$OPENMCL_OPTIONS"
  implementation_ccl "$@" && BIN_ARG=OPENMCL
}

exec_lisp_noarg () {
  prepare_arg_form "$@"
  exec_lisp
}
exec_lisp_file () {
  prepare_arg_form "$@"
  LOADFILE=${TMPDIR:-/tmp}/cl-load-file-$(date +%s)-$$
  cat > $LOADFILE <<END
${MAYBE_PACKAGE_FORM}
${HASH_BANG_FORM}
${LAUNCH_FORMS}
END
  $LISP_BIN $IMAGE_OPT $IMAGE $OPTIONS $LOAD "$LOADFILE"
  RET=$?
  rm -f $LOADFILE
  exit $RET
}
implementation_clisp_noarg () {
  implementation_clisp
  EXEC_LISP=exec_lisp_noarg
  # For testing purposes
}
implementation_clisp_file () {
  implementation_clisp
  EXEC_LISP=exec_lisp_file
  # For testing purposes
}
implementation () {
  if [ -n "$USE_CLBUILD" ] ; then
    if CLBUILD_BIN="`which clbuild 2> /dev/null`" ; then
      LISP_BIN="$CLBUILD_BIN --implementation $IMPL lisp"
      return 0
    else
      return 1
    fi
  elif [ -x "$1" ] ; then
    LISP_BIN="$1"
    return 0
  elif LISP_BIN="`which "$1" 2> /dev/null`" ; then
    return 0
  else
    return 1
  fi
}
trylisp () {
  IMPL="$1" ; shift
  implementation_${IMPL} "$@"
}
do_exec_lisp () {
  if [ -n "$IMAGE" ] ; then
    if [ "x$IMAGE_ARG" = xEXECUTABLE_IMAGE ] ; then
      LISP_BIN= IMAGE_OPT=
    else
      IMAGE_OPT="$IMAGE_ARG"
    fi
  fi
  $EXEC_LISP "$@"
}
no_implementation_found () {
  ABORT "$PROG: Cannot find a supported lisp implementation.
Tried the following: $*"
}
ensure_implementation () {
  trylisp "$1" || no_implementation_found "$1"
}
try_all_lisps () {
  for l in $LISP $LISPS ; do
    if trylisp $l ; then
      $DO_LISP "$@"
      return 0
    fi
  done
  no_implementation_found "$LISP $LISPS"
}
exec_lisp () {
  # SBCL wants only one form per --eval so we need put everything in one progn.
  # However we also want any in-package form to be evaluated before any of the
  # remaining forms is read, so we get it to be evaluated at read-time as the
  # first thing in the main progn.
  # GNU clisp allows multiple forms per -x but prints the result of every form
  # evaluated and so we also need put everything in a single progn, and that progn
  # must quit before it may return to the clisp frame that would print its value.
  # CMUCL allows multiple forms per -eval and won't print values, so is ok anyway.
  # I don't know about other Lisps, but they will all work this way.
  LAUNCH_FORM="${PROGN}${MAYBE_PACKAGE_FORM}${HASH_BANG_FORM}${LAUNCH_FORMS}${NGORP}"
  ### This is partial support for CLBUILD.
  if [ -n "$USE_CLBUILD" ] ; then
    if [ -z "$IMAGE_OPT" ] ; then
      OPTIONS=
    else
      ABORT "Cannot use clbuild with a non-executable image different from clbuild's"
    fi
  fi
  if [ -n "$CL_LAUNCH_VERBOSE" ] ; then set -x ; fi
  exec $LISP_BIN $IMAGE_OPT $IMAGE $OPTIONS $EVAL "$LAUNCH_FORM" $ENDARGS "$@"
}
launch_self () {
  LAUNCH_FORMS="$(load_form "$PROG")"
  try_all_lisps "$@"
}
invoke_image () {
  if [ "x$IMAGE_ARG" = xEXECUTABLE_IMAGE ] ; then
    LISP_BIN= IMAGE_OPT=
  else
    IMAGE_OPT="$IMAGE_ARG"
  fi
  PACKAGE_FORM=
  HASH_BANG_FORM=
  LAUNCH_FORMS="(uiop:restore-image)"
  "$EXEC_LISP" "$@"
}

export CL_LAUNCH_PID=$$
export CL_LAUNCH_FILE="$PROG"

## execute configuration-provided code
eval "$WRAPPER_CODE"

### END OF CL-LAUNCH SHELL WRAPPER
