[24.03 RFC] argparse: add argparse library

Stephen Hemminger stephen at networkplumber.org
Tue Nov 21 17:36:24 CET 2023


On Tue, 21 Nov 2023 12:26:51 +0000
Chengwen Feng <fengchengwen at huawei.com> wrote:

> Introduce argparse library (which was inspired by the thread [1]),
> compared with getopt, the argparse has following advantages:
> 1) Set the help information when defining parameters.
> 2) Support positional parameters.
> 
> The parameters parsing according following:
> 1) positional: use callback to parse (passed the long-name as the key
>    for callback).
> 2) optional:
>    In addition to callback to parse, but also support:
> 2.1) no-val: support set default value to saver.
> 2.2) has-val: support set value to saver, the value must be conform
>               RTE_ARGPARSE_ARG_VAL_xxx.
> 2.3) opt-val: if current without value then treat as no-val, else could
>               treat as has-val.
> 
> Examples: (take dmafwd as example):
> 1) If parse with callback:
> 	static int
> 	func(const char *key, const char *value, const char *opaque)
> 	{
> 		if (!strcmp("--mac-updating", key)) {
> 			mac_updating = 1;
> 		} else if (!strcmp("--no-mac-updating", key)) {
> 			mac_updating = 0;
> 		} else if (!strcmp("--portmask", key)) {
> 			dma_enabled_port_mask = dma_parse_portmask(optarg);
> 			if (dma_enabled_port_mask & ~default_port_mask ||
> 						dma_enabled_port_mask <= 0) {
> 				...
> 			}
> 		} else {
> 			...
> 		}
> 	}
> 
> 	static int
> 	dma_parse_args(int argc, char **argv, unsigned int nb_ports)
> 	{
> 		static struct rte_argparse opts[] = {
> 			.prog = "dma",
> 			.usage = NULL,
> 			.descriptor = "dma and nic fwd example",
> 			.epilog = NULL,
> 			.exit_on_error = true,
> 			.opt = {
> 				{ "--mac-updating", NULL, "Enable MAC addresses updating", func, 0, NULL, NULL, RTE_ARGPARSE_ARG_NO_VAL },
> 				{ "--no-mac-updating", NULL, "disable MAC addresses updating", func, 0, NULL, NULL, RTE_ARGPARSE_ARG_NO_VAL },
> 				{ "--portmask", "-p", "hexadecimal bitmask of ports to configure", func, 0, NULL, NULL, RTE_ARGPARSE_ARG_HAS_VAL },
> 				{ NULL, NULL, NULL, NULL, 0, NULL, NULL, 0}
> 			}
> 		};
> 		return rte_argparse_parse(opts, argc, argv);
> 	}
> 
> 2) If parse with value:
> 	static int
> 	dma_parse_args(int argc, char **argv, unsigned int nb_ports)
> 	{
> 		static struct rte_argparse opts[] = {
> 			.prog = "dma",
> 			.usage = NULL,
> 			.descriptor = "dma and nic fwd example",
> 			.epilog = NULL,
> 			.exit_on_error = true,
> 			.opt = {
> 				{ "--mac-updating", NULL, "Enable MAC addresses updating", NULL, 0, &mac_updating, (void *)1, RTE_ARGPARSE_ARG_NO_VAL },
> 				{ "--no-mac-updating", NULL, "disable MAC addresses updating", NULL, 0, &mac_updating, (void *)0, RTE_ARGPARSE_ARG_NO_VAL },
> 				{ "--portmask", "-p", "hexadecimal bitmask of ports to configure", NULL, 0, &dma_enabled_port_mask, NULL, RTE_ARGPARSE_ARG_HAS_VAL },
> 				{ NULL, NULL, NULL, NULL, 0, NULL, NULL, 0}
> 			}
> 		};
> 		int ret;
> 		ret = rte_argparse_parse(opts, argc, argv);
> 		if (ret != 0)
> 			return ret;
> 		if (dma_enabled_port_mask & ~default_port_mask ||
> 					dma_enabled_port_mask <= 0) {
> 			...
> 		}
> 	}
> 
> 3) Also could mix parse with func and with value.
> 
> [1] https://patchwork.dpdk.org/project/dpdk/patch/20231105054539.22303-2-fengchengwen@huawei.com/
> 
> Signed-off-by: Chengwen Feng <fengchengwen at huawei.com>
> ---

Need tests and more detailed man page.
Maybe convert one of the existing examples.

Can it be used in nested fashion for kvargs? 
The existing kvargs syntax is awkward, would be nice to fix/change that but would
cause lots of arguments :-)


More information about the dev mailing list