clap/app/
parser.rs

1// Std
2use std::ffi::{OsStr, OsString};
3use std::fmt::Display;
4use std::fs::File;
5use std::io::{self, BufWriter, Write};
6#[cfg(all(feature = "debug", not(any(target_os = "windows", target_arch = "wasm32"))))]
7use std::os::unix::ffi::OsStrExt;
8#[cfg(all(feature = "debug", any(target_os = "windows", target_arch = "wasm32")))]
9use osstringext::OsStrExt3;
10use std::path::PathBuf;
11use std::slice::Iter;
12use std::iter::Peekable;
13use std::cell::Cell;
14
15// Internal
16use INTERNAL_ERROR_MSG;
17use INVALID_UTF8;
18use SubCommand;
19use app::App;
20use app::help::Help;
21use app::meta::AppMeta;
22use app::settings::AppFlags;
23use args::{AnyArg, Arg, ArgGroup, ArgMatcher, Base, FlagBuilder, OptBuilder, PosBuilder, Switched};
24use args::settings::ArgSettings;
25use completions::ComplGen;
26use errors::{Error, ErrorKind};
27use errors::Result as ClapResult;
28use fmt::ColorWhen;
29use osstringext::OsStrExt2;
30use completions::Shell;
31use suggestions;
32use app::settings::AppSettings as AS;
33use app::validator::Validator;
34use app::usage;
35use map::{self, VecMap};
36
37#[derive(Debug, PartialEq, Copy, Clone)]
38#[doc(hidden)]
39pub 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)]
52pub struct Parser<'a, 'b>
53where
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
76impl<'a, 'b> Parser<'a, 'b>
77where
78    'a: 'b,
79{
80    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
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
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
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
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]
138    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]
173    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]
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]
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]
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]
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
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)
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
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
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
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))]
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
450    pub fn required(&self) -> Iter<&str> { self.required.iter() }
451
452    #[cfg_attr(feature = "lints", allow(needless_borrow))]
453    #[inline]
454    pub fn has_args(&self) -> bool {
455        !(self.flags.is_empty() && self.opts.is_empty() && self.positionals.is_empty())
456    }
457
458    #[inline]
459    pub fn has_opts(&self) -> bool { !self.opts.is_empty() }
460
461    #[inline]
462    pub fn has_flags(&self) -> bool { !self.flags.is_empty() }
463
464    #[inline]
465    pub fn has_positionals(&self) -> bool { !self.positionals.is_empty() }
466
467    #[inline]
468    pub fn has_subcommands(&self) -> bool { !self.subcommands.is_empty() }
469
470    #[inline]
471    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]
479    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]
487    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]
497    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]
506    pub fn is_set(&self, s: AS) -> bool { self.settings.is_set(s) }
507
508    #[inline]
509    pub fn set(&mut self, s: AS) { self.settings.set(s) }
510
511    #[inline]
512    pub fn unset(&mut self, s: AS) { self.settings.unset(s) }
513
514    #[cfg_attr(feature = "lints", allow(block_in_if_condition_stmt))]
515    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
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)
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
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))]
782    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))]
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
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
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
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
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
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
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
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
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
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
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
1515    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    
1535    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
1549    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
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))]
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
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
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
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
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
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
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
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
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
1952    pub fn write_help<W: Write>(&self, w: &mut W) -> ClapResult<()> {
1953        Help::write_parser_help(w, self, false)
1954    }
1955
1956    pub fn write_long_help<W: Write>(&self, w: &mut W) -> ClapResult<()> {
1957        Help::write_parser_help(w, self, true)
1958    }
1959
1960    pub fn write_help_err<W: Write>(&self, w: &mut W) -> ClapResult<()> {
1961        Help::write_parser_help_to_stderr(w, self)
1962    }
1963
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
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
2073    pub fn flags(&self) -> Iter<FlagBuilder<'a, 'b>> { self.flags.iter() }
2074
2075    pub fn opts(&self) -> Iter<OptBuilder<'a, 'b>> { self.opts.iter() }
2076
2077    pub fn positionals(&self) -> map::Values<PosBuilder<'a, 'b>> { self.positionals.values() }
2078
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)]
2083    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
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
2112    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
2121    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))]
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]
2163    fn contains_long(&self, l: &str) -> bool { longs!(self).any(|al| al == &l) }
2164
2165    #[inline]
2166    fn contains_short(&self, s: char) -> bool { shorts!(self).any(|arg_s| arg_s == &s) }
2167}