2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-03 15:55:19 +00:00

table: Add new "bare" output formatting options.

--format=list corresponds to the output format that "ovs-vsctl list" has
always used.

--bare is easier for scripts to parse.
This commit is contained in:
Ben Pfaff
2011-02-02 11:24:35 -08:00
parent 3a3eb9daef
commit c6a4125250
7 changed files with 110 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2009, 2010 Nicira Networks /* Copyright (c) 2009, 2010, 2011 Nicira Networks
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -625,6 +625,20 @@ ovsdb_atom_to_string(const union ovsdb_atom *atom, enum ovsdb_atomic_type type,
} }
} }
/* Appends 'atom' (which has the given 'type') to 'out', in a bare string
* format that cannot be parsed uniformly back into a datum but is easier for
* shell scripts, etc., to deal with. */
void
ovsdb_atom_to_bare(const union ovsdb_atom *atom, enum ovsdb_atomic_type type,
struct ds *out)
{
if (type == OVSDB_TYPE_STRING) {
ds_put_cstr(out, atom->string);
} else {
ovsdb_atom_to_string(atom, type, out);
}
}
static struct ovsdb_error * static struct ovsdb_error *
check_string_constraints(const char *s, check_string_constraints(const char *s,
const struct ovsdb_string_constraints *c) const struct ovsdb_string_constraints *c)
@@ -1445,6 +1459,29 @@ ovsdb_datum_to_string(const struct ovsdb_datum *datum,
} }
} }
/* Appends to 'out' the 'datum' (with the given 'type') in a bare string format
* that cannot be parsed uniformly back into a datum but is easier for shell
* scripts, etc., to deal with. */
void
ovsdb_datum_to_bare(const struct ovsdb_datum *datum,
const struct ovsdb_type *type, struct ds *out)
{
bool is_map = ovsdb_type_is_map(type);
size_t i;
for (i = 0; i < datum->n; i++) {
if (i > 0) {
ds_put_cstr(out, " ");
}
ovsdb_atom_to_bare(&datum->keys[i], type->key.type, out);
if (is_map) {
ds_put_char(out, '=');
ovsdb_atom_to_bare(&datum->values[i], type->value.type, out);
}
}
}
/* Initializes 'datum' as a string-to-string map whose contents are taken from /* Initializes 'datum' as a string-to-string map whose contents are taken from
* 'sh'. Destroys 'sh'. */ * 'sh'. Destroys 'sh'. */
void void

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2009, 2010 Nicira Networks /* Copyright (c) 2009, 2010, 2011 Nicira Networks
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -94,6 +94,8 @@ char *ovsdb_atom_from_string(union ovsdb_atom *,
WARN_UNUSED_RESULT; WARN_UNUSED_RESULT;
void ovsdb_atom_to_string(const union ovsdb_atom *, enum ovsdb_atomic_type, void ovsdb_atom_to_string(const union ovsdb_atom *, enum ovsdb_atomic_type,
struct ds *); struct ds *);
void ovsdb_atom_to_bare(const union ovsdb_atom *, enum ovsdb_atomic_type,
struct ds *);
struct ovsdb_error *ovsdb_atom_check_constraints( struct ovsdb_error *ovsdb_atom_check_constraints(
const union ovsdb_atom *, const struct ovsdb_base_type *) const union ovsdb_atom *, const struct ovsdb_base_type *)
@@ -167,6 +169,8 @@ char *ovsdb_datum_from_string(struct ovsdb_datum *,
WARN_UNUSED_RESULT; WARN_UNUSED_RESULT;
void ovsdb_datum_to_string(const struct ovsdb_datum *, void ovsdb_datum_to_string(const struct ovsdb_datum *,
const struct ovsdb_type *, struct ds *); const struct ovsdb_type *, struct ds *);
void ovsdb_datum_to_bare(const struct ovsdb_datum *,
const struct ovsdb_type *, struct ds *);
void ovsdb_datum_from_shash(struct ovsdb_datum *, struct shash *); void ovsdb_datum_from_shash(struct ovsdb_datum *, struct shash *);

View File

@@ -36,7 +36,7 @@ cell_to_text(struct cell *cell, const struct table_style *style)
if (cell->json) { if (cell->json) {
if (style->cell_format == CF_JSON || !cell->type) { if (style->cell_format == CF_JSON || !cell->type) {
cell->text = json_to_string(cell->json, JSSF_SORT); cell->text = json_to_string(cell->json, JSSF_SORT);
} else if (style->cell_format == CF_STRING) { } else {
struct ovsdb_datum datum; struct ovsdb_datum datum;
struct ovsdb_error *error; struct ovsdb_error *error;
struct ds s; struct ds s;
@@ -45,14 +45,16 @@ cell_to_text(struct cell *cell, const struct table_style *style)
NULL); NULL);
if (!error) { if (!error) {
ds_init(&s); ds_init(&s);
if (style->cell_format == CF_STRING) {
ovsdb_datum_to_string(&datum, cell->type, &s); ovsdb_datum_to_string(&datum, cell->type, &s);
} else {
ovsdb_datum_to_bare(&datum, cell->type, &s);
}
ovsdb_datum_destroy(&datum, cell->type); ovsdb_datum_destroy(&datum, cell->type);
cell->text = ds_steal_cstr(&s); cell->text = ds_steal_cstr(&s);
} else { } else {
cell->text = json_to_string(cell->json, JSSF_SORT); cell->text = json_to_string(cell->json, JSSF_SORT);
} }
} else {
NOT_REACHED();
} }
} else { } else {
cell->text = xstrdup(""); cell->text = xstrdup("");
@@ -272,6 +274,34 @@ table_print_table__(const struct table *table, const struct table_style *style)
free(widths); free(widths);
} }
static void
table_print_list__(const struct table *table, const struct table_style *style)
{
static int n = 0;
size_t x, y;
if (n++ > 0) {
putchar('\n');
}
if (table->caption) {
puts(table->caption);
}
for (y = 0; y < table->n_rows; y++) {
if (y > 0) {
putchar('\n');
}
for (x = 0; x < table->n_columns; x++) {
const char *text = cell_to_text(table_cell__(table, y, x), style);
if (style->headings) {
printf("%-20s: ", table->columns[x].heading);
}
puts(text);
}
}
}
static void static void
table_escape_html_text__(const char *s, size_t n) table_escape_html_text__(const char *s, size_t n)
{ {
@@ -469,6 +499,8 @@ table_parse_format(struct table_style *style, const char *format)
{ {
if (!strcmp(format, "table")) { if (!strcmp(format, "table")) {
style->format = TF_TABLE; style->format = TF_TABLE;
} else if (!strcmp(format, "list")) {
style->format = TF_LIST;
} else if (!strcmp(format, "html")) { } else if (!strcmp(format, "html")) {
style->format = TF_HTML; style->format = TF_HTML;
} else if (!strcmp(format, "csv")) { } else if (!strcmp(format, "csv")) {
@@ -487,6 +519,8 @@ table_parse_cell_format(struct table_style *style, const char *format)
{ {
if (!strcmp(format, "string")) { if (!strcmp(format, "string")) {
style->cell_format = CF_STRING; style->cell_format = CF_STRING;
} else if (!strcmp(format, "bare")) {
style->cell_format = CF_BARE;
} else if (!strcmp(format, "json")) { } else if (!strcmp(format, "json")) {
style->cell_format = CF_JSON; style->cell_format = CF_JSON;
} else { } else {
@@ -503,6 +537,10 @@ table_print(const struct table *table, const struct table_style *style)
table_print_table__(table, style); table_print_table__(table, style);
break; break;
case TF_LIST:
table_print_list__(table, style);
break;
case TF_HTML: case TF_HTML:
table_print_html__(table, style); table_print_html__(table, style);
break; break;

View File

@@ -59,6 +59,7 @@ struct cell *table_add_cell(struct table *);
enum table_format { enum table_format {
TF_TABLE, /* 2-d table. */ TF_TABLE, /* 2-d table. */
TF_LIST, /* One cell per line, one row per paragraph. */
TF_HTML, /* HTML table. */ TF_HTML, /* HTML table. */
TF_CSV, /* Comma-separated lines. */ TF_CSV, /* Comma-separated lines. */
TF_JSON /* JSON. */ TF_JSON /* JSON. */
@@ -66,6 +67,7 @@ enum table_format {
enum cell_format { enum cell_format {
CF_STRING, /* String format. */ CF_STRING, /* String format. */
CF_BARE, /* String format without most punctuation. */
CF_JSON /* JSON. */ CF_JSON /* JSON. */
}; };
@@ -80,13 +82,15 @@ struct table_style {
#define TABLE_OPTION_ENUMS \ #define TABLE_OPTION_ENUMS \
OPT_NO_HEADINGS, \ OPT_NO_HEADINGS, \
OPT_PRETTY OPT_PRETTY, \
OPT_BARE
#define TABLE_LONG_OPTIONS \ #define TABLE_LONG_OPTIONS \
{"format", required_argument, 0, 'f'}, \ {"format", required_argument, 0, 'f'}, \
{"data", required_argument, 0, 'd'}, \ {"data", required_argument, 0, 'd'}, \
{"no-headings", no_argument, 0, OPT_NO_HEADINGS}, \ {"no-headings", no_argument, 0, OPT_NO_HEADINGS}, \
{"pretty", no_argument, 0, OPT_PRETTY}, {"pretty", no_argument, 0, OPT_PRETTY}, \
{"bare", no_argument, 0, OPT_BARE}
#define TABLE_OPTION_HANDLERS(STYLE) \ #define TABLE_OPTION_HANDLERS(STYLE) \
case 'f': \ case 'f': \
@@ -103,6 +107,12 @@ struct table_style {
\ \
case OPT_PRETTY: \ case OPT_PRETTY: \
(STYLE)->json_flags |= JSSF_PRETTY; \ (STYLE)->json_flags |= JSSF_PRETTY; \
break; \
\
case OPT_BARE: \
(STYLE)->format = TF_LIST; \
(STYLE)->cell_format = CF_BARE; \
(STYLE)->headings = false; \
break; break;
void table_parse_format(struct table_style *, const char *format); void table_parse_format(struct table_style *, const char *format);

View File

@@ -3,8 +3,10 @@
Sets the type of table formatting. The following types of Sets the type of table formatting. The following types of
\fIformat\fR are available: \fIformat\fR are available:
.RS .RS
.IP "\fBtable\fR (default)" .IP "\fBtable\fR"
Text-based tables with aligned columns. 2-D text tables with aligned columns.
.IP "\fBlist\fR"
A list with one column per line and rows separated by a blank line.
.IP "\fBhtml\fR" .IP "\fBhtml\fR"
HTML tables. HTML tables.
.IP "\fBcvs\fR" .IP "\fBcvs\fR"
@@ -37,6 +39,11 @@ types of \fIformat\fR are available:
.RS .RS
.IP "\fBstring\fR (default)" .IP "\fBstring\fR (default)"
The simple format described in \fBovs\-vsctl\fR(8). The simple format described in \fBovs\-vsctl\fR(8).
.IP "\fBbare\fR"
The simple format with punctuation stripped off: \fB[]\fR and \fB{}\fR
are omitted around sets, maps, and empty columns, items within sets
and maps are space-separated, and strings are never quoted. This
format may be easier for scripts to parse.
.IP "\fBjson\fR" .IP "\fBjson\fR"
JSON. JSON.
.RE .RE
@@ -56,3 +63,5 @@ per line, with indentation.
.IP .IP
This option does not affect JSON in tables, which is always printed This option does not affect JSON in tables, which is always printed
compactly. compactly.
.IP "\fB\-\-bare\fR"
Equivalent to \fB\-\-format=list \-\-data=bare \-\-no\-headings\fR.

View File

@@ -127,6 +127,7 @@ contents of \fItable\fR.
Much of the output from \fBovsdb\-client\fR is in the form of tables. Much of the output from \fBovsdb\-client\fR is in the form of tables.
The following options controlling output formatting: The following options controlling output formatting:
. .
.ds TD (default)
.so lib/table.man .so lib/table.man
. .
.SS "Daemon Options" .SS "Daemon Options"

View File

@@ -80,7 +80,7 @@ parse_options(int argc, char *argv[])
DAEMON_LONG_OPTIONS, DAEMON_LONG_OPTIONS,
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
{"bootstrap-ca-cert", required_argument, 0, OPT_BOOTSTRAP_CA_CERT}, {"bootstrap-ca-cert", required_argument, 0, OPT_BOOTSTRAP_CA_CERT},
TABLE_LONG_OPTIONS TABLE_LONG_OPTIONS,
STREAM_SSL_LONG_OPTIONS STREAM_SSL_LONG_OPTIONS
#endif #endif
{0, 0, 0, 0}, {0, 0, 0, 0},