]> git.proxmox.com Git - rustc.git/blob - vendor/clap/src/app/parser.rs
New upstream version 1.59.0+dfsg1
[rustc.git] / vendor / clap / src / app / parser.rs
1 // Std
2 #[cfg(not(any(target_os = "windows", target_arch = "wasm32")))]
3 use std::os::unix::ffi::OsStrExt;
4 use 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")))]
17 use crate::osstringext::OsStrExt3;
18 #[cfg(any(target_os = "windows", target_arch = "wasm32"))]
19 use crate::osstringext::OsStrExt3;
20 use 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)]
40 pub 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)]
53 pub struct Parser<'a, 'b>
54 where
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
77 impl<'a, 'b> Parser<'a, 'b>
78 where
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 }