diff options
Diffstat (limited to 'tools/create-commands.c')
-rw-r--r-- | tools/create-commands.c | 283 |
1 files changed, 226 insertions, 57 deletions
diff --git a/tools/create-commands.c b/tools/create-commands.c index d9f82186f..7bea84a44 100644 --- a/tools/create-commands.c +++ b/tools/create-commands.c @@ -68,6 +68,7 @@ struct opt_name { int val_enum; /* xyz_VAL when --foo takes a val like "--foo xyz" */ uint32_t unused1; uint32_t unused2; + const char *desc; }; /* also see val_props in tools.h and vals.h */ @@ -104,7 +105,7 @@ enum { /* create foo_ARG enums for --option's */ enum { -#define arg(a, b, c, d, e, f) a , +#define arg(a, b, c, d, e, f, g) a , #include "args.h" #undef arg }; @@ -136,7 +137,7 @@ static struct val_name val_names[VAL_COUNT + 1] = { /* create table of option names, e.g. --foo, and corresponding enum from args.h */ static struct opt_name opt_names[ARG_COUNT + 1] = { -#define arg(a, b, c, d, e, f) { # a, a, b, "", "--" c, d, e, f }, +#define arg(a, b, c, d, e, f, g) { # a, a, b, "", "--" c, d, e, f, g }, #include "args.h" #undef arg }; @@ -180,9 +181,15 @@ static struct cmd_name cmd_names[MAX_CMD_NAMES] = { #undef xx }; +/* array of pointers into opt_names[] that is sorted alphabetically (by long opt name) */ + +static struct opt_name *opt_names_alpha[ARG_COUNT + 1]; + #define MAX_LINE 1024 #define MAX_LINE_ARGC 256 +#define DESC_LINE 256 + #define REQUIRED 1 /* required option */ #define OPTIONAL 0 /* optional option */ #define IGNORE -1 /* ignore option */ @@ -2050,6 +2057,23 @@ void print_man_usage(struct command *cmd) printf("\n"); } +/* + * common options listed in the usage section. + * + * For commands with only one variant, this is only + * the options which are common to all lvm commands + * (in lvm_all, see is_lvm_all_opt). + * + * For commands with more than one variant, this + * is the set of options common to all variants + * (in cname->common_options), (which obviously + * includes the options common to all lvm commands.) + * + * List ordering: + * options with short+long names, alphabetically, + * then options with only long names, alphabetically + */ + void print_man_usage_common(struct command *cmd) { struct cmd_name *cname; @@ -2063,23 +2087,17 @@ void print_man_usage_common(struct command *cmd) printf(".RS 4\n"); printf("["); - /* - * when there's more than one variant, options that - * are common to all commands with a common name. - */ - - if (cname->variants < 2) - goto all; - /* print those with short opts */ - for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) { + for (i = 0; i < ARG_COUNT; i++) { + opt_enum = opt_names_alpha[i]->opt_enum; + if (!cname->common_options[opt_enum]) continue; if (!opt_names[opt_enum].short_opt) continue; - if (is_lvm_all_opt(opt_enum)) + if ((cname->variants < 2) && !is_lvm_all_opt(opt_enum)) continue; if (sep) { @@ -2107,14 +2125,16 @@ void print_man_usage_common(struct command *cmd) } /* print those without short opts */ - for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) { + for (i = 0; i < ARG_COUNT; i++) { + opt_enum = opt_names_alpha[i]->opt_enum; + if (!cname->common_options[opt_enum]) continue; if (opt_names[opt_enum].short_opt) continue; - if (is_lvm_all_opt(opt_enum)) + if ((cname->variants < 2) && !is_lvm_all_opt(opt_enum)) continue; if (sep) { @@ -2140,67 +2160,99 @@ void print_man_usage_common(struct command *cmd) break; } } - all: - /* options that are common to all lvm commands */ - - /* those with short opts */ - for (oo = 0; oo < lvm_all.oo_count; oo++) { - opt_enum = lvm_all.optional_opt_args[oo].opt; - if (!opt_names[opt_enum].short_opt) - continue; + printf(" ]\n"); + return; +} - if (sep) { - printf(","); - printf("\n.br\n"); - printf(" "); - } +/* + * Format of description, when different command names have + * different descriptions: + * + * "#cmdname1" + * "text foo goes here" + * "a second line of text." + * "#cmdname2" + * "text bar goes here" + * "another line of text." + * + * When called for cmdname2, this function should just print: + * + * "text bar goes here" + * "another line of text." + */ - printf(" \\fB-%c\\fP|\\fB%s\\fP", - opt_names[opt_enum].short_opt, - man_long_opt_name(cmd->name, opt_enum)); +static void print_man_option_desc(struct cmd_name *cname, int opt_enum) +{ + const char *desc = opt_names[opt_enum].desc; + char buf[DESC_LINE]; + int started_cname = 0; + int di, bi; - if (lvm_all.optional_opt_args[oo].def.val_bits) { - printf(" "); - print_def(&lvm_all.optional_opt_args[oo].def, 1); - } - sep = 1; + if (!strstr(desc, "#")) { + printf("%s", desc); + return; } - /* those without short opts */ - for (oo = 0; oo < lvm_all.oo_count; oo++) { - opt_enum = lvm_all.optional_opt_args[oo].opt; + for (di = 0; di < strlen(desc); di++) { + buf[bi++] = desc[di]; - if (opt_names[opt_enum].short_opt) + if (bi == DESC_LINE) { + printf("print_man_option_desc line too long\n"); + return; + } + + if (buf[bi-1] != '\n') continue; - if (sep) { - printf(","); - printf("\n.br\n"); - printf(" "); + if (buf[0] != '#') { + if (started_cname) + printf("%s", buf); + + memset(buf, 0, sizeof(buf)); + bi = 0; + continue; } - /* space alignment without short opt */ - printf(" "); + /* Line starting with #cmdname */ - printf(" \\fB%s\\fP", man_long_opt_name(cmd->name, opt_enum)); + /* Must be starting a new command name. */ + if (started_cname) + return; - if (lvm_all.optional_opt_args[oo].def.val_bits) { - printf(" "); - print_def(&lvm_all.optional_opt_args[oo].def, 1); + if (!strncmp(buf + 1, cname->name, strlen(cname->name))) { + /* The start of our command name. */ + started_cname = 1; + memset(buf, 0, sizeof(buf)); + bi = 0; + } else { + /* The start of another command name. */ + memset(buf, 0, sizeof(buf)); + bi = 0; } - sep = 1; } - printf(" ]\n"); + + if (bi && started_cname) + printf("%s", buf); } -void print_man_all_options(struct cmd_name *cname) +/* + * Print a list of all options names for a given + * command name, listed by: + * options with short+long names, alphabetically, + * then options with only long names, alphabetically + */ + +void print_man_all_options_list(struct cmd_name *cname) { int opt_enum, val_enum; int sep = 0; + int i; + + /* print those with both short and long opts */ + for (i = 0; i < ARG_COUNT; i++) { + opt_enum = opt_names_alpha[i]->opt_enum; - /* print those with short opts */ - for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) { if (!cname->all_options[opt_enum]) continue; @@ -2232,7 +2284,9 @@ void print_man_all_options(struct cmd_name *cname) } /* print those without short opts */ - for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) { + for (i = 0; i < ARG_COUNT; i++) { + opt_enum = opt_names_alpha[i]->opt_enum; + if (!cname->all_options[opt_enum]) continue; @@ -2265,7 +2319,79 @@ void print_man_all_options(struct cmd_name *cname) } } -#define DESC_LINE 256 +/* + * All options used for a given command name, along with descriptions. + * listed in order of: + * 1. options that are not common to all lvm commands, alphabetically + * 2. options common to all lvm commands, alphabetically + */ + +void print_man_all_options_desc(struct cmd_name *cname) +{ + int opt_enum, val_enum; + int print_common = 0; + int sep = 0; + int i; + + again: + /* + * Loop 1: print options that are not common to all lvm commands. + * Loop 2: print options common to all lvm commands (lvm_all) + */ + + for (i = 0; i < ARG_COUNT; i++) { + opt_enum = opt_names_alpha[i]->opt_enum; + + if (!cname->all_options[opt_enum]) + continue; + + if (!print_common && is_lvm_all_opt(opt_enum)) + continue; + + if (print_common && !is_lvm_all_opt(opt_enum)) + continue; + + if (sep) + printf("\n.br\n"); + + printf("\n.TP\n"); + + if (opt_names[opt_enum].short_opt) { + printf("\\fB-%c\\fP|\\fB%s\\fP", + opt_names[opt_enum].short_opt, + man_long_opt_name(cname->name, opt_enum)); + } else { + printf("\\fB%s\\fP", man_long_opt_name(cname->name, opt_enum)); + } + + val_enum = opt_names[opt_enum].val_enum; + + if (!val_names[val_enum].fn) { + /* takes no arg */ + } else if (!val_names[val_enum].usage) { + printf(" "); + printf("\\fI"); + printf("%s", val_names[val_enum].name); + printf("\\fP"); + } else { + printf(" "); + print_val_man(val_names[val_enum].usage); + } + + if (opt_names[opt_enum].desc) { + printf("\n"); + printf(".br\n"); + print_man_option_desc(cname, opt_enum); + } + + sep = 1; + } + + if (!print_common) { + print_common = 1; + goto again; + } +} void print_desc_man(const char *desc) { @@ -2338,6 +2464,12 @@ void print_man_command(void) printf("Common options:\n"); printf(".\n"); print_man_usage_common(prev_cmd); + + printf("\n"); + printf(".SH OPTIONS\n"); + printf(".br\n"); + print_man_all_options_desc(cname); + prev_cmd = NULL; } @@ -2396,7 +2528,7 @@ void print_man_command(void) /* listing them all when there's only 1 or 2 is just repetative */ if (cname->variants > 2) { printf(".P\n"); - print_man_all_options(cname); + print_man_all_options_list(cname); printf("\n"); printf(".P\n"); printf("\n"); @@ -2419,6 +2551,12 @@ void print_man_command(void) printf("Common options:\n"); printf(".\n"); print_man_usage_common(cmd); + + printf("\n"); + printf(".SH OPTIONS\n"); + printf(".br\n"); + print_man_all_options_desc(cname); + } printf("\n"); @@ -2730,6 +2868,23 @@ next: } } +static int long_name_compare(const void *on1, const void *on2) +{ + struct opt_name **optname1 = (void *)on1; + struct opt_name **optname2 = (void *)on2; + return strcmp((*optname1)->long_opt + 2, (*optname2)->long_opt + 2); +} + +static void create_opt_names_alpha(void) +{ + int i; + + for (i = 0; i < ARG_COUNT; i++) + opt_names_alpha[i] = &opt_names[i]; + + qsort(opt_names_alpha, ARG_COUNT, sizeof(long), long_name_compare); +} + void print_command_list(void) { int i; @@ -2754,6 +2909,17 @@ void print_option_list(void) opt_names[i].short_opt ? opt_names[i].short_opt : 0); } +void print_option_alpha_list(void) +{ + int i; + + for (i = 0; i < ARG_COUNT; i++) + printf("%d %s %s %c (%d)\n", + opt_names_alpha[i]->opt_enum, opt_names_alpha[i]->name, + opt_names_alpha[i]->long_opt, opt_names_alpha[i]->short_opt ?: ' ', + opt_names_alpha[i]->short_opt ? opt_names_alpha[i]->short_opt : 0); +} + static void print_help(int argc, char *argv[]) { printf("%s [options] --output <format> <filename>\n", argv[0]); @@ -2791,9 +2957,12 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + create_opt_names_alpha(); + if (!strcmp(argv[1], "debug")) { print_command_list(); print_option_list(); + print_option_alpha_list(); return 0; } |