]> sourceware.org Git - lvm2.git/commitdiff
command: refactor struct command_name
authorZdenek Kabelac <zkabelac@redhat.com>
Sat, 11 May 2024 23:14:14 +0000 (01:14 +0200)
committerZdenek Kabelac <zkabelac@redhat.com>
Sun, 12 May 2024 21:53:19 +0000 (23:53 +0200)
Split struct command_name to the constant part (keep the name)
and new 'struct command_name_args' which holds runtime computed
info.   To get to the _args part - we can easily use
lvm_command_enum as equivalent index.

Constified part 'struct command_name' is now fully stored
in .data.rel.ro segment, while command_name_args part goes
to .bss segment.

Code will be further reduced with next refactoring.

tools/command.c
tools/command.h
tools/lvm.c
tools/lvm2cmdline.h
tools/lvmcmdline.c
tools/man-generator.c

index 91b50b81a1818bb54f85d8384ed22345cd305cc7..0a5ea1a50cd78ec3ffea8722cfb6a0c866ba7c71 100644 (file)
@@ -83,7 +83,7 @@ static const struct cmd_name cmd_names[CMD_COUNT + 1] = {
 
 #ifdef MAN_PAGE_GENERATOR
 
-static struct command_name command_names[] = {
+static const struct command_name command_names[] = {
 #define xx(a, b, c...) { # a, b, c, NULL, a ## _COMMAND },
 #include "commands.h"
 #undef xx
@@ -92,11 +92,12 @@ static struct command commands[COMMAND_COUNT];
 
 #else /* MAN_PAGE_GENERATOR */
 
-struct command_name command_names[] = {
+const struct command_name command_names[] = {
 #define xx(a, b, c...) { # a, b, c, a, a ## _COMMAND },
 #include "commands.h"
 #undef xx
 };
+
 extern struct command commands[COMMAND_COUNT]; /* defined in lvmcmdline.c */
 
 const struct opt_name *get_opt_name(int opt)
@@ -125,6 +126,8 @@ const struct lv_type *get_lv_type(int lvt_enum)
 
 #endif /* MAN_PAGE_GENERATOR */
 
+struct command_name_args command_names_args[LVM_COMMAND_COUNT] = { 0 };
+
 /* array of pointers into opt_names[] that is sorted alphabetically (by long opt name) */
 
 static const struct opt_name *opt_names_alpha[ARG_COUNT + 1];
@@ -1182,7 +1185,7 @@ void factor_common_options(void)
 
        for (cn = 0; cn < LVM_COMMAND_COUNT; ++cn) {
                /* already factored */
-               if (command_names[cn].variants)
+               if (command_names_args[cn].variants)
                        continue;
 
                for (ci = 0; ci < COMMAND_COUNT; ci++) {
@@ -1191,7 +1194,7 @@ void factor_common_options(void)
                        if (strcmp(cmd->name, command_names[cn].name))
                                continue;
 
-                       command_names[cn].variants++;
+                       command_names_args[cn].variants++;
                }
 
                for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
@@ -1203,22 +1206,22 @@ void factor_common_options(void)
                                        continue;
 
                                if (cmd->ro_count || cmd->any_ro_count)
-                                       command_names[cn].variant_has_ro = 1;
+                                       command_names_args[cn].variant_has_ro = 1;
                                if (cmd->rp_count)
-                                       command_names[cn].variant_has_rp = 1;
+                                       command_names_args[cn].variant_has_rp = 1;
                                if (cmd->oo_count)
-                                       command_names[cn].variant_has_oo = 1;
+                                       command_names_args[cn].variant_has_oo = 1;
                                if (cmd->op_count)
-                                       command_names[cn].variant_has_op = 1;
+                                       command_names_args[cn].variant_has_op = 1;
 
                                for (ro = 0; ro < cmd->ro_count + cmd->any_ro_count; ro++) {
-                                       command_names[cn].all_options[cmd->required_opt_args[ro].opt] = 1;
+                                       command_names_args[cn].all_options[cmd->required_opt_args[ro].opt] = 1;
 
                                        if ((cmd->required_opt_args[ro].opt == size_ARG) && !strncmp(cmd->name, "lv", 2))
-                                               command_names[cn].all_options[extents_ARG] = 1;
+                                               command_names_args[cn].all_options[extents_ARG] = 1;
                                }
                                for (oo = 0; oo < cmd->oo_count; oo++)
-                                       command_names[cn].all_options[cmd->optional_opt_args[oo].opt] = 1;
+                                       command_names_args[cn].all_options[cmd->optional_opt_args[oo].opt] = 1;
 
                                found = 0;
 
@@ -1234,7 +1237,7 @@ void factor_common_options(void)
                        }
 
                        /* all commands starting with this name use this option */
-                       command_names[cn].common_options[opt_enum] = 1;
+                       command_names_args[cn].common_options[opt_enum] = 1;
  next_opt:
                        ;
                }
@@ -1723,6 +1726,7 @@ static void _print_usage_def(struct command *cmd, int opt_enum, struct arg_def *
 void print_usage(struct command *cmd, int longhelp, int desc_first)
 {
        const struct command_name *cname = _find_command_name(cmd->name);
+       const struct command_name_args *cna = (cname) ? &command_names_args[cname->lvm_command_enum] : NULL;
        int any_req = (cmd->cmd_flags & CMD_FLAG_ANY_REQUIRED_OPT) ? 1 : 0;
        int include_extents = 0;
        int ro, rp, oo, op, opt_enum, first;
@@ -1875,7 +1879,7 @@ void print_usage(struct command *cmd, int longhelp, int desc_first)
                         * see print_common_options_cmd()
                         */
 
-                       if (cname && (cname->variants > 1) && cname->common_options[opt_enum])
+                       if (cna && (cna->variants > 1) && cna->common_options[opt_enum])
                                continue;
 
                        printf("\n\t[");
@@ -1915,7 +1919,7 @@ void print_usage(struct command *cmd, int longhelp, int desc_first)
                         * see print_common_options_cmd()
                         */
 
-                       if (cname && (cname->variants > 1) && cname->common_options[opt_enum])
+                       if (cna && (cna->variants > 1) && cna->common_options[opt_enum])
                                continue;
 
                        printf("\n\t[");
@@ -1999,6 +2003,7 @@ void print_usage_common_lvm(const struct command_name *cname, struct command *cm
 
 void print_usage_common_cmd(const struct command_name *cname, struct command *cmd)
 {
+       const struct command_name_args *cna = &command_names_args[cname->lvm_command_enum];
        int oo, opt_enum;
        int found_common_command = 0;
 
@@ -2007,11 +2012,11 @@ void print_usage_common_cmd(const struct command_name *cname, struct command *cm
         * are common to all commands with a common name.
         */
 
-       if (cname->variants < 2)
+       if (cna->variants < 2)
                return;
 
        for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
-               if (!cname->common_options[opt_enum])
+               if (!cna->common_options[opt_enum])
                        continue;
                if (_is_lvm_all_opt(opt_enum))
                        continue;
@@ -2027,7 +2032,7 @@ void print_usage_common_cmd(const struct command_name *cname, struct command *cm
        /* print options with short opts */
 
        for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
-               if (!cname->common_options[opt_enum])
+               if (!cna->common_options[opt_enum])
                        continue;
 
                if (_is_lvm_all_opt(opt_enum))
@@ -2055,7 +2060,7 @@ void print_usage_common_cmd(const struct command_name *cname, struct command *cm
        /* print options without short opts */
 
        for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
-               if (!cname->common_options[opt_enum])
+               if (!cna->common_options[opt_enum])
                        continue;
 
                if (_is_lvm_all_opt(opt_enum))
index 5f9c9172c831e72005ee6cbaa4f0e04ab78749c1..b0492a316b6f601c86e1043b982485aa4c0e91e6 100644 (file)
@@ -36,7 +36,9 @@ struct command_name {
        unsigned int flags;
        command_fn fn; /* old style */
        uint16_t lvm_command_enum; /* as declared in commands.h with _COMMAND */
+};
 
+struct command_name_args {
        uint16_t num_args;
        uint16_t variants;        /* number of command defs with this command name */
        /* union of {required,optional}_opt_args for all commands with this name */
@@ -184,8 +186,8 @@ struct command {
        const char *name;
        const char *desc; /* specific command description from command-lines.in */
        const char *command_id; /* ID string in command-lines.in */
-       int command_enum; /* <command_id>_CMD */
-       int command_index; /* position in commands[] */
+       uint16_t command_enum; /* <command_id>_CMD */
+       uint16_t command_index; /* position in commands[] */
 
        const struct command_function *functions; /* new style */
        command_fn fn;                      /* old style */
index 1d001dbe90cda03f272246bb1645ae8cb6d429ed..2d7f1a51654a183f63e325370d6d5b808dfcd929 100644 (file)
@@ -63,6 +63,7 @@ static char *_list_args(const char *text, int state)
        static int match_no = 0;
        static size_t len = 0;
        static struct command_name *cname;
+       static struct command_name_args *cna;
 
        /* Initialise if this is a new completion attempt */
        if (!state) {
@@ -71,6 +72,7 @@ static char *_list_args(const char *text, int state)
 
                match_no = 0;
                cname = NULL;
+               cna = NULL;
                len = strlen(text);
 
                /* Find start of first word in line buffer */
@@ -89,6 +91,7 @@ static char *_list_args(const char *text, int state)
                        }
                        if ((!*p) && *q == ' ') {
                                cname = _cmdline->command_names + j;
+                               cna = _cmdline->command_names_args + j;
                                break;
                        }
                }
@@ -99,11 +102,11 @@ static char *_list_args(const char *text, int state)
 
        /* Short form arguments */
        if (len < 3) {
-               while (match_no < cname->num_args) {
+               while (match_no < cna->num_args) {
                        char s[3];
                        char c;
                        if (!(c = (_cmdline->opt_names +
-                                  cname->valid_args[match_no++])->short_opt))
+                                  cna->valid_args[match_no++])->short_opt))
                                continue;
 
                        sprintf(s, "-%c", c);
@@ -113,13 +116,13 @@ static char *_list_args(const char *text, int state)
        }
 
        /* Long form arguments */
-       if (match_no < cname->num_args)
-               match_no = cname->num_args;
+       if (match_no < cna->num_args)
+               match_no = cna->num_args;
 
-       while (match_no - cname->num_args < cname->num_args) {
+       while (match_no - cna->num_args < cna->num_args) {
                const char *l;
                l = (_cmdline->opt_names +
-                    cname->valid_args[match_no++ - cname->num_args])->long_opt;
+                    cna->valid_args[match_no++ - cna->num_args])->long_opt;
                if (*(l + 2) && !strncmp(text, l, len))
                        return strdup(l);
        }
index a5d5e8f67e1d0f110601d664fd770158ac708659..15df29ff66ae2f287a505f38a230fb72eb7ecd31 100644 (file)
@@ -23,6 +23,7 @@ struct cmdline_context {
        struct command *commands;
        int num_commands;
        struct command_name *command_names;
+       struct command_name_args *command_names_args;
        int num_command_names;
 };
 
index 35b368a1cae5e6070964b56ee02dffe9897661fe..da69de6e7388e8f6d5e29551193977a4c44cc2cd 100644 (file)
@@ -53,6 +53,7 @@ extern char *optarg;
  * Table of command names
  */
 extern struct command_name command_names[];
+extern struct command_name_args command_names_args[];
 
 /*
  * Table of commands (as defined in command-lines.in)
@@ -159,10 +160,11 @@ static const struct command_function _command_functions[CMD_COUNT] = {
 /* Command line args */
 int arg_is_valid_for_command(const struct cmd_context *cmd, int a)
 {
+       const struct command_name_args *cna = &command_names_args[cmd->cname->lvm_command_enum];
        int i;
 
-       for (i = 0; i < cmd->cname->num_args; i++) {
-               if (cmd->cname->valid_args[i] == a)
+       for (i = 0; i < cna->num_args; i++) {
+               if (cna->valid_args[i] == a)
                        return 1;
        }
 
@@ -1268,18 +1270,18 @@ static void _set_valid_args_for_command_name(int ci)
                if (all_args[i]) {
                        opt_enum = _cmdline.opt_names[i].opt_enum;
 
-                       command_names[ci].valid_args[num_args] = opt_enum;
+                       command_names_args[ci].valid_args[num_args] = opt_enum;
                        num_args++;
 
                        /* Automatically recognize --extents in addition to --size. */
                        if (opt_enum == size_ARG) {
-                               command_names[ci].valid_args[num_args] = extents_ARG;
+                               command_names_args[ci].valid_args[num_args] = extents_ARG;
                                num_args++;
                        }
 
                        /* Recognize synonyms */
                        if ((opt_syn = _opt_standard_to_synonym(command_names[ci].name, opt_enum))) {
-                               command_names[ci].valid_args[num_args] = opt_syn;
+                               command_names_args[ci].valid_args[num_args] = opt_syn;
                                num_args++;
                        }
 
@@ -1290,13 +1292,13 @@ static void _set_valid_args_for_command_name(int ci)
                         * so just add allocation whenever either is seen.
                         */
                        if ((opt_enum == allocatable_ARG) || (opt_enum == resizeable_ARG)) {
-                               command_names[ci].valid_args[num_args] = allocation_ARG;
+                               command_names_args[ci].valid_args[num_args] = allocation_ARG;
                                num_args++;
                        }
                }
        }
 
-       command_names[ci].num_args = num_args;
+       command_names_args[ci].num_args = num_args;
 }
 
 static const struct command_function *_find_command_id_function(int command_enum)
@@ -1318,6 +1320,7 @@ static void _unregister_commands(void)
        _cmdline.commands = NULL;
        _cmdline.num_commands = 0;
        _cmdline.command_names = NULL;
+       _cmdline.command_names_args = NULL;
        _cmdline.num_command_names = 0;
 }
 
@@ -1385,6 +1388,7 @@ int lvm_register_commands(struct cmd_context *cmd, const char *run_name)
 
        _cmdline.num_command_names = i; /* Also counted how many command entries we have */
        _cmdline.command_names = command_names;
+       _cmdline.command_names_args = command_names_args;
 
        return 1;
 }
@@ -2012,6 +2016,7 @@ static void _short_usage(const char *name)
 static int _usage(const char *name, int longhelp, int skip_notes)
 {
        const struct command_name *cname = find_command_name(name);
+       const struct command_name_args *cna = &command_names_args[cname->lvm_command_enum];
        struct command *cmd = NULL;
        int show_full = longhelp;
        int i;
@@ -2031,7 +2036,7 @@ static int _usage(const char *name, int longhelp, int skip_notes)
 
        /* Reduce the default output when there are several variants. */
 
-       if (cname->variants < 3)
+       if (cna->variants < 3)
                show_full = 1;
 
        for (i = 0; i < COMMAND_COUNT; i++) {
@@ -2167,14 +2172,17 @@ static void _add_getopt_arg(int opt_enum, char **optstrp, struct option **longop
 static int _find_arg(const char *cmd_name, int goval)
 {
        const struct command_name *cname;
+       const struct command_name_args *cna;
        int arg_enum;
        int i;
 
        if (!(cname = find_command_name(cmd_name)))
                return -1;
 
-       for (i = 0; i < cname->num_args; i++) {
-               arg_enum = cname->valid_args[i];
+       cna = &command_names_args[cname->lvm_command_enum];
+
+       for (i = 0; i < cna->num_args; i++) {
+               arg_enum = cna->valid_args[i];
 
                /* assert arg_enum == _cmdline.opt_names[arg_enum].arg_enum */
 
@@ -2212,9 +2220,11 @@ static int _process_command_line(struct cmd_context *cmd, int *argc, char ***arg
         * array (opts) to pass to the getopt_long() function.  IOW we generate
         * the arguments to pass to getopt_long() from the opt_names data.
         */
-       if (cmd->cname)
-               for (i = 0; i < cmd->cname->num_args; i++)
-                       _add_getopt_arg(cmd->cname->valid_args[i], &ptr, &o);
+       if (cmd->cname) {
+               struct command_name_args *cna = &command_names_args[cmd->cname->lvm_command_enum];
+               for (i = 0; i < cna->num_args; i++)
+                       _add_getopt_arg(cna->valid_args[i], &ptr, &o);
+       }
 
        *ptr = '\0';
        memset(o, 0, sizeof(*o));
index 7be39a68bdbb655ef4bb53377c23b7e0f116685b..32fbd998263f94be43a7e3d8fdab4c26932412e9 100644 (file)
@@ -347,6 +347,7 @@ static const char *_man_long_opt_name(const char *cmdname, int opt_enum)
 static void _print_man_usage(char *lvmname, struct command *cmd)
 {
        const struct command_name *cname;
+       const struct command_name_args *cna;
        int any_req = (cmd->cmd_flags & CMD_FLAG_ANY_REQUIRED_OPT) ? 1 : 0;
        int sep, ro, rp, oo, op, opt_enum;
        int need_ro_indent_end = 0;
@@ -358,6 +359,8 @@ static void _print_man_usage(char *lvmname, struct command *cmd)
        if (!(cname = _find_command_name(cmd->name)))
                return;
 
+       cna = &command_names_args[cname->lvm_command_enum];
+
        printf("\\fB%s\\fP", lvmname);
 
        if (!any_req)
@@ -594,7 +597,7 @@ static void _print_man_usage(char *lvmname, struct command *cmd)
                        if (_is_lvm_all_opt(opt_enum))
                                continue;
 
-                       if ((cname->variants > 1) && cname->common_options[opt_enum])
+                       if ((cna->variants > 1) && cna->common_options[opt_enum])
                                continue;
 
                        if (sep)
@@ -623,7 +626,7 @@ static void _print_man_usage(char *lvmname, struct command *cmd)
                        if (_is_lvm_all_opt(opt_enum))
                                continue;
 
-                       if ((cname->variants > 1) && cname->common_options[opt_enum])
+                       if ((cna->variants > 1) && cna->common_options[opt_enum])
                                continue;
 
                        if (sep)
@@ -794,17 +797,20 @@ static void _print_man_usage_common_lvm(struct command *cmd)
 static void _print_man_usage_common_cmd(struct command *cmd)
 {
        const struct command_name *cname;
+       const struct command_name_args *cna;
        int i, sep, oo, opt_enum;
        int found_common_command = 0;
 
        if (!(cname = _find_command_name(cmd->name)))
                return;
 
-       if (cname->variants < 2)
+       cna = &command_names_args[cname->lvm_command_enum];
+
+       if (cna->variants < 2)
                return;
 
        for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
-               if (!cname->common_options[opt_enum])
+               if (!cna->common_options[opt_enum])
                        continue;
                if (_is_lvm_all_opt(opt_enum))
                        continue;
@@ -827,14 +833,14 @@ static void _print_man_usage_common_cmd(struct command *cmd)
        for (i = 0; i < ARG_COUNT; i++) {
                opt_enum = opt_names_alpha[i]->opt_enum;
 
-               if (!cname->common_options[opt_enum])
+               if (!cna->common_options[opt_enum])
                        continue;
 
                if (!opt_names[opt_enum].short_opt)
                        continue;
 
                /* common cmd options only used with variants */
-               if (cname->variants < 2)
+               if (cna->variants < 2)
                        continue;
 
                if (_is_lvm_all_opt(opt_enum))
@@ -865,14 +871,14 @@ static void _print_man_usage_common_cmd(struct command *cmd)
        for (i = 0; i < ARG_COUNT; i++) {
                opt_enum = opt_names_alpha[i]->opt_enum;
 
-               if (!cname->common_options[opt_enum])
+               if (!cna->common_options[opt_enum])
                        continue;
 
                if (opt_names[opt_enum].short_opt)
                        continue;
 
                /* common cmd options only used with variants */
-               if (cname->variants < 2)
+               if (cna->variants < 2)
                        continue;
 
                if (_is_lvm_all_opt(opt_enum))
@@ -992,15 +998,18 @@ static void _print_man_option_desc(const struct command_name *cname, int opt_enu
 
 static void _print_man_all_options_list(const struct command_name *cname)
 {
+       const struct command_name_args *cna;
        int opt_enum, val_enum;
        int sep = 0;
        int i;
        int adl = 0;
 
+       cna = &command_names_args[cname->lvm_command_enum];
+
        for (i = 0; i < ARG_COUNT; i++) {
                opt_enum = opt_names_alpha[i]->opt_enum;
 
-               if (!cname->all_options[opt_enum])
+               if (!cna->all_options[opt_enum])
                        continue;
 
                if (sep)
@@ -1046,14 +1055,17 @@ static void _print_man_all_options_list(const struct command_name *cname)
 
 static void _print_man_all_options_desc(const struct command_name *cname)
 {
+       const struct command_name_args *cna;
        int opt_enum, val_enum;
        int i;
        int adl;
 
+       cna = &command_names_args[cname->lvm_command_enum];
+
        for (i = 0; i < ARG_COUNT; i++) {
                opt_enum = opt_names_alpha[i]->opt_enum;
 
-               if (!cname->all_options[opt_enum])
+               if (!cna->all_options[opt_enum])
                        continue;
 
                val_enum = _get_val_enum(cname, opt_enum);
@@ -1347,6 +1359,7 @@ out_close:
 static int _print_man(char *name, char *des_file, int secondary)
 {
        const struct command_name *cname;
+       const struct command_name_args *cna;
        struct command *cmd, *prev_cmd = NULL;
        char *lvmname = name;
        int i;
@@ -1399,29 +1412,31 @@ static int _print_man(char *name, char *des_file, int secondary)
                        if (!(cname = _find_command_name(cmd->name)))
                                return 0;
 
-                       if (cname->variant_has_ro && cname->variant_has_rp)
+                       cna = &command_names_args[cname->lvm_command_enum];
+
+                       if (cna->variant_has_ro && cna->variant_has_rp)
                                printf("\\fB%s\\fP \\fIoption_args\\fP \\fIposition_args\\fP\n", lvmname);
-                       else if (cname->variant_has_ro && !cname->variant_has_rp)
+                       else if (cna->variant_has_ro && !cna->variant_has_rp)
                                printf("\\fB%s\\fP \\fIoption_args\\fP\n", lvmname);
-                       else if (!cname->variant_has_ro && cname->variant_has_rp)
+                       else if (!cna->variant_has_ro && cna->variant_has_rp)
                                printf("\\fB%s\\fP \\fIposition_args\\fP\n", lvmname);
-                       else if (!cname->variant_has_ro && !cname->variant_has_rp)
+                       else if (!cna->variant_has_ro && !cna->variant_has_rp)
                                printf("\\fB%s\\fP\n", lvmname);
 
                        printf(".br\n");
 
-                       if (cname->variant_has_oo) {
+                       if (cna->variant_has_oo) {
                                printf("    [ \\fIoption_args\\fP ]\n");
                                printf(".br\n");
                        }
 
-                       if (cname->variant_has_op) {
+                       if (cna->variant_has_op) {
                                printf("    [ \\fIposition_args\\fP ]\n");
                                printf(".br\n");
                        }
 
                        /* listing them all when there's only 1 or 2 is just repetative */
-                       if (cname->variants > 2) {
+                       if (cna->variants > 2) {
                                printf(".P\n");
                                _print_man_all_options_list(cname);
                        }
@@ -1448,7 +1463,7 @@ static int _print_man(char *name, char *des_file, int secondary)
                        printf(".\n.SH VARIABLES\n.\n");
                        _print_man_all_positions_desc(cname);
                } else {
-                       if (cname->variants > 2) {
+                       if (cna->variants > 2) {
                                printf("\\(em\n");
                                printf(".P\n");
                        }
This page took 0.068204 seconds and 5 git commands to generate.