]> git.proxmox.com Git - rustc.git/blob - src/vendor/clap/src/app/parser.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / vendor / clap / src / app / parser.rs
1 // Std
2 use std::collections::{BTreeMap, HashMap, VecDeque};
3 use std::ffi::{OsStr, OsString};
4 use std::fmt::Display;
5 use std::fs::File;
6 use std::io::{self, BufWriter, Write};
7 #[cfg(feature = "debug")]
8 use std::os::unix::ffi::OsStrExt;
9 use std::path::PathBuf;
10 use std::slice::Iter;
11 use std::iter::Peekable;
12
13 // Third Party
14 use vec_map::{self, VecMap};
15
16 // Internal
17 use INTERNAL_ERROR_MSG;
18 use INVALID_UTF8;
19 use SubCommand;
20 use app::App;
21 use app::help::Help;
22 use app::meta::AppMeta;
23 use app::settings::{AppFlags, AppSettings};
24 use args::{AnyArg, ArgMatcher, Base, Switched, Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder};
25 use args::MatchedArg;
26 use args::settings::ArgSettings;
27 use completions::ComplGen;
28 use errors::{Error, ErrorKind};
29 use errors::Result as ClapResult;
30 use fmt::{Colorizer, ColorWhen};
31 use osstringext::OsStrExt2;
32 use completions::Shell;
33 use suggestions;
34
35 #[allow(missing_debug_implementations)]
36 #[doc(hidden)]
37 pub struct Parser<'a, 'b>
38 where 'a: 'b
39 {
40 propogated: bool,
41 required: Vec<&'a str>,
42 r_ifs: Vec<(&'a str, &'b str, &'a str)>,
43 pub short_list: Vec<char>,
44 pub long_list: Vec<&'b str>,
45 blacklist: Vec<&'b str>,
46 // A list of possible flags
47 pub flags: Vec<FlagBuilder<'a, 'b>>,
48 // A list of possible options
49 pub opts: Vec<OptBuilder<'a, 'b>>,
50 // A list of positional arguments
51 pub positionals: VecMap<PosBuilder<'a, 'b>>,
52 // A list of subcommands
53 #[doc(hidden)]
54 pub subcommands: Vec<App<'a, 'b>>,
55 groups: HashMap<&'a str, ArgGroup<'a>>,
56 pub global_args: Vec<Arg<'a, 'b>>,
57 overrides: Vec<&'b str>,
58 help_short: Option<char>,
59 version_short: Option<char>,
60 settings: AppFlags,
61 pub g_settings: AppFlags,
62 pub meta: AppMeta<'b>,
63 pub id: usize,
64 trailing_vals: bool,
65 valid_neg_num: bool,
66 // have we found a valid arg yet
67 valid_arg: bool,
68 }
69
70 impl<'a, 'b> Default for Parser<'a, 'b> {
71 fn default() -> Self {
72 Parser {
73 propogated: false,
74 flags: vec![],
75 opts: vec![],
76 positionals: VecMap::new(),
77 subcommands: vec![],
78 help_short: None,
79 version_short: None,
80 required: vec![],
81 r_ifs: vec![],
82 short_list: vec![],
83 long_list: vec![],
84 blacklist: vec![],
85 groups: HashMap::new(),
86 global_args: vec![],
87 overrides: vec![],
88 g_settings: AppFlags::new(),
89 settings: AppFlags::new(),
90 meta: AppMeta::new(),
91 trailing_vals: false,
92 id: 0,
93 valid_neg_num: false,
94 valid_arg: false,
95 }
96 }
97 }
98
99 impl<'a, 'b> Parser<'a, 'b>
100 where 'a: 'b
101 {
102 pub fn with_name(n: String) -> Self {
103 Parser { meta: AppMeta::with_name(n), ..Default::default() }
104 }
105
106 pub fn help_short(&mut self, s: &str) {
107 self.help_short = s.trim_left_matches(|c| c == '-')
108 .chars()
109 .nth(0);
110 }
111
112 pub fn version_short(&mut self, s: &str) {
113 self.version_short = s.trim_left_matches(|c| c == '-')
114 .chars()
115 .nth(0);
116 }
117
118 pub fn gen_completions_to<W: Write>(&mut self, for_shell: Shell, buf: &mut W) {
119 if !self.propogated {
120 self.propogate_help_version();
121 self.build_bin_names();
122 self.propogate_globals();
123 self.propogate_settings();
124 self.propogated = true;
125 }
126
127 ComplGen::new(self).generate(for_shell, buf)
128 }
129
130 pub fn gen_completions(&mut self, for_shell: Shell, od: OsString) {
131 use std::error::Error;
132
133 let out_dir = PathBuf::from(od);
134 let name = &*self.meta.bin_name.as_ref().unwrap().clone();
135 let file_name = match for_shell {
136 Shell::Bash => format!("{}.bash-completion", name),
137 Shell::Fish => format!("{}.fish", name),
138 Shell::Zsh => format!("_{}", name),
139 Shell::PowerShell => format!("_{}.ps1", name),
140 };
141
142 let mut file = match File::create(out_dir.join(file_name)) {
143 Err(why) => panic!("couldn't create completion file: {}", why.description()),
144 Ok(file) => file,
145 };
146 self.gen_completions_to(for_shell, &mut file)
147 }
148
149 // actually adds the arguments
150 pub fn add_arg(&mut self, a: &Arg<'a, 'b>) {
151 debug_assert!(!(self.flags.iter().any(|f| &f.b.name == &a.name) ||
152 self.opts.iter().any(|o| o.b.name == a.name) ||
153 self.positionals.values().any(|p| p.b.name == a.name)),
154 format!("Non-unique argument name: {} is already in use", a.name));
155 if let Some(ref r_ifs) = a.r_ifs {
156 for &(arg, val) in r_ifs {
157 self.r_ifs.push((arg, val, a.name));
158 }
159 }
160 if let Some(ref grps) = a.groups {
161 for g in grps {
162 let ag = self.groups.entry(g).or_insert_with(|| ArgGroup::with_name(g));
163 ag.args.push(a.name);
164 }
165 }
166 if let Some(s) = a.short {
167 debug_assert!(!self.short_list.contains(&s),
168 format!("Argument short must be unique\n\n\t-{} is already in use",
169 s));
170 self.short_list.push(s);
171 }
172 if let Some(l) = a.long {
173 debug_assert!(!self.long_list.contains(&l),
174 format!("Argument long must be unique\n\n\t--{} is already in use",
175 l));
176 self.long_list.push(l);
177 if l == "help" {
178 self.unset(AppSettings::NeedsLongHelp);
179 } else if l == "version" {
180 self.unset(AppSettings::NeedsLongVersion);
181 }
182 }
183 if a.is_set(ArgSettings::Required) {
184 self.required.push(a.name);
185 }
186 if a.index.is_some() || (a.short.is_none() && a.long.is_none()) {
187 let i = if a.index.is_none() {
188 (self.positionals.len() + 1)
189 } else {
190 a.index.unwrap() as usize
191 };
192 debug_assert!(!self.positionals.contains_key(i),
193 format!("Argument \"{}\" has the same index as another positional \
194 argument\n\n\tPerhaps try .multiple(true) to allow one positional argument \
195 to take multiple values",
196 a.name));
197 let pb = PosBuilder::from_arg(a, i as u64, &mut self.required);
198 self.positionals.insert(i, pb);
199 } else if a.is_set(ArgSettings::TakesValue) {
200 let mut ob = OptBuilder::from_arg(a, &mut self.required);
201 let id = self.opts.len();
202 ob.b.id = id;
203 ob.s.unified_ord = self.flags.len() + self.opts.len();
204 self.opts.insert(id, ob);
205 } else {
206 let mut fb = FlagBuilder::from(a);
207 let id = self.flags.len();
208 fb.b.id = id;
209 fb.s.unified_ord = self.flags.len() + self.opts.len();
210 self.flags.insert(id, fb);
211 }
212 if a.is_set(ArgSettings::Global) {
213 debug_assert!(!a.is_set(ArgSettings::Required),
214 format!("Global arguments cannot be required.\n\n\t'{}' is marked as \
215 global and required",
216 a.name));
217 self.global_args.push(a.into());
218 }
219 }
220
221 pub fn add_group(&mut self, group: ArgGroup<'a>) {
222 if group.required {
223 self.required.push(group.name.into());
224 if let Some(ref reqs) = group.requires {
225 self.required.extend_from_slice(reqs);
226 }
227 if let Some(ref bl) = group.conflicts {
228 self.blacklist.extend_from_slice(bl);
229 }
230 }
231 let mut found = false;
232 if let Some(ref mut grp) = self.groups.get_mut(&group.name) {
233 grp.args.extend_from_slice(&group.args);
234 grp.requires = group.requires.clone();
235 grp.conflicts = group.conflicts.clone();
236 grp.required = group.required;
237 found = true;
238 }
239 if !found {
240 self.groups.insert(group.name.into(), group);
241 }
242 }
243
244 pub fn add_subcommand(&mut self, mut subcmd: App<'a, 'b>) {
245 debugln!("Parser::add_subcommand: term_w={:?}, name={}",
246 self.meta.term_w, subcmd.p.meta.name);
247 subcmd.p.meta.term_w = self.meta.term_w;
248 if subcmd.p.meta.name == "help" {
249 self.settings.unset(AppSettings::NeedsSubcommandHelp);
250 }
251
252 self.subcommands.push(subcmd);
253 }
254
255 pub fn propogate_settings(&mut self) {
256 debugln!("Parser::propogate_settings: self={}, g_settings={:#?}",
257 self.meta.name, self.g_settings);
258 for sc in &mut self.subcommands {
259 debugln!("Parser::propogate_settings: sc={}, settings={:#?}, g_settings={:#?}",
260 sc.p.meta.name, sc.p.settings, sc.p.g_settings);
261 // We have to create a new scope in order to tell rustc the borrow of `sc` is
262 // done and to recursively call this method
263 {
264 let vsc = self.settings.is_set(AppSettings::VersionlessSubcommands);
265 let gv = self.settings.is_set(AppSettings::GlobalVersion);
266
267 if vsc {
268 sc.p.settings.set(AppSettings::DisableVersion);
269 }
270 if gv && sc.p.meta.version.is_none() && self.meta.version.is_some() {
271 sc.p.set(AppSettings::GlobalVersion);
272 sc.p.meta.version = Some(self.meta.version.unwrap());
273 }
274 sc.p.settings = sc.p.settings | self.g_settings;
275 sc.p.g_settings = sc.p.g_settings | self.g_settings;
276 }
277 sc.p.propogate_settings();
278 }
279 }
280
281 #[cfg_attr(feature = "lints", allow(needless_borrow))]
282 pub fn derive_display_order(&mut self) {
283 if self.settings.is_set(AppSettings::DeriveDisplayOrder) {
284 let unified = self.settings.is_set(AppSettings::UnifiedHelpMessage);
285 for (i, o) in self.opts
286 .iter_mut()
287 .enumerate()
288 .filter(|&(_, ref o)| o.s.disp_ord == 999) {
289 o.s.disp_ord = if unified { o.s.unified_ord } else { i };
290 }
291 for (i, f) in self.flags
292 .iter_mut()
293 .enumerate()
294 .filter(|&(_, ref f)| f.s.disp_ord == 999) {
295 f.s.disp_ord = if unified { f.s.unified_ord } else { i };
296 }
297 for (i, sc) in &mut self.subcommands
298 .iter_mut()
299 .enumerate()
300 .filter(|&(_, ref sc)| sc.p.meta.disp_ord == 999) {
301 sc.p.meta.disp_ord = i;
302 }
303 }
304 for sc in &mut self.subcommands {
305 sc.p.derive_display_order();
306 }
307 }
308
309 pub fn required(&self) -> Iter<&str> { self.required.iter() }
310
311 pub fn get_required_from(&self,
312 reqs: &[&'a str],
313 matcher: Option<&ArgMatcher<'a>>,
314 extra: Option<&str>)
315 -> VecDeque<String> {
316 debugln!("Parser::get_required_from: reqs={:?}, extra={:?}", reqs, extra);
317 let mut c_flags: Vec<&str> = vec![];
318 let mut c_pos: Vec<&str> = vec![];
319 let mut c_opt: Vec<&str> = vec![];
320 let mut grps: Vec<&str> = vec![];
321 macro_rules! categorize {
322 ($_self:ident, $name:ident, $c_flags:ident, $c_pos:ident, $c_opt:ident, $grps:ident) => {
323 if $_self.flags.iter().any(|f| &f.b.name == $name) {
324 $c_flags.push($name);
325 } else if self.opts.iter().any(|o| &o.b.name == $name) {
326 $c_opt.push($name);
327 } else if self.groups.contains_key($name) {
328 $grps.push($name);
329 } else {
330 $c_pos.push($name);
331 }
332 }
333 };
334 for name in reqs {
335 categorize!(self, name, c_flags, c_pos, c_opt, grps);
336 }
337 if let Some(ref name) = extra {
338 categorize!(self, name, c_flags, c_pos, c_opt, grps);
339 }
340 macro_rules! fill_vecs {
341 ($_self:ident {
342 $t1:ident => $v1:ident => $i1:ident,
343 $t2:ident => $v2:ident => $i2:ident,
344 $t3:ident => $v3:ident => $i3:ident,
345 $gv:ident, $tmp:ident
346 }) => {
347 for a in &$v1 {
348 if let Some(a) = self.$t1.$i1().filter(|arg| &arg.b.name == a).next() {
349 if let Some(ref rl) = a.b.requires {
350 for &(_, r) in rl.iter() {
351 if !reqs.contains(&r) {
352 if $_self.$t1.$i1().any(|t| &t.b.name == &r) {
353 $tmp.push(r);
354 } else if $_self.$t2.$i2().any(|t| &t.b.name == &r) {
355 $v2.push(r);
356 } else if $_self.$t3.$i3().any(|t| &t.b.name == &r) {
357 $v3.push(r);
358 } else if $_self.groups.contains_key(r) {
359 $gv.push(r);
360 }
361 }
362 }
363 }
364 }
365 }
366 $v1.extend(&$tmp);
367 };
368 }
369
370 let mut tmp = vec![];
371 fill_vecs!(self {
372 flags => c_flags => iter,
373 opts => c_opt => iter,
374 positionals => c_pos => values,
375 grps, tmp
376 });
377 tmp.clear();
378 fill_vecs!(self {
379 opts => c_opt => iter,
380 flags => c_flags => iter,
381 positionals => c_pos => values,
382 grps, tmp
383 });
384 tmp.clear();
385 fill_vecs!(self {
386 positionals => c_pos => values,
387 opts => c_opt => iter,
388 flags => c_flags => iter,
389 grps, tmp
390 });
391 let mut ret_val = VecDeque::new();
392 c_pos.dedup();
393 c_flags.dedup();
394 c_opt.dedup();
395 grps.dedup();
396 let args_in_groups = grps.iter()
397 .flat_map(|g| self.arg_names_in_group(g))
398 .collect::<Vec<_>>();
399
400 let pmap = c_pos.into_iter()
401 .filter(|&p| matcher.is_none() || !matcher.as_ref().unwrap().contains(p))
402 .filter_map(|p| self.positionals.values().find(|x| x.b.name == p))
403 .filter(|p| !args_in_groups.contains(&p.b.name))
404 .map(|p| (p.index, p))
405 .collect::<BTreeMap<u64, &PosBuilder>>();// sort by index
406 debugln!("Parser::get_required_from: args_in_groups={:?}", args_in_groups);
407 for &p in pmap.values() {
408 let s = p.to_string();
409 if args_in_groups.is_empty() || !args_in_groups.contains(&&*s) {
410 ret_val.push_back(s);
411 }
412 }
413 macro_rules! write_arg {
414 ($i:expr, $m:ident, $v:ident, $r:ident, $aig:ident) => {
415 for f in $v {
416 if $m.is_some() && $m.as_ref().unwrap().contains(f) || $aig.contains(&f) {
417 continue;
418 }
419 $r.push_back($i.filter(|flg| &flg.b.name == &f).next().unwrap().to_string());
420 }
421 }
422 }
423 write_arg!(self.flags.iter(), matcher, c_flags, ret_val, args_in_groups);
424 write_arg!(self.opts.iter(), matcher, c_opt, ret_val, args_in_groups);
425 let mut g_vec = vec![];
426 for g in grps {
427 let g_string = self.args_in_group(g)
428 .join("|");
429 g_vec.push(format!("<{}>", &g_string[..g_string.len()]));
430 }
431 g_vec.dedup();
432 for g in g_vec {
433 ret_val.push_back(g);
434 }
435
436 ret_val
437 }
438
439 // Gets the `[ARGS]` tag for the usage string
440 pub fn get_args_tag(&self) -> Option<String> {
441 debugln!("Parser::get_args_tag;");
442 let mut count = 0;
443 'outer: for p in self.positionals.values().filter(|p| !p.is_set(ArgSettings::Required)) {
444 debugln!("Parser::get_args_tag:iter:iter: p={};", p.b.name);
445 if let Some(g_vec) = self.groups_for_arg(p.b.name) {
446 for grp_s in &g_vec {
447 debugln!("Parser::get_args_tag:iter:iter: grp_s={};", grp_s);
448 if let Some(grp) = self.groups.get(grp_s) {
449 debug!("Parser::get_args_tag:iter:iter: Is group required...{:?}", grp.required);
450 if grp.required {
451 // if it's part of a required group we don't want to count it
452 continue 'outer;
453 }
454 }
455 }
456 }
457 count += 1;
458 debugln!("Parser::get_args_tag:iter: {} Args not required", count);
459 }
460 if !self.is_set(AppSettings::DontCollapseArgsInUsage) &&
461 (count > 1 || self.positionals.len() > 1) {
462 return None; // [ARGS]
463 } else if count == 1 {
464 let p = self.positionals
465 .values()
466 .find(|p| !p.is_set(ArgSettings::Required))
467 .expect(INTERNAL_ERROR_MSG);
468 return Some(format!(" [{}]{}", p.name_no_brackets(), p.multiple_str()));
469 } else if self.is_set(AppSettings::DontCollapseArgsInUsage) &&
470 !self.positionals.is_empty() {
471 return Some(self.positionals
472 .values()
473 .filter(|p| !p.is_set(ArgSettings::Required))
474 .map(|p| format!(" [{}]{}", p.name_no_brackets(), p.multiple_str()))
475 .collect::<Vec<_>>()
476 .join(""));
477 }
478 Some("".into())
479 }
480
481 // Determines if we need the `[FLAGS]` tag in the usage string
482 pub fn needs_flags_tag(&self) -> bool {
483 debugln!("Parser::needs_flags_tag;");
484 'outer: for f in &self.flags {
485 debugln!("Parser::needs_flags_tag:iter: f={};", f.b.name);
486 if let Some(l) = f.s.long {
487 if l == "help" || l == "version" {
488 // Don't print `[FLAGS]` just for help or version
489 continue;
490 }
491 }
492 if let Some(g_vec) = self.groups_for_arg(f.b.name) {
493 for grp_s in &g_vec {
494 debugln!("Parser::needs_flags_tag:iter:iter: grp_s={};", grp_s);
495 if let Some(grp) = self.groups.get(grp_s) {
496 debug!("Parser::needs_flags_tag:iter:iter: Is group required...{:?}", grp.required);
497 if grp.required {
498 continue 'outer;
499 }
500 }
501 }
502 }
503 debugln!("Parser::needs_flags_tag:iter: [FLAGS] required");
504 return true;
505 }
506
507 debugln!("Parser::needs_flags_tag: [FLAGS] not required");
508 false
509 }
510
511 #[inline]
512 pub fn has_opts(&self) -> bool { !self.opts.is_empty() }
513
514 #[inline]
515 pub fn has_flags(&self) -> bool { !self.flags.is_empty() }
516
517 #[inline]
518 pub fn has_positionals(&self) -> bool { !self.positionals.is_empty() }
519
520 #[inline]
521 pub fn has_subcommands(&self) -> bool { !self.subcommands.is_empty() }
522
523 #[inline]
524 pub fn is_set(&self, s: AppSettings) -> bool { self.settings.is_set(s) }
525
526 #[inline]
527 pub fn set(&mut self, s: AppSettings) { self.settings.set(s) }
528
529 #[inline]
530 pub fn unset(&mut self, s: AppSettings) { self.settings.unset(s) }
531
532 #[cfg_attr(feature = "lints", allow(block_in_if_condition_stmt))]
533 pub fn verify_positionals(&mut self) {
534 // Because you must wait until all arguments have been supplied, this is the first chance
535 // to make assertions on positional argument indexes
536 //
537 // Firt we verify that the index highest supplied index, is equal to the number of
538 // positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3
539 // but no 2)
540 if let Some((idx, p)) = self.positionals.iter().rev().next() {
541 debug_assert!(!(idx != self.positionals.len()),
542 format!("Found positional argument \"{}\" who's index is {} but there are \
543 only {} positional arguments defined",
544 p.b.name,
545 idx,
546 self.positionals.len()));
547 }
548
549 // Next we verify that only the highest index has a .multiple(true) (if any)
550 if self.positionals
551 .values()
552 .any(|a| {
553 a.b.settings.is_set(ArgSettings::Multiple) &&
554 (a.index as usize != self.positionals.len())
555 }) {
556
557 debug_assert!({
558 let mut it = self.positionals.values().rev();
559 // Either the final positional is required
560 it.next().unwrap().is_set(ArgSettings::Required)
561 // Or the second to last has a terminator set
562 || it.next().unwrap().v.terminator.is_some()
563 },
564 "When using a positional argument with .multiple(true) that is *not the last* \
565 positional argument, the last positional argument (i.e the one with the highest \
566 index) *must* have .required(true) set."
567 );
568
569 debug_assert!({
570 let num = self.positionals.len() - 1;
571 self.positionals.get(num).unwrap().is_set(ArgSettings::Multiple)
572 },
573 "Only the last positional argument, or second to last positional argument may be set to .multiple(true)");
574
575 self.set(AppSettings::LowIndexMultiplePositional);
576 }
577
578 debug_assert!(self.positionals.values()
579 .filter(|p| p.b.settings.is_set(ArgSettings::Multiple)
580 && p.v.num_vals.is_none())
581 .map(|_| 1)
582 .sum::<u64>() <= 1,
583 "Only one positional argument with .multiple(true) set is allowed per command");
584
585 // If it's required we also need to ensure all previous positionals are
586 // required too
587 if self.is_set(AppSettings::AllowMissingPositional) {
588 let mut found = false;
589 let mut foundx2 = false;
590 for p in self.positionals.values().rev() {
591 if foundx2 && !p.b.settings.is_set(ArgSettings::Required) {
592 // [arg1] <arg2> is Ok
593 // [arg1] <arg2> <arg3> Is not
594 debug_assert!(p.b.settings.is_set(ArgSettings::Required),
595 "Found positional argument which is not required with a lower index \
596 than a required positional argument by two or more: {:?} index {}",
597 p.b.name,
598 p.index);
599 } else if p.b.settings.is_set(ArgSettings::Required) {
600 if found {
601 foundx2 = true;
602 continue;
603 }
604 found = true;
605 continue;
606 } else {
607 found = false;
608 }
609 }
610 } else {
611 let mut found = false;
612 for p in self.positionals.values().rev() {
613 if found {
614 debug_assert!(p.b.settings.is_set(ArgSettings::Required),
615 "Found positional argument which is not required with a lower index \
616 than a required positional argument: {:?} index {}",
617 p.b.name,
618 p.index);
619 } else if p.b.settings.is_set(ArgSettings::Required) {
620 found = true;
621 continue;
622 }
623 }
624 }
625 }
626
627 pub fn propogate_globals(&mut self) {
628 for sc in &mut self.subcommands {
629 // We have to create a new scope in order to tell rustc the borrow of `sc` is
630 // done and to recursively call this method
631 {
632 for a in &self.global_args {
633 sc.p.add_arg(a);
634 }
635 }
636 sc.p.propogate_globals();
637 }
638 }
639
640 // Checks if the arg matches a subcommand name, or any of it's aliases (if defined)
641 #[inline]
642 fn possible_subcommand(&self, arg_os: &OsStr) -> bool {
643 debugln!("Parser::possible_subcommand: arg={:?}", arg_os);
644 if self.is_set(AppSettings::ArgsNegateSubcommands) && self.valid_arg {
645 return false;
646 }
647 self.subcommands
648 .iter()
649 .any(|s| {
650 &s.p.meta.name[..] == &*arg_os ||
651 (s.p.meta.aliases.is_some() &&
652 s.p
653 .meta
654 .aliases
655 .as_ref()
656 .unwrap()
657 .iter()
658 .any(|&(a, _)| a == &*arg_os))
659 })
660 }
661
662 fn parse_help_subcommand<I, T>(&self, it: &mut I) -> ClapResult<()>
663 where I: Iterator<Item = T>,
664 T: Into<OsString>
665 {
666 debugln!("Parser::parse_help_subcommand;");
667 let cmds: Vec<OsString> = it.map(|c| c.into()).collect();
668 let mut help_help = false;
669 let mut bin_name = self.meta
670 .bin_name
671 .as_ref()
672 .unwrap_or(&self.meta.name)
673 .clone();
674 let mut sc = {
675 let mut sc: &Parser = self;
676 for (i, cmd) in cmds.iter().enumerate() {
677 if &*cmd.to_string_lossy() == "help" {
678 // cmd help help
679 help_help = true;
680 }
681 if let Some(c) = sc.subcommands
682 .iter()
683 .find(|s| &*s.p.meta.name == cmd)
684 .map(|sc| &sc.p) {
685 sc = c;
686 if i == cmds.len() - 1 {
687 break;
688 }
689 } else if let Some(c) = sc.subcommands
690 .iter()
691 .find(|s| if let Some(ref als) = s.p
692 .meta
693 .aliases {
694 als.iter()
695 .any(|&(a, _)| &a == &&*cmd.to_string_lossy())
696 } else {
697 false
698 })
699 .map(|sc| &sc.p) {
700 sc = c;
701 if i == cmds.len() - 1 {
702 break;
703 }
704 } else {
705 return Err(Error::unrecognized_subcommand(cmd.to_string_lossy().into_owned(),
706 self.meta
707 .bin_name
708 .as_ref()
709 .unwrap_or(&self.meta.name),
710 self.color()));
711 }
712 bin_name = format!("{} {}",
713 bin_name,
714 &*sc.meta.name);
715 }
716 sc.clone()
717 };
718 if help_help {
719 let mut pb = PosBuilder::new("subcommand", 1);
720 pb.b.help = Some("The subcommand whose help message to display");
721 pb.set(ArgSettings::Multiple);
722 sc.positionals.insert(1, pb);
723 sc.settings = sc.settings | self.g_settings;
724 } else {
725 sc.create_help_and_version();
726 }
727 if sc.meta.bin_name != self.meta.bin_name {
728 sc.meta.bin_name = Some(format!("{} {}", bin_name, sc.meta.name));
729 }
730 sc._help()
731 }
732
733 // allow wrong self convention due to self.valid_neg_num = true and it's a private method
734 #[cfg_attr(feature = "lints", allow(wrong_self_convention))]
735 #[inline]
736 fn is_new_arg(&mut self, arg_os: &OsStr, needs_val_of: Option<&'a str>) -> bool {
737 debugln!("Parser::is_new_arg: arg={:?}, Needs Val of={:?}", arg_os, needs_val_of);
738 let app_wide_settings = if self.is_set(AppSettings::AllowLeadingHyphen) {
739 true
740 } else if self.is_set(AppSettings::AllowNegativeNumbers) {
741 let a = arg_os.to_string_lossy();
742 if a.parse::<i64>().is_ok() || a.parse::<f64>().is_ok() {
743 self.valid_neg_num = true;
744 true
745 } else {
746 false
747 }
748 } else {
749 false
750 };
751 let arg_allows_tac = if let Some(name) = needs_val_of {
752 if let Some(o) = find_by_name!(self, &name, opts, iter) {
753 (o.is_set(ArgSettings::AllowLeadingHyphen) || app_wide_settings)
754 } else if let Some(p) = find_by_name!(self, &name, positionals, values) {
755 (p.is_set(ArgSettings::AllowLeadingHyphen) || app_wide_settings)
756 } else {
757 false
758 }
759 } else {
760 false
761 };
762 debugln!("Parser::is_new_arg: Does arg allow leading hyphen...{:?}", arg_allows_tac);
763
764 // Is this a new argument, or values from a previous option?
765 debug!("Parser::is_new_arg: Starts new arg...");
766 let mut ret = if arg_os.starts_with(b"--") {
767 sdebugln!("--");
768 if arg_os.len_() == 2 {
769 return true; // We have to return true so override everything else
770 }
771 true
772 } else if arg_os.starts_with(b"-") {
773 sdebugln!("-");
774 // a singe '-' by itself is a value and typically means "stdin" on unix systems
775 !(arg_os.len_() == 1)
776 } else {
777 sdebugln!("Probable value");
778 false
779 };
780
781 ret = ret && !arg_allows_tac;
782
783 debugln!("Parser::is_new_arg: Starts new arg...{:?}", ret);
784 ret
785 }
786
787 // The actual parsing function
788 #[cfg_attr(feature = "lints", allow(while_let_on_iterator, collapsible_if))]
789 pub fn get_matches_with<I, T>(&mut self,
790 matcher: &mut ArgMatcher<'a>,
791 it: &mut Peekable<I>)
792 -> ClapResult<()>
793 where I: Iterator<Item = T>,
794 T: Into<OsString> + Clone
795 {
796 debugln!("Parser::get_matches_with;");
797 // Verify all positional assertions pass
798 self.verify_positionals();
799
800 // Next we create the `--help` and `--version` arguments and add them if
801 // necessary
802 self.create_help_and_version();
803
804 let mut subcmd_name: Option<String> = None;
805 let mut needs_val_of: Option<&'a str> = None;
806 let mut pos_counter = 1;
807 while let Some(arg) = it.next() {
808 let arg_os = arg.into();
809 debugln!("Parser::get_matches_with: Begin parsing '{:?}' ({:?})", arg_os, &*arg_os.as_bytes());
810
811 self.valid_neg_num = false;
812 // Is this a new argument, or values from a previous option?
813 let starts_new_arg = self.is_new_arg(&arg_os, needs_val_of);
814
815 // Has the user already passed '--'? Meaning only positional args follow
816 if !self.trailing_vals {
817 // Does the arg match a subcommand name, or any of it's aliases (if defined)
818 if self.possible_subcommand(&arg_os) {
819 if &*arg_os == "help" && self.is_set(AppSettings::NeedsSubcommandHelp) {
820 try!(self.parse_help_subcommand(it));
821 }
822 subcmd_name = Some(arg_os.to_str().expect(INVALID_UTF8).to_owned());
823 break;
824 }
825
826 if !starts_new_arg {
827 if let Some(name) = needs_val_of {
828 // Check to see if parsing a value from a previous arg
829 if let Some(arg) = find_by_name!(self, &name, opts, iter) {
830 // get the OptBuilder so we can check the settings
831 needs_val_of = try!(self.add_val_to_arg(&*arg, &arg_os, matcher));
832 // get the next value from the iterator
833 continue;
834 }
835 }
836 } else {
837 if arg_os.starts_with(b"--") {
838 if arg_os.len_() == 2 {
839 // The user has passed '--' which means only positional args follow no
840 // matter what they start with
841 self.trailing_vals = true;
842 continue;
843 }
844
845 needs_val_of = try!(self.parse_long_arg(matcher, &arg_os));
846 if !(needs_val_of.is_none() && self.is_set(AppSettings::AllowLeadingHyphen)) {
847 continue;
848 }
849 } else if arg_os.starts_with(b"-") && arg_os.len_() != 1 {
850 // Try to parse short args like normal, if AllowLeadingHyphen or
851 // AllowNegativeNumbers is set, parse_short_arg will *not* throw
852 // an error, and instead return Ok(None)
853 needs_val_of = try!(self.parse_short_arg(matcher, &arg_os));
854 // If it's None, we then check if one of those two AppSettings was set
855 if needs_val_of.is_none() {
856 if self.is_set(AppSettings::AllowNegativeNumbers) {
857 if !(arg_os.to_string_lossy().parse::<i64>().is_ok() ||
858 arg_os.to_string_lossy().parse::<f64>().is_ok()) {
859 return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
860 "",
861 &*self.create_current_usage(matcher, None),
862 self.color()));
863 }
864 } else if !self.is_set(AppSettings::AllowLeadingHyphen) {
865 continue;
866 }
867 } else {
868 continue;
869 }
870 }
871 }
872
873 if !self.is_set(AppSettings::ArgsNegateSubcommands) {
874 if let Some(cdate) =
875 suggestions::did_you_mean(&*arg_os.to_string_lossy(),
876 self.subcommands
877 .iter()
878 .map(|s| &s.p.meta.name)) {
879 return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(),
880 cdate,
881 self.meta
882 .bin_name
883 .as_ref()
884 .unwrap_or(&self.meta.name),
885 &*self.create_current_usage(matcher, None),
886 self.color()));
887 }
888 }
889 }
890
891 let low_index_mults = self.is_set(AppSettings::LowIndexMultiplePositional) &&
892 !self.positionals.is_empty() &&
893 pos_counter == (self.positionals.len() - 1);
894 let missing_pos = self.is_set(AppSettings::AllowMissingPositional) &&
895 !self.positionals.is_empty() &&
896 pos_counter == (self.positionals.len() - 1);
897 debugln!("Parser::get_matches_with: Low index multiples...{:?}", low_index_mults);
898 debugln!("Parser::get_matches_with: Positional counter...{}", pos_counter);
899 if low_index_mults || missing_pos {
900 if let Some(na) = it.peek() {
901 let n = (*na).clone().into();
902 needs_val_of = if needs_val_of.is_none() {
903 if let Some(p) = self.positionals.get(pos_counter) {
904 Some(p.b.name)
905 } else {
906 None
907 }
908 } else {
909 None
910 };
911 if self.is_new_arg(&n, needs_val_of) || self.possible_subcommand(&n) ||
912 suggestions::did_you_mean(&n.to_string_lossy(),
913 self.subcommands
914 .iter()
915 .map(|s| &s.p.meta.name))
916 .is_some() {
917 debugln!("Parser::get_matches_with: Bumping the positional counter...");
918 pos_counter += 1;
919 }
920 } else {
921 debugln!("Parser::get_matches_with: Bumping the positional counter...");
922 pos_counter += 1;
923 }
924 }
925 if let Some(p) = self.positionals.get(pos_counter) {
926 parse_positional!(self, p, arg_os, pos_counter, matcher);
927 self.valid_arg = true;
928 } else if self.settings.is_set(AppSettings::AllowExternalSubcommands) {
929 // Get external subcommand name
930 let sc_name = match arg_os.to_str() {
931 Some(s) => s.to_string(),
932 None => {
933 if !self.settings.is_set(AppSettings::StrictUtf8) {
934 return Err(Error::invalid_utf8(&*self.create_current_usage(matcher, None),
935 self.color()));
936 }
937 arg_os.to_string_lossy().into_owned()
938 }
939 };
940
941 // Collect the external subcommand args
942 let mut sc_m = ArgMatcher::new();
943 while let Some(v) = it.next() {
944 let a = v.into();
945 if a.to_str().is_none() && !self.settings.is_set(AppSettings::StrictUtf8) {
946 return Err(Error::invalid_utf8(&*self.create_current_usage(matcher, None),
947 self.color()));
948 }
949 sc_m.add_val_to("", &a);
950 }
951
952 matcher.subcommand(SubCommand {
953 name: sc_name,
954 matches: sc_m.into(),
955 });
956 } else if !(self.is_set(AppSettings::AllowLeadingHyphen) ||
957 self.is_set(AppSettings::AllowNegativeNumbers)) {
958 return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
959 "",
960 &*self.create_current_usage(matcher, None),
961 self.color()));
962 }
963 }
964
965 if let Some(ref pos_sc_name) = subcmd_name {
966 // is this is a real subcommand, or an alias
967 if self.subcommands.iter().any(|sc| &sc.p.meta.name == pos_sc_name) {
968 try!(self.parse_subcommand(&*pos_sc_name, matcher, it));
969 } else {
970 let sc_name = &*self.subcommands
971 .iter()
972 .filter(|sc| sc.p.meta.aliases.is_some())
973 .filter(|sc| {
974 sc.p
975 .meta
976 .aliases
977 .as_ref()
978 .expect(INTERNAL_ERROR_MSG)
979 .iter()
980 .any(|&(a, _)| &a == &&*pos_sc_name)
981 })
982 .map(|sc| sc.p.meta.name.clone())
983 .next()
984 .expect(INTERNAL_ERROR_MSG);
985 try!(self.parse_subcommand(sc_name, matcher, it));
986 }
987 } else if self.is_set(AppSettings::SubcommandRequired) {
988 let bn = self.meta.bin_name.as_ref().unwrap_or(&self.meta.name);
989 return Err(Error::missing_subcommand(bn,
990 &self.create_current_usage(matcher, None),
991 self.color()));
992 } else if self.is_set(AppSettings::SubcommandRequiredElseHelp) {
993 debugln!("parser::get_matches_with: SubcommandRequiredElseHelp=true");
994 let mut out = vec![];
995 try!(self.write_help_err(&mut out));
996 return Err(Error {
997 message: String::from_utf8_lossy(&*out).into_owned(),
998 kind: ErrorKind::MissingArgumentOrSubcommand,
999 info: None,
1000 });
1001 }
1002
1003 self.validate(needs_val_of, subcmd_name, matcher)
1004 }
1005
1006 fn validate(&mut self,
1007 needs_val_of: Option<&'a str>,
1008 subcmd_name: Option<String>,
1009 matcher: &mut ArgMatcher<'a>)
1010 -> ClapResult<()> {
1011 debugln!("Parser::validate;");
1012 let mut reqs_validated = false;
1013 try!(self.add_defaults(matcher));
1014 if let Some(a) = needs_val_of {
1015 debugln!("Parser::validate: needs_val_of={:?}", a);
1016 if let Some(o) = find_by_name!(self, &a, opts, iter) {
1017 try!(self.validate_required(matcher));
1018 reqs_validated = true;
1019 let should_err = if let Some(v) = matcher.0.args.get(&*o.b.name) {
1020 v.vals.is_empty() && !(o.v.min_vals.is_some() && o.v.min_vals.unwrap() == 0)
1021 } else {
1022 true
1023 };
1024 if should_err {
1025 return Err(Error::empty_value(o,
1026 &*self.create_current_usage(matcher, None),
1027 self.color()));
1028 }
1029 }
1030 }
1031
1032 try!(self.validate_blacklist(matcher));
1033 if !(self.settings.is_set(AppSettings::SubcommandsNegateReqs) && subcmd_name.is_some()) &&
1034 !reqs_validated {
1035 try!(self.validate_required(matcher));
1036 }
1037 try!(self.validate_matched_args(matcher));
1038 matcher.usage(self.create_usage(&[]));
1039
1040 if matcher.is_empty() && matcher.subcommand_name().is_none() &&
1041 self.is_set(AppSettings::ArgRequiredElseHelp) {
1042 let mut out = vec![];
1043 try!(self.write_help_err(&mut out));
1044 return Err(Error {
1045 message: String::from_utf8_lossy(&*out).into_owned(),
1046 kind: ErrorKind::MissingArgumentOrSubcommand,
1047 info: None,
1048 });
1049 }
1050 Ok(())
1051 }
1052
1053 fn propogate_help_version(&mut self) {
1054 debugln!("Parser::propogate_help_version;");
1055 self.create_help_and_version();
1056 for sc in &mut self.subcommands {
1057 sc.p.propogate_help_version();
1058 }
1059 }
1060
1061 fn build_bin_names(&mut self) {
1062 debugln!("Parser::build_bin_names;");
1063 for sc in &mut self.subcommands {
1064 debug!("Parser::build_bin_names:iter: bin_name set...");
1065 if sc.p.meta.bin_name.is_none() {
1066 sdebugln!("No");
1067 let bin_name = format!("{}{}{}",
1068 self.meta
1069 .bin_name
1070 .as_ref()
1071 .unwrap_or(&self.meta.name.clone()),
1072 if self.meta.bin_name.is_some() {
1073 " "
1074 } else {
1075 ""
1076 },
1077 &*sc.p.meta.name);
1078 debugln!("Parser::build_bin_names:iter: Setting bin_name of {} to {}", self.meta.name, bin_name);
1079 sc.p.meta.bin_name = Some(bin_name);
1080 } else {
1081 sdebugln!("yes ({:?})", sc.p.meta.bin_name);
1082 }
1083 debugln!("Parser::build_bin_names:iter: Calling build_bin_names from...{}", sc.p.meta.name);
1084 sc.p.build_bin_names();
1085 }
1086 }
1087
1088 fn parse_subcommand<I, T>(&mut self,
1089 sc_name: &str,
1090 matcher: &mut ArgMatcher<'a>,
1091 it: &mut Peekable<I>)
1092 -> ClapResult<()>
1093 where I: Iterator<Item = T>,
1094 T: Into<OsString> + Clone
1095 {
1096 use std::fmt::Write;
1097 debugln!("Parser::parse_subcommand;");
1098 let mut mid_string = String::new();
1099 if !self.settings.is_set(AppSettings::SubcommandsNegateReqs) {
1100 let mut hs: Vec<&str> = self.required.iter().map(|n| &**n).collect();
1101 for k in matcher.arg_names() {
1102 hs.push(k);
1103 }
1104 let reqs = self.get_required_from(&hs, Some(matcher), None);
1105
1106 for s in &reqs {
1107 write!(&mut mid_string, " {}", s).expect(INTERNAL_ERROR_MSG);
1108 }
1109 }
1110 mid_string.push_str(" ");
1111 if let Some(ref mut sc) = self.subcommands
1112 .iter_mut()
1113 .find(|s| &s.p.meta.name == &sc_name) {
1114 let mut sc_matcher = ArgMatcher::new();
1115 // bin_name should be parent's bin_name + [<reqs>] + the sc's name separated by
1116 // a space
1117 sc.p.meta.usage = Some(format!("{}{}{}",
1118 self.meta.bin_name.as_ref().unwrap_or(&String::new()),
1119 if self.meta.bin_name.is_some() {
1120 &*mid_string
1121 } else {
1122 ""
1123 },
1124 &*sc.p.meta.name));
1125 sc.p.meta.bin_name = Some(format!("{}{}{}",
1126 self.meta
1127 .bin_name
1128 .as_ref()
1129 .unwrap_or(&String::new()),
1130 if self.meta.bin_name.is_some() {
1131 " "
1132 } else {
1133 ""
1134 },
1135 &*sc.p.meta.name));
1136 debugln!("Parser::parse_subcommand: About to parse sc={}", sc.p.meta.name);
1137 debugln!("Parser::parse_subcommand: sc settings={:#?}", sc.p.settings);
1138 try!(sc.p.get_matches_with(&mut sc_matcher, it));
1139 matcher.subcommand(SubCommand {
1140 name: sc.p.meta.name.clone(),
1141 matches: sc_matcher.into(),
1142 });
1143 }
1144 Ok(())
1145 }
1146
1147
1148 fn groups_for_arg(&self, name: &str) -> Option<Vec<&'a str>> {
1149 debugln!("Parser::groups_for_arg: name={}", name);
1150
1151 if self.groups.is_empty() {
1152 debugln!("Parser::groups_for_arg: No groups defined");
1153 return None;
1154 }
1155 let mut res = vec![];
1156 debugln!("Parser::groups_for_arg: Searching through groups...");
1157 for (gn, grp) in &self.groups {
1158 for a in &grp.args {
1159 if a == &name {
1160 sdebugln!("\tFound '{}'", gn);
1161 res.push(*gn);
1162 }
1163 }
1164 }
1165 if res.is_empty() {
1166 return None;
1167 }
1168
1169 Some(res)
1170 }
1171
1172 fn args_in_group(&self, group: &str) -> Vec<String> {
1173 let mut g_vec = vec![];
1174 let mut args = vec![];
1175
1176 for n in &self.groups[group].args {
1177 if let Some(f) = self.flags.iter().find(|f| &f.b.name == n) {
1178 args.push(f.to_string());
1179 } else if let Some(f) = self.opts.iter().find(|o| &o.b.name == n) {
1180 args.push(f.to_string());
1181 } else if self.groups.contains_key(&**n) {
1182 g_vec.push(*n);
1183 } else if let Some(p) = self.positionals
1184 .values()
1185 .find(|p| &p.b.name == n) {
1186 args.push(p.b.name.to_owned());
1187 }
1188 }
1189
1190 for av in g_vec.iter().map(|g| self.args_in_group(g)) {
1191 args.extend(av);
1192 }
1193 args.dedup();
1194 args.iter().map(ToOwned::to_owned).collect()
1195 }
1196
1197 fn arg_names_in_group(&self, group: &str) -> Vec<&'a str> {
1198 let mut g_vec = vec![];
1199 let mut args = vec![];
1200
1201 for n in &self.groups[group].args {
1202 if self.groups.contains_key(&*n) {
1203 g_vec.push(*n);
1204 } else {
1205 args.push(*n);
1206 }
1207 }
1208
1209 for av in g_vec.iter().map(|g| self.arg_names_in_group(g)) {
1210 args.extend(av);
1211 }
1212 args.dedup();
1213 args.iter().map(|s| *s).collect()
1214 }
1215
1216 pub fn create_help_and_version(&mut self) {
1217 debugln!("Parser::create_help_and_version;");
1218 // name is "hclap_help" because flags are sorted by name
1219 if self.is_set(AppSettings::NeedsLongHelp) {
1220 debugln!("Parser::create_help_and_version: Building --help");
1221 if self.help_short.is_none() && !self.short_list.contains(&'h') {
1222 self.help_short = Some('h');
1223 }
1224 let id = self.flags.len();
1225 let arg = FlagBuilder {
1226 b: Base {
1227 name: "hclap_help",
1228 help: Some("Prints help information"),
1229 id: id,
1230 ..Default::default()
1231 },
1232 s: Switched {
1233 short: self.help_short,
1234 long: Some("help"),
1235 ..Default::default()
1236 },
1237 };
1238 if let Some(h) = self.help_short {
1239 self.short_list.push(h);
1240 }
1241 self.long_list.push("help");
1242 self.flags.insert(id, arg);
1243 }
1244 if !self.settings.is_set(AppSettings::DisableVersion) &&
1245 self.is_set(AppSettings::NeedsLongVersion) {
1246 debugln!("Parser::create_help_and_version: Building --version");
1247 if self.version_short.is_none() && !self.short_list.contains(&'V') {
1248 self.version_short = Some('V');
1249 }
1250 let id = self.flags.len();
1251 // name is "vclap_version" because flags are sorted by name
1252 let arg = FlagBuilder {
1253 b: Base {
1254 name: "vclap_version",
1255 help: Some("Prints version information"),
1256 id: id,
1257 ..Default::default()
1258 },
1259 s: Switched {
1260 short: self.version_short,
1261 long: Some("version"),
1262 ..Default::default()
1263 },
1264 };
1265 if let Some(v) = self.version_short {
1266 self.short_list.push(v);
1267 }
1268 self.long_list.push("version");
1269 self.flags.insert(id, arg);
1270 }
1271 if !self.subcommands.is_empty() && !self.is_set(AppSettings::DisableHelpSubcommand) &&
1272 self.is_set(AppSettings::NeedsSubcommandHelp) {
1273 debugln!("Parser::create_help_and_version: Building help");
1274 self.subcommands
1275 .push(App::new("help")
1276 .about("Prints this message or the help of the given subcommand(s)"));
1277 }
1278 }
1279
1280 // Retrieves the names of all args the user has supplied thus far, except required ones
1281 // because those will be listed in self.required
1282 pub fn create_current_usage(&self, matcher: &'b ArgMatcher<'a>, extra: Option<&str>) -> String {
1283 let mut args: Vec<_> = matcher.arg_names()
1284 .iter()
1285 .filter(|n| {
1286 if let Some(o) = find_by_name!(self, *n, opts, iter) {
1287 !o.b.settings.is_set(ArgSettings::Required)
1288 } else if let Some(p) = find_by_name!(self, *n, positionals, values) {
1289 !p.b.settings.is_set(ArgSettings::Required)
1290 } else {
1291 true // flags can't be required, so they're always true
1292 }
1293 })
1294 .map(|&n| n)
1295 .collect();
1296 if let Some(r) = extra {
1297 args.push(r);
1298 }
1299 self.create_usage(&*args)
1300 }
1301
1302 fn check_for_help_and_version_str(&self, arg: &OsStr) -> ClapResult<()> {
1303 debugln!("Parser::check_for_help_and_version_str;");
1304 debug!("Parser::check_for_help_and_version_str: Checking if --{} is help or version...",
1305 arg.to_str().unwrap());
1306 if arg == "help" && self.settings.is_set(AppSettings::NeedsLongHelp) {
1307 sdebugln!("Help");
1308 try!(self._help());
1309 }
1310 if arg == "version" && self.settings.is_set(AppSettings::NeedsLongVersion) {
1311 sdebugln!("Version");
1312 try!(self._version());
1313 }
1314 sdebugln!("Neither");
1315
1316 Ok(())
1317 }
1318
1319 fn check_for_help_and_version_char(&self, arg: char) -> ClapResult<()> {
1320 debugln!("Parser::check_for_help_and_version_char;");
1321 debug!("Parser::check_for_help_and_version_char: Checking if -{} is help or version...", arg);
1322 if let Some(h) = self.help_short {
1323 if arg == h && self.settings.is_set(AppSettings::NeedsLongHelp) {
1324 sdebugln!("Help");
1325 try!(self._help());
1326 }
1327 }
1328 if let Some(v) = self.version_short {
1329 if arg == v && self.settings.is_set(AppSettings::NeedsLongVersion) {
1330 sdebugln!("Version");
1331 try!(self._version());
1332 }
1333 }
1334 sdebugln!("Neither");
1335 Ok(())
1336 }
1337
1338 fn _help(&self) -> ClapResult<()> {
1339 let mut buf = vec![];
1340 try!(Help::write_parser_help(&mut buf, self));
1341 Err(Error {
1342 message: unsafe { String::from_utf8_unchecked(buf) },
1343 kind: ErrorKind::HelpDisplayed,
1344 info: None,
1345 })
1346 }
1347
1348 fn _version(&self) -> ClapResult<()> {
1349 let out = io::stdout();
1350 let mut buf_w = BufWriter::new(out.lock());
1351 try!(self.print_version(&mut buf_w));
1352 Err(Error {
1353 message: String::new(),
1354 kind: ErrorKind::VersionDisplayed,
1355 info: None,
1356 })
1357 }
1358
1359 fn parse_long_arg(&mut self,
1360 matcher: &mut ArgMatcher<'a>,
1361 full_arg: &OsStr)
1362 -> ClapResult<Option<&'a str>> {
1363 // maybe here lifetime should be 'a
1364 debugln!("Parser::parse_long_arg;");
1365 let mut val = None;
1366 debug!("Parser::parse_long_arg: Does it contain '='...");
1367 let arg = if full_arg.contains_byte(b'=') {
1368 let (p0, p1) = full_arg.trim_left_matches(b'-').split_at_byte(b'=');
1369 sdebugln!("Yes '{:?}'", p1);
1370 val = Some(p1);
1371 p0
1372 } else {
1373 sdebugln!("No");
1374 full_arg.trim_left_matches(b'-')
1375 };
1376
1377 if let Some(opt) = find_by_long!(self, &arg, opts) {
1378 debugln!("Parser::parse_long_arg: Found valid opt '{}'", opt.to_string());
1379 self.valid_arg = true;
1380 let ret = try!(self.parse_opt(val, opt, matcher));
1381 arg_post_processing!(self, opt, matcher);
1382
1383 return Ok(ret);
1384 } else if let Some(flag) = find_by_long!(self, &arg, flags) {
1385 debugln!("Parser::parse_long_arg: Found valid flag '{}'", flag.to_string());
1386 self.valid_arg = true;
1387 // Only flags could be help or version, and we need to check the raw long
1388 // so this is the first point to check
1389 try!(self.check_for_help_and_version_str(arg));
1390
1391 try!(self.parse_flag(flag, matcher));
1392
1393 // Handle conflicts, requirements, etc.
1394 arg_post_processing!(self, flag, matcher);
1395
1396 return Ok(None);
1397 } else if self.is_set(AppSettings::AllowLeadingHyphen) {
1398 return Ok(None);
1399 } else if self.valid_neg_num {
1400 return Ok(None);
1401 }
1402
1403 debugln!("Parser::parse_long_arg: Didn't match anything");
1404 self.did_you_mean_error(arg.to_str().expect(INVALID_UTF8), matcher).map(|_| None)
1405 }
1406
1407 fn parse_short_arg(&mut self,
1408 matcher: &mut ArgMatcher<'a>,
1409 full_arg: &OsStr)
1410 -> ClapResult<Option<&'a str>> {
1411 debugln!("Parser::parse_short_arg;");
1412 // let mut utf8 = true;
1413 let arg_os = full_arg.trim_left_matches(b'-');
1414 let arg = arg_os.to_string_lossy();
1415
1416 // If AllowLeadingHyphen is set, we want to ensure `-val` gets parsed as `-val` and not `-v` `-a` `-l` assuming
1417 // `v` `a` and `l` are all, or mostly, valid shorts.
1418 if self.is_set(AppSettings::AllowLeadingHyphen) {
1419 let mut good = true;
1420 for c in arg.chars() {
1421 good = self.short_list.contains(&c);
1422 }
1423 if !good {
1424 return Ok(None);
1425 }
1426 } else if self.valid_neg_num {
1427 // TODO: Add docs about having AllowNegativeNumbers and `-2` as a valid short
1428 // May be better to move this to *after* not finding a valid flag/opt?
1429 debugln!("Parser::parse_short_arg: Valid negative num...");
1430 return Ok(None);
1431 }
1432
1433 for c in arg.chars() {
1434 debugln!("Parser::parse_short_arg:iter: short={}", c);
1435 // Check for matching short options, and return the name if there is no trailing
1436 // concatenated value: -oval
1437 // Option: -o
1438 // Value: val
1439 if let Some(opt) = self.opts
1440 .iter()
1441 .find(|&o| o.s.short.is_some() && o.s.short.unwrap() == c) {
1442 debugln!("Parser::parse_short_arg:iter: Found valid short opt -{} in '{}'", c, arg);
1443 self.valid_arg = true;
1444 // Check for trailing concatenated value
1445 let p: Vec<_> = arg.splitn(2, c).collect();
1446 debugln!("Parser::parse_short_arg:iter: arg: {:?}, arg_os: {:?}, full_arg: {:?}",
1447 arg,
1448 arg_os,
1449 full_arg);
1450 debugln!("Parser::parse_short_arg:iter: p[0]: {:?}, p[1]: {:?}", p[0].as_bytes(), p[1].as_bytes());
1451 let i = p[0].as_bytes().len() + 1;
1452 let val = if p[1].as_bytes().len() > 0 {
1453 debugln!("Parser::parse_short_arg:iter: setting val: {:?} (bytes), {:?} (ascii)",
1454 arg_os.split_at(i).1.as_bytes(),
1455 arg_os.split_at(i).1);
1456 Some(arg_os.split_at(i).1)
1457 } else {
1458 None
1459 };
1460
1461 // Default to "we're expecting a value later"
1462 let ret = try!(self.parse_opt(val, opt, matcher));
1463
1464 arg_post_processing!(self, opt, matcher);
1465
1466 return Ok(ret);
1467 } else if let Some(flag) = self.flags
1468 .iter()
1469 .find(|&f| f.s.short.is_some() && f.s.short.unwrap() == c) {
1470 debugln!("Parser::parse_short_arg:iter: Found valid short flag -{}", c);
1471 self.valid_arg = true;
1472 // Only flags can be help or version
1473 try!(self.check_for_help_and_version_char(c));
1474 try!(self.parse_flag(flag, matcher));
1475 // Handle conflicts, requirements, overrides, etc.
1476 // Must be called here due to mutablilty
1477 arg_post_processing!(self, flag, matcher);
1478 } else {
1479 let mut arg = String::new();
1480 arg.push('-');
1481 arg.push(c);
1482 return Err(Error::unknown_argument(&*arg,
1483 "",
1484 &*self.create_current_usage(matcher, None),
1485 self.color()));
1486 }
1487 }
1488 Ok(None)
1489 }
1490
1491 fn parse_opt(&self,
1492 val: Option<&OsStr>,
1493 opt: &OptBuilder<'a, 'b>,
1494 matcher: &mut ArgMatcher<'a>)
1495 -> ClapResult<Option<&'a str>> {
1496 debugln!("Parser::parse_opt;");
1497 validate_multiples!(self, opt, matcher);
1498 let mut has_eq = false;
1499
1500 debug!("Parser::parse_optChecking for val...");
1501 if let Some(fv) = val {
1502 has_eq = fv.starts_with(&[b'=']);
1503 let v = fv.trim_left_matches(b'=');
1504 if !opt.is_set(ArgSettings::EmptyValues) && v.len_() == 0 {
1505 sdebugln!("Found Empty - Error");
1506 return Err(Error::empty_value(opt,
1507 &*self.create_current_usage(matcher, None),
1508 self.color()));
1509 }
1510 sdebugln!("Found - {:?}, len: {}", v, v.len_());
1511 debugln!("Parser::parse_opt: {:?} contains '='...{:?}", fv, fv.starts_with(&[b'=']));
1512 try!(self.add_val_to_arg(opt, v, matcher));
1513 } else {
1514 sdebugln!("None");
1515 }
1516
1517 matcher.inc_occurrence_of(opt.b.name);
1518 // Increment or create the group "args"
1519 self.groups_for_arg(opt.b.name).and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
1520
1521 if val.is_none() ||
1522 !has_eq &&
1523 (opt.is_set(ArgSettings::Multiple) && !opt.is_set(ArgSettings::RequireDelimiter) &&
1524 matcher.needs_more_vals(opt)) {
1525 debugln!("Parser::parse_opt: More arg vals required...");
1526 return Ok(Some(opt.b.name));
1527 }
1528 debugln!("Parser::parse_opt: More arg vals not required...");
1529 Ok(None)
1530 }
1531
1532 fn add_val_to_arg<A>(&self,
1533 arg: &A,
1534 val: &OsStr,
1535 matcher: &mut ArgMatcher<'a>)
1536 -> ClapResult<Option<&'a str>>
1537 where A: AnyArg<'a, 'b> + Display
1538 {
1539 debugln!("Parser::add_val_to_arg;");
1540 let mut ret = None;
1541 if !(self.trailing_vals && self.is_set(AppSettings::DontDelimitTrailingValues)) {
1542 if let Some(delim) = arg.val_delim() {
1543 if val.is_empty_() {
1544 ret = try!(self.add_single_val_to_arg(arg, val, matcher));
1545 } else {
1546 for v in val.split(delim as u32 as u8) {
1547 ret = try!(self.add_single_val_to_arg(arg, v, matcher));
1548 }
1549 // If there was a delimiter used, we're not looking for more values
1550 if val.contains_byte(delim as u32 as u8) ||
1551 arg.is_set(ArgSettings::RequireDelimiter) {
1552 ret = None;
1553 }
1554 }
1555 } else {
1556 ret = try!(self.add_single_val_to_arg(arg, val, matcher));
1557 }
1558 } else {
1559 ret = try!(self.add_single_val_to_arg(arg, val, matcher));
1560 }
1561 Ok(ret)
1562 }
1563
1564 fn add_single_val_to_arg<A>(&self,
1565 arg: &A,
1566 v: &OsStr,
1567 matcher: &mut ArgMatcher<'a>)
1568 -> ClapResult<Option<&'a str>>
1569 where A: AnyArg<'a, 'b> + Display
1570 {
1571 debugln!("Parser::add_single_val_to_arg;");
1572 debugln!("Parser::add_single_val_to_arg: adding val...{:?}", v);
1573 if let Some(t) = arg.val_terminator() {
1574 if t == v {
1575 return Ok(None);
1576 }
1577 }
1578 matcher.add_val_to(arg.name(), v);
1579
1580 // Increment or create the group "args"
1581 if let Some(grps) = self.groups_for_arg(arg.name()) {
1582 for grp in grps {
1583 matcher.add_val_to(&*grp, v);
1584 }
1585 }
1586
1587 // The validation must come AFTER inserting into 'matcher' or the usage string
1588 // can't be built
1589 self.validate_value(arg, v, matcher)
1590 }
1591
1592 fn validate_value<A>(&self,
1593 arg: &A,
1594 val: &OsStr,
1595 matcher: &ArgMatcher<'a>)
1596 -> ClapResult<Option<&'a str>>
1597 where A: AnyArg<'a, 'b> + Display
1598 {
1599 debugln!("Parser::validate_value: val={:?}", val);
1600 if self.is_set(AppSettings::StrictUtf8) && val.to_str().is_none() {
1601 return Err(Error::invalid_utf8(&*self.create_current_usage(matcher, None), self.color()));
1602 }
1603 if let Some(p_vals) = arg.possible_vals() {
1604 let val_str = val.to_string_lossy();
1605 if !p_vals.contains(&&*val_str) {
1606 return Err(Error::invalid_value(val_str,
1607 p_vals,
1608 arg,
1609 &*self.create_current_usage(matcher, None),
1610 self.color()));
1611 }
1612 }
1613 if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_() &&
1614 matcher.contains(&*arg.name()) {
1615 return Err(Error::empty_value(arg, &*self.create_current_usage(matcher, None), self.color()));
1616 }
1617 if let Some(vtor) = arg.validator() {
1618 if let Err(e) = vtor(val.to_string_lossy().into_owned()) {
1619 return Err(Error::value_validation(Some(arg), e, self.color()));
1620 }
1621 }
1622 if let Some(vtor) = arg.validator_os() {
1623 if let Err(e) = vtor(val) {
1624 return Err(Error::value_validation(Some(arg),
1625 (*e).to_string_lossy().to_string(),
1626 self.color()));
1627 }
1628 }
1629 if matcher.needs_more_vals(arg) {
1630 return Ok(Some(arg.name()));
1631 }
1632 Ok(None)
1633 }
1634
1635 fn parse_flag(&self,
1636 flag: &FlagBuilder<'a, 'b>,
1637 matcher: &mut ArgMatcher<'a>)
1638 -> ClapResult<()> {
1639 debugln!("Parser::parse_flag;");
1640 validate_multiples!(self, flag, matcher);
1641
1642 matcher.inc_occurrence_of(flag.b.name);
1643 // Increment or create the group "args"
1644 self.groups_for_arg(flag.b.name).and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
1645
1646 Ok(())
1647 }
1648
1649 fn validate_blacklist(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1650 debugln!("Parser::validate_blacklist: blacklist={:?}", self.blacklist);
1651 macro_rules! build_err {
1652 ($me:ident, $name:expr, $matcher:ident) => ({
1653 debugln!("build_err!: name={}", $name);
1654 let mut c_with = find_from!($me, $name, blacklist, &$matcher);
1655 c_with = c_with.or(
1656 $me.find_any_arg($name).map_or(None, |aa| aa.blacklist())
1657 .map_or(None, |bl| bl.iter().find(|arg| $matcher.contains(arg)))
1658 .map_or(None, |an| $me.find_any_arg(an))
1659 .map_or(None, |aa| Some(format!("{}", aa)))
1660 );
1661 debugln!("build_err!: '{:?}' conflicts with '{}'", c_with, $name);
1662 $matcher.remove($name);
1663 let usg = $me.create_current_usage($matcher, None);
1664 if let Some(f) = find_by_name!($me, $name, flags, iter) {
1665 debugln!("build_err!: It was a flag...");
1666 Error::argument_conflict(f, c_with, &*usg, self.color())
1667 } else if let Some(o) = find_by_name!($me, $name, opts, iter) {
1668 debugln!("build_err!: It was an option...");
1669 Error::argument_conflict(o, c_with, &*usg, self.color())
1670 } else {
1671 match find_by_name!($me, $name, positionals, values) {
1672 Some(p) => {
1673 debugln!("build_err!: It was a positional...");
1674 Error::argument_conflict(p, c_with, &*usg, self.color())
1675 },
1676 None => panic!(INTERNAL_ERROR_MSG)
1677 }
1678 }
1679 });
1680 }
1681
1682 for name in &self.blacklist {
1683 debugln!("Parser::validate_blacklist:iter: Checking blacklisted name: {}", name);
1684 if self.groups.contains_key(name) {
1685 debugln!("Parser::validate_blacklist:iter: groups contains it...");
1686 for n in self.arg_names_in_group(name) {
1687 debugln!("Parser::validate_blacklist:iter:iter: Checking arg '{}' in group...", n);
1688 if matcher.contains(n) {
1689 debugln!("Parser::validate_blacklist:iter:iter: matcher contains it...");
1690 return Err(build_err!(self, &n, matcher));
1691 }
1692 }
1693 } else if matcher.contains(name) {
1694 debugln!("Parser::validate_blacklist:iter: matcher contains it...");
1695 return Err(build_err!(self, name, matcher));
1696 }
1697 }
1698 Ok(())
1699 }
1700
1701 fn validate_matched_args(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1702 debugln!("Parser::validate_matched_args;");
1703 for (name, ma) in matcher.iter() {
1704 debugln!("Parser::validate_matched_args:iter: name={}", name);
1705 if let Some(opt) = find_by_name!(self, name, opts, iter) {
1706 try!(self.validate_arg_num_vals(opt, ma, matcher));
1707 try!(self.validate_arg_requires(opt, ma, matcher));
1708 } else if let Some(flag) = find_by_name!(self, name, flags, iter) {
1709 // Only requires
1710 try!(self.validate_arg_requires(flag, ma, matcher));
1711 } else if let Some(pos) = find_by_name!(self, name, positionals, values) {
1712 try!(self.validate_arg_num_vals(pos, ma, matcher));
1713 try!(self.validate_arg_requires(pos, ma, matcher));
1714 } else if let Some(grp) = self.groups.get(name) {
1715 if let Some(ref g_reqs) = grp.requires {
1716 if g_reqs.iter().any(|&n| !matcher.contains(n)) {
1717 return self.missing_required_error(matcher, None);
1718 }
1719 }
1720 }
1721 }
1722 Ok(())
1723 }
1724
1725 fn validate_arg_num_vals<A>(&self,
1726 a: &A,
1727 ma: &MatchedArg,
1728 matcher: &ArgMatcher)
1729 -> ClapResult<()>
1730 where A: AnyArg<'a, 'b> + Display
1731 {
1732 debugln!("Parser::validate_arg_num_vals;");
1733 if let Some(num) = a.num_vals() {
1734 debugln!("Parser::validate_arg_num_vals: num_vals set...{}", num);
1735 let should_err = if a.is_set(ArgSettings::Multiple) {
1736 ((ma.vals.len() as u64) % num) != 0
1737 } else {
1738 num != (ma.vals.len() as u64)
1739 };
1740 if should_err {
1741 debugln!("Parser::validate_arg_num_vals: Sending error WrongNumberOfValues");
1742 return Err(Error::wrong_number_of_values(a,
1743 num,
1744 if a.is_set(ArgSettings::Multiple) {
1745 (ma.vals.len() % num as usize)
1746 } else {
1747 ma.vals.len()
1748 },
1749 if ma.vals.len() == 1 ||
1750 (a.is_set(ArgSettings::Multiple) &&
1751 (ma.vals.len() % num as usize) ==
1752 1) {
1753 "as"
1754 } else {
1755 "ere"
1756 },
1757 &*self.create_current_usage(matcher, None),
1758 self.color()));
1759 }
1760 }
1761 if let Some(num) = a.max_vals() {
1762 debugln!("Parser::validate_arg_num_vals: max_vals set...{}", num);
1763 if (ma.vals.len() as u64) > num {
1764 debugln!("Parser::validate_arg_num_vals: Sending error TooManyValues");
1765 return Err(Error::too_many_values(ma.vals
1766 .get(ma.vals
1767 .keys()
1768 .last()
1769 .expect(INTERNAL_ERROR_MSG))
1770 .expect(INTERNAL_ERROR_MSG)
1771 .to_str()
1772 .expect(INVALID_UTF8),
1773 a,
1774 &*self.create_current_usage(matcher, None),
1775 self.color()));
1776 }
1777 }
1778 if let Some(num) = a.min_vals() {
1779 debugln!("Parser::validate_arg_num_vals: min_vals set: {}", num);
1780 if (ma.vals.len() as u64) < num {
1781 debugln!("Parser::validate_arg_num_vals: Sending error TooFewValues");
1782 return Err(Error::too_few_values(a,
1783 num,
1784 ma.vals.len(),
1785 &*self.create_current_usage(matcher, None),
1786 self.color()));
1787 }
1788 }
1789 // Issue 665 (https://github.com/kbknapp/clap-rs/issues/665)
1790 if a.takes_value() && !a.is_set(ArgSettings::EmptyValues) && ma.vals.is_empty() {
1791 return Err(Error::empty_value(a, &*self.create_current_usage(matcher, None), self.color()));
1792 }
1793 Ok(())
1794 }
1795
1796 fn validate_arg_requires<A>(&self,
1797 a: &A,
1798 ma: &MatchedArg,
1799 matcher: &ArgMatcher)
1800 -> ClapResult<()>
1801 where A: AnyArg<'a, 'b> + Display
1802 {
1803 debugln!("Parser::validate_arg_requires;");
1804 if let Some(a_reqs) = a.requires() {
1805 for &(val, name) in a_reqs.iter().filter(|&&(val, _)| val.is_some()) {
1806 if ma.vals
1807 .values()
1808 .any(|v| v == val.expect(INTERNAL_ERROR_MSG) && !matcher.contains(name)) {
1809 return self.missing_required_error(matcher, None);
1810 }
1811 }
1812 }
1813 Ok(())
1814 }
1815
1816 #[inline]
1817 fn missing_required_error(&self, matcher: &ArgMatcher, extra: Option<&str>) -> ClapResult<()> {
1818 debugln!("Parser::missing_required_error: extra={:?}", extra);
1819 let c = Colorizer {
1820 use_stderr: true,
1821 when: self.color(),
1822 };
1823 let mut reqs = self.required.iter().map(|&r| &*r).collect::<Vec<_>>();
1824 if let Some(r) = extra {
1825 reqs.push(r);
1826 }
1827 reqs.retain(|n| !matcher.contains(n));
1828 reqs.dedup();
1829 debugln!("Parser::missing_required_error: reqs={:#?}", reqs);
1830 Err(Error::missing_required_argument(&*self.get_required_from(&reqs[..],
1831 Some(matcher),
1832 extra)
1833 .iter()
1834 .fold(String::new(), |acc, s| {
1835 acc + &format!("\n {}", c.error(s))[..]
1836 }),
1837 &*self.create_current_usage(matcher, extra),
1838 self.color()))
1839 }
1840
1841 fn validate_required(&self, matcher: &ArgMatcher) -> ClapResult<()> {
1842 debugln!("Parser::validate_required: required={:?};", self.required);
1843 'outer: for name in &self.required {
1844 debugln!("Parser::validate_required:iter: name={}", name);
1845 if matcher.contains(name) {
1846 continue 'outer;
1847 }
1848 if let Some(grp) = self.groups.get(name) {
1849 for arg in &grp.args {
1850 if matcher.contains(arg) {
1851 continue 'outer;
1852 }
1853 }
1854 }
1855 if self.groups.values().any(|g| g.args.contains(name)) {
1856 continue 'outer;
1857 }
1858 if let Some(a) = find_by_name!(self, name, flags, iter) {
1859 if self.is_missing_required_ok(a, matcher) {
1860 continue 'outer;
1861 }
1862 } else if let Some(a) = find_by_name!(self, name, opts, iter) {
1863 if self.is_missing_required_ok(a, matcher) {
1864 continue 'outer;
1865 }
1866 } else if let Some(a) = find_by_name!(self, name, positionals, values) {
1867 if self.is_missing_required_ok(a, matcher) {
1868 continue 'outer;
1869 }
1870 }
1871 return self.missing_required_error(matcher, None);
1872 }
1873
1874 // Validate the conditionally required args
1875 for &(a, v, r) in &self.r_ifs {
1876 if let Some(ma) = matcher.get(a) {
1877 for val in ma.vals.values() {
1878 if v == val && matcher.get(r).is_none() {
1879 return self.missing_required_error(matcher, Some(r));
1880 }
1881 }
1882 }
1883 }
1884 Ok(())
1885 }
1886
1887 fn is_missing_required_ok<A>(&self, a: &A, matcher: &ArgMatcher) -> bool
1888 where A: AnyArg<'a, 'b>
1889 {
1890 debugln!("Parser::is_missing_required_ok: a={}", a.name());
1891 if let Some(bl) = a.blacklist() {
1892 debugln!("Parser::is_missing_required_ok: Conflicts found...{:?}", bl);
1893 for n in bl.iter() {
1894 debugln!("Parser::is_missing_required_ok:iter: conflict={}", n);
1895 if matcher.contains(n) ||
1896 self.groups
1897 .get(n)
1898 .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) {
1899 return true;
1900 }
1901 }
1902 }
1903 if let Some(ru) = a.required_unless() {
1904 debugln!("Parser::is_missing_required_ok: Required unless found...{:?}", ru);
1905 let mut found_any = false;
1906 for n in ru.iter() {
1907 debugln!("Parser::is_missing_required_ok:iter: ru={}", n);
1908 if matcher.contains(n) ||
1909 self.groups
1910 .get(n)
1911 .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) {
1912 if !a.is_set(ArgSettings::RequiredUnlessAll) {
1913 debugln!("Parser::is_missing_required_ok:iter: Doesn't require all...returning true");
1914 return true;
1915 }
1916 debugln!("Parser::is_missing_required_ok:iter: Requires all...next");
1917 found_any = true;
1918 } else if a.is_set(ArgSettings::RequiredUnlessAll) {
1919 debugln!("Parser::is_missing_required_ok:iter: Not in matcher, or group and requires all...returning false");
1920 return false;
1921 }
1922 }
1923 return found_any;
1924 }
1925 false
1926 }
1927
1928 fn did_you_mean_error(&self, arg: &str, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
1929 // Didn't match a flag or option...maybe it was a typo and close to one
1930 let suffix =
1931 suggestions::did_you_mean_suffix(arg,
1932 self.long_list.iter(),
1933 suggestions::DidYouMeanMessageStyle::LongFlag);
1934
1935 // Add the arg to the matches to build a proper usage string
1936 if let Some(name) = suffix.1 {
1937 if let Some(opt) = find_by_long!(self, &name, opts) {
1938 self.groups_for_arg(&*opt.b.name)
1939 .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
1940 matcher.insert(&*opt.b.name);
1941 } else if let Some(flg) = find_by_long!(self, &name, flags) {
1942 self.groups_for_arg(&*flg.b.name)
1943 .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
1944 matcher.insert(&*flg.b.name);
1945 }
1946 }
1947
1948 let used_arg = format!("--{}", arg);
1949 Err(Error::unknown_argument(&*used_arg,
1950 &*suffix.0,
1951 &*self.create_current_usage(matcher, None),
1952 self.color()))
1953 }
1954
1955 // Creates a usage string if one was not provided by the user manually. This happens just
1956 // after all arguments were parsed, but before any subcommands have been parsed
1957 // (so as to give subcommands their own usage recursively)
1958 pub fn create_usage(&self, used: &[&str]) -> String {
1959 debugln!("Parser::create_usage;");
1960 let mut usage = String::with_capacity(75);
1961 usage.push_str("USAGE:\n ");
1962 usage.push_str(&self.create_usage_no_title(used));
1963 usage
1964 }
1965
1966 // Creates a usage string (*without title*) if one was not provided by the user
1967 // manually. This happens just
1968 // after all arguments were parsed, but before any subcommands have been parsed
1969 // (so as to give subcommands their own usage recursively)
1970 pub fn create_usage_no_title(&self, used: &[&str]) -> String {
1971 debugln!("Parser::create_usage_no_title;");
1972 let mut usage = String::with_capacity(75);
1973 if let Some(u) = self.meta.usage_str {
1974 usage.push_str(&*u);
1975 } else if used.is_empty() {
1976 usage.push_str(&*self.meta
1977 .usage
1978 .as_ref()
1979 .unwrap_or_else(|| self.meta
1980 .bin_name
1981 .as_ref()
1982 .unwrap_or(&self.meta.name)));
1983 let mut reqs: Vec<&str> = self.required().map(|r| &**r).collect();
1984 reqs.dedup();
1985 let req_string = self.get_required_from(&reqs, None, None)
1986 .iter()
1987 .fold(String::new(), |a, s| a + &format!(" {}", s)[..]);
1988
1989 let flags = self.needs_flags_tag();
1990 if flags && !self.is_set(AppSettings::UnifiedHelpMessage) {
1991 usage.push_str(" [FLAGS]");
1992 } else if flags {
1993 usage.push_str(" [OPTIONS]");
1994 }
1995 if !self.is_set(AppSettings::UnifiedHelpMessage) && self.has_opts() &&
1996 self.opts.iter().any(|o| !o.b.settings.is_set(ArgSettings::Required)) {
1997 usage.push_str(" [OPTIONS]");
1998 }
1999
2000 usage.push_str(&req_string[..]);
2001
2002 // places a '--' in the usage string if there are args and options
2003 // supporting multiple values
2004 if self.has_positionals() &&
2005 self.opts.iter().any(|o| o.b.settings.is_set(ArgSettings::Multiple)) &&
2006 self.positionals.values().any(|p| !p.b.settings.is_set(ArgSettings::Required)) &&
2007 !self.has_subcommands() {
2008 usage.push_str(" [--]")
2009 }
2010 if self.has_positionals() &&
2011 self.positionals.values().any(|p| !p.b.settings.is_set(ArgSettings::Required)) {
2012 if let Some(args_tag) = self.get_args_tag() {
2013 usage.push_str(&*args_tag);
2014 } else {
2015 usage.push_str(" [ARGS]");
2016 }
2017 }
2018
2019
2020 if self.has_subcommands() && !self.is_set(AppSettings::SubcommandRequired) {
2021 usage.push_str(" [SUBCOMMAND]");
2022 } else if self.is_set(AppSettings::SubcommandRequired) && self.has_subcommands() {
2023 usage.push_str(" <SUBCOMMAND>");
2024 }
2025 } else {
2026 self.smart_usage(&mut usage, used);
2027 }
2028
2029 usage.shrink_to_fit();
2030 usage
2031 }
2032
2033 // Creates a context aware usage string, or "smart usage" from currently used
2034 // args, and requirements
2035 fn smart_usage(&self, usage: &mut String, used: &[&str]) {
2036 debugln!("Parser::smart_usage;");
2037 let mut hs: Vec<&str> = self.required().map(|s| &**s).collect();
2038 hs.extend_from_slice(used);
2039
2040 let r_string = self.get_required_from(&hs, None, None)
2041 .iter()
2042 .fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]);
2043
2044 usage.push_str(&self.meta
2045 .usage
2046 .as_ref()
2047 .unwrap_or_else(|| self.meta
2048 .bin_name
2049 .as_ref()
2050 .unwrap_or(&self.meta
2051 .name))[..]);
2052 usage.push_str(&*r_string);
2053 if self.is_set(AppSettings::SubcommandRequired) {
2054 usage.push_str(" <SUBCOMMAND>");
2055 }
2056 }
2057
2058 // Prints the version to the user and exits if quit=true
2059 fn print_version<W: Write>(&self, w: &mut W) -> ClapResult<()> {
2060 try!(self.write_version(w));
2061 w.flush().map_err(Error::from)
2062 }
2063
2064 pub fn write_version<W: Write>(&self, w: &mut W) -> io::Result<()> {
2065 if let Some(bn) = self.meta.bin_name.as_ref() {
2066 if bn.contains(' ') {
2067 // Incase we're dealing with subcommands i.e. git mv is translated to git-mv
2068 write!(w,
2069 "{} {}",
2070 bn.replace(" ", "-"),
2071 self.meta.version.unwrap_or("".into()))
2072 } else {
2073 write!(w,
2074 "{} {}",
2075 &self.meta.name[..],
2076 self.meta.version.unwrap_or("".into()))
2077 }
2078 } else {
2079 write!(w,
2080 "{} {}",
2081 &self.meta.name[..],
2082 self.meta.version.unwrap_or("".into()))
2083 }
2084 }
2085
2086 pub fn print_help(&self) -> ClapResult<()> {
2087 let out = io::stdout();
2088 let mut buf_w = BufWriter::new(out.lock());
2089 self.write_help(&mut buf_w)
2090 }
2091
2092 pub fn write_help<W: Write>(&self, w: &mut W) -> ClapResult<()> {
2093 Help::write_parser_help(w, self)
2094 }
2095
2096 pub fn write_help_err<W: Write>(&self, w: &mut W) -> ClapResult<()> {
2097 Help::write_parser_help_to_stderr(w, self)
2098 }
2099
2100 fn add_defaults(&mut self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
2101 macro_rules! add_val {
2102 (@default $_self:ident, $a:ident, $m:ident) => {
2103 if let Some(ref val) = $a.v.default_val {
2104 if $m.get($a.b.name).is_none() {
2105 try!($_self.add_val_to_arg($a, OsStr::new(val), $m));
2106 arg_post_processing!($_self, $a, $m);
2107 }
2108 }
2109 };
2110 ($_self:ident, $a:ident, $m:ident) => {
2111 if let Some(ref vm) = $a.v.default_vals_ifs {
2112 let mut done = false;
2113 if $m.get($a.b.name).is_none() {
2114 for &(arg, val, default) in vm.values() {
2115 let add = if let Some(a) = $m.get(arg) {
2116 if let Some(v) = val {
2117 a.vals.values().any(|value| v == value)
2118 } else {
2119 true
2120 }
2121 } else {
2122 false
2123 };
2124 if add {
2125 try!($_self.add_val_to_arg($a, OsStr::new(default), $m));
2126 arg_post_processing!($_self, $a, $m);
2127 done = true;
2128 break;
2129 }
2130 }
2131 }
2132
2133 if done {
2134 continue; // outer loop (outside macro)
2135 }
2136 }
2137 add_val!(@default $_self, $a, $m)
2138 };
2139 }
2140
2141 for o in &self.opts {
2142 add_val!(self, o, matcher);
2143 }
2144 for p in self.positionals.values() {
2145 add_val!(self, p, matcher);
2146 }
2147 Ok(())
2148 }
2149
2150 pub fn flags(&self) -> Iter<FlagBuilder<'a, 'b>> { self.flags.iter() }
2151
2152 pub fn opts(&self) -> Iter<OptBuilder<'a, 'b>> { self.opts.iter() }
2153
2154 pub fn positionals(&self) -> vec_map::Values<PosBuilder<'a, 'b>> { self.positionals.values() }
2155
2156 pub fn subcommands(&self) -> Iter<App> { self.subcommands.iter() }
2157
2158 // Should we color the output? None=determined by output location, true=yes, false=no
2159 #[doc(hidden)]
2160 pub fn color(&self) -> ColorWhen {
2161 debugln!("Parser::color;");
2162 debug!("Parser::color: Color setting...");
2163 if self.is_set(AppSettings::ColorNever) {
2164 sdebugln!("Never");
2165 ColorWhen::Never
2166 } else if self.is_set(AppSettings::ColorAlways) {
2167 sdebugln!("Always");
2168 ColorWhen::Always
2169 } else {
2170 sdebugln!("Auto");
2171 ColorWhen::Auto
2172 }
2173 }
2174
2175 pub fn find_any_arg(&self, name: &str) -> Option<&AnyArg> {
2176 if let Some(f) = find_by_name!(self, &name, flags, iter) {
2177 return Some(f);
2178 }
2179 if let Some(o) = find_by_name!(self, &name, opts, iter) {
2180 return Some(o);
2181 }
2182 if let Some(p) = find_by_name!(self, &name, positionals, values) {
2183 return Some(p);
2184 }
2185 None
2186 }
2187
2188 #[cfg_attr(feature = "lints", allow(explicit_iter_loop))]
2189 pub fn find_subcommand(&'b self, sc: &str) -> Option<&'b App<'a, 'b>> {
2190 debugln!("Parser::find_subcommand: sc={}", sc);
2191 debugln!("Parser::find_subcommand: Currently in Parser...{}", self.meta.bin_name.as_ref().unwrap());
2192 for s in self.subcommands.iter() {
2193 if s.p.meta.bin_name.as_ref().unwrap_or(&String::new()) == sc ||
2194 (s.p.meta.aliases.is_some() &&
2195 s.p
2196 .meta
2197 .aliases
2198 .as_ref()
2199 .unwrap()
2200 .iter()
2201 .any(|&(s, _)| s == sc.split(' ').rev().next().expect(INTERNAL_ERROR_MSG))) {
2202 return Some(s);
2203 }
2204 if let Some(app) = s.p.find_subcommand(sc) {
2205 return Some(app);
2206 }
2207 }
2208 None
2209 }
2210 }
2211
2212 impl<'a, 'b> Clone for Parser<'a, 'b>
2213 where 'a: 'b
2214 {
2215 fn clone(&self) -> Self {
2216 Parser {
2217 propogated: self.propogated,
2218 required: self.required.clone(),
2219 short_list: self.short_list.clone(),
2220 long_list: self.long_list.clone(),
2221 blacklist: self.blacklist.clone(),
2222 flags: self.flags.clone(),
2223 opts: self.opts.clone(),
2224 positionals: self.positionals.clone(),
2225 subcommands: self.subcommands.clone(),
2226 groups: self.groups.clone(),
2227 global_args: self.global_args.clone(),
2228 overrides: self.overrides.clone(),
2229 help_short: self.help_short,
2230 version_short: self.version_short,
2231 settings: self.settings,
2232 g_settings: self.g_settings,
2233 meta: self.meta.clone(),
2234 trailing_vals: self.trailing_vals,
2235 id: self.id,
2236 valid_neg_num: self.valid_neg_num,
2237 r_ifs: self.r_ifs.clone(),
2238 valid_arg: self.valid_arg,
2239 }
2240 }
2241 }