clap/app/
parser.rs

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