# #
#############################################################################*/
-#include <errno.h>
-#include <getopt.h>
+#include <argp.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
unsigned int num_disable_repos;
};
-static int cli_main(struct pakfire* pakfire, int argc, char* argv[]) {
- static const struct command commands[] = {
- { "build", 0, cli_build },
- { "clean", 0, cli_clean },
- { "dist", 0, cli_dist },
- { "image", 0, cli_image },
- { "info", 0, cli_info },
- { "provides", 0, cli_provides },
- { "repo", 0, cli_repo },
- { "repolist", 0, cli_repolist },
- { "requires", 0, cli_requires },
- { "shell", 0, cli_shell },
- { "search", 0, cli_search },
- { NULL },
- };
-
- return command_dispatch(pakfire, commands, argc, argv);
-}
+const char* argp_program_version = PACKAGE_VERSION;
-static void help(void) {
- printf(
- "%s [OPTIONS...] COMMAND\n\n"
- "Options:\n"
- " -a --arch Run in different architecture\n"
- " --distro Selects the distribution to compile for\n"
- " --debug Run in debug mode\n"
- " -h --help Show help\n"
- " --version Show version\n"
- "\n"
- "Commands:\n"
- " search Search for packages\n"
- " provides Shows which package provides a dependency\n"
- " requires Shows which package requries a dependency\n"
- " repolist Show all configured repositories\n"
- " clean Cleans up no longer needed resources\n",
- program_invocation_short_name
- );
-
- exit(0);
-}
+enum {
+ OPT_ARCH = 1,
+ OPT_DEBUG = 2,
+ OPT_DISTRO = 3,
-static int parse_argv(struct config* config, int argc, char* argv[]) {
- enum {
- ARG_DEBUG,
- ARG_DISTRO,
- ARG_VERSION,
+ OPT_ENABLE_REPO = 4,
+ OPT_DISABLE_REPO = 5,
+};
- // Repos
- ARG_ENABLE_REPO,
- ARG_DISABLE_REPO,
- };
+static struct argp_option options[] = {
+ { "arch", OPT_ARCH, "ARCH", 0, "Choose an architecture", 0 },
+ { "debug", OPT_DEBUG, NULL, 0, "Run in debug mode", 0 },
+ { "distro", OPT_DISTRO, "DISTRO", 0, "Build for this distribution", 0 },
+ { NULL },
+};
- static const struct option options[] = {
- { "arch", required_argument, NULL, 'a' },
- { "debug", no_argument, NULL, ARG_DEBUG },
- { "distro", required_argument, NULL, ARG_DISTRO },
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
-
- // Repos
- { "enable-repo", required_argument, NULL, ARG_ENABLE_REPO },
- { "disable-repo", required_argument, NULL, ARG_DISABLE_REPO },
- { NULL },
- };
- int c;
+static const struct command commands[] = {
+ { "build", 0, cli_build },
+ { "clean", 0, cli_clean },
+ { "dist", 0, cli_dist },
+ { "image", 0, cli_image },
+ { "info", 0, cli_info },
+ { "provides", 0, cli_provides },
+ { "repo", 0, cli_repo },
+ { "repolist", 0, cli_repolist },
+ { "requires", 0, cli_requires },
+ { "shell", 0, cli_shell },
+ { "search", 0, cli_search },
+ { NULL },
+};
- for (;;) {
- c = getopt_long(argc, argv, "ah", options, NULL);
- if (c < 0)
+const char* doc =
+ "build [OPTIONS...] MAKEFILES...\n"
+ "clean\n"
+ "dist MAKEFILES...\n"
+ "image ...\n"
+ "provides PATTERN\n"
+ "repo compose PATH PACKAGES...\n"
+ "repolist\n"
+ "requires PATTERN\n"
+ "shell [OPTIONS...]\n"
+ "search [OPTIONS...] PATTERN";
+
+static error_t parse(int key, char* arg, struct argp_state* state) {
+ struct config* config = state->input;
+
+ switch (key) {
+ case OPT_ARCH:
+ // XXX Check if the architecture is supported
+ config->arch = arg;
break;
- switch (c) {
- case 'a':
- config->arch = optarg;
- break;
-
- case 'h':
- help();
+ case OPT_DEBUG:
+ config->flags |= PAKFIRE_FLAGS_DEBUG;
+ break;
- case ARG_DEBUG:
- config->flags |= PAKFIRE_FLAGS_DEBUG;
- break;
+ case OPT_DISTRO:
+ config->distro = arg;
+ break;
- case ARG_DISTRO:
- config->distro = optarg;
- break;
+ // Enable/Disable Repositories
- case ARG_VERSION:
- cli_version();
- exit(0);
+ case OPT_ENABLE_REPO:
+ if (config->num_enable_repos >= MAX_REPOS)
+ return -ENOBUFS;
- case ARG_ENABLE_REPO:
- if (config->num_enable_repos >= MAX_REPOS)
- return -ENOBUFS;
+ config->enable_repos[config->num_enable_repos++] = arg;
+ break;
- config->enable_repos[config->num_enable_repos++] = optarg;
- break;
+ case OPT_DISABLE_REPO:
+ if (config->num_disable_repos >= MAX_REPOS)
+ return -ENOBUFS;
- case ARG_DISABLE_REPO:
- if (config->num_disable_repos >= MAX_REPOS)
- return -ENOBUFS;
+ config->disable_repos[config->num_disable_repos++] = arg;
+ break;
- config->disable_repos[config->num_disable_repos++] = optarg;
- break;
+ // Show help if no arguments have been passed
+ case ARGP_KEY_NO_ARGS:
+ argp_usage(state);
- case '?':
- break;
+ // Stop parsing when we find the first argument
+ case ARGP_KEY_ARG:
+ break;
- default:
- assert_unreachable();
- }
+ default:
+ return ARGP_ERR_UNKNOWN;
}
return 0;
}
int main(int argc, char* argv[]) {
- struct pakfire* pakfire = NULL;
- int r;
-
struct config config = {
// XXX hard-coded distro
.distro = "ipfire3",
.arch = NULL,
.flags = PAKFIRE_FLAGS_BUILD,
};
+ struct pakfire* pakfire = NULL;
+ int r;
+
+ struct argp parser = {
+ .options = options,
+ .parser = parse,
+ .args_doc = doc,
+ };
+ int arg_index = 0;
- // Parse command line arguments
- r = parse_argv(&config, argc, argv);
+ // Parse command line options
+ r = argp_parse(&parser, argc, argv, 0, &arg_index, &config);
if (r)
goto ERROR;
goto ERROR;
// Run a command
- r = cli_main(pakfire, argc, argv);
+ r = command_dispatch(pakfire, commands, arg_index - 1, argc, argv);
ERROR:
if (pakfire)