strutil: Fix sr_parse_rational for integral parts between -0 and -1

Values like '-0.1' would be parsed as being positive, as the integral
type does not discern +0 and -0. Also allow values without leading
integral value, to match behaviour of strtod/sr_atof.
This commit is contained in:
Stefan Brüns 2017-09-23 22:16:24 +02:00 committed by Uwe Hermann
parent f05600f4be
commit 41c47f2c6a
2 changed files with 18 additions and 2 deletions

View File

@ -233,13 +233,19 @@ SR_API int sr_parse_rational(const char *str, struct sr_rational *ret)
int64_t denominator = 1;
int32_t fractional_len = 0;
int32_t exponent = 0;
int is_negative = 0;
errno = 0;
integral = g_ascii_strtoll(str, &endptr, 10);
if (errno)
if (str == endptr && (str[0] == '-' || str[0] == '+') && str[1] == '.')
endptr += 1;
else if (errno)
return SR_ERR;
if (integral < 0 || str[0] == '-')
is_negative = 1;
if (*endptr == '.') {
const char* start = endptr + 1;
fractional = g_ascii_strtoll(start, &endptr, 10);
@ -261,7 +267,7 @@ SR_API int sr_parse_rational(const char *str, struct sr_rational *ret)
integral *= 10;
exponent -= fractional_len;
if (integral >= 0)
if (!is_negative)
integral += fractional;
else
integral -= fractional;

View File

@ -255,6 +255,11 @@ START_TEST(test_fractional)
test_rational("12.34", (struct sr_rational){1234, 100});
test_rational("-12.34", (struct sr_rational){-1234, 100});
test_rational("10.00", (struct sr_rational){1000, 100});
test_rational(".1", (struct sr_rational){1, 10});
test_rational("+0.1", (struct sr_rational){1, 10});
test_rational("+.1", (struct sr_rational){1, 10});
test_rational("-0.1", (struct sr_rational){-1, 10});
test_rational("-.1", (struct sr_rational){-1, 10});
}
END_TEST
@ -270,6 +275,11 @@ START_TEST(test_exponent)
test_rational("0.001e3", (struct sr_rational){1, 1});
test_rational("0.001e0", (struct sr_rational){1, 1000});
test_rational("0.001e-3", (struct sr_rational){1, 1000000});
test_rational("43.737E-3", (struct sr_rational){43737, 1000000});
test_rational("-0.1e-2", (struct sr_rational){-1, 1000});
test_rational("-.1e-2", (struct sr_rational){-1, 1000});
test_rational("-.0e-2", (struct sr_rational){0, 1000});
test_rational("+.0e-2", (struct sr_rational){0, 1000});
}
END_TEST