FD.io VPP  v21.06-3-gbb25fbf28
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 
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  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 }
default_title
static table_text_attr_t default_title
Definition: table.c:27
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
clib_max
#define clib_max(x, y)
Definition: clib.h:335
TTAA_RIGHT
@ TTAA_RIGHT
Definition: table.h:55
TTAA_LEFT
@ TTAA_LEFT
Definition: table.h:54
table_text_attr_t::align
table_text_attr_align_t align
Definition: table.h:64
table_t::no_ansi
u8 no_ansi
Definition: table.h:75
table_text_attr_t::fg_color
table_text_attr_color_t fg_color
Definition: table.h:62
TTAF_RESET
@ TTAF_RESET
Definition: table.h:29
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:1071
table_t::title
u8 * title
Definition: table.h:76
TTAF_FG_COLOR_SET
@ TTAF_FG_COLOR_SET
Definition: table.h:33
TTAF_DIM
@ TTAF_DIM
Definition: table.h:31
default_header_row
static table_text_attr_t default_header_row
Definition: table.c:43
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
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: table.c:205
TTAC_GREEN
@ TTAC_GREEN
Definition: table.h:43
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
table_t::n_header_rows
int n_header_rows
Definition: table.h:80
table_cell_t::attr
table_text_attr_t attr
Definition: table.h:69
TTAF_FG_COLOR_BRIGHT
@ TTAF_FG_COLOR_BRIGHT
Definition: table.h:35
table_add_header_col
void table_add_header_col(table_t *t, int n_strings,...)
Definition: table.c:236
table_text_attr_color_t
table_text_attr_color_t
Definition: table.h:39
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
TTAF_BG_COLOR_BRIGHT
@ TTAF_BG_COLOR_BRIGHT
Definition: table.h:36
TTAC_YELLOW
@ TTAC_YELLOW
Definition: table.h:44
TTAF_BOLD
@ TTAF_BOLD
Definition: table.h:30
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
table_get_cell
static table_cell_t * table_get_cell(table_t *t, int c, int r)
Definition: table.c:168
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
format.h
TTAF_BG_COLOR_SET
@ TTAF_BG_COLOR_SET
Definition: table.h:34
default_body
static table_text_attr_t default_body
Definition: table.c:33
table_cell_t::text
u8 * text
Definition: table.h:70
fmt
int cJSON_bool fmt
Definition: cJSON.h:160
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: table.c:213
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
size
u32 size
Definition: vhost_user.h:125
table_t::n_header_cols
int n_header_cols
Definition: table.h:79
table_free
void table_free(table_t *t)
Definition: table.c:221
default_header_col
static table_text_attr_t default_header_col
Definition: table.c:37
table_t
Definition: table.h:73
format
description fragment has unexpected format
Definition: map.api:433
table_cell_t
Definition: table.h:67
table_format_title
void table_format_title(table_t *t, char *fmt,...)
Definition: table.c:158
TTAA_DEFAULT
@ TTAA_DEFAULT
Definition: table.h:53
table_format_cell
void table_format_cell(table_t *t, int c, int r, char *fmt,...)
Definition: table.c:181
TTAA_CENTER
@ TTAA_CENTER
Definition: table.h:56
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:544
table_t::row_sizes
int * row_sizes
Definition: table.h:78
svmdb_client_t::flags
int flags
Definition: svmdb.h:67
format_text_cell
u8 * format_text_cell(table_t *t, u8 *s, table_cell_t *c, table_text_attr_t *def, int size)
Definition: table.c:50
table_text_attr_t::bg_color
table_text_attr_color_t bg_color
Definition: table.h:63
table_add_header_row
void table_add_header_row(table_t *t, int n_strings,...)
Definition: table.c:258
table_set_cell_align
void table_set_cell_align(table_t *t, int c, int r, table_text_attr_align_t a)
Definition: table.c:198
table_t::cells
table_cell_t ** cells
Definition: table.h:77
table_text_attr_t::flags
table_text_attr_flags_t flags
Definition: table.h:61
TTAF_UNDERLINE
@ TTAF_UNDERLINE
Definition: table.h:32
table.h
table_text_attr_t
Definition: 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
format_table
u8 * format_table(u8 *s, va_list *args)
Definition: table.c:121
table_text_attr_align_t
table_text_attr_align_t
Definition: table.h:51