Let’s examine this program step-by-step now.
First, we put ourselves in the Common Lisp user package, and load Clon
’s
main ASDF system, called ‘net.didierverna.clon’. Next, we use the
Clon
package, also named ‘net.didierverna.clon’.
(in-package :cl-user) ;; This is the ASDF way, but use Quicklisp's ql:quickload if you prefer. (require "asdf") (asdf:load-system :net.didierverna.clon) (use-package :net.didierverna.clon) |
In fact, using the Clon
package directly is done here for simplicity,
but is not recommended. In case you find the package name too long to
prefix every symbol with, Clon
provides a utility function that
allows you to add (and use) a shorter nickname instead (the
demonstration programs in the distribution show how to use it):
Add NICKNAME (:clon
by default) to the
:NET.DIDIERVERNA.CLON
package.
The next thing you want to do is to create a set of options, groups or
texts that your application will recognize and/or display in its help
string. The structure of your command-line is known to Clon
as the
synopsis. In order to create it, use the macro defsynopsis
.
(defsynopsis (:postfix "FILES...") (text :contents "A very short program.") (group (:header "Immediate exit options:") (flag :short-name "h" :long-name "help" :description "Print this help and exit.") (flag :short-name "v" :long-name "version" :description "Print version number and exit."))) |
Note that the synopsis has a double role: it not only serves to define the options recognized by your application, but also the order in which every element appears in the help string. In that particular example, we define a line of text and a group with a header and two flags.
Now, we are going to define a function main
for our standalone
application. The first thing that we need to do is create a
context. A context is an object that Clon
uses to store various
things, including some state related to the parsing of the command-line.
You create a context with the function make-context
.
(defun main () "Entry point for our standalone application." (make-context) |
At that point, Clon
is ready to retrieve the options you want from
the command-line. Let’s first see if the user has called the option
-h, and give him the help string. Option retrieval is done with
the function getopt
, and automatic help string output with the
function help
. Note that what we do here is not process
the command-line in sequence, but look directly for a specific option by
name (this retrieval method is said to be explicit).
(when (getopt :short-name "h") (help) (uiop:quit)) |
UIOP’s quit
function is a portable wrapper around an
implementation-dependent way of saying goodbye. It takes an exit status
code as optional argument.
And now, we are going to retrieve the other options and simply print
them. This time however, we process the command-line sequentially (so this
retrieval method is said to be sequential). This is done with the
do-cmdline-options
macro. We also close the main
function.
(do-cmdline-options (option name value source) (print (list option name value source))) (terpri) (uiop:quit)) |
Finally, time to save the Lisp image.
(dump "quickstart" main) |
The first argument to dump
is the name of the executable to
produce, and the second argument is the name of the function to call
automatically at startup. In fact, dump
also accepts a
&rest
argument that just be passed on to the underlying
(implementation-specific) dumping facility.
In order to get a standalone executable from this program, all you need
to do now is to type ‘sbcl --script quickstart.lisp’. Note that the
actual way of dumping executables is compiler-dependent. For more
information on the proper way to do it and on the compilers currently
supported, see Dumping Executables. Note also that it is possible
to use Clon
without actually dumping a standalone executable
(see Delivering Scripts) at all.