summaryrefslogtreecommitdiffstats
path: root/options/m_option.h
diff options
context:
space:
mode:
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 */