提交 4295f879 编写于 作者: M Markus Armbruster

util/cutils: Rewrite documentation of qemu_strtol() & friends

Fixes the following documentation bugs:

* Fails to document that null @nptr is safe.

* Fails to document that we return -EINVAL when no conversion could be
  performed (commit 47d4be12).

* Confuses long long with int64_t, and unsigned long long with
  uint64_t.

* Claims the unsigned conversions can underflow.  They can't.

While there, mark problematic assumptions that int64_t is long long,
and uint64_t is unsigned long long with FIXME comments.
Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
Reviewed-by: NEric Blake <eblake@redhat.com>
Reviewed-by: NPhilippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1487708048-2131-6-git-send-email-armbru@redhat.com>
上级 bc7c08a2
...@@ -265,9 +265,6 @@ int64_t qemu_strtosz(const char *nptr, char **end) ...@@ -265,9 +265,6 @@ int64_t qemu_strtosz(const char *nptr, char **end)
static int check_strtox_error(const char *p, char *endptr, const char **next, static int check_strtox_error(const char *p, char *endptr, const char **next,
int err) int err)
{ {
/* If no conversion was performed, prefer BSD behavior over glibc
* behavior.
*/
if (err == 0 && endptr == p) { if (err == 0 && endptr == p) {
err = EINVAL; err = EINVAL;
} }
...@@ -281,30 +278,28 @@ static int check_strtox_error(const char *p, char *endptr, const char **next, ...@@ -281,30 +278,28 @@ static int check_strtox_error(const char *p, char *endptr, const char **next,
} }
/** /**
* QEMU wrappers for strtol(), strtoll(), strtoul(), strotull() C functions. * Convert string @nptr to a long integer, and store it in @result.
* *
* Convert ASCII string @nptr to a long integer value * This is a wrapper around strtol() that is harder to misuse.
* from the given @base. Parameters @nptr, @endptr, @base * Semantics of @nptr, @endptr, @base match strtol() with differences
* follows same semantics as strtol() C function. * noted below.
* *
* Unlike from strtol() function, if @endptr is not NULL, this * @nptr may be null, and no conversion is performed then.
* function will return -EINVAL whenever it cannot fully convert *
* the string in @nptr with given @base to a long. This function returns * If no conversion is performed, store @nptr in *@endptr and return
* the result of the conversion only through the @result parameter. * -EINVAL.
* *
* If NULL is passed in @endptr, then the whole string in @ntpr * If @endptr is null, and the string isn't fully converted, return
* is a number otherwise it returns -EINVAL. * -EINVAL. This is the case when the pointer that would be stored in
* * a non-null @endptr points to a character other than '\0'.
* RETURN VALUE *
* Unlike from strtol() function, this wrapper returns either * If the conversion overflows @result, store LONG_MAX in @result,
* -EINVAL or the errno set by strtol() function (e.g -ERANGE). * and return -ERANGE.
* If the conversion overflows, -ERANGE is returned, and @result *
* is set to the max value of the desired type * If the conversion underflows @result, store LONG_MIN in @result,
* (e.g. LONG_MAX, LLONG_MAX, ULONG_MAX, ULLONG_MAX). If the case * and return -ERANGE.
* of underflow, -ERANGE is returned, and @result is set to the min *
* value of the desired type. For strtol(), strtoll(), @result is set to * Else store the converted value in @result, and return zero.
* LONG_MIN, LLONG_MIN, respectively, and for strtoul(), strtoull() it
* is set to 0.
*/ */
int qemu_strtol(const char *nptr, const char **endptr, int base, int qemu_strtol(const char *nptr, const char **endptr, int base,
long *result) long *result)
...@@ -325,17 +320,29 @@ int qemu_strtol(const char *nptr, const char **endptr, int base, ...@@ -325,17 +320,29 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
} }
/** /**
* Converts ASCII string to an unsigned long integer. * Convert string @nptr to an unsigned long, and store it in @result.
*
* This is a wrapper around strtoul() that is harder to misuse.
* Semantics of @nptr, @endptr, @base match strtoul() 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 string contains a negative number, value will be converted to * If the conversion overflows @result, store ULONG_MAX in @result,
* the unsigned representation of the signed value, unless the original * and return -ERANGE.
* (nonnegated) value would overflow, in this case, it will set @result
* to ULONG_MAX, and return ERANGE.
* *
* The same behavior holds, for qemu_strtoull() but sets @result to * Else store the converted value in @result, and return zero.
* ULLONG_MAX instead of ULONG_MAX.
* *
* See qemu_strtol() documentation for more info. * Note that a number with a leading minus sign gets converted without
* the minus sign, checked for overflow (see above), then negated (in
* @result's type). This is exactly how strtoul() works.
*/ */
int qemu_strtoul(const char *nptr, const char **endptr, int base, int qemu_strtoul(const char *nptr, const char **endptr, int base,
unsigned long *result) unsigned long *result)
...@@ -360,9 +367,10 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base, ...@@ -360,9 +367,10 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
} }
/** /**
* Converts ASCII string to a long long integer. * Convert string @nptr to an int64_t.
* *
* See qemu_strtol() documentation for more info. * Works like qemu_strtol(), except it stores INT64_MAX on overflow,
* and INT_MIN on underflow.
*/ */
int qemu_strtoll(const char *nptr, const char **endptr, int base, int qemu_strtoll(const char *nptr, const char **endptr, int base,
int64_t *result) int64_t *result)
...@@ -376,6 +384,7 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base, ...@@ -376,6 +384,7 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base,
err = -EINVAL; err = -EINVAL;
} else { } else {
errno = 0; errno = 0;
/* FIXME This assumes int64_t is long long */
*result = strtoll(nptr, &p, base); *result = strtoll(nptr, &p, base);
err = check_strtox_error(nptr, p, endptr, errno); err = check_strtox_error(nptr, p, endptr, errno);
} }
...@@ -383,9 +392,9 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base, ...@@ -383,9 +392,9 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base,
} }
/** /**
* Converts ASCII string to an unsigned long long integer. * Convert string @nptr to an uint64_t.
* *
* See qemu_strtol() documentation for more info. * Works like qemu_strtoul(), except it stores UINT64_MAX on overflow.
*/ */
int qemu_strtoull(const char *nptr, const char **endptr, int base, int qemu_strtoull(const char *nptr, const char **endptr, int base,
uint64_t *result) uint64_t *result)
...@@ -399,6 +408,7 @@ int qemu_strtoull(const char *nptr, const char **endptr, int base, ...@@ -399,6 +408,7 @@ int qemu_strtoull(const char *nptr, const char **endptr, int base,
err = -EINVAL; err = -EINVAL;
} else { } else {
errno = 0; errno = 0;
/* FIXME This assumes uint64_t is unsigned long long */
*result = strtoull(nptr, &p, base); *result = strtoull(nptr, &p, base);
/* Windows returns 1 for negative out-of-range values. */ /* Windows returns 1 for negative out-of-range values. */
if (errno == ERANGE) { if (errno == ERANGE) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册