ggetopt
A module for the
V programming language
Version 0.4
Features:
- V-like getopt() shim
- V-like getopt_long() shim
- Auto
--help
output generation
Installation
$ v install edam.ggetopt
Usage
The API has been kept in the spirit of GNU getopt library.
Short Options (very basic)
At its most basic, you can use
getopt()
import edam.ggetopt
struct Options {
mut:
verbose bool
name string = 'user'
}
fn main() {
mut opts := &Options{}
ggetopt.getopt_cli('vu:?', fn [mut opts] (arg string, val ?string) ! {
match arg {
'v' { opts.verbose = true }
'u' { opts.name = val or { '' } }
'?' { println('Usage: myprog [-v] [-u NAME] [-?]') exit(0) }
else {}
}
}) or { exit(1) }
if opts.verbose {
println('debug: printing name')
}
println('Hi ${opts.name}!')
}
Note:
getopt_cli()
getopt()
os.args
Long Options (typical usage)
Defining long options is done in an array, just like
getopt_long()
Note that the array of options (
OptDef
- option factory function:
opt(long_name string, short_opt ?rune)
- extend option with an argument:
.arg(arg_name string, required bool)
- default
--help
option factory function: opt_help()
import edam.ggetopt
const (
options = [
ggetopt.opt('user', `u`).arg('NAME', true),
ggetopt.opt('insult', `i`).arg('ADJECTIVE', false),
ggetopt.opt('verbose', none),
ggetopt.opt_help(),
]
)
[heap]
struct Options {
mut:
name string = 'user'
insult ?string
verbose bool
}
fn (mut o Options) process_arg(arg string, val ?string) ! {
match arg {
'u', 'user' { o.name = val or { '' } }
'i', 'insult' { o.insult = val or { 'stinky' } }
'verbose' { o.verbose = true }
'help' { ggetopt.print_help(options) exit(0) }
else {}
}
}
fn main() {
mut opts := Options{}
rest := ggetopt.getopt_long_cli(options, opts.process_arg) or { exit(1) }
if opts.verbose {
println('debug: printing message')
}
greet := if insult := opts.insult { 'Hi ${insult}' } else { 'Hello' }
println('${greet} ${opts.name}!')
if rest.len > 10 {
ggetopt.die('too many arguments!')
} else if rest.len > 0 {
println(rest.join(' '))
}
}
You can use
die()
myprog: your message
os.args[0]
prog()
OptDefs and Automatic Help (getting fancy!)
To use
getopt_long()
getopt_long_cli()
OptDef
print_help()
- extend option with help text:
.help(text string)
- line of text (not an option) factory function:
text(text string)
- default
--help
option factory function: opt_help()
- default
--version
option factory function: opt_version()
All help/text output is line-wrapped.
const (
options = [
ggetopt.text('Usage: ${ggetopt.prog()} [OPTION]... [MESSAGE]...')
ggetopt.text('')
ggetopt.text('Options:')
ggetopt.opt('user', `u`).arg('NAME', true)
.help("provide the user's NAME")
ggetopt.opt('insult', `i`).arg('ADJECTIVE', false)
.help('insult the user (default: stinky)')
ggetopt.opt('verbose', none)
.help('show debug information')
ggetopt.opt_help()
]
)
Then,
print_help()
Usage: myprog [OPTION]... [MESSAGE]...
Options:
-u, --user=NAME provide the user's NAME
-i, --insult[=ADJECTIVE] insult the user (default: stinky)
--verbose show debug information
--help display this help and exit
Note, there's also a
print_version()
--version
Error handling
By default, GNU getopt writes errors to stderr (as well as returning them). This can be disabled, so that you can display any returned error yourself:
ggetopt.report_errors(false)
The errors that are returned by
getopt()
getopt_cli()
getopt_long()
getopt_long_cli()
Development
Testing the module
$ v test .
Debugging
To dump GNU getopt library state, after each call to
getopt_long()
ggetopt_debug
$ v -d ggetopt_debug ...
Changes
0.1 - Initial version
0.2 - Renamed opt() fns; tests; help-gen improvements (wrapping, config)
0.3 - Added print_version(); fixed tests
0.4 - Added die(), prog(); fixed text(''); gen_wraped_lines() handles newlines; errors from process_fn are eprintln()ed when report_errors(true)
Licence
Copyright (C) 2023 Tim Marston [email protected]