Turn OptGroups into a main opt and a main and an aliased opts
This way opt_present("apple") will match no matter if the user passed -a or --apple
This commit is contained in:
parent
8a91ab9a61
commit
0aa51544ce
1 changed files with 68 additions and 31 deletions
|
|
@ -114,7 +114,8 @@ pub enum Occur {
|
||||||
pub struct Opt {
|
pub struct Opt {
|
||||||
name: Name,
|
name: Name,
|
||||||
hasarg: HasArg,
|
hasarg: HasArg,
|
||||||
occur: Occur
|
occur: Occur,
|
||||||
|
aliases: ~[Opt],
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mkname(nm: &str) -> Name {
|
fn mkname(nm: &str) -> Name {
|
||||||
|
|
@ -127,29 +128,29 @@ fn mkname(nm: &str) -> Name {
|
||||||
|
|
||||||
/// Create an option that is required and takes an argument
|
/// Create an option that is required and takes an argument
|
||||||
pub fn reqopt(name: &str) -> Opt {
|
pub fn reqopt(name: &str) -> Opt {
|
||||||
return Opt {name: mkname(name), hasarg: Yes, occur: Req};
|
return Opt {name: mkname(name), hasarg: Yes, occur: Req, aliases: ~[]};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an option that is optional and takes an argument
|
/// Create an option that is optional and takes an argument
|
||||||
pub fn optopt(name: &str) -> Opt {
|
pub fn optopt(name: &str) -> Opt {
|
||||||
return Opt {name: mkname(name), hasarg: Yes, occur: Optional};
|
return Opt {name: mkname(name), hasarg: Yes, occur: Optional, aliases: ~[]};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an option that is optional and does not take an argument
|
/// Create an option that is optional and does not take an argument
|
||||||
pub fn optflag(name: &str) -> Opt {
|
pub fn optflag(name: &str) -> Opt {
|
||||||
return Opt {name: mkname(name), hasarg: No, occur: Optional};
|
return Opt {name: mkname(name), hasarg: No, occur: Optional, aliases: ~[]};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create an option that is optional, does not take an argument,
|
/** Create an option that is optional, does not take an argument,
|
||||||
* and may occur multiple times.
|
* and may occur multiple times.
|
||||||
*/
|
*/
|
||||||
pub fn optflagmulti(name: &str) -> Opt {
|
pub fn optflagmulti(name: &str) -> Opt {
|
||||||
return Opt {name: mkname(name), hasarg: No, occur: Multi};
|
return Opt {name: mkname(name), hasarg: No, occur: Multi, aliases: ~[]};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an option that is optional and takes an optional argument
|
/// Create an option that is optional and takes an optional argument
|
||||||
pub fn optflagopt(name: &str) -> Opt {
|
pub fn optflagopt(name: &str) -> Opt {
|
||||||
return Opt {name: mkname(name), hasarg: Maybe, occur: Optional};
|
return Opt {name: mkname(name), hasarg: Maybe, occur: Optional, aliases: ~[]};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -157,7 +158,7 @@ pub fn optflagopt(name: &str) -> Opt {
|
||||||
* multiple times
|
* multiple times
|
||||||
*/
|
*/
|
||||||
pub fn optmulti(name: &str) -> Opt {
|
pub fn optmulti(name: &str) -> Opt {
|
||||||
return Opt {name: mkname(name), hasarg: Yes, occur: Multi};
|
return Opt {name: mkname(name), hasarg: Yes, occur: Multi, aliases: ~[]};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
|
|
@ -189,7 +190,20 @@ fn name_str(nm: &Name) -> ~str {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
|
fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
|
||||||
opts.iter().position(|opt| opt.name == nm)
|
// search main options
|
||||||
|
let pos = opts.iter().position(|opt| opt.name == nm);
|
||||||
|
if pos.is_some() {
|
||||||
|
return pos
|
||||||
|
}
|
||||||
|
|
||||||
|
// search in aliases
|
||||||
|
for candidate in opts.iter() {
|
||||||
|
if candidate.aliases.iter().position(|opt| opt.name == nm).is_some() {
|
||||||
|
return opts.iter().position(|opt| opt.name == candidate.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -488,8 +502,6 @@ pub mod groups {
|
||||||
use getopts::{HasArg, Long, Maybe, Multi, No, Occur, Opt, Optional, Req};
|
use getopts::{HasArg, Long, Maybe, Multi, No, Occur, Opt, Optional, Req};
|
||||||
use getopts::{Short, Yes};
|
use getopts::{Short, Yes};
|
||||||
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
/** one group of options, e.g., both -h and --help, along with
|
/** one group of options, e.g., both -h and --help, along with
|
||||||
* their shared description and properties
|
* their shared description and properties
|
||||||
*/
|
*/
|
||||||
|
|
@ -587,7 +599,7 @@ pub mod groups {
|
||||||
|
|
||||||
// translate OptGroup into Opt
|
// translate OptGroup into Opt
|
||||||
// (both short and long names correspond to different Opts)
|
// (both short and long names correspond to different Opts)
|
||||||
pub fn long_to_short(lopt: &OptGroup) -> ~[Opt] {
|
pub fn long_to_short(lopt: &OptGroup) -> Opt {
|
||||||
let OptGroup{short_name: short_name,
|
let OptGroup{short_name: short_name,
|
||||||
long_name: long_name,
|
long_name: long_name,
|
||||||
hasarg: hasarg,
|
hasarg: hasarg,
|
||||||
|
|
@ -595,24 +607,29 @@ pub mod groups {
|
||||||
_} = (*lopt).clone();
|
_} = (*lopt).clone();
|
||||||
|
|
||||||
match (short_name.len(), long_name.len()) {
|
match (short_name.len(), long_name.len()) {
|
||||||
(0,0) => fail!("this long-format option was given no name"),
|
(0,0) => fail!("this long-format option was given no name"),
|
||||||
|
|
||||||
(0,_) => ~[Opt {name: Long((long_name)),
|
(0,_) => Opt {name: Long((long_name)),
|
||||||
hasarg: hasarg,
|
hasarg: hasarg,
|
||||||
occur: occur}],
|
occur: occur,
|
||||||
|
aliases: ~[]},
|
||||||
|
|
||||||
(1,0) => ~[Opt {name: Short(short_name.char_at(0)),
|
(1,0) => Opt {name: Short(short_name.char_at(0)),
|
||||||
hasarg: hasarg,
|
hasarg: hasarg,
|
||||||
occur: occur}],
|
occur: occur,
|
||||||
|
aliases: ~[]},
|
||||||
|
|
||||||
(1,_) => ~[Opt {name: Short(short_name.char_at(0)),
|
(1,_) => Opt {name: Long((long_name)),
|
||||||
hasarg: hasarg,
|
hasarg: hasarg,
|
||||||
occur: occur},
|
occur: occur,
|
||||||
Opt {name: Long((long_name)),
|
aliases: ~[Opt {
|
||||||
hasarg: hasarg,
|
name: Short(short_name.char_at(0)),
|
||||||
occur: occur}],
|
hasarg: hasarg,
|
||||||
|
occur: occur,
|
||||||
|
aliases: ~[]
|
||||||
|
}]},
|
||||||
|
|
||||||
(_,_) => fail!("something is wrong with the long-form opt")
|
(_,_) => fail!("something is wrong with the long-form opt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -620,7 +637,7 @@ pub mod groups {
|
||||||
* Parse command line args with the provided long format options
|
* Parse command line args with the provided long format options
|
||||||
*/
|
*/
|
||||||
pub fn getopts(args: &[~str], opts: &[OptGroup]) -> ::getopts::Result {
|
pub fn getopts(args: &[~str], opts: &[OptGroup]) -> ::getopts::Result {
|
||||||
::getopts::getopts(args, vec::flat_map(opts, long_to_short))
|
::getopts::getopts(args, opts.map(long_to_short))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1454,7 +1471,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_groups_long_to_short() {
|
fn test_groups_long_to_short() {
|
||||||
let short = ~[reqopt("b"), reqopt("banana")];
|
let mut short = reqopt("banana");
|
||||||
|
short.aliases = ~[reqopt("b")];
|
||||||
let verbose = groups::reqopt("b", "banana", "some bananas", "VAL");
|
let verbose = groups::reqopt("b", "banana", "some bananas", "VAL");
|
||||||
|
|
||||||
assert_eq!(groups::long_to_short(&verbose), short);
|
assert_eq!(groups::long_to_short(&verbose), short);
|
||||||
|
|
@ -1462,10 +1480,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_groups_getopts() {
|
fn test_groups_getopts() {
|
||||||
|
let mut banana = reqopt("banana");
|
||||||
|
banana.aliases = ~[reqopt("b")];
|
||||||
|
let mut apple = optopt("apple");
|
||||||
|
apple.aliases = ~[optopt("a")];
|
||||||
|
let mut kiwi = optflag("kiwi");
|
||||||
|
kiwi.aliases = ~[optflag("k")];
|
||||||
let short = ~[
|
let short = ~[
|
||||||
reqopt("b"), reqopt("banana"),
|
banana,
|
||||||
optopt("a"), optopt("apple"),
|
apple,
|
||||||
optflag("k"), optflagopt("kiwi"),
|
kiwi,
|
||||||
optflagopt("p"),
|
optflagopt("p"),
|
||||||
optmulti("l")
|
optmulti("l")
|
||||||
];
|
];
|
||||||
|
|
@ -1478,7 +1502,7 @@ mod tests {
|
||||||
groups::optmulti("l", "", "Desc", "VAL"),
|
groups::optmulti("l", "", "Desc", "VAL"),
|
||||||
];
|
];
|
||||||
|
|
||||||
let sample_args = ~[~"-k", ~"15", ~"--apple", ~"1", ~"k",
|
let sample_args = ~[~"--kiwi", ~"15", ~"--apple", ~"1", ~"k",
|
||||||
~"-p", ~"16", ~"l", ~"35"];
|
~"-p", ~"16", ~"l", ~"35"];
|
||||||
|
|
||||||
// FIXME #4681: sort options here?
|
// FIXME #4681: sort options here?
|
||||||
|
|
@ -1486,6 +1510,19 @@ mod tests {
|
||||||
== groups::getopts(sample_args, verbose));
|
== groups::getopts(sample_args, verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_groups_aliases_long_and_short() {
|
||||||
|
let opts = ~[
|
||||||
|
groups::optflagmulti("a", "apple", "Desc"),
|
||||||
|
];
|
||||||
|
|
||||||
|
let args = ~[~"-a", ~"--apple", ~"-a"];
|
||||||
|
|
||||||
|
let matches = groups::getopts(args, opts).unwrap();
|
||||||
|
assert_eq!(3, opt_count(&matches, "a"));
|
||||||
|
assert_eq!(3, opt_count(&matches, "apple"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_groups_usage() {
|
fn test_groups_usage() {
|
||||||
let optgroups = ~[
|
let optgroups = ~[
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue