1use 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
15use 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 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 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 pub fn add_arg(&mut self, a: Arg<'a, 'b>) {
290 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 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 }
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 {
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 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 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 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 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 if found {
597 foundx2 = true;
598 continue;
599 }
600 found = true;
601 continue;
602 } else {
603 found = false;
604 }
605 }
606 } else {
607 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 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 {
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 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 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 #[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 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; } 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 !(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 #[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 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 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 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 if !self.is_set(AS::TrailingValues) {
896 {
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 needs_val_of = self.parse_short_arg(matcher, &arg_os)?;
948 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 let arg = self.opts
976 .iter()
977 .find(|o| o.b.name == name)
978 .expect(INTERNAL_ERROR_MSG);
979 needs_val_of = self.add_val_to_arg(arg, &arg_os, matcher)?;
981 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 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 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 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 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 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 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 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 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 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 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 debugln!("Parser::parse_long_arg;");
1575
1576 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 self.check_for_help_and_version_str(arg)?;
1612
1613 self.parse_flag(flag, matcher)?;
1614
1615 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 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 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 self.cur_idx.set(self.cur_idx.get() + 1);
1671
1672 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 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 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 self.check_for_help_and_version_char(c)?;
1713 ret = self.parse_flag(flag, matcher)?;
1714
1715 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 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 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 self.cur_idx.set(self.cur_idx.get() + 1);
1850
1851 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 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 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 let suffix = suggestions::did_you_mean_flag_suffix(arg, &args_rest, longs!(self), &self.subcommands);
1895
1896 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 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 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; }
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 #[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 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 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 #[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 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}