diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-01-04 16:16:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-04 16:16:28 +0100 |
commit | 1377e23afff90128b18ac60c10071295fc0afbab (patch) | |
tree | 04397dab9be96a5978e08366299671a8aa507267 /lib | |
parent | 8907ce41a36f8d42097d884550fb3cfbba62e6c5 (diff) | |
parent | b605dbfcf04f310e08634b52507da7a4155bfce1 (diff) |
Merge pull request #30 from jow-/rework-number-handling
treewide: rework numeric value handling
Diffstat (limited to 'lib')
-rw-r--r-- | lib/math.c | 40 | ||||
-rw-r--r-- | lib/nl80211.c | 74 | ||||
-rw-r--r-- | lib/rtnl.c | 74 |
3 files changed, 48 insertions, 140 deletions
@@ -15,6 +15,7 @@ */ #include <math.h> +#include <errno.h> #include <sys/time.h> #include "ucode/module.h" @@ -24,20 +25,43 @@ static bool srand_called = false; static uc_value_t * uc_abs(uc_vm_t *vm, size_t nargs) { - uc_value_t *v = uc_fn_arg(0); - uc_type_t t; + uc_value_t *v = uc_fn_arg(0), *nv, *res; int64_t n; double d; - if (ucv_type(v) == UC_NULL) - return ucv_double_new(NAN); + nv = v ? ucv_to_number(v) : NULL; + + switch (ucv_type(nv)) { + case UC_INTEGER: + n = ucv_int64_get(nv); + + if (n >= 0 || errno == ERANGE) + res = ucv_get(nv); + else if (n == INT64_MIN) + res = ucv_uint64_new((uint64_t)INT64_MAX + 1); + else + res = ucv_uint64_new(-n); + + break; - t = ucv_cast_number(v, &n, &d); + case UC_DOUBLE: + d = ucv_double_get(nv); + + if (isnan(d) || d >= 0) + res = ucv_get(nv); + else + res = ucv_double_new(-d); + + break; + + default: + res = ucv_double_new(NAN); + break; + } - if (t == UC_DOUBLE) - return (isnan(d) || d < 0) ? ucv_double_new(-d) : ucv_get(v); + ucv_put(nv); - return (n < 0) ? ucv_int64_new(-n) : ucv_get(v); + return res; } static uc_value_t * diff --git a/lib/nl80211.c b/lib/nl80211.c index b48ff2a..8504203 100644 --- a/lib/nl80211.c +++ b/lib/nl80211.c @@ -69,29 +69,14 @@ set_error(int errcode, const char *fmt, ...) { static bool uc_nl_parse_u32(uc_value_t *val, uint32_t *n) { - uc_type_t t; - int64_t i; - double d; - - t = ucv_cast_number(val, &i, &d); - - if (t == UC_DOUBLE) { - if (isnan(d) || d < 0 || d > UINT32_MAX) - return false; - - i = (int64_t)d; + uint64_t u; - if (d - i > 0) - return false; - } - else if (errno != 0) { - return false; - } + u = ucv_to_unsigned(val); - if (i < 0 || i > UINT32_MAX) + if (errno != 0 || u > UINT32_MAX) return false; - *n = (uint32_t)i; + *n = (uint32_t)u; return true; } @@ -99,26 +84,11 @@ uc_nl_parse_u32(uc_value_t *val, uint32_t *n) static bool uc_nl_parse_s32(uc_value_t *val, uint32_t *n) { - uc_type_t t; int64_t i; - double d; - - t = ucv_cast_number(val, &i, &d); - - if (t == UC_DOUBLE) { - if (isnan(d) || d < INT32_MIN || d > INT32_MAX) - return false; - - i = (int64_t)d; - if (d - i > 0) - return false; - } - else if (errno != 0) { - return false; - } + i = ucv_to_integer(val); - if (i < INT32_MIN || i > INT32_MAX) + if (errno != 0 || i < INT32_MIN || i > INT32_MAX) return false; *n = (uint32_t)i; @@ -129,37 +99,9 @@ uc_nl_parse_s32(uc_value_t *val, uint32_t *n) static bool uc_nl_parse_u64(uc_value_t *val, uint64_t *n) { - uc_type_t t; - int64_t i; - double d; - - if (ucv_type(val) == UC_INTEGER) { - *n = ucv_uint64_get(val); - - return true; - } - - t = ucv_cast_number(val, &i, &d); - - if (t == UC_DOUBLE) { - if (isnan(d) || d < 0) - return false; - - i = (int64_t)d; + *n = ucv_to_unsigned(val); - if (d - i > 0) - return false; - } - else if (errno != 0) { - return false; - } - - if (i < 0) - return false; - - *n = (uint64_t)i; - - return true; + return (errno == 0); } static bool @@ -97,29 +97,14 @@ typedef struct { static bool uc_nl_parse_u32(uc_value_t *val, uint32_t *n) { - uc_type_t t; - int64_t i; - double d; - - t = ucv_cast_number(val, &i, &d); - - if (t == UC_DOUBLE) { - if (isnan(d) || d < 0 || d > UINT32_MAX) - return false; - - i = (int64_t)d; + uint64_t u; - if (d - i > 0) - return false; - } - else if (errno != 0) { - return false; - } + u = ucv_to_unsigned(val); - if (i < 0 || i > UINT32_MAX) + if (errno != 0 || u > UINT32_MAX) return false; - *n = (uint32_t)i; + *n = (uint32_t)u; return true; } @@ -127,26 +112,11 @@ uc_nl_parse_u32(uc_value_t *val, uint32_t *n) static bool uc_nl_parse_s32(uc_value_t *val, uint32_t *n) { - uc_type_t t; int64_t i; - double d; - - t = ucv_cast_number(val, &i, &d); - - if (t == UC_DOUBLE) { - if (isnan(d) || d < INT32_MIN || d > INT32_MAX) - return false; - - i = (int64_t)d; - if (d - i > 0) - return false; - } - else if (errno != 0) { - return false; - } + i = ucv_to_integer(val); - if (i < INT32_MIN || i > INT32_MAX) + if (errno != 0 || i < INT32_MIN || i > INT32_MAX) return false; *n = (uint32_t)i; @@ -157,37 +127,9 @@ uc_nl_parse_s32(uc_value_t *val, uint32_t *n) static bool uc_nl_parse_u64(uc_value_t *val, uint64_t *n) { - uc_type_t t; - int64_t i; - double d; - - if (ucv_type(val) == UC_INTEGER) { - *n = ucv_uint64_get(val); - - return true; - } - - t = ucv_cast_number(val, &i, &d); + *n = ucv_to_unsigned(val); - if (t == UC_DOUBLE) { - if (isnan(d) || d < 0) - return false; - - i = (int64_t)d; - - if (d - i > 0) - return false; - } - else if (errno != 0) { - return false; - } - - if (i < 0) - return false; - - *n = (uint64_t)i; - - return true; + return (errno == 0); } static const char * |