summaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-01-04 16:16:28 +0100
committerGitHub <noreply@github.com>2022-01-04 16:16:28 +0100
commit1377e23afff90128b18ac60c10071295fc0afbab (patch)
tree04397dab9be96a5978e08366299671a8aa507267 /lib
parent8907ce41a36f8d42097d884550fb3cfbba62e6c5 (diff)
parentb605dbfcf04f310e08634b52507da7a4155bfce1 (diff)
Merge pull request #30 from jow-/rework-number-handling
treewide: rework numeric value handling
Diffstat (limited to 'lib')
-rw-r--r--lib/math.c40
-rw-r--r--lib/nl80211.c74
-rw-r--r--lib/rtnl.c74
3 files changed, 48 insertions, 140 deletions
diff --git a/lib/math.c b/lib/math.c
index c4a08e3..f16d309 100644
--- a/lib/math.c
+++ b/lib/math.c
@@ -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
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 *