Skip to content

Commit

Permalink
ctdb-common: Change cmdline implementation to support multiple sections
Browse files Browse the repository at this point in the history
Signed-off-by: Amitay Isaacs <[email protected]>
Reviewed-by: Martin Schwenke <[email protected]>
  • Loading branch information
amitay authored and Martin Schwenke committed Nov 14, 2019
1 parent 7a008c6 commit 977a6f7
Showing 1 changed file with 101 additions and 33 deletions.
134 changes: 101 additions & 33 deletions ctdb/common/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@

#define CMDLINE_MAX_LEN 80

struct cmdline_section {
const char *name;
struct cmdline_command *commands;
};

struct cmdline_context {
const char *prog;
struct poptOption *options;
const char *section;
struct cmdline_command *commands;
struct cmdline_section *section;
int num_sections;
int max_len;
poptContext pc;
int argc, arg0;
Expand Down Expand Up @@ -207,16 +212,51 @@ static bool cmdline_commands_check(struct cmdline_command *commands,

static int cmdline_context_destructor(struct cmdline_context *cmdline);

static int cmdline_section_add(struct cmdline_context *cmdline,
const char *name,
struct cmdline_command *commands)
{
struct cmdline_section *section;
size_t max_len = 0;
bool ok;

ok = cmdline_commands_check(commands, &max_len);
if (!ok) {
return EINVAL;
}

section = talloc_realloc(cmdline,
cmdline->section,
struct cmdline_section,
cmdline->num_sections + 1);
if (section == NULL) {
return ENOMEM;
}

section[cmdline->num_sections] = (struct cmdline_section) {
.name = name,
.commands = commands,
};

if (max_len > cmdline->max_len) {
cmdline->max_len = max_len;
}

cmdline->section = section;
cmdline->num_sections += 1;

return 0;
}

int cmdline_init(TALLOC_CTX *mem_ctx,
const char *prog,
struct poptOption *options,
const char *section,
const char *name,
struct cmdline_command *commands,
struct cmdline_context **result)
{
struct cmdline_context *cmdline;
int ret;
size_t max_len = 0;
bool ok;

if (prog == NULL) {
Expand All @@ -228,11 +268,6 @@ int cmdline_init(TALLOC_CTX *mem_ctx,
return EINVAL;
}

ok = cmdline_commands_check(commands, &max_len);
if (!ok) {
return EINVAL;
}

cmdline = talloc_zero(mem_ctx, struct cmdline_context);
if (cmdline == NULL) {
return ENOMEM;
Expand All @@ -249,9 +284,12 @@ int cmdline_init(TALLOC_CTX *mem_ctx,
talloc_free(cmdline);
return ret;
}
cmdline->section = section;
cmdline->commands = commands;
cmdline->max_len = max_len;

ret = cmdline_section_add(cmdline, name, commands);
if (ret != 0) {
talloc_free(cmdline);
return ret;
}

cmdline->argc = 1;
cmdline->argv = talloc_array(cmdline, const char *, 2);
Expand Down Expand Up @@ -326,24 +364,20 @@ static int cmdline_parse_options(struct cmdline_context *cmdline,
return 0;
}

static int cmdline_match(struct cmdline_context *cmdline)
static int cmdline_match_section(struct cmdline_context *cmdline,
struct cmdline_section *section)
{
int i;

if (cmdline->argc == 0 || cmdline->argv == NULL) {
cmdline->match_cmd = NULL;
return EINVAL;
}

for (i=0; cmdline->commands[i].name != NULL; i++) {
for (i=0; section->commands[i].name != NULL; i++) {
struct cmdline_command *cmd;
char name[CMDLINE_MAX_LEN+1];
size_t len;
char *t, *str;
int n = 0;
bool match = false;

cmd = &cmdline->commands[i];
cmd = &section->commands[i];
len = strlcpy(name, cmd->name, sizeof(name));
if (len >= sizeof(name)) {
D_ERR("Skipping long command '%s'\n", cmd->name);
Expand Down Expand Up @@ -382,6 +416,25 @@ static int cmdline_match(struct cmdline_context *cmdline)
return ENOENT;
}

static int cmdline_match(struct cmdline_context *cmdline)
{
int i, ret = ENOENT;

if (cmdline->argc == 0 || cmdline->argv == NULL) {
cmdline->match_cmd = NULL;
return EINVAL;
}

for (i=0; i<cmdline->num_sections; i++) {
ret = cmdline_match_section(cmdline, &cmdline->section[i]);
if (ret == 0) {
break;
}
}

return ret;
}

int cmdline_parse(struct cmdline_context *cmdline,
int argc,
const char **argv,
Expand Down Expand Up @@ -445,38 +498,53 @@ static void cmdline_usage_command(struct cmdline_context *cmdline,
printf(" %s\n", cmd->msg_help);
}

static void cmdline_usage_full(struct cmdline_context *cmdline)
static void cmdline_usage_section(struct cmdline_context *cmdline,
struct cmdline_section *section)
{
int i;

poptSetOtherOptionHelp(cmdline->pc, "[<options>] <command> [<args>]");
poptPrintHelp(cmdline->pc, stdout, 0);

printf("\n");
if (cmdline->section != NULL) {
printf("%s ", cmdline->section);

if (section->name != NULL) {
printf("%s ", section->name);
}
printf("Commands:\n");
for (i=0; cmdline->commands[i].name != NULL; i++) {
cmdline_usage_command(cmdline, &cmdline->commands[i], true);
for (i=0; section->commands[i].name != NULL; i++) {
cmdline_usage_command(cmdline, &section->commands[i], true);

}
}

static void cmdline_usage_full(struct cmdline_context *cmdline)
{
int i;

poptSetOtherOptionHelp(cmdline->pc, "[<options>] <command> [<args>]");
poptPrintHelp(cmdline->pc, stdout, 0);

for (i=0; i<cmdline->num_sections; i++) {
cmdline_usage_section(cmdline, &cmdline->section[i]);
}
}

void cmdline_usage(struct cmdline_context *cmdline, const char *cmd_name)
{
struct cmdline_command *cmd = NULL;
int i;
int i, j;

if (cmd_name == NULL) {
cmdline_usage_full(cmdline);
return;
}

for (i=0; cmdline->commands[i].name != NULL; i++) {
if (strcmp(cmdline->commands[i].name, cmd_name) == 0) {
cmd = &cmdline->commands[i];
break;
for (j=0; j<cmdline->num_sections; j++) {
struct cmdline_section *section = &cmdline->section[j];

for (i=0; section->commands[i].name != NULL; i++) {
if (strcmp(section->commands[i].name, cmd_name) == 0) {
cmd = &section->commands[i];
break;
}
}
}

Expand Down

0 comments on commit 977a6f7

Please sign in to comment.