From 3d67041089c7945dcea0162c0038e495d588b379 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Sep 2012 11:48:50 +0200 Subject: options: remove CONF_TYPE_POSITION This was the option parser for the off_t C type. These days, off_t is always int64_t, so replace all its uses by int64_t and CONF_TYPE_INT64. Fix the --sstep option. It used CONF_TYPE_INT with an off_t variable, which will result in invalid memory accesses. Make it use type double instead, which seems to make more sense for this option. --- m_option.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index 57fdc33610..73752e7a56 100644 --- a/m_option.h +++ b/m_option.h @@ -43,7 +43,6 @@ 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_position; extern const m_option_type_t m_option_type_time; extern const m_option_type_t m_option_type_time_size; extern const m_option_type_t m_option_type_choice; @@ -167,7 +166,6 @@ struct m_sub_options { #define CONF_TYPE_PRINT_FUNC (&m_option_type_print_func) #define CONF_TYPE_SUBCONFIG (&m_option_type_subconfig) #define CONF_TYPE_STRING_LIST (&m_option_type_string_list) -#define CONF_TYPE_POSITION (&m_option_type_position) #define CONF_TYPE_IMGFMT (&m_option_type_imgfmt) #define CONF_TYPE_AFMT (&m_option_type_afmt) #define CONF_TYPE_SPAN (&m_option_type_span) -- cgit v1.2.3 From cac7702565b560d5a16bc82bf553d1a4c08297e1 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Sep 2012 14:00:08 +0200 Subject: commands: handle property stepping in a generic way Instead of forcing each property implementation implement its own logic for M_PROPERTY_STEP_UP/M_PROPERTY_STEP_DOWN, handle it in the generic property code. Rename the M_PROPERTY_STEP_UP command to M_PROPERTY_SWITCH (the other property command, M_PROPERTY_STEP_DOWN, isn't needed anymore: stepping downwards is done by passing a negative argument). Always use double as argument type; it makes the code easier, and covers all property types. Move the code which does the actual type-specific value stepping to m_option.c (the idea is that m_option handles types). Some properties still have custom handlers implemented with M_PROPERTY_SWITCH. They can't be mapped to the generic mechanism, because their value range is dynamic or entirely unknown. For some properties, the default step stride is changed to 1. This is no issue, because the default bindings in input.conf all use an explicit stride in the affected cases. --- m_option.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index 73752e7a56..75f9ee5925 100644 --- a/m_option.h +++ b/m_option.h @@ -222,6 +222,11 @@ struct m_option_type { * set to NULL. */ void (*free)(void *dst); + + // Add the value add to the value in val. For types that are not numeric, + // add gives merely the direction. The wrap parameter determines whether + // the value is clipped, or wraps around to the opposite max/min. + void (*add)(const m_option_t *opt, void *val, double add, bool wrap); }; // Option description -- cgit v1.2.3 From 69ce4591d09f1fda85c6a71d452d26a2712cda4e Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Sep 2012 15:31:46 +0200 Subject: commands: generally handle property formatting with m_option Use the m_option code by default to format property values, instead of having separate code in m_property. To facilitate that, add a pretty_print callback to option types. These format values in a more human readable and user friendly way, as opposed to the print callback, which produces parseable values. This also changes the strings used with flags. Instead of "enabled" and "disabled", flags are formatted as "yes" and "no". (We could use the pretty_print callback to deal with this, but we don't for consistency.) --- m_option.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index 75f9ee5925..acbbb3fd9f 100644 --- a/m_option.h +++ b/m_option.h @@ -209,6 +209,11 @@ struct m_option_type { */ char *(*print)(const m_option_t *opt, const void *val); + // Print the value in a human readable form. Unlike print(), it doesn't + // necessarily return the exact value, and is generally not parseable with + // parse(). + char *(*pretty_print)(const m_option_t *opt, const void *val); + // Copy data between two locations. Deep copy if the data has pointers. /** \param opt The option to copy. * \param dst Pointer to the destination memory. @@ -413,6 +418,15 @@ static inline char *m_option_print(const m_option_t *opt, const void *val_ptr) return NULL; } +static inline char *m_option_pretty_print(const m_option_t *opt, + const void *val_ptr) +{ + if (opt->type->pretty_print) + return opt->type->pretty_print(opt, val_ptr); + else + return m_option_print(opt, val_ptr); +} + // Helper around \ref m_option_type::copy. static inline void m_option_copy(const m_option_t *opt, void *dst, const void *src) -- cgit v1.2.3 From 1a5a7a49293c2c70a5caf9d51dad7bd5aa938471 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Sep 2012 15:50:24 +0200 Subject: options: accept "yes" and "no" only for flags This removes the alternative values like "off", "0", "false" etc., and also the non-English versions of these. This is done for general consistency. It's better to have a single way of doing things when multiple ways don't add singificant value. Also update some choices for consistency. --- m_option.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index acbbb3fd9f..69694c4286 100644 --- a/m_option.h +++ b/m_option.h @@ -488,7 +488,7 @@ static inline void m_option_free(const m_option_t *opt, void *dst) #define OPT_CHOICE_OR_INT_(optname, varname, flags, minval, maxval, choices, ...) OPT_GENERAL(optname, varname, (flags) | CONF_RANGE, .min = minval, .max = maxval, .priv = (void *)&(const struct m_opt_choice_alternatives[]){OPT_HELPER_REMOVEPAREN choices, {NULL}}, __VA_ARGS__) #define OPT_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_time) -#define OPT_TRACKCHOICE(name, var) OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"off", -2}, {"no", -2}, {"auto", -1})) +#define OPT_TRACKCHOICE(name, var) OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"no", -2}, {"auto", -1})) // subconf must have the type struct m_sub_options. // flagv should be M_OPT_MERGE or M_OPT_FLATTEN. -- cgit v1.2.3 From 426640204b409d1034a1c32ad01b9bc547e93684 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Sep 2012 16:08:17 +0200 Subject: 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. --- m_option.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index 69694c4286..11e9e620fb 100644 --- a/m_option.h +++ b/m_option.h @@ -176,6 +176,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 -- cgit v1.2.3 From 86ed6efd8acbf86c7f85d69e51c40d08f421a1ca Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Sep 2012 17:05:11 +0200 Subject: commands: handle property clamping in m_option Instead of clamping property values to the valid range in each property implementation, handle it in the property layer. The functionality to handle clamping for each type is in m_option.c. It's not really clear whether this is really needed. Normally, the raw values for M_PROPERTY_SET come only from m_option_type.parse (setting properties as string) or from m_option_parse.add (using the "switch" input command). However, since this was already done before, and since we _really_ want to be sure only to write valid values, add this code anyway. The newly added warnings/error messages should never actually be printed during normal operation and are for debugging (if they happen, we definitely want to see them). --- m_option.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index 11e9e620fb..166e38e999 100644 --- a/m_option.h +++ b/m_option.h @@ -251,6 +251,13 @@ struct m_option_type { // add gives merely the direction. The wrap parameter determines whether // the value is clipped, or wraps around to the opposite max/min. void (*add)(const m_option_t *opt, void *val, double add, bool wrap); + + // Clamp the value in val to the option's valid value range. + // Return values: + // M_OPT_OUT_OF_RANGE: val was invalid, and modified (clamped) to be valid + // M_OPT_INVALID: val was invalid, and can't be made valid + // 0: val was already valid and is unchanged + int (*clamp)(const m_option_t *opt, void *val); }; // Option description -- cgit v1.2.3 From d7207b4cbca3bb2335e87c899d978e56e22dc1a5 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Sep 2012 13:07:22 +0200 Subject: commands: don't replicate mapping to option in levels_property_helper This should be done by mp_property_generic_option() only. Also reindent levels_property_helper() to make it a little bit more readable. Remove the m_option_get_ptr() function, which doesn't really make sense anymore. --- m_option.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index 166e38e999..4ff62cb071 100644 --- a/m_option.h +++ b/m_option.h @@ -422,12 +422,6 @@ char *m_option_strerror(int code); */ const m_option_t *m_option_list_find(const m_option_t *list, const char *name); -static inline void *m_option_get_ptr(const struct m_option *opt, - void *optstruct) -{ - return opt->new ? (char *) optstruct + opt->offset : opt->p; -} - // Helper to parse options, see \ref m_option_type::parse. static inline int m_option_parse(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) -- cgit v1.2.3 From a441cd3eeb9291e20d5a8052d32ce8180b017763 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 24 Sep 2012 19:57:59 +0200 Subject: m_option.h: separate creating choices array into M_CHOICES macro Reduces code duplication, increases reusability. --- m_option.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'm_option.h') diff --git a/m_option.h b/m_option.h index 4ff62cb071..3298e8e9da 100644 --- a/m_option.h +++ b/m_option.h @@ -500,12 +500,13 @@ static inline void m_option_free(const m_option_t *opt, void *dst) #define OPT_SETTINGSLIST(optname, varname, flags, objlist) OPT_GENERAL(optname, varname, flags, .type = &m_option_type_obj_settings_list, .priv = objlist) #define OPT_AUDIOFORMAT(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_afmt) #define OPT_HELPER_REMOVEPAREN(...) __VA_ARGS__ +#define M_CHOICES(choices) .priv = (void *)&(const struct m_opt_choice_alternatives[]){OPT_HELPER_REMOVEPAREN choices, {NULL}} #define OPT_CHOICE(...) OPT_CHOICE_(__VA_ARGS__, .type = &m_option_type_choice) -#define OPT_CHOICE_(optname, varname, flags, choices, ...) OPT_GENERAL(optname, varname, flags, .priv = (void *)&(const struct m_opt_choice_alternatives[]){OPT_HELPER_REMOVEPAREN choices, {NULL}}, __VA_ARGS__) +#define OPT_CHOICE_(optname, varname, flags, choices, ...) OPT_GENERAL(optname, varname, flags, M_CHOICES(choices), __VA_ARGS__) // Union of choices and an int range. The choice values can be included in the // int range, or be completely separate - both works. #define OPT_CHOICE_OR_INT(...) OPT_CHOICE_OR_INT_(__VA_ARGS__, .type = &m_option_type_choice) -#define OPT_CHOICE_OR_INT_(optname, varname, flags, minval, maxval, choices, ...) OPT_GENERAL(optname, varname, (flags) | CONF_RANGE, .min = minval, .max = maxval, .priv = (void *)&(const struct m_opt_choice_alternatives[]){OPT_HELPER_REMOVEPAREN choices, {NULL}}, __VA_ARGS__) +#define OPT_CHOICE_OR_INT_(optname, varname, flags, minval, maxval, choices, ...) OPT_GENERAL(optname, varname, (flags) | CONF_RANGE, .min = minval, .max = maxval, M_CHOICES(choices), __VA_ARGS__) #define OPT_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_time) #define OPT_TRACKCHOICE(name, var) OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"no", -2}, {"auto", -1})) -- cgit v1.2.3