• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Std
2 use std::{
3     cell::Cell,
4     ffi::{OsStr, OsString},
5 };
6 
7 // Third Party
8 use clap_lex::RawOsStr;
9 
10 // Internal
11 use crate::builder::AppSettings as AS;
12 use crate::builder::{Arg, Command};
13 use crate::error::Error as ClapError;
14 use crate::error::Result as ClapResult;
15 use crate::mkeymap::KeyType;
16 use crate::output::fmt::Stream;
17 use crate::output::{fmt::Colorizer, Usage};
18 use crate::parser::features::suggestions;
19 use crate::parser::{ArgMatcher, SubCommand};
20 use crate::parser::{Validator, ValueSource};
21 use crate::util::Id;
22 use crate::ArgAction;
23 use crate::{INTERNAL_ERROR_MSG, INVALID_UTF8};
24 
25 pub(crate) struct Parser<'help, 'cmd> {
26     cmd: &'cmd mut Command<'help>,
27     cur_idx: Cell<usize>,
28     /// Index of the previous flag subcommand in a group of flags.
29     flag_subcmd_at: Option<usize>,
30     /// Counter indicating the number of items to skip
31     /// when revisiting the group of flags which includes the flag subcommand.
32     flag_subcmd_skip: usize,
33 }
34 
35 // Initializing Methods
36 impl<'help, 'cmd> Parser<'help, 'cmd> {
new(cmd: &'cmd mut Command<'help>) -> Self37     pub(crate) fn new(cmd: &'cmd mut Command<'help>) -> Self {
38         Parser {
39             cmd,
40             cur_idx: Cell::new(0),
41             flag_subcmd_at: None,
42             flag_subcmd_skip: 0,
43         }
44     }
45 }
46 
47 // Parsing Methods
48 impl<'help, 'cmd> Parser<'help, 'cmd> {
49     // The actual parsing function
50     #[allow(clippy::cognitive_complexity)]
get_matches_with( &mut self, matcher: &mut ArgMatcher, raw_args: &mut clap_lex::RawArgs, mut args_cursor: clap_lex::ArgCursor, ) -> ClapResult<()>51     pub(crate) fn get_matches_with(
52         &mut self,
53         matcher: &mut ArgMatcher,
54         raw_args: &mut clap_lex::RawArgs,
55         mut args_cursor: clap_lex::ArgCursor,
56     ) -> ClapResult<()> {
57         debug!("Parser::get_matches_with");
58         // Verify all positional assertions pass
59 
60         let mut subcmd_name: Option<String> = None;
61         let mut keep_state = false;
62         let mut parse_state = ParseState::ValuesDone;
63         let mut pos_counter = 1;
64 
65         // Already met any valid arg(then we shouldn't expect subcommands after it).
66         let mut valid_arg_found = false;
67         // If the user already passed '--'. Meaning only positional args follow.
68         let mut trailing_values = false;
69 
70         // Count of positional args
71         let positional_count = self
72             .cmd
73             .get_keymap()
74             .keys()
75             .filter(|x| x.is_position())
76             .count();
77         // If any arg sets .last(true)
78         let contains_last = self.cmd.get_arguments().any(|x| x.is_last_set());
79 
80         while let Some(arg_os) = raw_args.next(&mut args_cursor) {
81             // Recover the replaced items if any.
82             if let Some(replaced_items) = arg_os
83                 .to_value()
84                 .ok()
85                 .and_then(|a| self.cmd.get_replacement(a))
86             {
87                 debug!(
88                     "Parser::get_matches_with: found replacer: {:?}, target: {:?}",
89                     arg_os, replaced_items
90                 );
91                 raw_args.insert(&args_cursor, replaced_items);
92                 continue;
93             }
94 
95             debug!(
96                 "Parser::get_matches_with: Begin parsing '{:?}' ({:?})",
97                 arg_os.to_value_os(),
98                 arg_os.to_value_os().as_raw_bytes()
99             );
100 
101             // Has the user already passed '--'? Meaning only positional args follow
102             if !trailing_values {
103                 if self.cmd.is_subcommand_precedence_over_arg_set()
104                     || !matches!(parse_state, ParseState::Opt(_) | ParseState::Pos(_))
105                 {
106                     // Does the arg match a subcommand name, or any of its aliases (if defined)
107                     let sc_name = self.possible_subcommand(arg_os.to_value(), valid_arg_found);
108                     debug!("Parser::get_matches_with: sc={:?}", sc_name);
109                     if let Some(sc_name) = sc_name {
110                         #[allow(deprecated)]
111                         if sc_name == "help"
112                             && !self.is_set(AS::NoAutoHelp)
113                             && !self.cmd.is_disable_help_subcommand_set()
114                         {
115                             self.parse_help_subcommand(raw_args.remaining(&mut args_cursor))?;
116                             unreachable!("`parse_help_subcommand` always errors");
117                         } else {
118                             subcmd_name = Some(sc_name.to_owned());
119                         }
120                         break;
121                     }
122                 }
123 
124                 if arg_os.is_escape() {
125                     if matches!(&parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
126                         self.cmd[opt].is_allow_hyphen_values_set())
127                     {
128                         // ParseResult::MaybeHyphenValue, do nothing
129                     } else {
130                         debug!("Parser::get_matches_with: setting TrailingVals=true");
131                         trailing_values = true;
132                         continue;
133                     }
134                 } else if let Some((long_arg, long_value)) = arg_os.to_long() {
135                     let parse_result = self.parse_long_arg(
136                         matcher,
137                         long_arg,
138                         long_value,
139                         &parse_state,
140                         &mut valid_arg_found,
141                         trailing_values,
142                     )?;
143                     debug!(
144                         "Parser::get_matches_with: After parse_long_arg {:?}",
145                         parse_result
146                     );
147                     match parse_result {
148                         ParseResult::NoArg => {
149                             unreachable!("`to_long` always has the flag specified")
150                         }
151                         ParseResult::ValuesDone => {
152                             parse_state = ParseState::ValuesDone;
153                             continue;
154                         }
155                         ParseResult::Opt(id) => {
156                             parse_state = ParseState::Opt(id);
157                             continue;
158                         }
159                         ParseResult::FlagSubCommand(name) => {
160                             debug!(
161                                 "Parser::get_matches_with: FlagSubCommand found in long arg {:?}",
162                                 &name
163                             );
164                             subcmd_name = Some(name);
165                             break;
166                         }
167                         ParseResult::EqualsNotProvided { arg } => {
168                             let _ = self.resolve_pending(matcher);
169                             return Err(ClapError::no_equals(
170                                 self.cmd,
171                                 arg,
172                                 Usage::new(self.cmd).create_usage_with_title(&[]),
173                             ));
174                         }
175                         ParseResult::NoMatchingArg { arg } => {
176                             let _ = self.resolve_pending(matcher);
177                             let remaining_args: Vec<_> = raw_args
178                                 .remaining(&mut args_cursor)
179                                 .map(|x| x.to_str().expect(INVALID_UTF8))
180                                 .collect();
181                             return Err(self.did_you_mean_error(&arg, matcher, &remaining_args));
182                         }
183                         ParseResult::UnneededAttachedValue { rest, used, arg } => {
184                             let _ = self.resolve_pending(matcher);
185                             return Err(ClapError::too_many_values(
186                                 self.cmd,
187                                 rest,
188                                 arg,
189                                 Usage::new(self.cmd).create_usage_no_title(&used),
190                             ));
191                         }
192                         ParseResult::MaybeHyphenValue => {
193                             // Maybe a hyphen value, do nothing.
194                         }
195                         ParseResult::AttachedValueNotConsumed => {
196                             unreachable!()
197                         }
198                     }
199                 } else if let Some(short_arg) = arg_os.to_short() {
200                     // Arg looks like a short flag, and not a possible number
201 
202                     // Try to parse short args like normal, if allow_hyphen_values or
203                     // AllowNegativeNumbers is set, parse_short_arg will *not* throw
204                     // an error, and instead return Ok(None)
205                     let parse_result = self.parse_short_arg(
206                         matcher,
207                         short_arg,
208                         &parse_state,
209                         pos_counter,
210                         &mut valid_arg_found,
211                         trailing_values,
212                     )?;
213                     // If it's None, we then check if one of those two AppSettings was set
214                     debug!(
215                         "Parser::get_matches_with: After parse_short_arg {:?}",
216                         parse_result
217                     );
218                     match parse_result {
219                         ParseResult::NoArg => {
220                             // Is a single dash `-`, try positional.
221                         }
222                         ParseResult::ValuesDone => {
223                             parse_state = ParseState::ValuesDone;
224                             continue;
225                         }
226                         ParseResult::Opt(id) => {
227                             parse_state = ParseState::Opt(id);
228                             continue;
229                         }
230                         ParseResult::FlagSubCommand(name) => {
231                             // If there are more short flags to be processed, we should keep the state, and later
232                             // revisit the current group of short flags skipping the subcommand.
233                             keep_state = self
234                                 .flag_subcmd_at
235                                 .map(|at| {
236                                     raw_args
237                                         .seek(&mut args_cursor, clap_lex::SeekFrom::Current(-1));
238                                     // Since we are now saving the current state, the number of flags to skip during state recovery should
239                                     // be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position.
240                                     self.flag_subcmd_skip = self.cur_idx.get() - at + 1;
241                                 })
242                                 .is_some();
243 
244                             debug!(
245                                 "Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}",
246                                 name,
247                                 keep_state,
248                                 self.flag_subcmd_skip
249                             );
250 
251                             subcmd_name = Some(name);
252                             break;
253                         }
254                         ParseResult::EqualsNotProvided { arg } => {
255                             let _ = self.resolve_pending(matcher);
256                             return Err(ClapError::no_equals(
257                                 self.cmd,
258                                 arg,
259                                 Usage::new(self.cmd).create_usage_with_title(&[]),
260                             ));
261                         }
262                         ParseResult::NoMatchingArg { arg } => {
263                             let _ = self.resolve_pending(matcher);
264                             return Err(ClapError::unknown_argument(
265                                 self.cmd,
266                                 arg,
267                                 None,
268                                 Usage::new(self.cmd).create_usage_with_title(&[]),
269                             ));
270                         }
271                         ParseResult::MaybeHyphenValue => {
272                             // Maybe a hyphen value, do nothing.
273                         }
274                         ParseResult::UnneededAttachedValue { .. }
275                         | ParseResult::AttachedValueNotConsumed => unreachable!(),
276                     }
277                 }
278 
279                 if let ParseState::Opt(id) = &parse_state {
280                     // Assume this is a value of a previous arg.
281 
282                     // get the option so we can check the settings
283                     let arg_values = matcher.pending_values_mut(id, None);
284                     let arg = &self.cmd[id];
285                     let parse_result = self.split_arg_values(
286                         arg,
287                         arg_os.to_value_os(),
288                         trailing_values,
289                         arg_values,
290                     );
291                     let parse_result = parse_result.unwrap_or_else(|| {
292                         if matcher.needs_more_vals(arg) {
293                             ParseResult::Opt(arg.id.clone())
294                         } else {
295                             ParseResult::ValuesDone
296                         }
297                     });
298                     parse_state = match parse_result {
299                         ParseResult::Opt(id) => ParseState::Opt(id),
300                         ParseResult::ValuesDone => ParseState::ValuesDone,
301                         _ => unreachable!(),
302                     };
303                     // get the next value from the iterator
304                     continue;
305                 }
306             }
307 
308             // Correct pos_counter.
309             pos_counter = {
310                 let is_second_to_last = pos_counter + 1 == positional_count;
311 
312                 // The last positional argument, or second to last positional
313                 // argument may be set to .multiple_values(true) or `.multiple_occurrences(true)`
314                 let low_index_mults = is_second_to_last
315                     && self
316                         .cmd
317                         .get_positionals()
318                         .any(|a| a.is_multiple() && (positional_count != a.index.unwrap_or(0)))
319                     && self
320                         .cmd
321                         .get_positionals()
322                         .last()
323                         .map_or(false, |p_name| !p_name.is_last_set());
324 
325                 let missing_pos = self.cmd.is_allow_missing_positional_set()
326                     && is_second_to_last
327                     && !trailing_values;
328 
329                 debug!(
330                     "Parser::get_matches_with: Positional counter...{}",
331                     pos_counter
332                 );
333                 debug!(
334                     "Parser::get_matches_with: Low index multiples...{:?}",
335                     low_index_mults
336                 );
337 
338                 if low_index_mults || missing_pos {
339                     let skip_current = if let Some(n) = raw_args.peek(&args_cursor) {
340                         if let Some(arg) = self
341                             .cmd
342                             .get_positionals()
343                             .find(|a| a.index == Some(pos_counter))
344                         {
345                             // If next value looks like a new_arg or it's a
346                             // subcommand, skip positional argument under current
347                             // pos_counter(which means current value cannot be a
348                             // positional argument with a value next to it), assume
349                             // current value matches the next arg.
350                             self.is_new_arg(&n, arg)
351                                 || self
352                                     .possible_subcommand(n.to_value(), valid_arg_found)
353                                     .is_some()
354                         } else {
355                             true
356                         }
357                     } else {
358                         true
359                     };
360 
361                     if skip_current {
362                         debug!("Parser::get_matches_with: Bumping the positional counter...");
363                         pos_counter + 1
364                     } else {
365                         pos_counter
366                     }
367                 } else if trailing_values
368                     && (self.cmd.is_allow_missing_positional_set() || contains_last)
369                 {
370                     // Came to -- and one positional has .last(true) set, so we go immediately
371                     // to the last (highest index) positional
372                     debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
373                     positional_count
374                 } else {
375                     pos_counter
376                 }
377             };
378 
379             if let Some(arg) = self.cmd.get_keymap().get(&pos_counter) {
380                 if arg.is_last_set() && !trailing_values {
381                     let _ = self.resolve_pending(matcher);
382                     return Err(ClapError::unknown_argument(
383                         self.cmd,
384                         arg_os.display().to_string(),
385                         None,
386                         Usage::new(self.cmd).create_usage_with_title(&[]),
387                     ));
388                 }
389 
390                 if self.cmd.is_trailing_var_arg_set() && pos_counter == positional_count {
391                     trailing_values = true;
392                 }
393 
394                 if matcher.pending_arg_id() != Some(&arg.id) || !arg.is_multiple_values_set() {
395                     self.resolve_pending(matcher)?;
396                 }
397                 let arg_values = matcher.pending_values_mut(&arg.id, Some(Identifier::Index));
398                 let _parse_result =
399                     self.split_arg_values(arg, arg_os.to_value_os(), trailing_values, arg_values);
400                 if let Some(_parse_result) = _parse_result {
401                     if _parse_result != ParseResult::ValuesDone {
402                         debug!(
403                             "Parser::get_matches_with: Ignoring state {:?}; positionals do their own thing",
404                             _parse_result
405                         );
406                     }
407                 }
408 
409                 // Only increment the positional counter if it doesn't allow multiples
410                 if !arg.is_multiple() {
411                     pos_counter += 1;
412                     parse_state = ParseState::ValuesDone;
413                 } else {
414                     parse_state = ParseState::Pos(arg.id.clone());
415                 }
416                 valid_arg_found = true;
417             } else if let Some(external_parser) =
418                 self.cmd.get_external_subcommand_value_parser().cloned()
419             {
420                 // Get external subcommand name
421                 let sc_name = match arg_os.to_value() {
422                     Ok(s) => s.to_string(),
423                     Err(_) => {
424                         let _ = self.resolve_pending(matcher);
425                         return Err(ClapError::invalid_utf8(
426                             self.cmd,
427                             Usage::new(self.cmd).create_usage_with_title(&[]),
428                         ));
429                     }
430                 };
431 
432                 // Collect the external subcommand args
433                 let mut sc_m = ArgMatcher::new(self.cmd);
434                 if cfg!(feature = "unstable-v4") || !raw_args.is_end(&args_cursor) {
435                     sc_m.start_occurrence_of_external(self.cmd);
436                 }
437 
438                 for raw_val in raw_args.remaining(&mut args_cursor) {
439                     let val = external_parser.parse_ref(self.cmd, None, raw_val)?;
440                     let external_id = &Id::empty_hash();
441                     sc_m.add_val_to(external_id, val, raw_val.to_os_string());
442                 }
443 
444                 matcher.subcommand(SubCommand {
445                     id: Id::from(&*sc_name),
446                     name: sc_name,
447                     matches: sc_m.into_inner(),
448                 });
449 
450                 self.resolve_pending(matcher)?;
451                 #[cfg(feature = "env")]
452                 self.add_env(matcher)?;
453                 self.add_defaults(matcher)?;
454                 return Validator::new(self.cmd).validate(parse_state, matcher);
455             } else {
456                 // Start error processing
457                 let _ = self.resolve_pending(matcher);
458                 return Err(self.match_arg_error(&arg_os, valid_arg_found, trailing_values));
459             }
460         }
461 
462         if let Some(ref pos_sc_name) = subcmd_name {
463             let sc_name = self
464                 .cmd
465                 .find_subcommand(pos_sc_name)
466                 .expect(INTERNAL_ERROR_MSG)
467                 .get_name()
468                 .to_owned();
469             self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor, keep_state)?;
470         }
471 
472         self.resolve_pending(matcher)?;
473         #[cfg(feature = "env")]
474         self.add_env(matcher)?;
475         self.add_defaults(matcher)?;
476         Validator::new(self.cmd).validate(parse_state, matcher)
477     }
478 
match_arg_error( &self, arg_os: &clap_lex::ParsedArg<'_>, valid_arg_found: bool, trailing_values: bool, ) -> ClapError479     fn match_arg_error(
480         &self,
481         arg_os: &clap_lex::ParsedArg<'_>,
482         valid_arg_found: bool,
483         trailing_values: bool,
484     ) -> ClapError {
485         // If argument follows a `--`
486         if trailing_values {
487             // If the arg matches a subcommand name, or any of its aliases (if defined)
488             if self
489                 .possible_subcommand(arg_os.to_value(), valid_arg_found)
490                 .is_some()
491             {
492                 return ClapError::unnecessary_double_dash(
493                     self.cmd,
494                     arg_os.display().to_string(),
495                     Usage::new(self.cmd).create_usage_with_title(&[]),
496                 );
497             }
498         }
499         let candidates = suggestions::did_you_mean(
500             &arg_os.display().to_string(),
501             self.cmd.all_subcommand_names(),
502         );
503         // If the argument looks like a subcommand.
504         if !candidates.is_empty() {
505             let candidates: Vec<_> = candidates
506                 .iter()
507                 .map(|candidate| format!("'{}'", candidate))
508                 .collect();
509             return ClapError::invalid_subcommand(
510                 self.cmd,
511                 arg_os.display().to_string(),
512                 candidates.join(" or "),
513                 self.cmd
514                     .get_bin_name()
515                     .unwrap_or_else(|| self.cmd.get_name())
516                     .to_owned(),
517                 Usage::new(self.cmd).create_usage_with_title(&[]),
518             );
519         }
520         // If the argument must be a subcommand.
521         if !self.cmd.has_args() || self.cmd.is_infer_subcommands_set() && self.cmd.has_subcommands()
522         {
523             return ClapError::unrecognized_subcommand(
524                 self.cmd,
525                 arg_os.display().to_string(),
526                 Usage::new(self.cmd).create_usage_with_title(&[]),
527             );
528         }
529         ClapError::unknown_argument(
530             self.cmd,
531             arg_os.display().to_string(),
532             None,
533             Usage::new(self.cmd).create_usage_with_title(&[]),
534         )
535     }
536 
537     // Checks if the arg matches a subcommand name, or any of its aliases (if defined)
possible_subcommand( &self, arg: Result<&str, &RawOsStr>, valid_arg_found: bool, ) -> Option<&str>538     fn possible_subcommand(
539         &self,
540         arg: Result<&str, &RawOsStr>,
541         valid_arg_found: bool,
542     ) -> Option<&str> {
543         debug!("Parser::possible_subcommand: arg={:?}", arg);
544         let arg = arg.ok()?;
545 
546         if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) {
547             if self.cmd.is_infer_subcommands_set() {
548                 // For subcommand `test`, we accepts it's prefix: `t`, `te`,
549                 // `tes` and `test`.
550                 let v = self
551                     .cmd
552                     .all_subcommand_names()
553                     .filter(|s| s.starts_with(arg))
554                     .collect::<Vec<_>>();
555 
556                 if v.len() == 1 {
557                     return Some(v[0]);
558                 }
559 
560                 // If there is any ambiguity, fallback to non-infer subcommand
561                 // search.
562             }
563             if let Some(sc) = self.cmd.find_subcommand(arg) {
564                 return Some(sc.get_name());
565             }
566         }
567         None
568     }
569 
570     // Checks if the arg matches a long flag subcommand name, or any of its aliases (if defined)
possible_long_flag_subcommand(&self, arg: &str) -> Option<&str>571     fn possible_long_flag_subcommand(&self, arg: &str) -> Option<&str> {
572         debug!("Parser::possible_long_flag_subcommand: arg={:?}", arg);
573         if self.cmd.is_infer_subcommands_set() {
574             let options = self
575                 .cmd
576                 .get_subcommands()
577                 .fold(Vec::new(), |mut options, sc| {
578                     if let Some(long) = sc.get_long_flag() {
579                         if long.starts_with(arg) {
580                             options.push(long);
581                         }
582                         options.extend(sc.get_all_aliases().filter(|alias| alias.starts_with(arg)))
583                     }
584                     options
585                 });
586             if options.len() == 1 {
587                 return Some(options[0]);
588             }
589 
590             for sc in options {
591                 if sc == arg {
592                     return Some(sc);
593                 }
594             }
595         } else if let Some(sc_name) = self.cmd.find_long_subcmd(arg) {
596             return Some(sc_name);
597         }
598         None
599     }
600 
parse_help_subcommand( &self, cmds: impl Iterator<Item = &'cmd OsStr>, ) -> ClapResult<std::convert::Infallible>601     fn parse_help_subcommand(
602         &self,
603         cmds: impl Iterator<Item = &'cmd OsStr>,
604     ) -> ClapResult<std::convert::Infallible> {
605         debug!("Parser::parse_help_subcommand");
606 
607         let mut cmd = self.cmd.clone();
608         let sc = {
609             let mut sc = &mut cmd;
610 
611             for cmd in cmds {
612                 sc = if let Some(sc_name) =
613                     sc.find_subcommand(cmd).map(|sc| sc.get_name().to_owned())
614                 {
615                     sc._build_subcommand(&sc_name).unwrap()
616                 } else {
617                     return Err(ClapError::unrecognized_subcommand(
618                         sc,
619                         cmd.to_string_lossy().into_owned(),
620                         Usage::new(sc).create_usage_with_title(&[]),
621                     ));
622                 };
623             }
624 
625             sc
626         };
627         let parser = Parser::new(sc);
628 
629         Err(parser.help_err(true, Stream::Stdout))
630     }
631 
is_new_arg(&self, next: &clap_lex::ParsedArg<'_>, current_positional: &Arg) -> bool632     fn is_new_arg(&self, next: &clap_lex::ParsedArg<'_>, current_positional: &Arg) -> bool {
633         #![allow(clippy::needless_bool)] // Prefer consistent if/else-if ladder
634 
635         debug!(
636             "Parser::is_new_arg: {:?}:{:?}",
637             next.to_value_os(),
638             current_positional.name
639         );
640 
641         if self.cmd.is_allow_hyphen_values_set()
642             || self.cmd[&current_positional.id].is_allow_hyphen_values_set()
643             || (self.cmd.is_allow_negative_numbers_set() && next.is_number())
644         {
645             // If allow hyphen, this isn't a new arg.
646             debug!("Parser::is_new_arg: Allow hyphen");
647             false
648         } else if next.is_long() {
649             // If this is a long flag, this is a new arg.
650             debug!("Parser::is_new_arg: --<something> found");
651             true
652         } else if next.is_short() {
653             // If this is a short flag, this is a new arg. But a singe '-' by
654             // itself is a value and typically means "stdin" on unix systems.
655             debug!("Parser::is_new_arg: -<something> found");
656             true
657         } else {
658             // Nothing special, this is a value.
659             debug!("Parser::is_new_arg: value");
660             false
661         }
662     }
663 
parse_subcommand( &mut self, sc_name: &str, matcher: &mut ArgMatcher, raw_args: &mut clap_lex::RawArgs, args_cursor: clap_lex::ArgCursor, keep_state: bool, ) -> ClapResult<()>664     fn parse_subcommand(
665         &mut self,
666         sc_name: &str,
667         matcher: &mut ArgMatcher,
668         raw_args: &mut clap_lex::RawArgs,
669         args_cursor: clap_lex::ArgCursor,
670         keep_state: bool,
671     ) -> ClapResult<()> {
672         debug!("Parser::parse_subcommand");
673 
674         let partial_parsing_enabled = self.cmd.is_ignore_errors_set();
675 
676         if let Some(sc) = self.cmd._build_subcommand(sc_name) {
677             let mut sc_matcher = ArgMatcher::new(sc);
678 
679             debug!(
680                 "Parser::parse_subcommand: About to parse sc={}",
681                 sc.get_name()
682             );
683 
684             {
685                 let mut p = Parser::new(sc);
686                 // HACK: maintain indexes between parsers
687                 // FlagSubCommand short arg needs to revisit the current short args, but skip the subcommand itself
688                 if keep_state {
689                     p.cur_idx.set(self.cur_idx.get());
690                     p.flag_subcmd_at = self.flag_subcmd_at;
691                     p.flag_subcmd_skip = self.flag_subcmd_skip;
692                 }
693                 if let Err(error) = p.get_matches_with(&mut sc_matcher, raw_args, args_cursor) {
694                     if partial_parsing_enabled {
695                         debug!(
696                             "Parser::parse_subcommand: ignored error in subcommand {}: {:?}",
697                             sc_name, error
698                         );
699                     } else {
700                         return Err(error);
701                     }
702                 }
703             }
704             matcher.subcommand(SubCommand {
705                 id: sc.get_id(),
706                 name: sc.get_name().to_owned(),
707                 matches: sc_matcher.into_inner(),
708             });
709         }
710         Ok(())
711     }
712 
parse_long_arg( &mut self, matcher: &mut ArgMatcher, long_arg: Result<&str, &RawOsStr>, long_value: Option<&RawOsStr>, parse_state: &ParseState, valid_arg_found: &mut bool, trailing_values: bool, ) -> ClapResult<ParseResult>713     fn parse_long_arg(
714         &mut self,
715         matcher: &mut ArgMatcher,
716         long_arg: Result<&str, &RawOsStr>,
717         long_value: Option<&RawOsStr>,
718         parse_state: &ParseState,
719         valid_arg_found: &mut bool,
720         trailing_values: bool,
721     ) -> ClapResult<ParseResult> {
722         // maybe here lifetime should be 'a
723         debug!("Parser::parse_long_arg");
724 
725         if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
726             self.cmd[opt].is_allow_hyphen_values_set())
727         {
728             return Ok(ParseResult::MaybeHyphenValue);
729         }
730 
731         debug!("Parser::parse_long_arg: Does it contain '='...");
732         let long_arg = match long_arg {
733             Ok(long_arg) => long_arg,
734             Err(long_arg) => {
735                 return Ok(ParseResult::NoMatchingArg {
736                     arg: long_arg.to_str_lossy().into_owned(),
737                 });
738             }
739         };
740         if long_arg.is_empty() {
741             debug_assert!(
742                 long_value.is_some(),
743                 "`--` should be filtered out before this point"
744             );
745         }
746 
747         let arg = if let Some(arg) = self.cmd.get_keymap().get(long_arg) {
748             debug!(
749                 "Parser::parse_long_arg: Found valid arg or flag '{}'",
750                 arg.to_string()
751             );
752             Some((long_arg, arg))
753         } else if self.cmd.is_infer_long_args_set() {
754             self.cmd.get_arguments().find_map(|a| {
755                 if let Some(long) = a.long {
756                     if long.starts_with(long_arg) {
757                         return Some((long, a));
758                     }
759                 }
760                 a.aliases
761                     .iter()
762                     .find_map(|(alias, _)| alias.starts_with(long_arg).then(|| (*alias, a)))
763             })
764         } else {
765             None
766         };
767 
768         if let Some((_long_arg, arg)) = arg {
769             let ident = Identifier::Long;
770             *valid_arg_found = true;
771             if arg.is_takes_value_set() {
772                 debug!(
773                     "Parser::parse_long_arg({:?}): Found an arg with value '{:?}'",
774                     long_arg, &long_value
775                 );
776                 let has_eq = long_value.is_some();
777                 self.parse_opt_value(ident, long_value, arg, matcher, trailing_values, has_eq)
778             } else if let Some(rest) = long_value {
779                 let required = self.cmd.required_graph();
780                 debug!(
781                     "Parser::parse_long_arg({:?}): Got invalid literal `{:?}`",
782                     long_arg, rest
783                 );
784                 let used: Vec<Id> = matcher
785                     .arg_ids()
786                     .filter(|arg_id| {
787                         matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent)
788                     })
789                     .filter(|&n| {
790                         self.cmd
791                             .find(n)
792                             .map_or(true, |a| !(a.is_hide_set() || required.contains(&a.id)))
793                     })
794                     .cloned()
795                     .collect();
796 
797                 Ok(ParseResult::UnneededAttachedValue {
798                     rest: rest.to_str_lossy().into_owned(),
799                     used,
800                     arg: arg.to_string(),
801                 })
802             } else {
803                 debug!("Parser::parse_long_arg({:?}): Presence validated", long_arg);
804                 self.react(Some(ident), ValueSource::CommandLine, arg, vec![], matcher)
805             }
806         } else if let Some(sc_name) = self.possible_long_flag_subcommand(long_arg) {
807             Ok(ParseResult::FlagSubCommand(sc_name.to_string()))
808         } else if self.cmd.is_allow_hyphen_values_set() {
809             Ok(ParseResult::MaybeHyphenValue)
810         } else {
811             Ok(ParseResult::NoMatchingArg {
812                 arg: long_arg.to_owned(),
813             })
814         }
815     }
816 
parse_short_arg( &mut self, matcher: &mut ArgMatcher, mut short_arg: clap_lex::ShortFlags<'_>, parse_state: &ParseState, pos_counter: usize, valid_arg_found: &mut bool, trailing_values: bool, ) -> ClapResult<ParseResult>817     fn parse_short_arg(
818         &mut self,
819         matcher: &mut ArgMatcher,
820         mut short_arg: clap_lex::ShortFlags<'_>,
821         parse_state: &ParseState,
822         // change this to possible pos_arg when removing the usage of &mut Parser.
823         pos_counter: usize,
824         valid_arg_found: &mut bool,
825         trailing_values: bool,
826     ) -> ClapResult<ParseResult> {
827         debug!("Parser::parse_short_arg: short_arg={:?}", short_arg);
828 
829         #[allow(clippy::blocks_in_if_conditions)]
830         if self.cmd.is_allow_negative_numbers_set() && short_arg.is_number() {
831             debug!("Parser::parse_short_arg: negative number");
832             return Ok(ParseResult::MaybeHyphenValue);
833         } else if self.cmd.is_allow_hyphen_values_set()
834             && short_arg
835                 .clone()
836                 .any(|c| !c.map(|c| self.cmd.contains_short(c)).unwrap_or_default())
837         {
838             debug!("Parser::parse_short_args: contains non-short flag");
839             return Ok(ParseResult::MaybeHyphenValue);
840         } else if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt)
841                 if self.cmd[opt].is_allow_hyphen_values_set())
842         {
843             debug!("Parser::parse_short_args: prior arg accepts hyphenated values",);
844             return Ok(ParseResult::MaybeHyphenValue);
845         } else if self
846             .cmd
847             .get_keymap()
848             .get(&pos_counter)
849             .map_or(false, |arg| {
850                 arg.is_allow_hyphen_values_set() && !arg.is_last_set()
851             })
852         {
853             debug!(
854                 "Parser::parse_short_args: positional at {} allows hyphens",
855                 pos_counter
856             );
857             return Ok(ParseResult::MaybeHyphenValue);
858         }
859 
860         let mut ret = ParseResult::NoArg;
861 
862         let skip = self.flag_subcmd_skip;
863         self.flag_subcmd_skip = 0;
864         let res = short_arg.advance_by(skip);
865         debug_assert_eq!(
866             res,
867             Ok(()),
868             "tracking of `flag_subcmd_skip` is off for `{:?}`",
869             short_arg
870         );
871         while let Some(c) = short_arg.next_flag() {
872             let c = match c {
873                 Ok(c) => c,
874                 Err(rest) => {
875                     return Ok(ParseResult::NoMatchingArg {
876                         arg: format!("-{}", rest.to_str_lossy()),
877                     });
878                 }
879             };
880             debug!("Parser::parse_short_arg:iter:{}", c);
881 
882             // Check for matching short options, and return the name if there is no trailing
883             // concatenated value: -oval
884             // Option: -o
885             // Value: val
886             if let Some(arg) = self.cmd.get_keymap().get(&c) {
887                 let ident = Identifier::Short;
888                 debug!(
889                     "Parser::parse_short_arg:iter:{}: Found valid opt or flag",
890                     c
891                 );
892                 *valid_arg_found = true;
893                 if !arg.is_takes_value_set() {
894                     ret =
895                         self.react(Some(ident), ValueSource::CommandLine, arg, vec![], matcher)?;
896                     continue;
897                 }
898 
899                 // Check for trailing concatenated value
900                 //
901                 // Cloning the iterator, so we rollback if it isn't there.
902                 let val = short_arg.clone().next_value_os().unwrap_or_default();
903                 debug!(
904                     "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii), short_arg={:?}",
905                     c, val, val.as_raw_bytes(), short_arg
906                 );
907                 let val = Some(val).filter(|v| !v.is_empty());
908 
909                 // Default to "we're expecting a value later".
910                 //
911                 // If attached value is not consumed, we may have more short
912                 // flags to parse, continue.
913                 //
914                 // e.g. `-xvf`, when require_equals && x.min_vals == 0, we don't
915                 // consume the `vf`, even if it's provided as value.
916                 let (val, has_eq) = if let Some(val) = val.and_then(|v| v.strip_prefix('=')) {
917                     (Some(val), true)
918                 } else {
919                     (val, false)
920                 };
921                 match self.parse_opt_value(ident, val, arg, matcher, trailing_values, has_eq)? {
922                     ParseResult::AttachedValueNotConsumed => continue,
923                     x => return Ok(x),
924                 }
925             }
926 
927             return if let Some(sc_name) = self.cmd.find_short_subcmd(c) {
928                 debug!("Parser::parse_short_arg:iter:{}: subcommand={}", c, sc_name);
929                 // Make sure indices get updated before reading `self.cur_idx`
930                 self.resolve_pending(matcher)?;
931                 self.cur_idx.set(self.cur_idx.get() + 1);
932                 debug!("Parser::parse_short_arg: cur_idx:={}", self.cur_idx.get());
933 
934                 let name = sc_name.to_string();
935                 // Get the index of the previously saved flag subcommand in the group of flags (if exists).
936                 // If it is a new flag subcommand, then the formentioned index should be the current one
937                 // (ie. `cur_idx`), and should be registered.
938                 let cur_idx = self.cur_idx.get();
939                 self.flag_subcmd_at.get_or_insert(cur_idx);
940                 let done_short_args = short_arg.is_empty();
941                 if done_short_args {
942                     self.flag_subcmd_at = None;
943                 }
944                 Ok(ParseResult::FlagSubCommand(name))
945             } else {
946                 Ok(ParseResult::NoMatchingArg {
947                     arg: format!("-{}", c),
948                 })
949             };
950         }
951         Ok(ret)
952     }
953 
parse_opt_value( &self, ident: Identifier, attached_value: Option<&RawOsStr>, arg: &Arg<'help>, matcher: &mut ArgMatcher, trailing_values: bool, has_eq: bool, ) -> ClapResult<ParseResult>954     fn parse_opt_value(
955         &self,
956         ident: Identifier,
957         attached_value: Option<&RawOsStr>,
958         arg: &Arg<'help>,
959         matcher: &mut ArgMatcher,
960         trailing_values: bool,
961         has_eq: bool,
962     ) -> ClapResult<ParseResult> {
963         debug!(
964             "Parser::parse_opt_value; arg={}, val={:?}, has_eq={:?}",
965             arg.name, attached_value, has_eq
966         );
967         debug!("Parser::parse_opt_value; arg.settings={:?}", arg.settings);
968 
969         debug!("Parser::parse_opt_value; Checking for val...");
970         // require_equals is set, but no '=' is provided, try throwing error.
971         if arg.is_require_equals_set() && !has_eq {
972             if arg.min_vals == Some(0) {
973                 debug!("Requires equals, but min_vals == 0");
974                 let mut arg_values = Vec::new();
975                 // We assume this case is valid: require equals, but min_vals == 0.
976                 if !arg.default_missing_vals.is_empty() {
977                     debug!("Parser::parse_opt_value: has default_missing_vals");
978                     for v in arg.default_missing_vals.iter() {
979                         let trailing_values = false; // CLI should not be affecting default_missing_values
980                         let _parse_result = self.split_arg_values(
981                             arg,
982                             &RawOsStr::new(v),
983                             trailing_values,
984                             &mut arg_values,
985                         );
986                         if let Some(_parse_result) = _parse_result {
987                             if _parse_result != ParseResult::ValuesDone {
988                                 debug!("Parser::parse_opt_value: Ignoring state {:?}; no values accepted after default_missing_values", _parse_result);
989                             }
990                         }
991                     }
992                 };
993                 let react_result = self.react(
994                     Some(ident),
995                     ValueSource::CommandLine,
996                     arg,
997                     arg_values,
998                     matcher,
999                 )?;
1000                 debug_assert_eq!(react_result, ParseResult::ValuesDone);
1001                 if attached_value.is_some() {
1002                     Ok(ParseResult::AttachedValueNotConsumed)
1003                 } else {
1004                     Ok(ParseResult::ValuesDone)
1005                 }
1006             } else {
1007                 debug!("Requires equals but not provided. Error.");
1008                 Ok(ParseResult::EqualsNotProvided {
1009                     arg: arg.to_string(),
1010                 })
1011             }
1012         } else if let Some(v) = attached_value {
1013             let mut arg_values = Vec::new();
1014             let parse_result = self.split_arg_values(arg, v, trailing_values, &mut arg_values);
1015             let react_result = self.react(
1016                 Some(ident),
1017                 ValueSource::CommandLine,
1018                 arg,
1019                 arg_values,
1020                 matcher,
1021             )?;
1022             debug_assert_eq!(react_result, ParseResult::ValuesDone);
1023             let mut parse_result = parse_result.unwrap_or_else(|| {
1024                 if matcher.needs_more_vals(arg) {
1025                     ParseResult::Opt(arg.id.clone())
1026                 } else {
1027                     ParseResult::ValuesDone
1028                 }
1029             });
1030             if parse_result != ParseResult::ValuesDone {
1031                 debug!("Parser::parse_opt_value: Overriding state {:?}; no values accepted after attached", parse_result);
1032                 parse_result = ParseResult::ValuesDone;
1033             }
1034             Ok(parse_result)
1035         } else {
1036             debug!("Parser::parse_opt_value: More arg vals required...");
1037             self.resolve_pending(matcher)?;
1038             matcher.pending_values_mut(&arg.id, Some(ident));
1039             Ok(ParseResult::Opt(arg.id.clone()))
1040         }
1041     }
1042 
split_arg_values( &self, arg: &Arg<'help>, val: &RawOsStr, trailing_values: bool, output: &mut Vec<OsString>, ) -> Option<ParseResult>1043     fn split_arg_values(
1044         &self,
1045         arg: &Arg<'help>,
1046         val: &RawOsStr,
1047         trailing_values: bool,
1048         output: &mut Vec<OsString>,
1049     ) -> Option<ParseResult> {
1050         debug!("Parser::split_arg_values; arg={}, val={:?}", arg.name, val);
1051         debug!(
1052             "Parser::split_arg_values; trailing_values={:?}, DontDelimTrailingVals={:?}",
1053             trailing_values,
1054             self.cmd.is_dont_delimit_trailing_values_set()
1055         );
1056 
1057         let mut delim = arg.val_delim;
1058         if trailing_values && self.cmd.is_dont_delimit_trailing_values_set() {
1059             delim = None;
1060         }
1061         match delim {
1062             Some(delim) if val.contains(delim) => {
1063                 let vals = val.split(delim).map(|x| x.to_os_str().into_owned());
1064                 for raw_val in vals {
1065                     if Some(raw_val.as_os_str()) == arg.terminator.map(OsStr::new) {
1066                         return Some(ParseResult::ValuesDone);
1067                     }
1068                     output.push(raw_val);
1069                 }
1070                 // Delimited values are always considered the final value
1071                 Some(ParseResult::ValuesDone)
1072             }
1073             _ if Some(val) == arg.terminator.map(RawOsStr::from_str) => {
1074                 Some(ParseResult::ValuesDone)
1075             }
1076             _ => {
1077                 output.push(val.to_os_str().into_owned());
1078                 if arg.is_require_value_delimiter_set() {
1079                     Some(ParseResult::ValuesDone)
1080                 } else {
1081                     None
1082                 }
1083             }
1084         }
1085     }
1086 
push_arg_values( &self, arg: &Arg<'help>, raw_vals: Vec<OsString>, matcher: &mut ArgMatcher, ) -> ClapResult<()>1087     fn push_arg_values(
1088         &self,
1089         arg: &Arg<'help>,
1090         raw_vals: Vec<OsString>,
1091         matcher: &mut ArgMatcher,
1092     ) -> ClapResult<()> {
1093         debug!("Parser::push_arg_values: {:?}", raw_vals);
1094 
1095         for raw_val in raw_vals {
1096             // update the current index because each value is a distinct index to clap
1097             self.cur_idx.set(self.cur_idx.get() + 1);
1098             debug!(
1099                 "Parser::add_single_val_to_arg: cur_idx:={}",
1100                 self.cur_idx.get()
1101             );
1102             let value_parser = arg.get_value_parser();
1103             let val = value_parser.parse_ref(self.cmd, Some(arg), &raw_val)?;
1104 
1105             // Increment or create the group "args"
1106             for group in self.cmd.groups_for_arg(&arg.id) {
1107                 matcher.add_val_to(&group, val.clone(), raw_val.clone());
1108             }
1109 
1110             matcher.add_val_to(&arg.id, val, raw_val);
1111             matcher.add_index_to(&arg.id, self.cur_idx.get());
1112         }
1113 
1114         Ok(())
1115     }
1116 
resolve_pending(&self, matcher: &mut ArgMatcher) -> ClapResult<()>1117     fn resolve_pending(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1118         let pending = match matcher.take_pending() {
1119             Some(pending) => pending,
1120             None => {
1121                 return Ok(());
1122             }
1123         };
1124 
1125         debug!("Parser::resolve_pending: id={:?}", pending.id);
1126         let arg = self.cmd.find(&pending.id).expect(INTERNAL_ERROR_MSG);
1127         let _ = self.react(
1128             pending.ident,
1129             ValueSource::CommandLine,
1130             arg,
1131             pending.raw_vals,
1132             matcher,
1133         )?;
1134 
1135         Ok(())
1136     }
1137 
react( &self, ident: Option<Identifier>, source: ValueSource, arg: &Arg<'help>, raw_vals: Vec<OsString>, matcher: &mut ArgMatcher, ) -> ClapResult<ParseResult>1138     fn react(
1139         &self,
1140         ident: Option<Identifier>,
1141         source: ValueSource,
1142         arg: &Arg<'help>,
1143         raw_vals: Vec<OsString>,
1144         matcher: &mut ArgMatcher,
1145     ) -> ClapResult<ParseResult> {
1146         self.resolve_pending(matcher)?;
1147 
1148         debug!(
1149             "Parser::react action={:?}, identifier={:?}, source={:?}",
1150             arg.get_action(),
1151             ident,
1152             source
1153         );
1154         match arg.get_action() {
1155             ArgAction::Set => {
1156                 if source == ValueSource::CommandLine
1157                     && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
1158                 {
1159                     // Record flag's index
1160                     self.cur_idx.set(self.cur_idx.get() + 1);
1161                     debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
1162                 }
1163                 matcher.remove(&arg.id);
1164                 self.start_custom_arg(matcher, arg, source);
1165                 self.push_arg_values(arg, raw_vals, matcher)?;
1166                 if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
1167                     debug!(
1168                         "Parser::react not enough values passed in, leaving it to the validator to complain",
1169                     );
1170                 }
1171                 Ok(ParseResult::ValuesDone)
1172             }
1173             ArgAction::Append => {
1174                 if source == ValueSource::CommandLine
1175                     && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
1176                 {
1177                     // Record flag's index
1178                     self.cur_idx.set(self.cur_idx.get() + 1);
1179                     debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
1180                 }
1181                 self.start_custom_arg(matcher, arg, source);
1182                 self.push_arg_values(arg, raw_vals, matcher)?;
1183                 if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
1184                     debug!(
1185                         "Parser::react not enough values passed in, leaving it to the validator to complain",
1186                     );
1187                 }
1188                 Ok(ParseResult::ValuesDone)
1189             }
1190             #[allow(deprecated)]
1191             ArgAction::StoreValue => {
1192                 if ident == Some(Identifier::Index)
1193                     && arg.is_multiple_values_set()
1194                     && matcher.contains(&arg.id)
1195                 {
1196                     // HACK: Reuse existing occurrence
1197                 } else if source == ValueSource::CommandLine {
1198                     if matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) {
1199                         // Record flag's index
1200                         self.cur_idx.set(self.cur_idx.get() + 1);
1201                         debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
1202                     }
1203                     self.start_occurrence_of_arg(matcher, arg);
1204                 } else {
1205                     self.start_custom_arg(matcher, arg, source);
1206                 }
1207                 self.push_arg_values(arg, raw_vals, matcher)?;
1208                 if ident == Some(Identifier::Index) && arg.is_multiple_values_set() {
1209                     // HACK: Maintain existing occurrence behavior
1210                     let matched = matcher.get_mut(&arg.id).unwrap();
1211                     #[allow(deprecated)]
1212                     matched.set_occurrences(matched.num_vals() as u64);
1213                 }
1214                 if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
1215                     debug!(
1216                         "Parser::react not enough values passed in, leaving it to the validator to complain",
1217                     );
1218                 }
1219                 Ok(ParseResult::ValuesDone)
1220             }
1221             #[allow(deprecated)]
1222             ArgAction::IncOccurrence => {
1223                 debug_assert_eq!(raw_vals, Vec::<OsString>::new());
1224                 if source == ValueSource::CommandLine {
1225                     if matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) {
1226                         // Record flag's index
1227                         self.cur_idx.set(self.cur_idx.get() + 1);
1228                         debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
1229                     }
1230                     self.start_occurrence_of_arg(matcher, arg);
1231                 } else {
1232                     self.start_custom_arg(matcher, arg, source);
1233                 }
1234                 matcher.add_index_to(&arg.id, self.cur_idx.get());
1235                 Ok(ParseResult::ValuesDone)
1236             }
1237             ArgAction::SetTrue => {
1238                 let raw_vals = match raw_vals.len() {
1239                     0 => {
1240                         vec![OsString::from("true")]
1241                     }
1242                     1 => raw_vals,
1243                     _ => {
1244                         debug!("Parser::react ignoring trailing values: {:?}", raw_vals);
1245                         let mut raw_vals = raw_vals;
1246                         raw_vals.resize(1, Default::default());
1247                         raw_vals
1248                     }
1249                 };
1250 
1251                 matcher.remove(&arg.id);
1252                 self.start_custom_arg(matcher, arg, source);
1253                 self.push_arg_values(arg, raw_vals, matcher)?;
1254                 Ok(ParseResult::ValuesDone)
1255             }
1256             ArgAction::SetFalse => {
1257                 let raw_vals = match raw_vals.len() {
1258                     0 => {
1259                         vec![OsString::from("false")]
1260                     }
1261                     1 => raw_vals,
1262                     _ => {
1263                         debug!("Parser::react ignoring trailing values: {:?}", raw_vals);
1264                         let mut raw_vals = raw_vals;
1265                         raw_vals.resize(1, Default::default());
1266                         raw_vals
1267                     }
1268                 };
1269 
1270                 matcher.remove(&arg.id);
1271                 self.start_custom_arg(matcher, arg, source);
1272                 self.push_arg_values(arg, raw_vals, matcher)?;
1273                 Ok(ParseResult::ValuesDone)
1274             }
1275             ArgAction::Count => {
1276                 let raw_vals = match raw_vals.len() {
1277                     0 => {
1278                         let existing_value = *matcher
1279                             .get_one::<crate::builder::CountType>(arg.get_id())
1280                             .unwrap_or(&0);
1281                         let next_value = existing_value.saturating_add(1);
1282                         vec![OsString::from(next_value.to_string())]
1283                     }
1284                     1 => raw_vals,
1285                     _ => {
1286                         debug!("Parser::react ignoring trailing values: {:?}", raw_vals);
1287                         let mut raw_vals = raw_vals;
1288                         raw_vals.resize(1, Default::default());
1289                         raw_vals
1290                     }
1291                 };
1292 
1293                 matcher.remove(&arg.id);
1294                 self.start_custom_arg(matcher, arg, source);
1295                 self.push_arg_values(arg, raw_vals, matcher)?;
1296                 Ok(ParseResult::ValuesDone)
1297             }
1298             ArgAction::Help => {
1299                 debug_assert_eq!(raw_vals, Vec::<OsString>::new());
1300                 let use_long = match ident {
1301                     Some(Identifier::Long) => true,
1302                     Some(Identifier::Short) => false,
1303                     Some(Identifier::Index) => true,
1304                     None => true,
1305                 };
1306                 debug!("Help: use_long={}", use_long);
1307                 Err(self.help_err(use_long, Stream::Stdout))
1308             }
1309             ArgAction::Version => {
1310                 debug_assert_eq!(raw_vals, Vec::<OsString>::new());
1311                 let use_long = match ident {
1312                     Some(Identifier::Long) => true,
1313                     Some(Identifier::Short) => false,
1314                     Some(Identifier::Index) => true,
1315                     None => true,
1316                 };
1317                 debug!("Version: use_long={}", use_long);
1318                 Err(self.version_err(use_long))
1319             }
1320         }
1321     }
1322 
remove_overrides(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher)1323     fn remove_overrides(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher) {
1324         debug!("Parser::remove_overrides: id={:?}", arg.id);
1325         for override_id in &arg.overrides {
1326             debug!("Parser::remove_overrides:iter:{:?}: removing", override_id);
1327             matcher.remove(override_id);
1328         }
1329 
1330         // Override anything that can override us
1331         let mut transitive = Vec::new();
1332         for arg_id in matcher.arg_ids() {
1333             if let Some(overrider) = self.cmd.find(arg_id) {
1334                 if overrider.overrides.contains(&arg.id) {
1335                     transitive.push(&overrider.id);
1336                 }
1337             }
1338         }
1339         for overrider_id in transitive {
1340             debug!("Parser::remove_overrides:iter:{:?}: removing", overrider_id);
1341             matcher.remove(overrider_id);
1342         }
1343     }
1344 
1345     #[cfg(feature = "env")]
add_env(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()>1346     fn add_env(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1347         debug!("Parser::add_env");
1348         use crate::util::str_to_bool;
1349 
1350         let trailing_values = false; // defaults are independent of the commandline
1351         for arg in self.cmd.get_arguments() {
1352             // Use env only if the arg was absent among command line args,
1353             // early return if this is not the case.
1354             if matcher.contains(&arg.id) {
1355                 debug!("Parser::add_env: Skipping existing arg `{}`", arg);
1356                 continue;
1357             }
1358 
1359             debug!("Parser::add_env: Checking arg `{}`", arg);
1360             if let Some((_, Some(ref val))) = arg.env {
1361                 let val = RawOsStr::new(val);
1362 
1363                 if arg.is_takes_value_set() {
1364                     debug!(
1365                         "Parser::add_env: Found an opt with value={:?}, trailing={:?}",
1366                         val, trailing_values
1367                     );
1368                     let mut arg_values = Vec::new();
1369                     let _parse_result =
1370                         self.split_arg_values(arg, &val, trailing_values, &mut arg_values);
1371                     let _ = self.react(None, ValueSource::EnvVariable, arg, arg_values, matcher)?;
1372                     if let Some(_parse_result) = _parse_result {
1373                         if _parse_result != ParseResult::ValuesDone {
1374                             debug!("Parser::add_env: Ignoring state {:?}; env variables are outside of the parse loop", _parse_result);
1375                         }
1376                     }
1377                 } else {
1378                     match arg.get_action() {
1379                         #[allow(deprecated)]
1380                         ArgAction::StoreValue => unreachable!("{:?} is not a flag", arg.get_id()),
1381                         #[allow(deprecated)]
1382                         ArgAction::IncOccurrence => {
1383                             debug!("Parser::add_env: Found a flag with value `{:?}`", val);
1384                             let predicate = str_to_bool(val.to_str_lossy());
1385                             debug!("Parser::add_env: Found boolean literal `{:?}`", predicate);
1386                             if predicate.unwrap_or(true) {
1387                                 let _ = self.react(
1388                                     None,
1389                                     ValueSource::EnvVariable,
1390                                     arg,
1391                                     vec![],
1392                                     matcher,
1393                                 )?;
1394                             }
1395                         }
1396                         ArgAction::Set
1397                         | ArgAction::Append
1398                         | ArgAction::SetTrue
1399                         | ArgAction::SetFalse
1400                         | ArgAction::Count => {
1401                             let mut arg_values = Vec::new();
1402                             let _parse_result =
1403                                 self.split_arg_values(arg, &val, trailing_values, &mut arg_values);
1404                             let _ = self.react(
1405                                 None,
1406                                 ValueSource::EnvVariable,
1407                                 arg,
1408                                 arg_values,
1409                                 matcher,
1410                             )?;
1411                             if let Some(_parse_result) = _parse_result {
1412                                 if _parse_result != ParseResult::ValuesDone {
1413                                     debug!("Parser::add_env: Ignoring state {:?}; env variables are outside of the parse loop", _parse_result);
1414                                 }
1415                             }
1416                         }
1417                         // Early return on `Help` or `Version`.
1418                         ArgAction::Help | ArgAction::Version => {
1419                             let _ =
1420                                 self.react(None, ValueSource::EnvVariable, arg, vec![], matcher)?;
1421                         }
1422                     }
1423                 }
1424             }
1425         }
1426 
1427         Ok(())
1428     }
1429 
add_defaults(&self, matcher: &mut ArgMatcher) -> ClapResult<()>1430     fn add_defaults(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1431         debug!("Parser::add_defaults");
1432 
1433         for arg in self.cmd.get_arguments() {
1434             debug!("Parser::add_defaults:iter:{}:", arg.name);
1435             self.add_default_value(arg, matcher)?;
1436         }
1437 
1438         Ok(())
1439     }
1440 
add_default_value(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher) -> ClapResult<()>1441     fn add_default_value(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher) -> ClapResult<()> {
1442         let trailing_values = false; // defaults are independent of the commandline
1443 
1444         if !arg.default_missing_vals.is_empty() {
1445             debug!(
1446                 "Parser::add_default_value:iter:{}: has default missing vals",
1447                 arg.name
1448             );
1449             match matcher.get(&arg.id) {
1450                 Some(ma) if ma.all_val_groups_empty() => {
1451                     debug!(
1452                         "Parser::add_default_value:iter:{}: has no user defined vals",
1453                         arg.name
1454                     );
1455                     // The flag occurred, we just want to add the val groups
1456                     let mut arg_values = Vec::new();
1457                     for v in arg.default_missing_vals.iter() {
1458                         let _parse_result = self.split_arg_values(
1459                             arg,
1460                             &RawOsStr::new(v),
1461                             trailing_values,
1462                             &mut arg_values,
1463                         );
1464                         if let Some(_parse_result) = _parse_result {
1465                             if _parse_result != ParseResult::ValuesDone {
1466                                 debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result);
1467                             }
1468                         }
1469                     }
1470                     self.start_custom_arg(matcher, arg, ValueSource::CommandLine);
1471                     self.push_arg_values(arg, arg_values, matcher)?;
1472                 }
1473                 None => {
1474                     debug!("Parser::add_default_value:iter:{}: wasn't used", arg.name);
1475                     // do nothing
1476                 }
1477                 _ => {
1478                     debug!(
1479                         "Parser::add_default_value:iter:{}: has user defined vals",
1480                         arg.name
1481                     );
1482                     // do nothing
1483                 }
1484             }
1485         } else {
1486             debug!(
1487                 "Parser::add_default_value:iter:{}: doesn't have default missing vals",
1488                 arg.name
1489             );
1490             // do nothing
1491         }
1492 
1493         if !arg.default_vals_ifs.is_empty() {
1494             debug!("Parser::add_default_value: has conditional defaults");
1495             if !matcher.contains(&arg.id) {
1496                 for (id, val, default) in arg.default_vals_ifs.iter() {
1497                     let add = if let Some(a) = matcher.get(id) {
1498                         match val {
1499                             crate::builder::ArgPredicate::Equals(v) => {
1500                                 a.raw_vals_flatten().any(|value| v == value)
1501                             }
1502                             crate::builder::ArgPredicate::IsPresent => true,
1503                         }
1504                     } else {
1505                         false
1506                     };
1507 
1508                     if add {
1509                         if let Some(default) = default {
1510                             let mut arg_values = Vec::new();
1511                             let _parse_result = self.split_arg_values(
1512                                 arg,
1513                                 &RawOsStr::new(default),
1514                                 trailing_values,
1515                                 &mut arg_values,
1516                             );
1517                             let _ = self.react(
1518                                 None,
1519                                 ValueSource::DefaultValue,
1520                                 arg,
1521                                 arg_values,
1522                                 matcher,
1523                             )?;
1524                             if let Some(_parse_result) = _parse_result {
1525                                 if _parse_result != ParseResult::ValuesDone {
1526                                     debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result);
1527                                 }
1528                             }
1529                         }
1530                         return Ok(());
1531                     }
1532                 }
1533             }
1534         } else {
1535             debug!("Parser::add_default_value: doesn't have conditional defaults");
1536         }
1537 
1538         if !arg.default_vals.is_empty() {
1539             debug!(
1540                 "Parser::add_default_value:iter:{}: has default vals",
1541                 arg.name
1542             );
1543             if matcher.contains(&arg.id) {
1544                 debug!("Parser::add_default_value:iter:{}: was used", arg.name);
1545             // do nothing
1546             } else {
1547                 debug!("Parser::add_default_value:iter:{}: wasn't used", arg.name);
1548                 let mut arg_values = Vec::new();
1549                 for v in arg.default_vals.iter() {
1550                     let _parse_result = self.split_arg_values(
1551                         arg,
1552                         &RawOsStr::new(v),
1553                         trailing_values,
1554                         &mut arg_values,
1555                     );
1556                     if let Some(_parse_result) = _parse_result {
1557                         if _parse_result != ParseResult::ValuesDone {
1558                             debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result);
1559                         }
1560                     }
1561                 }
1562                 let _ = self.react(None, ValueSource::DefaultValue, arg, arg_values, matcher)?;
1563             }
1564         } else {
1565             debug!(
1566                 "Parser::add_default_value:iter:{}: doesn't have default vals",
1567                 arg.name
1568             );
1569 
1570             // do nothing
1571         }
1572 
1573         Ok(())
1574     }
1575 
start_custom_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>, source: ValueSource)1576     fn start_custom_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>, source: ValueSource) {
1577         if source == ValueSource::CommandLine {
1578             // With each new occurrence, remove overrides from prior occurrences
1579             self.remove_overrides(arg, matcher);
1580         }
1581         matcher.start_custom_arg(arg, source);
1582         for group in self.cmd.groups_for_arg(&arg.id) {
1583             matcher.start_custom_group(&group, source);
1584         }
1585     }
1586 
1587     /// Increase occurrence of specific argument and the grouped arg it's in.
start_occurrence_of_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>)1588     fn start_occurrence_of_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>) {
1589         // With each new occurrence, remove overrides from prior occurrences
1590         self.remove_overrides(arg, matcher);
1591 
1592         matcher.start_occurrence_of_arg(arg);
1593         // Increment or create the group "args"
1594         for group in self.cmd.groups_for_arg(&arg.id) {
1595             matcher.start_occurrence_of_group(&group);
1596         }
1597     }
1598 }
1599 
1600 // Error, Help, and Version Methods
1601 impl<'help, 'cmd> Parser<'help, 'cmd> {
1602     /// 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], ) -> ClapError1603     fn did_you_mean_error(
1604         &mut self,
1605         arg: &str,
1606         matcher: &mut ArgMatcher,
1607         remaining_args: &[&str],
1608     ) -> ClapError {
1609         debug!("Parser::did_you_mean_error: arg={}", arg);
1610         // Didn't match a flag or option
1611         let longs = self
1612             .cmd
1613             .get_keymap()
1614             .keys()
1615             .filter_map(|x| match x {
1616                 KeyType::Long(l) => Some(l.to_string_lossy().into_owned()),
1617                 _ => None,
1618             })
1619             .collect::<Vec<_>>();
1620         debug!("Parser::did_you_mean_error: longs={:?}", longs);
1621 
1622         let did_you_mean = suggestions::did_you_mean_flag(
1623             arg,
1624             remaining_args,
1625             longs.iter().map(|x| &x[..]),
1626             self.cmd.get_subcommands_mut(),
1627         );
1628 
1629         // Add the arg to the matches to build a proper usage string
1630         if let Some((name, _)) = did_you_mean.as_ref() {
1631             if let Some(arg) = self.cmd.get_keymap().get(&name.as_ref()) {
1632                 self.start_occurrence_of_arg(matcher, arg);
1633             }
1634         }
1635 
1636         let required = self.cmd.required_graph();
1637         let used: Vec<Id> = matcher
1638             .arg_ids()
1639             .filter(|arg_id| {
1640                 matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent)
1641             })
1642             .filter(|n| self.cmd.find(n).map_or(true, |a| !a.is_hide_set()))
1643             .cloned()
1644             .collect();
1645 
1646         ClapError::unknown_argument(
1647             self.cmd,
1648             format!("--{}", arg),
1649             did_you_mean,
1650             Usage::new(self.cmd)
1651                 .required(&required)
1652                 .create_usage_with_title(&*used),
1653         )
1654     }
1655 
help_err(&self, use_long: bool, stream: Stream) -> ClapError1656     fn help_err(&self, use_long: bool, stream: Stream) -> ClapError {
1657         match self.cmd.write_help_err(use_long, stream) {
1658             Ok(c) => ClapError::display_help(self.cmd, c),
1659             Err(e) => e,
1660         }
1661     }
1662 
version_err(&self, use_long: bool) -> ClapError1663     fn version_err(&self, use_long: bool) -> ClapError {
1664         debug!("Parser::version_err");
1665 
1666         let msg = self.cmd._render_version(use_long);
1667         let mut c = Colorizer::new(Stream::Stdout, self.cmd.color_help());
1668         c.none(msg);
1669         ClapError::display_version(self.cmd, c)
1670     }
1671 }
1672 
1673 // Query Methods
1674 impl<'help, 'cmd> Parser<'help, 'cmd> {
is_set(&self, s: AS) -> bool1675     pub(crate) fn is_set(&self, s: AS) -> bool {
1676         self.cmd.is_set(s)
1677     }
1678 }
1679 
1680 #[derive(Debug, PartialEq, Eq)]
1681 pub(crate) enum ParseState {
1682     ValuesDone,
1683     Opt(Id),
1684     Pos(Id),
1685 }
1686 
1687 /// Recoverable Parsing results.
1688 #[derive(Debug, PartialEq, Clone)]
1689 #[must_use]
1690 enum ParseResult {
1691     FlagSubCommand(String),
1692     Opt(Id),
1693     ValuesDone,
1694     /// Value attached to the short flag is not consumed(e.g. 'u' for `-cu` is
1695     /// not consumed).
1696     AttachedValueNotConsumed,
1697     /// This long flag doesn't need a value but is provided one.
1698     UnneededAttachedValue {
1699         rest: String,
1700         used: Vec<Id>,
1701         arg: String,
1702     },
1703     /// This flag might be an hyphen Value.
1704     MaybeHyphenValue,
1705     /// Equals required but not provided.
1706     EqualsNotProvided {
1707         arg: String,
1708     },
1709     /// Failed to match a Arg.
1710     NoMatchingArg {
1711         arg: String,
1712     },
1713     /// No argument found e.g. parser is given `-` when parsing a flag.
1714     NoArg,
1715 }
1716 
1717 #[derive(Clone, Debug, PartialEq, Eq)]
1718 pub(crate) struct PendingArg {
1719     pub(crate) id: Id,
1720     pub(crate) ident: Option<Identifier>,
1721     pub(crate) raw_vals: Vec<OsString>,
1722 }
1723 
1724 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1725 pub(crate) enum Identifier {
1726     Short,
1727     Long,
1728     Index,
1729 }
1730