From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: Bruce Richardson <bruce.richardson@intel.com>,
Chengwen Feng <fengchengwen@huawei.com>
Subject: [PATCH 1/3] argparse: track parsed arguments internally
Date: Mon, 16 Jun 2025 11:49:41 +0100 [thread overview]
Message-ID: <20250616104944.3425929-2-bruce.richardson@intel.com> (raw)
In-Reply-To: <20250616104944.3425929-1-bruce.richardson@intel.com>
Change how the argparse library records what cmdline arguments have been
seen or not; instead of setting an extra hidden flag in the user-passed
argument structure, set a flag on an internally allocated and managed
array. This means that the user parameters are not modified during the
parse operation, so they can be reused multiple times if necessary, e.g.
in testing.
This change also fixes a coverity issue, where the flag used to indicate
a seen argument was not adjusted to take account of the change of type
of the "flags" setting from 64-bit to 32-bit.
Coverity issue: 470190
Fixes: 04acc21beeeb ("argparse: use enums to remove max-value defines in lists")
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
lib/argparse/rte_argparse.c | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/lib/argparse/rte_argparse.c b/lib/argparse/rte_argparse.c
index b5b8467dea..431d0f9b84 100644
--- a/lib/argparse/rte_argparse.c
+++ b/lib/argparse/rte_argparse.c
@@ -16,8 +16,6 @@ RTE_LOG_REGISTER_DEFAULT(rte_argparse_logtype, INFO);
#define ARGPARSE_LOG(level, ...) \
RTE_LOG_LINE(level, ARGPARSE, "" __VA_ARGS__)
-#define ARG_ATTR_FLAG_PARSED_MASK RTE_BIT64(63)
-
static inline bool
is_arg_optional(const struct rte_argparse_arg *arg)
{
@@ -273,9 +271,9 @@ verify_argparse_arg(const struct rte_argparse *obj, uint32_t index)
}
static int
-verify_argparse(const struct rte_argparse *obj)
+verify_argparse(const struct rte_argparse *obj, size_t *nb_args)
{
- uint32_t idx;
+ size_t idx;
int ret;
if (obj->prog_name == NULL) {
@@ -302,6 +300,7 @@ verify_argparse(const struct rte_argparse *obj)
return ret;
idx++;
}
+ *nb_args = idx;
return 0;
}
@@ -361,8 +360,8 @@ is_arg_match(struct rte_argparse_arg *arg, const char *curr_argv, uint32_t len)
}
static struct rte_argparse_arg *
-find_option_arg(struct rte_argparse *obj, const char *curr_argv, const char *has_equal,
- const char **arg_name)
+find_option_arg(struct rte_argparse *obj, uint32_t *idx,
+ const char *curr_argv, const char *has_equal, const char **arg_name)
{
uint32_t len = strlen(curr_argv) - (has_equal != NULL ? strlen(has_equal) : 0);
struct rte_argparse_arg *arg;
@@ -377,6 +376,7 @@ find_option_arg(struct rte_argparse *obj, const char *curr_argv, const char *has
if (match) {
/* Obtains the exact matching name (long or short). */
*arg_name = len > 2 ? arg->name_long : arg->name_short;
+ *idx = i;
return arg;
}
}
@@ -606,12 +606,14 @@ is_help(const char *curr_argv)
}
static int
-parse_args(struct rte_argparse *obj, int argc, char **argv, bool *show_help)
+parse_args(struct rte_argparse *obj, bool *arg_parsed,
+ int argc, char **argv, bool *show_help)
{
uint32_t position_count = calc_position_count(obj);
struct rte_argparse_arg *arg;
uint32_t position_index = 0;
const char *arg_name;
+ uint32_t arg_idx;
char *curr_argv;
char *has_equal;
char *value;
@@ -648,13 +650,13 @@ parse_args(struct rte_argparse *obj, int argc, char **argv, bool *show_help)
has_equal = strchr(curr_argv, '=');
arg_name = NULL;
- arg = find_option_arg(obj, curr_argv, has_equal, &arg_name);
+ arg = find_option_arg(obj, &arg_idx, curr_argv, has_equal, &arg_name);
if (arg == NULL || arg_name == NULL) {
ARGPARSE_LOG(ERR, "unknown argument %s!", curr_argv);
return -EINVAL;
}
- if ((arg->flags & ARG_ATTR_FLAG_PARSED_MASK) && !arg_attr_flag_multi(arg)) {
+ if (arg_parsed[arg_idx] && !arg_attr_flag_multi(arg)) {
ARGPARSE_LOG(ERR, "argument %s should not occur multiple times!", arg_name);
return -EINVAL;
}
@@ -684,7 +686,7 @@ parse_args(struct rte_argparse *obj, int argc, char **argv, bool *show_help)
return ret;
/* This argument parsed success! then mark it parsed. */
- arg->flags |= ARG_ATTR_FLAG_PARSED_MASK;
+ arg_parsed[arg_idx] = true;
}
return i;
@@ -795,14 +797,25 @@ RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_argparse_parse, 24.03)
int
rte_argparse_parse(struct rte_argparse *obj, int argc, char **argv)
{
+ bool *arg_parsed = NULL;
bool show_help = false;
+ size_t nb_args = 0;
int ret;
- ret = verify_argparse(obj);
+ ret = verify_argparse(obj, &nb_args);
if (ret != 0)
goto error;
- ret = parse_args(obj, argc, argv, &show_help);
+ /* allocate the flags array to indicate what arguments are parsed or not */
+ arg_parsed = calloc(nb_args, sizeof(*arg_parsed));
+ if (arg_parsed == NULL) {
+ ARGPARSE_LOG(ERR, "failed to allocate memory for argument flags!");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ ret = parse_args(obj, arg_parsed, argc, argv, &show_help);
+ free(arg_parsed);
if (ret < 0)
goto error;
--
2.48.1
next prev parent reply other threads:[~2025-06-16 10:49 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-16 10:49 [PATCH 0/3] argparse: improve handling of multi-instance args Bruce Richardson
2025-06-16 10:49 ` Bruce Richardson [this message]
2025-06-16 10:49 ` [PATCH 2/3] argparse: mark parameter struct as const Bruce Richardson
2025-06-16 10:49 ` [PATCH 3/3] test/argparse: add test for repeated arguments Bruce Richardson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250616104944.3425929-2-bruce.richardson@intel.com \
--to=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=fengchengwen@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).