diff options
Diffstat (limited to 'input')
-rw-r--r-- | input/input.c | 106 | ||||
-rw-r--r-- | input/input.h | 8 |
2 files changed, 64 insertions, 50 deletions
diff --git a/input/input.c b/input/input.c index b5b9c4ce1b..a1ab808125 100644 --- a/input/input.c +++ b/input/input.c @@ -85,12 +85,20 @@ struct key_name { * argument value if the user didn't give enough arguments to specify it. * A command can take a maximum of MP_CMD_MAX_ARGS arguments (10). */ -#define ARG_INT { .type = MP_CMD_ARG_INT } -#define OARG_INT(def) { .type = MP_CMD_ARG_INT, .optional = true, .v.i = def } -#define ARG_FLOAT { .type = MP_CMD_ARG_FLOAT } -#define OARG_FLOAT(def) { .type = MP_CMD_ARG_FLOAT, .optional = true, .v.f = def } -#define ARG_STRING { .type = MP_CMD_ARG_STRING } -#define OARG_STRING(def) { .type = MP_CMD_ARG_STRING, .optional = true, .v.s = def } + +#define ARG_INT { .type = {"", NULL, &m_option_type_int} } +#define ARG_FLOAT { .type = {"", NULL, &m_option_type_float} } +#define ARG_STRING { .type = {"", NULL, &m_option_type_string} } +#define ARG_CHOICE(c) { .type = {"", NULL, &m_option_type_choice, \ + M_CHOICES(c)} } + +#define OARG_FLOAT(def) { .type = {"", NULL, &m_option_type_float}, \ + .optional = true, .v.f = def } +#define OARG_INT(def) { .type = {"", NULL, &m_option_type_int}, \ + .optional = true, .v.i = def } +#define OARG_CHOICE(def, c) { .type = {"", NULL, &m_option_type_choice, \ + M_CHOICES(c)}, \ + .optional = true, .v.i = def } static const mp_cmd_t mp_cmds[] = { { MP_CMD_IGNORE, "ignore", }, @@ -100,14 +108,28 @@ static const mp_cmd_t mp_cmds[] = { { MP_CMD_RADIO_SET_FREQ, "radio_set_freq", { ARG_FLOAT } }, { MP_CMD_RADIO_STEP_FREQ, "radio_step_freq", {ARG_FLOAT } }, #endif - { MP_CMD_SEEK, "seek", { ARG_FLOAT, OARG_INT(0), OARG_INT(0) } }, + { MP_CMD_SEEK, "seek", { + ARG_FLOAT, + OARG_CHOICE(0, ({"relative", 0}, {"0", 0}, + {"absolute-percent", 1}, {"1", 1}, + {"absolute", 2}, {"2", 2})), + OARG_CHOICE(0, ({"default-precise", 0}, {"0", 0}, + {"exact", 1}, {"1", 1}, + {"keyframes", -1}, {"-1", -1})), + }}, { MP_CMD_EDL_MARK, "edl_mark", }, { MP_CMD_SPEED_MULT, "speed_mult", { ARG_FLOAT } }, { MP_CMD_QUIT, "quit", { OARG_INT(0) } }, { MP_CMD_STOP, "stop", }, { MP_CMD_FRAME_STEP, "frame_step", }, - { MP_CMD_PLAYLIST_NEXT, "playlist_next", { OARG_INT(0) } }, - { MP_CMD_PLAYLIST_PREV, "playlist_prev", { OARG_INT(0) } }, + { MP_CMD_PLAYLIST_NEXT, "playlist_next", { + OARG_CHOICE(0, ({"weak", 0}, {"0", 0}, + {"force", 1}, {"1", 1})), + }}, + { MP_CMD_PLAYLIST_PREV, "playlist_prev", { + OARG_CHOICE(0, ({"weak", 0}, {"0", 0}, + {"force", 1}, {"1", 1})), + }}, { MP_CMD_SUB_STEP, "sub_step", { ARG_INT, OARG_INT(0) } }, { MP_CMD_OSD, "osd", { OARG_INT(-1) } }, { MP_CMD_SHOW_TEXT, "show_text", { ARG_STRING, OARG_INT(-1), OARG_INT(0) } }, @@ -127,9 +149,22 @@ static const mp_cmd_t mp_cmds[] = { #ifdef CONFIG_DVBIN { MP_CMD_DVB_SET_CHANNEL, "dvb_set_channel", { ARG_INT, ARG_INT } }, #endif - { MP_CMD_SCREENSHOT, "screenshot", { OARG_INT(0), OARG_INT(0) } }, - { MP_CMD_LOADFILE, "loadfile", { ARG_STRING, OARG_INT(0) } }, - { MP_CMD_LOADLIST, "loadlist", { ARG_STRING, OARG_INT(0) } }, + { MP_CMD_SCREENSHOT, "screenshot", { + OARG_CHOICE(0, ({"single", 0}, {"0", 0}, + {"each-frame", 1}, {"1", 1})), + OARG_CHOICE(0, ({"video", 0}, {"0", 0}, + {"window", 1}, {"1", 1})), + }}, + { MP_CMD_LOADFILE, "loadfile", { + ARG_STRING, + OARG_CHOICE(0, ({"replace", 0}, {"0", 0}, + {"append", 1}, {"1", 1})), + }}, + { MP_CMD_LOADLIST, "loadlist", { + ARG_STRING, + OARG_CHOICE(0, ({"replace", 0}, {"0", 0}, + {"append", 1}, {"1", 1})), + }}, { MP_CMD_PLAYLIST_CLEAR, "playlist_clear", }, { MP_CMD_RUN, "run", { ARG_STRING } }, @@ -838,11 +873,13 @@ mp_cmd_t *mp_input_parse_cmd(bstr str) cmd->on_osd = on_osd; for (int i = 0; i < MP_CMD_MAX_ARGS; i++) { - if (!cmd->args[i].type) + struct mp_cmd_arg *cmdarg = &cmd->args[i]; + if (!cmdarg->type.type) break; + cmd->nargs++; str = bstr_lstrip(str); bstr arg = {0}; - if (cmd->args[i].type == MP_CMD_ARG_STRING && + if (cmdarg->type.type == &m_option_type_string && bstr_eatstart0(&str, "\"")) { if (!read_escaped_string(tmp, &str, &arg)) { @@ -858,26 +895,20 @@ mp_cmd_t *mp_input_parse_cmd(bstr str) } else { if (!read_token(str, &str, &arg)) break; + if (cmdarg->optional && bstrcmp0(arg, "-") == 0) + continue; } // Prevent option API from trying to deallocate static strings - cmd->args[i].v = ((struct mp_cmd_arg) {0}).v; - struct m_option opt = {0}; - switch (cmd->args[i].type) { - case MP_CMD_ARG_INT: opt.type = &m_option_type_int; break; - case MP_CMD_ARG_FLOAT: opt.type = &m_option_type_float; break; - case MP_CMD_ARG_STRING: opt.type = &m_option_type_string; break; - default: abort(); - } - int r = m_option_parse(&opt, bstr0(cmd->name), arg, &cmd->args[i].v); + cmdarg->v = ((struct mp_cmd_arg) {{0}}).v; + int r = m_option_parse(&cmdarg->type, bstr0(cmd->name), arg, &cmdarg->v); if (r < 0) { mp_tmsg(MSGT_INPUT, MSGL_ERR, "Command %s: argument %d " "can't be parsed: %s.\n", cmd->name, i + 1, m_option_strerror(r)); goto error; } - if (opt.type == &m_option_type_string) - cmd->args[i].v.s = talloc_steal(cmd, cmd->args[i].v.s); - cmd->nargs++; + if (cmdarg->type.type == &m_option_type_string) + cmdarg->v.s = talloc_steal(cmd, cmdarg->v.s); } bstr dummy; @@ -889,7 +920,7 @@ mp_cmd_t *mp_input_parse_cmd(bstr str) } int min_args = 0; - while (min_args < MP_CMD_MAX_ARGS && cmd->args[min_args].type + while (min_args < MP_CMD_MAX_ARGS && cmd->args[min_args].type.type && !cmd->args[min_args].optional) { min_args++; @@ -1424,8 +1455,8 @@ mp_cmd_t *mp_cmd_clone(mp_cmd_t *cmd) ret = talloc_memdup(NULL, cmd, sizeof(mp_cmd_t)); ret->name = talloc_strdup(ret, cmd->name); - for (i = 0; i < MP_CMD_MAX_ARGS && cmd->args[i].type; i++) { - if (cmd->args[i].type == MP_CMD_ARG_STRING && cmd->args[i].v.s != NULL) + for (i = 0; i < MP_CMD_MAX_ARGS; i++) { + if (cmd->args[i].type.type == &m_option_type_string) ret->args[i].v.s = talloc_strdup(ret, cmd->args[i].v.s); } @@ -1771,24 +1802,11 @@ static int print_cmd_list(m_option_t *cfg, char *optname, char *optparam) { const mp_cmd_t *cmd; int i, j; - const char *type; for (i = 0; (cmd = &mp_cmds[i])->name != NULL; i++) { printf("%-20.20s", cmd->name); - for (j = 0; j < MP_CMD_MAX_ARGS && cmd->args[j].type; j++) { - switch (cmd->args[j].type) { - case MP_CMD_ARG_INT: - type = "Integer"; - break; - case MP_CMD_ARG_FLOAT: - type = "Float"; - break; - case MP_CMD_ARG_STRING: - type = "String"; - break; - default: - type = "??"; - } + for (j = 0; j < MP_CMD_MAX_ARGS && cmd->args[j].type.type; j++) { + const char *type = cmd->args[j].type.type->name; if (cmd->args[j].optional) printf(" [%s]", type); else diff --git a/input/input.h b/input/input.h index 4823ab75f0..e4eb0a8d32 100644 --- a/input/input.h +++ b/input/input.h @@ -21,6 +21,7 @@ #include <stdbool.h> #include "bstr.h" +#include "m_option.h" // All command IDs enum mp_command_type { @@ -80,11 +81,6 @@ enum mp_command_type { MP_CMD_VO_CMDLINE, }; -// The arg types -#define MP_CMD_ARG_INT 1 -#define MP_CMD_ARG_FLOAT 2 -#define MP_CMD_ARG_STRING 3 - #define MP_CMD_MAX_ARGS 10 // Error codes for the drivers @@ -115,7 +111,7 @@ enum mp_input_section_flags { struct input_ctx; struct mp_cmd_arg { - int type; + struct m_option type; bool optional; union { int i; |