2015-11-09 13:57:20 +00:00
|
|
|
macro_rules! remove_overriden {
|
2016-02-02 10:46:28 +00:00
|
|
|
(@remove $_self:ident, $v:ident, $a:ident.$ov:ident) => {
|
|
|
|
if let Some(ref ora) = $a.$ov {
|
|
|
|
vec_remove_all!($_self.$v, ora);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
(@arg $_self:ident, $arg:ident) => {
|
|
|
|
remove_overriden!(@remove $_self, required, $arg.requires);
|
|
|
|
remove_overriden!(@remove $_self, blacklist, $arg.blacklist);
|
|
|
|
remove_overriden!(@remove $_self, overrides, $arg.overrides);
|
|
|
|
};
|
|
|
|
($_self:ident, $name:expr) => {
|
2016-01-22 17:58:56 +00:00
|
|
|
debugln!("macro=remove_overriden!;");
|
2016-02-02 10:46:28 +00:00
|
|
|
if let Some(ref o) = $_self.opts.iter().filter(|o| o.name == *$name).next() {
|
|
|
|
remove_overriden!(@arg $_self, o);
|
|
|
|
} else if let Some(ref f) = $_self.flags.iter().filter(|f| f.name == *$name).next() {
|
|
|
|
remove_overriden!(@arg $_self, f);
|
|
|
|
} else if let Some(p) = $_self.positionals.values().filter(|p| p.name == *$name).next() {
|
|
|
|
remove_overriden!(@arg $_self, p);
|
2015-11-09 13:57:20 +00:00
|
|
|
}
|
2016-02-02 10:46:28 +00:00
|
|
|
};
|
2015-11-09 13:57:20 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 11:17:23 +00:00
|
|
|
macro_rules! arg_post_processing {
|
|
|
|
($me:ident, $arg:ident, $matcher:ident) => {
|
2016-01-22 17:58:56 +00:00
|
|
|
debugln!("macro=arg_post_processing!;");
|
2015-11-09 13:57:20 +00:00
|
|
|
// Handle POSIX overrides
|
2016-01-22 04:18:52 +00:00
|
|
|
debug!("Is '{}' in overrides...", $arg.to_string());
|
2015-11-09 13:57:20 +00:00
|
|
|
if $me.overrides.contains(&$arg.name()) {
|
2016-10-31 04:35:23 +00:00
|
|
|
if let Some(ref name) = find_name_from!($me, &$arg.name(), overrides, $matcher) {
|
2016-01-22 04:18:52 +00:00
|
|
|
sdebugln!("Yes by {}", name);
|
2015-11-09 13:57:20 +00:00
|
|
|
$matcher.remove(name);
|
|
|
|
remove_overriden!($me, name);
|
|
|
|
}
|
2016-01-22 04:18:52 +00:00
|
|
|
} else { sdebugln!("No"); }
|
|
|
|
|
|
|
|
// Add overrides
|
|
|
|
debug!("Does '{}' have overrides...", $arg.to_string());
|
2015-11-09 13:57:20 +00:00
|
|
|
if let Some(or) = $arg.overrides() {
|
2016-02-02 11:17:23 +00:00
|
|
|
sdebugln!("Yes");
|
|
|
|
$matcher.remove_all(or);
|
|
|
|
for pa in or { remove_overriden!($me, pa); }
|
|
|
|
$me.overrides.extend(or);
|
|
|
|
vec_remove_all!($me.required, or);
|
2016-01-22 04:18:52 +00:00
|
|
|
} else { sdebugln!("No"); }
|
|
|
|
|
2015-11-09 13:57:20 +00:00
|
|
|
// Handle conflicts
|
2016-01-22 17:58:56 +00:00
|
|
|
debug!("Does '{}' have conflicts...", $arg.to_string());
|
2015-11-09 13:57:20 +00:00
|
|
|
if let Some(bl) = $arg.blacklist() {
|
2016-02-02 11:17:23 +00:00
|
|
|
sdebugln!("Yes");
|
2016-10-31 04:35:23 +00:00
|
|
|
|
|
|
|
for c in bl {
|
|
|
|
// Inject two-way conflicts
|
|
|
|
debug!("Has '{}' already been matched...", c);
|
|
|
|
if $matcher.contains(c) {
|
|
|
|
sdebugln!("Yes");
|
|
|
|
// find who blacklisted us...
|
|
|
|
$me.blacklist.push(&$arg.name);
|
|
|
|
// if let Some(f) = $me.find_flag_mut(c) {
|
|
|
|
// if let Some(ref mut bl) = f.blacklist {
|
|
|
|
// bl.push(&$arg.name);
|
|
|
|
// }
|
|
|
|
// } else if let Some(o) = $me.find_option_mut(c) {
|
|
|
|
// if let Some(ref mut bl) = o.blacklist {
|
|
|
|
// bl.push(&$arg.name);
|
|
|
|
// }
|
|
|
|
// } else if let Some(p) = $me.find_positional_mut(c) {
|
|
|
|
// if let Some(ref mut bl) = p.blacklist {
|
|
|
|
// bl.push(&$arg.name);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
} else {
|
|
|
|
sdebugln!("No");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-02 11:17:23 +00:00
|
|
|
$me.blacklist.extend(bl);
|
|
|
|
vec_remove_all!($me.overrides, bl);
|
|
|
|
vec_remove_all!($me.required, bl);
|
2016-01-22 04:18:52 +00:00
|
|
|
} else { sdebugln!("No"); }
|
2015-11-09 13:57:20 +00:00
|
|
|
|
|
|
|
// Add all required args which aren't already found in matcher to the master
|
|
|
|
// list
|
2016-01-22 04:18:52 +00:00
|
|
|
debug!("Does '{}' have requirements...", $arg.to_string());
|
2015-11-09 13:57:20 +00:00
|
|
|
if let Some(reqs) = $arg.requires() {
|
|
|
|
for n in reqs {
|
2016-01-22 04:18:52 +00:00
|
|
|
if $matcher.contains(&n) {
|
|
|
|
sdebugln!("\tYes '{}' but it's already met", n);
|
2015-11-09 13:57:20 +00:00
|
|
|
continue;
|
2016-01-22 04:18:52 +00:00
|
|
|
} else { sdebugln!("\tYes '{}'", n); }
|
2015-11-09 13:57:20 +00:00
|
|
|
|
|
|
|
$me.required.push(n);
|
|
|
|
}
|
2016-01-22 04:18:52 +00:00
|
|
|
} else { sdebugln!("No"); }
|
2015-11-09 13:57:20 +00:00
|
|
|
|
|
|
|
_handle_group_reqs!($me, $arg);
|
2016-02-02 11:17:23 +00:00
|
|
|
};
|
|
|
|
}
|
2015-11-09 13:57:20 +00:00
|
|
|
|
|
|
|
macro_rules! _handle_group_reqs{
|
|
|
|
($me:ident, $arg:ident) => ({
|
|
|
|
use args::AnyArg;
|
2016-01-22 17:58:56 +00:00
|
|
|
debugln!("macro=_handle_group_reqs!;");
|
2015-11-09 13:57:20 +00:00
|
|
|
for grp in $me.groups.values() {
|
2016-06-08 04:10:56 +00:00
|
|
|
let found = if grp.args.contains(&$arg.name()) {
|
2016-05-09 19:54:10 +00:00
|
|
|
vec_remove!($me.required, &$arg.name());
|
|
|
|
if let Some(ref reqs) = grp.requires {
|
|
|
|
$me.required.extend(reqs);
|
2015-11-09 13:57:20 +00:00
|
|
|
}
|
2016-05-09 19:54:10 +00:00
|
|
|
if let Some(ref bl) = grp.conflicts {
|
|
|
|
$me.blacklist.extend(bl);
|
|
|
|
}
|
2016-06-08 04:10:56 +00:00
|
|
|
true // What if arg is in more than one group with different reqs?
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
};
|
2016-09-13 01:48:22 +00:00
|
|
|
debugln!("iter;grp={};found={:?}", grp.name, found);
|
2015-11-09 13:57:20 +00:00
|
|
|
if found {
|
2016-02-02 11:00:19 +00:00
|
|
|
vec_remove_all!($me.required, &grp.args);
|
2016-05-09 19:54:10 +00:00
|
|
|
debugln!("Adding args from group to blacklist...{:?}", grp.args);
|
2016-06-23 14:01:19 +00:00
|
|
|
if !grp.multiple {
|
|
|
|
$me.blacklist.extend(&grp.args);
|
|
|
|
vec_remove!($me.blacklist, &$arg.name());
|
|
|
|
}
|
2015-11-09 13:57:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2016-01-22 04:18:52 +00:00
|
|
|
|
|
|
|
macro_rules! validate_multiples {
|
|
|
|
($_self:ident, $a:ident, $m:ident) => {
|
2016-01-22 17:58:56 +00:00
|
|
|
debugln!("macro=validate_multiples!;");
|
2016-01-22 04:18:52 +00:00
|
|
|
if $m.contains(&$a.name) && !$a.settings.is_set(ArgSettings::Multiple) {
|
2016-09-05 19:29:40 +00:00
|
|
|
// Not the first time, and we don't allow multiples
|
|
|
|
return Err(Error::unexpected_multiple_usage($a,
|
|
|
|
&*$_self.create_current_usage($m),
|
|
|
|
$_self.color()))
|
2016-01-22 04:18:52 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2016-05-06 21:35:53 +00:00
|
|
|
|
|
|
|
macro_rules! parse_positional {
|
|
|
|
(
|
|
|
|
$_self:ident,
|
|
|
|
$p:ident,
|
|
|
|
$arg_os:ident,
|
|
|
|
$pos_counter:ident,
|
|
|
|
$matcher:ident
|
|
|
|
) => {
|
|
|
|
debugln!("macro=parse_positional!;");
|
|
|
|
validate_multiples!($_self, $p, $matcher);
|
|
|
|
|
2016-06-05 05:09:07 +00:00
|
|
|
if !$_self.trailing_vals &&
|
2016-05-06 21:35:53 +00:00
|
|
|
($_self.settings.is_set(AppSettings::TrailingVarArg) &&
|
|
|
|
$pos_counter == $_self.positionals.len()) {
|
2016-06-05 05:09:07 +00:00
|
|
|
$_self.trailing_vals = true;
|
|
|
|
}
|
|
|
|
if let Err(e) = $_self.add_val_to_arg($p, &$arg_os, $matcher) {
|
|
|
|
return Err(e);
|
2016-05-06 21:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$matcher.inc_occurrence_of($p.name);
|
|
|
|
let _ = $_self.groups_for_arg($p.name)
|
|
|
|
.and_then(|vec| Some($matcher.inc_occurrences_of(&*vec)));
|
|
|
|
arg_post_processing!($_self, $p, $matcher);
|
2016-06-05 05:09:07 +00:00
|
|
|
// Only increment the positional counter if it doesn't allow multiples
|
2016-05-06 21:35:53 +00:00
|
|
|
if !$p.settings.is_set(ArgSettings::Multiple) {
|
|
|
|
$pos_counter += 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2016-10-31 04:35:23 +00:00
|
|
|
|
|
|
|
macro_rules! find_from {
|
|
|
|
($_self:ident, $arg_name:expr, $from:ident, $matcher:expr) => {{
|
|
|
|
let mut ret = None;
|
|
|
|
for k in $matcher.arg_names() {
|
|
|
|
if let Some(f) = $_self.find_flag(k) {
|
|
|
|
if let Some(ref v) = f.$from {
|
|
|
|
if v.contains($arg_name) {
|
|
|
|
ret = Some(f.to_string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if let Some(o) = $_self.find_option(k) {
|
|
|
|
if let Some(ref v) = o.$from {
|
|
|
|
if v.contains(&$arg_name) {
|
|
|
|
ret = Some(o.to_string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if let Some(pos) = $_self.find_positional(k) {
|
|
|
|
if let Some(ref v) = pos.$from {
|
|
|
|
if v.contains($arg_name) {
|
|
|
|
ret = Some(pos.name.to_owned());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! find_name_from {
|
|
|
|
($_self:ident, $arg_name:expr, $from:ident, $matcher:expr) => {{
|
|
|
|
let mut ret = None;
|
|
|
|
for k in $matcher.arg_names() {
|
|
|
|
if let Some(f) = $_self.find_flag(k) {
|
|
|
|
if let Some(ref v) = f.$from {
|
|
|
|
if v.contains($arg_name) {
|
|
|
|
ret = Some(f.name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if let Some(o) = $_self.find_option(k) {
|
|
|
|
if let Some(ref v) = o.$from {
|
|
|
|
if v.contains(&$arg_name) {
|
|
|
|
ret = Some(o.name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if let Some(pos) = $_self.find_positional(k) {
|
|
|
|
if let Some(ref v) = pos.$from {
|
|
|
|
if v.contains($arg_name) {
|
|
|
|
ret = Some(pos.name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret
|
|
|
|
}};
|
|
|
|
}
|