Skip to content

Commit c6a4125

Browse files
committed
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.
1 parent 3a3eb9d commit c6a4125

7 files changed

Lines changed: 110 additions & 11 deletions

File tree

lib/ovsdb-data.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2009, 2010 Nicira Networks
1+
/* Copyright (c) 2009, 2010, 2011 Nicira Networks
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* 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,
625625
}
626626
}
627627

628+
/* Appends 'atom' (which has the given 'type') to 'out', in a bare string
629+
* format that cannot be parsed uniformly back into a datum but is easier for
630+
* shell scripts, etc., to deal with. */
631+
void
632+
ovsdb_atom_to_bare(const union ovsdb_atom *atom, enum ovsdb_atomic_type type,
633+
struct ds *out)
634+
{
635+
if (type == OVSDB_TYPE_STRING) {
636+
ds_put_cstr(out, atom->string);
637+
} else {
638+
ovsdb_atom_to_string(atom, type, out);
639+
}
640+
}
641+
628642
static struct ovsdb_error *
629643
check_string_constraints(const char *s,
630644
const struct ovsdb_string_constraints *c)
@@ -1445,6 +1459,29 @@ ovsdb_datum_to_string(const struct ovsdb_datum *datum,
14451459
}
14461460
}
14471461

1462+
/* Appends to 'out' the 'datum' (with the given 'type') in a bare string format
1463+
* that cannot be parsed uniformly back into a datum but is easier for shell
1464+
* scripts, etc., to deal with. */
1465+
void
1466+
ovsdb_datum_to_bare(const struct ovsdb_datum *datum,
1467+
const struct ovsdb_type *type, struct ds *out)
1468+
{
1469+
bool is_map = ovsdb_type_is_map(type);
1470+
size_t i;
1471+
1472+
for (i = 0; i < datum->n; i++) {
1473+
if (i > 0) {
1474+
ds_put_cstr(out, " ");
1475+
}
1476+
1477+
ovsdb_atom_to_bare(&datum->keys[i], type->key.type, out);
1478+
if (is_map) {
1479+
ds_put_char(out, '=');
1480+
ovsdb_atom_to_bare(&datum->values[i], type->value.type, out);
1481+
}
1482+
}
1483+
}
1484+
14481485
/* Initializes 'datum' as a string-to-string map whose contents are taken from
14491486
* 'sh'. Destroys 'sh'. */
14501487
void

lib/ovsdb-data.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2009, 2010 Nicira Networks
1+
/* Copyright (c) 2009, 2010, 2011 Nicira Networks
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -94,6 +94,8 @@ char *ovsdb_atom_from_string(union ovsdb_atom *,
9494
WARN_UNUSED_RESULT;
9595
void ovsdb_atom_to_string(const union ovsdb_atom *, enum ovsdb_atomic_type,
9696
struct ds *);
97+
void ovsdb_atom_to_bare(const union ovsdb_atom *, enum ovsdb_atomic_type,
98+
struct ds *);
9799

98100
struct ovsdb_error *ovsdb_atom_check_constraints(
99101
const union ovsdb_atom *, const struct ovsdb_base_type *)
@@ -167,6 +169,8 @@ char *ovsdb_datum_from_string(struct ovsdb_datum *,
167169
WARN_UNUSED_RESULT;
168170
void ovsdb_datum_to_string(const struct ovsdb_datum *,
169171
const struct ovsdb_type *, struct ds *);
172+
void ovsdb_datum_to_bare(const struct ovsdb_datum *,
173+
const struct ovsdb_type *, struct ds *);
170174

171175
void ovsdb_datum_from_shash(struct ovsdb_datum *, struct shash *);
172176

lib/table.c

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ cell_to_text(struct cell *cell, const struct table_style *style)
3636
if (cell->json) {
3737
if (style->cell_format == CF_JSON || !cell->type) {
3838
cell->text = json_to_string(cell->json, JSSF_SORT);
39-
} else if (style->cell_format == CF_STRING) {
39+
} else {
4040
struct ovsdb_datum datum;
4141
struct ovsdb_error *error;
4242
struct ds s;
@@ -45,14 +45,16 @@ cell_to_text(struct cell *cell, const struct table_style *style)
4545
NULL);
4646
if (!error) {
4747
ds_init(&s);
48-
ovsdb_datum_to_string(&datum, cell->type, &s);
48+
if (style->cell_format == CF_STRING) {
49+
ovsdb_datum_to_string(&datum, cell->type, &s);
50+
} else {
51+
ovsdb_datum_to_bare(&datum, cell->type, &s);
52+
}
4953
ovsdb_datum_destroy(&datum, cell->type);
5054
cell->text = ds_steal_cstr(&s);
5155
} else {
5256
cell->text = json_to_string(cell->json, JSSF_SORT);
5357
}
54-
} else {
55-
NOT_REACHED();
5658
}
5759
} else {
5860
cell->text = xstrdup("");
@@ -272,6 +274,34 @@ table_print_table__(const struct table *table, const struct table_style *style)
272274
free(widths);
273275
}
274276

277+
static void
278+
table_print_list__(const struct table *table, const struct table_style *style)
279+
{
280+
static int n = 0;
281+
size_t x, y;
282+
283+
if (n++ > 0) {
284+
putchar('\n');
285+
}
286+
287+
if (table->caption) {
288+
puts(table->caption);
289+
}
290+
291+
for (y = 0; y < table->n_rows; y++) {
292+
if (y > 0) {
293+
putchar('\n');
294+
}
295+
for (x = 0; x < table->n_columns; x++) {
296+
const char *text = cell_to_text(table_cell__(table, y, x), style);
297+
if (style->headings) {
298+
printf("%-20s: ", table->columns[x].heading);
299+
}
300+
puts(text);
301+
}
302+
}
303+
}
304+
275305
static void
276306
table_escape_html_text__(const char *s, size_t n)
277307
{
@@ -469,6 +499,8 @@ table_parse_format(struct table_style *style, const char *format)
469499
{
470500
if (!strcmp(format, "table")) {
471501
style->format = TF_TABLE;
502+
} else if (!strcmp(format, "list")) {
503+
style->format = TF_LIST;
472504
} else if (!strcmp(format, "html")) {
473505
style->format = TF_HTML;
474506
} else if (!strcmp(format, "csv")) {
@@ -487,6 +519,8 @@ table_parse_cell_format(struct table_style *style, const char *format)
487519
{
488520
if (!strcmp(format, "string")) {
489521
style->cell_format = CF_STRING;
522+
} else if (!strcmp(format, "bare")) {
523+
style->cell_format = CF_BARE;
490524
} else if (!strcmp(format, "json")) {
491525
style->cell_format = CF_JSON;
492526
} else {
@@ -503,6 +537,10 @@ table_print(const struct table *table, const struct table_style *style)
503537
table_print_table__(table, style);
504538
break;
505539

540+
case TF_LIST:
541+
table_print_list__(table, style);
542+
break;
543+
506544
case TF_HTML:
507545
table_print_html__(table, style);
508546
break;

lib/table.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ struct cell *table_add_cell(struct table *);
5959

6060
enum table_format {
6161
TF_TABLE, /* 2-d table. */
62+
TF_LIST, /* One cell per line, one row per paragraph. */
6263
TF_HTML, /* HTML table. */
6364
TF_CSV, /* Comma-separated lines. */
6465
TF_JSON /* JSON. */
6566
};
6667

