1 // Std
2 use std::{
3     cell::Cell,
4     ffi::{OsStr, OsString},
5 };
6 
7 // Third Party
8 use os_str_bytes::RawOsStr;
9 
10 // Internal
11 use crate::{
12     build::AppSettings as AS,
13     build::{App, Arg, ArgSettings},
14     mkeymap::KeyType,
15     output::{fmt::Colorizer, Help, HelpWriter, Usage},
16     parse::errors::Error as ClapError,
17     parse::errors::ErrorKind,
18     parse::errors::Result as ClapResult,
19     parse::features::suggestions,
20     parse::{ArgMatcher, SubCommand},
21     parse::{Validator, ValueType},
22     util::{ChildGraph, Id},
23     INTERNAL_ERROR_MSG, INVALID_UTF8,
24 };
25 
26 pub(crate) enum ParseState {
27     ValuesDone,
28     Opt(Id),
29     Pos(Id),
30 }
31 
32 /// Recoverable Parsing results.
33 #[derive(Debug, PartialEq, Clone)]
34 enum ParseResult {
35     FlagSubCommand(String),
36     Opt(Id),
37     ValuesDone,
38     /// Value attached to the short flag is not consumed(e.g. 'u' for `-cu` is
39     /// not consumed).
40     AttachedValueNotConsumed,
41     /// This long flag doesn't need a value but is provided one.
42     UnneededAttachedValue {
43         rest: String,
44         used: Vec<Id>,
45         arg: String,
46     },
47     /// This flag might be an hyphen Value.
48     MaybeHyphenValue,
49     /// Equals required but not provided.
50     EqualsNotProvided {
51         arg: String,
52     },
53     /// Failed to match a Arg.
54     NoMatchingArg {
55         arg: String,
56     },
57     /// No argument found e.g. parser is given `-` when parsing a flag.
58     NoArg,
59     /// This is a Help flag.
60     HelpFlag,
61     /// This is a version flag.
62     VersionFlag,
63 }
64 
65 #[derive(Debug)]
66 pub(crate) struct Input {
67     items: Vec<OsString>,
68     cursor: usize,
69 }
70 
71 impl<I, T> From<I> for Input
72 where
73     I: Iterator<Item = T>,
74     T: Into<OsString> + Clone,
75 {
from(val: I) -> Self76     fn from(val: I) -> Self {
77         Self {
78             items: val.map(|x| x.into()).collect(),
79             cursor: 0,
80         }
81     }
82 }
83 
84 impl Input {
next(&mut self) -> Option<(&OsStr, &[OsString])>85     pub(crate) fn next(&mut self) -> Option<(&OsStr, &[OsString])> {
86         if self.cursor >= self.items.len() {
87             None
88         } else {
89             let current = &self.items[self.cursor];
90             self.cursor += 1;
91             let remaining = &self.items[self.cursor..];
92             Some((current, remaining))
93         }
94     }
95 
96     /// Insert some items to the Input items just after current parsing cursor.
97     /// Usually used by replaced items recovering.
insert(&mut self, insert_items: &[&str])98     pub(crate) fn insert(&mut self, insert_items: &[&str]) {
99         self.items = insert_items
100             .iter()
101             .map(OsString::from)
102             .chain(self.items.drain(self.cursor..))
103             .collect();
104         self.cursor = 0;
105     }
106 }
107 
108 pub(crate) struct Parser<'help, 'app> {
109     pub(crate) app: &'app mut App<'help>,
110     pub(crate) required: ChildGraph<Id>,
111     pub(crate) overridden: Vec<Id>,
112     pub(crate) seen: Vec<Id>,
113     pub(crate) cur_idx: Cell<usize>,
114     /// Index of the previous flag subcommand in a group of flags.
115     pub(crate) flag_subcmd_at: Option<usize>,
116     /// Counter indicating the number of items to skip
117     /// when revisiting the group of flags which includes the flag subcommand.
118     pub(crate) flag_subcmd_skip: usize,
119 }
120 
121 // Initializing Methods
122 impl<'help, 'app> Parser<'help, 'app> {
new(app: &'app mut App<'help>) -> Self123     pub(crate) fn new(app: &'app mut App<'help>) -> Self {
124         let mut reqs = ChildGraph::with_capacity(5);
125         for a in app
126             .args
127             .args()
128             .filter(|a| a.settings.is_set(ArgSettings::Required))
129         {
130             reqs.insert(a.id.clone());
131         }
132 
133         Parser {
134             app,
135             required: reqs,
136             overridden: Vec::new(),
137             seen: Vec::new(),
138             cur_idx: Cell::new(0),
139             flag_subcmd_at: None,
140             flag_subcmd_skip: 0,
141         }
142     }
143 
144     #[cfg(debug_assertions)]
_verify_positionals(&self) -> bool145     fn _verify_positionals(&self) -> bool {
146         debug!("Parser::_verify_positionals");
147         // Because you must wait until all arguments have been supplied, this is the first chance
148         // to make assertions on positional argument indexes
149         //
150         // First we verify that the index highest supplied index, is equal to the number of
151         // positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3
152         // but no 2)
153 
154         let highest_idx = self
155             .app
156             .args
157             .keys()
158             .filter_map(|x| {
159                 if let KeyType::Position(n) = x {
160                     Some(*n)
161                 } else {
162                     None
163                 }
164             })
165             .max()
166             .unwrap_or(0);
167 
168         //_highest_idx(&self.positionals);
169 
170         let num_p = self.app.args.keys().filter(|x| x.is_position()).count();
171 
172         assert!(
173             highest_idx == num_p,
174             "Found positional argument whose index is {} but there \
175              are only {} positional arguments defined",
176             highest_idx,
177             num_p
178         );
179 
180         // Next we verify that only the highest index has a .multiple_values(true) (if any)
181         let only_highest = |a: &Arg| {
182             a.is_set(ArgSettings::MultipleValues) && (a.index.unwrap_or(0) != highest_idx)
183         };
184         if self.app.get_positionals().any(only_highest) {
185             // First we make sure if there is a positional that allows multiple values
186             // the one before it (second to last) has one of these:
187             //  * a value terminator
188             //  * ArgSettings::Last
189             //  * The last arg is Required
190 
191             // We can't pass the closure (it.next()) to the macro directly because each call to
192             // find() (iterator, not macro) gets called repeatedly.
193             let last = &self.app.args[&KeyType::Position(highest_idx)];
194             let second_to_last = &self.app.args[&KeyType::Position(highest_idx - 1)];
195 
196             // Either the final positional is required
197             // Or the second to last has a terminator or .last(true) set
198             let ok = last.is_set(ArgSettings::Required)
199                 || (second_to_last.terminator.is_some()
200                     || second_to_last.is_set(ArgSettings::Last))
201                 || last.is_set(ArgSettings::Last);
202             assert!(
203                 ok,
204                 "When using a positional argument with .multiple_values(true) that is *not the \
205                  last* positional argument, the last positional argument (i.e. the one \
206                  with the highest index) *must* have .required(true) or .last(true) set."
207             );
208 
209             // We make sure if the second to last is Multiple the last is ArgSettings::Last
210             let ok = second_to_last.is_set(ArgSettings::MultipleValues)
211                 || last.is_set(ArgSettings::Last);
212             assert!(
213                 ok,
214                 "Only the last positional argument, or second to last positional \
215                  argument may be set to .multiple_values(true)"
216             );
217 
218             // Next we check how many have both Multiple and not a specific number of values set
219             let count = self
220                 .app
221                 .get_positionals()
222                 .filter(|p| p.settings.is_set(ArgSettings::MultipleValues) && p.num_vals.is_none())
223                 .count();
224             let ok = count <= 1
225                 || (last.is_set(ArgSettings::Last)
226                     && last.is_set(ArgSettings::MultipleValues)
227                     && second_to_last.is_set(ArgSettings::MultipleValues)
228                     && count == 2);
229             assert!(
230                 ok,
231                 "Only one positional argument with .multiple_values(true) set is allowed per \
232                  command, unless the second one also has .last(true) set"
233             );
234         }
235 
236         let mut found = false;
237 
238         if self.is_set(AS::AllowMissingPositional) {
239             // Check that if a required positional argument is found, all positions with a lower
240             // index are also required.
241             let mut foundx2 = false;
242 
243             for p in self.app.get_positionals() {
244                 if foundx2 && !p.is_set(ArgSettings::Required) {
245                     assert!(
246                         p.is_set(ArgSettings::Required),
247                         "Found non-required positional argument with a lower \
248                          index than a required positional argument by two or more: {:?} \
249                          index {:?}",
250                         p.name,
251                         p.index
252                     );
253                 } else if p.is_set(ArgSettings::Required) && !p.is_set(ArgSettings::Last) {
254                     // Args that .last(true) don't count since they can be required and have
255                     // positionals with a lower index that aren't required
256                     // Imagine: prog <req1> [opt1] -- <req2>
257                     // Both of these are valid invocations:
258                     //      $ prog r1 -- r2
259                     //      $ prog r1 o1 -- r2
260                     if found {
261                         foundx2 = true;
262                         continue;
263                     }
264                     found = true;
265                     continue;
266                 } else {
267                     found = false;
268                 }
269             }
270         } else {
271             // Check that if a required positional argument is found, all positions with a lower
272             // index are also required
273             for p in (1..=num_p).rev().filter_map(|n| self.app.args.get(&n)) {
274                 if found {
275                     assert!(
276                         p.is_set(ArgSettings::Required),
277                         "Found non-required positional argument with a lower \
278                          index than a required positional argument: {:?} index {:?}",
279                         p.name,
280                         p.index
281                     );
282                 } else if p.is_set(ArgSettings::Required) && !p.is_set(ArgSettings::Last) {
283                     // Args that .last(true) don't count since they can be required and have
284                     // positionals with a lower index that aren't required
285                     // Imagine: prog <req1> [opt1] -- <req2>
286                     // Both of these are valid invocations:
287                     //      $ prog r1 -- r2
288                     //      $ prog r1 o1 -- r2
289                     found = true;
290                     continue;
291                 }
292             }
293         }
294         assert!(
295             self.app
296                 .get_positionals()
297                 .filter(|p| p.is_set(ArgSettings::Last))
298                 .count()
299                 < 2,
300             "Only one positional argument may have last(true) set. Found two."
301         );
302         if self
303             .app
304             .get_positionals()
305             .any(|p| p.is_set(ArgSettings::Last) && p.is_set(ArgSettings::Required))
306             && self.app.has_subcommands()
307             && !self.is_set(AS::SubcommandsNegateReqs)
308         {
309             panic!(
310                 "Having a required positional argument with .last(true) set *and* child \
311                  subcommands without setting SubcommandsNegateReqs isn't compatible."
312             );
313         }
314 
315         true
316     }
317 
318     // Does all the initializing and prepares the parser
_build(&mut self)319     pub(crate) fn _build(&mut self) {
320         debug!("Parser::_build");
321 
322         #[cfg(debug_assertions)]
323         self._verify_positionals();
324 
325         for group in &self.app.groups {
326             if group.required {
327                 let idx = self.required.insert(group.id.clone());
328                 for a in &group.requires {
329                     self.required.insert_child(idx, a.clone());
330                 }
331             }
332         }
333     }
334 }
335 
336 // Parsing Methods
337 impl<'help, 'app> Parser<'help, 'app> {
338     // The actual parsing function
339     #[allow(clippy::cognitive_complexity)]
get_matches_with( &mut self, matcher: &mut ArgMatcher, it: &mut Input, ) -> ClapResult<()>340     pub(crate) fn get_matches_with(
341         &mut self,
342         matcher: &mut ArgMatcher,
343         it: &mut Input,
344     ) -> ClapResult<()> {
345         debug!("Parser::get_matches_with");
346         // Verify all positional assertions pass
347         self._build();
348 
349         let mut subcmd_name: Option<String> = None;
350         let mut keep_state = false;
351         let mut parse_state = ParseState::ValuesDone;
352         let mut pos_counter = 1;
353 
354         // Already met any valid arg(then we shouldn't expect subcommands after it).
355         let mut valid_arg_found = false;
356         // If the user already passed '--'. Meaning only positional args follow.
357         let mut trailing_values = false;
358 
359         // Count of positional args
360         let positional_count = self.app.args.keys().filter(|x| x.is_position()).count();
361         // If any arg sets .last(true)
362         let contains_last = self.app.args.args().any(|x| x.is_set(ArgSettings::Last));
363 
364         while let Some((arg_os, remaining_args)) = it.next() {
365             // Recover the replaced items if any.
366             if let Some((_replacer, replaced_items)) = self
367                 .app
368                 .replacers
369                 .iter()
370                 .find(|(key, _)| OsStr::new(key) == arg_os)
371             {
372                 it.insert(replaced_items);
373                 debug!(
374                     "Parser::get_matches_with: found replacer: {:?}, target: {:?}",
375                     _replacer, replaced_items
376                 );
377                 continue;
378             }
379 
380             let arg_os = RawOsStr::new(arg_os);
381             debug!(
382                 "Parser::get_matches_with: Begin parsing '{:?}' ({:?})",
383                 arg_os,
384                 arg_os.as_raw_bytes()
385             );
386 
387             // Correct pos_counter.
388             pos_counter = {
389                 let is_second_to_last = pos_counter + 1 == positional_count;
390 
391                 // The last positional argument, or second to last positional
392                 // argument may be set to .multiple_values(true)
393                 let low_index_mults = is_second_to_last
394                     && self.app.get_positionals().any(|a| {
395                         a.is_set(ArgSettings::MultipleValues)
396                             && (positional_count != a.index.unwrap_or(0))
397                     })
398                     && self
399                         .app
400                         .get_positionals()
401                         .last()
402                         .map_or(false, |p_name| !p_name.is_set(ArgSettings::Last));
403 
404                 let missing_pos = self.is_set(AS::AllowMissingPositional)
405                     && is_second_to_last
406                     && !trailing_values;
407 
408                 debug!(
409                     "Parser::get_matches_with: Positional counter...{}",
410                     pos_counter
411                 );
412                 debug!(
413                     "Parser::get_matches_with: Low index multiples...{:?}",
414                     low_index_mults
415                 );
416 
417                 if low_index_mults || missing_pos {
418                     let skip_current = if let Some(n) = remaining_args.get(0) {
419                         if let Some(p) = self
420                             .app
421                             .get_positionals()
422                             .find(|p| p.index == Some(pos_counter))
423                         {
424                             // If next value looks like a new_arg or it's a
425                             // subcommand, skip positional argument under current
426                             // pos_counter(which means current value cannot be a
427                             // positional argument with a value next to it), assume
428                             // current value matches the next arg.
429                             let n = RawOsStr::new(n);
430                             self.is_new_arg(&n, p)
431                                 || self.possible_subcommand(&n, valid_arg_found).is_some()
432                         } else {
433                             true
434                         }
435                     } else {
436                         true
437                     };
438 
439                     if skip_current {
440                         debug!("Parser::get_matches_with: Bumping the positional counter...");
441                         pos_counter + 1
442                     } else {
443                         pos_counter
444                     }
445                 } else if trailing_values
446                     && (self.is_set(AS::AllowMissingPositional) || contains_last)
447                 {
448                     // Came to -- and one positional has .last(true) set, so we go immediately
449                     // to the last (highest index) positional
450                     debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
451                     positional_count
452                 } else {
453                     pos_counter
454                 }
455             };
456 
457             // Has the user already passed '--'? Meaning only positional args follow
458             if !trailing_values {
459                 if self.is_set(AS::SubcommandPrecedenceOverArg)
460                     || !matches!(parse_state, ParseState::Opt(_) | ParseState::Pos(_))
461                 {
462                     // Does the arg match a subcommand name, or any of its aliases (if defined)
463                     let sc_name = self.possible_subcommand(&arg_os, valid_arg_found);
464                     debug!("Parser::get_matches_with: sc={:?}", sc_name);
465                     if let Some(sc_name) = sc_name {
466                         if sc_name == "help"
467                             && !self.is_set(AS::NoAutoHelp)
468                             && !self.is_set(AS::DisableHelpSubcommand)
469                         {
470                             self.parse_help_subcommand(remaining_args)?;
471                         }
472                         subcmd_name = Some(sc_name.to_owned());
473                         break;
474                     }
475                 }
476 
477                 if let Some(long_arg) = arg_os.strip_prefix("--") {
478                     let parse_result = self.parse_long_arg(
479                         matcher,
480                         long_arg,
481                         &parse_state,
482                         &mut valid_arg_found,
483                         trailing_values,
484                     );
485                     debug!(
486                         "Parser::get_matches_with: After parse_long_arg {:?}",
487                         parse_result
488                     );
489                     match parse_result {
490                         ParseResult::NoArg => {
491                             debug!("Parser::get_matches_with: setting TrailingVals=true");
492                             trailing_values = true;
493                             continue;
494                         }
495                         ParseResult::ValuesDone => {
496                             parse_state = ParseState::ValuesDone;
497                             continue;
498                         }
499                         ParseResult::Opt(id) => {
500                             parse_state = ParseState::Opt(id);
501                             continue;
502                         }
503                         ParseResult::FlagSubCommand(name) => {
504                             debug!(
505                                 "Parser::get_matches_with: FlagSubCommand found in long arg {:?}",
506                                 &name
507                             );
508                             subcmd_name = Some(name);
509                             break;
510                         }
511                         ParseResult::EqualsNotProvided { arg } => {
512                             return Err(ClapError::no_equals(
513                                 self.app,
514                                 arg,
515                                 Usage::new(self).create_usage_with_title(&[]),
516                             ));
517                         }
518                         ParseResult::NoMatchingArg { arg } => {
519                             let remaining_args: Vec<_> = remaining_args
520                                 .iter()
521                                 .map(|x| x.to_str().expect(INVALID_UTF8))
522                                 .collect();
523                             return Err(self.did_you_mean_error(&arg, matcher, &remaining_args));
524                         }
525                         ParseResult::UnneededAttachedValue { rest, used, arg } => {
526                             return Err(ClapError::too_many_values(
527                                 self.app,
528                                 rest,
529                                 arg,
530                                 Usage::new(self).create_usage_no_title(&used),
531                             ))
532                         }
533                         ParseResult::HelpFlag => {
534                             return Err(self.help_err(true));
535                         }
536                         ParseResult::VersionFlag => {
537                             return Err(self.version_err(true));
538                         }
539                         ParseResult::MaybeHyphenValue => {
540                             // Maybe a hyphen value, do nothing.
541                         }
542                         ParseResult::AttachedValueNotConsumed => {
543                             unreachable!()
544                         }
545                     }
546                 } else if let Some(short_arg) = arg_os.strip_prefix("-") {
547                     // Arg looks like a short flag, and not a possible number
548 
549                     // Try to parse short args like normal, if AllowLeadingHyphen or
550                     // AllowNegativeNumbers is set, parse_short_arg will *not* throw
551                     // an error, and instead return Ok(None)
552                     let parse_result = self.parse_short_arg(
553                         matcher,
554                         short_arg,
555                         &parse_state,
556                         pos_counter,
557                         &mut valid_arg_found,
558                         trailing_values,
559                     );
560                     // If it's None, we then check if one of those two AppSettings was set
561                     debug!(
562                         "Parser::get_matches_with: After parse_short_arg {:?}",
563                         parse_result
564                     );
565                     match parse_result {
566                         ParseResult::NoArg => {
567                             // Is a single dash `-`, try positional.
568                         }
569                         ParseResult::ValuesDone => {
570                             parse_state = ParseState::ValuesDone;
571                             continue;
572                         }
573                         ParseResult::Opt(id) => {
574                             parse_state = ParseState::Opt(id);
575                             continue;
576                         }
577                         ParseResult::FlagSubCommand(name) => {
578                             // If there are more short flags to be processed, we should keep the state, and later
579                             // revisit the current group of short flags skipping the subcommand.
580                             keep_state = self
581                                 .flag_subcmd_at
582                                 .map(|at| {
583                                     it.cursor -= 1;
584                                     // Since we are now saving the current state, the number of flags to skip during state recovery should
585                                     // be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position.
586                                     self.flag_subcmd_skip = self.cur_idx.get() - at + 1;
587                                 })
588                                 .is_some();
589 
590                             debug!(
591                                 "Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}",
592                                 name,
593                                 keep_state,
594                                 self.flag_subcmd_skip
595                             );
596 
597                             subcmd_name = Some(name);
598                             break;
599                         }
600                         ParseResult::EqualsNotProvided { arg } => {
601                             return Err(ClapError::no_equals(
602                                 self.app,
603                                 arg,
604                                 Usage::new(self).create_usage_with_title(&[]),
605                             ))
606                         }
607                         ParseResult::NoMatchingArg { arg } => {
608                             return Err(ClapError::unknown_argument(
609                                 self.app,
610                                 arg,
611                                 None,
612                                 Usage::new(self).create_usage_with_title(&[]),
613                             ));
614                         }
615                         ParseResult::HelpFlag => {
616                             return Err(self.help_err(false));
617                         }
618                         ParseResult::VersionFlag => {
619                             return Err(self.version_err(false));
620                         }
621                         ParseResult::MaybeHyphenValue => {
622                             // Maybe a hyphen value, do nothing.
623                         }
624                         ParseResult::UnneededAttachedValue { .. }
625                         | ParseResult::AttachedValueNotConsumed => unreachable!(),
626                     }
627                 }
628 
629                 if let ParseState::Opt(id) = &parse_state {
630                     // Assume this is a value of a previous arg.
631 
632                     // get the option so we can check the settings
633                     let parse_result = self.add_val_to_arg(
634                         &self.app[id],
635                         &arg_os,
636                         matcher,
637                         ValueType::CommandLine,
638                         true,
639                         trailing_values,
640                     );
641                     parse_state = match parse_result {
642                         ParseResult::Opt(id) => ParseState::Opt(id),
643                         ParseResult::ValuesDone => ParseState::ValuesDone,
644                         _ => unreachable!(),
645                     };
646                     // get the next value from the iterator
647                     continue;
648                 }
649             }
650 
651             if let Some(p) = self.app.args.get(&pos_counter) {
652                 if p.is_set(ArgSettings::Last) && !trailing_values {
653                     return Err(ClapError::unknown_argument(
654                         self.app,
655                         arg_os.to_str_lossy().into_owned(),
656                         None,
657                         Usage::new(self).create_usage_with_title(&[]),
658                     ));
659                 }
660 
661                 if self.is_set(AS::TrailingVarArg) && pos_counter == positional_count {
662                     trailing_values = true;
663                 }
664 
665                 self.seen.push(p.id.clone());
666                 // Creating new value group rather than appending when the arg
667                 // doesn't have any value. This behaviour is right because
668                 // positional arguments are always present continiously.
669                 let append = self.arg_have_val(matcher, p);
670                 self.add_val_to_arg(
671                     p,
672                     &arg_os,
673                     matcher,
674                     ValueType::CommandLine,
675                     append,
676                     trailing_values,
677                 );
678 
679                 // Increase occurrence no matter if we are appending, occurrences
680                 // of positional argument equals to number of values rather than
681                 // the number of value groups.
682                 self.inc_occurrence_of_arg(matcher, p);
683 
684                 // Only increment the positional counter if it doesn't allow multiples
685                 if !p.settings.is_set(ArgSettings::MultipleValues) {
686                     pos_counter += 1;
687                     parse_state = ParseState::ValuesDone;
688                 } else {
689                     parse_state = ParseState::Pos(p.id.clone());
690                 }
691                 valid_arg_found = true;
692             } else if self.is_set(AS::AllowExternalSubcommands) {
693                 // Get external subcommand name
694                 let sc_name = match arg_os.to_str() {
695                     Some(s) => s.to_string(),
696                     None => {
697                         return Err(ClapError::invalid_utf8(
698                             self.app,
699                             Usage::new(self).create_usage_with_title(&[]),
700                         ));
701                     }
702                 };
703 
704                 // Collect the external subcommand args
705                 let mut sc_m = ArgMatcher::default();
706 
707                 while let Some((v, _)) = it.next() {
708                     if !self.is_set(AS::AllowInvalidUtf8ForExternalSubcommands)
709                         && v.to_str().is_none()
710                     {
711                         return Err(ClapError::invalid_utf8(
712                             self.app,
713                             Usage::new(self).create_usage_with_title(&[]),
714                         ));
715                     }
716                     sc_m.add_val_to(
717                         &Id::empty_hash(),
718                         v.to_os_string(),
719                         ValueType::CommandLine,
720                         false,
721                     );
722                 }
723 
724                 matcher.subcommand(SubCommand {
725                     name: sc_name.clone(),
726                     id: sc_name.into(),
727                     matches: sc_m.into_inner(),
728                 });
729 
730                 self.remove_overrides(matcher);
731 
732                 return Validator::new(self).validate(
733                     parse_state,
734                     subcmd_name.is_some(),
735                     matcher,
736                     trailing_values,
737                 );
738             } else {
739                 // Start error processing
740                 return Err(self.match_arg_error(&arg_os, valid_arg_found, trailing_values));
741             }
742         }
743 
744         if let Some(ref pos_sc_name) = subcmd_name {
745             let sc_name = self
746                 .app
747                 .find_subcommand(pos_sc_name)
748                 .expect(INTERNAL_ERROR_MSG)
749                 .name
750                 .clone();
751             self.parse_subcommand(&sc_name, matcher, it, keep_state)?;
752         } else if self.is_set(AS::SubcommandRequired) {
753             let bn = self.app.bin_name.as_ref().unwrap_or(&self.app.name);
754             return Err(ClapError::missing_subcommand(
755                 self.app,
756                 bn.to_string(),
757                 Usage::new(self).create_usage_with_title(&[]),
758             ));
759         } else if self.is_set(AS::SubcommandRequiredElseHelp) {
760             debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true");
761             let message = self.write_help_err()?;
762             return Err(ClapError::new(
763                 message,
764                 ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand,
765             ));
766         }
767 
768         self.remove_overrides(matcher);
769 
770         Validator::new(self).validate(parse_state, subcmd_name.is_some(), matcher, trailing_values)
771     }
772 
match_arg_error( &self, arg_os: &RawOsStr, valid_arg_found: bool, trailing_values: bool, ) -> ClapError773     fn match_arg_error(
774         &self,
775         arg_os: &RawOsStr,
776         valid_arg_found: bool,
777         trailing_values: bool,
778     ) -> ClapError {
779         // If argument follows a `--`
780         if trailing_values {
781             // If the arg matches a subcommand name, or any of its aliases (if defined)
782             if self.possible_subcommand(arg_os, valid_arg_found).is_some() {
783                 return ClapError::unnecessary_double_dash(
784                     self.app,
785                     arg_os.to_str_lossy().into_owned(),
786                     Usage::new(self).create_usage_with_title(&[]),
787                 );
788             }
789         }
790         let candidates =
791             suggestions::did_you_mean(&arg_os.to_str_lossy(), self.app.all_subcommand_names());
792         // If the argument looks like a subcommand.
793         if !candidates.is_empty() {
794             let candidates: Vec<_> = candidates
795                 .iter()
796                 .map(|candidate| format!("'{}'", candidate))
797                 .collect();
798             return ClapError::invalid_subcommand(
799                 self.app,
800                 arg_os.to_str_lossy().into_owned(),
801                 candidates.join(" or "),
802                 self.app
803                     .bin_name
804                     .as_ref()
805                     .unwrap_or(&self.app.name)
806                     .to_string(),
807                 Usage::new(self).create_usage_with_title(&[]),
808             );
809         }
810         // If the argument must be a subcommand.
811         if !self.app.has_args() || self.is_set(AS::InferSubcommands) && self.app.has_subcommands() {
812             return ClapError::unrecognized_subcommand(
813                 self.app,
814                 arg_os.to_str_lossy().into_owned(),
815                 self.app
816                     .bin_name
817                     .as_ref()
818                     .unwrap_or(&self.app.name)
819                     .to_string(),
820             );
821         }
822         ClapError::unknown_argument(
823             self.app,
824             arg_os.to_str_lossy().into_owned(),
825             None,
826             Usage::new(self).create_usage_with_title(&[]),
827         )
828     }
829 
830     // Checks if the arg matches a subcommand name, or any of its aliases (if defined)
possible_subcommand(&self, arg_os: &RawOsStr, valid_arg_found: bool) -> Option<&str>831     fn possible_subcommand(&self, arg_os: &RawOsStr, valid_arg_found: bool) -> Option<&str> {
832         debug!("Parser::possible_subcommand: arg={:?}", arg_os);
833 
834         if !(self.is_set(AS::ArgsNegateSubcommands) && valid_arg_found) {
835             if self.is_set(AS::InferSubcommands) {
836                 // For subcommand `test`, we accepts it's prefix: `t`, `te`,
837                 // `tes` and `test`.
838                 let v = self
839                     .app
840                     .all_subcommand_names()
841                     .filter(|s| RawOsStr::from_str(s).starts_with_os(arg_os))
842                     .collect::<Vec<_>>();
843 
844                 if v.len() == 1 {
845                     return Some(v[0]);
846                 }
847 
848                 // If there is any ambiguity, fallback to non-infer subcommand
849                 // search.
850             }
851             if let Some(sc) = self.app.find_subcommand(arg_os) {
852                 return Some(&sc.name);
853             }
854         }
855         None
856     }
857 
858     // Checks if the arg matches a long flag subcommand name, or any of its aliases (if defined)
possible_long_flag_subcommand(&self, arg_os: &RawOsStr) -> Option<&str>859     fn possible_long_flag_subcommand(&self, arg_os: &RawOsStr) -> Option<&str> {
860         debug!("Parser::possible_long_flag_subcommand: arg={:?}", arg_os);
861         if self.is_set(AS::InferSubcommands) {
862             let options = self
863                 .app
864                 .get_subcommands()
865                 .fold(Vec::new(), |mut options, sc| {
866                     if let Some(long) = sc.long_flag {
867                         if RawOsStr::from_str(long).starts_with_os(arg_os) {
868                             options.push(long);
869                         }
870                         options.extend(
871                             sc.get_all_aliases()
872                                 .filter(|alias| RawOsStr::from_str(alias).starts_with_os(arg_os)),
873                         )
874                     }
875                     options
876                 });
877             if options.len() == 1 {
878                 return Some(options[0]);
879             }
880 
881             for sc in options {
882                 if sc == arg_os {
883                     return Some(sc);
884                 }
885             }
886         } else if let Some(sc_name) = self.app.find_long_subcmd(arg_os) {
887             return Some(sc_name);
888         }
889         None
890     }
891 
parse_help_subcommand(&self, cmds: &[OsString]) -> ClapResult<ParseResult>892     fn parse_help_subcommand(&self, cmds: &[OsString]) -> ClapResult<ParseResult> {
893         debug!("Parser::parse_help_subcommand");
894 
895         let mut bin_name = self.app.bin_name.as_ref().unwrap_or(&self.app.name).clone();
896 
897         let mut sc = {
898             // @TODO @perf: cloning all these Apps isn't great, but since it's just displaying the
899             // help message there are bigger fish to fry
900             let mut sc = self.app.clone();
901 
902             for cmd in cmds.iter() {
903                 sc = if let Some(c) = sc.find_subcommand(cmd) {
904                     c
905                 } else if let Some(c) = sc.find_subcommand(&cmd.to_string_lossy()) {
906                     c
907                 } else {
908                     return Err(ClapError::unrecognized_subcommand(
909                         self.app,
910                         cmd.to_string_lossy().into_owned(),
911                         self.app
912                             .bin_name
913                             .as_ref()
914                             .unwrap_or(&self.app.name)
915                             .to_string(),
916                     ));
917                 }
918                 .clone();
919 
920                 if cmd == OsStr::new("help") {
921                     let pb = Arg::new("subcommand")
922                         .index(1)
923                         .setting(ArgSettings::TakesValue)
924                         .setting(ArgSettings::MultipleValues)
925                         .value_name("SUBCOMMAND")
926                         .about("The subcommand whose help message to display");
927                     sc = sc.arg(pb);
928                 }
929 
930                 sc._build();
931                 bin_name.push(' ');
932                 bin_name.push_str(&sc.name);
933             }
934 
935             sc
936         };
937         sc = sc.bin_name(bin_name);
938 
939         let parser = Parser::new(&mut sc);
940 
941         Err(parser.help_err(self.app.is_set(AS::UseLongFormatForHelpSubcommand)))
942     }
943 
is_new_arg(&self, next: &RawOsStr, current_positional: &Arg) -> bool944     fn is_new_arg(&self, next: &RawOsStr, current_positional: &Arg) -> bool {
945         debug!(
946             "Parser::is_new_arg: {:?}:{:?}",
947             next, current_positional.name
948         );
949 
950         if self.is_set(AS::AllowLeadingHyphen)
951             || self.app[&current_positional.id].is_set(ArgSettings::AllowHyphenValues)
952             || (self.is_set(AS::AllowNegativeNumbers) && next.to_str_lossy().parse::<f64>().is_ok())
953         {
954             // If allow hyphen, this isn't a new arg.
955             debug!("Parser::is_new_arg: Allow hyphen");
956             false
957         } else if next.starts_with("--") {
958             // If this is a long flag, this is a new arg.
959             debug!("Parser::is_new_arg: -- found");
960             true
961         } else if next.starts_with("-") {
962             debug!("Parser::is_new_arg: - found");
963             // If this is a short flag, this is a new arg. But a singe '-' by
964             // itself is a value and typically means "stdin" on unix systems.
965             next.raw_len() != 1
966         } else {
967             debug!("Parser::is_new_arg: value");
968             // Nothing special, this is a value.
969             false
970         }
971     }
972 
parse_subcommand( &mut self, sc_name: &str, matcher: &mut ArgMatcher, it: &mut Input, keep_state: bool, ) -> ClapResult<()>973     fn parse_subcommand(
974         &mut self,
975         sc_name: &str,
976         matcher: &mut ArgMatcher,
977         it: &mut Input,
978         keep_state: bool,
979     ) -> ClapResult<()> {
980         debug!("Parser::parse_subcommand");
981 
982         let mut mid_string = String::from(" ");
983 
984         if !self.is_set(AS::SubcommandsNegateReqs) {
985             let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
986 
987             for s in &reqs {
988                 mid_string.push_str(s);
989                 mid_string.push(' ');
990             }
991         }
992 
993         let partial_parsing_enabled = self.is_set(AS::IgnoreErrors);
994 
995         if let Some(sc) = self.app.subcommands.iter_mut().find(|s| s.name == sc_name) {
996             let mut sc_matcher = ArgMatcher::default();
997             // Display subcommand name, short and long in usage
998             let mut sc_names = sc.name.clone();
999             let mut flag_subcmd = false;
1000             if let Some(l) = sc.long_flag {
1001                 sc_names.push_str(&format!(", --{}", l));
1002                 flag_subcmd = true;
1003             }
1004             if let Some(s) = sc.short_flag {
1005                 sc_names.push_str(&format!(", -{}", s));
1006                 flag_subcmd = true;
1007             }
1008 
1009             if flag_subcmd {
1010                 sc_names = format!("{{{}}}", sc_names);
1011             }
1012 
1013             sc.usage = Some(
1014                 self.app
1015                     .bin_name
1016                     .as_ref()
1017                     .map(|bin_name| format!("{}{}{}", bin_name, mid_string, sc_names))
1018                     .unwrap_or(sc_names),
1019             );
1020 
1021             // bin_name should be parent's bin_name + [<reqs>] + the sc's name separated by
1022             // a space
1023             sc.bin_name = Some(format!(
1024                 "{}{}{}",
1025                 self.app.bin_name.as_ref().unwrap_or(&String::new()),
1026                 if self.app.bin_name.is_some() { " " } else { "" },
1027                 &*sc.name
1028             ));
1029 
1030             // Ensure all args are built and ready to parse
1031             sc._build();
1032 
1033             debug!("Parser::parse_subcommand: About to parse sc={}", sc.name);
1034 
1035             {
1036                 let mut p = Parser::new(sc);
1037                 // HACK: maintain indexes between parsers
1038                 // FlagSubCommand short arg needs to revisit the current short args, but skip the subcommand itself
1039                 if keep_state {
1040                     p.cur_idx.set(self.cur_idx.get());
1041                     p.flag_subcmd_at = self.flag_subcmd_at;
1042                     p.flag_subcmd_skip = self.flag_subcmd_skip;
1043                 }
1044                 if let Err(error) = p.get_matches_with(&mut sc_matcher, it) {
1045                     if partial_parsing_enabled {
1046                         debug!(
1047                             "Parser::parse_subcommand: ignored error in subcommand {}: {:?}",
1048                             sc_name, error
1049                         );
1050                     } else {
1051                         return Err(error);
1052                     }
1053                 }
1054             }
1055             matcher.subcommand(SubCommand {
1056                 id: sc.id.clone(),
1057                 name: sc.name.clone(),
1058                 matches: sc_matcher.into_inner(),
1059             });
1060         }
1061         Ok(())
1062     }
1063 
1064     // Retrieves the names of all args the user has supplied thus far, except required ones
1065     // because those will be listed in self.required
check_for_help_and_version_str(&self, arg: &RawOsStr) -> Option<ParseResult>1066     fn check_for_help_and_version_str(&self, arg: &RawOsStr) -> Option<ParseResult> {
1067         debug!("Parser::check_for_help_and_version_str");
1068         debug!(
1069             "Parser::check_for_help_and_version_str: Checking if --{:?} is help or version...",
1070             arg
1071         );
1072 
1073         if let Some(help) = self.app.find(&Id::help_hash()) {
1074             if let Some(h) = help.long {
1075                 if arg == h && !self.is_set(AS::NoAutoHelp) && !self.is_set(AS::DisableHelpFlag) {
1076                     debug!("Help");
1077                     return Some(ParseResult::HelpFlag);
1078                 }
1079             }
1080         }
1081 
1082         if let Some(version) = self.app.find(&Id::version_hash()) {
1083             if let Some(v) = version.long {
1084                 if arg == v
1085                     && !self.is_set(AS::NoAutoVersion)
1086                     && !self.is_set(AS::DisableVersionFlag)
1087                 {
1088                     debug!("Version");
1089                     return Some(ParseResult::VersionFlag);
1090                 }
1091             }
1092         }
1093 
1094         debug!("Neither");
1095         None
1096     }
1097 
check_for_help_and_version_char(&self, arg: char) -> Option<ParseResult>1098     fn check_for_help_and_version_char(&self, arg: char) -> Option<ParseResult> {
1099         debug!("Parser::check_for_help_and_version_char");
1100         debug!(
1101             "Parser::check_for_help_and_version_char: Checking if -{} is help or version...",
1102             arg
1103         );
1104 
1105         if let Some(help) = self.app.find(&Id::help_hash()) {
1106             if let Some(h) = help.short {
1107                 if arg == h && !self.is_set(AS::NoAutoHelp) && !self.is_set(AS::DisableHelpFlag) {
1108                     debug!("Help");
1109                     return Some(ParseResult::HelpFlag);
1110                 }
1111             }
1112         }
1113 
1114         if let Some(version) = self.app.find(&Id::version_hash()) {
1115             if let Some(v) = version.short {
1116                 if arg == v
1117                     && !self.is_set(AS::NoAutoVersion)
1118                     && !self.is_set(AS::DisableVersionFlag)
1119                 {
1120                     debug!("Version");
1121                     return Some(ParseResult::VersionFlag);
1122                 }
1123             }
1124         }
1125 
1126         debug!("Neither");
1127         None
1128     }
1129 
use_long_help(&self) -> bool1130     fn use_long_help(&self) -> bool {
1131         debug!("Parser::use_long_help");
1132         // In this case, both must be checked. This allows the retention of
1133         // original formatting, but also ensures that the actual -h or --help
1134         // specified by the user is sent through. If HiddenShortHelp is not included,
1135         // then items specified with hidden_short_help will also be hidden.
1136         let should_long = |v: &Arg| {
1137             v.long_about.is_some()
1138                 || v.is_set(ArgSettings::HiddenLongHelp)
1139                 || v.is_set(ArgSettings::HiddenShortHelp)
1140         };
1141 
1142         self.app.long_about.is_some()
1143             || self.app.before_long_help.is_some()
1144             || self.app.after_long_help.is_some()
1145             || self.app.args.args().any(should_long)
1146             || self.app.subcommands.iter().any(|s| s.long_about.is_some())
1147     }
1148 
parse_long_arg( &mut self, matcher: &mut ArgMatcher, long_arg: &RawOsStr, parse_state: &ParseState, valid_arg_found: &mut bool, trailing_values: bool, ) -> ParseResult1149     fn parse_long_arg(
1150         &mut self,
1151         matcher: &mut ArgMatcher,
1152         long_arg: &RawOsStr,
1153         parse_state: &ParseState,
1154         valid_arg_found: &mut bool,
1155         trailing_values: bool,
1156     ) -> ParseResult {
1157         // maybe here lifetime should be 'a
1158         debug!("Parser::parse_long_arg");
1159 
1160         if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
1161             self.app[opt].is_set(ArgSettings::AllowHyphenValues))
1162         {
1163             return ParseResult::MaybeHyphenValue;
1164         }
1165 
1166         // Update the current index
1167         self.cur_idx.set(self.cur_idx.get() + 1);
1168         debug!("Parser::parse_long_arg: cur_idx:={}", self.cur_idx.get());
1169 
1170         debug!("Parser::parse_long_arg: Does it contain '='...");
1171         if long_arg.is_empty() {
1172             return ParseResult::NoArg;
1173         }
1174         let (arg, val) = if let Some(index) = long_arg.find("=") {
1175             let (p0, p1) = long_arg.split_at(index);
1176             debug!("Yes '{:?}'", p1);
1177             (p0, Some(p1))
1178         } else {
1179             debug!("No");
1180             (long_arg, None)
1181         };
1182 
1183         let opt = if let Some(opt) = self.app.args.get(&*arg.to_os_str()) {
1184             debug!(
1185                 "Parser::parse_long_arg: Found valid opt or flag '{}'",
1186                 opt.to_string()
1187             );
1188             Some(opt)
1189         } else if self.is_set(AS::InferLongArgs) {
1190             let arg_str = arg.to_str_lossy();
1191             self.app.args.args().find(|a| {
1192                 a.long.map_or(false, |long| long.starts_with(&*arg_str))
1193                     || a.aliases
1194                         .iter()
1195                         .any(|(alias, _)| alias.starts_with(&*arg_str))
1196             })
1197         } else {
1198             None
1199         };
1200 
1201         if let Some(opt) = opt {
1202             *valid_arg_found = true;
1203             self.seen.push(opt.id.clone());
1204             if opt.is_set(ArgSettings::TakesValue) {
1205                 debug!(
1206                     "Parser::parse_long_arg: Found an opt with value '{:?}'",
1207                     &val
1208                 );
1209                 self.parse_opt(val, opt, matcher, trailing_values)
1210             } else if let Some(rest) = val {
1211                 debug!("Parser::parse_long_arg: Got invalid literal `{:?}`", rest);
1212                 let used: Vec<Id> = matcher
1213                     .arg_names()
1214                     .filter(|&n| {
1215                         self.app.find(n).map_or(true, |a| {
1216                             !(a.is_set(ArgSettings::Hidden) || self.required.contains(&a.id))
1217                         })
1218                     })
1219                     .cloned()
1220                     .collect();
1221 
1222                 ParseResult::UnneededAttachedValue {
1223                     rest: rest.to_str_lossy().into_owned(),
1224                     used,
1225                     arg: opt.to_string(),
1226                 }
1227             } else if let Some(parse_result) = self.check_for_help_and_version_str(arg) {
1228                 parse_result
1229             } else {
1230                 debug!("Parser::parse_long_arg: Presence validated");
1231                 self.parse_flag(opt, matcher)
1232             }
1233         } else if let Some(sc_name) = self.possible_long_flag_subcommand(arg) {
1234             ParseResult::FlagSubCommand(sc_name.to_string())
1235         } else if self.is_set(AS::AllowLeadingHyphen) {
1236             ParseResult::MaybeHyphenValue
1237         } else {
1238             ParseResult::NoMatchingArg {
1239                 arg: arg.to_str_lossy().into_owned(),
1240             }
1241         }
1242     }
1243 
parse_short_arg( &mut self, matcher: &mut ArgMatcher, short_arg: &RawOsStr, parse_state: &ParseState, pos_counter: usize, valid_arg_found: &mut bool, trailing_values: bool, ) -> ParseResult1244     fn parse_short_arg(
1245         &mut self,
1246         matcher: &mut ArgMatcher,
1247         short_arg: &RawOsStr,
1248         parse_state: &ParseState,
1249         // change this to possible pos_arg when removing the usage of &mut Parser.
1250         pos_counter: usize,
1251         valid_arg_found: &mut bool,
1252         trailing_values: bool,
1253     ) -> ParseResult {
1254         debug!("Parser::parse_short_arg: short_arg={:?}", short_arg);
1255         let arg = short_arg.to_str_lossy();
1256 
1257         if (self.is_set(AS::AllowNegativeNumbers) && arg.parse::<f64>().is_ok())
1258             || (self.is_set(AS::AllowLeadingHyphen)
1259                 && arg.chars().any(|c| !self.app.contains_short(c)))
1260             || matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt)
1261                 if self.app[opt].is_set(ArgSettings::AllowHyphenValues))
1262             || self
1263                 .app
1264                 .args
1265                 .get(&pos_counter)
1266                 .map_or(false, |arg| arg.is_set(ArgSettings::AllowHyphenValues))
1267         {
1268             return ParseResult::MaybeHyphenValue;
1269         }
1270 
1271         let mut ret = ParseResult::NoArg;
1272 
1273         let skip = self.flag_subcmd_skip;
1274         self.flag_subcmd_skip = 0;
1275         for c in arg.chars().skip(skip) {
1276             debug!("Parser::parse_short_arg:iter:{}", c);
1277 
1278             // update each index because `-abcd` is four indices to clap
1279             self.cur_idx.set(self.cur_idx.get() + 1);
1280             debug!(
1281                 "Parser::parse_short_arg:iter:{}: cur_idx:={}",
1282                 c,
1283                 self.cur_idx.get()
1284             );
1285 
1286             // Check for matching short options, and return the name if there is no trailing
1287             // concatenated value: -oval
1288             // Option: -o
1289             // Value: val
1290             if let Some(opt) = self.app.args.get(&c) {
1291                 debug!(
1292                     "Parser::parse_short_arg:iter:{}: Found valid opt or flag",
1293                     c
1294                 );
1295                 *valid_arg_found = true;
1296                 self.seen.push(opt.id.clone());
1297                 if !opt.is_set(ArgSettings::TakesValue) {
1298                     if let Some(parse_result) = self.check_for_help_and_version_char(c) {
1299                         return parse_result;
1300                     }
1301                     ret = self.parse_flag(opt, matcher);
1302                     continue;
1303                 }
1304 
1305                 // Check for trailing concatenated value
1306                 let val = short_arg.split_once(c).expect(INTERNAL_ERROR_MSG).1;
1307                 debug!(
1308                     "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii), short_arg={:?}",
1309                     c, val, val.as_raw_bytes(), short_arg
1310                 );
1311                 let val = Some(val).filter(|v| !v.is_empty());
1312 
1313                 // Default to "we're expecting a value later".
1314                 //
1315                 // If attached value is not consumed, we may have more short
1316                 // flags to parse, continue.
1317                 //
1318                 // e.g. `-xvf`, when RequireEquals && x.min_vals == 0, we don't
1319                 // consume the `vf`, even if it's provided as value.
1320                 match self.parse_opt(val, opt, matcher, trailing_values) {
1321                     ParseResult::AttachedValueNotConsumed => continue,
1322                     x => return x,
1323                 }
1324             }
1325 
1326             return if let Some(sc_name) = self.app.find_short_subcmd(c) {
1327                 debug!("Parser::parse_short_arg:iter:{}: subcommand={}", c, sc_name);
1328                 let name = sc_name.to_string();
1329                 let done_short_args = {
1330                     let cur_idx = self.cur_idx.get();
1331                     // Get the index of the previously saved flag subcommand in the group of flags (if exists).
1332                     // If it is a new flag subcommand, then the formentioned index should be the current one
1333                     // (ie. `cur_idx`), and should be registered.
1334                     let at = *self.flag_subcmd_at.get_or_insert(cur_idx);
1335                     // If we are done, then the difference of indices (cur_idx - at) should be (end - at) which
1336                     // should equal to (arg.len() - 1),
1337                     // where `end` is the index of the end of the group.
1338                     cur_idx - at == arg.len() - 1
1339                 };
1340                 if done_short_args {
1341                     self.flag_subcmd_at = None;
1342                 }
1343                 ParseResult::FlagSubCommand(name)
1344             } else {
1345                 ParseResult::NoMatchingArg {
1346                     arg: format!("-{}", c),
1347                 }
1348             };
1349         }
1350         ret
1351     }
1352 
parse_opt( &self, attached_value: Option<&RawOsStr>, opt: &Arg<'help>, matcher: &mut ArgMatcher, trailing_values: bool, ) -> ParseResult1353     fn parse_opt(
1354         &self,
1355         attached_value: Option<&RawOsStr>,
1356         opt: &Arg<'help>,
1357         matcher: &mut ArgMatcher,
1358         trailing_values: bool,
1359     ) -> ParseResult {
1360         debug!(
1361             "Parser::parse_opt; opt={}, val={:?}",
1362             opt.name, attached_value
1363         );
1364         debug!("Parser::parse_opt; opt.settings={:?}", opt.settings);
1365         // has_eq: --flag=value
1366         let has_eq = matches!(attached_value, Some(fv) if fv.starts_with("="));
1367 
1368         debug!("Parser::parse_opt; Checking for val...");
1369         // RequireEquals is set, but no '=' is provided, try throwing error.
1370         if opt.is_set(ArgSettings::RequireEquals) && !has_eq {
1371             if opt.min_vals == Some(0) {
1372                 debug!("Requires equals, but min_vals == 0");
1373                 // We assume this case is valid: require equals, but min_vals == 0.
1374                 if !opt.default_missing_vals.is_empty() {
1375                     debug!("Parser::parse_opt: has default_missing_vals");
1376                     self.add_multiple_vals_to_arg(
1377                         opt,
1378                         opt.default_missing_vals.iter().map(OsString::from),
1379                         matcher,
1380                         ValueType::CommandLine,
1381                         false,
1382                     );
1383                 };
1384                 self.inc_occurrence_of_arg(matcher, opt);
1385                 if attached_value.is_some() {
1386                     ParseResult::AttachedValueNotConsumed
1387                 } else {
1388                     ParseResult::ValuesDone
1389                 }
1390             } else {
1391                 debug!("Requires equals but not provided. Error.");
1392                 ParseResult::EqualsNotProvided {
1393                     arg: opt.to_string(),
1394                 }
1395             }
1396         } else if let Some(fv) = attached_value {
1397             let v = fv.strip_prefix("=").unwrap_or(fv);
1398             debug!("Found - {:?}, len: {}", v, v.raw_len());
1399             debug!(
1400                 "Parser::parse_opt: {:?} contains '='...{:?}",
1401                 fv,
1402                 fv.starts_with("=")
1403             );
1404             self.add_val_to_arg(
1405                 opt,
1406                 v,
1407                 matcher,
1408                 ValueType::CommandLine,
1409                 false,
1410                 trailing_values,
1411             );
1412             self.inc_occurrence_of_arg(matcher, opt);
1413             ParseResult::ValuesDone
1414         } else {
1415             debug!("Parser::parse_opt: More arg vals required...");
1416             self.inc_occurrence_of_arg(matcher, opt);
1417             matcher.new_val_group(&opt.id);
1418             for group in self.app.groups_for_arg(&opt.id) {
1419                 matcher.new_val_group(&group);
1420             }
1421             ParseResult::Opt(opt.id.clone())
1422         }
1423     }
1424 
add_val_to_arg( &self, arg: &Arg<'help>, val: &RawOsStr, matcher: &mut ArgMatcher, ty: ValueType, append: bool, trailing_values: bool, ) -> ParseResult1425     fn add_val_to_arg(
1426         &self,
1427         arg: &Arg<'help>,
1428         val: &RawOsStr,
1429         matcher: &mut ArgMatcher,
1430         ty: ValueType,
1431         append: bool,
1432         trailing_values: bool,
1433     ) -> ParseResult {
1434         debug!("Parser::add_val_to_arg; arg={}, val={:?}", arg.name, val);
1435         debug!(
1436             "Parser::add_val_to_arg; trailing_values={:?}, DontDelimTrailingVals={:?}",
1437             trailing_values,
1438             self.is_set(AS::DontDelimitTrailingValues)
1439         );
1440         if !(trailing_values && self.is_set(AS::DontDelimitTrailingValues)) {
1441             if let Some(delim) = arg.val_delim {
1442                 let arg_split = val.split(delim);
1443                 let vals = if let Some(t) = arg.terminator {
1444                     let mut vals = vec![];
1445                     for val in arg_split {
1446                         if t == val {
1447                             break;
1448                         }
1449                         vals.push(val);
1450                     }
1451                     vals
1452                 } else {
1453                     arg_split.collect()
1454                 };
1455                 self.add_multiple_vals_to_arg(
1456                     arg,
1457                     vals.into_iter().map(|x| x.to_os_str().into_owned()),
1458                     matcher,
1459                     ty,
1460                     append,
1461                 );
1462                 // If there was a delimiter used or we must use the delimiter to
1463                 // separate the values or no more vals is needed, we're not
1464                 // looking for more values.
1465                 return if val.contains(delim)
1466                     || arg.is_set(ArgSettings::RequireDelimiter)
1467                     || !matcher.needs_more_vals(arg)
1468                 {
1469                     ParseResult::ValuesDone
1470                 } else {
1471                     ParseResult::Opt(arg.id.clone())
1472                 };
1473             }
1474         }
1475         if let Some(t) = arg.terminator {
1476             if t == val {
1477                 return ParseResult::ValuesDone;
1478             }
1479         }
1480         self.add_single_val_to_arg(arg, val.to_os_str().into_owned(), matcher, ty, append);
1481         if matcher.needs_more_vals(arg) {
1482             ParseResult::Opt(arg.id.clone())
1483         } else {
1484             ParseResult::ValuesDone
1485         }
1486     }
1487 
add_multiple_vals_to_arg( &self, arg: &Arg<'help>, vals: impl Iterator<Item = OsString>, matcher: &mut ArgMatcher, ty: ValueType, append: bool, )1488     fn add_multiple_vals_to_arg(
1489         &self,
1490         arg: &Arg<'help>,
1491         vals: impl Iterator<Item = OsString>,
1492         matcher: &mut ArgMatcher,
1493         ty: ValueType,
1494         append: bool,
1495     ) {
1496         // If not appending, create a new val group and then append vals in.
1497         if !append {
1498             matcher.new_val_group(&arg.id);
1499             for group in self.app.groups_for_arg(&arg.id) {
1500                 matcher.new_val_group(&group);
1501             }
1502         }
1503         for val in vals {
1504             self.add_single_val_to_arg(arg, val, matcher, ty, true);
1505         }
1506     }
1507 
add_single_val_to_arg( &self, arg: &Arg<'help>, val: OsString, matcher: &mut ArgMatcher, ty: ValueType, append: bool, )1508     fn add_single_val_to_arg(
1509         &self,
1510         arg: &Arg<'help>,
1511         val: OsString,
1512         matcher: &mut ArgMatcher,
1513         ty: ValueType,
1514         append: bool,
1515     ) {
1516         debug!("Parser::add_single_val_to_arg: adding val...{:?}", val);
1517 
1518         // update the current index because each value is a distinct index to clap
1519         self.cur_idx.set(self.cur_idx.get() + 1);
1520         debug!(
1521             "Parser::add_single_val_to_arg: cur_idx:={}",
1522             self.cur_idx.get()
1523         );
1524 
1525         // Increment or create the group "args"
1526         for group in self.app.groups_for_arg(&arg.id) {
1527             matcher.add_val_to(&group, val.clone(), ty, append);
1528         }
1529 
1530         matcher.add_val_to(&arg.id, val, ty, append);
1531         matcher.add_index_to(&arg.id, self.cur_idx.get(), ty);
1532     }
1533 
arg_have_val(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>) -> bool1534     fn arg_have_val(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>) -> bool {
1535         matcher.arg_have_val(&arg.id)
1536     }
1537 
parse_flag(&self, flag: &Arg<'help>, matcher: &mut ArgMatcher) -> ParseResult1538     fn parse_flag(&self, flag: &Arg<'help>, matcher: &mut ArgMatcher) -> ParseResult {
1539         debug!("Parser::parse_flag");
1540 
1541         matcher.add_index_to(&flag.id, self.cur_idx.get(), ValueType::CommandLine);
1542         self.inc_occurrence_of_arg(matcher, flag);
1543 
1544         ParseResult::ValuesDone
1545     }
1546 
remove_overrides(&mut self, matcher: &mut ArgMatcher)1547     fn remove_overrides(&mut self, matcher: &mut ArgMatcher) {
1548         debug!("Parser::remove_overrides");
1549         let mut to_rem: Vec<Id> = Vec::new();
1550         let mut self_override: Vec<Id> = Vec::new();
1551         let mut arg_overrides = Vec::new();
1552         for name in matcher.arg_names() {
1553             debug!("Parser::remove_overrides:iter:{:?}", name);
1554             if let Some(overrider) = self.app.find(name) {
1555                 let mut override_self = false;
1556                 for overridee in &overrider.overrides {
1557                     debug!(
1558                         "Parser::remove_overrides:iter:{:?} => {:?}",
1559                         name, overrider
1560                     );
1561                     if *overridee == overrider.id {
1562                         override_self = true;
1563                     } else {
1564                         arg_overrides.push((overrider.id.clone(), overridee));
1565                         arg_overrides.push((overridee.clone(), &overrider.id));
1566                     }
1567                 }
1568                 // Only do self override for argument that is not positional
1569                 // argument or flag with MultipleOccurrences setting enabled.
1570                 if (self.is_set(AS::AllArgsOverrideSelf) || override_self)
1571                     && !overrider.is_set(ArgSettings::MultipleOccurrences)
1572                     && !overrider.is_positional()
1573                 {
1574                     debug!(
1575                         "Parser::remove_overrides:iter:{:?}:iter:{:?}: self override",
1576                         name, overrider
1577                     );
1578                     self_override.push(overrider.id.clone());
1579                 }
1580             }
1581         }
1582 
1583         // remove future overrides in reverse seen order
1584         for arg in self.seen.iter().rev() {
1585             for (a, overr) in arg_overrides.iter().filter(|(a, _)| a == arg) {
1586                 if !to_rem.contains(a) {
1587                     to_rem.push((*overr).clone());
1588                 }
1589             }
1590         }
1591 
1592         // Do self overrides
1593         for name in &self_override {
1594             debug!("Parser::remove_overrides:iter:self:{:?}: resetting", name);
1595             if let Some(ma) = matcher.get_mut(name) {
1596                 ma.occurs = 1;
1597                 ma.override_vals();
1598             }
1599         }
1600 
1601         // Finally remove conflicts
1602         for name in &to_rem {
1603             debug!("Parser::remove_overrides:iter:{:?}: removing", name);
1604             matcher.remove(name);
1605             self.overridden.push(name.clone());
1606         }
1607     }
1608 
add_defaults(&mut self, matcher: &mut ArgMatcher, trailing_values: bool)1609     pub(crate) fn add_defaults(&mut self, matcher: &mut ArgMatcher, trailing_values: bool) {
1610         debug!("Parser::add_defaults");
1611 
1612         for o in self.app.get_opts() {
1613             debug!("Parser::add_defaults:iter:{}:", o.name);
1614             self.add_value(o, matcher, ValueType::DefaultValue, trailing_values);
1615         }
1616 
1617         for p in self.app.get_positionals() {
1618             debug!("Parser::add_defaults:iter:{}:", p.name);
1619             self.add_value(p, matcher, ValueType::DefaultValue, trailing_values);
1620         }
1621     }
1622 
add_value( &self, arg: &Arg<'help>, matcher: &mut ArgMatcher, ty: ValueType, trailing_values: bool, )1623     fn add_value(
1624         &self,
1625         arg: &Arg<'help>,
1626         matcher: &mut ArgMatcher,
1627         ty: ValueType,
1628         trailing_values: bool,
1629     ) {
1630         if !arg.default_vals_ifs.is_empty() {
1631             debug!("Parser::add_value: has conditional defaults");
1632             if matcher.get(&arg.id).is_none() {
1633                 for (id, val, default) in arg.default_vals_ifs.iter() {
1634                     let add = if let Some(a) = matcher.get(id) {
1635                         if let Some(v) = val {
1636                             a.vals_flatten().any(|value| v == value)
1637                         } else {
1638                             true
1639                         }
1640                     } else {
1641                         false
1642                     };
1643 
1644                     if add {
1645                         if let Some(default) = default {
1646                             self.add_val_to_arg(
1647                                 arg,
1648                                 &RawOsStr::new(default),
1649                                 matcher,
1650                                 ty,
1651                                 false,
1652                                 trailing_values,
1653                             );
1654                         }
1655                         return;
1656                     }
1657                 }
1658             }
1659         } else {
1660             debug!("Parser::add_value: doesn't have conditional defaults");
1661         }
1662 
1663         fn process_default_vals(arg: &Arg<'_>, default_vals: &[&OsStr]) -> Vec<OsString> {
1664             if let Some(delim) = arg.val_delim {
1665                 let mut vals = vec![];
1666                 for val in default_vals {
1667                     let val = RawOsStr::new(val);
1668                     for val in val.split(delim) {
1669                         vals.push(val.to_os_str().into_owned());
1670                     }
1671                 }
1672                 vals
1673             } else {
1674                 default_vals.iter().map(OsString::from).collect()
1675             }
1676         }
1677 
1678         if !arg.default_vals.is_empty() {
1679             debug!("Parser::add_value:iter:{}: has default vals", arg.name);
1680             if matcher.get(&arg.id).is_some() {
1681                 debug!("Parser::add_value:iter:{}: was used", arg.name);
1682             // do nothing
1683             } else {
1684                 debug!("Parser::add_value:iter:{}: wasn't used", arg.name);
1685 
1686                 self.add_multiple_vals_to_arg(
1687                     arg,
1688                     process_default_vals(arg, &arg.default_vals).into_iter(),
1689                     matcher,
1690                     ty,
1691                     false,
1692                 );
1693             }
1694         } else {
1695             debug!(
1696                 "Parser::add_value:iter:{}: doesn't have default vals",
1697                 arg.name
1698             );
1699 
1700             // do nothing
1701         }
1702 
1703         if !arg.default_missing_vals.is_empty() {
1704             debug!(
1705                 "Parser::add_value:iter:{}: has default missing vals",
1706                 arg.name
1707             );
1708             match matcher.get(&arg.id) {
1709                 Some(ma) if ma.is_vals_empty() => {
1710                     debug!(
1711                         "Parser::add_value:iter:{}: has no user defined vals",
1712                         arg.name
1713                     );
1714                     self.add_multiple_vals_to_arg(
1715                         arg,
1716                         process_default_vals(arg, &arg.default_missing_vals).into_iter(),
1717                         matcher,
1718                         ty,
1719                         false,
1720                     );
1721                 }
1722                 None => {
1723                     debug!("Parser::add_value:iter:{}: wasn't used", arg.name);
1724                     // do nothing
1725                 }
1726                 _ => {
1727                     debug!("Parser::add_value:iter:{}: has user defined vals", arg.name);
1728                     // do nothing
1729                 }
1730             }
1731         } else {
1732             debug!(
1733                 "Parser::add_value:iter:{}: doesn't have default missing vals",
1734                 arg.name
1735             );
1736 
1737             // do nothing
1738         }
1739     }
1740 
1741     #[cfg(feature = "env")]
add_env( &mut self, matcher: &mut ArgMatcher, trailing_values: bool, ) -> ClapResult<()>1742     pub(crate) fn add_env(
1743         &mut self,
1744         matcher: &mut ArgMatcher,
1745         trailing_values: bool,
1746     ) -> ClapResult<()> {
1747         use crate::util::str_to_bool;
1748 
1749         self.app.args.args().try_for_each(|a| {
1750             // Use env only if the arg was absent among command line args,
1751             // early return if this is not the case.
1752             if matcher.get(&a.id).map_or(false, |a| a.occurs != 0) {
1753                 debug!("Parser::add_env: Skipping existing arg `{}`", a);
1754                 return Ok(());
1755             }
1756 
1757             debug!("Parser::add_env: Checking arg `{}`", a);
1758             if let Some((_, Some(ref val))) = a.env {
1759                 let val = RawOsStr::new(val);
1760 
1761                 if a.is_set(ArgSettings::TakesValue) {
1762                     debug!(
1763                         "Parser::add_env: Found an opt with value={:?}, trailing={:?}",
1764                         val, trailing_values
1765                     );
1766                     self.add_val_to_arg(
1767                         a,
1768                         &val,
1769                         matcher,
1770                         ValueType::EnvVariable,
1771                         false,
1772                         trailing_values,
1773                     );
1774                     return Ok(());
1775                 }
1776 
1777                 debug!("Parser::add_env: Checking for help and version");
1778                 // Early return on `HelpFlag` or `VersionFlag`.
1779                 match self.check_for_help_and_version_str(&val) {
1780                     Some(ParseResult::HelpFlag) => {
1781                         return Err(self.help_err(true));
1782                     }
1783                     Some(ParseResult::VersionFlag) => {
1784                         return Err(self.version_err(true));
1785                     }
1786                     _ => (),
1787                 }
1788 
1789                 debug!("Parser::add_env: Found a flag with value `{:?}`", val);
1790                 let predicate = str_to_bool(val.to_str_lossy());
1791                 debug!("Parser::add_env: Found boolean literal `{}`", predicate);
1792                 if predicate {
1793                     matcher.add_index_to(&a.id, self.cur_idx.get(), ValueType::EnvVariable);
1794                 }
1795             }
1796 
1797             Ok(())
1798         })
1799     }
1800 
1801     /// Increase occurrence of specific argument and the grouped arg it's in.
inc_occurrence_of_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>)1802     fn inc_occurrence_of_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>) {
1803         matcher.inc_occurrence_of(&arg.id, arg.is_set(ArgSettings::IgnoreCase));
1804         // Increment or create the group "args"
1805         for group in self.app.groups_for_arg(&arg.id) {
1806             matcher.inc_occurrence_of(&group, false);
1807         }
1808     }
1809 }
1810 
1811 // Error, Help, and Version Methods
1812 impl<'help, 'app> Parser<'help, 'app> {
1813     /// Is only used for the long flag(which is the only one needs fuzzy searching)
did_you_mean_error( &mut self, arg: &str, matcher: &mut ArgMatcher, remaining_args: &[&str], ) -> ClapError1814     fn did_you_mean_error(
1815         &mut self,
1816         arg: &str,
1817         matcher: &mut ArgMatcher,
1818         remaining_args: &[&str],
1819     ) -> ClapError {
1820         debug!("Parser::did_you_mean_error: arg={}", arg);
1821         // Didn't match a flag or option
1822         let longs = self
1823             .app
1824             .args
1825             .keys()
1826             .filter_map(|x| match x {
1827                 KeyType::Long(l) => Some(l.to_string_lossy().into_owned()),
1828                 _ => None,
1829             })
1830             .collect::<Vec<_>>();
1831         debug!("Parser::did_you_mean_error: longs={:?}", longs);
1832 
1833         let did_you_mean = suggestions::did_you_mean_flag(
1834             arg,
1835             remaining_args,
1836             longs.iter().map(|x| &x[..]),
1837             self.app.subcommands.as_mut_slice(),
1838         );
1839 
1840         // Add the arg to the matches to build a proper usage string
1841         if let Some((name, _)) = did_you_mean.as_ref() {
1842             if let Some(opt) = self.app.args.get(&name.as_ref()) {
1843                 self.inc_occurrence_of_arg(matcher, opt);
1844             }
1845         }
1846 
1847         let used: Vec<Id> = matcher
1848             .arg_names()
1849             .filter(|n| {
1850                 self.app.find(n).map_or(true, |a| {
1851                     !(self.required.contains(&a.id) || a.is_set(ArgSettings::Hidden))
1852                 })
1853             })
1854             .cloned()
1855             .collect();
1856 
1857         ClapError::unknown_argument(
1858             self.app,
1859             format!("--{}", arg),
1860             did_you_mean,
1861             Usage::new(self).create_usage_with_title(&*used),
1862         )
1863     }
1864 
write_help_err(&self) -> ClapResult<Colorizer>1865     pub(crate) fn write_help_err(&self) -> ClapResult<Colorizer> {
1866         let mut c = Colorizer::new(true, self.app.get_color());
1867         Help::new(HelpWriter::Buffer(&mut c), self, false).write_help()?;
1868         Ok(c)
1869     }
1870 
help_err(&self, mut use_long: bool) -> ClapError1871     fn help_err(&self, mut use_long: bool) -> ClapError {
1872         debug!(
1873             "Parser::help_err: use_long={:?}",
1874             use_long && self.use_long_help()
1875         );
1876 
1877         use_long = use_long && self.use_long_help();
1878         let mut c = Colorizer::new(false, self.app.get_color());
1879 
1880         match Help::new(HelpWriter::Buffer(&mut c), self, use_long).write_help() {
1881             Err(e) => e.into(),
1882             _ => ClapError::new(c, ErrorKind::DisplayHelp),
1883         }
1884     }
1885 
version_err(&self, use_long: bool) -> ClapError1886     fn version_err(&self, use_long: bool) -> ClapError {
1887         debug!("Parser::version_err");
1888 
1889         let msg = self.app._render_version(use_long);
1890         let mut c = Colorizer::new(false, self.app.get_color());
1891         c.none(msg);
1892         ClapError::new(c, ErrorKind::DisplayVersion)
1893     }
1894 }
1895 
1896 // Query Methods
1897 impl<'help, 'app> Parser<'help, 'app> {
is_set(&self, s: AS) -> bool1898     pub(crate) fn is_set(&self, s: AS) -> bool {
1899         self.app.is_set(s)
1900     }
1901 }
1902