119625d8cSopenharmony_ci// Std
219625d8cSopenharmony_ciuse std::{
319625d8cSopenharmony_ci    cell::Cell,
419625d8cSopenharmony_ci    ffi::{OsStr, OsString},
519625d8cSopenharmony_ci};
619625d8cSopenharmony_ci
719625d8cSopenharmony_ci// Third Party
819625d8cSopenharmony_ciuse clap_lex::RawOsStr;
919625d8cSopenharmony_ciuse clap_lex::RawOsString;
1019625d8cSopenharmony_ci
1119625d8cSopenharmony_ci// Internal
1219625d8cSopenharmony_ciuse crate::builder::{Arg, Command};
1319625d8cSopenharmony_ciuse crate::error::Error as ClapError;
1419625d8cSopenharmony_ciuse crate::error::Result as ClapResult;
1519625d8cSopenharmony_ciuse crate::mkeymap::KeyType;
1619625d8cSopenharmony_ciuse crate::output::Usage;
1719625d8cSopenharmony_ciuse crate::parser::features::suggestions;
1819625d8cSopenharmony_ciuse crate::parser::AnyValue;
1919625d8cSopenharmony_ciuse crate::parser::{ArgMatcher, SubCommand};
2019625d8cSopenharmony_ciuse crate::parser::{Validator, ValueSource};
2119625d8cSopenharmony_ciuse crate::util::Id;
2219625d8cSopenharmony_ciuse crate::ArgAction;
2319625d8cSopenharmony_ciuse crate::INTERNAL_ERROR_MSG;
2419625d8cSopenharmony_ci
2519625d8cSopenharmony_cipub(crate) struct Parser<'cmd> {
2619625d8cSopenharmony_ci    cmd: &'cmd mut Command,
2719625d8cSopenharmony_ci    cur_idx: Cell<usize>,
2819625d8cSopenharmony_ci    /// Index of the previous flag subcommand in a group of flags.
2919625d8cSopenharmony_ci    flag_subcmd_at: Option<usize>,
3019625d8cSopenharmony_ci    /// Counter indicating the number of items to skip
3119625d8cSopenharmony_ci    /// when revisiting the group of flags which includes the flag subcommand.
3219625d8cSopenharmony_ci    flag_subcmd_skip: usize,
3319625d8cSopenharmony_ci}
3419625d8cSopenharmony_ci
3519625d8cSopenharmony_ci// Initializing Methods
3619625d8cSopenharmony_ciimpl<'cmd> Parser<'cmd> {
3719625d8cSopenharmony_ci    pub(crate) fn new(cmd: &'cmd mut Command) -> Self {
3819625d8cSopenharmony_ci        Parser {
3919625d8cSopenharmony_ci            cmd,
4019625d8cSopenharmony_ci            cur_idx: Cell::new(0),
4119625d8cSopenharmony_ci            flag_subcmd_at: None,
4219625d8cSopenharmony_ci            flag_subcmd_skip: 0,
4319625d8cSopenharmony_ci        }
4419625d8cSopenharmony_ci    }
4519625d8cSopenharmony_ci}
4619625d8cSopenharmony_ci
4719625d8cSopenharmony_ci// Parsing Methods
4819625d8cSopenharmony_ciimpl<'cmd> Parser<'cmd> {
4919625d8cSopenharmony_ci    // The actual parsing function
5019625d8cSopenharmony_ci    #[allow(clippy::cognitive_complexity)]
5119625d8cSopenharmony_ci    pub(crate) fn get_matches_with(
5219625d8cSopenharmony_ci        &mut self,
5319625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
5419625d8cSopenharmony_ci        raw_args: &mut clap_lex::RawArgs,
5519625d8cSopenharmony_ci        mut args_cursor: clap_lex::ArgCursor,
5619625d8cSopenharmony_ci    ) -> ClapResult<()> {
5719625d8cSopenharmony_ci        debug!("Parser::get_matches_with");
5819625d8cSopenharmony_ci        // Verify all positional assertions pass
5919625d8cSopenharmony_ci
6019625d8cSopenharmony_ci        let mut subcmd_name: Option<String> = None;
6119625d8cSopenharmony_ci        let mut keep_state = false;
6219625d8cSopenharmony_ci        let mut parse_state = ParseState::ValuesDone;
6319625d8cSopenharmony_ci        let mut pos_counter = 1;
6419625d8cSopenharmony_ci
6519625d8cSopenharmony_ci        // Already met any valid arg(then we shouldn't expect subcommands after it).
6619625d8cSopenharmony_ci        let mut valid_arg_found = false;
6719625d8cSopenharmony_ci        // If the user already passed '--'. Meaning only positional args follow.
6819625d8cSopenharmony_ci        let mut trailing_values = false;
6919625d8cSopenharmony_ci
7019625d8cSopenharmony_ci        // Count of positional args
7119625d8cSopenharmony_ci        let positional_count = self
7219625d8cSopenharmony_ci            .cmd
7319625d8cSopenharmony_ci            .get_keymap()
7419625d8cSopenharmony_ci            .keys()
7519625d8cSopenharmony_ci            .filter(|x| x.is_position())
7619625d8cSopenharmony_ci            .count();
7719625d8cSopenharmony_ci        // If any arg sets .last(true)
7819625d8cSopenharmony_ci        let contains_last = self.cmd.get_arguments().any(|x| x.is_last_set());
7919625d8cSopenharmony_ci
8019625d8cSopenharmony_ci        while let Some(arg_os) = raw_args.next(&mut args_cursor) {
8119625d8cSopenharmony_ci            // Recover the replaced items if any.
8219625d8cSopenharmony_ci            if let Some(replaced_items) = arg_os
8319625d8cSopenharmony_ci                .to_value()
8419625d8cSopenharmony_ci                .ok()
8519625d8cSopenharmony_ci                .and_then(|a| self.cmd.get_replacement(a))
8619625d8cSopenharmony_ci            {
8719625d8cSopenharmony_ci                debug!(
8819625d8cSopenharmony_ci                    "Parser::get_matches_with: found replacer: {:?}, target: {:?}",
8919625d8cSopenharmony_ci                    arg_os, replaced_items
9019625d8cSopenharmony_ci                );
9119625d8cSopenharmony_ci                raw_args.insert(&args_cursor, replaced_items);
9219625d8cSopenharmony_ci                continue;
9319625d8cSopenharmony_ci            }
9419625d8cSopenharmony_ci
9519625d8cSopenharmony_ci            debug!(
9619625d8cSopenharmony_ci                "Parser::get_matches_with: Begin parsing '{:?}' ({:?})",
9719625d8cSopenharmony_ci                arg_os.to_value_os(),
9819625d8cSopenharmony_ci                arg_os.to_value_os().as_raw_bytes()
9919625d8cSopenharmony_ci            );
10019625d8cSopenharmony_ci
10119625d8cSopenharmony_ci            // Has the user already passed '--'? Meaning only positional args follow
10219625d8cSopenharmony_ci            if !trailing_values {
10319625d8cSopenharmony_ci                if self.cmd.is_subcommand_precedence_over_arg_set()
10419625d8cSopenharmony_ci                    || !matches!(parse_state, ParseState::Opt(_) | ParseState::Pos(_))
10519625d8cSopenharmony_ci                {
10619625d8cSopenharmony_ci                    // Does the arg match a subcommand name, or any of its aliases (if defined)
10719625d8cSopenharmony_ci                    let sc_name = self.possible_subcommand(arg_os.to_value(), valid_arg_found);
10819625d8cSopenharmony_ci                    debug!("Parser::get_matches_with: sc={:?}", sc_name);
10919625d8cSopenharmony_ci                    if let Some(sc_name) = sc_name {
11019625d8cSopenharmony_ci                        if sc_name == "help" && !self.cmd.is_disable_help_subcommand_set() {
11119625d8cSopenharmony_ci                            ok!(self.parse_help_subcommand(raw_args.remaining(&mut args_cursor)));
11219625d8cSopenharmony_ci                            unreachable!("`parse_help_subcommand` always errors");
11319625d8cSopenharmony_ci                        } else {
11419625d8cSopenharmony_ci                            subcmd_name = Some(sc_name.to_owned());
11519625d8cSopenharmony_ci                        }
11619625d8cSopenharmony_ci                        break;
11719625d8cSopenharmony_ci                    }
11819625d8cSopenharmony_ci                }
11919625d8cSopenharmony_ci
12019625d8cSopenharmony_ci                if arg_os.is_escape() {
12119625d8cSopenharmony_ci                    if matches!(&parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
12219625d8cSopenharmony_ci                        self.cmd[opt].is_allow_hyphen_values_set())
12319625d8cSopenharmony_ci                    {
12419625d8cSopenharmony_ci                        // ParseResult::MaybeHyphenValue, do nothing
12519625d8cSopenharmony_ci                    } else {
12619625d8cSopenharmony_ci                        debug!("Parser::get_matches_with: setting TrailingVals=true");
12719625d8cSopenharmony_ci                        trailing_values = true;
12819625d8cSopenharmony_ci                        matcher.start_trailing();
12919625d8cSopenharmony_ci                        continue;
13019625d8cSopenharmony_ci                    }
13119625d8cSopenharmony_ci                } else if let Some((long_arg, long_value)) = arg_os.to_long() {
13219625d8cSopenharmony_ci                    let parse_result = ok!(self.parse_long_arg(
13319625d8cSopenharmony_ci                        matcher,
13419625d8cSopenharmony_ci                        long_arg,
13519625d8cSopenharmony_ci                        long_value,
13619625d8cSopenharmony_ci                        &parse_state,
13719625d8cSopenharmony_ci                        pos_counter,
13819625d8cSopenharmony_ci                        &mut valid_arg_found,
13919625d8cSopenharmony_ci                    ));
14019625d8cSopenharmony_ci                    debug!(
14119625d8cSopenharmony_ci                        "Parser::get_matches_with: After parse_long_arg {:?}",
14219625d8cSopenharmony_ci                        parse_result
14319625d8cSopenharmony_ci                    );
14419625d8cSopenharmony_ci                    match parse_result {
14519625d8cSopenharmony_ci                        ParseResult::NoArg => {
14619625d8cSopenharmony_ci                            unreachable!("`to_long` always has the flag specified")
14719625d8cSopenharmony_ci                        }
14819625d8cSopenharmony_ci                        ParseResult::ValuesDone => {
14919625d8cSopenharmony_ci                            parse_state = ParseState::ValuesDone;
15019625d8cSopenharmony_ci                            continue;
15119625d8cSopenharmony_ci                        }
15219625d8cSopenharmony_ci                        ParseResult::Opt(id) => {
15319625d8cSopenharmony_ci                            parse_state = ParseState::Opt(id);
15419625d8cSopenharmony_ci                            continue;
15519625d8cSopenharmony_ci                        }
15619625d8cSopenharmony_ci                        ParseResult::FlagSubCommand(name) => {
15719625d8cSopenharmony_ci                            debug!(
15819625d8cSopenharmony_ci                                "Parser::get_matches_with: FlagSubCommand found in long arg {:?}",
15919625d8cSopenharmony_ci                                &name
16019625d8cSopenharmony_ci                            );
16119625d8cSopenharmony_ci                            subcmd_name = Some(name);
16219625d8cSopenharmony_ci                            break;
16319625d8cSopenharmony_ci                        }
16419625d8cSopenharmony_ci                        ParseResult::EqualsNotProvided { arg } => {
16519625d8cSopenharmony_ci                            let _ = self.resolve_pending(matcher);
16619625d8cSopenharmony_ci                            return Err(ClapError::no_equals(
16719625d8cSopenharmony_ci                                self.cmd,
16819625d8cSopenharmony_ci                                arg,
16919625d8cSopenharmony_ci                                Usage::new(self.cmd).create_usage_with_title(&[]),
17019625d8cSopenharmony_ci                            ));
17119625d8cSopenharmony_ci                        }
17219625d8cSopenharmony_ci                        ParseResult::NoMatchingArg { arg } => {
17319625d8cSopenharmony_ci                            let _ = self.resolve_pending(matcher);
17419625d8cSopenharmony_ci                            let remaining_args: Vec<_> =
17519625d8cSopenharmony_ci                                raw_args.remaining(&mut args_cursor).collect();
17619625d8cSopenharmony_ci                            return Err(self.did_you_mean_error(
17719625d8cSopenharmony_ci                                &arg,
17819625d8cSopenharmony_ci                                matcher,
17919625d8cSopenharmony_ci                                &remaining_args,
18019625d8cSopenharmony_ci                                trailing_values,
18119625d8cSopenharmony_ci                            ));
18219625d8cSopenharmony_ci                        }
18319625d8cSopenharmony_ci                        ParseResult::UnneededAttachedValue { rest, used, arg } => {
18419625d8cSopenharmony_ci                            let _ = self.resolve_pending(matcher);
18519625d8cSopenharmony_ci                            return Err(ClapError::too_many_values(
18619625d8cSopenharmony_ci                                self.cmd,
18719625d8cSopenharmony_ci                                rest,
18819625d8cSopenharmony_ci                                arg,
18919625d8cSopenharmony_ci                                Usage::new(self.cmd).create_usage_with_title(&used),
19019625d8cSopenharmony_ci                            ));
19119625d8cSopenharmony_ci                        }
19219625d8cSopenharmony_ci                        ParseResult::MaybeHyphenValue => {
19319625d8cSopenharmony_ci                            // Maybe a hyphen value, do nothing.
19419625d8cSopenharmony_ci                        }
19519625d8cSopenharmony_ci                        ParseResult::AttachedValueNotConsumed => {
19619625d8cSopenharmony_ci                            unreachable!()
19719625d8cSopenharmony_ci                        }
19819625d8cSopenharmony_ci                    }
19919625d8cSopenharmony_ci                } else if let Some(short_arg) = arg_os.to_short() {
20019625d8cSopenharmony_ci                    // Arg looks like a short flag, and not a possible number
20119625d8cSopenharmony_ci
20219625d8cSopenharmony_ci                    // Try to parse short args like normal, if allow_hyphen_values or
20319625d8cSopenharmony_ci                    // AllowNegativeNumbers is set, parse_short_arg will *not* throw
20419625d8cSopenharmony_ci                    // an error, and instead return Ok(None)
20519625d8cSopenharmony_ci                    let parse_result = ok!(self.parse_short_arg(
20619625d8cSopenharmony_ci                        matcher,
20719625d8cSopenharmony_ci                        short_arg,
20819625d8cSopenharmony_ci                        &parse_state,
20919625d8cSopenharmony_ci                        pos_counter,
21019625d8cSopenharmony_ci                        &mut valid_arg_found,
21119625d8cSopenharmony_ci                    ));
21219625d8cSopenharmony_ci                    // If it's None, we then check if one of those two AppSettings was set
21319625d8cSopenharmony_ci                    debug!(
21419625d8cSopenharmony_ci                        "Parser::get_matches_with: After parse_short_arg {:?}",
21519625d8cSopenharmony_ci                        parse_result
21619625d8cSopenharmony_ci                    );
21719625d8cSopenharmony_ci                    match parse_result {
21819625d8cSopenharmony_ci                        ParseResult::NoArg => {
21919625d8cSopenharmony_ci                            // Is a single dash `-`, try positional.
22019625d8cSopenharmony_ci                        }
22119625d8cSopenharmony_ci                        ParseResult::ValuesDone => {
22219625d8cSopenharmony_ci                            parse_state = ParseState::ValuesDone;
22319625d8cSopenharmony_ci                            continue;
22419625d8cSopenharmony_ci                        }
22519625d8cSopenharmony_ci                        ParseResult::Opt(id) => {
22619625d8cSopenharmony_ci                            parse_state = ParseState::Opt(id);
22719625d8cSopenharmony_ci                            continue;
22819625d8cSopenharmony_ci                        }
22919625d8cSopenharmony_ci                        ParseResult::FlagSubCommand(name) => {
23019625d8cSopenharmony_ci                            // If there are more short flags to be processed, we should keep the state, and later
23119625d8cSopenharmony_ci                            // revisit the current group of short flags skipping the subcommand.
23219625d8cSopenharmony_ci                            keep_state = self
23319625d8cSopenharmony_ci                                .flag_subcmd_at
23419625d8cSopenharmony_ci                                .map(|at| {
23519625d8cSopenharmony_ci                                    raw_args
23619625d8cSopenharmony_ci                                        .seek(&mut args_cursor, clap_lex::SeekFrom::Current(-1));
23719625d8cSopenharmony_ci                                    // Since we are now saving the current state, the number of flags to skip during state recovery should
23819625d8cSopenharmony_ci                                    // be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position.
23919625d8cSopenharmony_ci                                    self.flag_subcmd_skip = self.cur_idx.get() - at + 1;
24019625d8cSopenharmony_ci                                })
24119625d8cSopenharmony_ci                                .is_some();
24219625d8cSopenharmony_ci
24319625d8cSopenharmony_ci                            debug!(
24419625d8cSopenharmony_ci                                "Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}",
24519625d8cSopenharmony_ci                                name,
24619625d8cSopenharmony_ci                                keep_state,
24719625d8cSopenharmony_ci                                self.flag_subcmd_skip
24819625d8cSopenharmony_ci                            );
24919625d8cSopenharmony_ci
25019625d8cSopenharmony_ci                            subcmd_name = Some(name);
25119625d8cSopenharmony_ci                            break;
25219625d8cSopenharmony_ci                        }
25319625d8cSopenharmony_ci                        ParseResult::EqualsNotProvided { arg } => {
25419625d8cSopenharmony_ci                            let _ = self.resolve_pending(matcher);
25519625d8cSopenharmony_ci                            return Err(ClapError::no_equals(
25619625d8cSopenharmony_ci                                self.cmd,
25719625d8cSopenharmony_ci                                arg,
25819625d8cSopenharmony_ci                                Usage::new(self.cmd).create_usage_with_title(&[]),
25919625d8cSopenharmony_ci                            ));
26019625d8cSopenharmony_ci                        }
26119625d8cSopenharmony_ci                        ParseResult::NoMatchingArg { arg } => {
26219625d8cSopenharmony_ci                            let _ = self.resolve_pending(matcher);
26319625d8cSopenharmony_ci                            // We already know it looks like a flag
26419625d8cSopenharmony_ci                            let suggested_trailing_arg =
26519625d8cSopenharmony_ci                                !trailing_values && self.cmd.has_positionals();
26619625d8cSopenharmony_ci                            return Err(ClapError::unknown_argument(
26719625d8cSopenharmony_ci                                self.cmd,
26819625d8cSopenharmony_ci                                arg,
26919625d8cSopenharmony_ci                                None,
27019625d8cSopenharmony_ci                                suggested_trailing_arg,
27119625d8cSopenharmony_ci                                Usage::new(self.cmd).create_usage_with_title(&[]),
27219625d8cSopenharmony_ci                            ));
27319625d8cSopenharmony_ci                        }
27419625d8cSopenharmony_ci                        ParseResult::MaybeHyphenValue => {
27519625d8cSopenharmony_ci                            // Maybe a hyphen value, do nothing.
27619625d8cSopenharmony_ci                        }
27719625d8cSopenharmony_ci                        ParseResult::UnneededAttachedValue { .. }
27819625d8cSopenharmony_ci                        | ParseResult::AttachedValueNotConsumed => unreachable!(),
27919625d8cSopenharmony_ci                    }
28019625d8cSopenharmony_ci                }
28119625d8cSopenharmony_ci
28219625d8cSopenharmony_ci                if let ParseState::Opt(id) = &parse_state {
28319625d8cSopenharmony_ci                    // Assume this is a value of a previous arg.
28419625d8cSopenharmony_ci
28519625d8cSopenharmony_ci                    // get the option so we can check the settings
28619625d8cSopenharmony_ci                    let arg = &self.cmd[id];
28719625d8cSopenharmony_ci                    let parse_result = if let Some(parse_result) =
28819625d8cSopenharmony_ci                        self.check_terminator(arg, arg_os.to_value_os())
28919625d8cSopenharmony_ci                    {
29019625d8cSopenharmony_ci                        parse_result
29119625d8cSopenharmony_ci                    } else {
29219625d8cSopenharmony_ci                        let trailing_values = false;
29319625d8cSopenharmony_ci                        let arg_values = matcher.pending_values_mut(id, None, trailing_values);
29419625d8cSopenharmony_ci                        arg_values.push(arg_os.to_value_os().to_os_str().into_owned());
29519625d8cSopenharmony_ci                        if matcher.needs_more_vals(arg) {
29619625d8cSopenharmony_ci                            ParseResult::Opt(arg.get_id().clone())
29719625d8cSopenharmony_ci                        } else {
29819625d8cSopenharmony_ci                            ParseResult::ValuesDone
29919625d8cSopenharmony_ci                        }
30019625d8cSopenharmony_ci                    };
30119625d8cSopenharmony_ci                    parse_state = match parse_result {
30219625d8cSopenharmony_ci                        ParseResult::Opt(id) => ParseState::Opt(id),
30319625d8cSopenharmony_ci                        ParseResult::ValuesDone => ParseState::ValuesDone,
30419625d8cSopenharmony_ci                        _ => unreachable!(),
30519625d8cSopenharmony_ci                    };
30619625d8cSopenharmony_ci                    // get the next value from the iterator
30719625d8cSopenharmony_ci                    continue;
30819625d8cSopenharmony_ci                }
30919625d8cSopenharmony_ci            }
31019625d8cSopenharmony_ci
31119625d8cSopenharmony_ci            // Correct pos_counter.
31219625d8cSopenharmony_ci            pos_counter = {
31319625d8cSopenharmony_ci                let is_second_to_last = pos_counter + 1 == positional_count;
31419625d8cSopenharmony_ci
31519625d8cSopenharmony_ci                // The last positional argument, or second to last positional
31619625d8cSopenharmony_ci                // argument may be set to .multiple_values(true) or `.multiple_occurrences(true)`
31719625d8cSopenharmony_ci                let low_index_mults = is_second_to_last
31819625d8cSopenharmony_ci                    && self.cmd.get_positionals().any(|a| {
31919625d8cSopenharmony_ci                        a.is_multiple() && (positional_count != a.get_index().unwrap_or(0))
32019625d8cSopenharmony_ci                    })
32119625d8cSopenharmony_ci                    && self
32219625d8cSopenharmony_ci                        .cmd
32319625d8cSopenharmony_ci                        .get_positionals()
32419625d8cSopenharmony_ci                        .last()
32519625d8cSopenharmony_ci                        .map_or(false, |p_name| !p_name.is_last_set());
32619625d8cSopenharmony_ci
32719625d8cSopenharmony_ci                let missing_pos = self.cmd.is_allow_missing_positional_set()
32819625d8cSopenharmony_ci                    && is_second_to_last
32919625d8cSopenharmony_ci                    && !trailing_values;
33019625d8cSopenharmony_ci
33119625d8cSopenharmony_ci                debug!(
33219625d8cSopenharmony_ci                    "Parser::get_matches_with: Positional counter...{}",
33319625d8cSopenharmony_ci                    pos_counter
33419625d8cSopenharmony_ci                );
33519625d8cSopenharmony_ci                debug!(
33619625d8cSopenharmony_ci                    "Parser::get_matches_with: Low index multiples...{:?}",
33719625d8cSopenharmony_ci                    low_index_mults
33819625d8cSopenharmony_ci                );
33919625d8cSopenharmony_ci
34019625d8cSopenharmony_ci                if low_index_mults || missing_pos {
34119625d8cSopenharmony_ci                    let skip_current = if let Some(n) = raw_args.peek(&args_cursor) {
34219625d8cSopenharmony_ci                        if let Some(arg) = self
34319625d8cSopenharmony_ci                            .cmd
34419625d8cSopenharmony_ci                            .get_positionals()
34519625d8cSopenharmony_ci                            .find(|a| a.get_index() == Some(pos_counter))
34619625d8cSopenharmony_ci                        {
34719625d8cSopenharmony_ci                            // If next value looks like a new_arg or it's a
34819625d8cSopenharmony_ci                            // subcommand, skip positional argument under current
34919625d8cSopenharmony_ci                            // pos_counter(which means current value cannot be a
35019625d8cSopenharmony_ci                            // positional argument with a value next to it), assume
35119625d8cSopenharmony_ci                            // current value matches the next arg.
35219625d8cSopenharmony_ci                            self.is_new_arg(&n, arg)
35319625d8cSopenharmony_ci                                || self
35419625d8cSopenharmony_ci                                    .possible_subcommand(n.to_value(), valid_arg_found)
35519625d8cSopenharmony_ci                                    .is_some()
35619625d8cSopenharmony_ci                        } else {
35719625d8cSopenharmony_ci                            true
35819625d8cSopenharmony_ci                        }
35919625d8cSopenharmony_ci                    } else {
36019625d8cSopenharmony_ci                        true
36119625d8cSopenharmony_ci                    };
36219625d8cSopenharmony_ci
36319625d8cSopenharmony_ci                    if skip_current {
36419625d8cSopenharmony_ci                        debug!("Parser::get_matches_with: Bumping the positional counter...");
36519625d8cSopenharmony_ci                        pos_counter + 1
36619625d8cSopenharmony_ci                    } else {
36719625d8cSopenharmony_ci                        pos_counter
36819625d8cSopenharmony_ci                    }
36919625d8cSopenharmony_ci                } else if trailing_values
37019625d8cSopenharmony_ci                    && (self.cmd.is_allow_missing_positional_set() || contains_last)
37119625d8cSopenharmony_ci                {
37219625d8cSopenharmony_ci                    // Came to -- and one positional has .last(true) set, so we go immediately
37319625d8cSopenharmony_ci                    // to the last (highest index) positional
37419625d8cSopenharmony_ci                    debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
37519625d8cSopenharmony_ci                    positional_count
37619625d8cSopenharmony_ci                } else {
37719625d8cSopenharmony_ci                    pos_counter
37819625d8cSopenharmony_ci                }
37919625d8cSopenharmony_ci            };
38019625d8cSopenharmony_ci
38119625d8cSopenharmony_ci            if let Some(arg) = self.cmd.get_keymap().get(&pos_counter) {
38219625d8cSopenharmony_ci                if arg.is_last_set() && !trailing_values {
38319625d8cSopenharmony_ci                    let _ = self.resolve_pending(matcher);
38419625d8cSopenharmony_ci                    // Its already considered a positional, we don't need to suggest turning it
38519625d8cSopenharmony_ci                    // into one
38619625d8cSopenharmony_ci                    let suggested_trailing_arg = false;
38719625d8cSopenharmony_ci                    return Err(ClapError::unknown_argument(
38819625d8cSopenharmony_ci                        self.cmd,
38919625d8cSopenharmony_ci                        arg_os.display().to_string(),
39019625d8cSopenharmony_ci                        None,
39119625d8cSopenharmony_ci                        suggested_trailing_arg,
39219625d8cSopenharmony_ci                        Usage::new(self.cmd).create_usage_with_title(&[]),
39319625d8cSopenharmony_ci                    ));
39419625d8cSopenharmony_ci                }
39519625d8cSopenharmony_ci
39619625d8cSopenharmony_ci                if arg.is_trailing_var_arg_set() {
39719625d8cSopenharmony_ci                    trailing_values = true;
39819625d8cSopenharmony_ci                }
39919625d8cSopenharmony_ci
40019625d8cSopenharmony_ci                if matcher.pending_arg_id() != Some(arg.get_id()) || !arg.is_multiple_values_set() {
40119625d8cSopenharmony_ci                    ok!(self.resolve_pending(matcher));
40219625d8cSopenharmony_ci                }
40319625d8cSopenharmony_ci                if let Some(_parse_result) = self.check_terminator(arg, arg_os.to_value_os()) {
40419625d8cSopenharmony_ci                    debug!(
40519625d8cSopenharmony_ci                        "Parser::get_matches_with: ignoring terminator result {:?}",
40619625d8cSopenharmony_ci                        _parse_result
40719625d8cSopenharmony_ci                    );
40819625d8cSopenharmony_ci                } else {
40919625d8cSopenharmony_ci                    let arg_values = matcher.pending_values_mut(
41019625d8cSopenharmony_ci                        arg.get_id(),
41119625d8cSopenharmony_ci                        Some(Identifier::Index),
41219625d8cSopenharmony_ci                        trailing_values,
41319625d8cSopenharmony_ci                    );
41419625d8cSopenharmony_ci                    arg_values.push(arg_os.to_value_os().to_os_str().into_owned());
41519625d8cSopenharmony_ci                }
41619625d8cSopenharmony_ci
41719625d8cSopenharmony_ci                // Only increment the positional counter if it doesn't allow multiples
41819625d8cSopenharmony_ci                if !arg.is_multiple() {
41919625d8cSopenharmony_ci                    pos_counter += 1;
42019625d8cSopenharmony_ci                    parse_state = ParseState::ValuesDone;
42119625d8cSopenharmony_ci                } else {
42219625d8cSopenharmony_ci                    parse_state = ParseState::Pos(arg.get_id().clone());
42319625d8cSopenharmony_ci                }
42419625d8cSopenharmony_ci                valid_arg_found = true;
42519625d8cSopenharmony_ci            } else if let Some(external_parser) =
42619625d8cSopenharmony_ci                self.cmd.get_external_subcommand_value_parser().cloned()
42719625d8cSopenharmony_ci            {
42819625d8cSopenharmony_ci                // Get external subcommand name
42919625d8cSopenharmony_ci                let sc_name = match arg_os.to_value() {
43019625d8cSopenharmony_ci                    Ok(s) => s.to_owned(),
43119625d8cSopenharmony_ci                    Err(_) => {
43219625d8cSopenharmony_ci                        let _ = self.resolve_pending(matcher);
43319625d8cSopenharmony_ci                        return Err(ClapError::invalid_utf8(
43419625d8cSopenharmony_ci                            self.cmd,
43519625d8cSopenharmony_ci                            Usage::new(self.cmd).create_usage_with_title(&[]),
43619625d8cSopenharmony_ci                        ));
43719625d8cSopenharmony_ci                    }
43819625d8cSopenharmony_ci                };
43919625d8cSopenharmony_ci
44019625d8cSopenharmony_ci                // Collect the external subcommand args
44119625d8cSopenharmony_ci                let mut sc_m = ArgMatcher::new(self.cmd);
44219625d8cSopenharmony_ci                sc_m.start_occurrence_of_external(self.cmd);
44319625d8cSopenharmony_ci
44419625d8cSopenharmony_ci                for raw_val in raw_args.remaining(&mut args_cursor) {
44519625d8cSopenharmony_ci                    let val = ok!(external_parser.parse_ref(self.cmd, None, raw_val));
44619625d8cSopenharmony_ci                    let external_id = Id::from_static_ref(Id::EXTERNAL);
44719625d8cSopenharmony_ci                    sc_m.add_val_to(&external_id, val, raw_val.to_os_string());
44819625d8cSopenharmony_ci                }
44919625d8cSopenharmony_ci
45019625d8cSopenharmony_ci                matcher.subcommand(SubCommand {
45119625d8cSopenharmony_ci                    name: sc_name,
45219625d8cSopenharmony_ci                    matches: sc_m.into_inner(),
45319625d8cSopenharmony_ci                });
45419625d8cSopenharmony_ci
45519625d8cSopenharmony_ci                ok!(self.resolve_pending(matcher));
45619625d8cSopenharmony_ci                #[cfg(feature = "env")]
45719625d8cSopenharmony_ci                ok!(self.add_env(matcher));
45819625d8cSopenharmony_ci                ok!(self.add_defaults(matcher));
45919625d8cSopenharmony_ci                return Validator::new(self.cmd).validate(parse_state, matcher);
46019625d8cSopenharmony_ci            } else {
46119625d8cSopenharmony_ci                // Start error processing
46219625d8cSopenharmony_ci                let _ = self.resolve_pending(matcher);
46319625d8cSopenharmony_ci                return Err(self.match_arg_error(&arg_os, valid_arg_found, trailing_values));
46419625d8cSopenharmony_ci            }
46519625d8cSopenharmony_ci        }
46619625d8cSopenharmony_ci
46719625d8cSopenharmony_ci        if let Some(ref pos_sc_name) = subcmd_name {
46819625d8cSopenharmony_ci            let sc_name = self
46919625d8cSopenharmony_ci                .cmd
47019625d8cSopenharmony_ci                .find_subcommand(pos_sc_name)
47119625d8cSopenharmony_ci                .expect(INTERNAL_ERROR_MSG)
47219625d8cSopenharmony_ci                .get_name()
47319625d8cSopenharmony_ci                .to_owned();
47419625d8cSopenharmony_ci            ok!(self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor, keep_state));
47519625d8cSopenharmony_ci        }
47619625d8cSopenharmony_ci
47719625d8cSopenharmony_ci        ok!(self.resolve_pending(matcher));
47819625d8cSopenharmony_ci        #[cfg(feature = "env")]
47919625d8cSopenharmony_ci        ok!(self.add_env(matcher));
48019625d8cSopenharmony_ci        ok!(self.add_defaults(matcher));
48119625d8cSopenharmony_ci        Validator::new(self.cmd).validate(parse_state, matcher)
48219625d8cSopenharmony_ci    }
48319625d8cSopenharmony_ci
48419625d8cSopenharmony_ci    fn match_arg_error(
48519625d8cSopenharmony_ci        &self,
48619625d8cSopenharmony_ci        arg_os: &clap_lex::ParsedArg<'_>,
48719625d8cSopenharmony_ci        valid_arg_found: bool,
48819625d8cSopenharmony_ci        trailing_values: bool,
48919625d8cSopenharmony_ci    ) -> ClapError {
49019625d8cSopenharmony_ci        // If argument follows a `--`
49119625d8cSopenharmony_ci        if trailing_values {
49219625d8cSopenharmony_ci            // If the arg matches a subcommand name, or any of its aliases (if defined)
49319625d8cSopenharmony_ci            if self
49419625d8cSopenharmony_ci                .possible_subcommand(arg_os.to_value(), valid_arg_found)
49519625d8cSopenharmony_ci                .is_some()
49619625d8cSopenharmony_ci            {
49719625d8cSopenharmony_ci                return ClapError::unnecessary_double_dash(
49819625d8cSopenharmony_ci                    self.cmd,
49919625d8cSopenharmony_ci                    arg_os.display().to_string(),
50019625d8cSopenharmony_ci                    Usage::new(self.cmd).create_usage_with_title(&[]),
50119625d8cSopenharmony_ci                );
50219625d8cSopenharmony_ci            }
50319625d8cSopenharmony_ci        }
50419625d8cSopenharmony_ci
50519625d8cSopenharmony_ci        if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) {
50619625d8cSopenharmony_ci            let candidates = suggestions::did_you_mean(
50719625d8cSopenharmony_ci                &arg_os.display().to_string(),
50819625d8cSopenharmony_ci                self.cmd.all_subcommand_names(),
50919625d8cSopenharmony_ci            );
51019625d8cSopenharmony_ci            // If the argument looks like a subcommand.
51119625d8cSopenharmony_ci            if !candidates.is_empty() {
51219625d8cSopenharmony_ci                return ClapError::invalid_subcommand(
51319625d8cSopenharmony_ci                    self.cmd,
51419625d8cSopenharmony_ci                    arg_os.display().to_string(),
51519625d8cSopenharmony_ci                    candidates,
51619625d8cSopenharmony_ci                    self.cmd
51719625d8cSopenharmony_ci                        .get_bin_name()
51819625d8cSopenharmony_ci                        .unwrap_or_else(|| self.cmd.get_name())
51919625d8cSopenharmony_ci                        .to_owned(),
52019625d8cSopenharmony_ci                    Usage::new(self.cmd).create_usage_with_title(&[]),
52119625d8cSopenharmony_ci                );
52219625d8cSopenharmony_ci            }
52319625d8cSopenharmony_ci
52419625d8cSopenharmony_ci            // If the argument must be a subcommand.
52519625d8cSopenharmony_ci            if self.cmd.has_subcommands()
52619625d8cSopenharmony_ci                && (!self.cmd.has_positionals() || self.cmd.is_infer_subcommands_set())
52719625d8cSopenharmony_ci            {
52819625d8cSopenharmony_ci                return ClapError::unrecognized_subcommand(
52919625d8cSopenharmony_ci                    self.cmd,
53019625d8cSopenharmony_ci                    arg_os.display().to_string(),
53119625d8cSopenharmony_ci                    Usage::new(self.cmd).create_usage_with_title(&[]),
53219625d8cSopenharmony_ci                );
53319625d8cSopenharmony_ci            }
53419625d8cSopenharmony_ci        }
53519625d8cSopenharmony_ci
53619625d8cSopenharmony_ci        let suggested_trailing_arg = !trailing_values
53719625d8cSopenharmony_ci            && self.cmd.has_positionals()
53819625d8cSopenharmony_ci            && (arg_os.is_long() || arg_os.is_short());
53919625d8cSopenharmony_ci        ClapError::unknown_argument(
54019625d8cSopenharmony_ci            self.cmd,
54119625d8cSopenharmony_ci            arg_os.display().to_string(),
54219625d8cSopenharmony_ci            None,
54319625d8cSopenharmony_ci            suggested_trailing_arg,
54419625d8cSopenharmony_ci            Usage::new(self.cmd).create_usage_with_title(&[]),
54519625d8cSopenharmony_ci        )
54619625d8cSopenharmony_ci    }
54719625d8cSopenharmony_ci
54819625d8cSopenharmony_ci    // Checks if the arg matches a subcommand name, or any of its aliases (if defined)
54919625d8cSopenharmony_ci    fn possible_subcommand(
55019625d8cSopenharmony_ci        &self,
55119625d8cSopenharmony_ci        arg: Result<&str, &RawOsStr>,
55219625d8cSopenharmony_ci        valid_arg_found: bool,
55319625d8cSopenharmony_ci    ) -> Option<&str> {
55419625d8cSopenharmony_ci        debug!("Parser::possible_subcommand: arg={:?}", arg);
55519625d8cSopenharmony_ci        let arg = some!(arg.ok());
55619625d8cSopenharmony_ci
55719625d8cSopenharmony_ci        if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) {
55819625d8cSopenharmony_ci            if self.cmd.is_infer_subcommands_set() {
55919625d8cSopenharmony_ci                // For subcommand `test`, we accepts it's prefix: `t`, `te`,
56019625d8cSopenharmony_ci                // `tes` and `test`.
56119625d8cSopenharmony_ci                let v = self
56219625d8cSopenharmony_ci                    .cmd
56319625d8cSopenharmony_ci                    .all_subcommand_names()
56419625d8cSopenharmony_ci                    .filter(|s| s.starts_with(arg))
56519625d8cSopenharmony_ci                    .collect::<Vec<_>>();
56619625d8cSopenharmony_ci
56719625d8cSopenharmony_ci                if v.len() == 1 {
56819625d8cSopenharmony_ci                    return Some(v[0]);
56919625d8cSopenharmony_ci                }
57019625d8cSopenharmony_ci
57119625d8cSopenharmony_ci                // If there is any ambiguity, fallback to non-infer subcommand
57219625d8cSopenharmony_ci                // search.
57319625d8cSopenharmony_ci            }
57419625d8cSopenharmony_ci            if let Some(sc) = self.cmd.find_subcommand(arg) {
57519625d8cSopenharmony_ci                return Some(sc.get_name());
57619625d8cSopenharmony_ci            }
57719625d8cSopenharmony_ci        }
57819625d8cSopenharmony_ci        None
57919625d8cSopenharmony_ci    }
58019625d8cSopenharmony_ci
58119625d8cSopenharmony_ci    // Checks if the arg matches a long flag subcommand name, or any of its aliases (if defined)
58219625d8cSopenharmony_ci    fn possible_long_flag_subcommand(&self, arg: &str) -> Option<&str> {
58319625d8cSopenharmony_ci        debug!("Parser::possible_long_flag_subcommand: arg={:?}", arg);
58419625d8cSopenharmony_ci        if self.cmd.is_infer_subcommands_set() {
58519625d8cSopenharmony_ci            let options = self
58619625d8cSopenharmony_ci                .cmd
58719625d8cSopenharmony_ci                .get_subcommands()
58819625d8cSopenharmony_ci                .fold(Vec::new(), |mut options, sc| {
58919625d8cSopenharmony_ci                    if let Some(long) = sc.get_long_flag() {
59019625d8cSopenharmony_ci                        if long.starts_with(arg) {
59119625d8cSopenharmony_ci                            options.push(long);
59219625d8cSopenharmony_ci                        }
59319625d8cSopenharmony_ci                        options.extend(sc.get_all_aliases().filter(|alias| alias.starts_with(arg)))
59419625d8cSopenharmony_ci                    }
59519625d8cSopenharmony_ci                    options
59619625d8cSopenharmony_ci                });
59719625d8cSopenharmony_ci            if options.len() == 1 {
59819625d8cSopenharmony_ci                return Some(options[0]);
59919625d8cSopenharmony_ci            }
60019625d8cSopenharmony_ci
60119625d8cSopenharmony_ci            for sc in options {
60219625d8cSopenharmony_ci                if sc == arg {
60319625d8cSopenharmony_ci                    return Some(sc);
60419625d8cSopenharmony_ci                }
60519625d8cSopenharmony_ci            }
60619625d8cSopenharmony_ci        } else if let Some(sc_name) = self.cmd.find_long_subcmd(arg) {
60719625d8cSopenharmony_ci            return Some(sc_name);
60819625d8cSopenharmony_ci        }
60919625d8cSopenharmony_ci        None
61019625d8cSopenharmony_ci    }
61119625d8cSopenharmony_ci
61219625d8cSopenharmony_ci    fn parse_help_subcommand(
61319625d8cSopenharmony_ci        &self,
61419625d8cSopenharmony_ci        cmds: impl Iterator<Item = &'cmd OsStr>,
61519625d8cSopenharmony_ci    ) -> ClapResult<std::convert::Infallible> {
61619625d8cSopenharmony_ci        debug!("Parser::parse_help_subcommand");
61719625d8cSopenharmony_ci
61819625d8cSopenharmony_ci        let mut cmd = self.cmd.clone();
61919625d8cSopenharmony_ci        let sc = {
62019625d8cSopenharmony_ci            let mut sc = &mut cmd;
62119625d8cSopenharmony_ci
62219625d8cSopenharmony_ci            for cmd in cmds {
62319625d8cSopenharmony_ci                sc = if let Some(sc_name) =
62419625d8cSopenharmony_ci                    sc.find_subcommand(cmd).map(|sc| sc.get_name().to_owned())
62519625d8cSopenharmony_ci                {
62619625d8cSopenharmony_ci                    sc._build_subcommand(&sc_name).unwrap()
62719625d8cSopenharmony_ci                } else {
62819625d8cSopenharmony_ci                    return Err(ClapError::unrecognized_subcommand(
62919625d8cSopenharmony_ci                        sc,
63019625d8cSopenharmony_ci                        cmd.to_string_lossy().into_owned(),
63119625d8cSopenharmony_ci                        Usage::new(sc).create_usage_with_title(&[]),
63219625d8cSopenharmony_ci                    ));
63319625d8cSopenharmony_ci                };
63419625d8cSopenharmony_ci            }
63519625d8cSopenharmony_ci
63619625d8cSopenharmony_ci            sc
63719625d8cSopenharmony_ci        };
63819625d8cSopenharmony_ci        let parser = Parser::new(sc);
63919625d8cSopenharmony_ci
64019625d8cSopenharmony_ci        Err(parser.help_err(true))
64119625d8cSopenharmony_ci    }
64219625d8cSopenharmony_ci
64319625d8cSopenharmony_ci    fn is_new_arg(&self, next: &clap_lex::ParsedArg<'_>, current_positional: &Arg) -> bool {
64419625d8cSopenharmony_ci        #![allow(clippy::needless_bool)] // Prefer consistent if/else-if ladder
64519625d8cSopenharmony_ci
64619625d8cSopenharmony_ci        debug!(
64719625d8cSopenharmony_ci            "Parser::is_new_arg: {:?}:{}",
64819625d8cSopenharmony_ci            next.to_value_os(),
64919625d8cSopenharmony_ci            current_positional.get_id()
65019625d8cSopenharmony_ci        );
65119625d8cSopenharmony_ci
65219625d8cSopenharmony_ci        if self.cmd[current_positional.get_id()].is_allow_hyphen_values_set()
65319625d8cSopenharmony_ci            || (self.cmd[current_positional.get_id()].is_allow_negative_numbers_set()
65419625d8cSopenharmony_ci                && next.is_number())
65519625d8cSopenharmony_ci        {
65619625d8cSopenharmony_ci            // If allow hyphen, this isn't a new arg.
65719625d8cSopenharmony_ci            debug!("Parser::is_new_arg: Allow hyphen");
65819625d8cSopenharmony_ci            false
65919625d8cSopenharmony_ci        } else if next.is_long() {
66019625d8cSopenharmony_ci            // If this is a long flag, this is a new arg.
66119625d8cSopenharmony_ci            debug!("Parser::is_new_arg: --<something> found");
66219625d8cSopenharmony_ci            true
66319625d8cSopenharmony_ci        } else if next.is_short() {
66419625d8cSopenharmony_ci            // If this is a short flag, this is a new arg. But a singe '-' by
66519625d8cSopenharmony_ci            // itself is a value and typically means "stdin" on unix systems.
66619625d8cSopenharmony_ci            debug!("Parser::is_new_arg: -<something> found");
66719625d8cSopenharmony_ci            true
66819625d8cSopenharmony_ci        } else {
66919625d8cSopenharmony_ci            // Nothing special, this is a value.
67019625d8cSopenharmony_ci            debug!("Parser::is_new_arg: value");
67119625d8cSopenharmony_ci            false
67219625d8cSopenharmony_ci        }
67319625d8cSopenharmony_ci    }
67419625d8cSopenharmony_ci
67519625d8cSopenharmony_ci    fn parse_subcommand(
67619625d8cSopenharmony_ci        &mut self,
67719625d8cSopenharmony_ci        sc_name: &str,
67819625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
67919625d8cSopenharmony_ci        raw_args: &mut clap_lex::RawArgs,
68019625d8cSopenharmony_ci        args_cursor: clap_lex::ArgCursor,
68119625d8cSopenharmony_ci        keep_state: bool,
68219625d8cSopenharmony_ci    ) -> ClapResult<()> {
68319625d8cSopenharmony_ci        debug!("Parser::parse_subcommand");
68419625d8cSopenharmony_ci
68519625d8cSopenharmony_ci        let partial_parsing_enabled = self.cmd.is_ignore_errors_set();
68619625d8cSopenharmony_ci
68719625d8cSopenharmony_ci        if let Some(sc) = self.cmd._build_subcommand(sc_name) {
68819625d8cSopenharmony_ci            let mut sc_matcher = ArgMatcher::new(sc);
68919625d8cSopenharmony_ci
69019625d8cSopenharmony_ci            debug!(
69119625d8cSopenharmony_ci                "Parser::parse_subcommand: About to parse sc={}",
69219625d8cSopenharmony_ci                sc.get_name()
69319625d8cSopenharmony_ci            );
69419625d8cSopenharmony_ci
69519625d8cSopenharmony_ci            {
69619625d8cSopenharmony_ci                let mut p = Parser::new(sc);
69719625d8cSopenharmony_ci                // HACK: maintain indexes between parsers
69819625d8cSopenharmony_ci                // FlagSubCommand short arg needs to revisit the current short args, but skip the subcommand itself
69919625d8cSopenharmony_ci                if keep_state {
70019625d8cSopenharmony_ci                    p.cur_idx.set(self.cur_idx.get());
70119625d8cSopenharmony_ci                    p.flag_subcmd_at = self.flag_subcmd_at;
70219625d8cSopenharmony_ci                    p.flag_subcmd_skip = self.flag_subcmd_skip;
70319625d8cSopenharmony_ci                }
70419625d8cSopenharmony_ci                if let Err(error) = p.get_matches_with(&mut sc_matcher, raw_args, args_cursor) {
70519625d8cSopenharmony_ci                    if partial_parsing_enabled {
70619625d8cSopenharmony_ci                        debug!(
70719625d8cSopenharmony_ci                            "Parser::parse_subcommand: ignored error in subcommand {}: {:?}",
70819625d8cSopenharmony_ci                            sc_name, error
70919625d8cSopenharmony_ci                        );
71019625d8cSopenharmony_ci                    } else {
71119625d8cSopenharmony_ci                        return Err(error);
71219625d8cSopenharmony_ci                    }
71319625d8cSopenharmony_ci                }
71419625d8cSopenharmony_ci            }
71519625d8cSopenharmony_ci            matcher.subcommand(SubCommand {
71619625d8cSopenharmony_ci                name: sc.get_name().to_owned(),
71719625d8cSopenharmony_ci                matches: sc_matcher.into_inner(),
71819625d8cSopenharmony_ci            });
71919625d8cSopenharmony_ci        }
72019625d8cSopenharmony_ci        Ok(())
72119625d8cSopenharmony_ci    }
72219625d8cSopenharmony_ci
72319625d8cSopenharmony_ci    fn parse_long_arg(
72419625d8cSopenharmony_ci        &mut self,
72519625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
72619625d8cSopenharmony_ci        long_arg: Result<&str, &RawOsStr>,
72719625d8cSopenharmony_ci        long_value: Option<&RawOsStr>,
72819625d8cSopenharmony_ci        parse_state: &ParseState,
72919625d8cSopenharmony_ci        pos_counter: usize,
73019625d8cSopenharmony_ci        valid_arg_found: &mut bool,
73119625d8cSopenharmony_ci    ) -> ClapResult<ParseResult> {
73219625d8cSopenharmony_ci        // maybe here lifetime should be 'a
73319625d8cSopenharmony_ci        debug!("Parser::parse_long_arg");
73419625d8cSopenharmony_ci
73519625d8cSopenharmony_ci        #[allow(clippy::blocks_in_if_conditions)]
73619625d8cSopenharmony_ci        if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
73719625d8cSopenharmony_ci            self.cmd[opt].is_allow_hyphen_values_set())
73819625d8cSopenharmony_ci        {
73919625d8cSopenharmony_ci            debug!("Parser::parse_long_arg: prior arg accepts hyphenated values",);
74019625d8cSopenharmony_ci            return Ok(ParseResult::MaybeHyphenValue);
74119625d8cSopenharmony_ci        }
74219625d8cSopenharmony_ci
74319625d8cSopenharmony_ci        debug!("Parser::parse_long_arg: Does it contain '='...");
74419625d8cSopenharmony_ci        let long_arg = match long_arg {
74519625d8cSopenharmony_ci            Ok(long_arg) => long_arg,
74619625d8cSopenharmony_ci            Err(long_arg) => {
74719625d8cSopenharmony_ci                return Ok(ParseResult::NoMatchingArg {
74819625d8cSopenharmony_ci                    arg: long_arg.to_str_lossy().into_owned(),
74919625d8cSopenharmony_ci                });
75019625d8cSopenharmony_ci            }
75119625d8cSopenharmony_ci        };
75219625d8cSopenharmony_ci        if long_arg.is_empty() {
75319625d8cSopenharmony_ci            debug_assert!(
75419625d8cSopenharmony_ci                long_value.is_some(),
75519625d8cSopenharmony_ci                "`--` should be filtered out before this point"
75619625d8cSopenharmony_ci            );
75719625d8cSopenharmony_ci        }
75819625d8cSopenharmony_ci
75919625d8cSopenharmony_ci        let arg = if let Some(arg) = self.cmd.get_keymap().get(long_arg) {
76019625d8cSopenharmony_ci            debug!("Parser::parse_long_arg: Found valid arg or flag '{}'", arg);
76119625d8cSopenharmony_ci            Some((long_arg, arg))
76219625d8cSopenharmony_ci        } else if self.cmd.is_infer_long_args_set() {
76319625d8cSopenharmony_ci            self.cmd.get_arguments().find_map(|a| {
76419625d8cSopenharmony_ci                if let Some(long) = a.get_long() {
76519625d8cSopenharmony_ci                    if long.starts_with(long_arg) {
76619625d8cSopenharmony_ci                        return Some((long, a));
76719625d8cSopenharmony_ci                    }
76819625d8cSopenharmony_ci                }
76919625d8cSopenharmony_ci                a.aliases
77019625d8cSopenharmony_ci                    .iter()
77119625d8cSopenharmony_ci                    .find_map(|(alias, _)| alias.starts_with(long_arg).then(|| (alias.as_str(), a)))
77219625d8cSopenharmony_ci            })
77319625d8cSopenharmony_ci        } else {
77419625d8cSopenharmony_ci            None
77519625d8cSopenharmony_ci        };
77619625d8cSopenharmony_ci
77719625d8cSopenharmony_ci        if let Some((_long_arg, arg)) = arg {
77819625d8cSopenharmony_ci            let ident = Identifier::Long;
77919625d8cSopenharmony_ci            *valid_arg_found = true;
78019625d8cSopenharmony_ci            if arg.is_takes_value_set() {
78119625d8cSopenharmony_ci                debug!(
78219625d8cSopenharmony_ci                    "Parser::parse_long_arg({:?}): Found an arg with value '{:?}'",
78319625d8cSopenharmony_ci                    long_arg, &long_value
78419625d8cSopenharmony_ci                );
78519625d8cSopenharmony_ci                let has_eq = long_value.is_some();
78619625d8cSopenharmony_ci                self.parse_opt_value(ident, long_value, arg, matcher, has_eq)
78719625d8cSopenharmony_ci            } else if let Some(rest) = long_value {
78819625d8cSopenharmony_ci                let required = self.cmd.required_graph();
78919625d8cSopenharmony_ci                debug!(
79019625d8cSopenharmony_ci                    "Parser::parse_long_arg({:?}): Got invalid literal `{:?}`",
79119625d8cSopenharmony_ci                    long_arg, rest
79219625d8cSopenharmony_ci                );
79319625d8cSopenharmony_ci                let mut used: Vec<Id> = matcher
79419625d8cSopenharmony_ci                    .arg_ids()
79519625d8cSopenharmony_ci                    .filter(|arg_id| {
79619625d8cSopenharmony_ci                        matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
79719625d8cSopenharmony_ci                    })
79819625d8cSopenharmony_ci                    .filter(|&n| {
79919625d8cSopenharmony_ci                        self.cmd.find(n).map_or(true, |a| {
80019625d8cSopenharmony_ci                            !(a.is_hide_set() || required.contains(a.get_id()))
80119625d8cSopenharmony_ci                        })
80219625d8cSopenharmony_ci                    })
80319625d8cSopenharmony_ci                    .cloned()
80419625d8cSopenharmony_ci                    .collect();
80519625d8cSopenharmony_ci                used.push(arg.get_id().clone());
80619625d8cSopenharmony_ci
80719625d8cSopenharmony_ci                Ok(ParseResult::UnneededAttachedValue {
80819625d8cSopenharmony_ci                    rest: rest.to_str_lossy().into_owned(),
80919625d8cSopenharmony_ci                    used,
81019625d8cSopenharmony_ci                    arg: arg.to_string(),
81119625d8cSopenharmony_ci                })
81219625d8cSopenharmony_ci            } else {
81319625d8cSopenharmony_ci                debug!("Parser::parse_long_arg({:?}): Presence validated", long_arg);
81419625d8cSopenharmony_ci                let trailing_idx = None;
81519625d8cSopenharmony_ci                self.react(
81619625d8cSopenharmony_ci                    Some(ident),
81719625d8cSopenharmony_ci                    ValueSource::CommandLine,
81819625d8cSopenharmony_ci                    arg,
81919625d8cSopenharmony_ci                    vec![],
82019625d8cSopenharmony_ci                    trailing_idx,
82119625d8cSopenharmony_ci                    matcher,
82219625d8cSopenharmony_ci                )
82319625d8cSopenharmony_ci            }
82419625d8cSopenharmony_ci        } else if let Some(sc_name) = self.possible_long_flag_subcommand(long_arg) {
82519625d8cSopenharmony_ci            Ok(ParseResult::FlagSubCommand(sc_name.to_string()))
82619625d8cSopenharmony_ci        } else if self
82719625d8cSopenharmony_ci            .cmd
82819625d8cSopenharmony_ci            .get_keymap()
82919625d8cSopenharmony_ci            .get(&pos_counter)
83019625d8cSopenharmony_ci            .map_or(false, |arg| {
83119625d8cSopenharmony_ci                arg.is_allow_hyphen_values_set() && !arg.is_last_set()
83219625d8cSopenharmony_ci            })
83319625d8cSopenharmony_ci        {
83419625d8cSopenharmony_ci            debug!(
83519625d8cSopenharmony_ci                "Parser::parse_long_args: positional at {} allows hyphens",
83619625d8cSopenharmony_ci                pos_counter
83719625d8cSopenharmony_ci            );
83819625d8cSopenharmony_ci            Ok(ParseResult::MaybeHyphenValue)
83919625d8cSopenharmony_ci        } else {
84019625d8cSopenharmony_ci            Ok(ParseResult::NoMatchingArg {
84119625d8cSopenharmony_ci                arg: long_arg.to_owned(),
84219625d8cSopenharmony_ci            })
84319625d8cSopenharmony_ci        }
84419625d8cSopenharmony_ci    }
84519625d8cSopenharmony_ci
84619625d8cSopenharmony_ci    fn parse_short_arg(
84719625d8cSopenharmony_ci        &mut self,
84819625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
84919625d8cSopenharmony_ci        mut short_arg: clap_lex::ShortFlags<'_>,
85019625d8cSopenharmony_ci        parse_state: &ParseState,
85119625d8cSopenharmony_ci        // change this to possible pos_arg when removing the usage of &mut Parser.
85219625d8cSopenharmony_ci        pos_counter: usize,
85319625d8cSopenharmony_ci        valid_arg_found: &mut bool,
85419625d8cSopenharmony_ci    ) -> ClapResult<ParseResult> {
85519625d8cSopenharmony_ci        debug!("Parser::parse_short_arg: short_arg={:?}", short_arg);
85619625d8cSopenharmony_ci
85719625d8cSopenharmony_ci        #[allow(clippy::blocks_in_if_conditions)]
85819625d8cSopenharmony_ci        if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt)
85919625d8cSopenharmony_ci                if self.cmd[opt].is_allow_hyphen_values_set() || (self.cmd[opt].is_allow_negative_numbers_set() && short_arg.is_number()))
86019625d8cSopenharmony_ci        {
86119625d8cSopenharmony_ci            debug!("Parser::parse_short_args: prior arg accepts hyphenated values",);
86219625d8cSopenharmony_ci            return Ok(ParseResult::MaybeHyphenValue);
86319625d8cSopenharmony_ci        } else if self
86419625d8cSopenharmony_ci            .cmd
86519625d8cSopenharmony_ci            .get_keymap()
86619625d8cSopenharmony_ci            .get(&pos_counter)
86719625d8cSopenharmony_ci            .map_or(false, |arg| arg.is_allow_negative_numbers_set())
86819625d8cSopenharmony_ci            && short_arg.is_number()
86919625d8cSopenharmony_ci        {
87019625d8cSopenharmony_ci            debug!("Parser::parse_short_arg: negative number");
87119625d8cSopenharmony_ci            return Ok(ParseResult::MaybeHyphenValue);
87219625d8cSopenharmony_ci        } else if self
87319625d8cSopenharmony_ci            .cmd
87419625d8cSopenharmony_ci            .get_keymap()
87519625d8cSopenharmony_ci            .get(&pos_counter)
87619625d8cSopenharmony_ci            .map_or(false, |arg| {
87719625d8cSopenharmony_ci                arg.is_allow_hyphen_values_set() && !arg.is_last_set()
87819625d8cSopenharmony_ci            })
87919625d8cSopenharmony_ci            && short_arg
88019625d8cSopenharmony_ci                .clone()
88119625d8cSopenharmony_ci                .any(|c| !c.map(|c| self.cmd.contains_short(c)).unwrap_or_default())
88219625d8cSopenharmony_ci        {
88319625d8cSopenharmony_ci            debug!(
88419625d8cSopenharmony_ci                "Parser::parse_short_args: positional at {} allows hyphens",
88519625d8cSopenharmony_ci                pos_counter
88619625d8cSopenharmony_ci            );
88719625d8cSopenharmony_ci            return Ok(ParseResult::MaybeHyphenValue);
88819625d8cSopenharmony_ci        }
88919625d8cSopenharmony_ci
89019625d8cSopenharmony_ci        let mut ret = ParseResult::NoArg;
89119625d8cSopenharmony_ci
89219625d8cSopenharmony_ci        let skip = self.flag_subcmd_skip;
89319625d8cSopenharmony_ci        self.flag_subcmd_skip = 0;
89419625d8cSopenharmony_ci        let res = short_arg.advance_by(skip);
89519625d8cSopenharmony_ci        debug_assert_eq!(
89619625d8cSopenharmony_ci            res,
89719625d8cSopenharmony_ci            Ok(()),
89819625d8cSopenharmony_ci            "tracking of `flag_subcmd_skip` is off for `{short_arg:?}`"
89919625d8cSopenharmony_ci        );
90019625d8cSopenharmony_ci        while let Some(c) = short_arg.next_flag() {
90119625d8cSopenharmony_ci            let c = match c {
90219625d8cSopenharmony_ci                Ok(c) => c,
90319625d8cSopenharmony_ci                Err(rest) => {
90419625d8cSopenharmony_ci                    return Ok(ParseResult::NoMatchingArg {
90519625d8cSopenharmony_ci                        arg: format!("-{}", rest.to_str_lossy()),
90619625d8cSopenharmony_ci                    });
90719625d8cSopenharmony_ci                }
90819625d8cSopenharmony_ci            };
90919625d8cSopenharmony_ci            debug!("Parser::parse_short_arg:iter:{}", c);
91019625d8cSopenharmony_ci
91119625d8cSopenharmony_ci            // Check for matching short options, and return the name if there is no trailing
91219625d8cSopenharmony_ci            // concatenated value: -oval
91319625d8cSopenharmony_ci            // Option: -o
91419625d8cSopenharmony_ci            // Value: val
91519625d8cSopenharmony_ci            if let Some(arg) = self.cmd.get_keymap().get(&c) {
91619625d8cSopenharmony_ci                let ident = Identifier::Short;
91719625d8cSopenharmony_ci                debug!(
91819625d8cSopenharmony_ci                    "Parser::parse_short_arg:iter:{}: Found valid opt or flag",
91919625d8cSopenharmony_ci                    c
92019625d8cSopenharmony_ci                );
92119625d8cSopenharmony_ci                *valid_arg_found = true;
92219625d8cSopenharmony_ci                if !arg.is_takes_value_set() {
92319625d8cSopenharmony_ci                    let arg_values = Vec::new();
92419625d8cSopenharmony_ci                    let trailing_idx = None;
92519625d8cSopenharmony_ci                    ret = ok!(self.react(
92619625d8cSopenharmony_ci                        Some(ident),
92719625d8cSopenharmony_ci                        ValueSource::CommandLine,
92819625d8cSopenharmony_ci                        arg,
92919625d8cSopenharmony_ci                        arg_values,
93019625d8cSopenharmony_ci                        trailing_idx,
93119625d8cSopenharmony_ci                        matcher,
93219625d8cSopenharmony_ci                    ));
93319625d8cSopenharmony_ci                    continue;
93419625d8cSopenharmony_ci                }
93519625d8cSopenharmony_ci
93619625d8cSopenharmony_ci                // Check for trailing concatenated value
93719625d8cSopenharmony_ci                //
93819625d8cSopenharmony_ci                // Cloning the iterator, so we rollback if it isn't there.
93919625d8cSopenharmony_ci                let val = short_arg.clone().next_value_os().unwrap_or_default();
94019625d8cSopenharmony_ci                debug!(
94119625d8cSopenharmony_ci                    "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii), short_arg={:?}",
94219625d8cSopenharmony_ci                    c, val, val.as_raw_bytes(), short_arg
94319625d8cSopenharmony_ci                );
94419625d8cSopenharmony_ci                let val = Some(val).filter(|v| !v.is_empty());
94519625d8cSopenharmony_ci
94619625d8cSopenharmony_ci                // Default to "we're expecting a value later".
94719625d8cSopenharmony_ci                //
94819625d8cSopenharmony_ci                // If attached value is not consumed, we may have more short
94919625d8cSopenharmony_ci                // flags to parse, continue.
95019625d8cSopenharmony_ci                //
95119625d8cSopenharmony_ci                // e.g. `-xvf`, when require_equals && x.min_vals == 0, we don't
95219625d8cSopenharmony_ci                // consume the `vf`, even if it's provided as value.
95319625d8cSopenharmony_ci                let (val, has_eq) = if let Some(val) = val.and_then(|v| v.strip_prefix('=')) {
95419625d8cSopenharmony_ci                    (Some(val), true)
95519625d8cSopenharmony_ci                } else {
95619625d8cSopenharmony_ci                    (val, false)
95719625d8cSopenharmony_ci                };
95819625d8cSopenharmony_ci                match ok!(self.parse_opt_value(ident, val, arg, matcher, has_eq)) {
95919625d8cSopenharmony_ci                    ParseResult::AttachedValueNotConsumed => continue,
96019625d8cSopenharmony_ci                    x => return Ok(x),
96119625d8cSopenharmony_ci                }
96219625d8cSopenharmony_ci            }
96319625d8cSopenharmony_ci
96419625d8cSopenharmony_ci            return if let Some(sc_name) = self.cmd.find_short_subcmd(c) {
96519625d8cSopenharmony_ci                debug!("Parser::parse_short_arg:iter:{}: subcommand={}", c, sc_name);
96619625d8cSopenharmony_ci                // Make sure indices get updated before reading `self.cur_idx`
96719625d8cSopenharmony_ci                ok!(self.resolve_pending(matcher));
96819625d8cSopenharmony_ci                self.cur_idx.set(self.cur_idx.get() + 1);
96919625d8cSopenharmony_ci                debug!("Parser::parse_short_arg: cur_idx:={}", self.cur_idx.get());
97019625d8cSopenharmony_ci
97119625d8cSopenharmony_ci                let name = sc_name.to_string();
97219625d8cSopenharmony_ci                // Get the index of the previously saved flag subcommand in the group of flags (if exists).
97319625d8cSopenharmony_ci                // If it is a new flag subcommand, then the formentioned index should be the current one
97419625d8cSopenharmony_ci                // (ie. `cur_idx`), and should be registered.
97519625d8cSopenharmony_ci                let cur_idx = self.cur_idx.get();
97619625d8cSopenharmony_ci                self.flag_subcmd_at.get_or_insert(cur_idx);
97719625d8cSopenharmony_ci                let done_short_args = short_arg.is_empty();
97819625d8cSopenharmony_ci                if done_short_args {
97919625d8cSopenharmony_ci                    self.flag_subcmd_at = None;
98019625d8cSopenharmony_ci                }
98119625d8cSopenharmony_ci                Ok(ParseResult::FlagSubCommand(name))
98219625d8cSopenharmony_ci            } else {
98319625d8cSopenharmony_ci                Ok(ParseResult::NoMatchingArg {
98419625d8cSopenharmony_ci                    arg: format!("-{c}"),
98519625d8cSopenharmony_ci                })
98619625d8cSopenharmony_ci            };
98719625d8cSopenharmony_ci        }
98819625d8cSopenharmony_ci        Ok(ret)
98919625d8cSopenharmony_ci    }
99019625d8cSopenharmony_ci
99119625d8cSopenharmony_ci    fn parse_opt_value(
99219625d8cSopenharmony_ci        &self,
99319625d8cSopenharmony_ci        ident: Identifier,
99419625d8cSopenharmony_ci        attached_value: Option<&RawOsStr>,
99519625d8cSopenharmony_ci        arg: &Arg,
99619625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
99719625d8cSopenharmony_ci        has_eq: bool,
99819625d8cSopenharmony_ci    ) -> ClapResult<ParseResult> {
99919625d8cSopenharmony_ci        debug!(
100019625d8cSopenharmony_ci            "Parser::parse_opt_value; arg={}, val={:?}, has_eq={:?}",
100119625d8cSopenharmony_ci            arg.get_id(),
100219625d8cSopenharmony_ci            attached_value,
100319625d8cSopenharmony_ci            has_eq
100419625d8cSopenharmony_ci        );
100519625d8cSopenharmony_ci        debug!("Parser::parse_opt_value; arg.settings={:?}", arg.settings);
100619625d8cSopenharmony_ci
100719625d8cSopenharmony_ci        debug!("Parser::parse_opt_value; Checking for val...");
100819625d8cSopenharmony_ci        // require_equals is set, but no '=' is provided, try throwing error.
100919625d8cSopenharmony_ci        if arg.is_require_equals_set() && !has_eq {
101019625d8cSopenharmony_ci            if arg.get_min_vals() == 0 {
101119625d8cSopenharmony_ci                debug!("Requires equals, but min_vals == 0");
101219625d8cSopenharmony_ci                let arg_values = Vec::new();
101319625d8cSopenharmony_ci                let trailing_idx = None;
101419625d8cSopenharmony_ci                let react_result = ok!(self.react(
101519625d8cSopenharmony_ci                    Some(ident),
101619625d8cSopenharmony_ci                    ValueSource::CommandLine,
101719625d8cSopenharmony_ci                    arg,
101819625d8cSopenharmony_ci                    arg_values,
101919625d8cSopenharmony_ci                    trailing_idx,
102019625d8cSopenharmony_ci                    matcher,
102119625d8cSopenharmony_ci                ));
102219625d8cSopenharmony_ci                debug_assert_eq!(react_result, ParseResult::ValuesDone);
102319625d8cSopenharmony_ci                if attached_value.is_some() {
102419625d8cSopenharmony_ci                    Ok(ParseResult::AttachedValueNotConsumed)
102519625d8cSopenharmony_ci                } else {
102619625d8cSopenharmony_ci                    Ok(ParseResult::ValuesDone)
102719625d8cSopenharmony_ci                }
102819625d8cSopenharmony_ci            } else {
102919625d8cSopenharmony_ci                debug!("Requires equals but not provided. Error.");
103019625d8cSopenharmony_ci                Ok(ParseResult::EqualsNotProvided {
103119625d8cSopenharmony_ci                    arg: arg.to_string(),
103219625d8cSopenharmony_ci                })
103319625d8cSopenharmony_ci            }
103419625d8cSopenharmony_ci        } else if let Some(v) = attached_value {
103519625d8cSopenharmony_ci            let arg_values = vec![v.to_os_str().into_owned()];
103619625d8cSopenharmony_ci            let trailing_idx = None;
103719625d8cSopenharmony_ci            let react_result = ok!(self.react(
103819625d8cSopenharmony_ci                Some(ident),
103919625d8cSopenharmony_ci                ValueSource::CommandLine,
104019625d8cSopenharmony_ci                arg,
104119625d8cSopenharmony_ci                arg_values,
104219625d8cSopenharmony_ci                trailing_idx,
104319625d8cSopenharmony_ci                matcher,
104419625d8cSopenharmony_ci            ));
104519625d8cSopenharmony_ci            debug_assert_eq!(react_result, ParseResult::ValuesDone);
104619625d8cSopenharmony_ci            // Attached are always done
104719625d8cSopenharmony_ci            Ok(ParseResult::ValuesDone)
104819625d8cSopenharmony_ci        } else {
104919625d8cSopenharmony_ci            debug!("Parser::parse_opt_value: More arg vals required...");
105019625d8cSopenharmony_ci            ok!(self.resolve_pending(matcher));
105119625d8cSopenharmony_ci            let trailing_values = false;
105219625d8cSopenharmony_ci            matcher.pending_values_mut(arg.get_id(), Some(ident), trailing_values);
105319625d8cSopenharmony_ci            Ok(ParseResult::Opt(arg.get_id().clone()))
105419625d8cSopenharmony_ci        }
105519625d8cSopenharmony_ci    }
105619625d8cSopenharmony_ci
105719625d8cSopenharmony_ci    fn check_terminator(&self, arg: &Arg, val: &RawOsStr) -> Option<ParseResult> {
105819625d8cSopenharmony_ci        if Some(val)
105919625d8cSopenharmony_ci            == arg
106019625d8cSopenharmony_ci                .terminator
106119625d8cSopenharmony_ci                .as_ref()
106219625d8cSopenharmony_ci                .map(|s| RawOsStr::from_str(s.as_str()))
106319625d8cSopenharmony_ci        {
106419625d8cSopenharmony_ci            debug!("Parser::check_terminator: terminator={:?}", arg.terminator);
106519625d8cSopenharmony_ci            Some(ParseResult::ValuesDone)
106619625d8cSopenharmony_ci        } else {
106719625d8cSopenharmony_ci            None
106819625d8cSopenharmony_ci        }
106919625d8cSopenharmony_ci    }
107019625d8cSopenharmony_ci
107119625d8cSopenharmony_ci    fn push_arg_values(
107219625d8cSopenharmony_ci        &self,
107319625d8cSopenharmony_ci        arg: &Arg,
107419625d8cSopenharmony_ci        raw_vals: Vec<OsString>,
107519625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
107619625d8cSopenharmony_ci    ) -> ClapResult<()> {
107719625d8cSopenharmony_ci        debug!("Parser::push_arg_values: {:?}", raw_vals);
107819625d8cSopenharmony_ci
107919625d8cSopenharmony_ci        for raw_val in raw_vals {
108019625d8cSopenharmony_ci            // update the current index because each value is a distinct index to clap
108119625d8cSopenharmony_ci            self.cur_idx.set(self.cur_idx.get() + 1);
108219625d8cSopenharmony_ci            debug!(
108319625d8cSopenharmony_ci                "Parser::add_single_val_to_arg: cur_idx:={}",
108419625d8cSopenharmony_ci                self.cur_idx.get()
108519625d8cSopenharmony_ci            );
108619625d8cSopenharmony_ci            let value_parser = arg.get_value_parser();
108719625d8cSopenharmony_ci            let val = ok!(value_parser.parse_ref(self.cmd, Some(arg), &raw_val));
108819625d8cSopenharmony_ci
108919625d8cSopenharmony_ci            matcher.add_val_to(arg.get_id(), val, raw_val);
109019625d8cSopenharmony_ci            matcher.add_index_to(arg.get_id(), self.cur_idx.get());
109119625d8cSopenharmony_ci        }
109219625d8cSopenharmony_ci
109319625d8cSopenharmony_ci        Ok(())
109419625d8cSopenharmony_ci    }
109519625d8cSopenharmony_ci
109619625d8cSopenharmony_ci    fn resolve_pending(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
109719625d8cSopenharmony_ci        let pending = match matcher.take_pending() {
109819625d8cSopenharmony_ci            Some(pending) => pending,
109919625d8cSopenharmony_ci            None => {
110019625d8cSopenharmony_ci                return Ok(());
110119625d8cSopenharmony_ci            }
110219625d8cSopenharmony_ci        };
110319625d8cSopenharmony_ci
110419625d8cSopenharmony_ci        debug!("Parser::resolve_pending: id={:?}", pending.id);
110519625d8cSopenharmony_ci        let arg = self.cmd.find(&pending.id).expect(INTERNAL_ERROR_MSG);
110619625d8cSopenharmony_ci        let _ = ok!(self.react(
110719625d8cSopenharmony_ci            pending.ident,
110819625d8cSopenharmony_ci            ValueSource::CommandLine,
110919625d8cSopenharmony_ci            arg,
111019625d8cSopenharmony_ci            pending.raw_vals,
111119625d8cSopenharmony_ci            pending.trailing_idx,
111219625d8cSopenharmony_ci            matcher,
111319625d8cSopenharmony_ci        ));
111419625d8cSopenharmony_ci
111519625d8cSopenharmony_ci        Ok(())
111619625d8cSopenharmony_ci    }
111719625d8cSopenharmony_ci
111819625d8cSopenharmony_ci    fn react(
111919625d8cSopenharmony_ci        &self,
112019625d8cSopenharmony_ci        ident: Option<Identifier>,
112119625d8cSopenharmony_ci        source: ValueSource,
112219625d8cSopenharmony_ci        arg: &Arg,
112319625d8cSopenharmony_ci        mut raw_vals: Vec<OsString>,
112419625d8cSopenharmony_ci        mut trailing_idx: Option<usize>,
112519625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
112619625d8cSopenharmony_ci    ) -> ClapResult<ParseResult> {
112719625d8cSopenharmony_ci        ok!(self.resolve_pending(matcher));
112819625d8cSopenharmony_ci
112919625d8cSopenharmony_ci        debug!(
113019625d8cSopenharmony_ci            "Parser::react action={:?}, identifier={:?}, source={:?}",
113119625d8cSopenharmony_ci            arg.get_action(),
113219625d8cSopenharmony_ci            ident,
113319625d8cSopenharmony_ci            source
113419625d8cSopenharmony_ci        );
113519625d8cSopenharmony_ci
113619625d8cSopenharmony_ci        // Process before `default_missing_values` to avoid it counting as values from the command
113719625d8cSopenharmony_ci        // line
113819625d8cSopenharmony_ci        if source == ValueSource::CommandLine {
113919625d8cSopenharmony_ci            ok!(self.verify_num_args(arg, &raw_vals));
114019625d8cSopenharmony_ci        }
114119625d8cSopenharmony_ci
114219625d8cSopenharmony_ci        if raw_vals.is_empty() {
114319625d8cSopenharmony_ci            // We assume this case is valid: require equals, but min_vals == 0.
114419625d8cSopenharmony_ci            if !arg.default_missing_vals.is_empty() {
114519625d8cSopenharmony_ci                debug!("Parser::react: has default_missing_vals");
114619625d8cSopenharmony_ci                trailing_idx = None;
114719625d8cSopenharmony_ci                raw_vals.extend(
114819625d8cSopenharmony_ci                    arg.default_missing_vals
114919625d8cSopenharmony_ci                        .iter()
115019625d8cSopenharmony_ci                        .map(|s| s.as_os_str().to_owned()),
115119625d8cSopenharmony_ci                );
115219625d8cSopenharmony_ci            }
115319625d8cSopenharmony_ci        }
115419625d8cSopenharmony_ci
115519625d8cSopenharmony_ci        if let Some(val_delim) = arg.get_value_delimiter() {
115619625d8cSopenharmony_ci            if self.cmd.is_dont_delimit_trailing_values_set() && trailing_idx == Some(0) {
115719625d8cSopenharmony_ci                // Nothing to do
115819625d8cSopenharmony_ci            } else {
115919625d8cSopenharmony_ci                let mut split_raw_vals = Vec::with_capacity(raw_vals.len());
116019625d8cSopenharmony_ci                for (i, raw_val) in raw_vals.into_iter().enumerate() {
116119625d8cSopenharmony_ci                    let raw_val = RawOsString::new(raw_val);
116219625d8cSopenharmony_ci                    if !raw_val.contains(val_delim)
116319625d8cSopenharmony_ci                        || (self.cmd.is_dont_delimit_trailing_values_set()
116419625d8cSopenharmony_ci                            && trailing_idx == Some(i))
116519625d8cSopenharmony_ci                    {
116619625d8cSopenharmony_ci                        split_raw_vals.push(raw_val.into_os_string());
116719625d8cSopenharmony_ci                    } else {
116819625d8cSopenharmony_ci                        split_raw_vals
116919625d8cSopenharmony_ci                            .extend(raw_val.split(val_delim).map(|x| x.to_os_str().into_owned()));
117019625d8cSopenharmony_ci                    }
117119625d8cSopenharmony_ci                }
117219625d8cSopenharmony_ci                raw_vals = split_raw_vals
117319625d8cSopenharmony_ci            }
117419625d8cSopenharmony_ci        }
117519625d8cSopenharmony_ci
117619625d8cSopenharmony_ci        match arg.get_action() {
117719625d8cSopenharmony_ci            ArgAction::Set => {
117819625d8cSopenharmony_ci                if source == ValueSource::CommandLine
117919625d8cSopenharmony_ci                    && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
118019625d8cSopenharmony_ci                {
118119625d8cSopenharmony_ci                    // Record flag's index
118219625d8cSopenharmony_ci                    self.cur_idx.set(self.cur_idx.get() + 1);
118319625d8cSopenharmony_ci                    debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
118419625d8cSopenharmony_ci                }
118519625d8cSopenharmony_ci                if matcher.remove(arg.get_id())
118619625d8cSopenharmony_ci                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
118719625d8cSopenharmony_ci                {
118819625d8cSopenharmony_ci                    return Err(ClapError::argument_conflict(
118919625d8cSopenharmony_ci                        self.cmd,
119019625d8cSopenharmony_ci                        arg.to_string(),
119119625d8cSopenharmony_ci                        vec![arg.to_string()],
119219625d8cSopenharmony_ci                        Usage::new(self.cmd).create_usage_with_title(&[]),
119319625d8cSopenharmony_ci                    ));
119419625d8cSopenharmony_ci                }
119519625d8cSopenharmony_ci                self.start_custom_arg(matcher, arg, source);
119619625d8cSopenharmony_ci                ok!(self.push_arg_values(arg, raw_vals, matcher));
119719625d8cSopenharmony_ci                if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
119819625d8cSopenharmony_ci                    debug!(
119919625d8cSopenharmony_ci                        "Parser::react not enough values passed in, leaving it to the validator to complain",
120019625d8cSopenharmony_ci                    );
120119625d8cSopenharmony_ci                }
120219625d8cSopenharmony_ci                Ok(ParseResult::ValuesDone)
120319625d8cSopenharmony_ci            }
120419625d8cSopenharmony_ci            ArgAction::Append => {
120519625d8cSopenharmony_ci                if source == ValueSource::CommandLine
120619625d8cSopenharmony_ci                    && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
120719625d8cSopenharmony_ci                {
120819625d8cSopenharmony_ci                    // Record flag's index
120919625d8cSopenharmony_ci                    self.cur_idx.set(self.cur_idx.get() + 1);
121019625d8cSopenharmony_ci                    debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
121119625d8cSopenharmony_ci                }
121219625d8cSopenharmony_ci                self.start_custom_arg(matcher, arg, source);
121319625d8cSopenharmony_ci                ok!(self.push_arg_values(arg, raw_vals, matcher));
121419625d8cSopenharmony_ci                if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
121519625d8cSopenharmony_ci                    debug!(
121619625d8cSopenharmony_ci                        "Parser::react not enough values passed in, leaving it to the validator to complain",
121719625d8cSopenharmony_ci                    );
121819625d8cSopenharmony_ci                }
121919625d8cSopenharmony_ci                Ok(ParseResult::ValuesDone)
122019625d8cSopenharmony_ci            }
122119625d8cSopenharmony_ci            ArgAction::SetTrue => {
122219625d8cSopenharmony_ci                let raw_vals = if raw_vals.is_empty() {
122319625d8cSopenharmony_ci                    vec![OsString::from("true")]
122419625d8cSopenharmony_ci                } else {
122519625d8cSopenharmony_ci                    raw_vals
122619625d8cSopenharmony_ci                };
122719625d8cSopenharmony_ci
122819625d8cSopenharmony_ci                if matcher.remove(arg.get_id())
122919625d8cSopenharmony_ci                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
123019625d8cSopenharmony_ci                {
123119625d8cSopenharmony_ci                    return Err(ClapError::argument_conflict(
123219625d8cSopenharmony_ci                        self.cmd,
123319625d8cSopenharmony_ci                        arg.to_string(),
123419625d8cSopenharmony_ci                        vec![arg.to_string()],
123519625d8cSopenharmony_ci                        Usage::new(self.cmd).create_usage_with_title(&[]),
123619625d8cSopenharmony_ci                    ));
123719625d8cSopenharmony_ci                }
123819625d8cSopenharmony_ci                self.start_custom_arg(matcher, arg, source);
123919625d8cSopenharmony_ci                ok!(self.push_arg_values(arg, raw_vals, matcher));
124019625d8cSopenharmony_ci                Ok(ParseResult::ValuesDone)
124119625d8cSopenharmony_ci            }
124219625d8cSopenharmony_ci            ArgAction::SetFalse => {
124319625d8cSopenharmony_ci                let raw_vals = if raw_vals.is_empty() {
124419625d8cSopenharmony_ci                    vec![OsString::from("false")]
124519625d8cSopenharmony_ci                } else {
124619625d8cSopenharmony_ci                    raw_vals
124719625d8cSopenharmony_ci                };
124819625d8cSopenharmony_ci
124919625d8cSopenharmony_ci                if matcher.remove(arg.get_id())
125019625d8cSopenharmony_ci                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
125119625d8cSopenharmony_ci                {
125219625d8cSopenharmony_ci                    return Err(ClapError::argument_conflict(
125319625d8cSopenharmony_ci                        self.cmd,
125419625d8cSopenharmony_ci                        arg.to_string(),
125519625d8cSopenharmony_ci                        vec![arg.to_string()],
125619625d8cSopenharmony_ci                        Usage::new(self.cmd).create_usage_with_title(&[]),
125719625d8cSopenharmony_ci                    ));
125819625d8cSopenharmony_ci                }
125919625d8cSopenharmony_ci                self.start_custom_arg(matcher, arg, source);
126019625d8cSopenharmony_ci                ok!(self.push_arg_values(arg, raw_vals, matcher));
126119625d8cSopenharmony_ci                Ok(ParseResult::ValuesDone)
126219625d8cSopenharmony_ci            }
126319625d8cSopenharmony_ci            ArgAction::Count => {
126419625d8cSopenharmony_ci                let raw_vals = if raw_vals.is_empty() {
126519625d8cSopenharmony_ci                    let existing_value = *matcher
126619625d8cSopenharmony_ci                        .get_one::<crate::builder::CountType>(arg.get_id().as_str())
126719625d8cSopenharmony_ci                        .unwrap_or(&0);
126819625d8cSopenharmony_ci                    let next_value = existing_value.saturating_add(1);
126919625d8cSopenharmony_ci                    vec![OsString::from(next_value.to_string())]
127019625d8cSopenharmony_ci                } else {
127119625d8cSopenharmony_ci                    raw_vals
127219625d8cSopenharmony_ci                };
127319625d8cSopenharmony_ci
127419625d8cSopenharmony_ci                matcher.remove(arg.get_id());
127519625d8cSopenharmony_ci                self.start_custom_arg(matcher, arg, source);
127619625d8cSopenharmony_ci                ok!(self.push_arg_values(arg, raw_vals, matcher));
127719625d8cSopenharmony_ci                Ok(ParseResult::ValuesDone)
127819625d8cSopenharmony_ci            }
127919625d8cSopenharmony_ci            ArgAction::Help => {
128019625d8cSopenharmony_ci                let use_long = match ident {
128119625d8cSopenharmony_ci                    Some(Identifier::Long) => true,
128219625d8cSopenharmony_ci                    Some(Identifier::Short) => false,
128319625d8cSopenharmony_ci                    Some(Identifier::Index) => true,
128419625d8cSopenharmony_ci                    None => true,
128519625d8cSopenharmony_ci                };
128619625d8cSopenharmony_ci                debug!("Help: use_long={}", use_long);
128719625d8cSopenharmony_ci                Err(self.help_err(use_long))
128819625d8cSopenharmony_ci            }
128919625d8cSopenharmony_ci            ArgAction::Version => {
129019625d8cSopenharmony_ci                let use_long = match ident {
129119625d8cSopenharmony_ci                    Some(Identifier::Long) => true,
129219625d8cSopenharmony_ci                    Some(Identifier::Short) => false,
129319625d8cSopenharmony_ci                    Some(Identifier::Index) => true,
129419625d8cSopenharmony_ci                    None => true,
129519625d8cSopenharmony_ci                };
129619625d8cSopenharmony_ci                debug!("Version: use_long={}", use_long);
129719625d8cSopenharmony_ci                Err(self.version_err(use_long))
129819625d8cSopenharmony_ci            }
129919625d8cSopenharmony_ci        }
130019625d8cSopenharmony_ci    }
130119625d8cSopenharmony_ci
130219625d8cSopenharmony_ci    fn verify_num_args(&self, arg: &Arg, raw_vals: &[OsString]) -> ClapResult<()> {
130319625d8cSopenharmony_ci        if self.cmd.is_ignore_errors_set() {
130419625d8cSopenharmony_ci            return Ok(());
130519625d8cSopenharmony_ci        }
130619625d8cSopenharmony_ci
130719625d8cSopenharmony_ci        let actual = raw_vals.len();
130819625d8cSopenharmony_ci        let expected = arg.get_num_args().expect(INTERNAL_ERROR_MSG);
130919625d8cSopenharmony_ci
131019625d8cSopenharmony_ci        if 0 < expected.min_values() && actual == 0 {
131119625d8cSopenharmony_ci            // Issue 665 (https://github.com/clap-rs/clap/issues/665)
131219625d8cSopenharmony_ci            // Issue 1105 (https://github.com/clap-rs/clap/issues/1105)
131319625d8cSopenharmony_ci            return Err(ClapError::empty_value(
131419625d8cSopenharmony_ci                self.cmd,
131519625d8cSopenharmony_ci                &super::get_possible_values_cli(arg)
131619625d8cSopenharmony_ci                    .iter()
131719625d8cSopenharmony_ci                    .filter(|pv| !pv.is_hide_set())
131819625d8cSopenharmony_ci                    .map(|n| n.get_name().to_owned())
131919625d8cSopenharmony_ci                    .collect::<Vec<_>>(),
132019625d8cSopenharmony_ci                arg.to_string(),
132119625d8cSopenharmony_ci            ));
132219625d8cSopenharmony_ci        } else if let Some(expected) = expected.num_values() {
132319625d8cSopenharmony_ci            if expected != actual {
132419625d8cSopenharmony_ci                debug!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues");
132519625d8cSopenharmony_ci                return Err(ClapError::wrong_number_of_values(
132619625d8cSopenharmony_ci                    self.cmd,
132719625d8cSopenharmony_ci                    arg.to_string(),
132819625d8cSopenharmony_ci                    expected,
132919625d8cSopenharmony_ci                    actual,
133019625d8cSopenharmony_ci                    Usage::new(self.cmd).create_usage_with_title(&[]),
133119625d8cSopenharmony_ci                ));
133219625d8cSopenharmony_ci            }
133319625d8cSopenharmony_ci        } else if actual < expected.min_values() {
133419625d8cSopenharmony_ci            return Err(ClapError::too_few_values(
133519625d8cSopenharmony_ci                self.cmd,
133619625d8cSopenharmony_ci                arg.to_string(),
133719625d8cSopenharmony_ci                expected.min_values(),
133819625d8cSopenharmony_ci                actual,
133919625d8cSopenharmony_ci                Usage::new(self.cmd).create_usage_with_title(&[]),
134019625d8cSopenharmony_ci            ));
134119625d8cSopenharmony_ci        } else if expected.max_values() < actual {
134219625d8cSopenharmony_ci            debug!("Validator::validate_arg_num_vals: Sending error TooManyValues");
134319625d8cSopenharmony_ci            return Err(ClapError::too_many_values(
134419625d8cSopenharmony_ci                self.cmd,
134519625d8cSopenharmony_ci                raw_vals
134619625d8cSopenharmony_ci                    .last()
134719625d8cSopenharmony_ci                    .expect(INTERNAL_ERROR_MSG)
134819625d8cSopenharmony_ci                    .to_string_lossy()
134919625d8cSopenharmony_ci                    .into_owned(),
135019625d8cSopenharmony_ci                arg.to_string(),
135119625d8cSopenharmony_ci                Usage::new(self.cmd).create_usage_with_title(&[]),
135219625d8cSopenharmony_ci            ));
135319625d8cSopenharmony_ci        }
135419625d8cSopenharmony_ci
135519625d8cSopenharmony_ci        Ok(())
135619625d8cSopenharmony_ci    }
135719625d8cSopenharmony_ci
135819625d8cSopenharmony_ci    fn remove_overrides(&self, arg: &Arg, matcher: &mut ArgMatcher) {
135919625d8cSopenharmony_ci        debug!("Parser::remove_overrides: id={:?}", arg.id);
136019625d8cSopenharmony_ci        for override_id in &arg.overrides {
136119625d8cSopenharmony_ci            debug!("Parser::remove_overrides:iter:{:?}: removing", override_id);
136219625d8cSopenharmony_ci            matcher.remove(override_id);
136319625d8cSopenharmony_ci        }
136419625d8cSopenharmony_ci
136519625d8cSopenharmony_ci        // Override anything that can override us
136619625d8cSopenharmony_ci        let mut transitive = Vec::new();
136719625d8cSopenharmony_ci        for arg_id in matcher.arg_ids() {
136819625d8cSopenharmony_ci            if let Some(overrider) = self.cmd.find(arg_id) {
136919625d8cSopenharmony_ci                if overrider.overrides.contains(arg.get_id()) {
137019625d8cSopenharmony_ci                    transitive.push(overrider.get_id());
137119625d8cSopenharmony_ci                }
137219625d8cSopenharmony_ci            }
137319625d8cSopenharmony_ci        }
137419625d8cSopenharmony_ci        for overrider_id in transitive {
137519625d8cSopenharmony_ci            debug!("Parser::remove_overrides:iter:{:?}: removing", overrider_id);
137619625d8cSopenharmony_ci            matcher.remove(overrider_id);
137719625d8cSopenharmony_ci        }
137819625d8cSopenharmony_ci    }
137919625d8cSopenharmony_ci
138019625d8cSopenharmony_ci    #[cfg(feature = "env")]
138119625d8cSopenharmony_ci    fn add_env(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> {
138219625d8cSopenharmony_ci        debug!("Parser::add_env");
138319625d8cSopenharmony_ci
138419625d8cSopenharmony_ci        for arg in self.cmd.get_arguments() {
138519625d8cSopenharmony_ci            // Use env only if the arg was absent among command line args,
138619625d8cSopenharmony_ci            // early return if this is not the case.
138719625d8cSopenharmony_ci            if matcher.contains(&arg.id) {
138819625d8cSopenharmony_ci                debug!("Parser::add_env: Skipping existing arg `{}`", arg);
138919625d8cSopenharmony_ci                continue;
139019625d8cSopenharmony_ci            }
139119625d8cSopenharmony_ci
139219625d8cSopenharmony_ci            debug!("Parser::add_env: Checking arg `{}`", arg);
139319625d8cSopenharmony_ci            if let Some((_, Some(ref val))) = arg.env {
139419625d8cSopenharmony_ci                debug!("Parser::add_env: Found an opt with value={:?}", val);
139519625d8cSopenharmony_ci                let arg_values = vec![val.to_owned()];
139619625d8cSopenharmony_ci                let trailing_idx = None;
139719625d8cSopenharmony_ci                let _ = ok!(self.react(
139819625d8cSopenharmony_ci                    None,
139919625d8cSopenharmony_ci                    ValueSource::EnvVariable,
140019625d8cSopenharmony_ci                    arg,
140119625d8cSopenharmony_ci                    arg_values,
140219625d8cSopenharmony_ci                    trailing_idx,
140319625d8cSopenharmony_ci                    matcher,
140419625d8cSopenharmony_ci                ));
140519625d8cSopenharmony_ci            }
140619625d8cSopenharmony_ci        }
140719625d8cSopenharmony_ci
140819625d8cSopenharmony_ci        Ok(())
140919625d8cSopenharmony_ci    }
141019625d8cSopenharmony_ci
141119625d8cSopenharmony_ci    fn add_defaults(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
141219625d8cSopenharmony_ci        debug!("Parser::add_defaults");
141319625d8cSopenharmony_ci
141419625d8cSopenharmony_ci        for arg in self.cmd.get_arguments() {
141519625d8cSopenharmony_ci            debug!("Parser::add_defaults:iter:{}:", arg.get_id());
141619625d8cSopenharmony_ci            ok!(self.add_default_value(arg, matcher));
141719625d8cSopenharmony_ci        }
141819625d8cSopenharmony_ci
141919625d8cSopenharmony_ci        Ok(())
142019625d8cSopenharmony_ci    }
142119625d8cSopenharmony_ci
142219625d8cSopenharmony_ci    fn add_default_value(&self, arg: &Arg, matcher: &mut ArgMatcher) -> ClapResult<()> {
142319625d8cSopenharmony_ci        if !arg.default_vals_ifs.is_empty() {
142419625d8cSopenharmony_ci            debug!("Parser::add_default_value: has conditional defaults");
142519625d8cSopenharmony_ci            if !matcher.contains(arg.get_id()) {
142619625d8cSopenharmony_ci                for (id, val, default) in arg.default_vals_ifs.iter() {
142719625d8cSopenharmony_ci                    let add = if let Some(a) = matcher.get(id) {
142819625d8cSopenharmony_ci                        match val {
142919625d8cSopenharmony_ci                            crate::builder::ArgPredicate::Equals(v) => {
143019625d8cSopenharmony_ci                                a.raw_vals_flatten().any(|value| v == value)
143119625d8cSopenharmony_ci                            }
143219625d8cSopenharmony_ci                            crate::builder::ArgPredicate::IsPresent => true,
143319625d8cSopenharmony_ci                        }
143419625d8cSopenharmony_ci                    } else {
143519625d8cSopenharmony_ci                        false
143619625d8cSopenharmony_ci                    };
143719625d8cSopenharmony_ci
143819625d8cSopenharmony_ci                    if add {
143919625d8cSopenharmony_ci                        if let Some(default) = default {
144019625d8cSopenharmony_ci                            let arg_values = vec![default.to_os_string()];
144119625d8cSopenharmony_ci                            let trailing_idx = None;
144219625d8cSopenharmony_ci                            let _ = ok!(self.react(
144319625d8cSopenharmony_ci                                None,
144419625d8cSopenharmony_ci                                ValueSource::DefaultValue,
144519625d8cSopenharmony_ci                                arg,
144619625d8cSopenharmony_ci                                arg_values,
144719625d8cSopenharmony_ci                                trailing_idx,
144819625d8cSopenharmony_ci                                matcher,
144919625d8cSopenharmony_ci                            ));
145019625d8cSopenharmony_ci                        }
145119625d8cSopenharmony_ci                        return Ok(());
145219625d8cSopenharmony_ci                    }
145319625d8cSopenharmony_ci                }
145419625d8cSopenharmony_ci            }
145519625d8cSopenharmony_ci        } else {
145619625d8cSopenharmony_ci            debug!("Parser::add_default_value: doesn't have conditional defaults");
145719625d8cSopenharmony_ci        }
145819625d8cSopenharmony_ci
145919625d8cSopenharmony_ci        if !arg.default_vals.is_empty() {
146019625d8cSopenharmony_ci            debug!(
146119625d8cSopenharmony_ci                "Parser::add_default_value:iter:{}: has default vals",
146219625d8cSopenharmony_ci                arg.get_id()
146319625d8cSopenharmony_ci            );
146419625d8cSopenharmony_ci            if matcher.contains(arg.get_id()) {
146519625d8cSopenharmony_ci                debug!("Parser::add_default_value:iter:{}: was used", arg.get_id());
146619625d8cSopenharmony_ci            // do nothing
146719625d8cSopenharmony_ci            } else {
146819625d8cSopenharmony_ci                debug!(
146919625d8cSopenharmony_ci                    "Parser::add_default_value:iter:{}: wasn't used",
147019625d8cSopenharmony_ci                    arg.get_id()
147119625d8cSopenharmony_ci                );
147219625d8cSopenharmony_ci                let arg_values: Vec<_> = arg
147319625d8cSopenharmony_ci                    .default_vals
147419625d8cSopenharmony_ci                    .iter()
147519625d8cSopenharmony_ci                    .map(crate::builder::OsStr::to_os_string)
147619625d8cSopenharmony_ci                    .collect();
147719625d8cSopenharmony_ci                let trailing_idx = None;
147819625d8cSopenharmony_ci                let _ = ok!(self.react(
147919625d8cSopenharmony_ci                    None,
148019625d8cSopenharmony_ci                    ValueSource::DefaultValue,
148119625d8cSopenharmony_ci                    arg,
148219625d8cSopenharmony_ci                    arg_values,
148319625d8cSopenharmony_ci                    trailing_idx,
148419625d8cSopenharmony_ci                    matcher,
148519625d8cSopenharmony_ci                ));
148619625d8cSopenharmony_ci            }
148719625d8cSopenharmony_ci        } else {
148819625d8cSopenharmony_ci            debug!(
148919625d8cSopenharmony_ci                "Parser::add_default_value:iter:{}: doesn't have default vals",
149019625d8cSopenharmony_ci                arg.get_id()
149119625d8cSopenharmony_ci            );
149219625d8cSopenharmony_ci
149319625d8cSopenharmony_ci            // do nothing
149419625d8cSopenharmony_ci        }
149519625d8cSopenharmony_ci
149619625d8cSopenharmony_ci        Ok(())
149719625d8cSopenharmony_ci    }
149819625d8cSopenharmony_ci
149919625d8cSopenharmony_ci    fn start_custom_arg(&self, matcher: &mut ArgMatcher, arg: &Arg, source: ValueSource) {
150019625d8cSopenharmony_ci        if source == ValueSource::CommandLine {
150119625d8cSopenharmony_ci            // With each new occurrence, remove overrides from prior occurrences
150219625d8cSopenharmony_ci            self.remove_overrides(arg, matcher);
150319625d8cSopenharmony_ci        }
150419625d8cSopenharmony_ci        matcher.start_custom_arg(arg, source);
150519625d8cSopenharmony_ci        if source.is_explicit() {
150619625d8cSopenharmony_ci            for group in self.cmd.groups_for_arg(arg.get_id()) {
150719625d8cSopenharmony_ci                matcher.start_custom_group(group.clone(), source);
150819625d8cSopenharmony_ci                matcher.add_val_to(
150919625d8cSopenharmony_ci                    &group,
151019625d8cSopenharmony_ci                    AnyValue::new(arg.get_id().clone()),
151119625d8cSopenharmony_ci                    OsString::from(arg.get_id().as_str()),
151219625d8cSopenharmony_ci                );
151319625d8cSopenharmony_ci            }
151419625d8cSopenharmony_ci        }
151519625d8cSopenharmony_ci    }
151619625d8cSopenharmony_ci}
151719625d8cSopenharmony_ci
151819625d8cSopenharmony_ci// Error, Help, and Version Methods
151919625d8cSopenharmony_ciimpl<'cmd> Parser<'cmd> {
152019625d8cSopenharmony_ci    /// Is only used for the long flag(which is the only one needs fuzzy searching)
152119625d8cSopenharmony_ci    fn did_you_mean_error(
152219625d8cSopenharmony_ci        &mut self,
152319625d8cSopenharmony_ci        arg: &str,
152419625d8cSopenharmony_ci        matcher: &mut ArgMatcher,
152519625d8cSopenharmony_ci        remaining_args: &[&OsStr],
152619625d8cSopenharmony_ci        trailing_values: bool,
152719625d8cSopenharmony_ci    ) -> ClapError {
152819625d8cSopenharmony_ci        debug!("Parser::did_you_mean_error: arg={}", arg);
152919625d8cSopenharmony_ci        // Didn't match a flag or option
153019625d8cSopenharmony_ci        let longs = self
153119625d8cSopenharmony_ci            .cmd
153219625d8cSopenharmony_ci            .get_keymap()
153319625d8cSopenharmony_ci            .keys()
153419625d8cSopenharmony_ci            .filter_map(|x| match x {
153519625d8cSopenharmony_ci                KeyType::Long(l) => Some(l.to_string_lossy().into_owned()),
153619625d8cSopenharmony_ci                _ => None,
153719625d8cSopenharmony_ci            })
153819625d8cSopenharmony_ci            .collect::<Vec<_>>();
153919625d8cSopenharmony_ci        debug!("Parser::did_you_mean_error: longs={:?}", longs);
154019625d8cSopenharmony_ci
154119625d8cSopenharmony_ci        let did_you_mean = suggestions::did_you_mean_flag(
154219625d8cSopenharmony_ci            arg,
154319625d8cSopenharmony_ci            remaining_args,
154419625d8cSopenharmony_ci            longs.iter().map(|x| &x[..]),
154519625d8cSopenharmony_ci            self.cmd.get_subcommands_mut(),
154619625d8cSopenharmony_ci        );
154719625d8cSopenharmony_ci
154819625d8cSopenharmony_ci        // Add the arg to the matches to build a proper usage string
154919625d8cSopenharmony_ci        if let Some((name, _)) = did_you_mean.as_ref() {
155019625d8cSopenharmony_ci            if let Some(arg) = self.cmd.get_keymap().get(&name.as_ref()) {
155119625d8cSopenharmony_ci                self.start_custom_arg(matcher, arg, ValueSource::CommandLine);
155219625d8cSopenharmony_ci            }
155319625d8cSopenharmony_ci        }
155419625d8cSopenharmony_ci
155519625d8cSopenharmony_ci        let required = self.cmd.required_graph();
155619625d8cSopenharmony_ci        let used: Vec<Id> = matcher
155719625d8cSopenharmony_ci            .arg_ids()
155819625d8cSopenharmony_ci            .filter(|arg_id| {
155919625d8cSopenharmony_ci                matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
156019625d8cSopenharmony_ci            })
156119625d8cSopenharmony_ci            .filter(|n| self.cmd.find(n).map_or(true, |a| !a.is_hide_set()))
156219625d8cSopenharmony_ci            .cloned()
156319625d8cSopenharmony_ci            .collect();
156419625d8cSopenharmony_ci
156519625d8cSopenharmony_ci        // `did_you_mean` is a lot more likely and should cause us to skip the `--` suggestion
156619625d8cSopenharmony_ci        //
156719625d8cSopenharmony_ci        // In theory, this is only called for `--long`s, so we don't need to check
156819625d8cSopenharmony_ci        let suggested_trailing_arg =
156919625d8cSopenharmony_ci            did_you_mean.is_none() && !trailing_values && self.cmd.has_positionals();
157019625d8cSopenharmony_ci        ClapError::unknown_argument(
157119625d8cSopenharmony_ci            self.cmd,
157219625d8cSopenharmony_ci            format!("--{arg}"),
157319625d8cSopenharmony_ci            did_you_mean,
157419625d8cSopenharmony_ci            suggested_trailing_arg,
157519625d8cSopenharmony_ci            Usage::new(self.cmd)
157619625d8cSopenharmony_ci                .required(&required)
157719625d8cSopenharmony_ci                .create_usage_with_title(&used),
157819625d8cSopenharmony_ci        )
157919625d8cSopenharmony_ci    }
158019625d8cSopenharmony_ci
158119625d8cSopenharmony_ci    fn help_err(&self, use_long: bool) -> ClapError {
158219625d8cSopenharmony_ci        let styled = self.cmd.write_help_err(use_long);
158319625d8cSopenharmony_ci        ClapError::display_help(self.cmd, styled)
158419625d8cSopenharmony_ci    }
158519625d8cSopenharmony_ci
158619625d8cSopenharmony_ci    fn version_err(&self, use_long: bool) -> ClapError {
158719625d8cSopenharmony_ci        let styled = self.cmd.write_version_err(use_long);
158819625d8cSopenharmony_ci        ClapError::display_version(self.cmd, styled)
158919625d8cSopenharmony_ci    }
159019625d8cSopenharmony_ci}
159119625d8cSopenharmony_ci
159219625d8cSopenharmony_ci#[derive(Debug, PartialEq, Eq)]
159319625d8cSopenharmony_cipub(crate) enum ParseState {
159419625d8cSopenharmony_ci    ValuesDone,
159519625d8cSopenharmony_ci    Opt(Id),
159619625d8cSopenharmony_ci    Pos(Id),
159719625d8cSopenharmony_ci}
159819625d8cSopenharmony_ci
159919625d8cSopenharmony_ci/// Recoverable Parsing results.
160019625d8cSopenharmony_ci#[derive(Debug, PartialEq, Clone)]
160119625d8cSopenharmony_ci#[must_use]
160219625d8cSopenharmony_cienum ParseResult {
160319625d8cSopenharmony_ci    FlagSubCommand(String),
160419625d8cSopenharmony_ci    Opt(Id),
160519625d8cSopenharmony_ci    ValuesDone,
160619625d8cSopenharmony_ci    /// Value attached to the short flag is not consumed(e.g. 'u' for `-cu` is
160719625d8cSopenharmony_ci    /// not consumed).
160819625d8cSopenharmony_ci    AttachedValueNotConsumed,
160919625d8cSopenharmony_ci    /// This long flag doesn't need a value but is provided one.
161019625d8cSopenharmony_ci    UnneededAttachedValue {
161119625d8cSopenharmony_ci        rest: String,
161219625d8cSopenharmony_ci        used: Vec<Id>,
161319625d8cSopenharmony_ci        arg: String,
161419625d8cSopenharmony_ci    },
161519625d8cSopenharmony_ci    /// This flag might be an hyphen Value.
161619625d8cSopenharmony_ci    MaybeHyphenValue,
161719625d8cSopenharmony_ci    /// Equals required but not provided.
161819625d8cSopenharmony_ci    EqualsNotProvided {
161919625d8cSopenharmony_ci        arg: String,
162019625d8cSopenharmony_ci    },
162119625d8cSopenharmony_ci    /// Failed to match a Arg.
162219625d8cSopenharmony_ci    NoMatchingArg {
162319625d8cSopenharmony_ci        arg: String,
162419625d8cSopenharmony_ci    },
162519625d8cSopenharmony_ci    /// No argument found e.g. parser is given `-` when parsing a flag.
162619625d8cSopenharmony_ci    NoArg,
162719625d8cSopenharmony_ci}
162819625d8cSopenharmony_ci
162919625d8cSopenharmony_ci#[derive(Clone, Debug, PartialEq, Eq)]
163019625d8cSopenharmony_cipub(crate) struct PendingArg {
163119625d8cSopenharmony_ci    pub(crate) id: Id,
163219625d8cSopenharmony_ci    pub(crate) ident: Option<Identifier>,
163319625d8cSopenharmony_ci    pub(crate) raw_vals: Vec<OsString>,
163419625d8cSopenharmony_ci    pub(crate) trailing_idx: Option<usize>,
163519625d8cSopenharmony_ci}
163619625d8cSopenharmony_ci
163719625d8cSopenharmony_ci#[derive(Copy, Clone, Debug, PartialEq, Eq)]
163819625d8cSopenharmony_cipub(crate) enum Identifier {
163919625d8cSopenharmony_ci    Short,
164019625d8cSopenharmony_ci    Long,
164119625d8cSopenharmony_ci    Index,
164219625d8cSopenharmony_ci}
1643