Reference arrays after its definition.

Signed-off-by: Linda Sun <l...@vmware.com>
---
 lib/netlink.c                |   19 +-
 lib/odp-util.c               |   15 +-
 ofproto/ofproto-dpif-xlate.c |    7 +-
 ovsdb/ovsdb-tool.c           |   21 +-
 utilities/ovs-dpctl.c        |   23 +-
 utilities/ovs-ofctl.c        |   23 +-
 utilities/ovs-vsctl.c        |  629 +++++++++++++++++++++---------------------
 7 files changed, 367 insertions(+), 370 deletions(-)

diff --git a/lib/netlink.c b/lib/netlink.c
index 7e7884e..421a58a 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -608,15 +608,16 @@ nl_attr_get_nested(const struct nlattr *nla, struct 
ofpbuf *nested)
 }
 
 /* Default minimum and maximum payload sizes for each type of attribute. */
-static const size_t attr_len_range[][2] = {
-    [0 ... N_NL_ATTR_TYPES - 1] = { 0, SIZE_MAX },
-    [NL_A_U8] = { 1, 1 },
-    [NL_A_U16] = { 2, 2 },
-    [NL_A_U32] = { 4, 4 },
-    [NL_A_U64] = { 8, 8 },
-    [NL_A_STRING] = { 1, SIZE_MAX },
-    [NL_A_FLAG] = { 0, SIZE_MAX },
-    [NL_A_NESTED] = { 0, SIZE_MAX },
+static const size_t attr_len_range[N_NL_ATTR_TYPES][2] = {
+  { 0, SIZE_MAX },       // NL_A_NO_ATTR
+  { 0, SIZE_MAX },       // NL_A_UNSPEC
+  { 1, 1 },              // NL_A_U8
+  { 2, 2 },              // NL_A_U16
+  { 4, 4 },              // NL_A_U32
+  { 8, 8 },              // NL_A_U64
+  { 1, SIZE_MAX },       // NL_A_STRING
+  { 0, SIZE_MAX },       // NL_A_FLAG
+  { 0, SIZE_MAX },       // NL_A_NESTED
 };
 
 bool
diff --git a/lib/odp-util.c b/lib/odp-util.c
index b233cbe..b41fd89 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -143,9 +143,10 @@ format_generic_odp_action(struct ds *ds, const struct 
nlattr *a)
 static void
 format_odp_sample_action(struct ds *ds, const struct nlattr *attr)
 {
-    static const struct nl_policy ovs_sample_policy[] = {
-        [OVS_SAMPLE_ATTR_PROBABILITY] = { .type = NL_A_U32 },
-        [OVS_SAMPLE_ATTR_ACTIONS] = { .type = NL_A_NESTED }
+    static const struct nl_policy ovs_sample_policy[__OVS_SAMPLE_ATTR_MAX] = {
+      { NL_A_NO_ATTR, 0, 0, false},    // OVS_SAMPLE_ATTR_UNSPEC
+      { NL_A_U32, 0, 0, false},        // OVS_SAMPLE_ATTR_PROBABILITY
+      { NL_A_NESTED, 0, 0, false},     // OVS_SAMPLE_ATTR_ACTIONS
     };
     struct nlattr *a[ARRAY_SIZE(ovs_sample_policy)];
     double percentage;
@@ -258,10 +259,10 @@ parse_flags(const char *s, const char 
*(*bit_to_string)(uint32_t),
 static void
 format_odp_userspace_action(struct ds *ds, const struct nlattr *attr)
 {
-    static const struct nl_policy ovs_userspace_policy[] = {
-        [OVS_USERSPACE_ATTR_PID] = { .type = NL_A_U32 },
-        [OVS_USERSPACE_ATTR_USERDATA] = { .type = NL_A_UNSPEC,
-                                          .optional = true },
+    static const struct nl_policy 
ovs_userspace_policy[__OVS_USERSPACE_ATTR_MAX] = {
+      { NL_A_NO_ATTR, 0, 0, false},   // OVS_USERSPACE_ATTR_UNSPEC
+      { NL_A_U32, 0, 0, false},       // OVS_USERSPACE_ATTR_PID
+      { NL_A_UNSPEC, 0, 0, true},     // OVS_USERSPACE_ATTR_USERDATA
     };
     struct nlattr *a[ARRAY_SIZE(ovs_userspace_policy)];
     const struct nlattr *userdata_attr;
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 0507f8e..2dda02f 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -161,10 +161,7 @@ struct xlate_ctx {
  * when an input bundle is needed for validation (e.g., mirroring or
  * OFPP_NORMAL processing).  It is not connected to an 'ofproto' or have
  * any 'port' structs, so care must be taken when dealing with it. */
-static struct xbundle ofpp_none_bundle = {
-    .name      = "OFPP_NONE",
-    .vlan_mode = PORT_VLAN_TRUNK
-};
+static struct xbundle ofpp_none_bundle;
 
 static struct hmap xbridges = HMAP_INITIALIZER(&xbridges);
 static struct hmap xbundles = HMAP_INITIALIZER(&xbundles);
@@ -530,6 +527,8 @@ lookup_input_bundle(const struct xbridge *xbridge, 
ofp_port_t in_port,
     /* Special-case OFPP_NONE, which a controller may use as the ingress
      * port for traffic that it is sourcing. */
     if (in_port == OFPP_NONE) {
+        ofpp_none_bundle.name = "OFPP_NONE";
+        ofpp_none_bundle.vlan_mode = PORT_VLAN_TRUNK;
         return &ofpp_none_bundle;
     }
 
diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c
index a8febda..4b20eb0 100644
--- a/ovsdb/ovsdb-tool.c
+++ b/ovsdb/ovsdb-tool.c
@@ -53,16 +53,6 @@ static void parse_options(int argc, char *argv[]);
 static const char *default_db(void);
 static const char *default_schema(void);
 
-int
-main(int argc, char *argv[])
-{
-    set_program_name(argv[0]);
-    parse_options(argc, argv);
-    signal(SIGPIPE, SIG_IGN);
-    run_command(argc - optind, argv + optind, all_commands);
-    return 0;
-}
-
 static void
 parse_options(int argc, char *argv[])
 {
@@ -564,3 +554,14 @@ static const struct command all_commands[] = {
     { "help", 0, INT_MAX, do_help },
     { NULL, 0, 0, NULL },
 };
+
+int
+main(int argc, char *argv[])
+{
+  set_program_name(argv[0]);
+  parse_options(argc, argv);
+  signal(SIGPIPE, SIG_IGN);
+  run_command(argc - optind, argv + optind, all_commands);
+  return 0;
+}
+
diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c
index 2389942..47f50d8 100644
--- a/utilities/ovs-dpctl.c
+++ b/utilities/ovs-dpctl.c
@@ -66,21 +66,9 @@ static bool may_create;
  * the option itself. */
 static int verbosity;
 
-static const struct command all_commands[];
-
 static void usage(void) NO_RETURN;
 static void parse_options(int argc, char *argv[]);
 
-int
-main(int argc, char *argv[])
-{
-    set_program_name(argv[0]);
-    parse_options(argc, argv);
-    signal(SIGPIPE, SIG_IGN);
-    run_command(argc - optind, argv + optind, all_commands);
-    return 0;
-}
-
 static void
 parse_options(int argc, char *argv[])
 {
@@ -1146,3 +1134,14 @@ static const struct command all_commands[] = {
 
     { NULL, 0, 0, NULL },
 };
+
+int
+main(int argc, char *argv[])
+{
+    set_program_name(argv[0]);
+    parse_options(argc, argv);
+    signal(SIGPIPE, SIG_IGN);
+    run_command(argc - optind, argv + optind, all_commands);
+    return 0;
+}
+
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 4d5a84e..9797fdc 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -98,8 +98,6 @@ struct sort_criterion {
 static struct sort_criterion *criteria;
 static size_t n_criteria, allocated_criteria;
 
-static const struct command all_commands[];
-
 static void usage(void) NO_RETURN;
 static void parse_options(int argc, char *argv[]);
 
@@ -107,16 +105,6 @@ static bool recv_flow_stats_reply(struct vconn *, ovs_be32 
send_xid,
                                   struct ofpbuf **replyp,
                                   struct ofputil_flow_stats *,
                                   struct ofpbuf *ofpacts);
-int
-main(int argc, char *argv[])
-{
-    set_program_name(argv[0]);
-    parse_options(argc, argv);
-    signal(SIGPIPE, SIG_IGN);
-    run_command(argc - optind, argv + optind, all_commands);
-    return 0;
-}
-
 static void
 add_sort_criterion(enum sort_order order, const char *field)
 {
@@ -2956,3 +2944,14 @@ static const struct command all_commands[] = {
 
     { NULL, 0, 0, NULL },
 };
+
+int
+main(int argc, char *argv[])
+{
+    set_program_name(argv[0]);
+    parse_options(argc, argv);
+    signal(SIGPIPE, SIG_IGN);
+    run_command(argc - optind, argv + optind, all_commands);
+    return 0;
+}
+
diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index e679e0d..86edba4 100644
--- a/utilities/ovs-vsctl.c
+++ b/utilities/ovs-vsctl.c
@@ -127,9 +127,6 @@ static bool retry;
 /* Format for table output. */
 static struct table_style table_style = TABLE_STYLE_DEFAULT;
 
-/* All supported commands. */
-static const struct vsctl_command_syntax all_commands[];
-
 /* The IDL we're using and the current transaction, if any.
  * This is for use by vsctl_exit() only, to allow it to clean up.
  * Other code should use its context arguments. */
@@ -251,188 +248,6 @@ add_option(struct option **optionsp, size_t *n_optionsp,
     return &(*optionsp)[(*n_optionsp)++];
 }
 
-static void
-parse_options(int argc, char *argv[], struct shash *local_options)
-{
-    enum {
-        OPT_DB = UCHAR_MAX + 1,
-        OPT_ONELINE,
-        OPT_NO_SYSLOG,
-        OPT_NO_WAIT,
-        OPT_DRY_RUN,
-        OPT_PEER_CA_CERT,
-        OPT_LOCAL,
-        OPT_RETRY,
-        VLOG_OPTION_ENUMS,
-        TABLE_OPTION_ENUMS
-    };
-    static const struct option global_long_options[] = {
-        {"db", required_argument, NULL, OPT_DB},
-        {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
-        {"no-wait", no_argument, NULL, OPT_NO_WAIT},
-        {"dry-run", no_argument, NULL, OPT_DRY_RUN},
-        {"oneline", no_argument, NULL, OPT_ONELINE},
-        {"timeout", required_argument, NULL, 't'},
-        {"retry", no_argument, NULL, OPT_RETRY},
-        {"help", no_argument, NULL, 'h'},
-        {"version", no_argument, NULL, 'V'},
-        VLOG_LONG_OPTIONS,
-        TABLE_LONG_OPTIONS,
-        STREAM_SSL_LONG_OPTIONS,
-        {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
-        {NULL, 0, NULL, 0},
-    };
-    const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
-    char *tmp, *short_options;
-
-    const struct vsctl_command_syntax *p;
-    struct option *options, *o;
-    size_t allocated_options;
-    size_t n_options;
-    size_t i;
-
-    tmp = long_options_to_short_options(global_long_options);
-    short_options = xasprintf("+%s", tmp);
-    free(tmp);
-
-    /* We want to parse both global and command-specific options here, but
-     * getopt_long() isn't too convenient for the job.  We copy our global
-     * options into a dynamic array, then append all of the command-specific
-     * options. */
-    options = xmemdup(global_long_options, sizeof global_long_options);
-    allocated_options = ARRAY_SIZE(global_long_options);
-    n_options = n_global_long_options;
-    for (p = all_commands; p->name; p++) {
-        if (p->options[0]) {
-            char *save_ptr = NULL;
-            char *name;
-            char *s;
-
-            s = xstrdup(p->options);
-            for (name = strtok_r(s, ",", &save_ptr); name != NULL;
-                 name = strtok_r(NULL, ",", &save_ptr)) {
-                char *equals;
-                int has_arg;
-
-                ovs_assert(name[0] == '-' && name[1] == '-' && name[2]);
-                name += 2;
-
-                equals = strchr(name, '=');
-                if (equals) {
-                    has_arg = required_argument;
-                    *equals = '\0';
-                } else {
-                    has_arg = no_argument;
-                }
-
-                o = find_option(name, options, n_options);
-                if (o) {
-                    ovs_assert(o - options >= n_global_long_options);
-                    ovs_assert(o->has_arg == has_arg);
-                } else {
-                    o = add_option(&options, &n_options, &allocated_options);
-                    o->name = xstrdup(name);
-                    o->has_arg = has_arg;
-                    o->flag = NULL;
-                    o->val = OPT_LOCAL;
-                }
-            }
-
-            free(s);
-        }
-    }
-    o = add_option(&options, &n_options, &allocated_options);
-    memset(o, 0, sizeof *o);
-
-    table_style.format = TF_LIST;
-
-    for (;;) {
-        int idx;
-        int c;
-
-        c = getopt_long(argc, argv, short_options, options, &idx);
-        if (c == -1) {
-            break;
-        }
-
-        switch (c) {
-        case OPT_DB:
-            db = optarg;
-            break;
-
-        case OPT_ONELINE:
-            oneline = true;
-            break;
-
-        case OPT_NO_SYSLOG:
-            vlog_set_levels(&VLM_vsctl, VLF_SYSLOG, VLL_WARN);
-            break;
-
-        case OPT_NO_WAIT:
-            wait_for_reload = false;
-            break;
-
-        case OPT_DRY_RUN:
-            dry_run = true;
-            break;
-
-        case OPT_LOCAL:
-            if (shash_find(local_options, options[idx].name)) {
-                vsctl_fatal("'%s' option specified multiple times",
-                            options[idx].name);
-            }
-            shash_add_nocopy(local_options,
-                             xasprintf("--%s", options[idx].name),
-                             optarg ? xstrdup(optarg) : NULL);
-            break;
-
-        case 'h':
-            usage();
-
-        case 'V':
-            ovs_print_version(0, 0);
-            exit(EXIT_SUCCESS);
-
-        case 't':
-            timeout = strtoul(optarg, NULL, 10);
-            if (timeout < 0) {
-                vsctl_fatal("value %s on -t or --timeout is invalid",
-                            optarg);
-            }
-            break;
-
-        case OPT_RETRY:
-            retry = true;
-            break;
-
-        VLOG_OPTION_HANDLERS
-        TABLE_OPTION_HANDLERS(&table_style)
-
-        STREAM_SSL_OPTION_HANDLERS
-
-        case OPT_PEER_CA_CERT:
-            stream_ssl_set_peer_ca_cert_file(optarg);
-            break;
-
-        case '?':
-            exit(EXIT_FAILURE);
-
-        default:
-            abort();
-        }
-    }
-    free(short_options);
-
-    if (!db) {
-        db = default_db();
-    }
-
-    for (i = n_global_long_options; options[i].name; i++) {
-        free(CONST_CAST(char *, options[i].name));
-    }
-    free(options);
-}
-
 static struct vsctl_command *
 parse_commands(int argc, char *argv[], struct shash *local_options,
                size_t *n_commandsp)
@@ -472,142 +287,37 @@ parse_commands(int argc, char *argv[], struct shash 
*local_options,
 }
 
 static void
-parse_command(int argc, char *argv[], struct shash *local_options,
-              struct vsctl_command *command)
+vsctl_fatal(const char *format, ...)
 {
-    const struct vsctl_command_syntax *p;
-    struct shash_node *node;
-    int n_arg;
-    int i;
-
-    shash_init(&command->options);
-    shash_swap(local_options, &command->options);
-    for (i = 0; i < argc; i++) {
-        const char *option = argv[i];
-        const char *equals;
-        char *key, *value;
-
-        if (option[0] != '-') {
-            break;
-        }
+    char *message;
+    va_list args;
 
-        equals = strchr(option, '=');
-        if (equals) {
-            key = xmemdup0(option, equals - option);
-            value = xstrdup(equals + 1);
-        } else {
-            key = xstrdup(option);
-            value = NULL;
-        }
+    va_start(args, format);
+    message = xvasprintf(format, args);
+    va_end(args);
 
-        if (shash_find(&command->options, key)) {
-            vsctl_fatal("'%s' option specified multiple times", argv[i]);
-        }
-        shash_add_nocopy(&command->options, key, value);
-    }
-    if (i == argc) {
-        vsctl_fatal("missing command name (use --help for help)");
-    }
+    vlog_set_levels(&VLM_vsctl, VLF_CONSOLE, VLL_OFF);
+    VLOG_ERR("%s", message);
+    ovs_error(0, "%s", message);
+    vsctl_exit(EXIT_FAILURE);
+}
 
-    p = find_command(argv[i]);
-    if (!p) {
-        vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
+/* Frees the current transaction and the underlying IDL and then calls
+ * exit(status).
+ *
+ * Freeing the transaction and the IDL is not strictly necessary, but it makes
+ * for a clean memory leak report from valgrind in the normal case.  That makes
+ * it easier to notice real memory leaks. */
+static void
+vsctl_exit(int status)
+{
+    if (the_idl_txn) {
+        ovsdb_idl_txn_abort(the_idl_txn);
+        ovsdb_idl_txn_destroy(the_idl_txn);
     }
-
-    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]);
-            }
-        }
-    }
-
-    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);
-            }
-        }
-
-        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);
-        }
-    }
-
-    return shash_find_data(&commands, name);
-}
-
-static void
-vsctl_fatal(const char *format, ...)
-{
-    char *message;
-    va_list args;
-
-    va_start(args, format);
-    message = xvasprintf(format, args);
-    va_end(args);
-
-    vlog_set_levels(&VLM_vsctl, VLF_CONSOLE, VLL_OFF);
-    VLOG_ERR("%s", message);
-    ovs_error(0, "%s", message);
-    vsctl_exit(EXIT_FAILURE);
-}
-
-/* Frees the current transaction and the underlying IDL and then calls
- * exit(status).
- *
- * Freeing the transaction and the IDL is not strictly necessary, but it makes
- * for a clean memory leak report from valgrind in the normal case.  That makes
- * it easier to notice real memory leaks. */
-static void
-vsctl_exit(int status)
-{
-    if (the_idl_txn) {
-        ovsdb_idl_txn_abort(the_idl_txn);
-        ovsdb_idl_txn_destroy(the_idl_txn);
-    }
-    ovsdb_idl_destroy(the_idl);
-    exit(status);
-}
+    ovsdb_idl_destroy(the_idl);
+    exit(status);
+}
 
 static void
 usage(void)
@@ -4228,3 +3938,290 @@ static const struct vsctl_command_syntax all_commands[] 
= {
     {NULL, 0, 0, NULL, NULL, NULL, NULL, RO},
 };
 
+static void
+parse_command(int argc, char *argv[], struct shash *local_options,
+              struct vsctl_command *command)
+{
+    const struct vsctl_command_syntax *p;
+    struct shash_node *node;
+    int n_arg;
+    int i;
+
+    shash_init(&command->options);
+    shash_swap(local_options, &command->options);
+    for (i = 0; i < argc; i++) {
+        const char *option = argv[i];
+        const char *equals;
+        char *key, *value;
+
+        if (option[0] != '-') {
+            break;
+        }
+
+        equals = strchr(option, '=');
+        if (equals) {
+            key = xmemdup0(option, equals - option);
+            value = xstrdup(equals + 1);
+        } else {
+            key = xstrdup(option);
+            value = NULL;
+        }
+
+        if (shash_find(&command->options, key)) {
+            vsctl_fatal("'%s' option specified multiple times", argv[i]);
+        }
+        shash_add_nocopy(&command->options, key, value);
+    }
+    if (i == argc) {
+        vsctl_fatal("missing command name (use --help for help)");
+    }
+
+    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;
+
+        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);
+            }
+        }
+
+        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];
+}
+
+static void
+parse_options(int argc, char *argv[], struct shash *local_options)
+{
+    enum {
+        OPT_DB = UCHAR_MAX + 1,
+        OPT_ONELINE,
+        OPT_NO_SYSLOG,
+        OPT_NO_WAIT,
+        OPT_DRY_RUN,
+        OPT_PEER_CA_CERT,
+        OPT_LOCAL,
+        OPT_RETRY,
+        VLOG_OPTION_ENUMS,
+        TABLE_OPTION_ENUMS
+    };
+    static const struct option global_long_options[] = {
+        {"db", required_argument, NULL, OPT_DB},
+        {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
+        {"no-wait", no_argument, NULL, OPT_NO_WAIT},
+        {"dry-run", no_argument, NULL, OPT_DRY_RUN},
+        {"oneline", no_argument, NULL, OPT_ONELINE},
+        {"timeout", required_argument, NULL, 't'},
+        {"retry", no_argument, NULL, OPT_RETRY},
+        {"help", no_argument, NULL, 'h'},
+        {"version", no_argument, NULL, 'V'},
+        VLOG_LONG_OPTIONS,
+        TABLE_LONG_OPTIONS,
+        STREAM_SSL_LONG_OPTIONS,
+        {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
+        {NULL, 0, NULL, 0},
+    };
+    const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
+    char *tmp, *short_options;
+
+    const struct vsctl_command_syntax *p;
+    struct option *options, *o;
+    size_t allocated_options;
+    size_t n_options;
+    size_t i;
+
+    tmp = long_options_to_short_options(global_long_options);
+    short_options = xasprintf("+%s", tmp);
+    free(tmp);
+
+    /* We want to parse both global and command-specific options here, but
+     * getopt_long() isn't too convenient for the job.  We copy our global
+     * options into a dynamic array, then append all of the command-specific
+     * options. */
+    options = xmemdup(global_long_options, sizeof global_long_options);
+    allocated_options = ARRAY_SIZE(global_long_options);
+    n_options = n_global_long_options;
+    for (p = all_commands; p->name; p++) {
+        if (p->options[0]) {
+            char *save_ptr = NULL;
+            char *name;
+            char *s;
+
+            s = xstrdup(p->options);
+            for (name = strtok_r(s, ",", &save_ptr); name != NULL;
+                 name = strtok_r(NULL, ",", &save_ptr)) {
+                char *equals;
+                int has_arg;
+
+                ovs_assert(name[0] == '-' && name[1] == '-' && name[2]);
+                name += 2;
+
+                equals = strchr(name, '=');
+                if (equals) {
+                    has_arg = required_argument;
+                    *equals = '\0';
+                } else {
+                    has_arg = no_argument;
+                }
+
+                o = find_option(name, options, n_options);
+                if (o) {
+                    ovs_assert(o - options >= n_global_long_options);
+                    ovs_assert(o->has_arg == has_arg);
+                } else {
+                    o = add_option(&options, &n_options, &allocated_options);
+                    o->name = xstrdup(name);
+                    o->has_arg = has_arg;
+                    o->flag = NULL;
+                    o->val = OPT_LOCAL;
+                }
+            }
+
+            free(s);
+        }
+    }
+    o = add_option(&options, &n_options, &allocated_options);
+    memset(o, 0, sizeof *o);
+
+    table_style.format = TF_LIST;
+
+    for (;;) {
+        int idx;
+        int c;
+
+        c = getopt_long(argc, argv, short_options, options, &idx);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+        case OPT_DB:
+            db = optarg;
+            break;
+
+        case OPT_ONELINE:
+            oneline = true;
+            break;
+
+        case OPT_NO_SYSLOG:
+            vlog_set_levels(&VLM_vsctl, VLF_SYSLOG, VLL_WARN);
+            break;
+
+        case OPT_NO_WAIT:
+            wait_for_reload = false;
+            break;
+
+        case OPT_DRY_RUN:
+            dry_run = true;
+            break;
+
+        case OPT_LOCAL:
+            if (shash_find(local_options, options[idx].name)) {
+                vsctl_fatal("'%s' option specified multiple times",
+                            options[idx].name);
+            }
+            shash_add_nocopy(local_options,
+                             xasprintf("--%s", options[idx].name),
+                             optarg ? xstrdup(optarg) : NULL);
+            break;
+
+        case 'h':
+            usage();
+
+        case 'V':
+            ovs_print_version(0, 0);
+            exit(EXIT_SUCCESS);
+
+        case 't':
+            timeout = strtoul(optarg, NULL, 10);
+            if (timeout < 0) {
+                vsctl_fatal("value %s on -t or --timeout is invalid",
+                            optarg);
+            }
+            break;
+
+        case OPT_RETRY:
+            retry = true;
+            break;
+
+        VLOG_OPTION_HANDLERS
+        TABLE_OPTION_HANDLERS(&table_style)
+
+        STREAM_SSL_OPTION_HANDLERS
+
+        case OPT_PEER_CA_CERT:
+            stream_ssl_set_peer_ca_cert_file(optarg);
+            break;
+
+        case '?':
+            exit(EXIT_FAILURE);
+
+        default:
+            abort();
+        }
+    }
+    free(short_options);
+
+    if (!db) {
+        db = default_db();
+    }
+
+    for (i = n_global_long_options; options[i].name; i++) {
+        free(CONST_CAST(char *, options[i].name));
+    }
+    free(options);
+}
+
+/* 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);
+    }
+  }
+
+  return shash_find_data(&commands, name);
+}
+
+
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to