Next: guile-tools PROGRAM, Previous: Executable Modules, Up: Miscellaneous Tools
The previous section described the basic requirements for writing an
executable module. This section presents the convenience function
HVQC-MAIN exported from the (scripts PROGRAM) module,
part of the Guile distribution.
The letters HVQC stand for Help, Version, Query-options and
Callback, respectively; these are the standard services provided by
HVQC-MAIN. The first two services do not involve callback
procedures, while the last two do.
These services are typically not useful when the executable module is
used from a Scheme program (as opposed to being invoked from the
shell), so the common construction is to use it in the entry point,
and arrange for (scripts PROGRAM) to load only if needed via
an #:autoload stanza in the define-module form. For
example:
(define-module (my modules my-prog)
#:autoload (scripts PROGRAM) (HVQC-MAIN)
...)
Parse and handle args, a list of strings, for
--help,--version, getopt-style command-line options processing and eventual application of callback, a procedure with one of two signatures (see below), all based on config, a list of zero or more key-value pairs for configuring the behavior ofHVQC-MAIN. Recognized keys are:package,version,usageandoption-spec.Specifically,
HVQC-MAINdoes these actions:
- Check
(cadr args)for--help. If found, display the help text to the current output port and exit successfully.The help text is by default
"Usage: ~A [ARGS]"(followed by newline), where~Ais the basename of the program. You can specify more appropriate help text with a(usage . WHERE)element in the config list. WHERE can be:
- the symbol
commentary, which means to display the commentary- a string to use directly
- a thunk which returns a string
For the
(usage . commentary)case, leading semicolons are removed from each line in the commentary automatically.- If
--helpis not found, check(cadr args)for--version. If found, display the version text to the current output port and exit successfully.The version text is by default
NAME VERSION(followed by newline), whereNAMEis the basename of the program, andVERSIONis the result of calling theversionprocedure.You can specify an optional version string and an optional package affiliation string, using
versionandpackageconfiguration elements, respectively. When a package is specified, it appears in parentheses between theNAMEandVERSION, like so:NAME (PACKAGE) VERSION.- If
--versionis not found, check config for anoption-speckey. If found, pass the associated option-spec along with the args to thegetopt-longprocedure as provided by module(ice-9 getopt-long). Use the result alist returned fromgetopt-longto make a qop (query-options procedure) and finally, pass this to the callback.The
qoptakes a key (a query of the parsed options) and an optional handler. If there is no associated parsed value for that key,qopreturns#f. If a handler is specified, it is passed the associated (non-#f) value, and its return value is returned byqop. Otherwise,qopsimply returns the associated (non-#f) value.- If there is no
option-specin config, construct an argument list from args where the first argument has been passed throughbasenameand the rest are unmodified. The invocation filename is available through an object property of the first arg namedinvocation-filename. Pass this arg list to callback.For example, this callback:
(define (callback args) (simple-format #t "args: ~S~%" args) (simple-format #t "invocation-filename: ~S~%" (object-property (car args) 'invocation-filename)) #t)for invocation
/path/to/my-prog 1 2 3displays:args: ("my-prog" "1" "2" "3") invocation-filename: "/path/to/my-prog"The rationale for passing this modified program argument list to callback instead of the unaltered original is that the program's basename is usually more appropriate for error messages and such, and so should be more easily accessible.
There are many examples of HVQC-MAIN usage in the Guile
distribution: all the (scripts FOO) modules use it in varying
ways. The easiest way is to browse the code:
$ guile-tools # to see a list of programs
$ guile-tools PROGRAM --help # to see PROGRAM's help
$ guile-tools PROGRAM --version # to see PROGRAM's version
$ guile-tools --source PROGRAM # to see PROGRAM's source
Happy toolsmithing!