diff options
Diffstat (limited to 'options')
-rw-r--r-- | options/m_option.c | 32 | ||||
-rw-r--r-- | options/m_option.h | 32 |
2 files changed, 48 insertions, 16 deletions
diff --git a/options/m_option.c b/options/m_option.c index 4d222df500..4c199967b3 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -61,6 +61,31 @@ const char m_option_path_separator = OPTION_PATH_SEPARATOR; #define OPT_INT_MAX(opt, T, Tm) ((opt)->min < (opt)->max \ ? ((opt)->max >= (double)(Tm) ? (Tm) : (T)((opt)->max)) : (Tm)) +int m_option_parse(struct mp_log *log, const m_option_t *opt, + struct bstr name, struct bstr param, void *dst) +{ + int r = M_OPT_INVALID; + if (bstr_equals0(param, "help") && opt->help) { + r = opt->help(log, opt, name); + if (r < 0) + return r; + } + + r = opt->type->parse(log, opt, name, param, dst); + if (r < 0) + return r; + + if (opt->validate) { + r = opt->validate(log, opt, name, dst); + if (r < 0) { + if (opt->type->free) + opt->type->free(dst); + return r; + } + } + return 1; +} + char *m_option_strerror(int code) { switch (code) { @@ -1192,13 +1217,6 @@ const m_option_type_t m_option_type_aspect = { static int parse_str(struct mp_log *log, const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { - m_opt_string_validate_fn validate = opt->priv; - if (validate) { - int r = validate(log, opt, name, param); - if (r < 0) - return r; - } - if (dst) { talloc_free(VAL(dst)); VAL(dst) = bstrdup0(NULL, param); diff --git a/options/m_option.h b/options/m_option.h index afd86eaf96..e7446ce663 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -189,9 +189,12 @@ struct m_opt_choice_alternatives { const char *m_opt_choice_str(const struct m_opt_choice_alternatives *choices, int value); -// For OPT_STRING_VALIDATE(). Behaves like m_option_type.parse(). +// Validator function signatures. Required to properly type the param value. +typedef int (*m_opt_generic_validate_fn)(struct mp_log *log, const m_option_t *opt, + struct bstr name, void *value); + typedef int (*m_opt_string_validate_fn)(struct mp_log *log, const m_option_t *opt, - struct bstr name, struct bstr param); + struct bstr name, const char **value); // m_option.priv points to this if OPT_SUBSTRUCT is used struct m_sub_options { @@ -270,6 +273,9 @@ struct m_option_type { // Parse the data from a string. /** It is the only required function, all others can be NULL. + * Generally should not be called directly outside of the options module, + * but instead through \ref m_option_parse which calls additional option + * specific callbacks during the process. * * \param log for outputting parser error or help messages * \param opt The option that is parsed. @@ -384,6 +390,12 @@ struct m_option { // Print a warning when this option is used (for options with no direct // replacement.) const char *deprecation_message; + + // Optional function that validates a param value for this option. + m_opt_generic_validate_fn validate; + + // Optional function that displays help. Will replace type-specific help. + int (*help)(struct mp_log *log, const m_option_t *opt, struct bstr name); }; char *format_file_size(int64_t size); @@ -490,12 +502,13 @@ char *format_file_size(int64_t size); char *m_option_strerror(int code); -// Helper to parse options, see \ref m_option_type::parse. -static inline int m_option_parse(struct mp_log *log, const m_option_t *opt, - struct bstr name, struct bstr param, void *dst) -{ - return opt->type->parse(log, opt, name, param, dst); -} +// Base function to parse options. Includes calling help and validation +// callbacks. Only when this functionality is for some reason required to not +// happen should the parse function pointer be utilized by itself. +// +// See \ref m_option_type::parse. +int m_option_parse(struct mp_log *log, const m_option_t *opt, + struct bstr name, struct bstr param, void *dst); // Helper to print options, see \ref m_option_type::print. static inline char *m_option_print(const m_option_t *opt, const void *val_ptr) @@ -663,7 +676,8 @@ extern const char m_option_path_separator; #define OPT_STRING_VALIDATE(field, validate_fn) \ OPT_TYPED_FIELD(m_option_type_string, char*, field), \ - .priv = MP_EXPECT_TYPE(m_opt_string_validate_fn, validate_fn) + .validate = (m_opt_generic_validate_fn) \ + MP_EXPECT_TYPE(m_opt_string_validate_fn, validate_fn) #define M_CHOICES(...) \ .priv = (void *)&(const struct m_opt_choice_alternatives[]){ __VA_ARGS__, {0}} |