FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
format_table.c
Go to the documentation of this file.
1 /*
2  Copyright (c) 2020 Damjan Marion
3 
4  Permission is hereby granted, free of charge, to any person obtaining
5  a copy of this software and associated documentation files (the
6  "Software"), to deal in the Software without restriction, including
7  without limitation the rights to use, copy, modify, merge, publish,
8  distribute, sublicense, and/or sell copies of the Software, and to
9  permit persons to whom the Software is furnished to do so, subject to
10  the following conditions:
11 
12  The above copyright notice and this permission notice shall be
13  included in all copies or substantial portions of the Software.
14 
15  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 
24 #include <vppinfra/format.h>
25 #include <vppinfra/format_table.h>
26 
29  .fg_color = TTAC_YELLOW,
30  .align = TTAA_CENTER,
31 };
32 
34  .align = TTAA_RIGHT,
35 };
36 
39  .fg_color = TTAC_YELLOW,
40  .align = TTAA_CENTER,
41 };
42 
45  .fg_color = TTAC_GREEN,
46  .align = TTAA_LEFT,
47 };
48 
49 u8 *
51  int size)
52 {
53  table_text_attr_t _a = {}, *a = &_a;
54 
55  if (a == 0)
56  return format (s, t->no_ansi ? "" : "\x1b[0m");
57 
58  clib_memcpy (a, def, sizeof (table_text_attr_t));
59 
60  if (t->no_ansi == 0)
61  {
62  int *codes = 0;
63  if (c->attr.flags & TTAF_FG_COLOR_SET)
64  {
65  a->fg_color = c->attr.fg_color;
66  a->flags |= TTAF_FG_COLOR_SET;
67  }
68 
69  if (c->attr.flags & TTAF_BG_COLOR_SET)
70  {
71  a->bg_color = c->attr.bg_color;
72  a->flags |= TTAF_BG_COLOR_SET;
73  }
74 
75  if (a->flags & TTAF_RESET)
76  vec_add1 (codes, 0);
77 
78  if (a->flags & TTAF_BOLD)
79  vec_add1 (codes, 1);
80 
81  if (a->flags & TTAF_DIM)
82  vec_add1 (codes, 2);
83 
84  if (a->flags & TTAF_UNDERLINE)
85  vec_add1 (codes, 4);
86 
87  if (a->flags & TTAF_FG_COLOR_SET)
88  vec_add1 (codes,
89  (a->flags & TTAF_FG_COLOR_BRIGHT ? 90 : 30) + a->fg_color);
90 
91  if (a->flags & TTAF_BG_COLOR_SET)
92  vec_add1 (codes,
93  (a->flags & TTAF_BG_COLOR_BRIGHT ? 100 : 40) + a->bg_color);
94 
95  if (codes)
96  {
97  s = format (s, "\x1b[");
98  for (int i = 0; i < vec_len (codes); i++)
99  s = format (s, "%s%u", i ? ";" : "", codes[i]);
100  s = format (s, "m");
101  vec_free (codes);
102  }
103  }
104 
105  u8 *fmt = 0;
106  table_text_attr_align_t align = c->attr.align;
107  if (align == TTAA_DEFAULT)
108  align = a->align;
109  if (align == TTAA_LEFT)
110  fmt = format (fmt, "%%-%uv%c", size, 0);
111  else if (align == TTAA_CENTER)
112  fmt = format (fmt, "%%=%uv%c", size, 0);
113  else
114  fmt = format (fmt, "%%%uv%c", size, 0);
115  s = format (s, (char *) fmt, c->text);
116  vec_free (fmt);
117  return format (s, t->no_ansi ? "" : "\x1b[0m");
118 }
119 
120 u8 *
121 format_table (u8 *s, va_list *args)
122 {
123  table_t *t = va_arg (*args, table_t *);
124  table_cell_t title_cell = { .text = t->title };
125  int table_width = 0;
126  for (int i = 0; i < vec_len (t->row_sizes); i++)
127  table_width += t->row_sizes[i];
128 
129  if (t->title)
130  {
131  table_text_attr_t *title_default;
132  title_default =
134  s = format_text_cell (t, s, &title_cell, title_default, table_width);
135  s = format (s, "\n");
136  }
137 
138  for (int c = 0; c < vec_len (t->cells); c++)
139  {
140  table_text_attr_t *col_default;
141 
142  if (c < t->n_header_cols)
143  col_default = t->default_header_col.as_u32 ? &t->default_header_col :
145  else
146  col_default =
148 
149  for (int r = 0; r < vec_len (t->cells[c]); r++)
150  {
151  table_text_attr_t *row_default = col_default;
152  if (r)
153  s = format (s, " ");
154  if (r < t->n_header_rows && c >= t->n_header_cols)
155  row_default = t->default_header_row.as_u32 ?
156  &t->default_header_row :
158  s = format_text_cell (t, s, &t->cells[c][r], row_default,
159  t->row_sizes[r]);
160  }
161  if (c + 1 < vec_len (t->cells))
162  s = format (s, "\n");
163  }
164 
165  return s;
166 }
167 
168 void
170 {
171  va_list va;
172 
173  va_start (va, fmt);
174  t->title = va_format (t->title, fmt, &va);
175  va_end (va);
176 }
177 
178 static table_cell_t *
179 table_get_cell (table_t *t, int c, int r)
180 {
181  c += t->n_header_cols;
182  r += t->n_header_rows;
183 
184  /* grow table if needed */
185  vec_validate (t->cells, c);
186  for (int i = 0; i < vec_len (t->cells); i++)
187  vec_validate (t->cells[i], r);
188  return &t->cells[c][r];
189 }
190 
191 void
192 table_format_cell (table_t *t, int c, int r, char *fmt, ...)
193 {
194  table_cell_t *cell = table_get_cell (t, c, r);
195  va_list va;
196 
197  c += t->n_header_cols;
198  r += t->n_header_rows;
199 
200  va_start (va, fmt);
201  cell->text = va_format (t->cells[c][r].text, fmt, &va);
202  va_end (va);
203 
204  vec_validate (t->row_sizes, r);
205  t->row_sizes[r] = clib_max (t->row_sizes[r], vec_len (t->cells[c][r].text));
206 }
207 
208 void
210 {
211  table_cell_t *cell = table_get_cell (t, c, r);
212  cell->attr.align = a;
213 }
214 
215 void
217 {
218  table_cell_t *cell = table_get_cell (t, c, r);
219  cell->attr.fg_color = v;
220  cell->attr.flags |= TTAF_FG_COLOR_SET;
221 }
222 
223 void
225 {
226  table_cell_t *cell = table_get_cell (t, c, r);
227  cell->attr.bg_color = v;
228  cell->attr.flags |= TTAF_BG_COLOR_SET;
229 }
230 
231 void
233 {
234  for (int c = 0; c < vec_len (t->cells); c++)
235  {
236  for (int r = 0; r < vec_len (t->cells[c]); r++)
237  vec_free (t->cells[c][r].text);
238  vec_free (t->cells[c]);
239  }
240  vec_free (t->cells);
241  vec_free (t->row_sizes);
242  vec_free (t->title);
243  clib_memset (t, 0, sizeof (table_t));
244 }
245 
246 void
247 table_add_header_col (table_t *t, int n_strings, ...)
248 {
249  va_list arg;
250  int r, c = t->n_header_cols++;
251  int n_rows;
252 
253  vec_insert (t->cells, 1, c);
254  n_rows = clib_max (n_strings, 1);
255  n_rows = clib_max (vec_len (t->row_sizes), n_rows);
256  vec_validate (t->cells[c], n_rows - 1);
257 
258  va_start (arg, n_strings);
259  for (r = 0; r < n_rows; r++)
260  {
261  if (n_strings-- > 0)
262  table_format_cell (t, -1, r - t->n_header_rows, "%s",
263  va_arg (arg, char *));
264  }
265  va_end (arg);
266 }
267 
268 void
269 table_add_header_row (table_t *t, int n_strings, ...)
270 {
271  va_list arg;
272  int c, r = t->n_header_rows++;
273 
274  vec_validate (t->cells, n_strings + t->n_header_cols - 1);
275 
276  va_start (arg, n_strings);
277  for (c = t->n_header_cols; c < vec_len (t->cells); c++)
278  {
279  vec_insert (t->cells[c + t->n_header_cols], 1, r);
280  if (n_strings-- > 0)
281  table_format_cell (t, c, -1, "%s", va_arg (arg, char *));
282  }
283  va_end (arg);
284 }
TTAF_FG_COLOR_BRIGHT
@ TTAF_FG_COLOR_BRIGHT
Definition: format_table.h:35
TTAF_UNDERLINE
@ TTAF_UNDERLINE
Definition: format_table.h:32
default_header_col
static table_text_attr_t default_header_col
Definition: format_table.c:37
table_add_header_row
void table_add_header_row(table_t *t, int n_strings,...)
Definition: format_table.c:269
table_free
void table_free(table_t *t)
Definition: format_table.c:232
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
clib_max
#define clib_max(x, y)
Definition: clib.h:335
format_table.h
table_text_attr_t::align
table_text_attr_align_t align
Definition: format_table.h:68
table_t::no_ansi
u8 no_ansi
Definition: format_table.h:82
table_text_attr_t::fg_color
table_text_attr_color_t fg_color
Definition: format_table.h:66
va_format
__clib_export u8 * va_format(u8 *s, const char *fmt, va_list *va)
Definition: format.c:391
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1089
table_text_attr_align_t
table_text_attr_align_t
Definition: format_table.h:51
table_t::title
u8 * title
Definition: format_table.h:83
TTAF_DIM
@ TTAF_DIM
Definition: format_table.h:31
format_table
u8 * format_table(u8 *s, va_list *args)
Definition: format_table.c:121
TTAC_YELLOW
@ TTAC_YELLOW
Definition: format_table.h:44
table_t::default_header_col
table_text_attr_t default_header_col
Definition: format_table.h:91
TTAF_FG_COLOR_SET
@ TTAF_FG_COLOR_SET
Definition: format_table.h:33
TTAF_BOLD
@ TTAF_BOLD
Definition: format_table.h:30
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
TTAA_CENTER
@ TTAA_CENTER
Definition: format_table.h:56
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
table_set_cell_fg_color
void table_set_cell_fg_color(table_t *t, int c, int r, table_text_attr_color_t v)
Definition: format_table.c:216
default_header_row
static table_text_attr_t default_header_row
Definition: format_table.c:43
table_t::n_header_rows
int n_header_rows
Definition: format_table.h:87
table_cell_t::attr
table_text_attr_t attr
Definition: format_table.h:76
table_get_cell
static table_cell_t * table_get_cell(table_t *t, int c, int r)
Definition: format_table.c:179
TTAF_RESET
@ TTAF_RESET
Definition: format_table.h:29
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
table_set_cell_align
void table_set_cell_align(table_t *t, int c, int r, table_text_attr_align_t a)
Definition: format_table.c:209
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
table_t::default_title
table_text_attr_t default_title
Definition: format_table.h:89
table_text_attr_color_t
table_text_attr_color_t
Definition: format_table.h:39
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
TTAA_LEFT
@ TTAA_LEFT
Definition: format_table.h:54
format.h
table_cell_t::text
u8 * text
Definition: format_table.h:77
fmt
int cJSON_bool fmt
Definition: cJSON.h:160
format_text_cell
u8 * format_text_cell(table_t *t, u8 *s, table_cell_t *c, table_text_attr_t *def, int size)
Definition: format_table.c:50
TTAA_RIGHT
@ TTAA_RIGHT
Definition: format_table.h:55
TTAF_BG_COLOR_BRIGHT
@ TTAF_BG_COLOR_BRIGHT
Definition: format_table.h:36
table_format_cell
void table_format_cell(table_t *t, int c, int r, char *fmt,...)
Definition: format_table.c:192
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
table_t::default_header_row
table_text_attr_t default_header_row
Definition: format_table.h:92
size
u32 size
Definition: vhost_user.h:125
table_t::n_header_cols
int n_header_cols
Definition: format_table.h:86
table_t
Definition: format_table.h:80
TTAC_GREEN
@ TTAC_GREEN
Definition: format_table.h:43
format
description fragment has unexpected format
Definition: map.api:433
table_cell_t
Definition: format_table.h:74
TTAF_BG_COLOR_SET
@ TTAF_BG_COLOR_SET
Definition: format_table.h:34
TTAA_DEFAULT
@ TTAA_DEFAULT
Definition: format_table.h:53
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u8
unsigned char u8
Definition: types.h:56
a
a
Definition: bitmap.h:525
table_format_title
void table_format_title(table_t *t, char *fmt,...)
Definition: format_table.c:169
table_t::row_sizes
int * row_sizes
Definition: format_table.h:85
svmdb_client_t::flags
int flags
Definition: svmdb.h:67
table_text_attr_t::as_u32
u32 as_u32
Definition: format_table.h:70
i
int i
Definition: flowhash_template.h:376
default_title
static table_text_attr_t default_title
Definition: format_table.c:27
table_text_attr_t::bg_color
table_text_attr_color_t bg_color
Definition: format_table.h:67
table_set_cell_bg_color
void table_set_cell_bg_color(table_t *t, int c, int r, table_text_attr_color_t v)
Definition: format_table.c:224
table_t::default_body
table_text_attr_t default_body
Definition: format_table.h:90
table_t::cells
table_cell_t ** cells
Definition: format_table.h:84
table_add_header_col
void table_add_header_col(table_t *t, int n_strings,...)
Definition: format_table.c:247
table_text_attr_t::flags
table_text_attr_flags_t flags
Definition: format_table.h:65
default_body
static table_text_attr_t default_body
Definition: format_table.c:33
table_text_attr_t
Definition: format_table.h:59
vec_insert
#define vec_insert(V, N, M)
Insert N vector elements starting at element M, initialize new elements to zero (no header,...
Definition: vec.h:775