summaryrefslogtreecommitdiffstats
path: root/options/m_option.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-03-14 21:28:01 +0100
committerwm4 <wm4@nowhere>2020-03-18 19:52:01 +0100
commit26f4f18c0629998a9b91e94722d166866d8b80a3 (patch)
tree16d4891d241d528f63ee99f0017530bba7b3dc8b /options/m_option.h
parentcdd6eb0994bc6aeb8aeb0326e5d8c61c06eb38eb (diff)
downloadmpv-26f4f18c0629998a9b91e94722d166866d8b80a3.tar.bz2
mpv-26f4f18c0629998a9b91e94722d166866d8b80a3.tar.xz
options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option initializer, and instead expand only to a part of it, which sets certain fields. This requires changing almost every option declaration, because they all use these macros. A declaration now always starts with {"name", ... followed by designated initializers only (possibly wrapped in macros). The OPT_* macros now initialize the .offset and .type fields only, sometimes also .priv and others. I think this change makes the option macros less tricky. The old code had to stuff everything into macro arguments (and attempted to allow setting arbitrary fields by letting the user pass designated initializers in the vararg parts). Some of this was made messy due to C99 and C11 not allowing 0-sized varargs with ',' removal. It's also possible that this change is pointless, other than cosmetic preferences. Not too happy about some things. For example, the OPT_CHOICE() indentation I applied looks a bit ugly. Much of this change was done with regex search&replace, but some places required manual editing. In particular, code in "obscure" areas (which I didn't include in compilation) might be broken now. In wayland_common.c the author of some option declarations confused the flags parameter with the default value (though the default value was also properly set below). I fixed this with this change.
Diffstat (limited to 'options/m_option.h')
-rw-r--r--options/m_option.h232
1 files changed, 99 insertions, 133 deletions
diff --git a/options/m_option.h b/options/m_option.h
index 97383237a5..fc48b42bd2 100644
--- a/options/m_option.h
+++ b/options/m_option.h
@@ -371,6 +371,7 @@ struct m_option {
// Float types use [DBL_MIN, DBL_MAX], though by setting min or max to
// -/+INFINITY, the range can be extended to INFINITY. (This part is buggy
// for "float".)
+ // Preferably use M_RANGE() to set these fields.
// Some types will abuse the min or max field for unrelated things.
double min, max;
@@ -569,6 +570,9 @@ extern const char m_option_path_separator;
(offsetof(type, member) + (0 && MP_EXPECT_TYPE(expected_member_type*, \
&((type*)0)->member)))
+#define OPT_TYPED_FIELD(type_, c_type, field) \
+ .type = &type_, \
+ .offset = MP_CHECKED_OFFSETOF(OPT_BASE_STRUCT, field, c_type)
#define OPTION_LIST_SEPARATOR ','
@@ -578,185 +582,147 @@ extern const char m_option_path_separator;
#define OPTDEF_FLOAT(f) .defval = (void *)&(const float){f}
#define OPTDEF_DOUBLE(d) .defval = (void *)&(const double){d}
-#define OPT_GENERAL(ctype, optname, varname, flagv, ...) \
- {.name = optname, .flags = flagv, \
- .offset = MP_CHECKED_OFFSETOF(OPT_BASE_STRUCT, varname, ctype), \
- __VA_ARGS__}
+#define M_RANGE(a, b) .min = (a), .max = (b)
-#define OPT_GENERAL_NOTYPE(optname, varname, flagv, ...) \
- {.name = optname, .flags = flagv, \
- .offset = offsetof(OPT_BASE_STRUCT, varname), \
- __VA_ARGS__}
+#define OPT_BOOL(field) \
+ OPT_TYPED_FIELD(m_option_type_bool, bool, field)
-#define OPT_HELPER_REMOVEPAREN(...) __VA_ARGS__
+#define OPT_FLAG(field) \
+ OPT_TYPED_FIELD(m_option_type_flag, int, field)
-#define OPTF_BOOL(field) \
- .type = &m_option_type_bool, \
- .offset = MP_CHECKED_OFFSETOF(OPT_BASE_STRUCT, field, bool),
+#define OPT_INT(field) \
+ OPT_TYPED_FIELD(m_option_type_int, int, field)
-/* The OPT_SOMETHING->OPT_SOMETHING_ kind of redirection exists to
- * make the code fully standard-conforming: the C standard requires that
- * __VA_ARGS__ has at least one argument (though GCC for example would accept
- * 0). Thus the first OPT_SOMETHING is a wrapper which just adds one
- * argument to ensure __VA_ARGS__ is not empty when calling the next macro.
- */
+#define OPT_INT64(field) \
+ OPT_TYPED_FIELD(m_option_type_int64, int64_t, field)
+
+#define OPT_FLOAT(field) \
+ OPT_TYPED_FIELD(m_option_type_float, float, field)
-// Note: new code should use OPTF_BOOL instead
-#define OPT_FLAG(...) \
- OPT_GENERAL(int, __VA_ARGS__, .type = &m_option_type_flag)
+#define OPT_DOUBLE(field) \
+ OPT_TYPED_FIELD(m_option_type_double, double, field)
-#define OPT_STRINGLIST(...) \
- OPT_GENERAL(char**, __VA_ARGS__, .type = &m_option_type_string_list)
+#define OPT_STRING(field) \
+ OPT_TYPED_FIELD(m_option_type_string, char*, field)
-#define OPT_KEYVALUELIST(...) \
- OPT_GENERAL(char**, __VA_ARGS__, .type = &m_option_type_keyvalue_list)
+#define OPT_STRINGLIST(field) \
+ OPT_TYPED_FIELD(m_option_type_string_list, char**, field)
-#define OPT_PATHLIST(...) \
- OPT_GENERAL(char**, __VA_ARGS__, .type = &m_option_type_string_list,\
- .priv = (void *)&m_option_path_separator)
+#define OPT_KEYVALUELIST(field) \
+ OPT_TYPED_FIELD(m_option_type_keyvalue_list, char**, field)
-#define OPT_INT(...) \
- OPT_GENERAL(int, __VA_ARGS__, .type = &m_option_type_int)
+#define OPT_PATHLIST(field) \
+ OPT_TYPED_FIELD(m_option_type_string_list, char**, field), \
+ .priv = (void *)&m_option_path_separator
-#define OPT_INT64(...) \
- OPT_GENERAL(int64_t, __VA_ARGS__, .type = &m_option_type_int64)
+#define OPT_TIME(field) \
+ OPT_TYPED_FIELD(m_option_type_time, double, field)
-#define OPT_RANGE_(ctype, optname, varname, flags, minval, maxval, ...) \
- OPT_GENERAL(ctype, optname, varname, flags, \
- .min = minval, .max = maxval, __VA_ARGS__)
+#define OPT_REL_TIME(field) \
+ OPT_TYPED_FIELD(m_option_type_rel_time, struct m_rel_time, field)
-#define OPT_INTRANGE(...) \
- OPT_RANGE_(int, __VA_ARGS__, .type = &m_option_type_int)
+#define OPT_COLOR(field) \
+ OPT_TYPED_FIELD(m_option_type_color, struct m_color, field)
-#define OPT_FLOATRANGE(...) \
- OPT_RANGE_(float, __VA_ARGS__, .type = &m_option_type_float)
+#define OPT_BYTE_SIZE(field) \
+ OPT_TYPED_FIELD(m_option_type_byte_size, int64_t, field)
-#define OPT_DOUBLERANGE(...) \
- OPT_RANGE_(double, __VA_ARGS__, .type = &m_option_type_double)
+#define OPT_GEOMETRY(field) \
+ OPT_TYPED_FIELD(m_option_type_geometry, struct m_geometry, field)
-#define OPT_FLOAT(...) \
- OPT_GENERAL(float, __VA_ARGS__, .type = &m_option_type_float)
+#define OPT_SIZE_BOX(field) \
+ OPT_TYPED_FIELD(m_option_type_size_box, struct m_geometry, field)
-#define OPT_DOUBLE(...) \
- OPT_GENERAL(double, __VA_ARGS__, .type = &m_option_type_double)
+#define OPT_TRACKCHOICE(field) \
+ OPT_CHOICE(field, {"no", -2}, {"auto", -1}), \
+ M_RANGE(0, 8190)
-#define OPT_STRING(...) \
- OPT_GENERAL(char*, __VA_ARGS__, .type = &m_option_type_string)
+#define OPT_MSGLEVELS(field) \
+ OPT_TYPED_FIELD(m_option_type_msglevels, char **, field)
-#define OPT_SETTINGSLIST(optname, varname, flags, objlist, ...) \
- OPT_GENERAL(m_obj_settings_t*, optname, varname, flags, \
- .type = &m_option_type_obj_settings_list, \
- .priv = (void*)MP_EXPECT_TYPE(const struct m_obj_list*, objlist), \
- __VA_ARGS__)
+#define OPT_ASPECT(field) \
+ OPT_TYPED_FIELD(m_option_type_aspect, float, field)
-#define OPT_IMAGEFORMAT(...) \
- OPT_GENERAL(int, __VA_ARGS__, .type = &m_option_type_imgfmt)
+#define OPT_IMAGEFORMAT(field) \
+ OPT_TYPED_FIELD(m_option_type_imgfmt, int, field)
-#define OPT_AUDIOFORMAT(...) \
- OPT_GENERAL(int, __VA_ARGS__, .type = &m_option_type_afmt)
+#define OPT_AUDIOFORMAT(field) \
+ OPT_TYPED_FIELD(m_option_type_afmt, int, field)
// If .min==1, then passing auto is disallowed, but "" is still accepted, and
// limit channel list to 1 item.
-#define OPT_CHANNELS(...) \
- OPT_GENERAL(struct m_channels, __VA_ARGS__, .type = &m_option_type_channels)
-
-#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(int, optname, varname, flags, M_CHOICES(choices), __VA_ARGS__)
-// Variant which takes a pointer to struct m_opt_choice_alternatives directly
-#define OPT_CHOICE_C(optname, varname, flags, choices, ...) \
- OPT_GENERAL(int, optname, varname, flags, .priv = (void *) \
- MP_EXPECT_TYPE(const struct m_opt_choice_alternatives*, choices), \
- .type = &m_option_type_choice, __VA_ARGS__)
-
-#define OPT_FLAGS(...) \
- OPT_CHOICE_(__VA_ARGS__, .type = &m_option_type_flags)
+#define OPT_CHANNELS(field) \
+ OPT_TYPED_FIELD(m_option_type_channels, struct m_channels, field)
-// 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_(optname, varname, flags, minval, maxval, choices, ...) \
- OPT_GENERAL(int, optname, varname, flags, \
- .min = minval, .max = maxval, \
- M_CHOICES(choices), __VA_ARGS__)
-#define OPT_CHOICE_OR_INT(...) \
- OPT_CHOICE_OR_INT_(__VA_ARGS__, .type = &m_option_type_choice)
+#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)
-#define OPT_TIME(...) \
- OPT_GENERAL(double, __VA_ARGS__, .type = &m_option_type_time)
+#define M_CHOICES(...) \
+ .priv = (void *)&(const struct m_opt_choice_alternatives[]){ __VA_ARGS__, {0}}
-#define OPT_REL_TIME(...) \
- OPT_GENERAL(struct m_rel_time, __VA_ARGS__, .type = &m_option_type_rel_time)
-
-#define OPT_COLOR(...) \
- OPT_GENERAL(struct m_color, __VA_ARGS__, .type = &m_option_type_color)
-
-#define OPT_BYTE_SIZE(...) \
- OPT_RANGE_(int64_t, __VA_ARGS__, .type = &m_option_type_byte_size)
-
-#define OPT_GEOMETRY(...) \
- OPT_GENERAL(struct m_geometry, __VA_ARGS__, .type = &m_option_type_geometry)
+// Variant which takes a pointer to struct m_opt_choice_alternatives directly
+#define OPT_CHOICE_C(field, choices) \
+ OPT_TYPED_FIELD(m_option_type_choice, int, field), \
+ .priv = (void *)MP_EXPECT_TYPE(const struct m_opt_choice_alternatives*, choices)
-#define OPT_SIZE_BOX(...) \
- OPT_GENERAL(struct m_geometry, __VA_ARGS__, .type = &m_option_type_size_box)
+// Variant where you pass a struct m_opt_choice_alternatives initializer
+#define OPT_CHOICE(field, ...) \
+ OPT_TYPED_FIELD(m_option_type_choice, int, field), \
+ M_CHOICES(__VA_ARGS__)
-#define OPT_TRACKCHOICE(name, var, ...) \
- OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"no", -2}, {"auto", -1}), \
- ## __VA_ARGS__)
+#define OPT_FLAGS(field, ...) \
+ OPT_TYPED_FIELD(m_option_type_flags, int, field), \
+ M_CHOICES(__VA_ARGS__)
-#define OPT_ASPECT(...) \
- OPT_GENERAL(float, __VA_ARGS__, .type = &m_option_type_aspect)
+#define OPT_SETTINGSLIST(field, objlist) \
+ OPT_TYPED_FIELD(m_option_type_obj_settings_list, m_obj_settings_t*, field), \
+ .priv = (void*)MP_EXPECT_TYPE(const struct m_obj_list*, objlist)
-#define OPT_STRING_VALIDATE_(optname, varname, flags, validate_fn, ...) \
- OPT_GENERAL(char*, optname, varname, flags, __VA_ARGS__, \
- .priv = MP_EXPECT_TYPE(m_opt_string_validate_fn, validate_fn))
-#define OPT_STRING_VALIDATE(...) \
- OPT_STRING_VALIDATE_(__VA_ARGS__, .type = &m_option_type_string)
+#define OPT_FOURCC(field) \
+ OPT_TYPED_FIELD(m_option_type_fourcc, int, field)
-#define OPT_PRINT(optname, fn) \
- {.name = optname, \
- .flags = M_OPT_NOCFG | M_OPT_PRE_PARSE | M_OPT_NOPROP, \
- .type = &m_option_type_print_fn, \
- .priv = MP_EXPECT_TYPE(m_opt_print_fn, fn), \
- .offset = -1}
+#define OPT_CYCLEDIR(field) \
+ OPT_TYPED_FIELD(m_option_type_cycle_dir, double, field)
// subconf must have the type struct m_sub_options.
// All sub-options are prefixed with "name-" and are added to the current
// (containing) option list.
// If name is "", add the sub-options directly instead.
-// varname refers to the field, that must be a pointer to a field described by
+// "field" refers to the field, that must be a pointer to a field described by
// the subconf struct.
-#define OPT_SUBSTRUCT(name, varname, subconf, flagv) \
- OPT_GENERAL_NOTYPE(name, varname, flagv, \
- .type = &m_option_type_subconfig, \
- .priv = (void*)&subconf)
+#define OPT_SUBSTRUCT(field, subconf) \
+ .offset = offsetof(OPT_BASE_STRUCT, field), \
+ .type = &m_option_type_subconfig, .priv = (void*)&subconf
+
+// Non-fields
-// Provide a another name for the option.
-#define OPT_ALIAS(optname, newname) \
- {.name = optname, .type = &m_option_type_alias, .priv = newname, \
- .offset = -1}
+#define OPT_ALIAS(newname) \
+ .type = &m_option_type_alias, .priv = newname, .offset = -1
// If "--optname" was removed, but "--newname" has the same semantics.
// It will be redirected, and a warning will be printed on first use.
-#define OPT_REPLACED_MSG(optname, newname, msg) \
- {.name = optname, .type = &m_option_type_alias, .priv = newname, \
- .deprecation_message = (msg), .offset = -1}
+#define OPT_REPLACED_MSG(newname, msg) \
+ .type = &m_option_type_alias, .priv = newname, \
+ .deprecation_message = (msg), .offset = -1
// Same, with a generic deprecation message.
-#define OPT_REPLACED(optname, newname) OPT_REPLACED_MSG(optname, newname, "")
+#define OPT_REPLACED(newname) OPT_REPLACED_MSG(newname, "")
// Alias, resolved on the CLI/config file/profile parser level only.
-#define OPT_CLI_ALIAS(optname, newname) \
- {.name = optname, .type = &m_option_type_cli_alias, .priv = newname, \
- .flags = M_OPT_NOPROP, .offset = -1}
+#define OPT_CLI_ALIAS(newname) \
+ .type = &m_option_type_cli_alias, .priv = newname, \
+ .flags = M_OPT_NOPROP, .offset = -1
// "--optname" doesn't exist, but inform the user about a replacement with msg.
-#define OPT_REMOVED(optname, msg) \
- {.name = optname, .type = &m_option_type_removed, .priv = msg, \
- .deprecation_message = "", .flags = M_OPT_NOPROP, .offset = -1}
+#define OPT_REMOVED(msg) \
+ .type = &m_option_type_removed, .priv = msg, \
+ .deprecation_message = "", .flags = M_OPT_NOPROP, .offset = -1
+
+#define OPT_PRINT(fn) \
+ .flags = M_OPT_NOCFG | M_OPT_PRE_PARSE | M_OPT_NOPROP, \
+ .type = &m_option_type_print_fn, \
+ .priv = MP_EXPECT_TYPE(m_opt_print_fn, fn), \
+ .offset = -1
#endif /* MPLAYER_M_OPTION_H */