refactor(cli): use X-macro pattern for CLI options definition
Extract CLI options into a reusable macro (CLI_OPTIONS_LIST) in cli_opt.h and refactor handler_map.c to eliminate manual option array duplication. Calculate g_has_len automatically from option definitions.
This commit is contained in:
parent
37a4085cfc
commit
a6cdef89ca
3 changed files with 113 additions and 44 deletions
|
|
@ -33,6 +33,7 @@ typedef struct s_option_descriptor
|
||||||
|
|
||||||
extern const t_option_descriptor g_options[];
|
extern const t_option_descriptor g_options[];
|
||||||
extern const size_t g_options_len;
|
extern const size_t g_options_len;
|
||||||
|
extern const size_t g_opt_str_len;
|
||||||
|
|
||||||
int cli_handle_count(const char *arg, t_ping_config *config);
|
int cli_handle_count(const char *arg, t_ping_config *config);
|
||||||
int cli_handle_flood(const char *arg, t_ping_config *config);
|
int cli_handle_flood(const char *arg, t_ping_config *config);
|
||||||
|
|
|
||||||
94
includes/cli_opt.h
Normal file
94
includes/cli_opt.h
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#ifndef PING_CLI_OPT_H
|
||||||
|
#define PING_CLI_OPT_H
|
||||||
|
|
||||||
|
#define CLI_OPTIONS_LIST \
|
||||||
|
X( \
|
||||||
|
'h', \
|
||||||
|
"help", \
|
||||||
|
no_argument, \
|
||||||
|
cli_handle_help, \
|
||||||
|
OPT_ARG_NONE, \
|
||||||
|
"Display this help and exit" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
'V', \
|
||||||
|
"version", \
|
||||||
|
no_argument, \
|
||||||
|
cli_handle_version, \
|
||||||
|
OPT_ARG_NONE, \
|
||||||
|
"Display version information and exit" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
'v', \
|
||||||
|
"verbose", \
|
||||||
|
no_argument, \
|
||||||
|
cli_handle_verbose, \
|
||||||
|
OPT_ARG_NONE, \
|
||||||
|
"Verbose output" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
'q', \
|
||||||
|
"quiet", \
|
||||||
|
no_argument, \
|
||||||
|
cli_handle_quiet, \
|
||||||
|
OPT_ARG_NONE, \
|
||||||
|
"Quiet mode (only show summary)" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
'c', \
|
||||||
|
"count", \
|
||||||
|
required_argument, \
|
||||||
|
cli_handle_count, \
|
||||||
|
OPT_ARG_UINT, \
|
||||||
|
"Stop after sending N packets" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
'i', \
|
||||||
|
"interval", \
|
||||||
|
required_argument, \
|
||||||
|
cli_handle_interval, \
|
||||||
|
OPT_ARG_SECONDS, \
|
||||||
|
"Wait N seconds between packets" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
't', \
|
||||||
|
"ttl", \
|
||||||
|
required_argument, \
|
||||||
|
cli_handle_ttl, \
|
||||||
|
OPT_ARG_TTL, \
|
||||||
|
"Set Time To Live" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
's', \
|
||||||
|
"size", \
|
||||||
|
required_argument, \
|
||||||
|
cli_handle_size, \
|
||||||
|
OPT_ARG_BYTES, \
|
||||||
|
"Packet size in bytes" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
'W', \
|
||||||
|
"timeout", \
|
||||||
|
required_argument, \
|
||||||
|
cli_handle_timeout, \
|
||||||
|
OPT_ARG_SECONDS, \
|
||||||
|
"Timeout for replies in seconds" \
|
||||||
|
) \
|
||||||
|
X( \
|
||||||
|
'f', \
|
||||||
|
"flood", \
|
||||||
|
no_argument, \
|
||||||
|
cli_handle_flood, \
|
||||||
|
OPT_ARG_NONE, \
|
||||||
|
"Flood mode" \
|
||||||
|
)
|
||||||
|
|
||||||
|
#undef X
|
||||||
|
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) \
|
||||||
|
+ (1 * (has_arg == no_argument) \
|
||||||
|
+ (2 * (has_arg == required_argument) \
|
||||||
|
+ (3 * (has_arg == optional_argument))))
|
||||||
|
|
||||||
|
#define CLI_OPT_STR_LEN (0 CLI_OPTIONS_LIST)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,52 +1,26 @@
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
|
#include "cli_opt.h"
|
||||||
|
|
||||||
|
#undef X
|
||||||
|
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) \
|
||||||
|
{ short_opt, long_opt, has_arg, handler, arg_type, desc },
|
||||||
|
|
||||||
const t_option_descriptor g_options[] = {
|
const t_option_descriptor g_options[] = {
|
||||||
{
|
CLI_OPTIONS_LIST
|
||||||
'h', "help", no_argument, cli_handle_help, OPT_ARG_NONE,
|
{0, NULL, 0, NULL, OPT_ARG_NONE, NULL }
|
||||||
"Display this help and exit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'V', "version", no_argument, cli_handle_version, OPT_ARG_NONE,
|
|
||||||
"Display version information and exit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'v', "verbose", no_argument, cli_handle_verbose, OPT_ARG_NONE,
|
|
||||||
"Verbose output"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'q', "quiet", no_argument, cli_handle_quiet, OPT_ARG_NONE,
|
|
||||||
"Quiet mode (only show summary)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'c', "count", required_argument, cli_handle_count, OPT_ARG_UINT,
|
|
||||||
"Stop after sending N packets"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'i', "interval", required_argument, cli_handle_interval, OPT_ARG_SECONDS,
|
|
||||||
"Wait N seconds between packets"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
't', "ttl", required_argument, cli_handle_ttl, OPT_ARG_TTL,
|
|
||||||
"Set Time To Live"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
's', "size", required_argument, cli_handle_size, OPT_ARG_BYTES,
|
|
||||||
"Packet size in bytes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'W', "timeout", required_argument, cli_handle_timeout, OPT_ARG_SECONDS,
|
|
||||||
"Timeout for replies in seconds"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'f', "flood", no_argument, cli_handle_flood, OPT_ARG_NONE,
|
|
||||||
"Flood mode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0, NULL, 0, NULL, OPT_ARG_NONE,
|
|
||||||
NULL
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const size_t g_options_len = ((sizeof(g_options) / sizeof(*g_options)) - 1);
|
const size_t g_options_len = ((sizeof(g_options) / sizeof(*g_options)) - 1);
|
||||||
|
|
||||||
|
#undef X
|
||||||
|
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) \
|
||||||
|
+ (1 * (has_arg == no_argument) \
|
||||||
|
+ (2 * (has_arg == required_argument) \
|
||||||
|
+ (3 * (has_arg == optional_argument))))
|
||||||
|
|
||||||
|
const size_t g_opt_str_len = CLI_OPT_STR_LEN;
|
||||||
|
#undef X
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue