From 0dc1e09205f8de90c1a6d1614e2cab11681c6187 Mon Sep 17 00:00:00 2001 From: lohhiiccc <96543753+lohhiiccc@users.noreply.github.com> Date: Thu, 12 Mar 2026 18:45:54 +0100 Subject: [PATCH] refactor: complete multi-binary CLI reorganization --- includes/cli.h | 42 +++++++ includes/compiler.h | 6 + includes/internal/cli/arg_handler.h | 42 +------ includes/internal/cli/messages.h | 2 +- includes/internal/cli/parse_utils.h | 4 - includes/internal/ping/cli_handlers.h | 20 +++ includes/internal/ping/parse_utils.h | 11 ++ includes/ping/cli.h | 7 +- sources/cli.mk | 6 + sources/ping.mk | 8 +- src/cli/parse.c | 117 ++++++++++++++++++ src/{ping => }/cli/parse_utils/parse_float.c | 0 src/{ping => }/cli/parse_utils/parse_int.c | 0 src/ping/cli/handlers/handle_count.c | 7 +- src/ping/cli/handlers/handle_deadline.c | 6 +- src/ping/cli/handlers/handle_flood.c | 4 +- src/ping/cli/handlers/handle_help.c | 6 +- src/ping/cli/handlers/handle_interval.c | 6 +- src/ping/cli/handlers/handle_quiet.c | 4 +- src/ping/cli/handlers/handle_size.c | 6 +- src/ping/cli/handlers/handle_timeout.c | 6 +- src/ping/cli/handlers/handle_ttl.c | 6 +- src/ping/cli/handlers/handle_verbose.c | 5 +- src/ping/cli/handlers/handle_version.c | 6 +- src/ping/cli/handlers/option_map.c | 2 +- src/ping/cli/messages/help.c | 2 +- src/ping/cli/parse.c | 86 ++----------- src/ping/cli/parse_utils/get_optstr.c | 40 ------ src/ping/cli/parse_utils/parse_destinations.c | 12 +- tests/cli/handlers/test_handle_count.c | 2 +- tests/cli/handlers/test_handle_flood.c | 2 +- tests/cli/handlers/test_handle_help.c | 2 +- tests/cli/handlers/test_handle_interval.c | 2 +- tests/cli/handlers/test_handle_quiet.c | 2 +- tests/cli/handlers/test_handle_size.c | 2 +- tests/cli/handlers/test_handle_timeout.c | 2 +- tests/cli/handlers/test_handle_ttl.c | 2 +- tests/cli/handlers/test_handle_verbose.c | 2 +- tests/cli/handlers/test_handle_version.c | 2 +- tests/cli/handlers/test_handler_map.c | 2 +- 40 files changed, 264 insertions(+), 227 deletions(-) create mode 100644 includes/cli.h create mode 100644 includes/compiler.h create mode 100644 includes/internal/ping/cli_handlers.h create mode 100644 includes/internal/ping/parse_utils.h create mode 100644 sources/cli.mk create mode 100644 src/cli/parse.c rename src/{ping => }/cli/parse_utils/parse_float.c (100%) rename src/{ping => }/cli/parse_utils/parse_int.c (100%) delete mode 100644 src/ping/cli/parse_utils/get_optstr.c diff --git a/includes/cli.h b/includes/cli.h new file mode 100644 index 0000000..94e82ee --- /dev/null +++ b/includes/cli.h @@ -0,0 +1,42 @@ +#ifndef CLI_H +#define CLI_H + +#include +#include + +#include "compiler.h" + +enum e_cli_code { + CLI_EXIT_SUCCESS = -1, + CLI_SUCCESS = 0, + CLI_ERROR = 1 +}; + +typedef int (*t_option_handler)(const char *arg, void *config); + +typedef enum e_option_arg_type +{ + OPT_ARG_NONE = 0, + OPT_ARG_INT, + OPT_ARG_UINT, + OPT_ARG_SECONDS, + OPT_ARG_BYTES, + OPT_ARG_TTL, + OPT_ARG_STRING +} t_option_arg_type; + +typedef struct s_option_descriptor +{ + char short_opt; + const char *long_opt; + int has_arg; + t_option_handler handler; + t_option_arg_type arg_type; + const char *description; +} t_option_descriptor; + +enum e_cli_code cli_parse(int argc, char **argv, void *config, + const t_option_descriptor *opts, size_t nb_opts, + char *opt_str, struct option *long_opts); + +#endif diff --git a/includes/compiler.h b/includes/compiler.h new file mode 100644 index 0000000..de88d27 --- /dev/null +++ b/includes/compiler.h @@ -0,0 +1,6 @@ +#ifndef COMPILER_H +#define COMPILER_H + +#define __unused __attribute__((unused)) + +#endif diff --git a/includes/internal/cli/arg_handler.h b/includes/internal/cli/arg_handler.h index 36d8990..729dd82 100644 --- a/includes/internal/cli/arg_handler.h +++ b/includes/internal/cli/arg_handler.h @@ -1,45 +1,7 @@ #ifndef CLI_INTERNAL_ARG_HANDLER #define CLI_INTERNAL_ARG_HANDLER -#include "ping/ft_ping.h" - -typedef int (*t_option_handler)(const char *arg, t_ping_config *config); - -typedef enum e_option_arg_type -{ - OPT_ARG_NONE = 0, - OPT_ARG_INT, - OPT_ARG_UINT, - OPT_ARG_SECONDS, - OPT_ARG_BYTES, - OPT_ARG_TTL, - OPT_ARG_STRING -} t_option_arg_type; - -typedef struct s_option_descriptor -{ - char short_opt; - const char *long_opt; - int has_arg; - t_option_handler handler; - t_option_arg_type arg_type; - const char *description; -} t_option_descriptor; - -extern const t_option_descriptor g_options[]; - -const char *cli_get_optstr(void); - -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_help(const char *arg, t_ping_config *config); -int cli_handle_interval(const char *arg, t_ping_config *config); -int cli_handle_quiet(const char *arg, t_ping_config *config); -int cli_handle_size(const char *arg, t_ping_config *config); -int cli_handle_deadline(const char *arg, t_ping_config *config); -int cli_handle_timeout(const char *arg, t_ping_config *config); -int cli_handle_ttl(const char *arg, t_ping_config *config); -int cli_handle_version(const char *arg, t_ping_config *config); -int cli_handle_verbose(const char *arg, t_ping_config *config); +#include "cli.h" +#include "internal/ping/cli_handlers.h" #endif diff --git a/includes/internal/cli/messages.h b/includes/internal/cli/messages.h index a31eac1..4bfb1e2 100644 --- a/includes/internal/cli/messages.h +++ b/includes/internal/cli/messages.h @@ -1,7 +1,7 @@ #ifndef CLI_INTERNAL_MESSAGES #define CLI_INTERNAL_MESSAGES -#include "ping/cli.h" +#include "cli.h" void print_help(void); void print_version(void); diff --git a/includes/internal/cli/parse_utils.h b/includes/internal/cli/parse_utils.h index 01b8703..8b54717 100644 --- a/includes/internal/cli/parse_utils.h +++ b/includes/internal/cli/parse_utils.h @@ -2,12 +2,8 @@ #define CLI_INTERNAL_PARSE_UTILS #include -#include -#include "ping/ft_ping.h" int cli_parse_uint64(const char *s, uint64_t *out); int cli_parse_float(const char *s, float *out); -int cli_parse_inet_addr(const char *s, struct in_addr *out); -int cli_parse_destinations(int argc, char **argv, int optind, t_ping_config *config); #endif diff --git a/includes/internal/ping/cli_handlers.h b/includes/internal/ping/cli_handlers.h new file mode 100644 index 0000000..2100820 --- /dev/null +++ b/includes/internal/ping/cli_handlers.h @@ -0,0 +1,20 @@ +#ifndef PING_CLI_HANDLERS_H +#define PING_CLI_HANDLERS_H + +#include "cli.h" + +extern const t_option_descriptor g_options[]; + +int cli_handle_count(const char *arg, void *config); +int cli_handle_deadline(const char *arg, void *config); +int cli_handle_flood(const char *arg, void *config); +int cli_handle_help(const char *arg, void *config); +int cli_handle_interval(const char *arg, void *config); +int cli_handle_quiet(const char *arg, void *config); +int cli_handle_size(const char *arg, void *config); +int cli_handle_timeout(const char *arg, void *config); +int cli_handle_ttl(const char *arg, void *config); +int cli_handle_verbose(const char *arg, void *config); +int cli_handle_version(const char *arg, void *config); + +#endif diff --git a/includes/internal/ping/parse_utils.h b/includes/internal/ping/parse_utils.h new file mode 100644 index 0000000..e4d36bc --- /dev/null +++ b/includes/internal/ping/parse_utils.h @@ -0,0 +1,11 @@ +#ifndef PING_CLI_PARSE_UTILS_H +#define PING_CLI_PARSE_UTILS_H + +#include +#include "ping/ft_ping.h" + +int cli_parse_inet_addr(const char *s, struct in_addr *out); +int cli_parse_destinations(int argc, char **argv, int first_arg, + t_ping_config *config); + +#endif diff --git a/includes/ping/cli.h b/includes/ping/cli.h index 67d0c8c..fa3dc7b 100644 --- a/includes/ping/cli.h +++ b/includes/ping/cli.h @@ -1,14 +1,9 @@ #ifndef PING_CLI_H #define PING_CLI_H +#include "../cli.h" #include "ping/ft_ping.h" -enum e_cli_code { - CLI_EXIT_SUCCESS = -1, - CLI_SUCCESS = 0, - CLI_ERROR = 1 -}; - enum e_cli_code cli_parse_arguments(int argc, char **argv, t_ping_config *config); void cli_config_free(t_ping_config *config); diff --git a/sources/cli.mk b/sources/cli.mk new file mode 100644 index 0000000..4fb24cf --- /dev/null +++ b/sources/cli.mk @@ -0,0 +1,6 @@ + +CLI_SRC_DIR = src/cli +CLI_SRCS = $(CLI_SRC_DIR)/parse.c \ + $(CLI_SRC_DIR)/parse_utils/parse_int.c \ + $(CLI_SRC_DIR)/parse_utils/parse_float.c \ + diff --git a/sources/ping.mk b/sources/ping.mk index 7e2dcf2..4c9f7cc 100644 --- a/sources/ping.mk +++ b/sources/ping.mk @@ -1,6 +1,9 @@ +include sources/cli.mk + PING_SRC_DIR = src/ping -PING_SRCS = $(PING_SRC_DIR)/main.c \ +PING_SRCS = $(CLI_SRCS) \ + $(PING_SRC_DIR)/main.c \ $(PING_SRC_DIR)/cli/parse.c \ $(PING_SRC_DIR)/cli/handlers/handle_count.c \ $(PING_SRC_DIR)/cli/handlers/handle_deadline.c \ @@ -14,11 +17,8 @@ PING_SRCS = $(PING_SRC_DIR)/main.c \ $(PING_SRC_DIR)/cli/handlers/handle_ttl.c \ $(PING_SRC_DIR)/cli/handlers/handle_version.c \ $(PING_SRC_DIR)/cli/handlers/handle_verbose.c \ - $(PING_SRC_DIR)/cli/parse_utils/parse_int.c \ - $(PING_SRC_DIR)/cli/parse_utils/parse_float.c \ $(PING_SRC_DIR)/cli/parse_utils/parse_inet_addr.c \ $(PING_SRC_DIR)/cli/parse_utils/parse_destinations.c \ - $(PING_SRC_DIR)/cli/parse_utils/get_optstr.c \ $(PING_SRC_DIR)/cli/config_free.c \ $(PING_SRC_DIR)/cli/messages/help.c \ $(PING_SRC_DIR)/cli/messages/version.c \ diff --git a/src/cli/parse.c b/src/cli/parse.c new file mode 100644 index 0000000..f501ded --- /dev/null +++ b/src/cli/parse.c @@ -0,0 +1,117 @@ +#include +#include + +#include "cli.h" +#include "internal/cli/messages.h" + +/* Map -? to -h to support help shortcut */ +#define HANDLE_QUESTION_MARK(opt) \ + do { \ + if (opt == '?' && (optopt) == '?') \ + opt = 'h'; \ + } while (0) + +/* Forward declarations */ +static void build_long_options(struct option *long_opts, size_t nb_opts, + const t_option_descriptor *src); +static void build_optstr(char *dest, const t_option_descriptor *opts, + size_t nb_opts); +static const t_option_descriptor *find_option_handler(int opt, + const t_option_descriptor *opts, size_t nb_opts); +static int handle_one_option(int opt, char **argv, void *config, + uint64_t *opt_tracker, + const t_option_descriptor *opts, size_t nb_opts); +/* ------------------- */ + +enum e_cli_code +cli_parse(int argc, char **argv, void *config, + const t_option_descriptor *opts, size_t nb_opts, + char *opt_str, struct option *long_opts) +{ + uint64_t tracker = 0; + int opt; + int res; + + build_optstr(opt_str, opts, nb_opts); + build_long_options(long_opts, nb_opts, opts); + while (-1 != (opt = getopt_long(argc, argv, opt_str, long_opts, NULL))) + { + HANDLE_QUESTION_MARK(opt); + res = handle_one_option(opt, argv, config, &tracker, opts, nb_opts); + if (CLI_SUCCESS != res) + return (enum e_cli_code)res; + } + return CLI_SUCCESS; +} + +static void +build_optstr(char *dest, const t_option_descriptor *opts, size_t nb_opts) +{ + size_t str_i = 1; + + /* Mute default error messages */ + dest[0] = ':'; + + for (size_t opt_i = 0; opt_i < nb_opts; ++opt_i) + { + dest[str_i++] = opts[opt_i].short_opt; + switch (opts[opt_i].has_arg) + { + case optional_argument: dest[str_i++] = ':'; /* fall through */ + case required_argument: dest[str_i++] = ':'; break; + default: break; + } + } + dest[str_i] = '\0'; +} + +static int +handle_one_option(int opt, char **argv, void *config, + uint64_t *opt_tracker, + const t_option_descriptor *opts, size_t nb_opts) +{ + const char *current_opt = argv[optind - 1]; + const t_option_descriptor *desc; + size_t bitmask_index; + int res; + + if ('?' == opt) + return error_unknown_opt(current_opt); + if (':' == opt) + return error_invalid_opt(current_opt); + + desc = find_option_handler(opt, opts, nb_opts); + bitmask_index = (size_t)(desc - opts); + if (*opt_tracker & (1ULL << bitmask_index)) + return error_duplicate_opt(current_opt); + + *opt_tracker |= (1ULL << bitmask_index); + res = desc->handler(optarg, config); + if (CLI_SUCCESS != res) + return error_invalid_opt(current_opt); + return CLI_SUCCESS; +} + +static void +build_long_options(struct option *long_opts, size_t nb_opts, + const t_option_descriptor *src) +{ + for (size_t i = 0; i < nb_opts; ++i) { + long_opts[i].name = src[i].long_opt; + long_opts[i].has_arg = src[i].has_arg; + long_opts[i].flag = NULL; + long_opts[i].val = src[i].short_opt; + } + long_opts[nb_opts] = (struct option){0}; +} + +static const t_option_descriptor * +find_option_handler(int opt, const t_option_descriptor *opts, size_t nb_opts) +{ + for (size_t i = 0; i < nb_opts; ++i) + { + if (opts[i].short_opt == opt) + return &opts[i]; + } + return NULL; +} diff --git a/src/ping/cli/parse_utils/parse_float.c b/src/cli/parse_utils/parse_float.c similarity index 100% rename from src/ping/cli/parse_utils/parse_float.c rename to src/cli/parse_utils/parse_float.c diff --git a/src/ping/cli/parse_utils/parse_int.c b/src/cli/parse_utils/parse_int.c similarity index 100% rename from src/ping/cli/parse_utils/parse_int.c rename to src/cli/parse_utils/parse_int.c diff --git a/src/ping/cli/handlers/handle_count.c b/src/ping/cli/handlers/handle_count.c index 83d31b2..4376270 100644 --- a/src/ping/cli/handlers/handle_count.c +++ b/src/ping/cli/handlers/handle_count.c @@ -1,17 +1,16 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/parse_utils.h" int -cli_handle_count(const char *arg, t_ping_config *config) +cli_handle_count(const char *arg, void *config_void) { - uint64_t count; + t_ping_config *config = (t_ping_config *)config_void; + uint64_t count; if (0 != cli_parse_uint64(arg, &count)) return CLI_ERROR; config->count = count; return CLI_SUCCESS; } - diff --git a/src/ping/cli/handlers/handle_deadline.c b/src/ping/cli/handlers/handle_deadline.c index cb53683..7efd336 100644 --- a/src/ping/cli/handlers/handle_deadline.c +++ b/src/ping/cli/handlers/handle_deadline.c @@ -1,11 +1,11 @@ #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/parse_utils.h" int -cli_handle_deadline(const char *arg, t_ping_config *config) +cli_handle_deadline(const char *arg, void *config_void) { - float deadline; + t_ping_config *config = (t_ping_config *)config_void; + float deadline; if (0 != cli_parse_float(arg, &deadline)) return CLI_ERROR; diff --git a/src/ping/cli/handlers/handle_flood.c b/src/ping/cli/handlers/handle_flood.c index 1c13d75..155a6bc 100644 --- a/src/ping/cli/handlers/handle_flood.c +++ b/src/ping/cli/handlers/handle_flood.c @@ -2,9 +2,9 @@ #include "ping/ft_ping_flags.h" int -cli_handle_flood(const char *arg, t_ping_config *config) +cli_handle_flood(__unused const char *arg, void *config_void) { - (void)arg; + t_ping_config *config = (t_ping_config *)config_void; SET_FLAG(config->flags, FLAG_FLOOD); return CLI_SUCCESS; } diff --git a/src/ping/cli/handlers/handle_help.c b/src/ping/cli/handlers/handle_help.c index eb72d9e..733326d 100644 --- a/src/ping/cli/handlers/handle_help.c +++ b/src/ping/cli/handlers/handle_help.c @@ -1,13 +1,9 @@ #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/messages.h" int -cli_handle_help(const char *arg, t_ping_config *config) +cli_handle_help(__unused const char *arg, __unused void *config_void) { - (void)arg; - (void)config; - print_help(); return CLI_EXIT_SUCCESS; diff --git a/src/ping/cli/handlers/handle_interval.c b/src/ping/cli/handlers/handle_interval.c index 8366089..a9f3e17 100644 --- a/src/ping/cli/handlers/handle_interval.c +++ b/src/ping/cli/handlers/handle_interval.c @@ -1,13 +1,13 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/parse_utils.h" int -cli_handle_interval(const char *arg, t_ping_config *config) +cli_handle_interval(const char *arg, void *config_void) { - float interval; + t_ping_config *config = (t_ping_config *)config_void; + float interval; if (0 != cli_parse_float(arg, &interval)) return CLI_ERROR; diff --git a/src/ping/cli/handlers/handle_quiet.c b/src/ping/cli/handlers/handle_quiet.c index fa8d039..88dde81 100644 --- a/src/ping/cli/handlers/handle_quiet.c +++ b/src/ping/cli/handlers/handle_quiet.c @@ -2,9 +2,9 @@ #include "ping/ft_ping_flags.h" int -cli_handle_quiet(const char *arg, t_ping_config *config) +cli_handle_quiet(__unused const char *arg, void *config_void) { - (void)arg; + t_ping_config *config = (t_ping_config *)config_void; SET_FLAG(config->flags, FLAG_QUIET); return CLI_SUCCESS; } diff --git a/src/ping/cli/handlers/handle_size.c b/src/ping/cli/handlers/handle_size.c index 0c23598..6093fcb 100644 --- a/src/ping/cli/handlers/handle_size.c +++ b/src/ping/cli/handlers/handle_size.c @@ -1,13 +1,13 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/parse_utils.h" int -cli_handle_size(const char *arg, t_ping_config *config) +cli_handle_size(const char *arg, void *config_void) { - uint64_t size; + t_ping_config *config = (t_ping_config *)config_void; + uint64_t size; if (0 != cli_parse_uint64(arg, &size) || size > (65535 - 8)) return CLI_ERROR; diff --git a/src/ping/cli/handlers/handle_timeout.c b/src/ping/cli/handlers/handle_timeout.c index fa678be..298637f 100644 --- a/src/ping/cli/handlers/handle_timeout.c +++ b/src/ping/cli/handlers/handle_timeout.c @@ -1,13 +1,13 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/parse_utils.h" int -cli_handle_timeout(const char *arg, t_ping_config *config) +cli_handle_timeout(const char *arg, void *config_void) { - float TO; + t_ping_config *config = (t_ping_config *)config_void; + float TO; if (0 != cli_parse_float(arg, &TO)) return CLI_ERROR; diff --git a/src/ping/cli/handlers/handle_ttl.c b/src/ping/cli/handlers/handle_ttl.c index e160478..7bb27c7 100644 --- a/src/ping/cli/handlers/handle_ttl.c +++ b/src/ping/cli/handlers/handle_ttl.c @@ -1,13 +1,13 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/parse_utils.h" int -cli_handle_ttl(const char *arg, t_ping_config *config) +cli_handle_ttl(const char *arg, void *config_void) { - uint64_t ttl; + t_ping_config *config = (t_ping_config *)config_void; + uint64_t ttl; if (0 != cli_parse_uint64(arg, &ttl) || ttl > 255) return CLI_ERROR; diff --git a/src/ping/cli/handlers/handle_verbose.c b/src/ping/cli/handlers/handle_verbose.c index 9b225d8..ee777b9 100644 --- a/src/ping/cli/handlers/handle_verbose.c +++ b/src/ping/cli/handlers/handle_verbose.c @@ -1,11 +1,10 @@ #include "ping/cli.h" -#include "ping/ft_ping.h" #include "ping/ft_ping_flags.h" int -cli_handle_verbose(const char *arg, t_ping_config *config) +cli_handle_verbose(__unused const char *arg, void *config_void) { - (void)arg; + t_ping_config *config = (t_ping_config *)config_void; SET_FLAG(config->flags, FLAG_VERBOSE); return CLI_SUCCESS; } diff --git a/src/ping/cli/handlers/handle_version.c b/src/ping/cli/handlers/handle_version.c index 868e792..a180e77 100644 --- a/src/ping/cli/handlers/handle_version.c +++ b/src/ping/cli/handlers/handle_version.c @@ -1,13 +1,9 @@ #include "ping/cli.h" -#include "internal/cli/arg_handler.h" #include "internal/cli/messages.h" int -cli_handle_version(const char *arg, t_ping_config *config) +cli_handle_version(__unused const char *arg, __unused void *config_void) { - (void)arg; - (void)config; - print_version(); return CLI_EXIT_SUCCESS; } diff --git a/src/ping/cli/handlers/option_map.c b/src/ping/cli/handlers/option_map.c index dd4434d..d9452e1 100644 --- a/src/ping/cli/handlers/option_map.c +++ b/src/ping/cli/handlers/option_map.c @@ -1,4 +1,4 @@ -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" #include "internal/cli/options.h" #undef X diff --git a/src/ping/cli/messages/help.c b/src/ping/cli/messages/help.c index 01e4241..335a3ee 100644 --- a/src/ping/cli/messages/help.c +++ b/src/ping/cli/messages/help.c @@ -1,6 +1,6 @@ #include -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" #include "internal/cli/options.h" /* Forward declarations */ diff --git a/src/ping/cli/parse.c b/src/ping/cli/parse.c index aac4e0a..66c7d4c 100644 --- a/src/ping/cli/parse.c +++ b/src/ping/cli/parse.c @@ -1,75 +1,31 @@ -#include #include #include #include "ping/cli.h" -#include "ping/ft_ping_flags.h" #include "ping/ft_ping_const.h" -#include "internal/cli/messages.h" +#include "internal/ping/cli_handlers.h" +#include "internal/ping/parse_utils.h" #include "internal/cli/options.h" -#include "internal/cli/arg_handler.h" -#include "internal/cli/parse_utils.h" -/* Map -? to -h to support help shortcut */ -#define HANDLE_QUESTION_MARK(opt) \ - do { \ - if (opt == '?' && (optopt) == '?') \ - opt = 'h'; \ - } while (0) - -/* Forward declatation */ +/* Forward declaration */ static void init_config(t_ping_config *config); -static void build_long_options(struct option *long_opts, size_t nb_opts, - const t_option_descriptor *src); -static inline const t_option_descriptor *find_option_handler(int opt); -static int handle_one_option(int opt, char **argv, t_ping_config *config, - uint64_t *opt_tacker); /* ------------------- */ enum e_cli_code cli_parse_arguments(int argc, char **argv, t_ping_config *config) { + char opt_str[CLI_OPT_STR_LEN]; struct option long_opts[CLI_OPT_LEN + 1]; - const char *opt_str = cli_get_optstr(); - uint64_t tracker = 0; - int opt; - int res; + enum e_cli_code ret; init_config(config); - build_long_options(long_opts, CLI_OPT_LEN, g_options); - while (-1 != (opt = getopt_long(argc, argv, opt_str, long_opts, NULL))) - { - HANDLE_QUESTION_MARK(opt); - res = handle_one_option(opt, argv, config, &tracker); - if (CLI_SUCCESS != res) - return res; - } + ret = cli_parse(argc, argv, config, g_options, CLI_OPT_LEN, + opt_str, long_opts); + if (CLI_SUCCESS != ret) + return ret; return cli_parse_destinations(argc, argv, optind, config); } -static int -handle_one_option(int opt, char **argv, t_ping_config *config, - uint64_t *opt_tracker) -{ - const t_option_descriptor *desc = find_option_handler(opt); - const size_t bitmask_index = (size_t)((desc) - (g_options)); - const char *current_opt = argv[optind - 1]; - int res = CLI_SUCCESS; - - if ('?' == opt) - return error_unknown_opt(current_opt); - if (':' == opt) - return error_invalid_opt(current_opt); - if (HAS_FLAG(*opt_tracker, (1ULL << bitmask_index))) - return error_duplicate_opt(current_opt); - - SET_FLAG(*opt_tracker, (1ULL) << bitmask_index); - res = desc->handler(optarg, config); - if (CLI_SUCCESS != res) - return error_invalid_opt(current_opt); - return CLI_SUCCESS; -} - static void init_config(t_ping_config *config) { @@ -80,27 +36,3 @@ init_config(t_ping_config *config) config->packet_size = DEFAULT_PACKET_SIZE; config->timeout = DEFAULT_TIMEOUT; } - -static void -build_long_options(struct option *long_opts, size_t nb_opts, - const t_option_descriptor *src) -{ - for (size_t i = 0; i < nb_opts; ++i) { - long_opts[i].name = src[i].long_opt; - long_opts[i].has_arg = src[i].has_arg; - long_opts[i].flag = NULL; - long_opts[i].val = src[i].short_opt; - } - long_opts[nb_opts] = (struct option){0}; -} - -static inline const t_option_descriptor -*find_option_handler(int opt) -{ - for (size_t i = 0; i < CLI_OPT_LEN; ++i) - { - if (g_options[i].short_opt == opt) - return &g_options[i]; - } - return NULL; -} diff --git a/src/ping/cli/parse_utils/get_optstr.c b/src/ping/cli/parse_utils/get_optstr.c deleted file mode 100644 index b968831..0000000 --- a/src/ping/cli/parse_utils/get_optstr.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "internal/cli/arg_handler.h" -#include "internal/cli/options.h" - -/* Forward declarations */ -static void init_opt_str(char *str); -/* -------------------- */ - -const char * -cli_get_optstr(void) -{ - /* Static string to act like a global */ - static char opt_str[CLI_OPT_STR_LEN] = ""; - - /* Lazy init */ - if ('\0' == *opt_str) - init_opt_str(opt_str); - - return opt_str; -} - -static void -init_opt_str(char *dest) -{ - /* Mute default error messages */ - dest[0] = ':'; - - size_t str_i = 1; - for (size_t opt_i = 0; opt_i < CLI_OPT_LEN; ++opt_i) - { - dest[str_i++] = g_options[opt_i].short_opt; - switch (g_options[opt_i].has_arg) - { - case optional_argument: dest[str_i++] = ':'; /* fall through */ - case required_argument: dest[str_i++] = ':'; break; - default: break; - } - } - dest[str_i] = '\0'; - return; -} diff --git a/src/ping/cli/parse_utils/parse_destinations.c b/src/ping/cli/parse_utils/parse_destinations.c index f1bab40..30819e4 100644 --- a/src/ping/cli/parse_utils/parse_destinations.c +++ b/src/ping/cli/parse_utils/parse_destinations.c @@ -2,22 +2,22 @@ #include "ping/cli.h" #include "internal/cli/messages.h" -#include "internal/cli/parse_utils.h" +#include "internal/ping/parse_utils.h" int -cli_parse_destinations(int argc, char **argv, int optind, t_ping_config *config) +cli_parse_destinations(int argc, char **argv, int first_arg, t_ping_config *config) { - if (optind >= argc) + if (first_arg >= argc) return error_missing_dest(); - config->nb_destinations = (size_t)(argc - optind); + config->nb_destinations = (size_t)(argc - first_arg); config->destinations = malloc(config->nb_destinations * sizeof(struct in_addr)); if (NULL == config->destinations) return CLI_ERROR; - for (int i = optind; i < argc; i++) + for (int i = first_arg; i < argc; i++) { - if (0 != cli_parse_inet_addr(argv[i], &config->destinations[i - optind])) + if (0 != cli_parse_inet_addr(argv[i], &config->destinations[i - first_arg])) { free(config->destinations); config->destinations = NULL; diff --git a/tests/cli/handlers/test_handle_count.c b/tests/cli/handlers/test_handle_count.c index 0586eda..aaea75e 100644 --- a/tests/cli/handlers/test_handle_count.c +++ b/tests/cli/handlers/test_handle_count.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" /* Test 1: basic test */ Test(cli_handle_count, valid_number) diff --git a/tests/cli/handlers/test_handle_flood.c b/tests/cli/handlers/test_handle_flood.c index 36f23cd..e8c9f38 100644 --- a/tests/cli/handlers/test_handle_flood.c +++ b/tests/cli/handlers/test_handle_flood.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" #include "ping/ft_ping_flags.h" /* Test 1: test flag*/ diff --git a/tests/cli/handlers/test_handle_help.c b/tests/cli/handlers/test_handle_help.c index 0807fc5..58d3b27 100644 --- a/tests/cli/handlers/test_handle_help.c +++ b/tests/cli/handlers/test_handle_help.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" /* Test 1: exit code test */ Test(handle_help, exit_code) diff --git a/tests/cli/handlers/test_handle_interval.c b/tests/cli/handlers/test_handle_interval.c index 3f8a266..d91699a 100644 --- a/tests/cli/handlers/test_handle_interval.c +++ b/tests/cli/handlers/test_handle_interval.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" /* Test 1: basic test */ Test(cli_handle_interval, valid_number) diff --git a/tests/cli/handlers/test_handle_quiet.c b/tests/cli/handlers/test_handle_quiet.c index 8afe741..c0d5d43 100644 --- a/tests/cli/handlers/test_handle_quiet.c +++ b/tests/cli/handlers/test_handle_quiet.c @@ -1,6 +1,6 @@ #include "ping/cli.h" #include "ping/ft_ping_flags.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" #include /* Test 1: test flag*/ diff --git a/tests/cli/handlers/test_handle_size.c b/tests/cli/handlers/test_handle_size.c index 4fcef21..8f45fda 100644 --- a/tests/cli/handlers/test_handle_size.c +++ b/tests/cli/handlers/test_handle_size.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" /* Test 1: basic test */ Test(cli_handle_size, valid_number) diff --git a/tests/cli/handlers/test_handle_timeout.c b/tests/cli/handlers/test_handle_timeout.c index ada3a32..2138572 100644 --- a/tests/cli/handlers/test_handle_timeout.c +++ b/tests/cli/handlers/test_handle_timeout.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" /* Test 1: basic test */ Test(cli_handle_timeout, valid_number) diff --git a/tests/cli/handlers/test_handle_ttl.c b/tests/cli/handlers/test_handle_ttl.c index 32d4fff..810ed72 100644 --- a/tests/cli/handlers/test_handle_ttl.c +++ b/tests/cli/handlers/test_handle_ttl.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" /* Test 1: basic test */ Test(cli_handle_ttl, valid_number) diff --git a/tests/cli/handlers/test_handle_verbose.c b/tests/cli/handlers/test_handle_verbose.c index 9195bdd..9505979 100644 --- a/tests/cli/handlers/test_handle_verbose.c +++ b/tests/cli/handlers/test_handle_verbose.c @@ -1,6 +1,6 @@ #include "ping/cli.h" #include "ping/ft_ping_flags.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" #include /* Test 1: test flag*/ diff --git a/tests/cli/handlers/test_handle_version.c b/tests/cli/handlers/test_handle_version.c index cfb944a..6f54a93 100644 --- a/tests/cli/handlers/test_handle_version.c +++ b/tests/cli/handlers/test_handle_version.c @@ -1,6 +1,6 @@ #include #include "ping/cli.h" -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" /* Test 1: exit code test */ Test(handle_version, exit_code) diff --git a/tests/cli/handlers/test_handler_map.c b/tests/cli/handlers/test_handler_map.c index a628d93..6ca27b1 100644 --- a/tests/cli/handlers/test_handler_map.c +++ b/tests/cli/handlers/test_handler_map.c @@ -1,4 +1,4 @@ -#include "internal/cli/arg_handler.h" +#include "internal/ping/cli_handlers.h" #include #include