diff --git a/clitest.c b/clitest.c index 6e38d88..834e539 100644 --- a/clitest.c +++ b/clitest.c @@ -304,6 +304,24 @@ int side_length_validator(struct cli_def *cli, const char *name, const char *val return rc; } +int check1_validator(struct cli_def *cli, UNUSED(const char *name), UNUSED(const char *value)) { + char *color; + char *transparent; + + printf("check1_validator called \n"); + color = cli_get_optarg_value(cli, "color", NULL); + transparent = cli_get_optarg_value(cli, "transparent", NULL); + + if (!color && !transparent) { + cli_error(cli,"\nMust supply either a color or transparent!"); + return CLI_ERROR; + } else if (color && !strcmp(color,"black") && transparent) { + cli_error(cli, "\nCan not have a transparent black object!"); + return CLI_ERROR; + } + return CLI_OK; +} + void run_child(int x) { struct cli_command *c; struct cli_def *cli; @@ -352,11 +370,14 @@ void run_child(int x) { "Set transparent flag", NULL, NULL, NULL); cli_register_optarg(c, "verbose", CLI_CMD_OPTIONAL_FLAG | CLI_CMD_OPTION_MULTIPLE, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Set transparent flag", NULL, NULL, NULL); + cli_register_optarg(c, "color", CLI_CMD_OPTIONAL_ARGUMENT, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Set color", + color_completor, color_validator, NULL); + cli_register_optarg(c, "__check1__", CLI_CMD_SPOT_CHECK,PRIVILEGE_UNPRIVILEGED, MODE_EXEC, + NULL, NULL, check1_validator, + NULL); cli_register_optarg(c, "shape", CLI_CMD_ARGUMENT | CLI_CMD_ALLOW_BUILDMODE, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Specify shape to calclate perimeter for", shape_completor, shape_validator, shape_transient_eval); - cli_register_optarg(c, "color", CLI_CMD_OPTIONAL_ARGUMENT, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Set color", - color_completor, color_validator, NULL); cli_register_optarg(c, "side_1", CLI_CMD_ARGUMENT, PRIVILEGE_UNPRIVILEGED, MODE_POLYGON_TRIANGLE, "Specify side 1 length", NULL, side_length_validator, NULL); cli_register_optarg(c, "side_1", CLI_CMD_ARGUMENT, PRIVILEGE_UNPRIVILEGED, MODE_POLYGON_RECTANGLE, diff --git a/libcli.c b/libcli.c index 416b839..fae25e9 100644 --- a/libcli.c +++ b/libcli.c @@ -2307,9 +2307,10 @@ int cli_int_enter_buildmode(struct cli_def *cli, struct cli_pipeline_stage *stag // build new *limited* list of commands from this commands optargs for (optarg = stage->command->optargs; optarg; optarg = optarg->next) { - // don't allow anything that could redefine our mode or buildmode mode, or redefine exit/cancel - if (!strcmp(optarg->name, "cancel") || (!strcmp(optarg->name, "exit"))) { - cli_error(cli, "Unable to build buildmode mode from optarg named %s", optarg->name); + // don't allow anything that could redefine our mode or buildmode mode, or redefine exit/cancel/show/unset + if (!strcmp(optarg->name, "cancel") || (!strcmp(optarg->name, "exit")) || + !strcmp(optarg->name, "show") || (!strcmp(optarg->name, "unset"))) { + cli_error(cli, "Default buildmode command conflicts with optarg named %s", optarg->name); rc = CLI_BUILDMODE_ERROR; goto out; } @@ -2343,7 +2344,7 @@ int cli_int_enter_buildmode(struct cli_def *cli, struct cli_pipeline_stage *stag } } cli->buildmode->cname = strdup(cli_command_name(cli, stage->command)); - // and lastly two 'always there' commands to cancel current mode and to execute the command + // and lastly four 'always there' commands to cancel current mode and to execute the command, show settings, and unset cli_int_register_buildmode_command(cli, NULL, "cancel", cli_int_buildmode_cancel_cback, PRIVILEGE_UNPRIVILEGED, cli->mode, "Cancel command"); cli_int_register_buildmode_command(cli, NULL, "exit", cli_int_buildmode_exit_cback, PRIVILEGE_UNPRIVILEGED, cli->mode, @@ -3000,7 +3001,14 @@ static void cli_int_parse_optargs(struct cli_def *cli, struct cli_pipeline_stage * Otherwise if the word is 'blank', could be an argument, or matches 'enough' of an option/flag it is a candidate * Once we accept an argument as a candidate, we're done looking for candidates as straight arguments are required */ - if (stage->words[w_idx] && (oaptr->flags & (CLI_CMD_OPTIONAL_FLAG | CLI_CMD_OPTIONAL_ARGUMENT)) && + if ((oaptr->flags & CLI_CMD_SPOT_CHECK) && (num_candidates == 0)) { + stage->status = (*oaptr->validator)(cli, NULL, NULL); + if (stage->status != CLI_OK) { + stage->error_word = stage->words[w_idx]; + cli_reprompt(cli); + return; + } + } else if (stage->words[w_idx] && (oaptr->flags & (CLI_CMD_OPTIONAL_FLAG | CLI_CMD_OPTIONAL_ARGUMENT)) && !strcmp(oaptr->name, stage->words[w_idx])) { candidates[0] = oaptr; num_candidates = 1; @@ -3035,7 +3043,7 @@ static void cli_int_parse_optargs(struct cli_def *cli, struct cli_pipeline_stage /* * So now we could have one or more candidates. We need to call get help/completions *only* if this is the * 'last-word' - * Remember that last word for optinal arguments is last or next to last.... + * Remember that last word for optional arguments is last or next to last.... */ if (lastchar != '\0') { int called_comphelp = 0; diff --git a/libcli.h b/libcli.h index f2c6022..73cafa7 100644 --- a/libcli.h +++ b/libcli.h @@ -132,6 +132,7 @@ enum optarg_flags { CLI_CMD_DO_NOT_RECORD = 1 << 7, CLI_CMD_REMAINDER_OF_LINE = 1 << 8, CLI_CMD_HYPHENATED_OPTION = 1 << 9, + CLI_CMD_SPOT_CHECK = 1 << 10, }; struct cli_optarg {