Reference arrays after its definition.
Signed-off-by: Linda Sun <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev