[v3,5/8] argparse: provide parsing known type API

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

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

fengchengwen Jan. 26, 2024, 6:10 a.m. UTC
  Provide API which could parsing the value from the input string based
on the value type. This API could used in user callback when parsing
string by argparse or kvargs library.

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 app/test/test_argparse.c    | 22 ++++++++++++++++++++++
 lib/argparse/rte_argparse.c | 19 +++++++++++++++++++
 lib/argparse/rte_argparse.h | 19 +++++++++++++++++++
 lib/argparse/version.map    |  1 +
 4 files changed, 61 insertions(+)
  

Patch

diff --git a/app/test/test_argparse.c b/app/test/test_argparse.c
index 59dc79c8c6..2b1391f3b0 100644
--- a/app/test/test_argparse.c
+++ b/app/test/test_argparse.c
@@ -747,6 +747,27 @@  test_argparse_pos_callback_parse_int(void)
 	return 0;
 }
 
+static int
+test_argparse_parse_type(void)
+{
+	char *str_erange = test_strdup("9999999999999999999999999999999999");
+	char *str_invalid = test_strdup("1a");
+	char *str_ok = test_strdup("123");
+	int value;
+	int ret;
+
+	/* test for int parsing */
+	ret = rte_argparse_parse_type(str_erange, RTE_ARGPARSE_ARG_VALUE_INT, &value);
+	TEST_ASSERT(ret != 0, "Argparse parse type expect failed!");
+	ret = rte_argparse_parse_type(str_invalid, RTE_ARGPARSE_ARG_VALUE_INT, &value);
+	TEST_ASSERT(ret != 0, "Argparse parse type expect failed!");
+	ret = rte_argparse_parse_type(str_ok, RTE_ARGPARSE_ARG_VALUE_INT, &value);
+	TEST_ASSERT(ret == 0, "Argparse parse type expect failed!");
+	TEST_ASSERT(value == 123, "Argparse parse type expect failed!");
+
+	return 0;
+}
+
 static struct unit_test_suite argparse_test_suite = {
 	.suite_name = "Argparse Unit Test Suite",
 	.setup = test_argparse_setup,
@@ -768,6 +789,7 @@  static struct unit_test_suite argparse_test_suite = {
 		TEST_CASE(test_argparse_opt_callback_parse_int_of_optional_val),
 		TEST_CASE(test_argparse_pos_autosave_parse_int),
 		TEST_CASE(test_argparse_pos_callback_parse_int),
+		TEST_CASE(test_argparse_parse_type),
 
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
diff --git a/lib/argparse/rte_argparse.c b/lib/argparse/rte_argparse.c
index ed9b2f778a..c179041e89 100644
--- a/lib/argparse/rte_argparse.c
+++ b/lib/argparse/rte_argparse.c
@@ -606,3 +606,22 @@  rte_argparse_parse(struct rte_argparse *obj, int argc, char **argv)
 		exit(ret);
 	return ret;
 }
+
+int
+rte_argparse_parse_type(const char *str, uint64_t val_type, void *val)
+{
+	uint32_t cmp_max = RTE_FIELD_GET64(ARG_ATTR_VAL_TYPE_MASK, RTE_ARGPARSE_ARG_VALUE_MAX);
+	struct rte_argparse_arg arg = {
+		.name_long = str,
+		.name_short = NULL,
+		.val_saver = val,
+		.val_set = NULL,
+		.flags = val_type,
+	};
+	uint32_t value_type = arg_attr_val_type(&arg);
+
+	if (value_type == 0 || value_type >= cmp_max)
+		return -EINVAL;
+
+	return parse_arg_autosave(&arg, str);
+}
diff --git a/lib/argparse/rte_argparse.h b/lib/argparse/rte_argparse.h
index 8285e812f0..a795263a81 100644
--- a/lib/argparse/rte_argparse.h
+++ b/lib/argparse/rte_argparse.h
@@ -183,6 +183,25 @@  struct rte_argparse {
 __rte_experimental
 int rte_argparse_parse(struct rte_argparse *obj, int argc, char **argv);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Parse the value from the input string based on the value type.
+ *
+ * @param str
+ *   Input string.
+ * @param val_type
+ *   The value type, @see RTE_ARGPARSE_ARG_VALUE_INT or other type.
+ * @param val
+ *   Saver for the value.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_experimental
+int rte_argparse_parse_type(const char *str, uint64_t val_type, void *val);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/argparse/version.map b/lib/argparse/version.map
index 1c176f69e9..9b68464600 100644
--- a/lib/argparse/version.map
+++ b/lib/argparse/version.map
@@ -2,6 +2,7 @@  EXPERIMENTAL {
 	global:
 
 	rte_argparse_parse;
+	rte_argparse_parse_type;
 
 	local: *;
 };