6.1. kink/ARGV_PARSER¶
Parses command line arguments, org argv, into option switches, option arguments, and non-option elements. Parsing is done in the style of glibc getopt_long.
Example
# filename: voxxx.kn
:ARGV_PARSER.require_from('kink/')
:PROCESS.require_from('kink/')
:parse_argv <- {(:Argv)
:Depot = new_val('Loglevel' 'ERROR')
:Non_opts = ARGV_PARSER.parse(Argv){(:P)
P.no_arg(['-h' '--help']){
stdout.print_line('USAGE: kink voxxx.kn [Options...] [--] [Args...]')
PROCESS.exit(0)
}
P.req_arg(['-L' '--loglevel']){(:Arg)
Depot:Loglevel <- Arg
}
P.on_error{(:Msg)
stderr.print_line('voxxx: {}'.format(Msg))
PROCESS.exit(64)
}
}
[Depot.Loglevel Non_opts]
}
:main <- {(:Argv)
[:Loglevel :Non_opts] = parse_argv(Argv)
stdout.print_line('loglevel={} non-option-elements={}'.format(Loglevel Non_opts.repr))
}
# $ kink voxxx.kn --log INFO foo bar
# loglevel=INFO non-option-elements=["foo" "bar"]
#
# $ kink voxxx.kn --LDEBUG foo bar
# loglevel=DEBUG non-option-elements=["foo" "bar"]
#
# $ kink voxxx.kn foo bar
# loglevel=ERROR non-option-elements=["foo" "bar"]
#
# $ kink voxxx.kn --help
# USAGE: kink voxxx.kn [Options...] [--] [Args...]
Option switches
There are two types of option switches:
• short switch: consists of leading `-` and one other code point, excluding `--`. Ex. `-h`
• long switch: consists of leading `--` and one or more code points. The switch must not include `=`. Ex. `--help`
Each option switch can be grouped to three categories depending on how it takes an argument.
• req_arg: takes one option argument
• opt_arg: takes zero or one option argument
• no_arg: takes no option argument
An argv element consisting of two hyphens `--` is not an option switch, but can be used as a separator between options and non-option elements.
Short req_arg option switch
Assume a short req_arg switch `-p` is defined. This option switch can be used in the following ways.
• -pkink/ → option argument = `kink/`
• -p kink/ → option argument = `kink/`
Long req_arg option switch
Assuem a long req_arg switch `--prefix` is defined. This option switch can be used in the following ways.
• --prefix=kink/ → option argument = `kink/`
• --prefix kink/ → option argument = `kink/`
The option switch can be abbreviated like `--pat`, `--pa`, or `--p`, if it is not ambiguous. See the later section for details.
Short opt_arg option switch
Assume a short opt_arg switch `-b` is defined. This option switch can be used in the following ways.
• -b4096 → option argument = `4096`
• -b → option argument = an empty string ``
Long opt_arg option switch
Assume a long opt_arg switch `--buffer` is defined. This option switch can be used in the following ways.
• --buffer=4096 → option argument = `4096`
• --buffer → option argument = an empty string ``
Short no_arg option switch
Assume a short no_arg switch `-h` is defined. This option switch can be used in the following way.
• -h
When there is one or more code points after the option switch, the following code points are handled as separate options. For example, if no_arg option switches `-x` and `-z` are defined, and a req_arg switch `-f` is defined, argv `-xzf./archive.tgz` is parsed as follows:
• -x with no option argument
• -z with no option argument
• -f with option argument `./archive.tgz`
Long no_arg option switch
Assume a long no_arg switch `--help` is defined. This option switch can be used in the following way.
• --help
Abbreviation of long option switches
A long option switch can be abbreviated to its prefix when it is not ambiguous. For example, if long options switches `--verbose` and `--version` are defined, they can be abbreviated as follows:
• --verbose: --verbos, --verbo, --verb
• --version: --versio, --versi, --vers
The exact match always takes precedence over abbreviation. For example, if long option switches `--time` and `--time-style` are defined, argv `--time` is parsed as the option switch `--time`, rather than abbreviation of `--time-style`.
Non-option elements
Argv elements which are neither option switches, option arguments, nor separator `--` are non-option elements.
Two hyphens `--` can be used to separate between options and non-option elements. For example, if no_arg switches `-x`, `-y`, and `-z` are defined, argv `-x -y -- -z a b c` is parsed as follows:
• options: -x, -y
• non-option elements: -z, a, b, c
If strict_order mode is not specified, options can appear after non-option elements. For example, if no_arg switches `-x`, `-y`, and `-z` are defined, argv `-x a b c -y -z` is parsed as follows:
• options: -x, -y, -z
• non-option elements: a b c
If strict_order mode is turned on, all the elements after the first non-option element are parsed as non-option elements. This corresponds to the behavior of getopt_long when POSIXLY_CORRECT is set. For example, if no_arg switches `-x`, `-y`, and `-z` are defined, argv `-x a b c -y -z` is parsed as follows:
• option: -x
• non-option elements: a, b, c, -y, -z
Difference from getopt_long
1. getopt_long assumes argv[0] is the name of the program, while ARGV_PARSER handles the arguments after the program name.
2. getopt_long has a feature to handle `-W foo` as `--foo`, while ARGV_PARSER has no such feature.
6.1.1. ARGV_PARSER.parse(Argv ...[$config={}])¶
`parse` method parses `Argv` into options and non-option elements, as configured by $config.
If the parsing completes without an error, `parse` tail-calls the success continuation (see C.on_success) with a `vec` of `str` values of non-option elements.
If the parsing results in an error, `parse` tail-calls the error continuation (see C.on_error) with a `str` value of the error message.
Precondition
`Argv` must be a `vec` of `str` values.
$config must be a function which takes a `argv_parser_config`.
6.1.2. type argv_parser_config¶
`argv_parser_config` is a config value of ARGV_PARSER.parse.
6.1.2.1. C.req_arg(Switches $action)¶
`req_arg` method defines req_arg option switches in `Switches`.
When an option switch in `Switches` is parsed, $action is called with a `str` value of the corresponding option argument.
Preconditions
`Switches` must be a `vec` of `str` values which are long or short option switches.
`Switches` must not be empty.
Option switches must be unique within an invocation of ARGV_PARSER.parse.
$action must be a function which takes a `str`.
6.1.2.2. C.opt_arg(Switches $action)¶
`opt_arg` method defines opt_arg option switches in `Switches`.
When an option switch in `Switches` is parsed, $action is called with a `str` value of the corresponding option argument. If the option argument is omitted, an empty `str` is passed to $action.
Preconditions
`Switches` must be a `vec` of `str` values which are long or short option switches.
`Switches` must not be empty.
Option switches must be unique within an invocation of ARGV_PARSER.parse.
$action must be a function which takes a `str`.
6.1.2.3. C.no_arg(Switches $action)¶
`no_arg` method defines no_arg option switches in `Switches`.
When an option switch in `Switches` is parsed, $action is called with no arg.
Preconditions
`Switches` must be a `vec` of `str` values which are long or short option switches.
`Switches` must not be empty.
Option switches must be unique within an invocation of ARGV_PARSER.parse.
$action must be a thunk.
6.1.2.4. C.strict_order¶
`strict_order` method specifies that parsing is done in strict_order mode.
This corresponds to setting POSIXLY_CORRECT to getopt_long.
6.1.2.5. C.on_success($success)¶
`on_success` specifies that $success be used as the success continuation of ARGV_PARSER.parse.
If `on_success` is not called, VAL.identity is used as the default.
Precondition
$success must be a function which takes a `vec` of `str` values, which are non-option elements of argv.
6.1.2.6. C.on_error($error)¶
`on_error` specifies that $error be used as the error continuation of ARGV_PARSER.parse.
If `on_error` is not called, `raise` is used as the default.
Precondition
$error must be a function which takes a `str` value, which is an error message.