cutils: Add qemu_strtod() and qemu_strtod_finite()

Let's provide a wrapper for strtod().

Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20181121164421.20780-2-david@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
David Hildenbrand 2018-11-21 17:44:13 +01:00 committed by Markus Armbruster
parent c3ec0fa1a8
commit ca28f54816
2 changed files with 67 additions and 0 deletions

View file

@ -146,6 +146,8 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base,
int64_t *result);
int qemu_strtou64(const char *nptr, const char **endptr, int base,
uint64_t *result);
int qemu_strtod(const char *nptr, const char **endptr, double *result);
int qemu_strtod_finite(const char *nptr, const char **endptr, double *result);
int parse_uint(const char *s, unsigned long long *value, char **endptr,
int base);

View file

@ -551,6 +551,71 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base,
return check_strtox_error(nptr, ep, endptr, errno);
}
/**
* Convert string @nptr to a double.
*
* This is a wrapper around strtod() that is harder to misuse.
* Semantics of @nptr and @endptr match strtod() with differences
* noted below.
*
* @nptr may be null, and no conversion is performed then.
*
* If no conversion is performed, store @nptr in *@endptr and return
* -EINVAL.
*
* If @endptr is null, and the string isn't fully converted, return
* -EINVAL. This is the case when the pointer that would be stored in
* a non-null @endptr points to a character other than '\0'.
*
* If the conversion overflows, store +/-HUGE_VAL in @result, depending
* on the sign, and return -ERANGE.
*
* If the conversion underflows, store +/-0.0 in @result, depending on the
* sign, and return -ERANGE.
*
* Else store the converted value in @result, and return zero.
*/
int qemu_strtod(const char *nptr, const char **endptr, double *result)
{
char *ep;
if (!nptr) {
if (endptr) {
*endptr = nptr;
}
return -EINVAL;
}
errno = 0;
*result = strtod(nptr, &ep);
return check_strtox_error(nptr, ep, endptr, errno);
}
/**
* Convert string @nptr to a finite double.
*
* Works like qemu_strtod(), except that "NaN" and "inf" are rejected
* with -EINVAL and no conversion is performed.
*/
int qemu_strtod_finite(const char *nptr, const char **endptr, double *result)
{
double tmp;
int ret;
ret = qemu_strtod(nptr, endptr, &tmp);
if (!ret && !isfinite(tmp)) {
if (endptr) {
*endptr = nptr;
}
ret = -EINVAL;
}
if (ret != -EINVAL) {
*result = tmp;
}
return ret;
}
/**
* Searches for the first occurrence of 'c' in 's', and returns a pointer
* to the trailing null byte if none was found.