flag: allow to define flags with abbreviation
* flag: allow to check the count of the free args to produce an error * flag: allow to define flags with abbreviation flags could be defined to use a single char as abbreviation like '--output' or '-o' '--help' or '-h'pull/1511/head
parent
1270e8a9f2
commit
c924a6cf00
|
@ -49,6 +49,7 @@ module flag
|
||||||
struct Flag {
|
struct Flag {
|
||||||
pub:
|
pub:
|
||||||
name string // name as it appears on command line
|
name string // name as it appears on command line
|
||||||
|
abbr byte // shortcut
|
||||||
usage string // help message
|
usage string // help message
|
||||||
val_desc string // something like '<arg>' that appears in usage
|
val_desc string // something like '<arg>' that appears in usage
|
||||||
}
|
}
|
||||||
|
@ -94,10 +95,11 @@ pub fn (fs mut FlagParser) skip_executable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// private helper to register a flag
|
// private helper to register a flag
|
||||||
fn (fs mut FlagParser) add_flag(n, u, vd string) {
|
fn (fs mut FlagParser) add_flag(n string, a byte, u, vd string) {
|
||||||
fs.flags << Flag{
|
fs.flags << Flag{
|
||||||
name: n,
|
name: n,
|
||||||
usage: u
|
abbr: a,
|
||||||
|
usage: u,
|
||||||
val_desc: vd
|
val_desc: vd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,10 +113,10 @@ fn (fs mut FlagParser) add_flag(n, u, vd string) {
|
||||||
//
|
//
|
||||||
// - the name, usage are registered
|
// - the name, usage are registered
|
||||||
// - found arguments and corresponding values are removed from args list
|
// - found arguments and corresponding values are removed from args list
|
||||||
fn (fs mut FlagParser) parse_value(n string) ?string {
|
fn (fs mut FlagParser) parse_value(n string, ab byte) ?string {
|
||||||
c := '--$n'
|
c := '--$n'
|
||||||
for i, a in fs.args {
|
for i, a in fs.args {
|
||||||
if a == c {
|
if a == c || (a.len == 2 && a[1] == ab) {
|
||||||
if fs.args.len > i+1 && fs.args[i+1].left(2) != '--' {
|
if fs.args.len > i+1 && fs.args[i+1].left(2) != '--' {
|
||||||
val := fs.args[i+1]
|
val := fs.args[i+1]
|
||||||
fs.args.delete(i+1)
|
fs.args.delete(i+1)
|
||||||
|
@ -138,10 +140,10 @@ fn (fs mut FlagParser) parse_value(n string) ?string {
|
||||||
// special: it is allowed to define bool flags without value
|
// special: it is allowed to define bool flags without value
|
||||||
// -> '--flag' is parsed as true
|
// -> '--flag' is parsed as true
|
||||||
// -> '--flag' is equal to '--flag=true'
|
// -> '--flag' is equal to '--flag=true'
|
||||||
fn (fs mut FlagParser) parse_bool_value(n string) ?string {
|
fn (fs mut FlagParser) parse_bool_value(n string, ab byte) ?string {
|
||||||
c := '--$n'
|
c := '--$n'
|
||||||
for i, a in fs.args {
|
for i, a in fs.args {
|
||||||
if a == c {
|
if a == c || (a.len == 2 && a[1] == ab) {
|
||||||
if fs.args.len > i+1 && (fs.args[i+1] in ['true', 'false']) {
|
if fs.args.len > i+1 && (fs.args[i+1] in ['true', 'false']) {
|
||||||
val := fs.args[i+1]
|
val := fs.args[i+1]
|
||||||
fs.args.delete(i+1)
|
fs.args.delete(i+1)
|
||||||
|
@ -166,15 +168,41 @@ fn (fs mut FlagParser) parse_bool_value(n string) ?string {
|
||||||
// the value is returned (true/false)
|
// the value is returned (true/false)
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
|
// version with abbreviation
|
||||||
//TODO error handling for invalid string to bool conversion
|
//TODO error handling for invalid string to bool conversion
|
||||||
pub fn (fs mut FlagParser) bool(n string, v bool, u string) bool {
|
pub fn (fs mut FlagParser) bool_(n string, a byte, v bool, u string) bool {
|
||||||
fs.add_flag(n, u, '')
|
fs.add_flag(n, a, u, '')
|
||||||
parsed := fs.parse_bool_value(n) or {
|
parsed := fs.parse_bool_value(n, a) or {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return parsed == 'true'
|
return parsed == 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// defining and parsing a bool flag
|
||||||
|
// if defined
|
||||||
|
// the value is returned (true/false)
|
||||||
|
// else
|
||||||
|
// the default value is returned
|
||||||
|
//TODO error handling for invalid string to bool conversion
|
||||||
|
pub fn (fs mut FlagParser) bool(n string, v bool, u string) bool {
|
||||||
|
return fs.bool_(n, `\0`, v, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// defining and parsing an int flag
|
||||||
|
// if defined
|
||||||
|
// the value is returned (int)
|
||||||
|
// else
|
||||||
|
// the default value is returned
|
||||||
|
// version with abbreviation
|
||||||
|
//TODO error handling for invalid string to int conversion
|
||||||
|
pub fn (fs mut FlagParser) int_(n string, a byte, i int, u string) int {
|
||||||
|
fs.add_flag(n, a, u, '<int>')
|
||||||
|
parsed := fs.parse_value(n, a) or {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
return parsed.int()
|
||||||
|
}
|
||||||
|
|
||||||
// defining and parsing an int flag
|
// defining and parsing an int flag
|
||||||
// if defined
|
// if defined
|
||||||
// the value is returned (int)
|
// the value is returned (int)
|
||||||
|
@ -182,11 +210,22 @@ pub fn (fs mut FlagParser) bool(n string, v bool, u string) bool {
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
//TODO error handling for invalid string to int conversion
|
//TODO error handling for invalid string to int conversion
|
||||||
pub fn (fs mut FlagParser) int(n string, i int, u string) int {
|
pub fn (fs mut FlagParser) int(n string, i int, u string) int {
|
||||||
fs.add_flag(n, u, '<int>')
|
return fs.int_(n, `\0`, i, u)
|
||||||
parsed := fs.parse_value(n) or {
|
|
||||||
return i
|
|
||||||
}
|
}
|
||||||
return parsed.int()
|
|
||||||
|
// defining and parsing a flaot flag
|
||||||
|
// if defined
|
||||||
|
// the value is returned (float)
|
||||||
|
// else
|
||||||
|
// the default value is returned
|
||||||
|
// version with abbreviation
|
||||||
|
//TODO error handling for invalid string to float conversion
|
||||||
|
pub fn (fs mut FlagParser) float_(n string, a byte, f f32, u string) f32 {
|
||||||
|
fs.add_flag(n, a, u, '<float>')
|
||||||
|
parsed := fs.parse_value(n, a) or {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
return parsed.f32()
|
||||||
}
|
}
|
||||||
|
|
||||||
// defining and parsing a flaot flag
|
// defining and parsing a flaot flag
|
||||||
|
@ -196,11 +235,21 @@ pub fn (fs mut FlagParser) int(n string, i int, u string) int {
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
//TODO error handling for invalid string to float conversion
|
//TODO error handling for invalid string to float conversion
|
||||||
pub fn (fs mut FlagParser) float(n string, f f32, u string) f32 {
|
pub fn (fs mut FlagParser) float(n string, f f32, u string) f32 {
|
||||||
fs.add_flag(n, u, '<float>')
|
return fs.float_(n, `\0`, f, u)
|
||||||
parsed := fs.parse_value(n) or {
|
|
||||||
return f
|
|
||||||
}
|
}
|
||||||
return parsed.f32()
|
|
||||||
|
// defining and parsing a string flag
|
||||||
|
// if defined
|
||||||
|
// the value is returned (string)
|
||||||
|
// else
|
||||||
|
// the default value is returned
|
||||||
|
// version with abbreviation
|
||||||
|
pub fn (fs mut FlagParser) string_(n string, a byte, v, u string) string {
|
||||||
|
fs.add_flag(n, a, u, '<arg>')
|
||||||
|
parsed := fs.parse_value(n, a) or {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return parsed
|
||||||
}
|
}
|
||||||
|
|
||||||
// defining and parsing a string flag
|
// defining and parsing a string flag
|
||||||
|
@ -209,14 +258,9 @@ pub fn (fs mut FlagParser) float(n string, f f32, u string) f32 {
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
pub fn (fs mut FlagParser) string(n, v, u string) string {
|
pub fn (fs mut FlagParser) string(n, v, u string) string {
|
||||||
fs.add_flag(n, u, '<arg>')
|
return fs.string_(n, `\0`, v, u)
|
||||||
parsed := fs.parse_value(n) or {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return parsed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add an additional check for free arguments
|
|
||||||
// this will cause an error in finalize() if free args are out of range
|
// this will cause an error in finalize() if free args are out of range
|
||||||
// (min, ..., max)
|
// (min, ..., max)
|
||||||
pub fn (fs mut FlagParser) limit_free_args(min, max int) {
|
pub fn (fs mut FlagParser) limit_free_args(min, max int) {
|
||||||
|
@ -247,7 +291,8 @@ pub fn (fs FlagParser) usage() string {
|
||||||
} else {
|
} else {
|
||||||
SPACE.right(flag_desc.len)
|
SPACE.right(flag_desc.len)
|
||||||
}
|
}
|
||||||
use += '$flag_desc$space$f.usage\n'
|
abbr_desc := if f.abbr == `\0` { '' } else { ' -${tos(f.abbr, 1)}\n' }
|
||||||
|
use += '$abbr_desc$flag_desc$space$f.usage\n'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,3 +231,17 @@ fn test_could_expect_no_free_args() {
|
||||||
}
|
}
|
||||||
assert args.len < 0 // expect an error and need to use args
|
assert args.len < 0 // expect an error and need to use args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_allow_abreviations() {
|
||||||
|
mut fp := flag.new_flag_parser(['-v', '-o', 'some_file', '-i', '42', '-f', '2.0'])
|
||||||
|
|
||||||
|
v := fp.bool_('version', `v`, false, '')
|
||||||
|
o := fp.string_('output', `o`, 'empty', '')
|
||||||
|
i := fp.int_('count', `i`, 0, '')
|
||||||
|
f := fp.float_('value', `f`, 0.0, '')
|
||||||
|
|
||||||
|
assert v && o == 'some_file' && i == 42 && f == 2.0
|
||||||
|
|
||||||
|
u := fp.usage()
|
||||||
|
assert u.contains(' -v') && u.contains(' -o') && u.contains(' -i') && u.contains(' -f')
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue