116 lines
2.8 KiB
C
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;
|
|
}
|