[ovs-dev] [PATCH 1/2] ovs-vsctl: Factor out and optimize searching for a command by name.

Justin Pettit jpettit at nicira.com
Thu Sep 30 17:49:35 UTC 2010


Looks good.

--Justin


On Sep 1, 2010, at 1:46 PM, Ben Pfaff wrote:

> The following commit will introduce a new function that wants to do this
> a lot, so we might as well do it efficiently.
> ---
> utilities/ovs-vsctl.c |  102 ++++++++++++++++++++++++++++--------------------
> 1 files changed, 59 insertions(+), 43 deletions(-)
> 
> diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
> index 4d50194..6eea509 100644
> --- a/utilities/ovs-vsctl.c
> +++ b/utilities/ovs-vsctl.c
> @@ -105,6 +105,7 @@ static void parse_options(int argc, char *argv[]);
> static struct vsctl_command *parse_commands(int argc, char *argv[],
>                                             size_t *n_commandsp);
> static void parse_command(int argc, char *argv[], struct vsctl_command *);
> +static const struct vsctl_command_syntax *find_command(const char *name);
> static void do_vsctl(const char *args,
>                      struct vsctl_command *, size_t n_commands,
>                      struct ovsdb_idl *);
> @@ -295,6 +296,8 @@ static void
> parse_command(int argc, char *argv[], struct vsctl_command *command)
> {
>     const struct vsctl_command_syntax *p;
> +    struct shash_node *node;
> +    int n_arg;
>     int i;
> 
>     shash_init(&command->options);
> @@ -325,58 +328,71 @@ parse_command(int argc, char *argv[], struct vsctl_command *command)
>         vsctl_fatal("missing command name");
>     }
> 
> -    for (p = all_commands; p->name; p++) {
> -        if (!strcmp(p->name, argv[i])) {
> -            struct shash_node *node;
> -            int n_arg;
> +    p = find_command(argv[i]);
> +    if (!p) {
> +        vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
> +    }
> 
> -            SHASH_FOR_EACH (node, &command->options) {
> -                const char *s = strstr(p->options, node->name);
> -                int end = s ? s[strlen(node->name)] : EOF;
> +    SHASH_FOR_EACH (node, &command->options) {
> +        const char *s = strstr(p->options, node->name);
> +        int end = s ? s[strlen(node->name)] : EOF;
> 
> -                if (end != '=' && end != ',' && end != ' ' && end != '\0') {
> -                    vsctl_fatal("'%s' command has no '%s' option",
> -                                argv[i], node->name);
> -                }
> -                if ((end == '=') != (node->data != NULL)) {
> -                    if (end == '=') {
> -                        vsctl_fatal("missing argument to '%s' option on '%s' "
> -                                    "command", node->name, argv[i]);
> -                    } else {
> -                        vsctl_fatal("'%s' option on '%s' does not accept an "
> -                                    "argument", node->name, argv[i]);
> -                    }
> -                }
> +        if (end != '=' && end != ',' && end != ' ' && end != '\0') {
> +            vsctl_fatal("'%s' command has no '%s' option",
> +                        argv[i], node->name);
> +        }
> +        if ((end == '=') != (node->data != NULL)) {
> +            if (end == '=') {
> +                vsctl_fatal("missing argument to '%s' option on '%s' "
> +                            "command", node->name, argv[i]);
> +            } else {
> +                vsctl_fatal("'%s' option on '%s' does not accept an "
> +                            "argument", node->name, argv[i]);
>             }
> +        }
> +    }
> 
> -            n_arg = argc - i - 1;
> -            if (n_arg < p->min_args) {
> -                vsctl_fatal("'%s' command requires at least %d arguments",
> -                            p->name, p->min_args);
> -            } else if (n_arg > p->max_args) {
> -                int j;
> -
> -                for (j = i + 1; j < argc; j++) {
> -                    if (argv[j][0] == '-') {
> -                        vsctl_fatal("'%s' command takes at most %d arguments "
> -                                    "(note that options must precede command "
> -                                    "names and follow a \"--\" argument)",
> -                                    p->name, p->max_args);
> -                    }
> -                }
> +    n_arg = argc - i - 1;
> +    if (n_arg < p->min_args) {
> +        vsctl_fatal("'%s' command requires at least %d arguments",
> +                    p->name, p->min_args);
> +    } else if (n_arg > p->max_args) {
> +        int j;
> 
> -                vsctl_fatal("'%s' command takes at most %d arguments",
> +        for (j = i + 1; j < argc; j++) {
> +            if (argv[j][0] == '-') {
> +                vsctl_fatal("'%s' command takes at most %d arguments "
> +                            "(note that options must precede command "
> +                            "names and follow a \"--\" argument)",
>                             p->name, p->max_args);
> -            } else {
> -                command->syntax = p;
> -                command->argc = n_arg + 1;
> -                command->argv = &argv[i];
> -                return;
>             }
>         }
> +
> +        vsctl_fatal("'%s' command takes at most %d arguments",
> +                    p->name, p->max_args);
> +    }
> +
> +    command->syntax = p;
> +    command->argc = n_arg + 1;
> +    command->argv = &argv[i];
> +}
> +
> +/* Returns the "struct vsctl_command_syntax" for a given command 'name', or a
> + * null pointer if there is none. */
> +static const struct vsctl_command_syntax *
> +find_command(const char *name)
> +{
> +    static struct shash commands = SHASH_INITIALIZER(&commands);
> +
> +    if (shash_is_empty(&commands)) {
> +        const struct vsctl_command_syntax *p;
> +
> +        for (p = all_commands; p->name; p++) {
> +            shash_add_assert(&commands, p->name, p);
> +        }
>     }
> 
> -    vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
> +    return shash_find_data(&commands, name);
> }
> 
> static void
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev_openvswitch.org





More information about the dev mailing list