From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C827C439CC; Fri, 26 Jan 2024 07:16:12 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 60A7B42E55; Fri, 26 Jan 2024 07:14:21 +0100 (CET) Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by mails.dpdk.org (Postfix) with ESMTP id C967740289 for ; Fri, 26 Jan 2024 07:14:08 +0100 (CET) Received: from mail.maildlp.com (unknown [172.19.88.194]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4TLnRw5chVz18MJf; Fri, 26 Jan 2024 14:13:00 +0800 (CST) Received: from dggpeml500024.china.huawei.com (unknown [7.185.36.10]) by mail.maildlp.com (Postfix) with ESMTPS id D1EC5140444; Fri, 26 Jan 2024 14:14:05 +0800 (CST) Received: from localhost.localdomain (10.50.165.33) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Fri, 26 Jan 2024 14:14:05 +0800 From: Chengwen Feng To: , , , CC: Subject: [PATCH v3 6/8] argparse: support parse unsigned base type Date: Fri, 26 Jan 2024 06:10:11 +0000 Message-ID: <20240126061013.53608-7-fengchengwen@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240126061013.53608-1-fengchengwen@huawei.com> References: <20231121122651.7078-1-fengchengwen@huawei.com> <20240126061013.53608-1-fengchengwen@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.50.165.33] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To dggpeml500024.china.huawei.com (7.185.36.10) X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This commit supports parsing unsigned base type (u8/u16/u32/u64). Signed-off-by: Chengwen Feng --- app/test/test_argparse.c | 63 ++++++++++++++++++-- lib/argparse/rte_argparse.c | 116 ++++++++++++++++++++++++++++++++++++ lib/argparse/rte_argparse.h | 10 +++- 3 files changed, 183 insertions(+), 6 deletions(-) diff --git a/app/test/test_argparse.c b/app/test/test_argparse.c index 2b1391f3b0..df11a129ba 100644 --- a/app/test/test_argparse.c +++ b/app/test/test_argparse.c @@ -751,19 +751,72 @@ static int test_argparse_parse_type(void) { char *str_erange = test_strdup("9999999999999999999999999999999999"); + char *str_erange_u32 = test_strdup("4294967296"); + char *str_erange_u16 = test_strdup("65536"); + char *str_erange_u8 = test_strdup("256"); char *str_invalid = test_strdup("1a"); char *str_ok = test_strdup("123"); - int value; + uint16_t val_u16; + uint32_t val_u32; + uint64_t val_u64; + uint8_t val_u8; + int val_int; int ret; /* test for int parsing */ - ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_INT, &value); + ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_INT, &val_int); TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); - ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_INT, &value); + ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_INT, &val_int); TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); - ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_INT, &value); + ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_INT, &val_int); TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); - TEST_ASSERT(value == 123, "Argparse parse type expect failed!"); + TEST_ASSERT(val_int == 123, "Argparse parse type expect failed!"); + + /* test for u8 parsing */ + ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + ret = rte_argparse_parse_type(str_erange_u8, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + val_u8 = 0; + ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U8, &val_u8); + TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); + TEST_ASSERT(val_u8 == 123, "Argparse parse type expect failed!"); + + /* test for u16 parsing */ + ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + ret = rte_argparse_parse_type(str_erange_u16, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + val_u16 = 0; + ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U16, &val_u16); + TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); + TEST_ASSERT(val_u16 == 123, "Argparse parse type expect failed!"); + + /* test for u32 parsing */ + ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + ret = rte_argparse_parse_type(str_erange_u32, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + val_u32 = 0; + ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U32, &val_u32); + TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); + TEST_ASSERT(val_u32 == 123, "Argparse parse type expect failed!"); + + /* test for u64 parsing */ + ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_U64, &val_u64); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_U64, &val_u64); + TEST_ASSERT(ret != 0, "Argparse parse type expect failed!"); + val_u64 = 0; + ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_U64, &val_u64); + TEST_ASSERT(ret == 0, "Argparse parse type expect failed!"); + TEST_ASSERT(val_u64 == 123, "Argparse parse type expect failed!"); return 0; } diff --git a/lib/argparse/rte_argparse.c b/lib/argparse/rte_argparse.c index c179041e89..4b10f3e519 100644 --- a/lib/argparse/rte_argparse.c +++ b/lib/argparse/rte_argparse.c @@ -401,6 +401,118 @@ parse_arg_int(struct rte_argparse_arg *arg, const char *value) return 0; } +static int +parse_arg_u8(struct rte_argparse_arg *arg, const char *value) +{ + unsigned long val; + char *s = NULL; + + if (value == NULL) { + *(uint8_t *)arg->val_saver = (uint8_t)(intptr_t)arg->val_set; + return 0; + } + + errno = 0; + val = strtoul(value, &s, 0); + if (errno == ERANGE || val > UINT8_MAX) { + ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long); + return -EINVAL; + } + + if (s[0] != '\0') { + ARGPARSE_LOG(ERR, "argument %s expect an uint8 value!", arg->name_long); + return -EINVAL; + } + + *(uint8_t *)arg->val_saver = val; + + return 0; +} + +static int +parse_arg_u16(struct rte_argparse_arg *arg, const char *value) +{ + unsigned long val; + char *s = NULL; + + if (value == NULL) { + *(uint16_t *)arg->val_saver = (uint16_t)(intptr_t)arg->val_set; + return 0; + } + + errno = 0; + val = strtoul(value, &s, 0); + if (errno == ERANGE || val > UINT16_MAX) { + ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long); + return -EINVAL; + } + + if (s[0] != '\0') { + ARGPARSE_LOG(ERR, "argument %s expect an uint16 value!", arg->name_long); + return -EINVAL; + } + + *(uint16_t *)arg->val_saver = val; + + return 0; +} + +static int +parse_arg_u32(struct rte_argparse_arg *arg, const char *value) +{ + unsigned long val; + char *s = NULL; + + if (value == NULL) { + *(uint32_t *)arg->val_saver = (uint32_t)(intptr_t)arg->val_set; + return 0; + } + + errno = 0; + val = strtoul(value, &s, 0); + if (errno == ERANGE || val > UINT32_MAX) { + ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long); + return -EINVAL; + } + + if (s[0] != '\0') { + ARGPARSE_LOG(ERR, "argument %s expect an uint32 value!", arg->name_long); + return -EINVAL; + } + + *(uint32_t *)arg->val_saver = val; + + return 0; +} + +static int +parse_arg_u64(struct rte_argparse_arg *arg, const char *value) +{ + unsigned long val; + char *s = NULL; + + if (value == NULL) { + *(uint64_t *)arg->val_saver = (uint64_t)(intptr_t)arg->val_set; + return 0; + } + + errno = 0; + val = strtoull(value, &s, 0); + if (errno == ERANGE) { + ARGPARSE_LOG(ERR, "argument %s numerical out of range!", arg->name_long); + return -EINVAL; + } + + if (s[0] != '\0') { + ARGPARSE_LOG(ERR, "argument %s expect an uint64 value!", arg->name_long); + return -EINVAL; + } + + *(uint64_t *)arg->val_saver = val; + + return 0; +} + static int parse_arg_autosave(struct rte_argparse_arg *arg, const char *value) { @@ -410,6 +522,10 @@ parse_arg_autosave(struct rte_argparse_arg *arg, const char *value) /* Sort by RTE_ARGPARSE_ARG_VALUE_XXX. */ { NULL }, { parse_arg_int }, + { parse_arg_u8 }, + { parse_arg_u16 }, + { parse_arg_u32 }, + { parse_arg_u64 }, }; uint32_t index = arg_attr_val_type(arg); int ret = -EINVAL; diff --git a/lib/argparse/rte_argparse.h b/lib/argparse/rte_argparse.h index a795263a81..7f785f017e 100644 --- a/lib/argparse/rte_argparse.h +++ b/lib/argparse/rte_argparse.h @@ -59,8 +59,16 @@ enum rte_argparse_flag { /** The argument's value is int type. */ RTE_ARGPARSE_ARG_VALUE_INT = RTE_SHIFT_VAL64(1, 2), + /** The argument's value is uint8 type. */ + RTE_ARGPARSE_ARG_VALUE_U8 = RTE_SHIFT_VAL64(2, 2), + /** The argument's value is uint16 type. */ + RTE_ARGPARSE_ARG_VALUE_U16 = RTE_SHIFT_VAL64(3, 2), + /** The argument's value is uint32 type. */ + RTE_ARGPARSE_ARG_VALUE_U32 = RTE_SHIFT_VAL64(4, 2), + /** The argument's value is uint64 type. */ + RTE_ARGPARSE_ARG_VALUE_U64 = RTE_SHIFT_VAL64(5, 2), /** Max value type. */ - RTE_ARGPARSE_ARG_VALUE_MAX = RTE_SHIFT_VAL64(2, 2), + RTE_ARGPARSE_ARG_VALUE_MAX = RTE_SHIFT_VAL64(6, 2), /** -- 2.17.1