6768
enum cell_format {
6869
CF_STRING, /* String format. */
70+
CF_BARE, /* String format without most punctuation. */
6971
CF_JSON /* JSON. */
7072
};
7173

@@ -80,13 +82,15 @@ struct table_style {
8082

8183
#define TABLE_OPTION_ENUMS \
8284
OPT_NO_HEADINGS, \
83-
OPT_PRETTY
85+
OPT_PRETTY, \
86+
OPT_BARE
8487

8588
#define TABLE_LONG_OPTIONS \
8689
{"format", required_argument, 0, 'f'}, \
8790
{"data", required_argument, 0, 'd'}, \
8891
{"no-headings", no_argument, 0, OPT_NO_HEADINGS}, \
89-
{"pretty", no_argument, 0, OPT_PRETTY},
92+
{"pretty", no_argument, 0, OPT_PRETTY}, \
93+
{"bare", no_argument, 0, OPT_BARE}
9094

9195
#define TABLE_OPTION_HANDLERS(STYLE) \
9296
case 'f': \
@@ -103,6 +107,12 @@ struct table_style {
103107
\
104108
case OPT_PRETTY: \
105109
(STYLE)->json_flags |= JSSF_PRETTY; \
110+
break; \
111+
\
112+
case OPT_BARE: \
113+
(STYLE)->format = TF_LIST; \
114+
(STYLE)->cell_format = CF_BARE; \
115+
(STYLE)->headings = false; \
106116
break;
107117

108118
void table_parse_format(struct table_style *, const char *format);

lib/table.man

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
Sets the type of table formatting. The following types of
44
\fIformat\fR are available:
55
.RS
6-
.IP "\fBtable\fR (default)"
7-
Text-based tables with aligned columns.
6+
.IP "\fBtable\fR"
7+
2-D text tables with aligned columns.
8+
.IP "\fBlist\fR"
9+
A list with one column per line and rows separated by a blank line.
810
.IP "\fBhtml\fR"
911
HTML tables.
1012
.IP "\fBcvs\fR"
@@ -37,6 +39,11 @@ types of \fIformat\fR are available:
3739
.RS
3840
.IP "\fBstring\fR (default)"
3941
The simple format described in \fBovs\-vsctl\fR(8).
42+
.IP "\fBbare\fR"
43+
The simple format with punctuation stripped off: \fB[]\fR and \fB{}\fR
44+
are omitted around sets, maps, and empty columns, items within sets
45+
and maps are space-separated, and strings are never quoted. This
46+
format may be easier for scripts to parse.
4047
.IP "\fBjson\fR"
4148
JSON.
4249
.RE
@@ -56,3 +63,5 @@ per line, with indentation.
5663
.IP
5764
This option does not affect JSON in tables, which is always printed
5865
compactly.
66+
.IP "\fB\-\-bare\fR"
67+
Equivalent to \fB\-\-format=list \-\-data=bare \-\-no\-headings\fR.

ovsdb/ovsdb-client.1.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ contents of \fItable\fR.
127127
Much of the output from \fBovsdb\-client\fR is in the form of tables.
128128
The following options controlling output formatting:
129129
.
130+
.ds TD (default)
130131
.so lib/table.man
131132
.
132133
.SS "Daemon Options"

ovsdb/ovsdb-client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ parse_options(int argc, char *argv[])
8080
DAEMON_LONG_OPTIONS,
8181
#ifdef HAVE_OPENSSL
8282
{"bootstrap-ca-cert", required_argument, 0, OPT_BOOTSTRAP_CA_CERT},
83-
TABLE_LONG_OPTIONS
83+
TABLE_LONG_OPTIONS,
8484
STREAM_SSL_LONG_OPTIONS
8585
#endif
8686
{0, 0, 0, 0},

0 commit comments

Comments
 (0)