mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2025-12-20 02:20:13 +01:00
shared: add safe_strtofloat()
This is for parsing multiple numbers from one weston.ini key, which means I cannot use weston_config_section_get_double(). Also going to use float type, which has less range than double. Ironically, the tests fill likely fail on locales that do not use period as the radix character. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
f0be8d94a5
commit
c0f79189dd
2 changed files with 84 additions and 0 deletions
|
|
@ -73,6 +73,37 @@ safe_strtoint(const char *str, int32_t *value)
|
|||
return true;
|
||||
}
|
||||
|
||||
/** Convert a localized string to a single-precision floating point value
|
||||
*
|
||||
* \param str The string to parse. Leading whitespace is ignored,
|
||||
* otherwise the string must be exactly a real number in the current locale.
|
||||
* \param[out] value Pointer to store the result to on success.
|
||||
* \return True on success. False on failure and errno set to
|
||||
* either ERANGE (under- or overflow) or EINVAL (the string is not strictly
|
||||
* a number).
|
||||
*/
|
||||
static inline bool
|
||||
safe_strtofloat(const char *str, float *value)
|
||||
{
|
||||
float ret;
|
||||
char *end;
|
||||
|
||||
assert(str != NULL);
|
||||
|
||||
errno = 0;
|
||||
ret = strtof(str, &end);
|
||||
if (errno != 0) {
|
||||
return false;
|
||||
} else if (end == str || *end != '\0') {
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
*value = ret;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exactly like asprintf(), but sets *str_out to NULL if it fails.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -88,3 +88,56 @@ TEST(strtol_conversions)
|
|||
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
TEST(strtof_conversions)
|
||||
{
|
||||
float val;
|
||||
|
||||
test_assert_true(safe_strtofloat("0.0", &val));
|
||||
test_assert_f32_eq(val, 0.0);
|
||||
|
||||
test_assert_true(safe_strtofloat("-0.25", &val));
|
||||
test_assert_f32_eq(val, -0.25);
|
||||
|
||||
test_assert_true(safe_strtofloat(" 10", &val));
|
||||
test_assert_f32_eq(val, 10.0);
|
||||
|
||||
test_assert_true(safe_strtofloat("+2.2e-4", &val));
|
||||
test_assert_f32_eq(val, 2.2e-4);
|
||||
|
||||
test_assert_true(safe_strtofloat("3.3e3", &val));
|
||||
test_assert_f32_eq(val, 3.3e3);
|
||||
|
||||
test_assert_true(safe_strtofloat("nan", &val));
|
||||
test_assert_true(isnan(val));
|
||||
|
||||
test_assert_true(safe_strtofloat("inf", &val));
|
||||
test_assert_f32_eq(val, HUGE_VALF);
|
||||
|
||||
test_assert_true(safe_strtofloat("-inf", &val));
|
||||
test_assert_f32_eq(val, -HUGE_VALF);
|
||||
|
||||
|
||||
test_assert_false(safe_strtofloat("", &val));
|
||||
test_assert_int_eq(errno, EINVAL);
|
||||
|
||||
test_assert_false(safe_strtofloat("x", &val));
|
||||
test_assert_int_eq(errno, EINVAL);
|
||||
|
||||
test_assert_false(safe_strtofloat("15k", &val));
|
||||
test_assert_int_eq(errno, EINVAL);
|
||||
|
||||
test_assert_false(safe_strtofloat("b2.2", &val));
|
||||
test_assert_int_eq(errno, EINVAL);
|
||||
|
||||
test_assert_false(safe_strtofloat("1.3f", &val));
|
||||
test_assert_int_eq(errno, EINVAL);
|
||||
|
||||
test_assert_false(safe_strtofloat("1e-500", &val));
|
||||
test_assert_int_eq(errno, ERANGE);
|
||||
|
||||
test_assert_false(safe_strtofloat("1e+500", &val));
|
||||
test_assert_int_eq(errno, ERANGE);
|
||||
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue