From b605dbfcf04f310e08634b52507da7a4155bfce1 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 13 Dec 2021 12:58:18 +0100 Subject: treewide: rework numeric value handling - Parse integer literals as unsigned numeric values in order to be able to represent the entire unsigned 64bit value range - Stop parsing minus-prefixed integer literals as negative numbers but treat them as separate minus operator followed by a positive integer instead - Only store unsigned numeric constants in bytecode - Rework numeric comparison logic to be able to handle full 64bit unsigned integers - If possible, yield unsigned 64 bit results for additions - Simplify numeric value conversion API - Compile code with -fwrapv for defined signed overflow semantics Signed-off-by: Jo-Philipp Wich --- lib/rtnl.c | 74 +++++++------------------------------------------------------- 1 file changed, 8 insertions(+), 66 deletions(-) (limited to 'lib/rtnl.c') diff --git a/lib/rtnl.c b/lib/rtnl.c index 2393264..4d5cc02 100644 --- a/lib/rtnl.c +++ b/lib/rtnl.c @@ -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 * -- cgit v1.2.3