feat(cli): auto-generated options string for getopt_long API

This commit is contained in:
lohhiiccc 2026-03-03 09:39:18 +01:00
parent 2fc8d92e98
commit 88b65cc62e
4 changed files with 43 additions and 5 deletions

View file

@ -23,7 +23,7 @@ typedef enum e_option_arg_type
typedef struct s_option_descriptor typedef struct s_option_descriptor
{ {
int short_opt; char short_opt;
const char *long_opt; const char *long_opt;
int has_arg; int has_arg;
t_option_handler handler; t_option_handler handler;
@ -46,5 +46,6 @@ int cli_handle_verbose(const char *arg, t_ping_config *config);
int cli_parse_uint64(const char *s, uint64_t *out); int cli_parse_uint64(const char *s, uint64_t *out);
int cli_parse_float(const char *s, float *out); int cli_parse_float(const char *s, float *out);
const char *get_optstr(void);
#endif #endif

View file

@ -14,7 +14,9 @@ SRCS = $(SRC_DIR)/main.c \
$(SRC_DIR)/cli/handlers/handle_version.c \ $(SRC_DIR)/cli/handlers/handle_version.c \
$(SRC_DIR)/cli/handlers/handle_verbose.c \ $(SRC_DIR)/cli/handlers/handle_verbose.c \
$(SRC_DIR)/cli/utils/parse_int.c \ $(SRC_DIR)/cli/utils/parse_int.c \
$(SRC_DIR)/cli/utils/parse_float.c $(SRC_DIR)/cli/utils/parse_float.c \
$(SRC_DIR)/cli/utils/get_optstr.c \
TESTS_DIR = tests TESTS_DIR = tests
TESTS = $(TESTS_DIR)/test_main.c \ TESTS = $(TESTS_DIR)/test_main.c \
@ -31,5 +33,5 @@ TESTS = $(TESTS_DIR)/test_main.c \
$(TESTS_DIR)/cli/handlers/test_handle_version.c \ $(TESTS_DIR)/cli/handlers/test_handle_version.c \
$(TESTS_DIR)/cli/handlers/test_handle_verbose.c \ $(TESTS_DIR)/cli/handlers/test_handle_verbose.c \
$(TESTS_DIR)/cli/utils/test_parse_int.c \ $(TESTS_DIR)/cli/utils/test_parse_int.c \
$(TESTS_DIR)/cli/utils/test_parse_float.c $(TESTS_DIR)/cli/utils/test_parse_float.c \

View file

@ -19,13 +19,12 @@ int
cli_parse_arguments(int argc, char **argv, t_ping_config *config) cli_parse_arguments(int argc, char **argv, t_ping_config *config)
{ {
struct option long_opts[CLI_OPT_LEN + 1]; struct option long_opts[CLI_OPT_LEN + 1];
const char *opt_str = "hVvqc:i:t:s:W:f";
int opt; int opt;
int res; int res;
init_config(config); init_config(config);
build_long_options(long_opts, CLI_OPT_LEN, g_options); build_long_options(long_opts, CLI_OPT_LEN, g_options);
while (-1 != (opt = getopt_long(argc, argv, opt_str, long_opts, NULL))) while (-1 != (opt = getopt_long(argc, argv, get_optstr(), long_opts, NULL)))
{ {
res = handle_one_option(opt, optarg, config); res = handle_one_option(opt, optarg, config);
if (0 != res) if (0 != res)

View file

@ -0,0 +1,36 @@
#include "cli.h"
#include "cli_opt.h"
#include <stddef.h>
/* Forward declarations */
static void init_opt_str(char *str);
/* -------------------- */
const char *
get_optstr(void)
{
static char opt_str[CLI_OPT_STR_LEN] = "";
if ('\0' == *opt_str)
init_opt_str(opt_str);
return opt_str;
}
static void
init_opt_str(char *opt_str)
{
size_t str_i = 0;
for (size_t opt_i = 0; opt_i < CLI_OPT_LEN; ++opt_i)
{
opt_str[str_i++] = g_options[opt_i].short_opt;
switch (g_options[opt_i].has_arg)
{
case optional_argument: opt_str[str_i++] = ':'; /* fall through */
case required_argument: opt_str[str_i++] = ':'; break;
default: break;
}
}
opt_str[str_i] = '\0';
return;
}