1851: Allow debug logs to work with clap tests themselves r=CreepySkeleton a=pksunkara



Co-authored-by: Pavan Kumar Sunkara <pavan.sss1991@gmail.com>
This commit is contained in:
bors[bot] 2020-04-22 20:01:24 +00:00 committed by GitHub
commit 0293fd7c4a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 381 additions and 436 deletions

View file

@ -24,12 +24,13 @@ Please use the following template to assist with creating an issue and to ensure
### Debug output ### Debug output
Compile clap with cargo features `"debug"` such as: Compile clap with `debug` feature:
```toml ```toml
[dependencies] [dependencies]
clap = { version = "2", features = ["debug"] } clap = { version = "*", features = ["debug"] }
``` ```
The output may be very long, so feel free to link to a gist or attach a text file The output may be very long, so feel free to link to a gist or attach a text file
<details> <details>

View file

@ -43,3 +43,25 @@ I think *this* should happen instead.
### Additional context ### Additional context
Add any other context about the problem here. Add any other context about the problem here.
### Debug output
Compile clap with `debug` feature:
```toml
[dependencies]
clap = { version = "*", features = ["debug"] }
```
The output may be very long, so feel free to link to a gist or attach a text file
<details>
<summary> Debug Output </summary>
<pre>
<code>
Paste Debug Output Here
</code>
</pre>
</details>

View file

