@@@ more wip
[runlisp] / runlisp.conf
index d2bad4e..78fc5b7 100644 (file)
 ;;; -*-conf-windows-*-
 
-;; Summary of syntax.
-;;
-;; Sections are started with a line `[NAME]', starting in the leftmost
-;; column.  Empty lines and lines starting with `;' -- /without/ preceding
-;; whitespace -- are ignored.  Assignments have the form `VAR = VALUE'; the
-;; VALUE may be continued across multiple lines, if they begin with
-;; whitespace.  All of the lines are stripped of initial and final whitespace
-;; and concatenated with spaces.
-;;
-;; Values may contain substitutions:
-;;
-;;   * ${[SECTION:]VAR[?ALT]} -- replace with the value of VAR in SECTION; if
-;;     not found, use ALT instead.  (If ALT isn't provided, it's an error.)
-;;
-;;   * $?[SECTION:]VAR{YES[|NO]} -- look up VAR in SECTION (or in the
-;;     (original) current section, and `@COMMON'); if found, use YES,
-;;     otherwise use NO.
-;;
-;; Variables are looked up starting in the home (or explicitly specified)
-;; section, then proceeding to the parents assigned to `@PARENTS'.
-;; (`@PARENTS' usually defaults to `@COMMON'; the parent of `@COMMON' is
-;; `@BUILTIN'; `@BUILTIN' and `@CONFIG' have no parents.)
-;;
-;; At top-level, the text is split into words at whitespace, unless prevented
-;; by double- and single-quote, or escaped by `\'.  Within single quotes, all
-;; characters are treated literally.  Within double quotes, `\' and `$' still
-;; works.  A variable reference within quotes, or within a word, suppresses
-;; word-splitting and quoting, within the variable value -- but `$'
-;; expansions still work.
-
-;;;--------------------------------------------------------------------------
-[@COMMON]
-
-;; Turn `#!' into a comment-to-end-of-line.  This is used in all Lisp
-;; invocations, even though some of them don't apparently need it.  For
-;; example, SBCL ignores an initial line beginning `#!' as a special feature
-;; of its `--script' option.  Other Lisps won't do this, so a countermeasure
-;; like the following is necessary in their case.  For the sake of a
-;; consistent environment, we ignore `#!' lines everywhere, even in Lisps
-;; which have their own, more specific, solution to this problem.
-ignore-shebang =
-       (set-dispatch-macro-character
-        #\\# #\\!
-        (lambda (#1=#:stream #2=#:char #3=#:arg)
-          (declare (ignore #2# #3#))
-          (values (read-line #1#))))
-
-;; Clear all present symbols from the `COMMON-LISP-USER' package.  Some Lisps
-;; leave débris in `COMMON-LISP-USER' -- for example, ECL leaves some
-;; allegedly useful symbols lying around, while ABCL has a straight-up bug in
-;; its `adjoin.lisp' file.
-clear-cl-user =
-       (let ((#4=#:pkg (find-package "COMMON-LISP-USER")))
-         (with-package-iterator (#5=#:next #4# :internal)
-           (loop (multiple-value-bind (#6=#:anyp #7=#:sym #8=#:how)
-                     (#5#)
-                   (declare (ignore #8#))
-                   (unless #6# (return))
-                   (unintern #7# #4#)))))
-
-;; Add `:runlisp-script' to `*features*' so that scripts can tell whether
-;; they're supposed to sit quietly and be debugged in a Lisp session or run
-;; as a script.
-set-script-feature =
-       (pushnew :runlisp-script *features*)
-
-;; Load the system's ASDF.
-require-asdf =
-       (require "asdf")
-
-;; Prevent ASDF from upgrading itself.  Otherwise it will do this
-;; automatically if a script invokes `asdf:load-system', but that will have a
-;; bad effect on startup time, and risks spamming the output streams with
-;; drivel.
-inhibit-asdf-upgrade =
-       (funcall (intern "REGISTER-IMMUTABLE-SYSTEM"
-                        (find-package "ASDF"))
-                "asdf")
-
-;; Upgrade ASDF from the source registry.
-upgrade-asdf =
-       (funcall (intern "UPGRADE-ASDF" (find-package "ASDF")))
-
-;; Common actions when resuming a custom image.
-image-restore =
-       (uiop:call-image-restore-hook)
-
-;; Common prelude for script startup in vanilla images.  Most of this is
-;; already done in custom images.
-run-script-prelude =
-       (progn
-         (setf *load-verbose* nil *compile-verbose* nil)
-         ${require-asdf}
-         ${inhibit-asdf-upgrade}
-         ${ignore-shebang}
-         ${set-script-feature})
-
-;; Common prelude for dumping images.
-dump-image-prelude =
-       (progn
-         ${require-asdf}
-         ${upgrade-asdf}
-         ${inhibit-asdf-upgrade}
-         ${ignore-shebang}
-         ${set-script-feature})
-
-image-path = ${@CONFIG:image-dir}/${image-file}
-
 ;;;--------------------------------------------------------------------------
-[sbcl]
-
-command = ${@ENV:SBCL?sbcl}
-image-file = sbcl+asdf.core
-
-run-script =
-       ${command} --noinform
-               $?@IMAGE{--core "${image-path}" --eval "${image-restore}" |
-                        --eval "${run-script-prelude}"}
-               --script ${@SCRIPT}
+;;; Top-level configuration.
 
-dump-image =
-       ${command} --noinform --no-userinit --no-sysinit --disable-debugger
-               --eval "${dump-image-prelude}"
-               --eval "(sb-ext:save-lisp-and-die \"${@IMAGE|q}\")"
+;; Lisp implementations for which custom images should be dumped by
+;; `dump-runlisp-image -a'.  Defaults to all installed Lisp implementations.
+; dump = sbcl, cmucl, ccl, clisp
 
+;; Lisp implementations to use by preference.  Defaults to the order read
+;; from the configuration file.  Overridden by `$RUNLISP_PREFER' in
+;; environment.
+; prefer = sbcl, ccl, clisp, ecl, cmucl, sbcl
 
-;;;--------------------------------------------------------------------------
-[ccl]
-
-command = ${@ENV:CCL?ccl}
-image-file = ccl+asdf.image
+;; Directory to look for or dump custom images.  Defaults to hardcoded
+;; directory; overridden by `$RUNLISP_IMAGEDIR' in environment.
+; image-dir = /path/to/things
 
-run-script =
-       ${command} -b -n -Q
-               $?@IMAGE{-I "${image-path}" -e "${image-restore}" |
-                        -e "${run-script-prelude}"}
-               -l ${@SCRIPT} -e "(ccl:quit)" --
+;; Directory to look for additional scripts.  Defaults to hardcoded
+;; directory; overridden by `$RUNLISP_DATADIR' in environment.
+; data-dir = /path/to/things
 
-;; A snaglet occurs here.  CCL wants to use the image name as a clue to where
-;; the rest of its installation is; but in fact the image is nowhere near its
-;; installation.  So we must hack...
-dump-image =
-       ${command} -b -n -Q
-               -e "${dump-image-prelude}"
-               -e "(ccl::in-development-mode
-                     (let ((#1=#:real-ccl-dir (ccl::ccl-directory)))
-                       (defun ccl::ccl-directory ()
-                         (let* ((#2=#:dirpath
-                                  (ccl:getenv \"CCL_DEFAULT_DIRECTORY\")))
-                           (if (and #2# (plusp (length (namestring #2#))))
-                               (ccl::native-to-directory-pathname #2#)
-                               #1#))))
-                     (compile 'ccl::ccl-directory))"
-               -e "(ccl:save-application \"${@IMAGE|q}\"
-                                         :init-file nil
-                                         :error-handler :quit)"
+;; Script to support eval-mode operation.  Defaults to
+;; `${data-dir}/eval.lisp'; opverridden by `$RUNLISP_EVAL' in environment.
+; eval-script = /path/to/script
 
 ;;;--------------------------------------------------------------------------
-[clisp]
-
-;; CLisp causes much sadness.  Superficially, it's the most sensible of all
-;; of the systems supported here: you just run `clisp SCRIPT -- ARGS ...' and
-;; it works.
-;;
-;; The problems come when you want to do some preparatory work (e.g., load
-;; `asdf') and then run the script.  There's a `-x' option to evaluate some
-;; Lisp code, but it has three major deficiencies.
-;;
-;;   * It insists on printing the values of the forms it evaluates.  It
-;;     prints a blank line even if the form goes out of its way to produce no
-;;     values at all.  So the whole thing has to be a single top-level form
-;;     which quits the Lisp rather than returning.
-;;
-;;   * For some idiotic reason, you can have /either/ `-x' forms /or/ a
-;;     script, but not both.  So we have to include the `load' here
-;;     explicitly.  I suppose that was inevitable because we have to inhibit
-;;     printing of the result forms, but it's still a separate source of
-;;     annoyance.
-;;
-;;   * The icing on the cake: the `-x' forms are collectively concatenated --
-;;     without spaces! -- and used to build a string stream, which is then
-;;     assigned over the top of `*standard-input*', making the original stdin
-;;     somewhat fiddly to track down.
-;;
-;; There's a `-i' option which will load a file without any of this
-;; stupidity, but nothing analogous for immediate expressions.
-
-clisp-common-startup =
-       (setf *standard-input* (ext:make-stream :input))
-       (load "${@SCRIPT|q}" :verbose nil :print nil)
-       (ext:quit)
-
-command = ${@ENV:CLISP?clisp}
-image-file = clisp+asdf.mem
-
-run-script =
-       ${command}
-               $?@IMAGE{-M "${image-path}" -q
-                        -x "(progn
-                              ${image-restore}
-                              ${clisp-common-startup})" |
-                        -norc -q
-                        -x "(progn
-                              ${run-script-prelude}
-                              ${clisp-common-startup})"}
-               --
-
-dump-image =
-       ${command} -norc -q -q
-               -x "${dump-image-prelude}"
-               -x "(ext:saveinitmem \"${@IMAGE|q}\" :norc t :script t)"
-
-;;;--------------------------------------------------------------------------
-[ecl]
-
-command = ${@ENV:ECL?ecl}
-image-file = ecl+asdf
-
-run-script =
-       $?@IMAGE{"${image-path}" -s ${@SCRIPT} |
-                ${@ENV:ECL?ecl} "${@ECLOPT}norc"
-                        "${@ECLOPT}eval" "(progn
-                                           ${run-script-prelude}
-                                           ${clear-cl-user})"
-                        "${@ECLOPT}shell" ${@SCRIPT}}
-               --
-
-dump-image =
-       "${@CONFIG:data-dir}/dump-ecl"
-               "${@IMAGE}" "${command}" "${@ECLOPT}" "${@TMPDIR}"
-
-;;;--------------------------------------------------------------------------
-[cmucl]
-
-command = ${@ENV:CMUCL?cmucl}
-image-file = cmucl+asdf.core
-
-run-script =
-       ${command}
-               $?@IMAGE{-core "${image-path}" -eval "${image-restore}" |
-                        -batch -noinit -nositeinit -quiet
-                                -eval "(progn
-                                         (setf ext:*require-verbose* nil)
-                                         ${run-script-prelude})"}
-               -load ${@SCRIPT} -eval "(ext:quit)" --
-
-dump-image =
-       ${command} -batch -noinit -nositeinit -quiet
-               -eval "${dump-image-prelude}"
-               -eval "(ext:save-lisp \"${@IMAGE|q}\"
-                                     :batch-mode t :print-herald nil
-                                     :site-init nil :load-init-file nil)"
-
-;;;--------------------------------------------------------------------------
-[abcl]
-
-;; CLisp made a worthy effort, but ABCL still manages to take the prize.
-;;
-;;   * ABCL manages to avoid touching the `stderr' stream at all, ever.  Its
-;;     startup machinery finds `stdout' (as `java.lang.System.out'), wraps it
-;;     up in a Lisp stream, and uses the result as `*standard-output*' and
-;;     `*error-output*' (and a goodly number of other things too).  So we
-;;     must manufacture a working `stderr' the hard way.
-;;
-;;   * There doesn't appear to be any easy way to prevent toplevel errors
-;;     from invoking the interactive debugger.  For extra fun, the debugger
-;;     reads from `stdin' by default, so an input file which somehow manages
-;;     to break the script can then take over its brain by providing Lisp
-;;     forms for the debugger to evaluate.
-;;
-;;   * And, just to really top everything off, ABCL's `adjoin.lisp' is
-;;     missing an `(in-package ...)' form at the top, so it leaks symbols
-;;     into the `COMMON-LISP-USER' package.
-
-command = ${@ENV:ABCL?abcl}
-
-abcl-startup =
-       (let ((#9=#:script "${@SCRIPT|q}"))
-         ${run-script-prelude}
-         ${clear-cl-user}
-         (setf *error-output*
-                 (java:jnew "org.armedbear.lisp.Stream"
-                            \'sys::system-stream
-                            (java:jfield "java.lang.System" "err")
-                            \'character
-                            java:+true+))
-         (handler-case (load #9# :verbose nil :print nil)
-           (error (error)
-             (format *error-output* "~A (unhandled error): ~A~%" #9# error)
-           (ext:quit :status 255))))
-
-run-script =
-       ${command} --batch --noinform --noinit --nosystem
-               --eval "${abcl-startup}"
-               --
-
-;;;----- That's all, folks --------------------------------------------------