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] == '-')
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) {
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;
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:
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),
};
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 },