diff options
author | wm4 <wm4@nowhere> | 2012-09-24 21:57:43 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2012-10-12 10:10:32 +0200 |
commit | 88849fd1d4056bc22305cc4433dc56360dd6d0e9 (patch) | |
tree | d444c8533404a303a07e36c288474d7d927457f9 /input | |
parent | a441cd3eeb9291e20d5a8052d32ce8180b017763 (diff) |
commands: add choice type to input commands
Allow using the choice type (as it used for command line) for arguments
of input commands. Change the magic integer arguments of some commands
(like seek) to use choices instead. The old numeric values are still
allowed (but only those which made sense before, not arbitrary
integers).
In order to do this, remove the input.c specific types (like
MP_CMD_ARG_INT) completely and specify commands using the m_option
types.
Also, add the special choice "-" to some arguments. It's supposed to
signify the default value, so arguments can be easily skipped. Maybe the
choice option should recognize this and not change the previous value,
but we'll leave this for later.
For now, leave compatibility integer values for all new choice
arguments, e.g. "0" maps to 0. We could let the choice option type do
this automatically, but we don't, because we want user input values and
internal mplayer values decoupled in general. The compatibility options
will be removed one day, too.
Also, remove optional args for strings - would require either annoying
additional code, or copying strings twice. It's not used, so remove it.
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; |