mirror of https://gitee.com/openkylin/qemu.git
cutils: Add qemu_strtoll() wrapper
Add wrapper for strtoll() function. Include unit tests. Signed-off-by: Carlos L. Torres <carlos.torres@rackspace.com> Message-Id: <7454a6bb9ec03b629e8beb4f109dd30dc2c9804c.1437346779.git.carlos.torres@rackspace.com> [Use int64_t in prototype, since that's what QEMU uses. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
c817c01548
commit
8ac4df40cc
|
@ -207,6 +207,8 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
|
|||
long *result);
|
||||
int qemu_strtoul(const char *nptr, const char **endptr, int base,
|
||||
unsigned long *result);
|
||||
int qemu_strtoll(const char *nptr, const char **endptr, int base,
|
||||
int64_t *result);
|
||||
|
||||
int parse_uint(const char *s, unsigned long long *value, char **endptr,
|
||||
int base);
|
||||
|
|
|
@ -802,6 +802,294 @@ static void test_qemu_strtoul_full_max(void)
|
|||
g_assert_cmpint(res, ==, ULONG_MAX);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_correct(void)
|
||||
{
|
||||
const char *str = "12345 foo";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 12345);
|
||||
g_assert(endptr == str + 5);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_null(void)
|
||||
{
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(NULL, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
g_assert(endptr == NULL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_empty(void)
|
||||
{
|
||||
const char *str = "";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_whitespace(void)
|
||||
{
|
||||
const char *str = " \t ";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_invalid(void)
|
||||
{
|
||||
const char *str = " xxxx \t abc";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert(endptr == str);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_trailing(void)
|
||||
{
|
||||
const char *str = "123xxx";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 123);
|
||||
g_assert(endptr == str + 3);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_octal(void)
|
||||
{
|
||||
const char *str = "0123";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 8, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0123);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
|
||||
endptr = &f;
|
||||
res = 999;
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0123);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_decimal(void)
|
||||
{
|
||||
const char *str = "0123";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 10, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 123);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
|
||||
str = "123";
|
||||
endptr = &f;
|
||||
res = 999;
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 123);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_hex(void)
|
||||
{
|
||||
const char *str = "0123";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 16, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0x123);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
|
||||
str = "0x123";
|
||||
endptr = &f;
|
||||
res = 999;
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0x123);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_max(void)
|
||||
{
|
||||
const char *str = g_strdup_printf("%lld", LLONG_MAX);
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, LLONG_MAX);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_overflow(void)
|
||||
{
|
||||
const char *str = "99999999999999999999999999999999999999999999";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, -ERANGE);
|
||||
g_assert_cmpint(res, ==, LLONG_MAX);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_underflow(void)
|
||||
{
|
||||
const char *str = "-99999999999999999999999999999999999999999999";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, -ERANGE);
|
||||
g_assert_cmpint(res, ==, LLONG_MIN);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_negative(void)
|
||||
{
|
||||
const char *str = " \t -321";
|
||||
char f = 'X';
|
||||
const char *endptr = &f;
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, &endptr, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, -321);
|
||||
g_assert(endptr == str + strlen(str));
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_full_correct(void)
|
||||
{
|
||||
const char *str = "123";
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 123);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_full_null(void)
|
||||
{
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(NULL, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_full_empty(void)
|
||||
{
|
||||
const char *str = "";
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, 0);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_full_negative(void)
|
||||
{
|
||||
const char *str = " \t -321";
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, -321);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_full_trailing(void)
|
||||
{
|
||||
const char *str = "123xxx";
|
||||
int64_t res = 999;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, -EINVAL);
|
||||
}
|
||||
|
||||
static void test_qemu_strtoll_full_max(void)
|
||||
{
|
||||
|
||||
const char *str = g_strdup_printf("%lld", LLONG_MAX);
|
||||
int64_t res;
|
||||
int err;
|
||||
|
||||
err = qemu_strtoll(str, NULL, 0, &res);
|
||||
|
||||
g_assert_cmpint(err, ==, 0);
|
||||
g_assert_cmpint(res, ==, LLONG_MAX);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
@ -884,5 +1172,37 @@ int main(int argc, char **argv)
|
|||
g_test_add_func("/cutils/qemu_strtoul_full/max",
|
||||
test_qemu_strtoul_full_max);
|
||||
|
||||
/* qemu_strtoll() tests */
|
||||
g_test_add_func("/cutils/qemu_strtoll/correct", test_qemu_strtoll_correct);
|
||||
g_test_add_func("/cutils/qemu_strtoll/null", test_qemu_strtoll_null);
|
||||
g_test_add_func("/cutils/qemu_strtoll/empty", test_qemu_strtoll_empty);
|
||||
g_test_add_func("/cutils/qemu_strtoll/whitespace",
|
||||
test_qemu_strtoll_whitespace);
|
||||
g_test_add_func("/cutils/qemu_strtoll/invalid", test_qemu_strtoll_invalid);
|
||||
g_test_add_func("/cutils/qemu_strtoll/trailing",
|
||||
test_qemu_strtoll_trailing);
|
||||
g_test_add_func("/cutils/qemu_strtoll/octal", test_qemu_strtoll_octal);
|
||||
g_test_add_func("/cutils/qemu_strtoll/decimal", test_qemu_strtoll_decimal);
|
||||
g_test_add_func("/cutils/qemu_strtoll/hex", test_qemu_strtoll_hex);
|
||||
g_test_add_func("/cutils/qemu_strtoll/max", test_qemu_strtoll_max);
|
||||
g_test_add_func("/cutils/qemu_strtoll/overflow",
|
||||
test_qemu_strtoll_overflow);
|
||||
g_test_add_func("/cutils/qemu_strtoll/underflow",
|
||||
test_qemu_strtoll_underflow);
|
||||
g_test_add_func("/cutils/qemu_strtoll/negative",
|
||||
test_qemu_strtoll_negative);
|
||||
g_test_add_func("/cutils/qemu_strtoll_full/correct",
|
||||
test_qemu_strtoll_full_correct);
|
||||
g_test_add_func("/cutils/qemu_strtoll_full/null",
|
||||
test_qemu_strtoll_full_null);
|
||||
g_test_add_func("/cutils/qemu_strtoll_full/empty",
|
||||
test_qemu_strtoll_full_empty);
|
||||
g_test_add_func("/cutils/qemu_strtoll_full/negative",
|
||||
test_qemu_strtoll_full_negative);
|
||||
g_test_add_func("/cutils/qemu_strtoll_full/trailing",
|
||||
test_qemu_strtoll_full_trailing);
|
||||
g_test_add_func("/cutils/qemu_strtoll_full/max",
|
||||
test_qemu_strtoll_full_max);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
|
@ -448,6 +448,29 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
|
|||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts ASCII string to a long long integer.
|
||||
*
|
||||
* See qemu_strtol() documentation for more info.
|
||||
*/
|
||||
int qemu_strtoll(const char *nptr, const char **endptr, int base,
|
||||
int64_t *result)
|
||||
{
|
||||
char *p;
|
||||
int err = 0;
|
||||
if (!nptr) {
|
||||
if (endptr) {
|
||||
*endptr = nptr;
|
||||
}
|
||||
err = -EINVAL;
|
||||
} else {
|
||||
errno = 0;
|
||||
*result = strtoll(nptr, &p, base);
|
||||
err = check_strtox_error(endptr, p, errno);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse_uint:
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue