- (concatenate
- 'string
- user-home
- "/.sbclrc"))))
- (/show0 "assigned SYSINIT-TRUENAME and USERINIT-TRUENAME")
- (when sysinit-truename
- (unless (load sysinit-truename)
- (error "~S was not successfully loaded." sysinit-truename))
- (flush-standard-output-streams))
- (/show0 "loaded SYSINIT-TRUENAME")
- (when userinit-truename
- (unless (load userinit-truename)
- (error "~S was not successfully loaded." userinit-truename))
- (flush-standard-output-streams))
- (/show0 "loaded USERINIT-TRUENAME"))
-
- ;; Handle --eval options.
- (/show0 "handling --eval options in TOPLEVEL-INIT")
- (dolist (eval (reverse evals))
- (/show0 "handling one --eval option in TOPLEVEL-INIT")
- (eval eval)
- (flush-standard-output-streams))
+ (concatenate 'string
+ user-home
+ "/.sbclrc"))))
+
+ ;; We wrap all the pre-REPL user/system customized startup code
+ ;; in a restart.
+ ;;
+ ;; (Why not wrap everything, even the stuff above, in this
+ ;; restart? Errors above here are basically command line or
+ ;; Unix environment errors, e.g. a missing file or a typo on
+ ;; the Unix command line, and you don't need to get into Lisp
+ ;; to debug them, you should just start over and do it right
+ ;; at the Unix level. Errors below here are generally errors
+ ;; in user Lisp code, and it might be helpful to let the user
+ ;; reach the REPL in order to help figure out what's going
+ ;; on.)
+ (restart-case
+ (progn
+ (flet ((process-init-file (truename)
+ (when truename
+ (unless (load truename)
+ (error "~S was not successfully loaded." truename))
+ (flush-standard-output-streams))))
+ (process-init-file sysinit-truename)
+ (process-init-file userinit-truename))
+
+ ;; Process --eval options.
+ (/show0 "handling --eval options in TOPLEVEL-INIT")
+ (dolist (expr-as-string (reverse reversed-evals))
+ (/show0 "handling one --eval option in TOPLEVEL-INIT")
+ (let ((expr (with-input-from-string (eval-stream
+ expr-as-string)
+ (let* ((eof-marker (cons :eof :eof))
+ (result (read eval-stream nil eof-marker))
+ (eof (read eval-stream nil eof-marker)))
+ (cond ((eq result eof-marker)
+ (error "unable to parse ~S"
+ expr-as-string))
+ ((not (eq eof eof-marker))
+ (error "more than one expression in ~S"
+ expr-as-string))
+ (t
+ result))))))
+ (eval expr)
+ (flush-standard-output-streams))))
+ (continue ()
+ :report
+ "Continue anyway (skipping to toplevel read/eval/print loop)."
+ (/show0 "CONTINUEing from pre-REPL RESTART-CASE")
+ (values)) ; (no-op, just fall through)
+ (quit ()
+ :report "Quit SBCL (calling #'QUIT, killing the process)."
+ (/show0 "falling through to QUIT from pre-REPL RESTART-CASE")
+ (quit))))
+
+ ;; one more time for good measure, in case we fell out of the
+ ;; RESTART-CASE above before one of the flushes in the ordinary
+ ;; flow of control had a chance to operate
+ (flush-standard-output-streams)