[v2,6/8] argparse: support parse unsigned base type

Message ID 20240125115229.41402-7-fengchengwen@huawei.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series add argparse library |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

fengchengwen Jan. 25, 2024, 11:52 a.m. UTC
  This commit supports parsing unsigned base type (u8/u16/u32/u64).

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 app/test/test_argparse.c    |  59 ++++++++++++++++--
 lib/argparse/rte_argparse.c | 116 ++++++++++++++++++++++++++++++++++++
 lib/argparse/rte_argparse.h |  10 +++-
 3 files changed, 179 insertions(+), 6 deletions(-)
  

Patch

diff --git a/app/test/test_argparse.c b/app/test/test_argparse.c
index 98c6cd6b80..470c1bd2b6 100644
--- a/app/test/test_argparse.c
+++ b/app/test/test_argparse.c
@@ -733,19 +733,68 @@  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!");
+	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!");
+	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!");
+	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!");
+	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 f33bd470ba..3cb1557b85 100644
--- a/lib/argparse/rte_argparse.c
+++ b/lib/argparse/rte_argparse.c
@@ -397,6 +397,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)
 {
@@ -406,6 +518,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),
 
 
 	/**