#include #include #include #include "cli.h" #include "cli_parse_utils.h" #include "compiler.h" /* Config */ #define FLAG_VERBOSE (1 << 0) struct greet_config { const char *name; uint64_t count; uint8_t flags; }; /* Handlers */ static int handle_help(__unused const char *arg, __unused void *cfg) { printf("Usage: greet [OPTIONS] ...\n\n"); printf(" -h, --help Display this help\n"); printf(" -V, --version Display version\n"); printf(" -v, --verbose Verbose output\n"); printf(" -n, --name NAME Name to greet (default: world)\n"); printf(" -c, --count N Number of greetings (default: 1)\n"); return CLI_EXIT_SUCCESS; } static int handle_version(__unused const char *arg, __unused void *cfg) { printf("greet 0.1.0 (libcli example)\n"); return CLI_EXIT_SUCCESS; } static int handle_verbose(__unused const char *arg, void *cfg) { struct greet_config *config = (struct greet_config *)cfg; SET_FLAG(config->flags, FLAG_VERBOSE); return CLI_SUCCESS; } static int handle_name(const char *arg, void *cfg) { struct greet_config *config = (struct greet_config *)cfg; config->name = arg; return CLI_SUCCESS; } static int handle_count(const char *arg, void *cfg) { struct greet_config *config = (struct greet_config *)cfg; if (0 != cli_parse_uint64(arg, &config->count)) return CLI_ERROR; return CLI_SUCCESS; } /* Option table */ #define GREET_OPTIONS_LIST \ X('h', "help", no_argument, handle_help, OPT_ARG_NONE, "Display this help") \ X('V', "version", no_argument, handle_version, OPT_ARG_NONE, "Display version") \ X('v', "verbose", no_argument, handle_verbose, OPT_ARG_NONE, "Verbose output") \ X('n', "name", required_argument, handle_name, OPT_ARG_STRING, "Name to greet") \ X('c', "count", required_argument, handle_count, OPT_ARG_UINT, "Number of greetings") #define X(s, l, a, h, t, d) + 1 enum { GREET_NB_OPTS = 0 GREET_OPTIONS_LIST }; #undef X #define X(s, l, a, h, t, d) + (1 + (a != no_argument ? 1 : 0)) enum { GREET_OPTSTR_LEN = 1 GREET_OPTIONS_LIST }; #undef X #define X(s, l, a, h, t, d) { s, l, a, h, t, d }, static const struct option_descriptor g_opts[] = { GREET_OPTIONS_LIST }; #undef X /* Main */ int main(int argc, char **argv) { struct greet_config config = { .name = "world", .count = 1 }; char opt_str[GREET_OPTSTR_LEN + 1]; struct option long_opts[GREET_NB_OPTS + 1]; enum cli_code ret; uint64_t i; cli_set_prog_name(argv[0]); ret = cli_parse(argc, argv, &config, g_opts, GREET_NB_OPTS, opt_str, long_opts); if (CLI_EXIT_SUCCESS == ret) return EXIT_SUCCESS; if (CLI_ERROR == ret) return EXIT_FAILURE; for (i = 0; i < config.count; i++) { if (HAS_FLAG(config.flags, FLAG_VERBOSE)) printf("[%llu] Hello, %s!\n", (unsigned long long)(i + 1), config.name); else printf("Hello, %s!\n", config.name); } return EXIT_SUCCESS; }