FD.io VPP  v21.06
Vector Packet Processing
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 "table.h"
26 
27 static table_text_attr_t default_title = {
29  .fg_color = TTAC_YELLOW,
30  .align = TTAA_CENTER,
31 };
32 
33 static table_text_attr_t default_body = {
34  .align = TTAA_RIGHT,
35 };
36 
37 static table_text_attr_t default_header_col = {
39  .fg_color = TTAC_YELLOW,
40  .align = TTAA_CENTER,
41 };
42 
43 static table_text_attr_t default_header_row = {
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;
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  s = format_text_cell (t, s, &title_cell, &default_title, table_width);
130  s = format (s, "\n");
131 
132  for (int c = 0; c < vec_len (t->cells); c++)
133  {
134  table_text_attr_t *col_default;
135 
136  if (c < t->n_header_cols)
137  col_default = &default_header_col;
138  else
139  col_default = &default_body;
140 
141  for (int r = 0; r < vec_len (t->cells[c]); r++)
142  {
143  table_text_attr_t *row_default = col_default;
144  if (r)
145  s = format (s, " ");
146  if (r < t->n_header_rows && c >= t->n_header_cols)
147  row_default = &default_header_row;
148  s = format_text_cell (t, s, &t->cells[c][r], row_default,
149  t->row_sizes[r]);
150  }
151  s = format (s, "\n");
152  }
153 
154  return s;
155 }
156 
157 void
159 {
160  va_list va;
161 
162  va_start (va, fmt);
163  t->title = va_format (t->title, fmt, &va);
164  va_end (va);
165 }
166 
167 static table_cell_t *
168 table_get_cell (table_t *t, int c, int r)
169 {
170  c += t->n_header_cols;
171  r += t->n_header_rows;
172 
173  /* grow table if needed */
174  vec_validate (t->cells, c);
175  for (int i = 0; i < vec_len (t->cells); i++)
176  vec_validate (t->cells[i], r);
177  return &t->cells[c][r];
178 }
179 
180 void
181 table_format_cell (table_t *t, int c, int r, char *fmt, ...)
182 {
183  table_cell_t *cell = table_get_cell (t, c, r);
184  va_list va;
185 
186  c += t->n_header_cols;
187  r += t->n_header_rows;
188 
189  va_start (va, fmt);
190  cell->text = va_format (t->cells[c][r].text, fmt, &va);
191  va_end (va);
192 
193  vec_validate (t->row_sizes, r);
194  t->row_sizes[r] = clib_max (t->row_sizes[r], vec_len (t->cells[c][r].text));
195 }
196 
197 void
199 {
200  table_cell_t *cell = table_get_cell (t, c, r);
201  cell->attr.align = a;
202 }
203 
204 void
206 {
207  table_cell_t *cell = table_get_cell (t, c, r);
208  cell->attr.fg_color = v;
209  cell->attr.flags |= TTAF_FG_COLOR_SET;
210 }
211 
212 void
214 {
215  table_cell_t *cell = table_get_cell (t, c, r);
216  cell->attr.bg_color = v;
217  cell->attr.flags |= TTAF_BG_COLOR_SET;
218 }
219 
220 void
222 {
223  for (int c = 0; c < vec_len (t->cells); c++)
224  {
225  for (int r = 0; r < vec_len (t->cells[c]); r++)
226  vec_free (t->cells[c][r].text);
227  vec_free (t->cells[c]);
228  }
229  vec_free (t->cells);
230  vec_free (t->row_sizes);
231  vec_free (t->title);
232  clib_memset (t, 0, sizeof (table_t));
233 }
234 
235 void
236 table_add_header_col (table_t *t, int n_strings, ...)
237 {
238  va_list arg;
239  int r, c = t->n_header_cols++;
240  int n_rows;
241 
242  vec_insert (t->cells, 1, c);
243  n_rows = clib_max (n_strings, 1);
244  n_rows = clib_max (vec_len (t->row_sizes), n_rows);
245  vec_validate (t->cells[c], n_rows - 1);
246 
247  va_start (arg, n_strings);
248  for (r = 0; r < n_rows; r++)
249  {
250  if (n_strings-- > 0)
251  table_format_cell (t, -1, r - t->n_header_rows, "%s",
252  va_arg (arg, char *));
253  }
254  va_end (arg);
255 }
256 
257 void
258 table_add_header_row (table_t *t, int n_strings, ...)
259 {
260  va_list arg;
261  int c, r = t->n_header_rows++;
262 
263  vec_validate (t->cells, n_strings + t->n_header_cols - 1);
264 
265  va_start (arg, n_strings);
266  for (c = t->n_header_cols; c < vec_len (t->cells); c++)
267  {
268  vec_insert (t->cells[c + t->n_header_cols], 1, r);
269  if (n_strings-- > 0)
270  table_format_cell (t, c, -1, "%s", va_arg (arg, char *));
271  }
272  va_end (arg);
273 }
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
__clib_export u8 * va_format(u8 *s, const char *fmt, va_list *va)
Definition: format.c:391
a
Definition: bitmap.h:544
vnet_hw_if_output_node_runtime_t * r
void table_set_cell_bg_color(table_t *t, int c, int r, table_text_attr_color_t v)
Definition: table.c:213
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
void table_format_title(table_t *t, char *fmt,...)
Definition: table.c:158
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
void table_set_cell_align(table_t *t, int c, int r, table_text_attr_align_t a)
Definition: table.c:198
unsigned char u8
Definition: types.h:56
#define clib_memcpy(d, s, n)
Definition: string.h:197
static table_text_attr_t default_body
Definition: table.c:33
void table_set_cell_fg_color(table_t *t, int c, int r, table_text_attr_color_t v)
Definition: table.c:205
table_text_attr_t attr
Definition: table.h:69
description fragment has unexpected format
Definition: map.api:433
table_text_attr_flags_t flags
Definition: table.h:61
#define vec_insert(V, N, M)
Insert N vector elements starting at element M, initialize new elements to zero (no header...
Definition: vec.h:776
int n_header_rows
Definition: table.h:80
u32 size
Definition: vhost_user.h:125
table_cell_t ** cells
Definition: table.h:77
u8 no_ansi
Definition: table.h:75
table_text_attr_color_t fg_color
Definition: table.h:62
int * row_sizes
Definition: table.h:78
static table_text_attr_t default_header_col
Definition: table.c:37
int cJSON_bool fmt
Definition: cJSON.h:160
table_text_attr_color_t bg_color
Definition: table.h:63
table_text_attr_color_t
Definition: table.h:39
void table_free(table_t *t)
Definition: table.c:221
svmdb_client_t * c
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
Definition: table.h:73
table_text_attr_align_t
Definition: table.h:51
u8 * title
Definition: table.h:76
static table_text_attr_t default_header_row
Definition: table.c:43
table_text_attr_align_t align
Definition: table.h:64
#define clib_max(x, y)
Definition: clib.h:335
int n_header_cols
Definition: table.h:79
void table_add_header_col(table_t *t, int n_strings,...)
Definition: table.c:236
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void table_format_cell(table_t *t, int c, int r, char *fmt,...)
Definition: table.c:181
u8 * text
Definition: table.h:70
u8 * format_table(u8 *s, va_list *args)
Definition: table.c:121
u8 * format_text_cell(table_t *t, u8 *s, table_cell_t *c, table_text_attr_t *def, int size)
Definition: table.c:50
static table_cell_t * table_get_cell(table_t *t, int c, int r)
Definition: table.c:168
void table_add_header_row(table_t *t, int n_strings,...)
Definition: table.c:258
Definition: table.h:31