[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v3 1/8] cutils: add qemu_strtoi & qemu_strtoui p
From: |
Marc-André Lureau |
Subject: |
Re: [Qemu-devel] [PATCH v3 1/8] cutils: add qemu_strtoi & qemu_strtoui parsers for int/unsigned int types |
Date: |
Wed, 3 Jan 2018 19:24:33 +0100 |
On Fri, Dec 22, 2017 at 2:45 PM, Daniel P. Berrange <address@hidden> wrote:
> There are qemu_strtoNN functions for various sized integers. This adds two
> more for plain int & unsigned int types, with suitable range checking.
>
> Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
> ---
> include/qemu/cutils.h | 4 +
> tests/test-cutils.c | 653
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> util/cutils.c | 104 ++++++++
> 3 files changed, 761 insertions(+)
>
> diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
> index f0878eaafa..a663340b23 100644
> --- a/include/qemu/cutils.h
> +++ b/include/qemu/cutils.h
> @@ -126,6 +126,10 @@ time_t mktimegm(struct tm *tm);
> int qemu_fdatasync(int fd);
> int fcntl_setfl(int fd, int flag);
> int qemu_parse_fd(const char *param);
> +int qemu_strtoi(const char *nptr, const char **endptr, int base,
> + int *result);
> +int qemu_strtoui(const char *nptr, const char **endptr, int base,
> + unsigned int *result);
> int qemu_strtol(const char *nptr, const char **endptr, int base,
> long *result);
> int qemu_strtoul(const char *nptr, const char **endptr, int base,
> diff --git a/tests/test-cutils.c b/tests/test-cutils.c
> index f64a49b7fb..0b2b5d417b 100644
> --- a/tests/test-cutils.c
> +++ b/tests/test-cutils.c
> @@ -223,6 +223,579 @@ static void test_parse_uint_full_correct(void)
> g_assert_cmpint(i, ==, 123);
> }
>
> +static void test_qemu_strtoi_correct(void)
> +{
> + const char *str = "12345 foo";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 12345);
> + g_assert(endptr == str + 5);
> +}
> +
> +static void test_qemu_strtoi_null(void)
> +{
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(NULL, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == NULL);
> +}
> +
> +static void test_qemu_strtoi_empty(void)
> +{
> + const char *str = "";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == str);
> +}
> +
> +static void test_qemu_strtoi_whitespace(void)
> +{
> + const char *str = " \t ";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == str);
> +}
> +
> +static void test_qemu_strtoi_invalid(void)
> +{
> + const char *str = " xxxx \t abc";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == str);
> +}
> +
> +static void test_qemu_strtoi_trailing(void)
> +{
> + const char *str = "123xxx";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 123);
> + g_assert(endptr == str + 3);
> +}
> +
> +static void test_qemu_strtoi_octal(void)
> +{
> + const char *str = "0123";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 8, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 0123);
> + g_assert(endptr == str + strlen(str));
> +
> + res = 999;
> + endptr = &f;
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 0123);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoi_decimal(void)
> +{
> + const char *str = "0123";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 10, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 123);
> + g_assert(endptr == str + strlen(str));
> +
> + str = "123";
> + res = 999;
> + endptr = &f;
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 123);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoi_hex(void)
> +{
> + const char *str = "0123";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 16, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 0x123);
> + g_assert(endptr == str + strlen(str));
> +
> + str = "0x123";
> + res = 999;
> + endptr = &f;
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 0x123);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoi_max(void)
> +{
> + char *str = g_strdup_printf("%d", INT_MAX);
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, INT_MAX);
> + g_assert(endptr == str + strlen(str));
> + g_free(str);
> +}
> +
> +static void test_qemu_strtoi_overflow(void)
> +{
> + const char *str = "99999999999999999999999999999999999999999999";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -ERANGE);
> + g_assert_cmpint(res, ==, INT_MAX);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoi_underflow(void)
> +{
> + const char *str = "-99999999999999999999999999999999999999999999";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -ERANGE);
> + g_assert_cmpint(res, ==, INT_MIN);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoi_negative(void)
> +{
> + const char *str = " \t -321";
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, -321);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoi_full_correct(void)
> +{
> + const char *str = "123";
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, 123);
> +}
> +
> +static void test_qemu_strtoi_full_null(void)
> +{
> + char f = 'X';
> + const char *endptr = &f;
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(NULL, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == NULL);
> +}
> +
> +static void test_qemu_strtoi_full_empty(void)
> +{
> + const char *str = "";
> + int res = 999L;
> + int err;
> +
> + err = qemu_strtoi(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> +}
> +
> +static void test_qemu_strtoi_full_negative(void)
> +{
> + const char *str = " \t -321";
> + int res = 999;
> + int err;
> +
> + err = qemu_strtoi(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, -321);
> +}
> +
> +static void test_qemu_strtoi_full_trailing(void)
> +{
> + const char *str = "123xxx";
> + int res;
> + int err;
> +
> + err = qemu_strtoi(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> +}
> +
> +static void test_qemu_strtoi_full_max(void)
> +{
> + char *str = g_strdup_printf("%d", INT_MAX);
> + int res;
> + int err;
> +
> + err = qemu_strtoi(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpint(res, ==, INT_MAX);
> + g_free(str);
> +}
> +
> +static void test_qemu_strtoui_correct(void)
> +{
> + const char *str = "12345 foo";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, 12345);
> + g_assert(endptr == str + 5);
> +}
> +
> +static void test_qemu_strtoui_null(void)
> +{
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(NULL, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == NULL);
> +}
> +
> +static void test_qemu_strtoui_empty(void)
> +{
> + const char *str = "";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == str);
> +}
> +
> +static void test_qemu_strtoui_whitespace(void)
> +{
> + const char *str = " \t ";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == str);
> +}
> +
> +static void test_qemu_strtoui_invalid(void)
> +{
> + const char *str = " xxxx \t abc";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> + g_assert(endptr == str);
> +}
> +
> +static void test_qemu_strtoui_trailing(void)
> +{
> + const char *str = "123xxx";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, 123);
> + g_assert(endptr == str + 3);
> +}
> +
> +static void test_qemu_strtoui_octal(void)
> +{
> + const char *str = "0123";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 8, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, 0123);
> + g_assert(endptr == str + strlen(str));
> +
> + res = 999;
> + endptr = &f;
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, 0123);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoui_decimal(void)
> +{
> + const char *str = "0123";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 10, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, 123);
> + g_assert(endptr == str + strlen(str));
> +
> + str = "123";
> + res = 999;
> + endptr = &f;
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, 123);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoui_hex(void)
> +{
> + const char *str = "0123";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 16, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmphex(res, ==, 0x123);
> + g_assert(endptr == str + strlen(str));
> +
> + str = "0x123";
> + res = 999;
> + endptr = &f;
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmphex(res, ==, 0x123);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoui_max(void)
> +{
> + char *str = g_strdup_printf("%u", UINT_MAX);
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmphex(res, ==, UINT_MAX);
> + g_assert(endptr == str + strlen(str));
> + g_free(str);
> +}
> +
> +static void test_qemu_strtoui_overflow(void)
> +{
> + const char *str = "99999999999999999999999999999999999999999999";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -ERANGE);
> + g_assert_cmphex(res, ==, UINT_MAX);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoui_underflow(void)
> +{
> + const char *str = "-99999999999999999999999999999999999999999999";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, -ERANGE);
> + g_assert_cmpuint(res, ==, (unsigned int)-1);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoui_negative(void)
> +{
> + const char *str = " \t -321";
> + char f = 'X';
> + const char *endptr = &f;
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, &endptr, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, (unsigned int)-321);
> + g_assert(endptr == str + strlen(str));
> +}
> +
> +static void test_qemu_strtoui_full_correct(void)
> +{
> + const char *str = "123";
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, 123);
> +}
> +
> +static void test_qemu_strtoui_full_null(void)
> +{
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(NULL, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> +}
> +
> +static void test_qemu_strtoui_full_empty(void)
> +{
> + const char *str = "";
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> +}
> +static void test_qemu_strtoui_full_negative(void)
> +{
> + const char *str = " \t -321";
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, NULL, 0, &res);
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmpuint(res, ==, (unsigned int)-321);
> +}
> +
> +static void test_qemu_strtoui_full_trailing(void)
> +{
> + const char *str = "123xxx";
> + unsigned int res;
> + int err;
> +
> + err = qemu_strtoui(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, -EINVAL);
> +}
> +
> +static void test_qemu_strtoui_full_max(void)
> +{
> + char *str = g_strdup_printf("%u", UINT_MAX);
> + unsigned int res = 999;
> + int err;
> +
> + err = qemu_strtoui(str, NULL, 0, &res);
> +
> + g_assert_cmpint(err, ==, 0);
> + g_assert_cmphex(res, ==, UINT_MAX);
> + g_free(str);
> +}
> +
> static void test_qemu_strtol_correct(void)
> {
> const char *str = "12345 foo";
> @@ -1612,6 +2185,86 @@ int main(int argc, char **argv)
> g_test_add_func("/cutils/parse_uint_full/correct",
> test_parse_uint_full_correct);
>
> + /* qemu_strtoi() tests */
> + g_test_add_func("/cutils/qemu_strtoi/correct",
> + test_qemu_strtoi_correct);
> + g_test_add_func("/cutils/qemu_strtoi/null",
> + test_qemu_strtoi_null);
> + g_test_add_func("/cutils/qemu_strtoi/empty",
> + test_qemu_strtoi_empty);
> + g_test_add_func("/cutils/qemu_strtoi/whitespace",
> + test_qemu_strtoi_whitespace);
> + g_test_add_func("/cutils/qemu_strtoi/invalid",
> + test_qemu_strtoi_invalid);
> + g_test_add_func("/cutils/qemu_strtoi/trailing",
> + test_qemu_strtoi_trailing);
> + g_test_add_func("/cutils/qemu_strtoi/octal",
> + test_qemu_strtoi_octal);
> + g_test_add_func("/cutils/qemu_strtoi/decimal",
> + test_qemu_strtoi_decimal);
> + g_test_add_func("/cutils/qemu_strtoi/hex",
> + test_qemu_strtoi_hex);
> + g_test_add_func("/cutils/qemu_strtoi/max",
> + test_qemu_strtoi_max);
> + g_test_add_func("/cutils/qemu_strtoi/overflow",
> + test_qemu_strtoi_overflow);
> + g_test_add_func("/cutils/qemu_strtoi/underflow",
> + test_qemu_strtoi_underflow);
> + g_test_add_func("/cutils/qemu_strtoi/negative",
> + test_qemu_strtoi_negative);
> + g_test_add_func("/cutils/qemu_strtoi_full/correct",
> + test_qemu_strtoi_full_correct);
> + g_test_add_func("/cutils/qemu_strtoi_full/null",
> + test_qemu_strtoi_full_null);
> + g_test_add_func("/cutils/qemu_strtoi_full/empty",
> + test_qemu_strtoi_full_empty);
> + g_test_add_func("/cutils/qemu_strtoi_full/negative",
> + test_qemu_strtoi_full_negative);
> + g_test_add_func("/cutils/qemu_strtoi_full/trailing",
> + test_qemu_strtoi_full_trailing);
> + g_test_add_func("/cutils/qemu_strtoi_full/max",
> + test_qemu_strtoi_full_max);
> +
> + /* qemu_strtoui() tests */
> + g_test_add_func("/cutils/qemu_strtoui/correct",
> + test_qemu_strtoui_correct);
> + g_test_add_func("/cutils/qemu_strtoui/null",
> + test_qemu_strtoui_null);
> + g_test_add_func("/cutils/qemu_strtoui/empty",
> + test_qemu_strtoui_empty);
> + g_test_add_func("/cutils/qemu_strtoui/whitespace",
> + test_qemu_strtoui_whitespace);
> + g_test_add_func("/cutils/qemu_strtoui/invalid",
> + test_qemu_strtoui_invalid);
> + g_test_add_func("/cutils/qemu_strtoui/trailing",
> + test_qemu_strtoui_trailing);
> + g_test_add_func("/cutils/qemu_strtoui/octal",
> + test_qemu_strtoui_octal);
> + g_test_add_func("/cutils/qemu_strtoui/decimal",
> + test_qemu_strtoui_decimal);
> + g_test_add_func("/cutils/qemu_strtoui/hex",
> + test_qemu_strtoui_hex);
> + g_test_add_func("/cutils/qemu_strtoui/max",
> + test_qemu_strtoui_max);
> + g_test_add_func("/cutils/qemu_strtoui/overflow",
> + test_qemu_strtoui_overflow);
> + g_test_add_func("/cutils/qemu_strtoui/underflow",
> + test_qemu_strtoui_underflow);
> + g_test_add_func("/cutils/qemu_strtoui/negative",
> + test_qemu_strtoui_negative);
> + g_test_add_func("/cutils/qemu_strtoui_full/correct",
> + test_qemu_strtoui_full_correct);
> + g_test_add_func("/cutils/qemu_strtoui_full/null",
> + test_qemu_strtoui_full_null);
> + g_test_add_func("/cutils/qemu_strtoui_full/empty",
> + test_qemu_strtoui_full_empty);
> + g_test_add_func("/cutils/qemu_strtoui_full/negative",
> + test_qemu_strtoui_full_negative);
> + g_test_add_func("/cutils/qemu_strtoui_full/trailing",
> + test_qemu_strtoui_full_trailing);
> + g_test_add_func("/cutils/qemu_strtoui_full/max",
> + test_qemu_strtoui_full_max);
> +
> /* qemu_strtol() tests */
> g_test_add_func("/cutils/qemu_strtol/correct",
> test_qemu_strtol_correct);
> diff --git a/util/cutils.c b/util/cutils.c
> index b33ede83d1..9f05b331d9 100644
> --- a/util/cutils.c
> +++ b/util/cutils.c
> @@ -297,6 +297,110 @@ static int check_strtox_error(const char *nptr, char
> *ep,
> return -libc_errno;
> }
>
> +/**
> + * Convert string @nptr to a long integer, and store it in @result.
> + *
> + * This is a wrapper around strtol() that is harder to misuse.
> + * Semantics of @nptr, @endptr, @base match strtol() with differences
> + * noted below.
> + *
> + * @nptr may be null, and no conversion is performed then.
> + *
> + * If no conversion is performed, store @nptr in address@hidden 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 @result, store INT_MAX in @result,
> + * and return -ERANGE.
> + *
> + * If the conversion underflows @result, store INT_MIN in @result,
> + * and return -ERANGE.
> + *
> + * Else store the converted value in @result, and return zero.
> + */
> +int qemu_strtoi(const char *nptr, const char **endptr, int base,
> + int *result)
> +{
> + char *ep;
> + long lresult;
> +
> + if (!nptr) {
> + if (endptr) {
> + *endptr = nptr;
> + }
> + return -EINVAL;
> + }
> +
> + errno = 0;
> + lresult = strtol(nptr, &ep, base);
> + if (lresult < INT_MIN) {
> + *result = INT_MIN;
> + } else if (lresult > INT_MAX) {
> + *result = INT_MAX;
> + } else {
> + *result = lresult;
> + }
> + return check_strtox_error(nptr, ep, endptr, errno);
> +}
> +
> +/**
> + * Convert string @nptr to an unsigned int, 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 address@hidden 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 @result, store UINT_MAX in @result,
> + * and return -ERANGE.
> + *
> + * Else store the converted value in @result, and return zero.
> + *
> + * 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_strtoui(const char *nptr, const char **endptr, int base,
> + unsigned int *result)
> +{
> + char *ep;
> + long lresult;
> +
> + if (!nptr) {
> + if (endptr) {
> + *endptr = nptr;
> + }
> + return -EINVAL;
> + }
> +
> + errno = 0;
> + lresult = strtol(nptr, &ep, base);
> + /* Windows returns 1 for negative out-of-range values. */
> + if (errno == ERANGE) {
> + *result = -1;
> + } else {
> + if (lresult > UINT_MAX) {
> + *result = UINT_MAX;
> + } else if (lresult < INT_MIN) {
> + *result = UINT_MAX;
> + } else {
> + *result = lresult;
> + }
> + }
> + return check_strtox_error(nptr, ep, endptr, errno);
> +}
> +
> /**
> * Convert string @nptr to a long integer, and store it in @result.
> *
> --
> 2.14.3
>
>
--
Marc-André Lureau
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [PATCH v3 1/8] cutils: add qemu_strtoi & qemu_strtoui parsers for int/unsigned int types,
Marc-André Lureau <=