48 lines
1.4 KiB
Common Lisp
48 lines
1.4 KiB
Common Lisp
;; -*- mode: lisp -*-
|
|
;;
|
|
;; Taken from Steve Losh, https://stevelosh.com/blog/2021/03/small-common-lisp-cli-programs/
|
|
;;
|
|
(eval-when (:compile-toplevel :load-toplevel :execute)
|
|
(ql:quickload '(:with-user-abort …) :silent t))
|
|
|
|
(defpackage :foo
|
|
(:use :cl)
|
|
(:export :toplevel *ui*))
|
|
|
|
(in-package :foo)
|
|
|
|
;;;; Configuration -----------------------------------------------
|
|
(defparameter *whatever* 123)
|
|
|
|
;;;; Errors ------------------------------------------------------
|
|
(define-condition user-error (error) ())
|
|
|
|
(define-condition missing-foo (user-error) ()
|
|
(:report "A foo is required, but none was supplied."))
|
|
|
|
;;;; Functionality -----------------------------------------------
|
|
(defun foo (string)
|
|
…)
|
|
|
|
;;;; Run ---------------------------------------------------------
|
|
(defun run (arguments)
|
|
(map nil #'foo arguments))
|
|
|
|
;;;; User Interface ----------------------------------------------
|
|
(defmacro exit-on-ctrl-c (&body body)
|
|
`(handler-case (with-user-abort:with-user-abort (progn ,@body))
|
|
(with-user-abort:user-abort () (sb-ext:exit :code 130))))
|
|
|
|
(defparameter *ui*
|
|
(adopt:make-interface
|
|
:name "foo"
|
|
…))
|
|
|
|
(defun toplevel ()
|
|
(sb-ext:disable-debugger)
|
|
(exit-on-ctrl-c
|
|
(multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
|
|
… ; Handle options.
|
|
(handler-case (run arguments)
|
|
(user-error (e) (adopt:print-error-and-exit e))))))
|