srfi.37
- args-fold: a program argument processor ¶This module implements args-fold
,
yet another procedure to process command-line
arguments, defined in SRFI-37.
Unlike gauche.parseopt
(see gauche.parseopt
- Parsing command-line options),
args-fold
provides functional interface, i.e.
the user’s states are explicitly passed via parser’s argument and
return values, and also follows POSIX and GNU getopt guidelines,
including long options.
[SRFI-37]{srfi.37
}
Processes program options args from left to right,
according to given option specification options,
and two procedures unrecognized-proc and operand-proc.
Options is a list of option objects, explained below. Each option object keeps the name(s) of the option, a flag to specify whether the option takes an argument or not, and a procedure to process that option (we’ll call it option procedure).
Args-fold
recognizes both single-character options (short options)
and long options. A short option must begin with single hyphen
(e.g. -a
), while long option must begin with double hyphens
(e.g. --help
). Short options can be
concatenated, e.g. -abc
or -a -b -c
.
Both a short option and a long option can take
required or optional arguments. Required short-option argument
can appear with or without space after the option, e.g.
-afoo
or -a foo
.
Long-option argument can appear after character ’=
’ or
space, e.g. --long=foo
or --long foo
.
When args-fold
encounters a command-line argument that cannot
be an option argument, and doesn’t begin with hyphen, the argument is
treated as an operand. Args-fold
allows operands and
options to be interleaved. However, if args-fold
encounters
’--
’, the rest of arguments are treated as operands,
regardless of beginning with hyphen or not.
When the given option matches one of option object in options, the option procedure is called as follows:
(option-proc option name arg seed ...)
where option is the matched option object, name is
the string actually used to specify the option, arg is
the option argument (or #f
if there’s none), and
seed … is the user’s state information.
Option-proc must return as many arguments as seeds.
When args-fold
encounters an option that doesn’t match
any of the option objects, it creates a new option object
for the option and calls unrecognized-proc
with the same arguments as option-proc.
When args-fold
finds an operand, operand-proc
is called as follows:
(operand-proc operand seed ...)
Operand-proc must return as many arguments as seeds.
The caller’s state should be explicitly passed around seed arguments
and return values. The initial seed values are seeds given
to args-fold
. The values returned from option procedure,
unrecognized-proc and operand-proc are used as the seed
arguments of next invocation of those procedures. The values
returned from the last call to the procedures are returned
from args-fold
.
[SRFI-37]{srfi.37
}
Creates an option object with the passed properties.
Names is a list of characters and/or strings. A character is used for a short option, and a string is used for a long option.
Two flags, require-arg? and optional-arg? indicates whether the option should take an option argument, or may take an option argument.
Processor is the option processor procedure.
Note that, if an option argument is passed using ’=
’
character, it is passed to the option procedure even if
the option has #f
in both require-arg?
and optional-arg?. It is up to the option procedure
to deal with the argument.
It should also be noted that the optional option argument
for a short option is only recognized if it is given
without whitespace after the short option. That is, if
a short option ’d
’ is marked to take optional option argument,
then ’-dfoo
’ is interpreted as ’-d
’ with argument ’foo
’,
but ’-d foo
’ is interpreted as ’-d
’ without argument
and an operand foo
. If ’d
’ is marked to
take required option argument, however, both are interpreted
as ’-d
’ with argument ’foo
’.
[SRFI-37]{srfi.37
}
Returns #t
if obj is an option object,
#f
otherwise.
[SRFI-37]{srfi.37
}
Returns the properties of an option object option.
A simple example:
(use srfi.37) (define options (list (option '(#\d "debug") #f #t (lambda (option name arg debug batch paths files) (values (or arg "2") batch paths files))) (option '(#\b "batch") #f #f (lambda (option name arg debug batch paths files) (values debug #t paths files))) (option '(#\I "include") #t #f (lambda (option name arg debug batch paths files) (values debug batch (cons arg paths) files))))) (define (main args) (receive (debug-level batch-mode include-paths files) (args-fold (cdr args) options (lambda (option name arg . seeds) ; unrecognized (error "Unrecognized option:" name)) (lambda (operand debug batch paths files) ; operand (values debug batch paths (cons operand files))) 0 ; default value of debug level #f ; default value of batch mode '() ; initial value of include paths '() ; initial value of files ) (print "debug level = " debug-level) (print "batch mode = " batch-mode) (print "include paths = " (reverse include-paths)) (print "files = " (reverse files)) 0))