Commit ca28f548 authored by David Hildenbrand's avatar David Hildenbrand Committed by Markus Armbruster
Browse files

cutils: Add qemu_strtod() and qemu_strtod_finite()



Let's provide a wrapper for strtod().

Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Message-Id: <20181121164421.20780-2-david@redhat.com>
Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
parent c3ec0fa1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+65 −0
Original line number Diff line number Diff line
@@ -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.