]> git.ipfire.org Git - pakfire.git/commitdiff
cli: command: Add option to min/max number of arguments
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 15 Oct 2023 11:20:05 +0000 (11:20 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 15 Oct 2023 11:20:05 +0000 (11:20 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/cli/lib/command.c
src/cli/lib/command.h
src/cli/pakfire-builder.c

index 41d03cedb801b4931e6a4226443b056da215aa85..3adf0365fc3fe561fd75706be76f4d300e2d224a 100644 (file)
@@ -35,8 +35,8 @@ static const struct command* command_find(const struct command* commands, const
        return NULL;
 }
 
-static unsigned int count_arguments(int argc, char* argv[]) {
-       unsigned int arguments = 0;
+static int count_arguments(int argc, char* argv[]) {
+       int arguments = 0;
 
        for (int i = 1; i < argc; i++) {
                if (*argv[i] == '-')
@@ -93,7 +93,6 @@ struct command_ctx {
 
 static error_t __command_parse(int key, char* arg, struct argp_state* state) {
        struct command_ctx* ctx = state->input;
-       int r;
 
        // Just call the parse function if we don't have any commands
        if (!ctx->commands) {
@@ -119,6 +118,8 @@ static error_t __command_parse(int key, char* arg, struct argp_state* state) {
                                break;
                        }
 
+                       // XXX actually we should update the program name here
+
                        // Return UNKNOWN so that we get called for ARGP_KEY_ARGS
                        return ARGP_ERR_UNKNOWN;
 
@@ -128,9 +129,22 @@ static error_t __command_parse(int key, char* arg, struct argp_state* state) {
                        ctx->argv = &state->argv[state->next];
                        break;
 
+               // Perform some final checks when parsing has been completed
+               case ARGP_KEY_SUCCESS:
+                       if (ctx->command) {
+                               int args = count_arguments(ctx->argc, ctx->argv);
+
+                               // Check if we have a sufficient number of arguments
+                               if (ctx->command->min_args > 0 && args < ctx->command->min_args)
+                                       argp_error(state, "Not enough arguments");
+
+                               else if (ctx->command->max_args >= 0 && args > ctx->command->max_args)
+                                       argp_error(state, "Too many arguments");
+                       }
+                       break;
+
                // Do not pass any other things to the callback
                case ARGP_KEY_END:
-               case ARGP_KEY_SUCCESS:
                case ARGP_KEY_ERROR:
                case ARGP_KEY_INIT:
                case ARGP_KEY_FINI:
index 5e1fc79f2d6812c738de8865dcc46a2b545bcb48..63a28baca4e2d37773e29b581467cf6e2d9b86b5 100644 (file)
@@ -28,6 +28,8 @@ typedef error_t (*command_parse)(int key, char* arg, void* data);
 struct command {
        const char* verb;
        int (*callback)(void* config, int argc, char* argv[]);
+       int min_args;
+       int max_args;
        enum {
                CLI_REQUIRE_ONE_ARGUMENT          = (1 << 0),
                CLI_REQUIRE_ONE_OR_MORE_ARGUMENTS = (1 << 1),
index 3eb40b6315d2ae3b06d6688ed38c5eda2c2e2a7d..9c9350f8955b80d4ee313b277a5c6305887d8f30 100644 (file)
@@ -64,8 +64,8 @@ static struct argp_option options[] = {
 };
 
 static const struct command commands[] = {
-       { "build",    cli_build, 0 },
-       { "clean",    cli_clean, 0 },
+       { "build",    cli_build, 1, -1, 0 },
+       { "clean",    cli_clean, 0,  0, 0 },
 #if 0
        { "dist",     0, cli_dist },
        { "image",    0, cli_image },