From 20db73fc9412b7d9bd92f93239d7f34a261d5402 Mon Sep 17 00:00:00 2001 From: David Lichteblau Date: Tue, 9 Aug 2011 16:45:13 +0200 Subject: [PATCH] New toplevel options --quit and --non-interactive Implements lp#822712. --- NEWS | 2 ++ doc/sbcl.1 | 11 +++++++++++ src/code/toplevel.lisp | 18 +++++++++++++++++- src/runtime/runtime.c | 2 ++ tests/toplevel.test.sh | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 428fca9..82484cb 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ changes relative to sbcl-1.0.50: and probe counts on Linux. * enhancement: building 32-bit SBCL on Linux/x86-64 now works without a chroot. (Use "SBCL_ARCH=x86 sh make.sh" to build.) + * enhancement: added new toplevel options --quit and --non-interactive + (lp#822712). * optimization: unsigned integer divisions by a constant are implemented using multiplication (affects CEILING, FLOOR, TRUNCATE, MOD, and REM.) * optimization: improved type-derivation for LOAD-TIME-VALUE. diff --git a/doc/sbcl.1 b/doc/sbcl.1 index 7a186a4..a877657 100644 --- a/doc/sbcl.1 +++ b/doc/sbcl.1 @@ -179,6 +179,17 @@ This option disables the debugger, causing errors to print a backtrace and exit with status 1 instead -- which is a mode of operation better suited for batch processing. See the User Manual on \f(CRSB\-EXT:DISABLE\-DEBUGGER\fR for details. .TP 3 +.B \-\-quit +At the end of toplevel option processing, exit SBCL with a successful +code of zero. Note that the effect of this option is delayed until after +toplevel options following this one. +.TP 3 +.B \-\-non-interactive +This option disables the read-eval-print loop for both exceptional and +non-exceptional reasons. It is short for --disable-debugger and --quit in +combination and is useful for batch uses where the special option processing +implied by --script is not desired. +.TP 3 .B \-\-script Implies \-\-no-sysinit \-\-no-userinit \-\-disable-debugger \-\-end\-toplevel\-options. diff --git a/src/code/toplevel.lisp b/src/code/toplevel.lisp index 05445b9..7f71449 100644 --- a/src/code/toplevel.lisp +++ b/src/code/toplevel.lisp @@ -288,7 +288,9 @@ any non-negative real number." (:load (with-simple-restart (continue "Ignore runtime option --load ~S." value) - (load (native-pathname value)))))) + (load (native-pathname value)))) + (:quit + (quit)))) (flush-standard-output-streams))) (with-simple-restart (abort "Skip rest of --eval and --load options.") (dolist (option options) @@ -356,6 +358,8 @@ any non-negative real number." (noprint nil) ;; Has a --script option been seen? (script nil) + ;; Quit after processing other options? + (finally-quit nil) ;; everything in *POSIX-ARGV* except for argv[0]=programname (options (rest *posix-argv*))) @@ -412,6 +416,16 @@ any non-negative real number." ((string= option "--disable-debugger") (pop-option) (setf disable-debugger t)) + ((string= option "--quit") + (pop-option) + (setf finally-quit t)) + ((string= option "--non-interactive") + ;; This option is short for --quit and --disable-debugger, + ;; which are needed in combination for reliable non- + ;; interactive startup. + (pop-option) + (setf finally-quit t) + (setf disable-debugger t)) ((string= option "--end-toplevel-options") (pop-option) (return)) @@ -464,6 +478,8 @@ any non-negative real number." (process-init-file sysinit :system)) (unless no-userinit (process-init-file userinit :user)) + (when finally-quit + (push (list :quit) reversed-options)) (process-eval/load-options (nreverse reversed-options)) (when script (process-script script) diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 642e7c5..d1a215b 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -182,6 +182,8 @@ Common toplevel options:\n\ --disable-debugger Invoke sb-ext:disable-debugger.\n\ --noprint Run a Read-Eval Loop without printing results.\n\ --script [] Skip #! line, disable debugger, avoid verbosity.\n\ + --quit Exit with code 0 after option processing.\n\ + --non-interactive Sets both --quit and --disable-debugger.\n\ Common toplevel options that are processed in order:\n\ --eval
Form to eval when processing this option.\n\ --load File to load when processing this option.\n\ diff --git a/tests/toplevel.test.sh b/tests/toplevel.test.sh index 1103354..04f805e 100644 --- a/tests/toplevel.test.sh +++ b/tests/toplevel.test.sh @@ -28,4 +28,50 @@ if [ "`grep -c FOO::BAR $TEST_FILESTEM`" != 1 ] ; then exit $EXIT_LOSE fi +# --quit +run_sbcl --eval "(defpackage :foo)" --eval "(print 'foo::bar)" --quit \ + > $TEST_FILESTEM +if [ "`grep -c FOO::BAR $TEST_FILESTEM`" != 1 ] ; then + echo failed DEFPACKAGE-then-PRINT with --quit + exit $EXIT_LOSE +fi +# --quit gets delayed +run_sbcl --eval "(defpackage :foo)" --quit --eval "(print 'foo::bar)" \ + > $TEST_FILESTEM +if [ "`grep -c FOO::BAR $TEST_FILESTEM`" != 1 ] ; then + echo failed DEFPACKAGE-then-PRINT with delayed --quit + exit $EXIT_LOSE +fi + +# --non-interactive +run_sbcl --eval "(defpackage :foo)" \ + --non-interactive \ + --eval "(print 'foo::bar)" \ + > $TEST_FILESTEM +if [ "`grep -c FOO::BAR $TEST_FILESTEM`" != 1 ] ; then + echo failed DEFPACKAGE-then-PRINT with --non-interactive + exit $EXIT_LOSE +fi + +# disable the use of --disable-debugger through run_sbcl for the rest of +# this file +SBCL_ARGS="--noinform --no-sysinit --no-userinit --noprint" + +# --non-interactive with error +# +# (This test would hang if --non-interactive did not work properly.) +run_sbcl --eval "(defpackage :foo)" \ + --non-interactive \ + --eval "(print 'foo::bar)" \ + --eval '(error "fail-safe")' \ + >$TEST_FILESTEM 2>&1 +if [ "`grep -c FOO::BAR $TEST_FILESTEM`" != 1 ] ; then + echo failed DEFPACKAGE-then-PRINT with --non-interactive and error + exit $EXIT_LOSE +fi +if [ "`grep -c -i SIMPLE-ERROR $TEST_FILESTEM`" -lt 1 ] ; then + echo no error seen in --non-interactive test + exit $EXIT_LOSE +fi + exit $EXIT_TEST_WIN -- 1.7.10.4