diff --git a/input/cmd.c b/input/cmd.c index 64232143f7644..3a26e2f792cbd 100644 --- a/input/cmd.c +++ b/input/cmd.c @@ -416,6 +416,19 @@ static struct mp_cmd *parse_cmd_str(struct mp_log *log, void *tmp, struct mp_cmd_arg arg = {.type = opt}; r = m_option_parse(ctx->log, opt, bstr0(cmd->name), cur_token, &arg.v); + + // Try to read the next cmd arg instead. + while (r < 0 && opt->skippable) { + assert(i + 1 < MP_CMD_MAX_ARGS); + ++i; + arg.skipped = true; + opt = get_arg_type(cmd->def, i); + if (!opt) + break; + arg.type = opt; + r = m_option_parse(ctx->log, opt, bstr0(cmd->name), cur_token, &arg.v); + } + if (r < 0) { MP_ERR(ctx, "Command %s: argument %d can't be parsed: %s.\n", cmd->name, i + 1, m_option_strerror(r)); diff --git a/input/cmd.h b/input/cmd.h index 3d4b15fcc3ee4..0efbf0558ab96 100644 --- a/input/cmd.h +++ b/input/cmd.h @@ -94,6 +94,7 @@ struct mp_cmd_arg { char **str_list; void *p; } v; + bool skipped; }; typedef struct mp_cmd { diff --git a/options/m_option.c b/options/m_option.c index 02dea2bf3c7cb..2ca3034d8dd9d 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -71,7 +71,12 @@ int m_option_parse(struct mp_log *log, const m_option_t *opt, return r; } + // Silence log on skippable options + int old_log_level = mp_msg_level(log); + mp_msg_set_max_level(log, -1); r = opt->type->parse(log, opt, name, param, dst); + mp_msg_set_max_level(log, old_log_level); + if (r < 0) return r; diff --git a/options/m_option.h b/options/m_option.h index 891b51794e1e1..4c339b41bfda8 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -384,6 +384,9 @@ struct m_option { // See \ref OptionFlags. unsigned int flags; + // Only for use with commands + bool skippable; + int offset; // Most numeric types restrict the range to [min, max] if minmpctx; char *filename = cmd->args[0].v.s; int action_flag = cmd->args[1].v.i; - int insert_at_idx = cmd->args[2].v.i; + int insert_at_idx = -1; + char **pairs; + + if (cmd->args[2].skipped) { + pairs = cmd->args[2].v.str_list; + } else { + insert_at_idx = cmd->args[2].v.i; + pairs = cmd->args[3].v.str_list; + } struct load_action action = get_load_action(mpctx, action_flag); @@ -5591,8 +5599,7 @@ static void cmd_loadfile(void *p) playlist_clear(mpctx->playlist); struct playlist_entry *entry = playlist_entry_new(filename); - if (cmd->args[3].v.str_list) { - char **pairs = cmd->args[3].v.str_list; + if (pairs) { for (int i = 0; pairs[i] && pairs[i + 1]; i += 2) playlist_entry_add_param(entry, bstr0(pairs[i]), bstr0(pairs[i + 1])); } @@ -6769,7 +6776,7 @@ const struct mp_cmd_def mp_cmds[] = { {"insert-at", 5}, {"insert-at-play", 6}), .flags = MP_CMD_OPT_ARG}, - {"index", OPT_INT(v.i), OPTDEF_INT(-1)}, + {"index", OPT_INT(v.i), .flags = MP_CMD_OPT_ARG, .skippable = true}, {"options", OPT_KEYVALUELIST(v.str_list), .flags = MP_CMD_OPT_ARG}, }, },