summaryrefslogtreecommitdiffhomepage
path: root/lib/rtnl.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-12-13 12:58:18 +0100
committerJo-Philipp Wich <jo@mein.io>2022-01-04 15:53:36 +0100
commitb605dbfcf04f310e08634b52507da7a4155bfce1 (patch)
tree04397dab9be96a5978e08366299671a8aa507267 /lib/rtnl.c
parent8907ce41a36f8d42097d884550fb3cfbba62e6c5 (diff)
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 <jo@mein.io>
Diffstat (limited to 'lib/rtnl.c')
-rw-r--r--lib/rtnl.c74
1 files changed, 8 insertions, 66 deletions
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 *