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