1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* ASCII table generator.
* Copyright (C) 2017 Cumulus Networks
* Quentin Young
*/
#ifndef _TERMTABLE_H_
#define _TERMTABLE_H_
#include <zebra.h>
#include "lib/json.h"
#ifdef __cplusplus
extern "C" {
#endif
enum ttable_align {
LEFT,
RIGHT,
TOP,
BOTTOM,
};
struct ttable_border {
char top;
char bottom;
char left;
char right;
bool top_on;
bool bottom_on;
bool left_on;
bool right_on;
};
/* cell style and cell */
struct ttable_cellstyle {
short lpad;
short rpad;
enum ttable_align align;
struct ttable_border border;
};
struct ttable_cell {
char *text;
struct ttable_cellstyle style;
};
/* table style and table */
struct ttable_style {
char corner; /* intersection */
int indent; /* left table indent */
bool rownums_on; /* show row numbers; unimplemented */
struct ttable_border border;
struct ttable_cellstyle cell;
};
struct ttable {
int nrows; /* number of rows */
int ncols; /* number of cols */
struct ttable_cell **table; /* table, row x col */
size_t size; /* size */
struct ttable_style style; /* style */
};
/* some predefined styles */
#define TTSTYLE_ASCII 0
#define TTSTYLE_BLANK 1
extern const struct ttable_style ttable_styles[2];
/**
* Creates a new table with the default style, which looks like this:
*
* +----------+----------+
* | column 1 | column 2 |
* +----------+----------+
* | data... | data!! |
* +----------+----------+
* | datums | 12345 |
* +----------+----------+
*
* @return the created table
*/
struct ttable *ttable_new(const struct ttable_style *tts);
/**
* Deletes a table and releases all associated resources.
*
* @param tt the table to destroy
*/
void ttable_del(struct ttable *tt);
/**
* Inserts a new row at the given index.
*
* The row contents are determined by a format string. The format string has
* the same form as a regular printf format string, except that columns are
* delimited by '|'. For example, to make the first column of the table above,
* the call is:
*
* ttable_insert_row(<tt>, <n>, "%s|%s", "column 1", "column 2");
*
* All features of printf format strings are permissible here.
*
* Caveats:
* - At present you cannot insert '|' into a cell's contents.
* - If there are N columns, '|' must appear n-1 times or the row will not be
* created
*
* @param tt table to insert row into
* @param row the row number (begins at 0)
* @param format column-separated format string
* @param ... arguments to format string
*
* @return pointer to the first cell in the created row, or NULL if not enough
* columns were specified
*/
struct ttable_cell *ttable_insert_row(struct ttable *tt, unsigned int row,
const char *format, ...) PRINTFRR(3, 4);
/**
* Inserts a new row at the end of the table.
*
* The row contents are determined by a format string. The format string has
* the same form as a regular printf format string, except that columns are
* delimited by '|'. For example, to make the first column of the table above,
* the call is:
*
* ttable_add_row(<tt>, "%s|%s", "column 1", "column 2");
*
* All features of printf format strings are permissible here.
*
* Caveats:
* - At present you cannot insert '|' into a cell's contents.
* - If there are N columns, '|' must appear n-1 times or the row will not be
* created
*
* @param tt table to insert row into
* @param format column-separated format string
* @param ... arguments to format string
*
* @return pointer to the first cell in the created row, or NULL if not enough
* columns were specified
*/
struct ttable_cell *ttable_add_row(struct ttable *tt, const char *format, ...)
PRINTFRR(2, 3);
/**
* Removes a row from the table.
*
* @param tt table to delete row from
* @param row the row number (begins at 0)
*/
void ttable_del_row(struct ttable *tt, unsigned int row);
/**
* Sets alignment for a range of cells.
*
* Available alignments are LEFT and RIGHT. Cell contents will be aligned
* accordingly, while respecting padding (if any). Suppose a cell has:
*
* lpad = 1
* rpad = 1
* align = RIGHT
* text = 'datums'
*
* The cell would look like:
*
* +-------------------+
* | datums |
* +-------------------+
*
* On the other hand:
*
* lpad = 1
* rpad = 10
* align = RIGHT
* text = 'datums'
*
* +-------------------+
* | datums |
* +-------------------+
*
* The default alignment is LEFT.
*
* @param tt the table to set alignment on
* @param srow starting row index
* @param scol starting column index
* @param nrow # rows to align
* @param ncol # cols to align
* @param align the alignment to set
*/
void ttable_align(struct ttable *tt, unsigned int srow, unsigned int scol,
unsigned int erow, unsigned int ecol,
enum ttable_align align);
/**
* Sets padding for a range of cells.
*
* Available padding options are LEFT and RIGHT (the alignment enum is reused).
* Both options may be set. Padding is treated as though it is stuck to the
* walls of the cell. Suppose a cell has:
*
* lpad = 4
* rpad = 2
* align = RIGHT
* text = 'datums'
*
* The cell padding, marked by '.', would look like:
*
* +--------------+
* | .datums. |
* +--------------+
*
* If the column is wider than the cell, the cell contents are aligned in an
* additional padded field according to the cell alignment.
*
* +--------------------+
* | Data!!!11!~~~~~:-) |
* +--------------------+
* | . datums. |
* +--------------------+
*
* @param tt the table to set padding on
* @param srow starting row index
* @param scol starting column index
* @param nrow # rows to pad
* @param ncol # cols to pad
* @param align LEFT or RIGHT
* @param pad # spaces to pad with
*/
void ttable_pad(struct ttable *tt, unsigned int srow, unsigned int scol,
unsigned int nrow, unsigned int ncol, enum ttable_align align,
short pad);
/**
* Restyle all cells according to table.cell.style.
*
* @param tt table to restyle
*/
void ttable_restyle(struct ttable *tt);
/**
* Turn left/right column separators on or off for specified column.
*
* @param tt table
* @param col column index
* @param align left or right separators
* @param on true/false for on/off
* @param sep character to use
*/
void ttable_colseps(struct ttable *tt, unsigned int col,
enum ttable_align align, bool on, char sep);
/**
* Turn bottom row separators on or off for specified row.
*
* @param tt table
* @param row row index
* @param align left or right separators
* @param on true/false for on/off
* @param sep character to use
*/
void ttable_rowseps(struct ttable *tt, unsigned int row,
enum ttable_align align, bool on, char sep);
/**
* Dumps a table to a heap-allocated string.
*
* Caller must free this string after use with
*
* XFREE (MTYPE_TMP, str);
*
* @param tt the table to dump
* @param newline the desired newline sequence to use, null terminated.
* @return table in text form
*/
char *ttable_dump(struct ttable *tt, const char *newline);
/**
* Convert a table to a JSON array of objects.
*
* Caller must free the returned json_object structure.
*
* @param tt the table to convert
* @param formats an array of characters indicating what JSON type should be
* used.
*/
json_object *ttable_json(struct ttable *tt, const char *const formats);
#ifdef __cplusplus
}
#endif
#endif /* _TERMTABLE_H */
|