mirror of https://github.com/mpv-player/mpv
options: simplify somewhat by introducing a union for option values
The m_option_value union is supposed to contain a field for each possible option type (as long as it actually stores data). This helps avoiding silly temporary memory alocations. Using a pointer to an union and to a field of the union interchangeably should be allowed by standard C.
This commit is contained in:
parent
7fe56f1602
commit
bfc3dbae88
11
m_config.c
11
m_config.c
|
@ -334,15 +334,14 @@ static void m_config_add_option(struct m_config *config,
|
|||
} else if (arg->type->flags & M_OPT_TYPE_DYNAMIC) {
|
||||
// Initialize dynamically managed fields from static data (like
|
||||
// string options): copy the option into temporary memory,
|
||||
// clear the original option (to void m_option freeing the
|
||||
// clear the original option (to stop m_option from freeing the
|
||||
// static data), copy it back.
|
||||
if (co->data) {
|
||||
void *temp = talloc_zero_size(NULL, arg->type->size);
|
||||
m_option_copy(arg, temp, co->data);
|
||||
union m_option_value temp = {0};
|
||||
m_option_copy(arg, &temp, co->data);
|
||||
memset(co->data, 0, arg->type->size);
|
||||
m_option_copy(arg, co->data, temp);
|
||||
m_option_free(arg, temp);
|
||||
talloc_free(temp);
|
||||
m_option_copy(arg, co->data, &temp);
|
||||
m_option_free(arg, &temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
19
m_option.h
19
m_option.h
|
@ -178,6 +178,25 @@ struct m_sub_options {
|
|||
#define CONF_TYPE_TIME (&m_option_type_time)
|
||||
#define CONF_TYPE_TIME_SIZE (&m_option_type_time_size)
|
||||
|
||||
// Possible option values. Code is allowed to access option data without going
|
||||
// through this union. It serves for self-documentation and to get minimal
|
||||
// size/alignment requirements for option values in general.
|
||||
union m_option_value {
|
||||
int flag; // not the C type "bool"!
|
||||
int int_;
|
||||
int64_t int64;
|
||||
float float_;
|
||||
double double_;
|
||||
char *string;
|
||||
char **string_list;
|
||||
int imgfmt;
|
||||
int afmt;
|
||||
m_span_t span;
|
||||
m_obj_settings_t *obj_settings_list;
|
||||
double time;
|
||||
m_time_size_t time_size;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Option type description
|
||||
|
|
20
m_property.c
20
m_property.c
|
@ -69,7 +69,7 @@ int m_property_do(const m_option_t *prop_list, const char *name,
|
|||
int action, void *arg, void *ctx)
|
||||
{
|
||||
const m_option_t *opt;
|
||||
void *val;
|
||||
union m_option_value val = {0};
|
||||
int r;
|
||||
|
||||
switch (action) {
|
||||
|
@ -85,15 +85,11 @@ int m_property_do(const m_option_t *prop_list, const char *name,
|
|||
if ((r =
|
||||
do_action(prop_list, name, M_PROPERTY_GET_TYPE, &opt, ctx)) <= 0)
|
||||
return r;
|
||||
val = calloc(1, opt->type->size);
|
||||
if ((r = do_action(prop_list, name, M_PROPERTY_GET, val, ctx)) <= 0) {
|
||||
free(val);
|
||||
if ((r = do_action(prop_list, name, M_PROPERTY_GET, &val, ctx)) <= 0)
|
||||
return r;
|
||||
}
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
char *str = m_option_print(opt, val);
|
||||
free(val);
|
||||
char *str = m_option_print(opt, &val);
|
||||
*(char **)arg = str;
|
||||
return str != NULL;
|
||||
case M_PROPERTY_PARSE:
|
||||
|
@ -107,14 +103,10 @@ int m_property_do(const m_option_t *prop_list, const char *name,
|
|||
return r;
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
val = calloc(1, opt->type->size);
|
||||
if ((r = m_option_parse(opt, bstr0(opt->name), bstr0(arg), val)) <= 0) {
|
||||
free(val);
|
||||
if ((r = m_option_parse(opt, bstr0(opt->name), bstr0(arg), &val)) <= 0)
|
||||
return r;
|
||||
}
|
||||
r = do_action(prop_list, name, M_PROPERTY_SET, val, ctx);
|
||||
m_option_free(opt, val);
|
||||
free(val);
|
||||
r = do_action(prop_list, name, M_PROPERTY_SET, &val, ctx);
|
||||
m_option_free(opt, &val);
|
||||
return r;
|
||||
}
|
||||
return do_action(prop_list, name, action, arg, ctx);
|
||||
|
|
Loading…
Reference in New Issue