unix-options

https://github.com/astine/unix-options.git

git clone 'https://github.com/astine/unix-options.git'

(ql:quickload :unix-options)
24

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 =| &parameters - symbol =| &free - symbol =| free - symbol =| map-parsed-options - function =| getopt - function =| with-cli-options - macro

An example of usage:

(with-cli-options () (print &parameters 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
         &parameters, 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 &parameters 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.