diff options
| author | wickerwaka <martin.donlon@gmail.com> | 2014-08-14 21:44:55 -0700 |
|---|---|---|
| committer | wickerwaka <martin.donlon@gmail.com> | 2014-08-15 06:34:24 -0700 |
| commit | 08d7fc76cf6b2fac291cecd7185af818940092e4 (patch) | |
| tree | 49a057339ce16e4469332142e9f85564eea9eedc | |
| parent | 1d12b6d444ec083466020777be5bb9f19e9a6d3a (diff) | |
| download | rust-08d7fc76cf6b2fac291cecd7185af818940092e4.tar.gz rust-08d7fc76cf6b2fac291cecd7185af818940092e4.zip | |
Change how libgetopts handles options grouped together
As soon as an option is found that takes an argument, consume the rest of the string and store it into i_arg. Previously this would only happen if the character after the option was not a recognized option. Addresses issue #16348
| -rw-r--r-- | src/libgetopts/lib.rs | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 6339dc58446..d0c06f8e6ba 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -567,7 +567,6 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { } } else { let mut j = 1; - let mut last_valid_opt_id = None; names = Vec::new(); while j < curlen { let range = cur.as_slice().char_range_at(j); @@ -580,27 +579,24 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { interpreted correctly */ - match find_opt(opts.as_slice(), opt.clone()) { - Some(id) => last_valid_opt_id = Some(id), - None => { - let arg_follows = - last_valid_opt_id.is_some() && - match opts[last_valid_opt_id.unwrap()] - .hasarg { - - Yes | Maybe => true, - No => false - }; - if arg_follows && j < curlen { - i_arg = Some(cur.as_slice() - .slice(j, curlen).to_string()); - break; - } else { - last_valid_opt_id = None; - } - } - } + let opt_id = match find_opt(opts.as_slice(), opt.clone()) { + Some(id) => id, + None => return Err(UnrecognizedOption(opt.to_string())) + }; + names.push(opt); + + let arg_follows = match opts[opt_id].hasarg { + Yes | Maybe => true, + No => false + }; + + if arg_follows && range.next < curlen { + i_arg = Some(cur.as_slice() + .slice(range.next, curlen).to_string()); + break; + } + j = range.next; } } @@ -613,7 +609,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { }; match opts[optid].hasarg { No => { - if !i_arg.is_none() { + if name_pos == names.len() && !i_arg.is_none() { return Err(UnexpectedArgument(nm.to_string())); } vals.get_mut(optid).push(Given); @@ -1438,6 +1434,21 @@ mod tests { } #[test] + fn test_nospace_conflict() { + let args = vec!("-vvLverbose".to_string(), "-v".to_string() ); + let opts = vec!(optmulti("L", "", "library directory", "LIB"), + optflagmulti("v", "verbose", "Verbose")); + let matches = &match getopts(args.as_slice(), opts.as_slice()) { + result::Ok(m) => m, + result::Err(e) => fail!( "{}", e ) + }; + assert!(matches.opts_present(["L".to_string()])); + assert_eq!(matches.opts_str(["L".to_string()]).unwrap(), "verbose".to_string()); + assert!(matches.opts_present(["v".to_string()])); + assert_eq!(3, matches.opt_count("v")); + } + + #[test] fn test_long_to_short() { let mut short = Opt { name: Long("banana".to_string()), |
