LCOV - code coverage report
Current view: top level - vppinfra - format_table.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 147 0.0 %
Date: 2023-10-26 01:39:38 Functions: 0 11 0.0 %

          Line data    Source code
       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             : 
      27             : static table_text_attr_t default_title = {
      28             :   .flags = TTAF_FG_COLOR_SET | TTAF_BOLD,
      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 = {
      38             :   .flags = TTAF_FG_COLOR_SET,
      39             :   .fg_color = TTAC_YELLOW,
      40             :   .align = TTAA_CENTER,
      41             : };
      42             : 
      43             : static table_text_attr_t default_header_row = {
      44             :   .flags = TTAF_FG_COLOR_SET | TTAF_BOLD,
      45             :   .fg_color = TTAC_GREEN,
      46             :   .align = TTAA_LEFT,
      47             : };
      48             : 
      49             : u8 *
      50           0 : format_text_cell (table_t *t, u8 *s, table_cell_t *c, table_text_attr_t *def,
      51             :                   int size)
      52             : {
      53           0 :   table_text_attr_t _a = {}, *a = &_a;
      54             : 
      55           0 :   if (c == 0)
      56           0 :     return format (s, t->no_ansi ? "" : "\x1b[0m");
      57             : 
      58           0 :   clib_memcpy (a, def, sizeof (table_text_attr_t));
      59             : 
      60           0 :   if (t->no_ansi == 0)
      61             :     {
      62           0 :       int *codes = 0;
      63           0 :       if (c->attr.flags & TTAF_FG_COLOR_SET)
      64             :         {
      65           0 :           a->fg_color = c->attr.fg_color;
      66           0 :           a->flags |= TTAF_FG_COLOR_SET;
      67           0 :           a->flags |= c->attr.flags & TTAF_FG_COLOR_BRIGHT;
      68             :         }
      69             : 
      70           0 :       if (c->attr.flags & TTAF_BG_COLOR_SET)
      71             :         {
      72           0 :           a->bg_color = c->attr.bg_color;
      73           0 :           a->flags |= TTAF_BG_COLOR_SET;
      74           0 :           a->flags |= c->attr.flags & TTAF_BG_COLOR_BRIGHT;
      75             :         }
      76             : 
      77           0 :       if (a->flags & TTAF_RESET)
      78           0 :         vec_add1 (codes, 0);
      79             : 
      80           0 :       if (a->flags & TTAF_BOLD)
      81           0 :         vec_add1 (codes, 1);
      82             : 
      83           0 :       if (a->flags & TTAF_DIM)
      84           0 :         vec_add1 (codes, 2);
      85             : 
      86           0 :       if (a->flags & TTAF_UNDERLINE)
      87           0 :         vec_add1 (codes, 4);
      88             : 
      89           0 :       if (a->flags & TTAF_FG_COLOR_SET)
      90           0 :         vec_add1 (codes,
      91             :                   (a->flags & TTAF_FG_COLOR_BRIGHT ? 90 : 30) + a->fg_color);
      92             : 
      93           0 :       if (a->flags & TTAF_BG_COLOR_SET)
      94           0 :         vec_add1 (codes,
      95             :                   (a->flags & TTAF_BG_COLOR_BRIGHT ? 100 : 40) + a->bg_color);
      96             : 
      97           0 :       if (codes)
      98             :         {
      99           0 :           s = format (s, "\x1b[");
     100           0 :           for (int i = 0; i < vec_len (codes); i++)
     101           0 :             s = format (s, "%s%u", i ? ";" : "", codes[i]);
     102           0 :           s = format (s, "m");
     103           0 :           vec_free (codes);
     104             :         }
     105             :     }
     106             : 
     107           0 :   u8 *fmt = 0;
     108           0 :   table_text_attr_align_t align = c->attr.align;
     109           0 :   if (align == TTAA_DEFAULT)
     110           0 :     align = a->align;
     111           0 :   if (align == TTAA_LEFT)
     112           0 :     fmt = format (fmt, "%%-%uv%c", size, 0);
     113           0 :   else if (align == TTAA_CENTER)
     114           0 :     fmt = format (fmt, "%%=%uv%c", size, 0);
     115             :   else
     116           0 :     fmt = format (fmt, "%%%uv%c", size, 0);
     117           0 :   s = format (s, (char *) fmt, c->text);
     118           0 :   vec_free (fmt);
     119           0 :   return format (s, t->no_ansi ? "" : "\x1b[0m");
     120             : }
     121             : 
     122             : u8 *
     123           0 : format_table (u8 *s, va_list *args)
     124             : {
     125           0 :   table_t *t = va_arg (*args, table_t *);
     126           0 :   table_cell_t title_cell = { .text = t->title };
     127           0 :   int table_width = 0;
     128           0 :   for (int i = 0; i < vec_len (t->row_sizes); i++)
     129           0 :     table_width += t->row_sizes[i];
     130             : 
     131           0 :   if (t->title)
     132             :     {
     133             :       table_text_attr_t *title_default;
     134           0 :       title_default =
     135           0 :         t->default_title.as_u32 ? &t->default_title : &default_title;
     136           0 :       s = format_text_cell (t, s, &title_cell, title_default, table_width);
     137           0 :       s = format (s, "\n");
     138             :     }
     139             : 
     140           0 :   for (int c = 0; c < vec_len (t->cells); c++)
     141             :     {
     142             :       table_text_attr_t *col_default;
     143             : 
     144           0 :       if (c < t->n_header_cols)
     145           0 :         col_default = t->default_header_col.as_u32 ? &t->default_header_col :
     146             :                                                      &default_header_col;
     147             :       else
     148           0 :         col_default =
     149           0 :           t->default_body.as_u32 ? &t->default_body : &default_body;
     150             : 
     151           0 :       for (int r = 0; r < vec_len (t->cells[c]); r++)
     152             :         {
     153           0 :           table_text_attr_t *row_default = col_default;
     154           0 :           if (r)
     155           0 :             s = format (s, " ");
     156           0 :           if (r < t->n_header_rows && c >= t->n_header_cols)
     157           0 :             row_default = t->default_header_row.as_u32 ?
     158           0 :                             &t->default_header_row :
     159             :                             &default_header_row;
     160           0 :           s = format_text_cell (t, s, &t->cells[c][r], row_default,
     161           0 :                                 t->row_sizes[r]);
     162             :         }
     163           0 :       if (c + 1 < vec_len (t->cells))
     164           0 :         s = format (s, "\n");
     165             :     }
     166             : 
     167           0 :   return s;
     168             : }
     169             : 
     170             : void
     171           0 : table_format_title (table_t *t, char *fmt, ...)
     172             : {
     173             :   va_list va;
     174             : 
     175           0 :   va_start (va, fmt);
     176           0 :   t->title = va_format (t->title, fmt, &va);
     177           0 :   va_end (va);
     178           0 : }
     179             : 
     180             : static table_cell_t *
     181           0 : table_get_cell (table_t *t, int c, int r)
     182             : {
     183           0 :   c += t->n_header_cols;
     184           0 :   r += t->n_header_rows;
     185             : 
     186             :   /* grow table if needed */
     187           0 :   vec_validate (t->cells, c);
     188           0 :   for (int i = 0; i < vec_len (t->cells); i++)
     189           0 :     vec_validate (t->cells[i], r);
     190           0 :   return &t->cells[c][r];
     191             : }
     192             : 
     193             : void
     194           0 : table_format_cell (table_t *t, int c, int r, char *fmt, ...)
     195             : {
     196           0 :   table_cell_t *cell = table_get_cell (t, c, r);
     197             :   va_list va;
     198             : 
     199           0 :   c += t->n_header_cols;
     200           0 :   r += t->n_header_rows;
     201             : 
     202           0 :   va_start (va, fmt);
     203           0 :   cell->text = va_format (t->cells[c][r].text, fmt, &va);
     204           0 :   va_end (va);
     205             : 
     206           0 :   vec_validate (t->row_sizes, r);
     207           0 :   t->row_sizes[r] = clib_max (t->row_sizes[r], vec_len (t->cells[c][r].text));
     208           0 : }
     209             : 
     210             : void
     211           0 : table_set_cell_align (table_t *t, int c, int r, table_text_attr_align_t a)
     212             : {
     213           0 :   table_cell_t *cell = table_get_cell (t, c, r);
     214           0 :   cell->attr.align = a;
     215           0 : }
     216             : 
     217             : void
     218           0 : table_set_cell_fg_color (table_t *t, int c, int r, table_text_attr_color_t v)
     219             : {
     220           0 :   table_cell_t *cell = table_get_cell (t, c, r);
     221           0 :   cell->attr.fg_color = v & 0x7;
     222           0 :   cell->attr.flags |= TTAF_FG_COLOR_SET;
     223           0 :   if (v & 8)
     224           0 :     cell->attr.flags |= TTAF_FG_COLOR_BRIGHT;
     225             :   else
     226           0 :     cell->attr.flags &= ~TTAF_FG_COLOR_BRIGHT;
     227           0 : }
     228             : 
     229             : void
     230           0 : table_set_cell_bg_color (table_t *t, int c, int r, table_text_attr_color_t v)
     231             : {
     232           0 :   table_cell_t *cell = table_get_cell (t, c, r);
     233           0 :   cell->attr.bg_color = v & 0x7;
     234           0 :   cell->attr.flags |= TTAF_BG_COLOR_SET;
     235           0 :   if (v & 8)
     236           0 :     cell->attr.flags |= TTAF_BG_COLOR_BRIGHT;
     237             :   else
     238           0 :     cell->attr.flags &= ~TTAF_BG_COLOR_BRIGHT;
     239           0 : }
     240             : 
     241             : void
     242           0 : table_free (table_t *t)
     243             : {
     244           0 :   for (int c = 0; c < vec_len (t->cells); c++)
     245             :     {
     246           0 :       for (int r = 0; r < vec_len (t->cells[c]); r++)
     247           0 :         vec_free (t->cells[c][r].text);
     248           0 :       vec_free (t->cells[c]);
     249             :     }
     250           0 :   vec_free (t->cells);
     251           0 :   vec_free (t->row_sizes);
     252           0 :   vec_free (t->title);
     253           0 :   clib_memset (t, 0, sizeof (table_t));
     254           0 : }
     255             : 
     256             : void
     257           0 : table_add_header_col (table_t *t, int n_strings, ...)
     258             : {
     259             :   va_list arg;
     260           0 :   int r, c = t->n_header_cols++;
     261             :   int n_rows;
     262             : 
     263           0 :   vec_insert (t->cells, 1, c);
     264           0 :   n_rows = clib_max (n_strings, 1);
     265           0 :   n_rows = clib_max (vec_len (t->row_sizes), n_rows);
     266           0 :   vec_validate (t->cells[c], n_rows - 1);
     267             : 
     268           0 :   va_start (arg, n_strings);
     269           0 :   for (r = 0; r < n_rows; r++)
     270             :     {
     271           0 :       if (n_strings-- > 0)
     272           0 :         table_format_cell (t, -1, r - t->n_header_rows, "%s",
     273             :                            va_arg (arg, char *));
     274             :     }
     275           0 :   va_end (arg);
     276           0 : }
     277             : 
     278             : void
     279           0 : table_add_header_row (table_t *t, int n_strings, ...)
     280             : {
     281             :   va_list arg;
     282           0 :   int c, r = t->n_header_rows++;
     283             : 
     284           0 :   vec_validate (t->cells, n_strings + t->n_header_cols - 1);
     285             : 
     286           0 :   va_start (arg, n_strings);
     287           0 :   for (c = t->n_header_cols; c < vec_len (t->cells); c++)
     288             :     {
     289           0 :       vec_insert (t->cells[c + t->n_header_cols], 1, r);
     290           0 :       if (n_strings-- > 0)
     291           0 :         table_format_cell (t, c, -1, "%s", va_arg (arg, char *));
     292             :     }
     293           0 :   va_end (arg);
     294           0 : }

Generated by: LCOV version 1.14