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.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) (limited to 'm_option.c') diff --git a/m_option.c b/m_option.c index 48539b3a4c..d48d4016b8 100644 --- a/m_option.c +++ b/m_option.c @@ -90,6 +90,14 @@ static void copy_opt(const m_option_t *opt, void *dst, const void *src) #define VAL(x) (*(int *)(x)) +static int clamp_flag(const m_option_t *opt, void *val) +{ + if (VAL(val) == opt->min || VAL(val) == opt->max) + return 0; + VAL(val) = opt->min; + return M_OPT_OUT_OF_RANGE; +} + static int parse_flag(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { @@ -141,12 +149,29 @@ const m_option_type_t m_option_type_flag = { .print = print_flag, .copy = copy_opt, .add = add_flag, + .clamp = clamp_flag, }; // Integer #undef VAL +static int clamp_longlong(const m_option_t *opt, void *val) +{ + long long v = *(long long *)val; + int r = 0; + if ((opt->flags & M_OPT_MAX) && (v > opt->max)) { + v = opt->max; + r = M_OPT_OUT_OF_RANGE; + } + if ((opt->flags & M_OPT_MIN) && (v < opt->min)) { + v = opt->min; + r = M_OPT_OUT_OF_RANGE; + } + *(long long *)val = v; + return r; +} + static int parse_longlong(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { @@ -184,6 +209,22 @@ static int parse_longlong(const m_option_t *opt, struct bstr name, return 1; } +static int clamp_int(const m_option_t *opt, void *val) +{ + long long tmp = *(int *)val; + int r = clamp_longlong(opt, &tmp); + *(int *)val = tmp; + return r; +} + +static int clamp_int64(const m_option_t *opt, void *val) +{ + long long tmp = *(int64_t *)val; + int r = clamp_longlong(opt, &tmp); + *(int64_t *)val = tmp; + return r; +} + static int parse_int(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { @@ -204,7 +245,6 @@ static int parse_int64(const m_option_t *opt, struct bstr name, return r; } - static char *print_int(const m_option_t *opt, const void *val) { if (opt->type->size == sizeof(int64_t)) @@ -247,6 +287,7 @@ const m_option_type_t m_option_type_int = { .print = print_int, .copy = copy_opt, .add = add_int, + .clamp = clamp_int, }; const m_option_type_t m_option_type_int64 = { @@ -256,6 +297,7 @@ const m_option_type_t m_option_type_int64 = { .print = print_int, .copy = copy_opt, .add = add_int64, + .clamp = clamp_int64, }; static int parse_intpair(const struct m_option *opt, struct bstr name, @@ -301,6 +343,21 @@ const struct m_option_type m_option_type_intpair = { .copy = copy_opt, }; +static int clamp_choice(const m_option_t *opt, void *val) +{ + int v = *(int *)val; + if ((opt->flags & M_OPT_MIN) && (opt->flags & M_OPT_MAX)) { + if (v >= opt->min && v <= opt->max) + return 0; + } + ; + for (struct m_opt_choice_alternatives *alt = opt->priv; alt->name; alt++) { + if (alt->value == v) + return 0; + } + return M_OPT_INVALID; +} + static int parse_choice(const struct m_option *opt, struct bstr name, struct bstr param, void *dst) { @@ -416,6 +473,7 @@ const struct m_option_type m_option_type_choice = { .print = print_choice, .copy = copy_opt, .add = add_choice, + .clamp = clamp_choice, }; // Float @@ -423,6 +481,22 @@ const struct m_option_type m_option_type_choice = { #undef VAL #define VAL(x) (*(double *)(x)) +static int clamp_double(const m_option_t *opt, void *val) +{ + double v = VAL(val); + int r = 0; + if ((opt->flags & M_OPT_MAX) && (v > opt->max)) { + v = opt->max; + r = M_OPT_OUT_OF_RANGE; + } + if ((opt->flags & M_OPT_MIN) && (v < opt->min)) { + v = opt->min; + r = M_OPT_OUT_OF_RANGE; + } + VAL(val) = v; + return r; +} + static int parse_double(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { @@ -514,11 +588,20 @@ const m_option_type_t m_option_type_double = { .print = print_double, .pretty_print = print_double_f2, .copy = copy_opt, + .clamp = clamp_double, }; #undef VAL #define VAL(x) (*(float *)(x)) +static int clamp_float(const m_option_t *opt, void *val) +{ + double tmp = VAL(val); + int r = clamp_double(opt, &tmp); + VAL(val) = tmp; + return r; +} + static int parse_float(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { @@ -555,6 +638,7 @@ const m_option_type_t m_option_type_float = { .pretty_print = print_float_f2, .copy = copy_opt, .add = add_float, + .clamp = clamp_float, }; ///////////// String @@ -562,6 +646,17 @@ const m_option_type_t m_option_type_float = { #undef VAL #define VAL(x) (*(char **)(x)) +static int clamp_str(const m_option_t *opt, void *val) +{ + char *v = VAL(val); + int len = v ? strlen(v) : 0; + if ((opt->flags & M_OPT_MIN) && (len < opt->min)) + return M_OPT_OUT_OF_RANGE; + if ((opt->flags & M_OPT_MAX) && (len > opt->max)) + return M_OPT_OUT_OF_RANGE; + return 0; +} + static int parse_str(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { @@ -620,6 +715,7 @@ const m_option_type_t m_option_type_string = { .print = print_str, .copy = copy_str, .free = free_str, + .clamp = clamp_str, }; //////////// String list @@ -1150,6 +1246,7 @@ const m_option_type_t m_option_type_time = { .pretty_print = pretty_print_time, .copy = copy_opt, .add = add_double, + .clamp = clamp_double, }; -- cgit v1.2.3