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