@ -92,8 +92,8 @@ pub trait Generator {
/// Subcommand `rustup toolchain install` would be converted to /// Subcommand `rustup toolchain install` would be converted to
/// `("install", "rustup toolchain install")`. /// `("install", "rustup toolchain install")`.
fn subcommands(p: &App) -> Vec<(String, String)> { fn subcommands(p: &App) -> Vec<(String, String)> {
debugln!("subcommands: name={}", p.get_name()); debug!("subcommands: name={}", p.get_name());
debugln!("subcommands: Has subcommands...{:?}", p.has_subcommands()); debug!("subcommands: Has subcommands...{:?}", p.has_subcommands());
let mut subcmds = vec![]; let mut subcmds = vec![];
@ -104,7 +104,7 @@ pub trait Generator {
for sc in p.get_subcommands() { for sc in p.get_subcommands() {
let sc_bin_name = sc.get_bin_name().unwrap(); let sc_bin_name = sc.get_bin_name().unwrap();
debugln!( debug!(
"subcommands:iter: name={}, bin_name={}", "subcommands:iter: name={}, bin_name={}",
sc.get_name(), sc.get_name(),
sc_bin_name sc_bin_name
@ -119,7 +119,7 @@ pub trait Generator {
/// Gets all the short options and flags of a [`clap::App`](../clap/struct.App.html). /// Gets all the short options and flags of a [`clap::App`](../clap/struct.App.html).
/// Includes `h` and `V` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html). /// Includes `h` and `V` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html).
fn shorts<'b>(p: &'b App<'b>) -> Vec<char> { fn shorts<'b>(p: &'b App<'b>) -> Vec<char> {
debugln!("shorts: name={}", p.get_name()); debug!("shorts: name={}", p.get_name());
let mut shorts: Vec<char> = p let mut shorts: Vec<char> = p
.get_arguments() .get_arguments()
@ -147,7 +147,7 @@ pub trait Generator {
/// Gets all the long options and flags of a [`clap::App`](../clap/struct.App.html). /// Gets all the long options and flags of a [`clap::App`](../clap/struct.App.html).
/// Includes `help` and `version` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html). /// Includes `help` and `version` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html).
fn longs<'b>(p: &'b App<'b>) -> Vec<String> { fn longs<'b>(p: &'b App<'b>) -> Vec<String> {
debugln!("longs: name={}", p.get_name()); debug!("longs: name={}", p.get_name());
let mut longs: Vec<String> = p let mut longs: Vec<String> = p
.get_arguments() .get_arguments()
@ -177,7 +177,7 @@ pub trait Generator {
/// Gets all the flags of a [`clap::App`](../clap/struct.App.html). /// Gets all the flags of a [`clap::App`](../clap/struct.App.html).
/// Includes `help` and `version` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html). /// Includes `help` and `version` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html).
fn flags<'b>(p: &'b App<'b>) -> Vec<Arg> { fn flags<'b>(p: &'b App<'b>) -> Vec<Arg> {
debugln!("flags: name={}", p.get_name()); debug!("flags: name={}", p.get_name());
let mut flags: Vec<_> = flags!(p).cloned().collect(); let mut flags: Vec<_> = flags!(p).cloned().collect();

View file

@ -74,7 +74,7 @@ complete -F _{name} -o bashdefault -o default {name}
} }
fn all_subcommands(app: &App) -> String { fn all_subcommands(app: &App) -> String {
debugln!("Bash::all_subcommands;"); debug!("all_subcommands");
let mut subcmds = String::new(); let mut subcmds = String::new();
let mut scs = Bash::all_subcommands(app) let mut scs = Bash::all_subcommands(app)
@ -101,7 +101,7 @@ fn all_subcommands(app: &App) -> String {
} }
fn subcommand_details(app: &App) -> String { fn subcommand_details(app: &App) -> String {
debugln!("Bash::subcommand_details;"); debug!("subcommand_details");
let mut subcmd_dets = String::new(); let mut subcmd_dets = String::new();
let mut scs = Bash::all_subcommands(app) let mut scs = Bash::all_subcommands(app)
@ -141,7 +141,7 @@ fn subcommand_details(app: &App) -> String {
} }
fn option_details_for_path(app: &App, path: &str) -> String { fn option_details_for_path(app: &App, path: &str) -> String {
debugln!("Bash::option_details_for_path: path={}", path); debug!("option_details_for_path: path={}", path);
let p = Bash::find_subcommand_with_path(app, path.split("__").skip(1).collect()); let p = Bash::find_subcommand_with_path(app, path.split("__").skip(1).collect());
let mut opts = String::new(); let mut opts = String::new();
@ -178,7 +178,7 @@ fn option_details_for_path(app: &App, path: &str) -> String {
} }
fn vals_for(o: &Arg) -> String { fn vals_for(o: &Arg) -> String {
debugln!("Bash::vals_for: o={}", o.get_name()); debug!("vals_for: o={}", o.get_name());
if let Some(ref vals) = o.get_possible_values() { if let Some(ref vals) = o.get_possible_values() {
format!("$(compgen -W \"{}\" -- ${{cur}})", vals.join(" ")) format!("$(compgen -W \"{}\" -- ${{cur}})", vals.join(" "))
@ -188,7 +188,7 @@ fn vals_for(o: &Arg) -> String {
} }
fn all_options_for_path(app: &App, path: &str) -> String { fn all_options_for_path(app: &App, path: &str) -> String {
debugln!("Bash::all_options_for_path: path={}", path); debug!("all_options_for_path: path={}", path);
let p = Bash::find_subcommand_with_path(app, path.split("__").skip(1).collect()); let p = Bash::find_subcommand_with_path(app, path.split("__").skip(1).collect());
let scs: Vec<_> = Bash::subcommands(p).iter().map(|x| x.0.clone()).collect(); let scs: Vec<_> = Bash::subcommands(p).iter().map(|x| x.0.clone()).collect();

View file

@ -66,7 +66,7 @@ fn generate_inner<'b>(
previous_command_name: &str, previous_command_name: &str,
names: &mut Vec<&'b str>, names: &mut Vec<&'b str>,
) -> String { ) -> String {
debugln!("Elvish::generate_inner;"); debug!("generate_inner");
let command_name = if previous_command_name.is_empty() { let command_name = if previous_command_name.is_empty() {
p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string() p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string()

View file

@ -28,7 +28,7 @@ fn escape_string(string: &str) -> String {
} }
fn gen_fish_inner(root_command: &str, app: &App, buffer: &mut String) { fn gen_fish_inner(root_command: &str, app: &App, buffer: &mut String) {
debugln!("Fish::gen_fish_inner;"); debug!("gen_fish_inner");
// example : // example :
// //
// complete // complete
@ -52,7 +52,7 @@ fn gen_fish_inner(root_command: &str, app: &App, buffer: &mut String) {
basic_template.push_str(format!("\"__fish_seen_subcommand_from {}\"", bin_name).as_str()); basic_template.push_str(format!("\"__fish_seen_subcommand_from {}\"", bin_name).as_str());
} }
debugln!("Fish::gen_fish_inner; bin_name={}", bin_name); debug!("gen_fish_inner: bin_name={}", bin_name);
for option in opts!(app) { for option in opts!(app) {
let mut template = basic_template.clone(); let mut template = basic_template.clone();

View file

@ -73,7 +73,7 @@ fn generate_inner<'b>(
previous_command_name: &str, previous_command_name: &str,
names: &mut Vec<&'b str>, names: &mut Vec<&'b str>,
) -> String { ) -> String {
debugln!("PowerShell::generate_inner;"); debug!("generate_inner");
let command_name = if previous_command_name.is_empty() { let command_name = if previous_command_name.is_empty() {
p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string() p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string()

View file

@ -80,7 +80,7 @@ _{name} \"$@\"",
// _describe -t commands 'rustup commands' commands "$@" // _describe -t commands 'rustup commands' commands "$@"
// //
fn subcommand_details(p: &App) -> String { fn subcommand_details(p: &App) -> String {
debugln!("ZshGen::subcommand_details;"); debug!("subcommand_details");
let name = p.get_bin_name().unwrap(); let name = p.get_bin_name().unwrap();
@ -106,7 +106,7 @@ _{bin_name_underscore}_commands() {{
all_subcommands.dedup(); all_subcommands.dedup();
for &(_, ref bin_name) in &all_subcommands { for &(_, ref bin_name) in &all_subcommands {
debugln!("Zsh::subcommand_details:iter: bin_name={}", bin_name); debug!("subcommand_details:iter: bin_name={}", bin_name);
ret.push(format!( ret.push(format!(
"\ "\
@ -138,12 +138,12 @@ _{bin_name_underscore}_commands() {{
// 'show:Show the active and installed toolchains' // 'show:Show the active and installed toolchains'
// 'update:Update Rust toolchains' // 'update:Update Rust toolchains'
fn subcommands_of(p: &App) -> String { fn subcommands_of(p: &App) -> String {
debugln!("Zsh::subcommands_of;"); debug!("subcommands_of");
let mut ret = vec![]; let mut ret = vec![];
fn add_sc(sc: &App, n: &str, ret: &mut Vec<String>) { fn add_sc(sc: &App, n: &str, ret: &mut Vec<String>) {
debugln!("Zsh::add_sc;"); debug!("add_sc");
let s = format!( let s = format!(
"\"{name}:{help}\" \\", "\"{name}:{help}\" \\",
@ -162,7 +162,7 @@ fn subcommands_of(p: &App) -> String {
// The subcommands // The subcommands
for sc in p.get_subcommands() { for sc in p.get_subcommands() {
debugln!("Zsh::subcommands_of:iter: subcommand={}", sc.get_name()); debug!("subcommands_of:iter: subcommand={}", sc.get_name());
add_sc(sc, &sc.get_name(), &mut ret); add_sc(sc, &sc.get_name(), &mut ret);
@ -204,9 +204,8 @@ fn subcommands_of(p: &App) -> String {
// [repeat] = From the same recursive calls, but for all subcommands // [repeat] = From the same recursive calls, but for all subcommands
// [subcommand_args] = The same as zsh::get_args_of // [subcommand_args] = The same as zsh::get_args_of
fn get_subcommands_of(p: &App) -> String { fn get_subcommands_of(p: &App) -> String {
debugln!("Zsh::get_subcommands_of;"); debug!(
debugln!( "get_subcommands_of: Has subcommands...{:?}",
"Zsh::get_subcommands_of: Has subcommands...{:?}",
p.has_subcommands() p.has_subcommands()
); );
@ -254,7 +253,7 @@ esac",
} }
fn parser_of<'b>(p: &'b App<'b>, mut sc: &str) -> &'b App<'b> { fn parser_of<'b>(p: &'b App<'b>, mut sc: &str) -> &'b App<'b> {
debugln!("Zsh::parser_of: sc={}", sc); debug!("parser_of: sc={}", sc);
if sc == p.get_bin_name().unwrap_or(&String::new()) { if sc == p.get_bin_name().unwrap_or(&String::new()) {
return p; return p;
@ -285,7 +284,7 @@ fn parser_of<'b>(p: &'b App<'b>, mut sc: &str) -> &'b App<'b> {
// -s: Allow stacking of short args (i.e. -a -b -c => -abc) // -s: Allow stacking of short args (i.e. -a -b -c => -abc)
// -S: Do not complete anything after '--' and treat those as argument values // -S: Do not complete anything after '--' and treat those as argument values
fn get_args_of(p: &App) -> String { fn get_args_of(p: &App) -> String {
debugln!("Zsh::get_args_of;"); debug!("get_args_of");
let mut ret = vec![String::from("_arguments \"${_arguments_options[@]}\" \\")]; let mut ret = vec![String::from("_arguments \"${_arguments_options[@]}\" \\")];
let opts = write_opts_of(p); let opts = write_opts_of(p);
@ -351,12 +350,12 @@ fn escape_value(string: &str) -> String {
} }
fn write_opts_of(p: &App) -> String { fn write_opts_of(p: &App) -> String {
debugln!("Zsh::write_opts_of;"); debug!("write_opts_of");
let mut ret = vec![]; let mut ret = vec![];
for o in opts!(p) { for o in opts!(p) {
debugln!("Zsh::write_opts_of:iter: o={}", o.get_name()); debug!("write_opts_of:iter: o={}", o.get_name());
let help = o.get_help().map_or(String::new(), escape_help); let help = o.get_help().map_or(String::new(), escape_help);
let conflicts = arg_conflicts(p, o); let conflicts = arg_conflicts(p, o);
@ -394,7 +393,7 @@ fn write_opts_of(p: &App) -> String {
help = help help = help
); );
debugln!("write_opts_of:iter: Wrote...{}", &*s); debug!("write_opts_of:iter: Wrote...{}", &*s);
ret.push(s); ret.push(s);
} }
@ -408,7 +407,7 @@ fn write_opts_of(p: &App) -> String {
help = help help = help
); );
debugln!("write_opts_of:iter: Wrote...{}", &*l); debug!("write_opts_of:iter: Wrote...{}", &*l);
ret.push(l); ret.push(l);
} }
} }
@ -438,12 +437,12 @@ fn arg_conflicts(app: &App, arg: &Arg) -> String {
} }
fn write_flags_of(p: &App) -> String { fn write_flags_of(p: &App) -> String {
debugln!("Zsh::write_flags_of;"); debug!("write_flags_of;");
let mut ret = vec![]; let mut ret = vec![];
for f in Zsh::flags(p) { for f in Zsh::flags(p) {
debugln!("Zsh::write_flags_of:iter: f={}", f.get_name()); debug!("write_flags_of:iter: f={}", f.get_name());
let help = f.get_help().map_or(String::new(), escape_help); let help = f.get_help().map_or(String::new(), escape_help);
let conflicts = arg_conflicts(p, &f); let conflicts = arg_conflicts(p, &f);
@ -463,7 +462,7 @@ fn write_flags_of(p: &App) -> String {
help = help help = help
); );
debugln!("Zsh::write_flags_of:iter: Wrote...{}", &*s); debug!("write_flags_of:iter: Wrote...{}", &*s);
ret.push(s); ret.push(s);
} }
@ -477,7 +476,7 @@ fn write_flags_of(p: &App) -> String {
help = help help = help
); );
debugln!("Zsh::write_flags_of:iter: Wrote...{}", &*l); debug!("write_flags_of:iter: Wrote...{}", &*l);
ret.push(l); ret.push(l);
} }
@ -487,12 +486,12 @@ fn write_flags_of(p: &App) -> String {
} }
fn write_positionals_of(p: &App) -> String { fn write_positionals_of(p: &App) -> String {
debugln!("Zsh::write_positionals_of;"); debug!("write_positionals_of;");
let mut ret = vec![]; let mut ret = vec![];
for arg in positionals!(p) { for arg in positionals!(p) {
debugln!("Zsh::write_positionals_of:iter: arg={}", arg.get_name()); debug!("write_positionals_of:iter: arg={}", arg.get_name());
let optional = if !arg.is_set(ArgSettings::Required) { let optional = if !arg.is_set(ArgSettings::Required) {
":" ":"
@ -524,7 +523,7 @@ fn write_positionals_of(p: &App) -> String {
}) })
); );
debugln!("Zsh::write_positionals_of:iter: Wrote...{}", a); debug!("write_positionals_of:iter: Wrote...{}", a);
ret.push(a); ret.push(a);
} }

View file

@ -8,41 +8,14 @@ macro_rules! w {
} }
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
#[cfg_attr(feature = "debug", macro_use)] macro_rules! debug {
#[cfg_attr(feature = "debug", allow(unused_macros))] ($($arg:tt)*) => {
mod debug_macros { print!("[{:>w$}] \t", module_path!(), w = 28);
macro_rules! debugln { println!($($arg)*)
($fmt:expr) => (println!(concat!("DEBUG:clap_generate:", $fmt)));
($fmt:expr, $($arg:tt)*) => (println!(concat!("DEBUG:clap_generate:",$fmt), $($arg)*));
}
macro_rules! sdebugln {
($fmt:expr) => (println!($fmt));
($fmt:expr, $($arg:tt)*) => (println!($fmt, $($arg)*));
}
macro_rules! debug {
($fmt:expr) => (print!(concat!("DEBUG:clap_generate:", $fmt)));
($fmt:expr, $($arg:tt)*) => (print!(concat!("DEBUG:clap_generate:",$fmt), $($arg)*));
}
macro_rules! sdebug {
($fmt:expr) => (print!($fmt));
($fmt:expr, $($arg:tt)*) => (print!($fmt, $($arg)*));
} }
} }
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
#[cfg_attr(not(feature = "debug"), macro_use)] macro_rules! debug {
#[cfg_attr(not(feature = "debug"), allow(unused_macros))] ($($arg:tt)*) => {};
mod debug_macros {
macro_rules! debugln {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => {};
}
macro_rules! sdebugln {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => {};
}
macro_rules! debug {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => {};
}
} }

View file

@ -1479,7 +1479,7 @@ impl<'b> App<'b> {
// Internally used only // Internally used only
impl<'b> App<'b> { impl<'b> App<'b> {
fn _do_parse(&mut self, it: &mut Input) -> ClapResult<ArgMatches> { fn _do_parse(&mut self, it: &mut Input) -> ClapResult<ArgMatches> {
debugln!("App::_do_parse;"); debug!("App::_do_parse");
let mut matcher = ArgMatcher::default(); let mut matcher = ArgMatcher::default();
// If there are global arguments, or settings we need to propgate them down to subcommands // If there are global arguments, or settings we need to propgate them down to subcommands
@ -1508,7 +1508,7 @@ impl<'b> App<'b> {
// used in clap_generate (https://github.com/clap-rs/clap_generate) // used in clap_generate (https://github.com/clap-rs/clap_generate)
#[doc(hidden)] #[doc(hidden)]
pub fn _build(&mut self) { pub fn _build(&mut self) {
debugln!("App::_build;"); debug!("App::_build");
// Make sure all the globally set flags apply to us as well // Make sure all the globally set flags apply to us as well
self.settings = self.settings | self.g_settings; self.settings = self.settings | self.g_settings;
@ -1582,7 +1582,7 @@ impl<'b> App<'b> {
// Perform some expensive assertions on the Parser itself // Perform some expensive assertions on the Parser itself
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
fn _debug_asserts(&self) { fn _debug_asserts(&self) {
debugln!("App::_debug_asserts;"); debug!("App::_debug_asserts");
for arg in &self.args.args { for arg in &self.args.args {
arg._debug_asserts(); arg._debug_asserts();
@ -1750,7 +1750,8 @@ impl<'b> App<'b> {
}}; }};
} }
debugln!("App::_propagate:{}", self.name); debug!("App::_propagate:{}", self.name);
match prop { match prop {
Propagation::NextLevel | Propagation::Full => { Propagation::NextLevel | Propagation::Full => {
for sc in &mut self.subcommands { for sc in &mut self.subcommands {
@ -1773,14 +1774,15 @@ impl<'b> App<'b> {
} }
pub(crate) fn _create_help_and_version(&mut self) { pub(crate) fn _create_help_and_version(&mut self) {
debugln!("App::_create_help_and_version;"); debug!("App::_create_help_and_version");
if !(self if !(self
.args .args
.args .args
.iter() .iter()
.any(|x| x.long == Some("help") || x.id == Id::help_hash())) .any(|x| x.long == Some("help") || x.id == Id::help_hash()))
{ {
debugln!("App::_create_help_and_version: Building --help"); debug!("App::_create_help_and_version: Building --help");
let mut help = Arg::with_name("help") let mut help = Arg::with_name("help")
.long("help") .long("help")
.help("Prints help information"); .help("Prints help information");
@ -1797,7 +1799,7 @@ impl<'b> App<'b> {
.any(|x| x.long == Some("version") || x.id == Id::version_hash()) .any(|x| x.long == Some("version") || x.id == Id::version_hash())
|| self.is_set(AppSettings::DisableVersion)) || self.is_set(AppSettings::DisableVersion))
{ {
debugln!("App::_create_help_and_version: Building --version"); debug!("App::_create_help_and_version: Building --version");
let mut version = Arg::with_name("version") let mut version = Arg::with_name("version")
.long("version") .long("version")
.help("Prints version information"); .help("Prints version information");
@ -1811,7 +1813,7 @@ impl<'b> App<'b> {
&& !self.is_set(AppSettings::DisableHelpSubcommand) && !self.is_set(AppSettings::DisableHelpSubcommand)
&& !self.subcommands.iter().any(|s| s.id == Id::help_hash()) && !self.subcommands.iter().any(|s| s.id == Id::help_hash())
{ {
debugln!("App::_create_help_and_version: Building help"); debug!("App::_create_help_and_version: Building help");
self.subcommands.push( self.subcommands.push(
App::new("help") App::new("help")
.about("Prints this message or the help of the given subcommand(s)"), .about("Prints this message or the help of the given subcommand(s)"),
@ -1820,7 +1822,8 @@ impl<'b> App<'b> {
} }
pub(crate) fn _derive_display_order(&mut self) { pub(crate) fn _derive_display_order(&mut self) {
debugln!("App::_derive_display_order:{}", self.name); debug!("App::_derive_display_order:{}", self.name);
if self.settings.is_set(AppSettings::DeriveDisplayOrder) { if self.settings.is_set(AppSettings::DeriveDisplayOrder) {
for (i, a) in self for (i, a) in self
.args .args
@ -1849,28 +1852,29 @@ impl<'b> App<'b> {
// used in clap_generate (https://github.com/clap-rs/clap_generate) // used in clap_generate (https://github.com/clap-rs/clap_generate)
#[doc(hidden)] #[doc(hidden)]
pub fn _build_bin_names(&mut self) { pub fn _build_bin_names(&mut self) {
debugln!("App::_build_bin_names;"); debug!("App::_build_bin_names");
for mut sc in &mut self.subcommands { for mut sc in &mut self.subcommands {
debug!("Parser::build_bin_names:iter: bin_name set..."); debug!("App::_build_bin_names:iter: bin_name set...");
if sc.bin_name.is_none() { if sc.bin_name.is_none() {
sdebugln!("No"); debug!("No");
let bin_name = format!( let bin_name = format!(
"{}{}{}", "{}{}{}",
self.bin_name.as_ref().unwrap_or(&self.name.clone()), self.bin_name.as_ref().unwrap_or(&self.name.clone()),
if self.bin_name.is_some() { " " } else { "" }, if self.bin_name.is_some() { " " } else { "" },
&*sc.name &*sc.name
); );
debugln!( debug!(
"Parser::build_bin_names:iter: Setting bin_name of {} to {}", "App::_build_bin_names:iter: Setting bin_name of {} to {}",
self.name, self.name, bin_name
bin_name
); );
sc.bin_name = Some(bin_name); sc.bin_name = Some(bin_name);
} else { } else {
sdebugln!("yes ({:?})", sc.bin_name); debug!("yes ({:?})", sc.bin_name);
} }
debugln!( debug!(
"Parser::build_bin_names:iter: Calling build_bin_names from...{}", "App::_build_bin_names:iter: Calling build_bin_names from...{}",
sc.name sc.name
); );
sc._build_bin_names(); sc._build_bin_names();
@ -1878,7 +1882,8 @@ impl<'b> App<'b> {
} }
pub(crate) fn _write_version<W: Write>(&self, w: &mut W, use_long: bool) -> io::Result<()> { pub(crate) fn _write_version<W: Write>(&self, w: &mut W, use_long: bool) -> io::Result<()> {
debugln!("App::_write_version;"); debug!("App::_write_version");
let ver = if use_long { let ver = if use_long {
self.long_version self.long_version
.unwrap_or_else(|| self.version.unwrap_or("")) .unwrap_or_else(|| self.version.unwrap_or(""))
@ -1924,17 +1929,16 @@ impl<'b> App<'b> {
// Should we color the output? // Should we color the output?
pub(crate) fn color(&self) -> ColorChoice { pub(crate) fn color(&self) -> ColorChoice {
debugln!("App::color;");
debug!("App::color: Color setting..."); debug!("App::color: Color setting...");
if self.is_set(AppSettings::ColorNever) { if self.is_set(AppSettings::ColorNever) {
sdebugln!("Never"); debug!("Never");
ColorChoice::Never ColorChoice::Never
} else if self.is_set(AppSettings::ColorAlways) { } else if self.is_set(AppSettings::ColorAlways) {
sdebugln!("Always"); debug!("Always");
ColorChoice::Always ColorChoice::Always
} else { } else {
sdebugln!("Auto"); debug!("Auto");
ColorChoice::Auto ColorChoice::Auto
} }
} }
@ -1975,7 +1979,7 @@ impl<'b> App<'b> {
} }
pub(crate) fn unroll_args_in_group(&self, group: &Id) -> Vec<Id> { pub(crate) fn unroll_args_in_group(&self, group: &Id) -> Vec<Id> {
debugln!("App::unroll_args_in_group: group={:?}", group); debug!("App::unroll_args_in_group: group={:?}", group);
let mut g_vec = vec![group]; let mut g_vec = vec![group];
let mut args = vec![]; let mut args = vec![];
@ -1988,13 +1992,13 @@ impl<'b> App<'b> {
.args .args
.iter() .iter()
{ {
debugln!("App::unroll_args_in_group:iter: entity={:?}", n); debug!("App::unroll_args_in_group:iter: entity={:?}", n);
if !args.contains(n) { if !args.contains(n) {
if self.find(n).is_some() { if self.find(n).is_some() {
debugln!("App::unroll_args_in_group:iter: this is an arg"); debug!("App::unroll_args_in_group:iter: this is an arg");
args.push(n.clone()) args.push(n.clone())
} else { } else {
debugln!("App::unroll_args_in_group:iter: this is a group"); debug!("App::unroll_args_in_group:iter: this is a group");
g_vec.push(n); g_vec.push(n);
} }
} }

View file

@ -4176,7 +4176,7 @@ impl<'help> Arg<'help> {
// Used for positionals when printing // Used for positionals when printing
pub(crate) fn name_no_brackets(&self) -> Cow<str> { pub(crate) fn name_no_brackets(&self) -> Cow<str> {
debugln!("PosBuilder::name_no_brackets:{}", self.name); debug!("Arg::name_no_brackets:{}", self.name);
let mut delim = String::new(); let mut delim = String::new();
delim.push(if self.is_set(ArgSettings::RequireDelimiter) { delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
self.val_delim.expect(INTERNAL_ERROR_MSG) self.val_delim.expect(INTERNAL_ERROR_MSG)
@ -4184,7 +4184,8 @@ impl<'help> Arg<'help> {
' ' ' '
}); });
if let Some(ref names) = self.val_names { if let Some(ref names) = self.val_names {
debugln!("PosBuilder:name_no_brackets: val_names={:#?}", names); debug!("Arg::name_no_brackets: val_names={:#?}", names);
if names.len() > 1 { if names.len() > 1 {
Cow::Owned( Cow::Owned(
names names
@ -4197,7 +4198,7 @@ impl<'help> Arg<'help> {
Cow::Borrowed(names.values().next().expect(INTERNAL_ERROR_MSG)) Cow::Borrowed(names.values().next().expect(INTERNAL_ERROR_MSG))
} }
} else { } else {
debugln!("PosBuilder:name_no_brackets: just name"); debug!("Arg::name_no_brackets: just name");
Cow::Borrowed(self.name) Cow::Borrowed(self.name)
} }
} }
@ -4205,7 +4206,7 @@ impl<'help> Arg<'help> {
impl<'a> Arg<'a> { impl<'a> Arg<'a> {
pub(crate) fn _debug_asserts(&self) { pub(crate) fn _debug_asserts(&self) {
debugln!("Arg::_debug_asserts:{};", self.name); debug!("Arg::_debug_asserts:{}", self.name);
// Self conflict // Self conflict
if let Some(vec) = &self.blacklist { if let Some(vec) = &self.blacklist {

View file

@ -26,7 +26,7 @@ pub(crate) struct UsageParser<'a> {
impl<'a> UsageParser<'a> { impl<'a> UsageParser<'a> {
fn new(usage: &'a str) -> Self { fn new(usage: &'a str) -> Self {
debugln!("UsageParser::new: usage={:?}", usage); debug!("new: usage={:?}", usage);
UsageParser { UsageParser {
usage, usage,
pos: 0, pos: 0,
@ -37,17 +37,17 @@ impl<'a> UsageParser<'a> {
} }
pub(crate) fn from_usage(usage: &'a str) -> Self { pub(crate) fn from_usage(usage: &'a str) -> Self {
debugln!("UsageParser::from_usage;"); debug!("UsageParser::from_usage");
UsageParser::new(usage) UsageParser::new(usage)
} }
pub(crate) fn parse(mut self) -> Arg<'a> { pub(crate) fn parse(mut self) -> Arg<'a> {
debugln!("UsageParser::parse;"); debug!("UsageParser::parse");
let mut arg = Arg::default(); let mut arg = Arg::default();
arg.disp_ord = 999; arg.disp_ord = 999;
arg.unified_ord = 999; arg.unified_ord = 999;
loop { loop {
debugln!("UsageParser::parse:iter: pos={};", self.pos); debug!("UsageParser::parse:iter: pos={}", self.pos);
self.stop_at(token); self.stop_at(token);
if let Some(&c) = self.usage.as_bytes().get(self.pos) { if let Some(&c) = self.usage.as_bytes().get(self.pos) {
match c { match c {
@ -69,12 +69,12 @@ impl<'a> UsageParser<'a> {
// We had a positional and need to set mult vals too // We had a positional and need to set mult vals too
arg.setb(ArgSettings::MultipleValues); arg.setb(ArgSettings::MultipleValues);
} }
debugln!("UsageParser::parse: vals...{:?}", arg.val_names); debug!("UsageParser::parse: vals...{:?}", arg.val_names);
arg arg
} }
fn name(&mut self, arg: &mut Arg<'a>) { fn name(&mut self, arg: &mut Arg<'a>) {
debugln!("UsageParser::name;"); debug!("UsageParser::name");
if *self if *self
.usage .usage
.as_bytes() .as_bytes()
@ -89,16 +89,16 @@ impl<'a> UsageParser<'a> {
self.stop_at(name_end); self.stop_at(name_end);
let name = &self.usage[self.start..self.pos]; let name = &self.usage[self.start..self.pos];
if self.prev == UsageToken::Unknown { if self.prev == UsageToken::Unknown {
debugln!("UsageParser::name: setting name...{}", name); debug!("UsageParser::name: setting name...{}", name);
arg.id = name.into(); arg.id = name.into();
arg.name = name; arg.name = name;
if arg.long.is_none() && arg.short.is_none() { if arg.long.is_none() && arg.short.is_none() {
debugln!("UsageParser::name: explicit name set..."); debug!("name: explicit name set...");
self.explicit_name_set = true; self.explicit_name_set = true;
self.prev = UsageToken::Name; self.prev = UsageToken::Name;
} }
} else { } else {
debugln!("UsageParser::name: setting val name...{}", name); debug!("UsageParser::name: setting val name...{}", name);
if let Some(ref mut v) = arg.val_names { if let Some(ref mut v) = arg.val_names {
let len = v.len(); let len = v.len();
v.insert(len, name); v.insert(len, name);
@ -116,7 +116,7 @@ impl<'a> UsageParser<'a> {
where where
F: Fn(u8) -> bool, F: Fn(u8) -> bool,
{ {
debugln!("UsageParser::stop_at;"); debug!("UsageParser::stop_at");
self.start = self.pos; self.start = self.pos;
self.pos += self.usage[self.start..] self.pos += self.usage[self.start..]
.bytes() .bytes()
@ -125,7 +125,7 @@ impl<'a> UsageParser<'a> {
} }
fn short_or_long(&mut self, arg: &mut Arg<'a>) { fn short_or_long(&mut self, arg: &mut Arg<'a>) {
debugln!("UsageParser::short_or_long;"); debug!("UsageParser::short_or_long");
self.pos += 1; self.pos += 1;
if *self if *self
.usage .usage
@ -142,29 +142,29 @@ impl<'a> UsageParser<'a> {
} }
fn long(&mut self, arg: &mut Arg<'a>) { fn long(&mut self, arg: &mut Arg<'a>) {
debugln!("UsageParser::long;"); debug!("UsageParser::long");
self.stop_at(long_end); self.stop_at(long_end);
let name = &self.usage[self.start..self.pos]; let name = &self.usage[self.start..self.pos];
if !self.explicit_name_set { if !self.explicit_name_set {
debugln!("UsageParser::long: setting name...{}", name); debug!("UsageParser::long: setting name...{}", name);
arg.id = name.into(); arg.id = name.into();
arg.name = name; arg.name = name;
} }
debugln!("UsageParser::long: setting long...{}", name); debug!("UsageParser::long: setting long...{}", name);
arg.long = Some(name); arg.long = Some(name);
self.prev = UsageToken::Long; self.prev = UsageToken::Long;
} }
fn short(&mut self, arg: &mut Arg<'a>) { fn short(&mut self, arg: &mut Arg<'a>) {
debugln!("UsageParser::short;"); debug!("UsageParser::short");
let start = &self.usage[self.pos..]; let start = &self.usage[self.pos..];
let short = start.chars().next().expect(INTERNAL_ERROR_MSG); let short = start.chars().next().expect(INTERNAL_ERROR_MSG);
debugln!("UsageParser::short: setting short...{}", short); debug!("UsageParser::short: setting short...{}", short);
arg.short = Some(short); arg.short = Some(short);
if arg.name.is_empty() { if arg.name.is_empty() {
// --long takes precedence but doesn't set self.explicit_name_set // --long takes precedence but doesn't set self.explicit_name_set
let name = &start[..short.len_utf8()]; let name = &start[..short.len_utf8()];
debugln!("UsageParser::short: setting name...{}", name); debug!("UsageParser::short: setting name...{}", name);
arg.id = name.into(); arg.id = name.into();
arg.name = name; arg.name = name;
} }
@ -173,7 +173,7 @@ impl<'a> UsageParser<'a> {
// "something..." // "something..."
fn multiple(&mut self, arg: &mut Arg) { fn multiple(&mut self, arg: &mut Arg) {
debugln!("UsageParser::multiple;"); debug!("UsageParser::multiple");
let mut dot_counter = 1; let mut dot_counter = 1;
let start = self.pos; let start = self.pos;
let mut bytes = self.usage[start..].bytes(); let mut bytes = self.usage[start..].bytes();
@ -181,7 +181,7 @@ impl<'a> UsageParser<'a> {
dot_counter += 1; dot_counter += 1;
self.pos += 1; self.pos += 1;
if dot_counter == 3 { if dot_counter == 3 {
debugln!("UsageParser::multiple: setting multiple"); debug!("UsageParser::multiple: setting multiple");
if arg.is_set(ArgSettings::TakesValue) { if arg.is_set(ArgSettings::TakesValue) {
arg.setb(ArgSettings::MultipleValues); arg.setb(ArgSettings::MultipleValues);
} }
@ -194,11 +194,11 @@ impl<'a> UsageParser<'a> {
} }
fn help(&mut self, arg: &mut Arg<'a>) { fn help(&mut self, arg: &mut Arg<'a>) {
debugln!("UsageParser::help;"); debug!("UsageParser::help");
self.stop_at(help_start); self.stop_at(help_start);
self.start = self.pos + 1; self.start = self.pos + 1;
self.pos = self.usage.len() - 1; self.pos = self.usage.len() - 1;
debugln!( debug!(
"UsageParser::help: setting help...{}", "UsageParser::help: setting help...{}",
&self.usage[self.start..self.pos] &self.usage[self.start..self.pos]
); );
@ -208,13 +208,13 @@ impl<'a> UsageParser<'a> {
} }
fn default(&mut self, arg: &mut Arg<'a>) { fn default(&mut self, arg: &mut Arg<'a>) {
debugln!( debug!(
"UsageParser::default; from: \"{}\"", "UsageParser::default: from=\"{}\"",
&self.usage[self.pos..self.usage.len()] &self.usage[self.pos..self.usage.len()]
); );
self.pos += 1; // Skip @ self.pos += 1; // Skip @
self.stop_at(default_value_end); // Find first space after value self.stop_at(default_value_end); // Find first space after value
debugln!( debug!(
"UsageParser::default: setting default...\"{}\"", "UsageParser::default: setting default...\"{}\"",
&self.usage[self.start..self.pos] &self.usage[self.start..self.pos]
); );

View file

@ -557,66 +557,24 @@ macro_rules! impl_settings {
} }
// Convenience for writing to stderr thanks to https://github.com/BurntSushi // Convenience for writing to stderr thanks to https://github.com/BurntSushi
macro_rules! wlnerr( macro_rules! wlnerr {
($($arg:tt)*) => ({ ($($arg:tt)*) => ({
use std::io::{Write, stderr}; use std::io::{Write, stderr};
writeln!(&mut stderr(), $($arg)*).ok(); writeln!(&mut stderr(), $($arg)*).ok();
}) })
); }
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
#[cfg_attr(feature = "debug", macro_use)] macro_rules! debug {
#[cfg_attr(feature = "debug", allow(unused_macros))] ($($arg:tt)*) => {
mod debug_macros { print!("[{:>w$}] \t", module_path!(), w = 28);
macro_rules! debugln { println!($($arg)*)
($fmt:expr) => (println!(concat!("DEBUG:clap:", $fmt)));
($fmt:expr, $($arg:tt)*) => (println!(concat!("DEBUG:clap:",$fmt), $($arg)*));
}
macro_rules! sdebugln {
($fmt:expr) => (println!($fmt));
($fmt:expr, $($arg:tt)*) => (println!($fmt, $($arg)*));
}
macro_rules! debug {
($fmt:expr) => (print!(concat!("DEBUG:clap:", $fmt)));
($fmt:expr, $($arg:tt)*) => (print!(concat!("DEBUG:clap:",$fmt), $($arg)*));
}
macro_rules! sdebug {
($fmt:expr) => (print!($fmt));
($fmt:expr, $($arg:tt)*) => (print!($fmt, $($arg)*));
} }
} }
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
#[cfg_attr(not(feature = "debug"), macro_use)] macro_rules! debug {
mod debug_macros { ($($arg:tt)*) => {};
macro_rules! debugln {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => { ignore_fmt_args!($($arg)*); };
}
macro_rules! sdebugln {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => { ignore_fmt_args!($($arg)*); };
}
macro_rules! debug {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => { ignore_fmt_args!($($arg)*); };
}
macro_rules! ignore_fmt_args {
() => {};
// name = expr
($name:ident = $val:expr $( , $($ts:tt)* )?) => {
let _ = &$val;
ignore_fmt_args!($($($ts)*)*);
};
// expr
($val:expr $( , $($ts:tt)* )?) => {
let _ = &$val;
ignore_fmt_args!($($($ts)*)*);
};
}
} }
#[macro_export] #[macro_export]
@ -659,7 +617,7 @@ macro_rules! positionals {
macro_rules! groups_for_arg { macro_rules! groups_for_arg {
($app:expr, $grp:expr) => {{ ($app:expr, $grp:expr) => {{
debugln!("Parser::groups_for_arg: name={:?}", $grp); debug!("groups_for_arg: name={:?}", $grp);
$app.groups $app.groups
.iter() .iter()
.filter(|grp| grp.args.iter().any(|a| *a == $grp)) .filter(|grp| grp.args.iter().any(|a| *a == $grp))

View file

@ -7,7 +7,7 @@ use std::io::{Result, Write};
#[cfg(feature = "color")] #[cfg(feature = "color")]
fn is_a_tty(stderr: bool) -> bool { fn is_a_tty(stderr: bool) -> bool {
debugln!("is_a_tty: stderr={:?}", stderr); debug!("is_a_tty: stderr={:?}", stderr);
let stream = if stderr { let stream = if stderr {
atty::Stream::Stderr atty::Stream::Stderr
@ -20,7 +20,7 @@ fn is_a_tty(stderr: bool) -> bool {
#[cfg(not(feature = "color"))] #[cfg(not(feature = "color"))]
fn is_a_tty(_: bool) -> bool { fn is_a_tty(_: bool) -> bool {
debugln!("is_a_tty;"); debug!("is_a_tty");
false false
} }

View file

@ -67,7 +67,7 @@ pub(crate) struct Help<'b, 'c, 'd, 'w> {
impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> { impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Create a new `Help` instance. /// Create a new `Help` instance.
pub(crate) fn new(w: HelpWriter<'w>, parser: &'d Parser<'b, 'c>, use_long: bool) -> Self { pub(crate) fn new(w: HelpWriter<'w>, parser: &'d Parser<'b, 'c>, use_long: bool) -> Self {
debugln!("Help::new;"); debug!("Help::new");
let term_w = match parser.app.term_w { let term_w = match parser.app.term_w {
Some(0) => usize::MAX, Some(0) => usize::MAX,
Some(w) => w, Some(w) => w,
@ -96,7 +96,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes the parser help to the wrapped stream. /// Writes the parser help to the wrapped stream.
pub(crate) fn write_help(&mut self) -> ClapResult<()> { pub(crate) fn write_help(&mut self) -> ClapResult<()> {
debugln!("Help::write_help;"); debug!("Help::write_help");
if let Some(h) = self.parser.app.help_str { if let Some(h) = self.parser.app.help_str {
self.none(h).map_err(Error::from)?; self.none(h).map_err(Error::from)?;
@ -123,7 +123,7 @@ macro_rules! write_method {
macro_rules! write_nspaces { macro_rules! write_nspaces {
($_self:ident, $num:expr) => {{ ($_self:ident, $num:expr) => {{
debugln!("write_nspaces!: num={}", $num); debug!("Help::write_nspaces!: num={}", $num);
for _ in 0..$num { for _ in 0..$num {
$_self.none(" ")?; $_self.none(" ")?;
} }
@ -151,7 +151,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes help for each argument in the order they were declared to the wrapped stream. /// Writes help for each argument in the order they were declared to the wrapped stream.
fn write_args_unsorted(&mut self, args: &[&Arg<'b>]) -> io::Result<()> { fn write_args_unsorted(&mut self, args: &[&Arg<'b>]) -> io::Result<()> {
debugln!("Help::write_args_unsorted;"); debug!("Help::write_args_unsorted");
// The shortest an arg can legally be is 2 (i.e. '-x') // The shortest an arg can legally be is 2 (i.e. '-x')
self.longest = 2; self.longest = 2;
let mut arg_v = Vec::with_capacity(10); let mut arg_v = Vec::with_capacity(10);
@ -177,7 +177,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Sorts arguments by length and display order and write their help to the wrapped stream. /// Sorts arguments by length and display order and write their help to the wrapped stream.
fn write_args(&mut self, args: &[&Arg<'b>]) -> io::Result<()> { fn write_args(&mut self, args: &[&Arg<'b>]) -> io::Result<()> {
debugln!("Help::write_args;"); debug!("Help::write_args");
// The shortest an arg can legally be is 2 (i.e. '-x') // The shortest an arg can legally be is 2 (i.e. '-x')
self.longest = 2; self.longest = 2;
let mut ord_m = VecMap::new(); let mut ord_m = VecMap::new();
@ -190,9 +190,9 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
should_show_arg(use_long, *arg) should_show_arg(use_long, *arg)
}) { }) {
if arg.longest_filter() { if arg.longest_filter() {
debugln!("Help::write_args: Current Longest...{}", self.longest); debug!("Help::write_args: Current Longest...{}", self.longest);
self.longest = cmp::max(self.longest, str_width(arg.to_string().as_str())); self.longest = cmp::max(self.longest, str_width(arg.to_string().as_str()));
debugln!("Help::write_args: New Longest...{}", self.longest); debug!("Help::write_args: New Longest...{}", self.longest);
} }
let btm = ord_m.entry(arg.disp_ord).or_insert(BTreeMap::new()); let btm = ord_m.entry(arg.disp_ord).or_insert(BTreeMap::new());
// We use name here for alphabetic sorting // We use name here for alphabetic sorting
@ -215,7 +215,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes help for an argument to the wrapped stream. /// Writes help for an argument to the wrapped stream.
fn write_arg(&mut self, arg: &Arg<'c>, prevent_nlh: bool) -> io::Result<()> { fn write_arg(&mut self, arg: &Arg<'c>, prevent_nlh: bool) -> io::Result<()> {
debugln!("Help::write_arg;"); debug!("Help::write_arg");
self.short(arg)?; self.short(arg)?;
self.long(arg)?; self.long(arg)?;
let spec_vals = self.val(arg)?; let spec_vals = self.val(arg)?;
@ -225,7 +225,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes argument's short command to the wrapped stream. /// Writes argument's short command to the wrapped stream.
fn short(&mut self, arg: &Arg<'c>) -> io::Result<()> { fn short(&mut self, arg: &Arg<'c>) -> io::Result<()> {
debugln!("Help::short;"); debug!("Help::short");
self.none(TAB)?; self.none(TAB)?;
@ -240,7 +240,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes argument's long command to the wrapped stream. /// Writes argument's long command to the wrapped stream.
fn long(&mut self, arg: &Arg<'c>) -> io::Result<()> { fn long(&mut self, arg: &Arg<'c>) -> io::Result<()> {
debugln!("Help::long;"); debug!("Help::long");
if !arg.has_switch() { if !arg.has_switch() {
return Ok(()); return Ok(());
} }
@ -269,7 +269,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes argument's possible values to the wrapped stream. /// Writes argument's possible values to the wrapped stream.
fn val(&mut self, arg: &Arg<'c>) -> Result<String, io::Error> { fn val(&mut self, arg: &Arg<'c>) -> Result<String, io::Error> {
debugln!("Help::val: arg={}", arg.name); debug!("Help::val: arg={}", arg.name);
let mult = let mult =
arg.is_set(ArgSettings::MultipleValues) || arg.is_set(ArgSettings::MultipleOccurrences); arg.is_set(ArgSettings::MultipleValues) || arg.is_set(ArgSettings::MultipleOccurrences);
if arg.is_set(ArgSettings::TakesValue) || arg.index.is_some() { if arg.is_set(ArgSettings::TakesValue) || arg.index.is_some() {
@ -323,20 +323,18 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
debug!("Help::val: Has switch..."); debug!("Help::val: Has switch...");
if arg.has_switch() { if arg.has_switch() {
sdebugln!("Yes"); debug!("Yes");
debugln!("Help::val: force_next_line...{:?}", self.force_next_line); debug!("Help::val: force_next_line...{:?}", self.force_next_line);
debugln!("Help::val: nlh...{:?}", nlh); debug!("Help::val: nlh...{:?}", nlh);
debugln!("Help::val: taken...{}", taken); debug!("Help::val: taken...{}", taken);
debugln!( debug!(
"Help::val: help_width > (width - taken)...{} > ({} - {})", "val: help_width > (width - taken)...{} > ({} - {})",
h_w, h_w, self.term_w, taken
self.term_w,
taken
); );
debugln!("Help::val: longest...{}", self.longest); debug!("Help::val: longest...{}", self.longest);
debug!("Help::val: next_line..."); debug!("Help::val: next_line...");
if !(nlh || self.force_next_line) { if !(nlh || self.force_next_line) {
sdebugln!("No"); debug!("No");
let self_len = str_width(arg.to_string().as_str()); let self_len = str_width(arg.to_string().as_str());
// subtract ourself // subtract ourself
let mut spcs = self.longest - self_len; let mut spcs = self.longest - self_len;
@ -352,25 +350,25 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
write_nspaces!(self, spcs); write_nspaces!(self, spcs);
} else { } else {
sdebugln!("Yes"); debug!("Yes");
} }
} else if !(nlh || self.force_next_line) { } else if !(nlh || self.force_next_line) {
sdebugln!("No, and not next_line"); debug!("No, and not next_line");
write_nspaces!( write_nspaces!(
self, self,
self.longest + 4 - (str_width(arg.to_string().as_str())) self.longest + 4 - (str_width(arg.to_string().as_str()))
); );
} else { } else {
sdebugln!("No"); debug!("No");
} }
Ok(spec_vals) Ok(spec_vals)
} }
fn write_before_after_help(&mut self, h: &str) -> io::Result<()> { fn write_before_after_help(&mut self, h: &str) -> io::Result<()> {
debugln!("Help::write_before_after_help;"); debug!("Help::write_before_after_help");
let mut help = String::from(h); let mut help = String::from(h);
// determine if our help fits or needs to wrap // determine if our help fits or needs to wrap
debugln!( debug!(
"Help::write_before_after_help: Term width...{}", "Help::write_before_after_help: Term width...{}",
self.term_w self.term_w
); );
@ -378,20 +376,20 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
debug!("Help::write_before_after_help: Too long..."); debug!("Help::write_before_after_help: Too long...");
if too_long { if too_long {
sdebugln!("Yes"); debug!("Yes");
debugln!("Help::write_before_after_help: help: {}", help); debug!("Help::write_before_after_help: help: {}", help);
debugln!( debug!(
"Help::write_before_after_help: help width: {}", "Help::write_before_after_help: help width: {}",
str_width(&*help) str_width(&*help)
); );
// Determine how many newlines we need to insert // Determine how many newlines we need to insert
debugln!( debug!(
"Help::write_before_after_help: Usable space: {}", "Help::write_before_after_help: Usable space: {}",
self.term_w self.term_w
); );
help = wrap_help(&help, self.term_w); help = wrap_help(&help, self.term_w);
} else { } else {
sdebugln!("No"); debug!("No");
} }
self.none(&help)?; self.none(&help)?;
Ok(()) Ok(())
@ -399,7 +397,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes argument's help to the wrapped stream. /// Writes argument's help to the wrapped stream.
fn help(&mut self, arg: &Arg<'c>, spec_vals: &str, prevent_nlh: bool) -> io::Result<()> { fn help(&mut self, arg: &Arg<'c>, spec_vals: &str, prevent_nlh: bool) -> io::Result<()> {
debugln!("Help::help;"); debug!("Help::help");
let h = if self.use_long { let h = if self.use_long {
arg.long_help.unwrap_or_else(|| arg.help.unwrap_or("")) arg.long_help.unwrap_or_else(|| arg.help.unwrap_or(""))
} else { } else {
@ -407,7 +405,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
}; };
let mut help = String::from(h) + spec_vals; let mut help = String::from(h) + spec_vals;
let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || self.use_long; let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || self.use_long;
debugln!("Help::help: Next Line...{:?}", nlh); debug!("Help::help: Next Line...{:?}", nlh);
let spcs = if nlh || self.force_next_line { let spcs = if nlh || self.force_next_line {
12 // "tab" * 3 12 // "tab" * 3
@ -424,15 +422,15 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
debug!("Help::help: Too long..."); debug!("Help::help: Too long...");
if too_long && spcs <= self.term_w { if too_long && spcs <= self.term_w {
sdebugln!("Yes"); debug!("Yes");
debugln!("Help::help: help...{}", help); debug!("Help::help: help...{}", help);
debugln!("Help::help: help width...{}", str_width(&*help)); debug!("Help::help: help width...{}", str_width(&*help));
// Determine how many newlines we need to insert // Determine how many newlines we need to insert
let avail_chars = self.term_w - spcs; let avail_chars = self.term_w - spcs;
debugln!("Help::help: Usable space...{}", avail_chars); debug!("Help::help: Usable space...{}", avail_chars);
help = wrap_help(&help, avail_chars); help = wrap_help(&help, avail_chars);
} else { } else {
sdebugln!("No"); debug!("No");
} }
if let Some(part) = help.lines().next() { if let Some(part) = help.lines().next() {
self.none(part)?; self.none(part)?;
@ -455,13 +453,12 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
fn spec_vals(&self, a: &Arg) -> String { fn spec_vals(&self, a: &Arg) -> String {
debugln!("Help::spec_vals: a={}", a); debug!("Help::spec_vals: a={}", a);
let mut spec_vals = vec![]; let mut spec_vals = vec![];
if let Some(ref env) = a.env { if let Some(ref env) = a.env {
debugln!( debug!(
"Help::spec_vals: Found environment variable...[{:?}:{:?}]", "Help::spec_vals: Found environment variable...[{:?}:{:?}]",
env.0, env.0, env.1
env.1
); );
let env_val = if !a.is_set(ArgSettings::HideEnvValues) { let env_val = if !a.is_set(ArgSettings::HideEnvValues) {
format!( format!(
@ -478,7 +475,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
if !a.is_set(ArgSettings::HideDefaultValue) { if !a.is_set(ArgSettings::HideDefaultValue) {
if let Some(ref pv) = a.default_vals { if let Some(ref pv) = a.default_vals {
debugln!("Help::spec_vals: Found default value...[{:?}]", pv); debug!("Help::spec_vals: Found default value...[{:?}]", pv);
let pvs = pv let pvs = pv
.iter() .iter()
@ -490,7 +487,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
} }
if let Some(ref aliases) = a.aliases { if let Some(ref aliases) = a.aliases {
debugln!("Help::spec_vals: Found aliases...{:?}", aliases); debug!("Help::spec_vals: Found aliases...{:?}", aliases);
let als = aliases let als = aliases
.iter() .iter()
@ -505,7 +502,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
if !self.hide_pv && !a.is_set(ArgSettings::HidePossibleValues) { if !self.hide_pv && !a.is_set(ArgSettings::HidePossibleValues) {
if let Some(ref pv) = a.possible_vals { if let Some(ref pv) = a.possible_vals {
debugln!("Help::spec_vals: Found possible vals...{:?}", pv); debug!("Help::spec_vals: Found possible vals...{:?}", pv);
spec_vals.push(format!(" [possible values: {}]", pv.join(", "))); spec_vals.push(format!(" [possible values: {}]", pv.join(", ")));
} }
@ -517,7 +514,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Methods to write a single subcommand /// Methods to write a single subcommand
impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> { impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
fn write_subcommand(&mut self, app: &App<'b>) -> io::Result<()> { fn write_subcommand(&mut self, app: &App<'b>) -> io::Result<()> {
debugln!("Help::write_subcommand;"); debug!("Help::write_subcommand");
self.none(TAB)?; self.none(TAB)?;
self.good(&app.name)?; self.good(&app.name)?;
let spec_vals = self.sc_val(app)?; let spec_vals = self.sc_val(app)?;
@ -526,7 +523,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
fn sc_val(&mut self, app: &App<'b>) -> Result<String, io::Error> { fn sc_val(&mut self, app: &App<'b>) -> Result<String, io::Error> {
debugln!("Help::sc_val: app={}", app.name); debug!("Help::sc_val: app={}", app.name);
let spec_vals = self.sc_spec_vals(app); let spec_vals = self.sc_spec_vals(app);
let h = app.about.unwrap_or(""); let h = app.about.unwrap_or("");
let h_w = str_width(h) + str_width(&*spec_vals); let h_w = str_width(h) + str_width(&*spec_vals);
@ -544,10 +541,10 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
fn sc_spec_vals(&self, a: &App) -> String { fn sc_spec_vals(&self, a: &App) -> String {
debugln!("Help::sc_spec_vals: a={}", a.name); debug!("Help::sc_spec_vals: a={}", a.name);
let mut spec_vals = vec![]; let mut spec_vals = vec![];
if let Some(ref aliases) = a.aliases { if let Some(ref aliases) = a.aliases {
debugln!("Help::spec_vals: Found aliases...{:?}", aliases); debug!("Help::spec_vals: Found aliases...{:?}", aliases);
let als = aliases let als = aliases
.iter() .iter()
@ -564,7 +561,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
fn sc_help(&mut self, app: &App<'b>, spec_vals: &str) -> io::Result<()> { fn sc_help(&mut self, app: &App<'b>, spec_vals: &str) -> io::Result<()> {
debugln!("Help::sc_help;"); debug!("Help::sc_help");
let h = if self.use_long { let h = if self.use_long {
app.long_about.unwrap_or_else(|| app.about.unwrap_or("")) app.long_about.unwrap_or_else(|| app.about.unwrap_or(""))
} else { } else {
@ -572,7 +569,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
}; };
let mut help = String::from(h) + spec_vals; let mut help = String::from(h) + spec_vals;
let nlh = self.next_line_help || self.use_long; let nlh = self.next_line_help || self.use_long;
debugln!("Help::sc_help: Next Line...{:?}", nlh); debug!("Help::sc_help: Next Line...{:?}", nlh);
let spcs = if nlh || self.force_next_line { let spcs = if nlh || self.force_next_line {
12 // "tab" * 3 12 // "tab" * 3
@ -589,15 +586,15 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
debug!("Help::sc_help: Too long..."); debug!("Help::sc_help: Too long...");
if too_long && spcs <= self.term_w { if too_long && spcs <= self.term_w {
sdebugln!("Yes"); debug!("Yes");
debugln!("Help::sc_help: help...{}", help); debug!("Help::sc_help: help...{}", help);
debugln!("Help::sc_help: help width...{}", str_width(&*help)); debug!("Help::sc_help: help width...{}", str_width(&*help));
// Determine how many newlines we need to insert // Determine how many newlines we need to insert
let avail_chars = self.term_w - spcs; let avail_chars = self.term_w - spcs;
debugln!("Help::sc_help: Usable space...{}", avail_chars); debug!("Help::sc_help: Usable space...{}", avail_chars);
help = wrap_help(&help, avail_chars); help = wrap_help(&help, avail_chars);
} else { } else {
sdebugln!("No"); debug!("No");
} }
if let Some(part) = help.lines().next() { if let Some(part) = help.lines().next() {
self.none(part)?; self.none(part)?;
@ -623,7 +620,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes help for all arguments (options, flags, args, subcommands) /// Writes help for all arguments (options, flags, args, subcommands)
/// including titles of a Parser Object to the wrapped stream. /// including titles of a Parser Object to the wrapped stream.
pub(crate) fn write_all_args(&mut self) -> ClapResult<()> { pub(crate) fn write_all_args(&mut self) -> ClapResult<()> {
debugln!("Help::write_all_args;"); debug!("Help::write_all_args");
let flags = self.parser.has_flags(); let flags = self.parser.has_flags();
// Strange filter/count vs fold... https://github.com/rust-lang/rust/issues/33038 // Strange filter/count vs fold... https://github.com/rust-lang/rust/issues/33038
let pos = positionals!(self.parser.app).fold(0, |acc, arg| { let pos = positionals!(self.parser.app).fold(0, |acc, arg| {
@ -729,7 +726,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes help for subcommands of a Parser Object to the wrapped stream. /// Writes help for subcommands of a Parser Object to the wrapped stream.
fn write_subcommands(&mut self, app: &App<'b>) -> io::Result<()> { fn write_subcommands(&mut self, app: &App<'b>) -> io::Result<()> {
debugln!("Help::write_subcommands;"); debug!("Help::write_subcommands");
// The shortest an arg can legally be is 2 (i.e. '-x') // The shortest an arg can legally be is 2 (i.e. '-x')
self.longest = 2; self.longest = 2;
let mut ord_m = VecMap::new(); let mut ord_m = VecMap::new();
@ -759,14 +756,14 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes version of a Parser Object to the wrapped stream. /// Writes version of a Parser Object to the wrapped stream.
fn write_version(&mut self) -> io::Result<()> { fn write_version(&mut self) -> io::Result<()> {
debugln!("Help::write_version;"); debug!("Help::write_version");
self.none(self.parser.app.version.unwrap_or(""))?; self.none(self.parser.app.version.unwrap_or(""))?;
Ok(()) Ok(())
} }
/// Writes binary name of a Parser Object to the wrapped stream. /// Writes binary name of a Parser Object to the wrapped stream.
fn write_bin_name(&mut self) -> io::Result<()> { fn write_bin_name(&mut self) -> io::Result<()> {
debugln!("Help::write_bin_name;"); debug!("Help::write_bin_name");
let term_w = self.term_w; let term_w = self.term_w;
macro_rules! write_name { macro_rules! write_name {
() => {{ () => {{
@ -788,7 +785,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// Writes default help for a Parser Object to the wrapped stream. /// Writes default help for a Parser Object to the wrapped stream.
pub(crate) fn write_default_help(&mut self) -> ClapResult<()> { pub(crate) fn write_default_help(&mut self) -> ClapResult<()> {
debugln!("Help::write_default_help;"); debug!("Help::write_default_help");
if let Some(h) = self.parser.app.pre_help { if let Some(h) = self.parser.app.pre_help {
self.write_before_after_help(h)?; self.write_before_after_help(h)?;
self.none("\n\n")?; self.none("\n\n")?;
@ -812,10 +809,10 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
if self.use_long && self.parser.app.long_about.is_some() { if self.use_long && self.parser.app.long_about.is_some() {
debugln!("Help::write_default_help: writing long about"); debug!("Help::write_default_help: writing long about");
write_thing!(self.parser.app.long_about.unwrap()); write_thing!(self.parser.app.long_about.unwrap());
} else if self.parser.app.about.is_some() { } else if self.parser.app.about.is_some() {
debugln!("Help::write_default_help: writing about"); debug!("Help::write_default_help: writing about");
write_thing!(self.parser.app.about.unwrap()); write_thing!(self.parser.app.about.unwrap());
} }
@ -861,7 +858,7 @@ enum CopyUntilResult {
/// On success, the total number of bytes that were /// On success, the total number of bytes that were
/// copied from reader to writer is returned. /// copied from reader to writer is returned.
fn copy_until<R: Read, W: Write>(r: &mut R, w: &mut W, delimiter_byte: u8) -> CopyUntilResult { fn copy_until<R: Read, W: Write>(r: &mut R, w: &mut W, delimiter_byte: u8) -> CopyUntilResult {
debugln!("copy_until;"); debug!("copy_until");
let mut count = 0; let mut count = 0;
for wb in r.bytes() { for wb in r.bytes() {
@ -897,7 +894,7 @@ fn copy_and_capture<R: Read, W: Write>(
tag_buffer: &mut Cursor<Vec<u8>>, tag_buffer: &mut Cursor<Vec<u8>>,
) -> Option<io::Result<usize>> { ) -> Option<io::Result<usize>> {
use self::CopyUntilResult::*; use self::CopyUntilResult::*;
debugln!("copy_and_capture;"); debug!("copy_and_capture");
// Find the opening byte. // Find the opening byte.
match copy_until(r, w, b'{') { match copy_until(r, w, b'{') {
@ -967,7 +964,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
/// The template system is, on purpose, very simple. Therefore the tags have to be written /// The template system is, on purpose, very simple. Therefore the tags have to be written
/// in the lowercase and without spacing. /// in the lowercase and without spacing.
fn write_templated_help(&mut self, template: &str) -> ClapResult<()> { fn write_templated_help(&mut self, template: &str) -> ClapResult<()> {
debugln!("Help::write_templated_help;"); debug!("Help::write_templated_help");
let mut tmplr = Cursor::new(&template); let mut tmplr = Cursor::new(&template);
let mut tag_buf = Cursor::new(vec![0u8; 15]); let mut tag_buf = Cursor::new(vec![0u8; 15]);
@ -985,8 +982,8 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
_ => continue, _ => continue,
}; };
debugln!( debug!(
"Help::write_template_help:iter: tag_buf={};", "Help::write_template_help:iter: tag_buf={}",
String::from_utf8_lossy(&tag_buf.get_ref()[0..tag_length]) String::from_utf8_lossy(&tag_buf.get_ref()[0..tag_length])
); );
match &tag_buf.get_ref()[0..tag_length] { match &tag_buf.get_ref()[0..tag_length] {
@ -1055,11 +1052,7 @@ impl<'b, 'c, 'd, 'w> Help<'b, 'c, 'd, 'w> {
} }
fn should_show_arg(use_long: bool, arg: &Arg) -> bool { fn should_show_arg(use_long: bool, arg: &Arg) -> bool {
debugln!( debug!("should_show_arg: use_long={:?}, arg={}", use_long, arg.name);
"Help::should_show_arg: use_long={:?}, arg={}",
use_long,
arg.name
);
if arg.is_set(ArgSettings::Hidden) { if arg.is_set(ArgSettings::Hidden) {
return false; return false;
} }

View file

@ -24,7 +24,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
// Creates a usage string for display. This happens just after all arguments were parsed, but before // Creates a usage string for display. This happens just after all arguments were parsed, but before
// any subcommands have been parsed (so as to give subcommands their own usage recursively) // any subcommands have been parsed (so as to give subcommands their own usage recursively)
pub(crate) fn create_usage_with_title(&self, used: &[Id]) -> String { pub(crate) fn create_usage_with_title(&self, used: &[Id]) -> String {
debugln!("usage::create_usage_with_title;"); debug!("Usage::create_usage_with_title");
let mut usage = String::with_capacity(75); let mut usage = String::with_capacity(75);
usage.push_str("USAGE:\n "); usage.push_str("USAGE:\n ");
usage.push_str(&*self.create_usage_no_title(used)); usage.push_str(&*self.create_usage_no_title(used));
@ -33,7 +33,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
// Creates a usage string (*without title*) if one was not provided by the user manually. // Creates a usage string (*without title*) if one was not provided by the user manually.
pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> String { pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> String {
debugln!("usage::create_usage_no_title;"); debug!("Usage::create_usage_no_title");
if let Some(u) = self.p.app.usage_str { if let Some(u) = self.p.app.usage_str {
String::from(&*u) String::from(&*u)
} else if used.is_empty() { } else if used.is_empty() {
@ -45,7 +45,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
// Creates a usage string for display in help messages (i.e. not for errors) // Creates a usage string for display in help messages (i.e. not for errors)
pub(crate) fn create_help_usage(&self, incl_reqs: bool) -> String { pub(crate) fn create_help_usage(&self, incl_reqs: bool) -> String {
debugln!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs); debug!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs);
let mut usage = String::with_capacity(75); let mut usage = String::with_capacity(75);
let name = self let name = self
.p .p
@ -102,7 +102,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
let pos = positionals!(self.p.app) let pos = positionals!(self.p.app)
.find(|p| p.is_set(ArgSettings::Last)) .find(|p| p.is_set(ArgSettings::Last))
.expect(INTERNAL_ERROR_MSG); .expect(INTERNAL_ERROR_MSG);
debugln!("Usage::create_help_usage: '{}' has .last(true)", pos.name); debug!("Usage::create_help_usage: '{}' has .last(true)", pos.name);
let req = pos.is_set(ArgSettings::Required); let req = pos.is_set(ArgSettings::Required);
if req && positionals!(self.p.app).any(|p| !p.is_set(ArgSettings::Required)) { if req && positionals!(self.p.app).any(|p| !p.is_set(ArgSettings::Required)) {
usage.push_str(" -- <"); usage.push_str(" -- <");
@ -144,14 +144,14 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
} }
} }
usage.shrink_to_fit(); usage.shrink_to_fit();
debugln!("usage::create_help_usage: usage={}", usage); debug!("Usage::create_help_usage: usage={}", usage);
usage usage
} }
// Creates a context aware usage string, or "smart usage" from currently used // Creates a context aware usage string, or "smart usage" from currently used
// args, and requirements // args, and requirements
fn create_smart_usage(&self, used: &[Id]) -> String { fn create_smart_usage(&self, used: &[Id]) -> String {
debugln!("usage::smart_usage;"); debug!("Usage::create_smart_usage");
let mut usage = String::with_capacity(75); let mut usage = String::with_capacity(75);
let r_string = self let r_string = self
@ -177,16 +177,16 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
// Gets the `[ARGS]` tag for the usage string // Gets the `[ARGS]` tag for the usage string
fn get_args_tag(&self, incl_reqs: bool) -> Option<String> { fn get_args_tag(&self, incl_reqs: bool) -> Option<String> {
debugln!("usage::get_args_tag; incl_reqs = {:?}", incl_reqs); debug!("Usage::get_args_tag; incl_reqs = {:?}", incl_reqs);
let mut count = 0; let mut count = 0;
'outer: for pos in positionals!(self.p.app) 'outer: for pos in positionals!(self.p.app)
.filter(|pos| !pos.is_set(ArgSettings::Required)) .filter(|pos| !pos.is_set(ArgSettings::Required))
.filter(|pos| !pos.is_set(ArgSettings::Hidden)) .filter(|pos| !pos.is_set(ArgSettings::Hidden))
.filter(|pos| !pos.is_set(ArgSettings::Last)) .filter(|pos| !pos.is_set(ArgSettings::Last))
{ {
debugln!("usage::get_args_tag:iter:{}:", pos.name); debug!("Usage::get_args_tag:iter:{}", pos.name);
for grp_s in groups_for_arg!(self.p.app, pos.id) { for grp_s in groups_for_arg!(self.p.app, pos.id) {
debugln!("usage::get_args_tag:iter:{:?}:iter:{:?};", pos.name, grp_s); debug!("Usage::get_args_tag:iter:{:?}:iter:{:?}", pos.name, grp_s);
// if it's part of a required group we don't want to count it // if it's part of a required group we don't want to count it
if self if self
.p .p
@ -199,13 +199,13 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
} }
} }
count += 1; count += 1;
debugln!( debug!(
"usage::get_args_tag:iter: {} Args not required or hidden", "Usage::get_args_tag:iter: {} Args not required or hidden",
count count
); );
} }
if !self.p.is_set(AS::DontCollapseArgsInUsage) && count > 1 { if !self.p.is_set(AS::DontCollapseArgsInUsage) && count > 1 {
debugln!("usage::get_args_tag:iter: More than one, returning [ARGS]"); debug!("Usage::get_args_tag:iter: More than one, returning [ARGS]");
return None; // [ARGS] return None; // [ARGS]
} else if count == 1 && incl_reqs { } else if count == 1 && incl_reqs {
let pos = positionals!(self.p.app) let pos = positionals!(self.p.app)
@ -215,8 +215,8 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
&& !pos.is_set(ArgSettings::Last) && !pos.is_set(ArgSettings::Last)
}) })
.expect(INTERNAL_ERROR_MSG); .expect(INTERNAL_ERROR_MSG);
debugln!( debug!(
"usage::get_args_tag:iter: Exactly one, returning '{}'", "Usage::get_args_tag:iter: Exactly one, returning '{}'",
pos.name pos.name
); );
return Some(format!( return Some(format!(
@ -228,7 +228,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
&& self.p.has_positionals() && self.p.has_positionals()
&& incl_reqs && incl_reqs
{ {
debugln!("usage::get_args_tag:iter: Don't collapse returning all"); debug!("Usage::get_args_tag:iter: Don't collapse returning all");
return Some( return Some(
positionals!(self.p.app) positionals!(self.p.app)
.filter(|pos| !pos.is_set(ArgSettings::Required)) .filter(|pos| !pos.is_set(ArgSettings::Required))
@ -239,7 +239,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
.join(""), .join(""),
); );
} else if !incl_reqs { } else if !incl_reqs {
debugln!("usage::get_args_tag:iter: incl_reqs=false, building secondary usage string"); debug!("Usage::get_args_tag:iter: incl_reqs=false, building secondary usage string");
let highest_req_pos = positionals!(self.p.app) let highest_req_pos = positionals!(self.p.app)
.filter_map(|pos| { .filter_map(|pos| {
if pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Last) { if pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Last) {
@ -272,9 +272,9 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
// Determines if we need the `[FLAGS]` tag in the usage string // Determines if we need the `[FLAGS]` tag in the usage string
fn needs_flags_tag(&self) -> bool { fn needs_flags_tag(&self) -> bool {
debugln!("usage::needs_flags_tag;"); debug!("Usage::needs_flags_tag");
'outer: for f in flags!(self.p.app) { 'outer: for f in flags!(self.p.app) {
debugln!("usage::needs_flags_tag:iter: f={};", f.name); debug!("Usage::needs_flags_tag:iter: f={}", f.name);
if let Some(l) = f.long { if let Some(l) = f.long {
if l == "help" || l == "version" { if l == "help" || l == "version" {
// Don't print `[FLAGS]` just for help or version // Don't print `[FLAGS]` just for help or version
@ -282,7 +282,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
} }
} }
for grp_s in groups_for_arg!(self.p.app, f.id) { for grp_s in groups_for_arg!(self.p.app, f.id) {
debugln!("usage::needs_flags_tag:iter:iter: grp_s={:?};", grp_s); debug!("Usage::needs_flags_tag:iter:iter: grp_s={:?}", grp_s);
if self if self
.p .p
.app .app
@ -290,18 +290,18 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
.iter() .iter()
.any(|g| g.id == grp_s && g.required) .any(|g| g.id == grp_s && g.required)
{ {
debugln!("usage::needs_flags_tag:iter:iter: Group is required"); debug!("Usage::needs_flags_tag:iter:iter: Group is required");
continue 'outer; continue 'outer;
} }
} }
if f.is_set(ArgSettings::Hidden) { if f.is_set(ArgSettings::Hidden) {
continue; continue;
} }
debugln!("usage::needs_flags_tag:iter: [FLAGS] required"); debug!("Usage::needs_flags_tag:iter: [FLAGS] required");
return true; return true;
} }
debugln!("usage::needs_flags_tag: [FLAGS] not required"); debug!("Usage::needs_flags_tag: [FLAGS] not required");
false false
} }
@ -315,7 +315,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
matcher: Option<&ArgMatcher>, matcher: Option<&ArgMatcher>,
incl_last: bool, incl_last: bool,
) -> VecDeque<String> { ) -> VecDeque<String> {
debugln!( debug!(
"Usage::get_required_usage_from: incls={:?}, matcher={:?}, incl_last={:?}", "Usage::get_required_usage_from: incls={:?}, matcher={:?}, incl_last={:?}",
incls, incls,
matcher.is_some(), matcher.is_some(),
@ -367,7 +367,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
.collect::<BTreeMap<u64, &Arg>>() // sort by index .collect::<BTreeMap<u64, &Arg>>() // sort by index
}; };
for p in pmap.values() { for p in pmap.values() {
debugln!("Usage::get_required_usage_from:iter:{:?}", p.id); debug!("Usage::get_required_usage_from:iter:{:?}", p.id);
if args_in_groups.is_empty() || !args_in_groups.contains(&p.id) { if args_in_groups.is_empty() || !args_in_groups.contains(&p.id) {
ret_val.push_back(p.to_string()); ret_val.push_back(p.to_string());
} }
@ -380,7 +380,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
.filter(|name| !args_in_groups.contains(name)) .filter(|name| !args_in_groups.contains(name))
.filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name))) .filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name)))
{ {
debugln!("Usage::get_required_usage_from:iter:{:?}:", a); debug!("Usage::get_required_usage_from:iter:{:?}", a);
let arg = self let arg = self
.p .p
.app .app
@ -403,7 +403,7 @@ impl<'b, 'c, 'z> Usage<'b, 'c, 'z> {
ret_val.push_back(g); ret_val.push_back(g);
} }
debugln!("Usage::get_required_usage_from: ret_val={:?}", ret_val); debug!("Usage::get_required_usage_from: ret_val={:?}", ret_val);
ret_val ret_val
} }
} }

View file

@ -31,7 +31,7 @@ impl ArgMatcher {
} }
pub(crate) fn propagate_globals(&mut self, global_arg_vec: &[Id]) { pub(crate) fn propagate_globals(&mut self, global_arg_vec: &[Id]) {
debugln!( debug!(
"ArgMatcher::get_global_values: global_arg_vec={:?}", "ArgMatcher::get_global_values: global_arg_vec={:?}",
global_arg_vec global_arg_vec
); );
@ -127,12 +127,12 @@ impl ArgMatcher {
} }
pub(crate) fn inc_occurrence_of(&mut self, arg: &Id) { pub(crate) fn inc_occurrence_of(&mut self, arg: &Id) {
debugln!("ArgMatcher::inc_occurrence_of: arg={:?}", arg); debug!("ArgMatcher::inc_occurrence_of: arg={:?}", arg);
if let Some(a) = self.get_mut(arg) { if let Some(a) = self.get_mut(arg) {
a.occurs += 1; a.occurs += 1;
return; return;
} }
debugln!("ArgMatcher::inc_occurrence_of: first instance"); debug!("ArgMatcher::inc_occurrence_of: first instance");
self.insert(arg); self.insert(arg);
} }
@ -155,20 +155,20 @@ impl ArgMatcher {
} }
pub(crate) fn needs_more_vals(&self, o: &Arg) -> bool { pub(crate) fn needs_more_vals(&self, o: &Arg) -> bool {
debugln!("ArgMatcher::needs_more_vals: o={}", o.name); debug!("ArgMatcher::needs_more_vals: o={}", o.name);
if let Some(ma) = self.get(&o.id) { if let Some(ma) = self.get(&o.id) {
if let Some(num) = o.num_vals { if let Some(num) = o.num_vals {
debugln!("ArgMatcher::needs_more_vals: num_vals...{}", num); debug!("ArgMatcher::needs_more_vals: num_vals...{}", num);
return if o.is_set(ArgSettings::MultipleValues) { return if o.is_set(ArgSettings::MultipleValues) {
((ma.vals.len() as u64) % num) != 0 ((ma.vals.len() as u64) % num) != 0
} else { } else {
num != (ma.vals.len() as u64) num != (ma.vals.len() as u64)
}; };
} else if let Some(num) = o.max_vals { } else if let Some(num) = o.max_vals {
debugln!("ArgMatcher::needs_more_vals: max_vals...{}", num); debug!("ArgMatcher::needs_more_vals: max_vals...{}", num);
return (ma.vals.len() as u64) < num; return (ma.vals.len() as u64) < num;
} else if o.min_vals.is_some() { } else if o.min_vals.is_some() {
debugln!("ArgMatcher::needs_more_vals: min_vals...true"); debug!("ArgMatcher::needs_more_vals: min_vals...true");
return true; return true;
} }
return o.is_set(ArgSettings::MultipleValues); return o.is_set(ArgSettings::MultipleValues);

View file

@ -127,7 +127,7 @@ where
} }
fn _verify_positionals(&self) -> bool { fn _verify_positionals(&self) -> bool {
debugln!("Parser::_verify_positionals;"); debug!("Parser::_verify_positionals");
// Because you must wait until all arguments have been supplied, this is the first chance // Because you must wait until all arguments have been supplied, this is the first chance
// to make assertions on positional argument indexes // to make assertions on positional argument indexes
// //
@ -335,7 +335,7 @@ where
#[allow(clippy::block_in_if_condition_stmt)] #[allow(clippy::block_in_if_condition_stmt)]
// Does all the initializing and prepares the parser // Does all the initializing and prepares the parser
pub(crate) fn _build(&mut self) { pub(crate) fn _build(&mut self) {
debugln!("Parser::_build;"); debug!("Parser::_build");
//I wonder whether this part is even needed if we insert all Args using make_entries //I wonder whether this part is even needed if we insert all Args using make_entries
let mut key: Vec<(KeyType, usize)> = Vec::new(); let mut key: Vec<(KeyType, usize)> = Vec::new();
@ -349,7 +349,7 @@ where
// Add args with default requirements // Add args with default requirements
if a.is_set(ArgSettings::Required) { if a.is_set(ArgSettings::Required) {
debugln!("Parser::_build: adding {} to default requires", a.name); debug!("Parser::_build: adding {} to default requires", a.name);
let idx = self.required.insert(a.id.clone()); let idx = self.required.insert(a.id.clone());
// If the arg is required, add all it's requirements to master required list // If the arg is required, add all it's requirements to master required list
if let Some(ref areqs) = a.requires { if let Some(ref areqs) = a.requires {
@ -417,7 +417,7 @@ where
matcher: &mut ArgMatcher, matcher: &mut ArgMatcher,
it: &mut Input, it: &mut Input,
) -> ClapResult<()> { ) -> ClapResult<()> {
debugln!("Parser::get_matches_with;"); debug!("Parser::get_matches_with");
// Verify all positional assertions pass // Verify all positional assertions pass
self._build(); self._build();
@ -431,7 +431,7 @@ where
while let Some((arg_os, next_arg)) = it.next(replace) { while let Some((arg_os, next_arg)) = it.next(replace) {
replace = None; replace = None;
debugln!( debug!(
"Parser::get_matches_with: Begin parsing '{:?}' ({:?})", "Parser::get_matches_with: Begin parsing '{:?}' ({:?})",
arg_os, arg_os,
&*arg_os.as_bytes() &*arg_os.as_bytes()
@ -441,7 +441,10 @@ where
let key_bytes = OsStr::new(key).as_bytes(); let key_bytes = OsStr::new(key).as_bytes();
if key_bytes == arg_os.as_bytes() { if key_bytes == arg_os.as_bytes() {
debugln!("found replacer: {:?}, target: {:?}", key, val); debug!(
"Parser::get_matches_with: found replacer: {:?}, target: {:?}",
key, val
);
replace = Some(val); replace = Some(val);
} }
} }
@ -460,7 +463,7 @@ where
&& arg_os.len() == 2 && arg_os.len() == 2
&& starts_new_arg && starts_new_arg
{ {
debugln!("Parser::get_matches_with: setting TrailingVals=true"); debug!("Parser::get_matches_with: setting TrailingVals=true");
self.set(AS::TrailingValues); self.set(AS::TrailingValues);
continue; continue;
} }
@ -473,7 +476,7 @@ where
if !self.is_set(AS::SubcommandPrecedenceOverArg) => {} if !self.is_set(AS::SubcommandPrecedenceOverArg) => {}
_ => { _ => {
let sc_name = self.possible_subcommand(arg_os); let sc_name = self.possible_subcommand(arg_os);
debugln!( debug!(
"Parser::get_matches_with: possible_sc={:?}, sc={:?}", "Parser::get_matches_with: possible_sc={:?}, sc={:?}",
sc_name.is_some(), sc_name.is_some(),
sc_name sc_name
@ -495,8 +498,8 @@ where
if starts_new_arg { if starts_new_arg {
if arg_os.starts_with(b"--") { if arg_os.starts_with(b"--") {
needs_val_of = self.parse_long_arg(matcher, arg_os)?; needs_val_of = self.parse_long_arg(matcher, arg_os)?;
debugln!( debug!(
"Parser:get_matches_with: After parse_long_arg {:?}", "Parser::get_matches_with: After parse_long_arg {:?}",
needs_val_of needs_val_of
); );
match needs_val_of { match needs_val_of {
@ -511,8 +514,8 @@ where
// an error, and instead return Ok(None) // an error, and instead return Ok(None)
needs_val_of = self.parse_short_arg(matcher, arg_os)?; needs_val_of = self.parse_short_arg(matcher, arg_os)?;
// If it's None, we then check if one of those two AppSettings was set // If it's None, we then check if one of those two AppSettings was set
debugln!( debug!(
"Parser:get_matches_with: After parse_short_arg {:?}", "Parser::get_matches_with: After parse_short_arg {:?}",
needs_val_of needs_val_of
); );
match needs_val_of { match needs_val_of {
@ -584,11 +587,11 @@ where
&& is_second_to_last && is_second_to_last
&& !self.is_set(AS::TrailingValues); && !self.is_set(AS::TrailingValues);
debugln!( debug!(
"Parser::get_matches_with: Positional counter...{}", "Parser::get_matches_with: Positional counter...{}",
pos_counter pos_counter
); );
debugln!( debug!(
"Parser::get_matches_with: Low index multiples...{:?}", "Parser::get_matches_with: Low index multiples...{:?}",
low_index_mults low_index_mults
); );
@ -614,11 +617,11 @@ where
|| !suggestions::did_you_mean(&n.to_string_lossy(), sc_names!(self.app)) || !suggestions::did_you_mean(&n.to_string_lossy(), sc_names!(self.app))
.is_empty() .is_empty()
{ {
debugln!("Parser::get_matches_with: Bumping the positional counter..."); debug!("Parser::get_matches_with: Bumping the positional counter...");
pos_counter += 1; pos_counter += 1;
} }
} else { } else {
debugln!("Parser::get_matches_with: Bumping the positional counter..."); debug!("Parser::get_matches_with: Bumping the positional counter...");
pos_counter += 1; pos_counter += 1;
} }
} else if (self.is_set(AS::AllowMissingPositional) && self.is_set(AS::TrailingValues)) } else if (self.is_set(AS::AllowMissingPositional) && self.is_set(AS::TrailingValues))
@ -626,7 +629,7 @@ where
{ {
// Came to -- and one postional has .last(true) set, so we go immediately // Came to -- and one postional has .last(true) set, so we go immediately
// to the last (highest index) positional // to the last (highest index) positional
debugln!("Parser::get_matches_with: .last(true) and --, setting last pos"); debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
pos_counter = self pos_counter = self
.app .app
.args .args
@ -780,7 +783,7 @@ where
self.app.color(), self.app.color(),
)?); )?);
} else if self.is_set(AS::SubcommandRequiredElseHelp) { } else if self.is_set(AS::SubcommandRequiredElseHelp) {
debugln!("Parser::get_matches_with: SubcommandRequiredElseHelp=true"); debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true");
let message = self.write_help_err()?; let message = self.write_help_err()?;
return Err(ClapError { return Err(ClapError {
cause: String::new(), cause: String::new(),
@ -797,7 +800,7 @@ where
// Should we color the help? // Should we color the help?
pub(crate) fn color_help(&self) -> ColorChoice { pub(crate) fn color_help(&self) -> ColorChoice {
debugln!("App::color_help;"); debug!("Parser::color_help");
if self.is_set(AS::ColoredHelp) { if self.is_set(AS::ColoredHelp) {
self.app.color() self.app.color()
@ -808,7 +811,7 @@ where
// Checks if the arg matches a subcommand name, or any of it's aliases (if defined) // Checks if the arg matches a subcommand name, or any of it's aliases (if defined)
fn possible_subcommand(&self, arg_os: &OsStr) -> Option<&str> { fn possible_subcommand(&self, arg_os: &OsStr) -> Option<&str> {
debugln!("Parser::possible_subcommand: arg={:?}", arg_os); debug!("Parser::possible_subcommand: arg={:?}", arg_os);
fn starts(h: &str, n: &OsStr) -> bool { fn starts(h: &str, n: &OsStr) -> bool {
let n_bytes = n.as_bytes(); let n_bytes = n.as_bytes();
let h_bytes = OsStr::new(h).as_bytes(); let h_bytes = OsStr::new(h).as_bytes();
@ -844,7 +847,7 @@ where
} }
fn parse_help_subcommand(&self, cmds: &[OsString]) -> ClapResult<ParseResult> { fn parse_help_subcommand(&self, cmds: &[OsString]) -> ClapResult<ParseResult> {
debugln!("Parser::parse_help_subcommand;"); debug!("Parser::parse_help_subcommand");
let mut help_help = false; let mut help_help = false;
let mut bin_name = self.app.bin_name.as_ref().unwrap_or(&self.app.name).clone(); let mut bin_name = self.app.bin_name.as_ref().unwrap_or(&self.app.name).clone();
@ -914,7 +917,7 @@ where
} }
fn is_new_arg(&mut self, arg_os: &OsStr, needs_val_of: ParseResult) -> bool { fn is_new_arg(&mut self, arg_os: &OsStr, needs_val_of: ParseResult) -> bool {
debugln!("Parser::is_new_arg:{:?}:{:?}", arg_os, needs_val_of); debug!("Parser::is_new_arg: {:?}:{:?}", arg_os, needs_val_of);
let app_wide_settings = if self.is_set(AS::AllowLeadingHyphen) { let app_wide_settings = if self.is_set(AS::AllowLeadingHyphen) {
true true
@ -944,11 +947,11 @@ where
_ => false, _ => false,
}; };
debugln!("Parser::is_new_arg: arg_allows_tac={:?}", arg_allows_tac); debug!("Parser::is_new_arg: arg_allows_tac={:?}", arg_allows_tac);
// Is this a new argument, or values from a previous option? // Is this a new argument, or values from a previous option?
let mut ret = if arg_os.starts_with(b"--") { let mut ret = if arg_os.starts_with(b"--") {
debugln!("Parser::is_new_arg: -- found"); debug!("Parser::is_new_arg: -- found");
if arg_os.len() == 2 && !arg_allows_tac { if arg_os.len() == 2 && !arg_allows_tac {
return true; // We have to return true so override everything else return true; // We have to return true so override everything else
@ -958,17 +961,17 @@ where
true true
} else if arg_os.starts_with(b"-") { } else if arg_os.starts_with(b"-") {
debugln!("Parser::is_new_arg: - found"); debug!("Parser::is_new_arg: - found");
// a singe '-' by itself is a value and typically means "stdin" on unix systems // a singe '-' by itself is a value and typically means "stdin" on unix systems
arg_os.len() != 1 arg_os.len() != 1
} else { } else {
debugln!("Parser::is_new_arg: probably value"); debug!("Parser::is_new_arg: probably value");
false false
}; };
ret = ret && !arg_allows_tac; ret = ret && !arg_allows_tac;
debugln!("Parser::is_new_arg: starts_new_arg={:?}", ret); debug!("Parser::is_new_arg: starts_new_arg={:?}", ret);
ret ret
} }
@ -980,7 +983,7 @@ where
) -> ClapResult<()> { ) -> ClapResult<()> {
use std::fmt::Write; use std::fmt::Write;
debugln!("Parser::parse_subcommand;"); debug!("Parser::parse_subcommand");
let mut mid_string = String::new(); let mut mid_string = String::new();
@ -1022,7 +1025,7 @@ where
// Ensure all args are built and ready to parse // Ensure all args are built and ready to parse
sc._build(); sc._build();
debugln!("Parser::parse_subcommand: About to parse sc={}", sc.name); debug!("Parser::parse_subcommand: About to parse sc={}", sc.name);
{ {
let mut p = Parser::new(sc); let mut p = Parser::new(sc);
@ -1041,7 +1044,7 @@ where
// Retrieves the names of all args the user has supplied thus far, except required ones // Retrieves the names of all args the user has supplied thus far, except required ones
// because those will be listed in self.required // because those will be listed in self.required
fn check_for_help_and_version_str(&self, arg: &OsStr) -> ClapResult<()> { fn check_for_help_and_version_str(&self, arg: &OsStr) -> ClapResult<()> {
debugln!("Parser::check_for_help_and_version_str;"); debug!("Parser::check_for_help_and_version_str");
debug!( debug!(
"Parser::check_for_help_and_version_str: Checking if --{} is help or version...", "Parser::check_for_help_and_version_str: Checking if --{} is help or version...",
arg.to_str().unwrap() arg.to_str().unwrap()
@ -1050,20 +1053,20 @@ where
// Needs to use app.settings.is_set instead of just is_set() because is_set() checks // Needs to use app.settings.is_set instead of just is_set() because is_set() checks
// both global and local settings, we only want to check local // both global and local settings, we only want to check local
if arg == "help" && !self.app.settings.is_set(AS::NoAutoHelp) { if arg == "help" && !self.app.settings.is_set(AS::NoAutoHelp) {
sdebugln!("Help"); debug!("Help");
return Err(self.help_err(true)); return Err(self.help_err(true));
} }
if arg == "version" && !self.app.settings.is_set(AS::NoAutoVersion) { if arg == "version" && !self.app.settings.is_set(AS::NoAutoVersion) {
sdebugln!("Version"); debug!("Version");
return Err(self.version_err(true)); return Err(self.version_err(true));
} }
sdebugln!("Neither"); debug!("Neither");
Ok(()) Ok(())
} }
fn check_for_help_and_version_char(&self, arg: char) -> ClapResult<()> { fn check_for_help_and_version_char(&self, arg: char) -> ClapResult<()> {
debugln!("Parser::check_for_help_and_version_char;"); debug!("Parser::check_for_help_and_version_char");
debug!( debug!(
"Parser::check_for_help_and_version_char: Checking if -{} is help or version...", "Parser::check_for_help_and_version_char: Checking if -{} is help or version...",
arg arg
@ -1073,7 +1076,7 @@ where
if let Some(help) = self.app.find(&Id::help_hash()) { if let Some(help) = self.app.find(&Id::help_hash()) {
if let Some(h) = help.short { if let Some(h) = help.short {
if arg == h && !self.app.settings.is_set(AS::NoAutoHelp) { if arg == h && !self.app.settings.is_set(AS::NoAutoHelp) {
sdebugln!("Help"); debug!("Help");
return Err(self.help_err(false)); return Err(self.help_err(false));
} }
} }
@ -1081,17 +1084,17 @@ where
if let Some(version) = self.app.find(&Id::version_hash()) { if let Some(version) = self.app.find(&Id::version_hash()) {
if let Some(v) = version.short { if let Some(v) = version.short {
if arg == v && !self.app.settings.is_set(AS::NoAutoVersion) { if arg == v && !self.app.settings.is_set(AS::NoAutoVersion) {
sdebugln!("Version"); debug!("Version");
return Err(self.version_err(false)); return Err(self.version_err(false));
} }
} }
} }
sdebugln!("Neither"); debug!("Neither");
Ok(()) Ok(())
} }
fn use_long_help(&self) -> bool { fn use_long_help(&self) -> bool {
debugln!("Parser::use_long_help;"); debug!("Parser::use_long_help");
// In this case, both must be checked. This allows the retention of // In this case, both must be checked. This allows the retention of
// original formatting, but also ensures that the actual -h or --help // original formatting, but also ensures that the actual -h or --help
// specified by the user is sent through. If HiddenShortHelp is not included, // specified by the user is sent through. If HiddenShortHelp is not included,
@ -1113,7 +1116,7 @@ where
full_arg: &OsStr, full_arg: &OsStr,
) -> ClapResult<ParseResult> { ) -> ClapResult<ParseResult> {
// maybe here lifetime should be 'a // maybe here lifetime should be 'a
debugln!("Parser::parse_long_arg;"); debug!("Parser::parse_long_arg");
// Update the curent index // Update the curent index
self.cur_idx.set(self.cur_idx.get() + 1); self.cur_idx.set(self.cur_idx.get() + 1);
@ -1122,15 +1125,15 @@ where
debug!("Parser::parse_long_arg: Does it contain '='..."); debug!("Parser::parse_long_arg: Does it contain '='...");
let arg = if full_arg.contains_byte(b'=') { let arg = if full_arg.contains_byte(b'=') {
let (p0, p1) = full_arg.trim_start_matches(b'-').split_at_byte(b'='); let (p0, p1) = full_arg.trim_start_matches(b'-').split_at_byte(b'=');
sdebugln!("Yes '{:?}'", p1); debug!("Yes '{:?}'", p1);
val = Some(p1); val = Some(p1);
p0 p0
} else { } else {
sdebugln!("No"); debug!("No");
full_arg.trim_start_matches(b'-') full_arg.trim_start_matches(b'-')
}; };
if let Some(opt) = self.app.args.get(&KeyType::Long(arg.into())) { if let Some(opt) = self.app.args.get(&KeyType::Long(arg.into())) {
debugln!( debug!(
"Parser::parse_long_arg: Found valid opt or flag '{}'", "Parser::parse_long_arg: Found valid opt or flag '{}'",
opt.to_string() opt.to_string()
); );
@ -1151,7 +1154,7 @@ where
return Ok(ParseResult::MaybeNegNum); return Ok(ParseResult::MaybeNegNum);
} }
debugln!("Parser::parse_long_arg: Didn't match anything"); debug!("Parser::parse_long_arg: Didn't match anything");
self.did_you_mean_error(arg.to_str().expect(INVALID_UTF8), matcher) self.did_you_mean_error(arg.to_str().expect(INVALID_UTF8), matcher)
.map(|_| ParseResult::NotFound) .map(|_| ParseResult::NotFound)
} }
@ -1161,7 +1164,7 @@ where
matcher: &mut ArgMatcher, matcher: &mut ArgMatcher,
full_arg: &OsStr, full_arg: &OsStr,
) -> ClapResult<ParseResult> { ) -> ClapResult<ParseResult> {
debugln!("Parser::parse_short_arg: full_arg={:?}", full_arg); debug!("Parser::parse_short_arg: full_arg={:?}", full_arg);
let arg_os = full_arg.trim_start_matches(b'-'); let arg_os = full_arg.trim_start_matches(b'-');
let arg = arg_os.to_string_lossy(); let arg = arg_os.to_string_lossy();
@ -1169,7 +1172,7 @@ where
// `-v` `-a` `-l` assuming `v` `a` and `l` are all, or mostly, valid shorts. // `-v` `-a` `-l` assuming `v` `a` and `l` are all, or mostly, valid shorts.
if self.is_set(AS::AllowLeadingHyphen) { if self.is_set(AS::AllowLeadingHyphen) {
if arg.chars().any(|c| !self.contains_short(c)) { if arg.chars().any(|c| !self.contains_short(c)) {
debugln!( debug!(
"Parser::parse_short_arg: LeadingHyphenAllowed yet -{} isn't valid", "Parser::parse_short_arg: LeadingHyphenAllowed yet -{} isn't valid",
arg arg
); );
@ -1178,13 +1181,13 @@ where
} else if self.is_set(AS::ValidNegNumFound) { } else if self.is_set(AS::ValidNegNumFound) {
// TODO: Add docs about having AllowNegativeNumbers and `-2` as a valid short // TODO: Add docs about having AllowNegativeNumbers and `-2` as a valid short
// May be better to move this to *after* not finding a valid flag/opt? // May be better to move this to *after* not finding a valid flag/opt?
debugln!("Parser::parse_short_arg: Valid negative num..."); debug!("Parser::parse_short_arg: Valid negative num...");
return Ok(ParseResult::MaybeNegNum); return Ok(ParseResult::MaybeNegNum);
} }
let mut ret = ParseResult::NotFound; let mut ret = ParseResult::NotFound;
for c in arg.chars() { for c in arg.chars() {
debugln!("Parser::parse_short_arg:iter:{}", c); debug!("Parser::parse_short_arg:iter:{}", c);
// update each index because `-abcd` is four indices to clap // update each index because `-abcd` is four indices to clap
self.cur_idx.set(self.cur_idx.get() + 1); self.cur_idx.set(self.cur_idx.get() + 1);
@ -1194,7 +1197,7 @@ where
// Option: -o // Option: -o
// Value: val // Value: val
if let Some(opt) = self.app.args.get(&KeyType::Short(c)) { if let Some(opt) = self.app.args.get(&KeyType::Short(c)) {
debugln!( debug!(
"Parser::parse_short_arg:iter:{}: Found valid opt or flag", "Parser::parse_short_arg:iter:{}: Found valid opt or flag",
c c
); );
@ -1208,7 +1211,7 @@ where
// Check for trailing concatenated value // Check for trailing concatenated value
let p: Vec<_> = arg.splitn(2, c).collect(); let p: Vec<_> = arg.splitn(2, c).collect();
debugln!( debug!(
"Parser::parse_short_arg:iter:{}: p[0]={:?}, p[1]={:?}", "Parser::parse_short_arg:iter:{}: p[0]={:?}, p[1]={:?}",
c, c,
p[0].as_bytes(), p[0].as_bytes(),
@ -1216,7 +1219,7 @@ where
); );
let i = p[0].as_bytes().len() + c.len_utf8(); let i = p[0].as_bytes().len() + c.len_utf8();
let val = if !p[1].is_empty() { let val = if !p[1].is_empty() {
debugln!( debug!(
"Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii)", "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii)",
c, c,
arg_os.split_at(i).1.as_bytes(), arg_os.split_at(i).1.as_bytes(),
@ -1250,8 +1253,8 @@ where
had_eq: bool, had_eq: bool,
matcher: &mut ArgMatcher, matcher: &mut ArgMatcher,
) -> ClapResult<ParseResult> { ) -> ClapResult<ParseResult> {
debugln!("Parser::parse_opt; opt={}, val={:?}", opt.name, val); debug!("Parser::parse_opt; opt={}, val={:?}", opt.name, val);
debugln!("Parser::parse_opt; opt.settings={:?}", opt.settings); debug!("Parser::parse_opt; opt.settings={:?}", opt.settings);
let mut has_eq = false; let mut has_eq = false;
let no_val = val.is_none(); let no_val = val.is_none();
let empty_vals = opt.is_set(ArgSettings::AllowEmptyValues); let empty_vals = opt.is_set(ArgSettings::AllowEmptyValues);
@ -1263,29 +1266,29 @@ where
has_eq = fv.starts_with(&[b'=']) || had_eq; has_eq = fv.starts_with(&[b'=']) || had_eq;
let v = fv.trim_start_n_matches(1, b'='); let v = fv.trim_start_n_matches(1, b'=');
if !empty_vals && (v.is_empty() || (needs_eq && !has_eq)) { if !empty_vals && (v.is_empty() || (needs_eq && !has_eq)) {
sdebugln!("Found Empty - Error"); debug!("Found Empty - Error");
return Err(ClapError::empty_value( return Err(ClapError::empty_value(
opt, opt,
&*Usage::new(self).create_usage_with_title(&[]), &*Usage::new(self).create_usage_with_title(&[]),
self.app.color(), self.app.color(),
)?); )?);
} }
sdebugln!("Found - {:?}, len: {}", v, v.len()); debug!("Found - {:?}, len: {}", v, v.len());
debugln!( debug!(
"Parser::parse_opt: {:?} contains '='...{:?}", "Parser::parse_opt: {:?} contains '='...{:?}",
fv, fv,
fv.starts_with(&[b'=']) fv.starts_with(&[b'='])
); );
self.add_val_to_arg(opt, v, matcher)?; self.add_val_to_arg(opt, v, matcher)?;
} else if needs_eq && !(empty_vals || min_vals_zero) { } else if needs_eq && !(empty_vals || min_vals_zero) {
sdebugln!("None, but requires equals...Error"); debug!("None, but requires equals...Error");
return Err(ClapError::empty_value( return Err(ClapError::empty_value(
opt, opt,
&*Usage::new(self).create_usage_with_title(&[]), &*Usage::new(self).create_usage_with_title(&[]),
self.app.color(), self.app.color(),
)?); )?);
} else { } else {
sdebugln!("None"); debug!("None");
} }
matcher.inc_occurrence_of(&opt.id); matcher.inc_occurrence_of(&opt.id);
@ -1298,13 +1301,13 @@ where
let mult = opt.is_set(ArgSettings::MultipleValues); let mult = opt.is_set(ArgSettings::MultipleValues);
// @TODO @soundness: if doesn't have an equal, but requires equal is ValuesDone?! // @TODO @soundness: if doesn't have an equal, but requires equal is ValuesDone?!
if no_val && min_vals_zero && !has_eq && needs_eq { if no_val && min_vals_zero && !has_eq && needs_eq {
debugln!("Parser::parse_opt: More arg vals not required..."); debug!("Parser::parse_opt: More arg vals not required...");
return Ok(ParseResult::ValuesDone); return Ok(ParseResult::ValuesDone);
} else if no_val || (mult && !needs_delim) && !has_eq && matcher.needs_more_vals(opt) { } else if no_val || (mult && !needs_delim) && !has_eq && matcher.needs_more_vals(opt) {
debugln!("Parser::parse_opt: More arg vals required..."); debug!("Parser::parse_opt: More arg vals required...");
return Ok(ParseResult::Opt(opt.id.clone())); return Ok(ParseResult::Opt(opt.id.clone()));
} }
debugln!("Parser::parse_opt: More arg vals not required..."); debug!("Parser::parse_opt: More arg vals not required...");
Ok(ParseResult::ValuesDone) Ok(ParseResult::ValuesDone)
} }
@ -1314,8 +1317,8 @@ where
val: &OsStr, val: &OsStr,
matcher: &mut ArgMatcher, matcher: &mut ArgMatcher,
) -> ClapResult<ParseResult> { ) -> ClapResult<ParseResult> {
debugln!("Parser::add_val_to_arg; arg={}, val={:?}", arg.name, val); debug!("Parser::add_val_to_arg; arg={}, val={:?}", arg.name, val);
debugln!( debug!(
"Parser::add_val_to_arg; trailing_vals={:?}, DontDelimTrailingVals={:?}", "Parser::add_val_to_arg; trailing_vals={:?}, DontDelimTrailingVals={:?}",
self.is_set(AS::TrailingValues), self.is_set(AS::TrailingValues),
self.is_set(AS::DontDelimitTrailingValues) self.is_set(AS::DontDelimitTrailingValues)
@ -1351,8 +1354,7 @@ where
v: &OsStr, v: &OsStr,
matcher: &mut ArgMatcher, matcher: &mut ArgMatcher,
) -> ClapResult<ParseResult> { ) -> ClapResult<ParseResult> {
debugln!("Parser::add_single_val_to_arg;"); debug!("Parser::add_single_val_to_arg: adding val...{:?}", v);
debugln!("Parser::add_single_val_to_arg: adding val...{:?}", v);
// update the current index because each value is a distinct index to clap // update the current index because each value is a distinct index to clap
self.cur_idx.set(self.cur_idx.get() + 1); self.cur_idx.set(self.cur_idx.get() + 1);
@ -1379,7 +1381,7 @@ where
} }
fn parse_flag(&self, flag: &Arg<'b>, matcher: &mut ArgMatcher) -> ClapResult<ParseResult> { fn parse_flag(&self, flag: &Arg<'b>, matcher: &mut ArgMatcher) -> ClapResult<ParseResult> {
debugln!("Parser::parse_flag;"); debug!("Parser::parse_flag");
matcher.inc_occurrence_of(&flag.id); matcher.inc_occurrence_of(&flag.id);
matcher.add_index_to(&flag.id, self.cur_idx.get()); matcher.add_index_to(&flag.id, self.cur_idx.get());
@ -1392,12 +1394,12 @@ where
} }
fn remove_overrides(&mut self, matcher: &mut ArgMatcher) { fn remove_overrides(&mut self, matcher: &mut ArgMatcher) {
debugln!("Parser::remove_overrides;"); debug!("Parser::remove_overrides");
let mut to_rem: Vec<Id> = Vec::new(); let mut to_rem: Vec<Id> = Vec::new();
let mut self_override: Vec<Id> = Vec::new(); let mut self_override: Vec<Id> = Vec::new();
let mut arg_overrides = Vec::new(); let mut arg_overrides = Vec::new();
for name in matcher.arg_names() { for name in matcher.arg_names() {
debugln!("Parser::remove_overrides:iter:{:?};", name); debug!("Parser::remove_overrides:iter:{:?}", name);
if let Some(arg) = self.app.find(name) { if let Some(arg) = self.app.find(name) {
let mut handle_self_override = |o: &Id| { let mut handle_self_override = |o: &Id| {
if (arg.is_set(ArgSettings::MultipleValues) if (arg.is_set(ArgSettings::MultipleValues)
@ -1406,16 +1408,15 @@ where
{ {
return true; return true;
} }
debugln!( debug!(
"Parser::remove_overrides:iter:{:?}:iter:{:?}: self override;", "Parser::remove_overrides:iter:{:?}:iter:{:?}: self override",
name, name, o
o
); );
self_override.push(o.clone()); self_override.push(o.clone());
false false
}; };
if let Some(ref overrides) = arg.overrides { if let Some(ref overrides) = arg.overrides {
debugln!("Parser::remove_overrides:iter:{:?}:{:?};", name, overrides); debug!("Parser::remove_overrides:iter:{:?}:{:?}", name, overrides);
for o in overrides { for o in overrides {
if *o == arg.id { if *o == arg.id {
if handle_self_override(o) { if handle_self_override(o) {
@ -1444,7 +1445,7 @@ where
// Do self overrides // Do self overrides
for name in &self_override { for name in &self_override {
debugln!("Parser::remove_overrides:iter:self:{:?}: resetting;", name); debug!("Parser::remove_overrides:iter:self:{:?}: resetting", name);
if let Some(ma) = matcher.get_mut(name) { if let Some(ma) = matcher.get_mut(name) {
if ma.occurs < 2 { if ma.occurs < 2 {
continue; continue;
@ -1460,14 +1461,14 @@ where
// Finally remove conflicts // Finally remove conflicts
for name in &to_rem { for name in &to_rem {
debugln!("Parser::remove_overrides:iter:{:?}: removing;", name); debug!("Parser::remove_overrides:iter:{:?}: removing", name);
matcher.remove(name); matcher.remove(name);
self.overriden.push(name.clone()); self.overriden.push(name.clone());
} }
} }
pub(crate) fn add_defaults(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> { pub(crate) fn add_defaults(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> {
debugln!("Parser::add_defaults;"); debug!("Parser::add_defaults");
for o in opts!(self.app) { for o in opts!(self.app) {
debug!("Parser::add_defaults:iter:{}:", o.name); debug!("Parser::add_defaults:iter:{}:", o.name);
@ -1484,7 +1485,7 @@ where
fn add_value(&self, arg: &Arg<'b>, matcher: &mut ArgMatcher) -> ClapResult<()> { fn add_value(&self, arg: &Arg<'b>, matcher: &mut ArgMatcher) -> ClapResult<()> {
if let Some(ref vm) = arg.default_vals_ifs { if let Some(ref vm) = arg.default_vals_ifs {
sdebugln!(" has conditional defaults"); debug!("Parser::add_value: has conditional defaults");
let mut done = false; let mut done = false;
if matcher.get(&arg.id).is_none() { if matcher.get(&arg.id).is_none() {
@ -1511,19 +1512,19 @@ where
return Ok(()); return Ok(());
} }
} else { } else {
sdebugln!(" doesn't have conditional defaults"); debug!("Parser::add_value: doesn't have conditional defaults");
} }
if let Some(ref vals) = arg.default_vals { if let Some(ref vals) = arg.default_vals {
debugln!("Parser::add_defaults:iter:{}: has default vals", arg.name); debug!("Parser::add_value:iter:{}: has default vals", arg.name);
if matcher if matcher
.get(&arg.id) .get(&arg.id)
.map(|ma| ma.vals.len()) .map(|ma| ma.vals.len())
.map(|len| len == 0) .map(|len| len == 0)
.unwrap_or(false) .unwrap_or(false)
{ {
debugln!( debug!(
"Parser::add_defaults:iter:{}: has no user defined vals", "Parser::add_value:iter:{}: has no user defined vals",
arg.name arg.name
); );
@ -1531,22 +1532,19 @@ where
self.add_val_to_arg(arg, val, matcher)?; self.add_val_to_arg(arg, val, matcher)?;
} }
} else if matcher.get(&arg.id).is_some() { } else if matcher.get(&arg.id).is_some() {
debugln!( debug!("Parser::add_value:iter:{}: has user defined vals", arg.name);
"Parser::add_defaults:iter:{}: has user defined vals",
arg.name
);
// do nothing // do nothing
} else { } else {
debugln!("Parser::add_defaults:iter:{}: wasn't used", arg.name); debug!("Parser::add_value:iter:{}: wasn't used", arg.name);
for val in vals { for val in vals {
self.add_val_to_arg(arg, val, matcher)?; self.add_val_to_arg(arg, val, matcher)?;
} }
} }
} else { } else {
debugln!( debug!(
"Parser::add_defaults:iter:{}: doesn't have default vals", "Parser::add_value:iter:{}: doesn't have default vals",
arg.name arg.name
); );
@ -1577,7 +1575,7 @@ where
'b: 'c, 'b: 'c,
{ {
fn did_you_mean_error(&mut self, arg: &str, matcher: &mut ArgMatcher) -> ClapResult<()> { fn did_you_mean_error(&mut self, arg: &str, matcher: &mut ArgMatcher) -> ClapResult<()> {
debugln!("Parser::did_you_mean_error: arg={}", arg); debug!("Parser::did_you_mean_error: arg={}", arg);
// Didn't match a flag or option // Didn't match a flag or option
let longs = self let longs = self
.app .app
@ -1590,7 +1588,7 @@ where
_ => None, _ => None,
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
debugln!("Parser::did_you_mean_error: longs={:?}", longs); debug!("Parser::did_you_mean_error: longs={:?}", longs);
let did_you_mean = suggestions::did_you_mean_flag( let did_you_mean = suggestions::did_you_mean_flag(
arg, arg,
@ -1647,7 +1645,7 @@ where
} }
fn help_err(&self, mut use_long: bool) -> ClapError { fn help_err(&self, mut use_long: bool) -> ClapError {
debugln!( debug!(
"Parser::help_err: use_long={:?}", "Parser::help_err: use_long={:?}",
use_long && self.use_long_help() use_long && self.use_long_help()
); );
@ -1667,7 +1665,7 @@ where
} }
fn version_err(&self, use_long: bool) -> ClapError { fn version_err(&self, use_long: bool) -> ClapError {
debugln!("Parser::version_err: "); debug!("Parser::version_err");
let mut c = Colorizer::new(false, self.app.color()); let mut c = Colorizer::new(false, self.app.color());

View file

@ -32,12 +32,12 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
is_subcmd: bool, is_subcmd: bool,
matcher: &mut ArgMatcher, matcher: &mut ArgMatcher,
) -> ClapResult<()> { ) -> ClapResult<()> {
debugln!("Validator::validate;"); debug!("Validator::validate");
let mut reqs_validated = false; let mut reqs_validated = false;
self.p.add_env(matcher)?; self.p.add_env(matcher)?;
self.p.add_defaults(matcher)?; self.p.add_defaults(matcher)?;
if let ParseResult::Opt(a) = needs_val_of { if let ParseResult::Opt(a) = needs_val_of {
debugln!("Validator::validate: needs_val_of={:?}", a); debug!("Validator::validate: needs_val_of={:?}", a);
self.validate_required(matcher)?; self.validate_required(matcher)?;
let o = self.p.app.find(&a).expect(INTERNAL_ERROR_MSG); let o = self.p.app.find(&a).expect(INTERNAL_ERROR_MSG);
@ -84,10 +84,10 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
ma: &MatchedArg, ma: &MatchedArg,
matcher: &ArgMatcher, matcher: &ArgMatcher,
) -> ClapResult<()> { ) -> ClapResult<()> {
debugln!("Validator::validate_arg_values: arg={:?}", arg.name); debug!("Validator::validate_arg_values: arg={:?}", arg.name);
for val in &ma.vals { for val in &ma.vals {
if self.p.is_set(AS::StrictUtf8) && val.to_str().is_none() { if self.p.is_set(AS::StrictUtf8) && val.to_str().is_none() {
debugln!( debug!(
"Validator::validate_arg_values: invalid UTF-8 found in val {:?}", "Validator::validate_arg_values: invalid UTF-8 found in val {:?}",
val val
); );
@ -97,7 +97,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
)?); )?);
} }
if let Some(ref p_vals) = arg.possible_vals { if let Some(ref p_vals) = arg.possible_vals {
debugln!("Validator::validate_arg_values: possible_vals={:?}", p_vals); debug!("Validator::validate_arg_values: possible_vals={:?}", p_vals);
let val_str = val.to_string_lossy(); let val_str = val.to_string_lossy();
let ok = if arg.is_set(ArgSettings::IgnoreCase) { let ok = if arg.is_set(ArgSettings::IgnoreCase) {
p_vals.iter().any(|pv| pv.eq_ignore_ascii_case(&*val_str)) p_vals.iter().any(|pv| pv.eq_ignore_ascii_case(&*val_str))
@ -129,7 +129,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
&& val.is_empty() && val.is_empty()
&& matcher.contains(&arg.id) && matcher.contains(&arg.id)
{ {
debugln!("Validator::validate_arg_values: illegal empty val found"); debug!("Validator::validate_arg_values: illegal empty val found");
return Err(Error::empty_value( return Err(Error::empty_value(
arg, arg,
&*Usage::new(self.p).create_usage_with_title(&[]), &*Usage::new(self.p).create_usage_with_title(&[]),
@ -139,23 +139,23 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
if let Some(ref vtor) = arg.validator { if let Some(ref vtor) = arg.validator {
debug!("Validator::validate_arg_values: checking validator..."); debug!("Validator::validate_arg_values: checking validator...");
if let Err(e) = vtor(val.to_string_lossy().into_owned()) { if let Err(e) = vtor(val.to_string_lossy().into_owned()) {
sdebugln!("error"); debug!("error");
return Err(Error::value_validation(Some(arg), &e, self.p.app.color())?); return Err(Error::value_validation(Some(arg), &e, self.p.app.color())?);
} else { } else {
sdebugln!("good"); debug!("good");
} }
} }
if let Some(ref vtor) = arg.validator_os { if let Some(ref vtor) = arg.validator_os {
debug!("Validator::validate_arg_values: checking validator_os..."); debug!("Validator::validate_arg_values: checking validator_os...");
if let Err(e) = vtor(val) { if let Err(e) = vtor(val) {
sdebugln!("error"); debug!("error");
return Err(Error::value_validation( return Err(Error::value_validation(
Some(arg), Some(arg),
&(*e).to_string(), &(*e).to_string(),
self.p.app.color(), self.p.app.color(),
)?); )?);
} else { } else {
sdebugln!("good"); debug!("good");
} }
} }
} }
@ -163,7 +163,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn build_conflict_err(&self, name: &Id, matcher: &ArgMatcher) -> ClapResult<()> { fn build_conflict_err(&self, name: &Id, matcher: &ArgMatcher) -> ClapResult<()> {
debugln!("build_err!: name={:?}", name); debug!("Validator::build_conflict_err: name={:?}", name);
let usg = Usage::new(self.p).create_usage_with_title(&[]); let usg = Usage::new(self.p).create_usage_with_title(&[]);
if let Some(other_arg) = self.p.app.find(name) { if let Some(other_arg) = self.p.app.find(name) {
for k in matcher.arg_names() { for k in matcher.arg_names() {
@ -190,7 +190,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
.arg_names() .arg_names()
.find(|x| x != &first && args_in_group.contains(x)) .find(|x| x != &first && args_in_group.contains(x))
.map(|x| self.p.app.find(x).expect(INTERNAL_ERROR_MSG).to_string()); .map(|x| self.p.app.find(x).expect(INTERNAL_ERROR_MSG).to_string());
debugln!("build_err!:c_with={:?}:group", c_with); debug!("Validator::build_conflict_err: c_with={:?}:group", c_with);
return Err(Error::argument_conflict( return Err(Error::argument_conflict(
self.p.app.find(first).expect(INTERNAL_ERROR_MSG), self.p.app.find(first).expect(INTERNAL_ERROR_MSG),
c_with, c_with,
@ -203,14 +203,14 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn validate_conflicts(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> { fn validate_conflicts(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> {
debugln!("Validator::validate_conflicts;"); debug!("Validator::validate_conflicts");
let validate_result = self.validate_exclusive(matcher); let validate_result = self.validate_exclusive(matcher);
if validate_result.is_err() { if validate_result.is_err() {
return validate_result; return validate_result;
} }
self.gather_conflicts(matcher); self.gather_conflicts(matcher);
for name in self.c.iter() { for name in self.c.iter() {
debugln!("Validator::validate_conflicts:iter:{:?};", name); debug!("Validator::validate_conflicts:iter:{:?}", name);
let mut should_err = false; let mut should_err = false;
if let Some(g) = self if let Some(g) = self
.p .p
@ -243,7 +243,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
should_err = conf_with_self || conf_with_arg || arg_conf_with_gr; should_err = conf_with_self || conf_with_arg || arg_conf_with_gr;
} else if let Some(ma) = matcher.get(name) { } else if let Some(ma) = matcher.get(name) {
debugln!( debug!(
"Validator::validate_conflicts:iter:{:?}: matcher contains it...", "Validator::validate_conflicts:iter:{:?}: matcher contains it...",
name name
); );
@ -257,13 +257,10 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn validate_exclusive(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> { fn validate_exclusive(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> {
debugln!("Validator::validate_exclusive;"); debug!("Validator::validate_exclusive");
let args_count = matcher.arg_names().count(); let args_count = matcher.arg_names().count();
for name in matcher.arg_names() { for name in matcher.arg_names() {
debugln!( debug!("Validator::validate_exclusive:iter:{:?}", name);
"Validator::validate_conflicts_with_everything:iter:{:?};",
name
);
if let Some(arg) = self.p.app.find(name) { if let Some(arg) = self.p.app.find(name) {
if arg.exclusive && args_count > 1 { if arg.exclusive && args_count > 1 {
let c_with: Option<String> = None; let c_with: Option<String> = None;
@ -282,9 +279,9 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
// Gathers potential conflicts based on used argument, but without considering requirements // Gathers potential conflicts based on used argument, but without considering requirements
// and such // and such
fn gather_conflicts(&mut self, matcher: &mut ArgMatcher) { fn gather_conflicts(&mut self, matcher: &mut ArgMatcher) {
debugln!("Validator::gather_conflicts;"); debug!("Validator::gather_conflicts");
for name in matcher.arg_names() { for name in matcher.arg_names() {
debugln!("Validator::gather_conflicts:iter:{:?};", name); debug!("Validator::gather_conflicts:iter:{:?}", name);
if let Some(arg) = self.p.app.find(name) { if let Some(arg) = self.p.app.find(name) {
// Since an arg was used, every arg it conflicts with is added to the conflicts // Since an arg was used, every arg it conflicts with is added to the conflicts
if let Some(ref bl) = arg.blacklist { if let Some(ref bl) = arg.blacklist {
@ -332,22 +329,22 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
.filter(|g| !g.multiple) .filter(|g| !g.multiple)
.find(|grp| grp.id == *name) .find(|grp| grp.id == *name)
{ {
debugln!("Validator::gather_conflicts:iter:{:?}:group;", name); debug!("Validator::gather_conflicts:iter:{:?}:group", name);
self.c.insert(g.id.clone()); self.c.insert(g.id.clone());
} }
} }
} }
fn gather_requirements(&mut self, matcher: &ArgMatcher) { fn gather_requirements(&mut self, matcher: &ArgMatcher) {
debugln!("Validator::gather_requirements;"); debug!("Validator::gather_requirements");
for name in matcher.arg_names() { for name in matcher.arg_names() {
debugln!("Validator::gather_requirements:iter:{:?};", name); debug!("Validator::gather_requirements:iter:{:?}", name);
if let Some(arg) = self.p.app.find(name) { if let Some(arg) = self.p.app.find(name) {
for req in self.p.app.unroll_requirements_for_arg(&arg.id, matcher) { for req in self.p.app.unroll_requirements_for_arg(&arg.id, matcher) {
self.p.required.insert(req); self.p.required.insert(req);
} }
} else if let Some(g) = self.p.app.groups.iter().find(|grp| grp.id == *name) { } else if let Some(g) = self.p.app.groups.iter().find(|grp| grp.id == *name) {
debugln!("Validator::gather_conflicts:iter:{:?}:group;", name); debug!("Validator::gather_conflicts:iter:{:?}:group", name);
if let Some(ref reqs) = g.requires { if let Some(ref reqs) = g.requires {
for r in reqs { for r in reqs {
self.p.required.insert(r.clone()); self.p.required.insert(r.clone());
@ -358,12 +355,11 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn validate_matched_args(&self, matcher: &mut ArgMatcher) -> ClapResult<()> { fn validate_matched_args(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
debugln!("Validator::validate_matched_args;"); debug!("Validator::validate_matched_args");
for (name, ma) in matcher.iter() { for (name, ma) in matcher.iter() {
debugln!( debug!(
"Validator::validate_matched_args:iter:{:?}: vals={:#?}", "Validator::validate_matched_args:iter:{:?}: vals={:#?}",
name, name, ma.vals
ma.vals
); );
if let Some(arg) = self.p.app.find(name) { if let Some(arg) = self.p.app.find(name) {
self.validate_arg_num_vals(arg, ma)?; self.validate_arg_num_vals(arg, ma)?;
@ -389,10 +385,9 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn validate_arg_num_occurs(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> { fn validate_arg_num_occurs(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> {
debugln!( debug!(
"Validator::validate_arg_num_occurs: {:?}={};", "Validator::validate_arg_num_occurs: {:?}={}",
a.name, a.name, ma.occurs
ma.occurs
); );
if ma.occurs > 1 && !a.is_set(ArgSettings::MultipleOccurrences) { if ma.occurs > 1 && !a.is_set(ArgSettings::MultipleOccurrences) {
// Not the first time, and we don't allow multiples // Not the first time, and we don't allow multiples
@ -406,16 +401,16 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn validate_arg_num_vals(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> { fn validate_arg_num_vals(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> {
debugln!("Validator::validate_arg_num_vals;"); debug!("Validator::validate_arg_num_vals");
if let Some(num) = a.num_vals { if let Some(num) = a.num_vals {
debugln!("Validator::validate_arg_num_vals: num_vals set...{}", num); debug!("Validator::validate_arg_num_vals: num_vals set...{}", num);
let should_err = if a.is_set(ArgSettings::MultipleValues) { let should_err = if a.is_set(ArgSettings::MultipleValues) {
((ma.vals.len() as u64) % num) != 0 ((ma.vals.len() as u64) % num) != 0
} else { } else {
num != (ma.vals.len() as u64) num != (ma.vals.len() as u64)
}; };
if should_err { if should_err {
debugln!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues"); debug!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues");
return Err(Error::wrong_number_of_values( return Err(Error::wrong_number_of_values(
a, a,
num, num,
@ -430,9 +425,9 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
} }
if let Some(num) = a.max_vals { if let Some(num) = a.max_vals {
debugln!("Validator::validate_arg_num_vals: max_vals set...{}", num); debug!("Validator::validate_arg_num_vals: max_vals set...{}", num);
if (ma.vals.len() as u64) > num { if (ma.vals.len() as u64) > num {
debugln!("Validator::validate_arg_num_vals: Sending error TooManyValues"); debug!("Validator::validate_arg_num_vals: Sending error TooManyValues");
return Err(Error::too_many_values( return Err(Error::too_many_values(
ma.vals ma.vals
.iter() .iter()
@ -447,9 +442,9 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
} }
let min_vals_zero = if let Some(num) = a.min_vals { let min_vals_zero = if let Some(num) = a.min_vals {
debugln!("Validator::validate_arg_num_vals: min_vals set: {}", num); debug!("Validator::validate_arg_num_vals: min_vals set: {}", num);
if (ma.vals.len() as u64) < num && num != 0 { if (ma.vals.len() as u64) < num && num != 0 {
debugln!("Validator::validate_arg_num_vals: Sending error TooFewValues"); debug!("Validator::validate_arg_num_vals: Sending error TooFewValues");
return Err(Error::too_few_values( return Err(Error::too_few_values(
a, a,
num, num,
@ -480,7 +475,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
ma: &MatchedArg, ma: &MatchedArg,
matcher: &ArgMatcher, matcher: &ArgMatcher,
) -> ClapResult<()> { ) -> ClapResult<()> {
debugln!("Validator::validate_arg_requires:{:?};", a.name); debug!("Validator::validate_arg_requires:{:?}", a.name);
if let Some(ref a_reqs) = a.requires { if let Some(ref a_reqs) = a.requires {
for (val, name) in a_reqs.iter().filter(|(val, _)| val.is_some()) { for (val, name) in a_reqs.iter().filter(|(val, _)| val.is_some()) {
let missing_req = let missing_req =
@ -499,21 +494,21 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn validate_required(&mut self, matcher: &ArgMatcher) -> ClapResult<()> { fn validate_required(&mut self, matcher: &ArgMatcher) -> ClapResult<()> {
debugln!( debug!(
"Validator::validate_required: required={:?};", "Validator::validate_required: required={:?}",
self.p.required self.p.required
); );
self.gather_requirements(matcher); self.gather_requirements(matcher);
for arg_or_group in self.p.required.iter().filter(|r| !matcher.contains(r)) { for arg_or_group in self.p.required.iter().filter(|r| !matcher.contains(r)) {
debugln!("Validator::validate_required:iter:aog={:?};", arg_or_group); debug!("Validator::validate_required:iter:aog={:?}", arg_or_group);
if let Some(arg) = self.p.app.find(&arg_or_group) { if let Some(arg) = self.p.app.find(&arg_or_group) {
debugln!("Validator::validate_required:iter: This is an arg"); debug!("Validator::validate_required:iter: This is an arg");
if !self.is_missing_required_ok(arg, matcher) { if !self.is_missing_required_ok(arg, matcher) {
return self.missing_required_error(matcher, None); return self.missing_required_error(matcher, None);
} }
} else if let Some(group) = self.p.app.groups.iter().find(|g| g.id == *arg_or_group) { } else if let Some(group) = self.p.app.groups.iter().find(|g| g.id == *arg_or_group) {
debugln!("Validator::validate_required:iter: This is a group"); debug!("Validator::validate_required:iter: This is a group");
if !self if !self
.p .p
.app .app
@ -548,12 +543,12 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn is_missing_required_ok(&self, a: &Arg<'b>, matcher: &ArgMatcher) -> bool { fn is_missing_required_ok(&self, a: &Arg<'b>, matcher: &ArgMatcher) -> bool {
debugln!("Validator::is_missing_required_ok: {}", a.name); debug!("Validator::is_missing_required_ok: {}", a.name);
self.validate_arg_conflicts(a, matcher) || self.p.overriden.contains(&a.id) self.validate_arg_conflicts(a, matcher) || self.p.overriden.contains(&a.id)
} }
fn validate_arg_conflicts(&self, a: &Arg<'b>, matcher: &ArgMatcher) -> bool { fn validate_arg_conflicts(&self, a: &Arg<'b>, matcher: &ArgMatcher) -> bool {
debugln!("Validator::validate_arg_conflicts: a={:?};", a.name); debug!("Validator::validate_arg_conflicts: a={:?}", a.name);
a.blacklist a.blacklist
.as_ref() .as_ref()
.map(|bl| { .map(|bl| {
@ -572,7 +567,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
} }
fn validate_required_unless(&self, matcher: &ArgMatcher) -> ClapResult<()> { fn validate_required_unless(&self, matcher: &ArgMatcher) -> ClapResult<()> {
debugln!("Validator::validate_required_unless;"); debug!("Validator::validate_required_unless");
for a in self for a in self
.p .p
.app .app
@ -582,7 +577,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
.filter(|a| a.r_unless.is_some()) .filter(|a| a.r_unless.is_some())
.filter(|a| !matcher.contains(&a.id)) .filter(|a| !matcher.contains(&a.id))
{ {
debugln!("Validator::validate_required_unless:iter:{};", a.name); debug!("Validator::validate_required_unless:iter:{}", a.name);
if self.fails_arg_required_unless(a, matcher) { if self.fails_arg_required_unless(a, matcher) {
return self.missing_required_error(matcher, Some(&a.id)); return self.missing_required_error(matcher, Some(&a.id));
} }
@ -593,7 +588,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
// Failing a required unless means, the arg's "unless" wasn't present, and neither were they // Failing a required unless means, the arg's "unless" wasn't present, and neither were they
fn fails_arg_required_unless(&self, a: &Arg<'b>, matcher: &ArgMatcher) -> bool { fn fails_arg_required_unless(&self, a: &Arg<'b>, matcher: &ArgMatcher) -> bool {
debugln!("Validator::fails_arg_required_unless: a={:?};", a.name); debug!("Validator::fails_arg_required_unless: a={:?}", a.name);
macro_rules! check { macro_rules! check {
($how:ident, $_self:expr, $a:ident, $m:ident) => {{ ($how:ident, $_self:expr, $a:ident, $m:ident) => {{
$a.r_unless $a.r_unless
@ -603,18 +598,18 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
}}; }};
} }
if a.is_set(ArgSettings::RequiredUnlessAll) { if a.is_set(ArgSettings::RequiredUnlessAll) {
debugln!("Validator::fails_arg_required_unless:{}:All;", a.name); debug!("Validator::fails_arg_required_unless:{}:All", a.name);
check!(all, self.p, a, matcher) check!(all, self.p, a, matcher)
} else { } else {
debugln!("Validator::fails_arg_required_unless:{}:Any;", a.name); debug!("Validator::fails_arg_required_unless:{}:Any", a.name);
check!(any, self.p, a, matcher) check!(any, self.p, a, matcher)
} }
} }
// `incl`: an arg to include in the error even if not used // `incl`: an arg to include in the error even if not used
fn missing_required_error(&self, matcher: &ArgMatcher, incl: Option<&Id>) -> ClapResult<()> { fn missing_required_error(&self, matcher: &ArgMatcher, incl: Option<&Id>) -> ClapResult<()> {
debugln!("Validator::missing_required_error; incl={:?}", incl); debug!("Validator::missing_required_error; incl={:?}", incl);
debugln!( debug!(
"Validator::missing_required_error: reqs={:?}", "Validator::missing_required_error: reqs={:?}",
self.p.required self.p.required
); );
@ -627,7 +622,7 @@ impl<'b, 'c, 'z> Validator<'b, 'c, 'z> {
usg.get_required_usage_from(&[], None, true) usg.get_required_usage_from(&[], None, true)
}; };
debugln!( debug!(
"Validator::missing_required_error: req_args={:#?}", "Validator::missing_required_error: req_args={:#?}",
req_args req_args
); );

View file

@ -116,7 +116,8 @@ impl<'a> Iterator for OsSplit<'a> {
type Item = &'a OsStr; type Item = &'a OsStr;
fn next(&mut self) -> Option<&'a OsStr> { fn next(&mut self) -> Option<&'a OsStr> {
debugln!("OsSplit::next: self={:?}", self); debug!("OsSplit::next: self={:?}", self);
if self.pos == self.val.len() { if self.pos == self.val.len() {
return None; return None;
} }