unix-options
2015-10-31
Easy to use command line option parser
unix-options (C) 2009-2010 Andrew Stine
This software is distributed under the terms of the Lisp Lesser GNU
Public License (http://opensource.franz.com/preamble.html), also
known as the LLGPL.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Unix-options is a small Common Lisp library for parsing unix-style
command line options.
This library is very new and not widely tested so suggestions,
bug-reports and patches (including changes to this document) are
welcome.
Please send any feedback to: unix dot options (at) librelist dot com
----------------------------------------------------------------------
Usage:
The library can be loaded through ASDF and used through the package
'unix-options.'
Exported symbols are:
=| cli-options - variable
=| ¶meters - symbol
=| &free - symbol
=| free - symbol
=| map-parsed-options - function
=| getopt - function
=| with-cli-options - macro
An example of usage:
(with-cli-options ()
(print ¶meters in-file out-file)
(when print
(with-open-file (in in-file :direction :input)
(with-open-file (out out-file :direction :output)
(while (peek-char in)
(write-char (read-char in) out))))))
$ sample-program -p -i input.txt -o output.txt
=> write input.txt to output.txt
---------------------------------------------------------------------
API:
getopt - An imitation of the Unix 'getopt' command line program
prototype: (getopt cli-options shortopts longopts)
details: Getopt accepts three arguments: a list of tokens passed
in on the CLI, a string detailing available short-form
options and a list detailing long-form options. Getopt
breaks the tokens up and sorts them so that they can be
handled by the calling program more easily.
Cli-options can be any list of strings. Each string
beginning with a single '-' is interpreted as a series of
short options and any beginning with '--' is interpreted
as a long option. Others are either free tokens or
parameters. Any tokens appearing after a token that is
soley a '--', are interpreted as free tokens.
Shortopts takes the form: "abf:" where each letter is the
name of a permissable short option and a ':' following a
letter signifies that it takes a parameter.
Longopts takes the form: '("option1" "file=") where each
string is the name of a long option and a '=' signifies
that the option takes a parameter.
Return three values which are all lists: (1) parsed command
line arguments with "--" separating valid options and free
arguments, (2) only the valid options and (3) only the free
arguments.
example: (getopt '("-ab" "--file" "file.txt" "free")
"ab"
'("file="))
=> ("a" "b" "file" "file.txt" "--" "free")
("a" "b" "file" "file.txt")
("free")
make-option-spec - A function which create an option-spec object
prototype: (make-option-spec tokens &optional parameter description)
details: Make-option-spec generates an option-spec object from the
the details provided. Tokens can either be a symbol, or a
list of characters, strings, and symbols. Parameter is either
nil, t, or a string. Description is always a string.
An option spec contains a list of short-tokens, as characters
and a list of long-tokens as strings. Short-tokens are drawn
from any characters passed under tokens and the first
letter of the name of any symbols passed. Long-tokens are
drawn from any strings passed likewise and from the complete
names of any symbols passed.
Parameter signifies whether an option takes a parameter. If
parameter is nil, then the option does not. Otherwise, the
option does. The parameter can be described briefly by passing
a string as parameter rather than simply t.
Description is a description of the option and it's purpose in
general.
Option-specs are used as parameters to several functions in
unix-options. Generally, anywhere an option-spec is required,
one may substitute a list of the parameters one would pass to
make-option-spec. Thus one might be able to type:
(function '(foo nil "foo option")) instead of:
(function (make-option-spec 'foo nil "foo option"))
example: (make-option-spec '(#\A foo) "integer" "A number to be passed in")
=> <option-spec {12f9sj39}>
with-cli-options - A macro that binds values passed in from the command
line to local variables
prototype: (with-cli-options (&optional (cli-options '(cli-options))
enable-usage-summary)
option-variables &body body)
details: With-cli-options takes a list of symbols and attempts to
bind values passed in on the command line to them according
to a set of rules. For every symbol named in
option-variables, with-cli-options creates a variable to
which it binds any long option of the same name.
With-cli-options also take the first letter of any symbol
and bind short options of that letter to that symbol. If
multiple symbols begin with the same letter, only the first
in option-variables is bound the short option of the same
letter; the second is bound to the uppercase version and any
more must use a long option.
Optionally, each entry in option-variables can be a short
list. The first item is symbol to be used. The second is
either a documentation string, or a full option-spec allowing
greater detail as to how that particular entry is to be
formed.
In addition, symbols in option-variables are boolean by
default; that is, they are bound to either t or nil depending on
whether they are passed in on the CLI. Symbols listed after
¶meters, if it is present, are considered parameter
options, that is, they are bound to the next token on the CLI
if they are long options or the same or the rest of the
current short option group, if they are short options. If
nothing is passed for this options (ie. if it is the last
token) it is bound to nil.
Any tokens that aren't options or parameters to options are
saved into a list of free tokens. This list is bound to 'free'
unless a different symbol is provided in option-variables
after &free.
If enable-usage-summary is set, then with-cli-options will be
able to print out a usage summary (using print-usage-summary)
based on the options bound in option-varibles. The summary
will be printed either when an invalid option is specified or
when the user uses '-h' or '--help' as an option. If
enable-usage-summary is set to a string, that string is passed
as control string to print-usage-summary. Else, a generic
string is used.
example: (with-cli-options ('("-pi" "in" "--out-file" "out" "another"))
(print ¶meters in-file out-file)
(print print)
(print in-file)
(print out-file)
(print free))
T
"in"
"out"
("another")
=> NIL
cli-options - returns the list of whitespace separated tokens passed
on the command line.
print-usage-summary - Prints a usage description of the current program
prototype: (print-usage-summary description option-specs)
details: Print-usage-summary prints a summary of options specified
by options-specs.
The function takes each option-spec and generates a string
describing each option in detail. The resulting strings are
passed as arguments to a call to format. Description is used
as the control string. The option-spec descriptions are auto-
aligned.
example: (print-usage-summary "Usage:~%~@{~A~%~}~%end summary"
'(((#\a "alpha") nil "A simple option")
((#\f "file") "FILENAME" "A filename")
((#\b #\d "beta") nil "Another option")))
Usage:
-a, --alpha A simple option
-f, --file=FILENAME A filename
-b, -d, --beta Another option
end summary
=>NIL
map-parsed-options - Function that does the actual parsing of CLI tokens
prototype: (map-parsed-options cli-options bool-options param-options
opt-val-func free-val-func)
details: Map-parsed-options is the backend function that does most
of the actual work in parsing CLI functions. It is exposed
to allow more front ends in addition to getopt and
with-cli-options. Map-parsed-options receives a list of CLI
tokens, as well as two list of options, boolean options and
options with parameters, respectively. The final two
arguments are functions, one to handle found options and
there values, and one to handle free tokens.
example: (map-parsed-options '("-ab" "value" "free") '("a") '("b")
(lambda (option value)
(format t "option: ~A; value: ~A~%"
option value))
(lambda (free-val)
(format t "free: ~A~%" free-val)))
option: a; value T
option: b; value value
free: free
=> NIL
With thanks to folks who've reported bugs and provided patches.