]>
Commit | Line | Data |
---|---|---|
8bb4bdeb | 1 | macro_rules! remove_overriden { |
041b39d2 XL |
2 | (@remove_requires $rem_from:expr, $a:ident.$ov:ident) => { |
3 | if let Some(ora) = $a.$ov() { | |
4 | for i in (0 .. $rem_from.len()).rev() { | |
5 | let should_remove = ora.iter().any(|&(_, ref name)| name == &$rem_from[i]); | |
6 | if should_remove { $rem_from.swap_remove(i); } | |
7 | } | |
8 | } | |
9 | }; | |
10 | (@remove $rem_from:expr, $a:ident.$ov:ident) => { | |
11 | if let Some(ora) = $a.$ov() { | |
12 | vec_remove_all!($rem_from, ora.iter()); | |
8bb4bdeb XL |
13 | } |
14 | }; | |
15 | (@arg $_self:ident, $arg:ident) => { | |
041b39d2 XL |
16 | remove_overriden!(@remove_requires $_self.required, $arg.requires); |
17 | remove_overriden!(@remove $_self.blacklist, $arg.blacklist); | |
18 | remove_overriden!(@remove $_self.overrides, $arg.overrides); | |
8bb4bdeb XL |
19 | }; |
20 | ($_self:ident, $name:expr) => { | |
041b39d2 XL |
21 | debugln!("remove_overriden!;"); |
22 | if let Some(o) = $_self.opts.iter() .find(|o| o.b.name == *$name) { | |
8bb4bdeb | 23 | remove_overriden!(@arg $_self, o); |
041b39d2 | 24 | } else if let Some(f) = $_self.flags.iter() .find(|f| f.b.name == *$name) { |
8bb4bdeb | 25 | remove_overriden!(@arg $_self, f); |
041b39d2 XL |
26 | } else { |
27 | let p = $_self.positionals.values() | |
28 | .find(|p| p.b.name == *$name) | |
29 | .expect(INTERNAL_ERROR_MSG); | |
8bb4bdeb XL |
30 | remove_overriden!(@arg $_self, p); |
31 | } | |
32 | }; | |
33 | } | |
34 | ||
35 | macro_rules! arg_post_processing { | |
36 | ($me:ident, $arg:ident, $matcher:ident) => { | |
041b39d2 | 37 | debugln!("arg_post_processing!;"); |
8bb4bdeb | 38 | // Handle POSIX overrides |
041b39d2 | 39 | debug!("arg_post_processing!: Is '{}' in overrides...", $arg.to_string()); |
8bb4bdeb XL |
40 | if $me.overrides.contains(&$arg.name()) { |
41 | if let Some(ref name) = find_name_from!($me, &$arg.name(), overrides, $matcher) { | |
42 | sdebugln!("Yes by {}", name); | |
43 | $matcher.remove(name); | |
44 | remove_overriden!($me, name); | |
45 | } | |
46 | } else { sdebugln!("No"); } | |
47 | ||
48 | // Add overrides | |
041b39d2 | 49 | debug!("arg_post_processing!: Does '{}' have overrides...", $arg.to_string()); |
8bb4bdeb XL |
50 | if let Some(or) = $arg.overrides() { |
51 | sdebugln!("Yes"); | |
52 | $matcher.remove_all(or); | |
53 | for pa in or { remove_overriden!($me, pa); } | |
54 | $me.overrides.extend(or); | |
041b39d2 | 55 | vec_remove_all!($me.required, or.iter()); |
8bb4bdeb XL |
56 | } else { sdebugln!("No"); } |
57 | ||
58 | // Handle conflicts | |
041b39d2 | 59 | debug!("arg_post_processing!: Does '{}' have conflicts...", $arg.to_string()); |
8bb4bdeb XL |
60 | if let Some(bl) = $arg.blacklist() { |
61 | sdebugln!("Yes"); | |
041b39d2 | 62 | |
8bb4bdeb XL |
63 | for c in bl { |
64 | // Inject two-way conflicts | |
041b39d2 | 65 | debug!("arg_post_processing!: Has '{}' already been matched...", c); |
8bb4bdeb XL |
66 | if $matcher.contains(c) { |
67 | sdebugln!("Yes"); | |
68 | // find who blacklisted us... | |
69 | $me.blacklist.push(&$arg.b.name); | |
70 | } else { | |
71 | sdebugln!("No"); | |
72 | } | |
73 | } | |
74 | ||
041b39d2 XL |
75 | $me.blacklist.extend_from_slice(bl); |
76 | vec_remove_all!($me.overrides, bl.iter()); | |
77 | // vec_remove_all!($me.required, bl.iter()); | |
8bb4bdeb XL |
78 | } else { sdebugln!("No"); } |
79 | ||
80 | // Add all required args which aren't already found in matcher to the master | |
81 | // list | |
041b39d2 | 82 | debug!("arg_post_processing!: Does '{}' have requirements...", $arg.to_string()); |
8bb4bdeb | 83 | if let Some(reqs) = $arg.requires() { |
041b39d2 XL |
84 | for n in reqs.iter() |
85 | .filter(|&&(val, _)| val.is_none()) | |
86 | .filter(|&&(_, req)| !$matcher.contains(&req)) | |
87 | .map(|&(_, name)| name) { | |
88 | ||
8bb4bdeb XL |
89 | $me.required.push(n); |
90 | } | |
91 | } else { sdebugln!("No"); } | |
92 | ||
93 | _handle_group_reqs!($me, $arg); | |
94 | }; | |
95 | } | |
96 | ||
97 | macro_rules! _handle_group_reqs{ | |
98 | ($me:ident, $arg:ident) => ({ | |
99 | use args::AnyArg; | |
041b39d2 XL |
100 | debugln!("_handle_group_reqs!;"); |
101 | for grp in &$me.groups { | |
8bb4bdeb | 102 | let found = if grp.args.contains(&$arg.name()) { |
8bb4bdeb | 103 | if let Some(ref reqs) = grp.requires { |
041b39d2 | 104 | debugln!("_handle_group_reqs!: Adding {:?} to the required list", reqs); |
8bb4bdeb XL |
105 | $me.required.extend(reqs); |
106 | } | |
107 | if let Some(ref bl) = grp.conflicts { | |
108 | $me.blacklist.extend(bl); | |
109 | } | |
110 | true // What if arg is in more than one group with different reqs? | |
111 | } else { | |
112 | false | |
113 | }; | |
041b39d2 | 114 | debugln!("_handle_group_reqs!:iter: grp={}, found={:?}", grp.name, found); |
8bb4bdeb | 115 | if found { |
041b39d2 XL |
116 | for i in (0 .. $me.required.len()).rev() { |
117 | let should_remove = grp.args.contains(&$me.required[i]); | |
118 | if should_remove { $me.required.swap_remove(i); } | |
119 | } | |
120 | debugln!("_handle_group_reqs!:iter: Adding args from group to blacklist...{:?}", grp.args); | |
8bb4bdeb XL |
121 | if !grp.multiple { |
122 | $me.blacklist.extend(&grp.args); | |
041b39d2 XL |
123 | debugln!("_handle_group_reqs!: removing {:?} from blacklist", $arg.name()); |
124 | for i in (0 .. $me.blacklist.len()).rev() { | |
125 | let should_remove = $me.blacklist[i] == $arg.name(); | |
126 | if should_remove { $me.blacklist.swap_remove(i); } | |
127 | } | |
8bb4bdeb XL |
128 | } |
129 | } | |
130 | } | |
131 | }) | |
132 | } | |
133 | ||
8bb4bdeb XL |
134 | macro_rules! parse_positional { |
135 | ( | |
136 | $_self:ident, | |
137 | $p:ident, | |
138 | $arg_os:ident, | |
139 | $pos_counter:ident, | |
140 | $matcher:ident | |
141 | ) => { | |
041b39d2 | 142 | debugln!("parse_positional!;"); |
8bb4bdeb | 143 | |
041b39d2 XL |
144 | if !$_self.is_set(AS::TrailingValues) && |
145 | ($_self.is_set(AS::TrailingVarArg) && | |
8bb4bdeb | 146 | $pos_counter == $_self.positionals.len()) { |
041b39d2 | 147 | $_self.settings.set(AS::TrailingValues); |
8bb4bdeb | 148 | } |
3b2f2976 | 149 | let _ = $_self.add_val_to_arg($p, &$arg_os, $matcher)?; |
8bb4bdeb XL |
150 | |
151 | $matcher.inc_occurrence_of($p.b.name); | |
152 | let _ = $_self.groups_for_arg($p.b.name) | |
153 | .and_then(|vec| Some($matcher.inc_occurrences_of(&*vec))); | |
041b39d2 XL |
154 | if $_self.cache.map_or(true, |name| name != $p.b.name) { |
155 | arg_post_processing!($_self, $p, $matcher); | |
156 | $_self.cache = Some($p.b.name); | |
157 | } | |
158 | ||
159 | $_self.settings.set(AS::ValidArgFound); | |
8bb4bdeb XL |
160 | // Only increment the positional counter if it doesn't allow multiples |
161 | if !$p.b.settings.is_set(ArgSettings::Multiple) { | |
162 | $pos_counter += 1; | |
163 | } | |
164 | }; | |
165 | } |