libcli/example/main.c
2026-03-29 16:35:29 +02:00

116 lines
2.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#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;
}