#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;
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) {
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;
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);
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;
int n = 0;
bool match = false;
- cmd = &cmdline->commands[i];
+ cmd = §ion->commands[i];
len = strlcpy(name, cmd->name, sizeof(name));
if (len >= sizeof(name)) {
D_ERR("Skipping long command '%s'\n", cmd->name);
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,
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, §ion->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 = §ion->commands[i];
+ break;
+ }
}
}