diff options
-rw-r--r-- | ccan/opt/helpers.c | 11 | ||||
-rw-r--r-- | ccan/opt/test/run-helpers.c | 29 |
2 files changed, 37 insertions, 3 deletions
diff --git a/ccan/opt/helpers.c b/ccan/opt/helpers.c index 43b86d7c..f247301c 100644 --- a/ccan/opt/helpers.c +++ b/ccan/opt/helpers.c @@ -9,6 +9,7 @@ #include <stdio.h> #include <limits.h> #include "private.h" +#include <float.h> /* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */ #define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1) @@ -126,8 +127,14 @@ char *opt_set_floatval(const char *arg, float *f) return err; *f = d; - if (*f != d) - return arg_bad("'%s' is out of range", arg); + + /*allow true infinity via --foo=INF, while avoiding isinf() from math.h + because it wasn't standard 25 years ago.*/ + double inf = 1e300 * 1e300; /*direct 1e600 annoys -Woverflow*/ + if ((d > FLT_MAX || d < -FLT_MAX) && d != inf && d != -inf) + return arg_bad("'%s' is out of range for a 32 bit float", arg); + if (d != 0 && *f == 0) + return arg_bad("'%s' is out of range (truncated to zero)", arg); return NULL; } diff --git a/ccan/opt/test/run-helpers.c b/ccan/opt/test/run-helpers.c index 49fb2062..6ec17f58 100644 --- a/ccan/opt/test/run-helpers.c +++ b/ccan/opt/test/run-helpers.c @@ -5,6 +5,7 @@ #include <stdlib.h> #include <limits.h> #include "utils.h" +#include <math.h> /* We don't actually want it to exit... */ static jmp_buf exited; @@ -77,7 +78,7 @@ static void set_args(int *argc, char ***argv, ...) /* Test helpers. */ int main(int argc, char *argv[]) { - plan_tests(476); + plan_tests(500); /* opt_set_bool */ { @@ -215,9 +216,25 @@ int main(int argc, char *argv[]) ok1(arg == 9999); ok1(parse_args(&argc, &argv, "-a", "-9999", NULL)); ok1(arg == -9999); + ok1(parse_args(&argc, &argv, "-a", "1e33", NULL)); + ok1(arg == 1e33f); + /*overflows should fail */ + ok1(!parse_args(&argc, &argv, "-a", "1e39", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "-1e40", NULL)); + /*low numbers lose precision but work */ + ok1(parse_args(&argc, &argv, "-a", "1e-39", NULL)); + ok1(arg == 1e-39f); + ok1(parse_args(&argc, &argv, "-a", "-1e-45", NULL)); + ok1(arg == -1e-45f); + ok1(!parse_args(&argc, &argv, "-a", "1e-99", NULL)); ok1(parse_args(&argc, &argv, "-a", "0", NULL)); ok1(arg == 0); + ok1(parse_args(&argc, &argv, "-a", "1.111111111111", NULL)); + ok1(arg == 1.1111112f); + ok1(parse_args(&argc, &argv, "-a", "INF", NULL)); + ok1(isinf(arg)); ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1e7crap", NULL)); } /* opt_set_doubleval */ { @@ -228,9 +245,19 @@ int main(int argc, char *argv[]) ok1(arg == 9999); ok1(parse_args(&argc, &argv, "-a", "-9999", NULL)); ok1(arg == -9999); + ok1(parse_args(&argc, &argv, "-a", "1e-299", NULL)); + ok1(arg == 1e-299); + ok1(parse_args(&argc, &argv, "-a", "-1e-305", NULL)); + ok1(arg == -1e-305); + ok1(!parse_args(&argc, &argv, "-a", "1e-499", NULL)); ok1(parse_args(&argc, &argv, "-a", "0", NULL)); ok1(arg == 0); + ok1(parse_args(&argc, &argv, "-a", "1.1111111111111111111", NULL)); + ok1(arg == 1.1111111111111112); + ok1(parse_args(&argc, &argv, "-a", "INF", NULL)); + ok1(isinf(arg)); ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1e7crap", NULL)); } { |