options: add key/value pair list option type

This commit is contained in:
wm4 2014-01-16 23:03:40 +01:00
parent 68f46675bc
commit 82067e6ac3
2 changed files with 69 additions and 0 deletions

View File

@ -1145,6 +1145,70 @@ const m_option_type_t m_option_type_string_list = {
.free = free_str_list,
};
static int read_subparam(struct mp_log *log, bstr optname,
bstr *str, bstr *out_subparam);
static int parse_keyvalue_list(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst)
{
char **lst = NULL;
int num = 0;
int r = 0;
while (param.len) {
bstr key, val;
r = read_subparam(log, name, &param, &key);
if (r < 0)
break;
if (!bstr_eatstart0(&param, "=")) {
mp_err(log, "Expected '=' and a value.\n");
r = M_OPT_INVALID;
break;
}
r = read_subparam(log, name, &param, &val);
if (r < 0)
break;
MP_TARRAY_APPEND(NULL, lst, num, bstrto0(NULL, key));
MP_TARRAY_APPEND(NULL, lst, num, bstrto0(NULL, val));
if (!bstr_eatstart0(&param, ","))
break;
}
MP_TARRAY_APPEND(NULL, lst, num, NULL);
if (param.len) {
mp_err(log, "Unparseable garbage at end of option value: '%.*s'\n",
BSTR_P(param));
r = M_OPT_INVALID;
}
VAL(dst) = lst;
if (r < 0)
free_str_list(dst);
return r;
}
static char *print_keyvalue_list(const m_option_t *opt, const void *src)
{
char **lst = VAL(src);
char *ret = talloc_strdup(NULL, "");
for (int n = 0; lst && lst[n] && lst[n + 1]; n += 2) {
if (ret[0])
ret = talloc_strdup_append(ret, ",");
ret = talloc_asprintf_append("%s%s=%s", ret, lst[n], lst[n + 1]);
}
return ret;
}
const m_option_type_t m_option_type_keyvalue_list = {
.name = "Key/value list",
.size = sizeof(char **),
.flags = M_OPT_TYPE_DYNAMIC,
.parse = parse_keyvalue_list,
.print = print_keyvalue_list,
.copy = copy_str_list,
.free = free_str_list,
};
/////////////////// Print

View File

@ -46,6 +46,7 @@ extern const m_option_type_t m_option_type_float;
extern const m_option_type_t m_option_type_double;
extern const m_option_type_t m_option_type_string;
extern const m_option_type_t m_option_type_string_list;
extern const m_option_type_t m_option_type_keyvalue_list;
extern const m_option_type_t m_option_type_time;
extern const m_option_type_t m_option_type_rel_time;
extern const m_option_type_t m_option_type_choice;
@ -199,6 +200,7 @@ union m_option_value {
double double_;
char *string;
char **string_list;
char **keyvalue_list;
int imgfmt;
unsigned int fourcc;
int afmt;
@ -534,6 +536,9 @@ extern const char m_option_path_separator;
#define OPT_STRINGLIST(...) \
OPT_GENERAL(char**, __VA_ARGS__, .type = &m_option_type_string_list)
#define OPT_KEYVALUELIST(...) \
OPT_GENERAL(char**, __VA_ARGS__, .type = &m_option_type_keyvalue_list)
#define OPT_PATHLIST(...) \
OPT_GENERAL(char**, __VA_ARGS__, .type = &m_option_type_string_list, \
.priv = (void *)&m_option_path_separator)