summaryrefslogtreecommitdiffstats
path: root/options/m_option.h
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2021-02-20 16:41:44 -0800
committerJan Ekström <jeebjp@gmail.com>2021-03-28 19:46:27 +0300
commit3f006eced47b35b7d752fdc19c22a7f39f970975 (patch)
tree7186f381e317fac2e8cc117d2ff20ab700a3b372 /options/m_option.h
parent6265724f3331e3dee8d9ec2b6639def5004a5fa2 (diff)
downloadmpv-3f006eced47b35b7d752fdc19c22a7f39f970975.tar.bz2
mpv-3f006eced47b35b7d752fdc19c22a7f39f970975.tar.xz
options: Make validation and help possible for all option types
Today, validation is only possible for string type options. But there's no particular reason why it needs to be restricted in this way, and there are potential uses, to allow other options to be validated without forcing the option to have to reimplement parsing from scratch. The first part, simply making the validation function an explicit field instead of overloading priv is simple enough. But if we only do that, then the validation function still needs to deal with the raw pre-parsed string. Instead, we want to allow the value to be parsed before it is validated. That in turn leads to us having validator functions that should be type aware. Unfortunately, that means we need to keep the explicit macro like OPT_STRING_VALIDATE() as a way to enforce the correct typing of the function. Otherwise, we'd have to have the validator take a void * and hope the implementation can cast it correctly. For help, we don't have this problem, as help doesn't look at the value. Then, we turn validators that are really help generators into explicit help functions and where a validator is help + validation, we split them into two parts. I have, however, left functions that need to query information for both help and validation as single functions to avoid code duplication. In this change, I have not added an other OPT_FOO_VALIDATE() macros as they are not needed, but I will add some in a separate change to illustrate the pattern.
Diffstat (limited to 'options/m_option.h')
-rw-r--r--options/m_option.h32
1 files changed, 23 insertions, 9 deletions
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}}