LCOV - code coverage report
Current view: top level - gcc/text-art - tree-widget.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.9 % 98 93
Test Date: 2025-09-20 13:40:47 Functions: 81.8 % 11 9
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Tree diagrams.
       2                 :             :    Copyright (C) 2024-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it under
       8                 :             : the terms of the GNU General Public License as published by the Free
       9                 :             : Software Foundation; either version 3, or (at your option) any later
      10                 :             : version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :             : for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #define INCLUDE_VECTOR
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "pretty-print.h"
      26                 :             : #include "selftest.h"
      27                 :             : #include "text-art/selftests.h"
      28                 :             : #include "text-art/tree-widget.h"
      29                 :             : #include "text-art/dump-widget-info.h"
      30                 :             : 
      31                 :             : using namespace text_art;
      32                 :             : 
      33                 :             : /* class text_art::tree_widget : public text_art::widget.  */
      34                 :             : 
      35                 :             : static const int margin_width = 3;
      36                 :             : 
      37                 :             : std::unique_ptr<tree_widget>
      38                 :         120 : tree_widget::make (styled_string str, const theme &theme, style::id_t style_id)
      39                 :             : {
      40                 :         120 :   return std::make_unique <tree_widget>
      41                 :         240 :     (std::make_unique <text_widget> (std::move (str)),
      42                 :             :      theme,
      43                 :         120 :      style_id);
      44                 :             : }
      45                 :             : 
      46                 :             : std::unique_ptr<tree_widget>
      47                 :           0 : tree_widget::make (const dump_widget_info &dwi, pretty_printer *pp)
      48                 :             : {
      49                 :           0 :   return tree_widget::make (styled_string (dwi.m_sm, pp_formatted_text (pp)),
      50                 :             :                             dwi.m_theme,
      51                 :           0 :                             dwi.get_tree_style_id ());
      52                 :             : }
      53                 :             : 
      54                 :             : std::unique_ptr<tree_widget>
      55                 :           8 : tree_widget::make (const dump_widget_info &dwi, const char *str)
      56                 :             : {
      57                 :           8 :   return tree_widget::make (styled_string (dwi.m_sm, str),
      58                 :             :                             dwi.m_theme,
      59                 :           8 :                             dwi.get_tree_style_id ());
      60                 :             : }
      61                 :             : 
      62                 :             : std::unique_ptr<tree_widget>
      63                 :         112 : tree_widget::from_fmt (const dump_widget_info &dwi,
      64                 :             :                        printer_fn format_decoder,
      65                 :             :                        const char *fmt, ...)
      66                 :             : {
      67                 :         112 :   va_list ap;
      68                 :         112 :   va_start (ap, fmt);
      69                 :         112 :   styled_string styled_str
      70                 :         112 :     (styled_string::from_fmt_va (dwi.m_sm, format_decoder, fmt, &ap));
      71                 :         112 :   va_end (ap);
      72                 :         112 :   return make (std::move (styled_str), dwi.m_theme, dwi.get_tree_style_id ());
      73                 :         112 : }
      74                 :             : 
      75                 :             : const char *
      76                 :           0 : tree_widget::get_desc () const
      77                 :             : {
      78                 :           0 :   return "tree_widget";
      79                 :             : }
      80                 :             : 
      81                 :             : canvas::size_t
      82                 :         116 : tree_widget::calc_req_size ()
      83                 :             : {
      84                 :         116 :   canvas::size_t result (0, 0);
      85                 :         116 :   if (m_node)
      86                 :             :     {
      87                 :         116 :       canvas::size_t node_req_size = m_node->get_req_size ();
      88                 :         116 :       result.h += node_req_size.h;
      89                 :         116 :       result.w = std::max (result.w, node_req_size.w);
      90                 :             :     }
      91                 :         220 :   for (auto &child : m_children)
      92                 :             :     {
      93                 :         104 :       canvas::size_t child_req_size = child->get_req_size ();
      94                 :         104 :       result.h += child_req_size.h;
      95                 :         104 :       result.w = std::max (result.w, child_req_size.w + margin_width);
      96                 :             :     }
      97                 :         116 :   return result;
      98                 :             : }
      99                 :             : 
     100                 :             : void
     101                 :         116 : tree_widget::update_child_alloc_rects ()
     102                 :             : {
     103                 :         116 :   const int x = get_min_x ();
     104                 :         116 :   int y = get_min_y ();
     105                 :         116 :   if (m_node)
     106                 :             :     {
     107                 :         116 :       m_node->set_alloc_rect
     108                 :         116 :         (canvas::rect_t (canvas::coord_t (x, y),
     109                 :             :                          canvas::size_t (get_alloc_w (),
     110                 :         116 :                                          m_node->get_req_h ())));
     111                 :         116 :       y += m_node->get_req_h ();
     112                 :             :     }
     113                 :         220 :   for (auto &child : m_children)
     114                 :             :     {
     115                 :         104 :       child->set_alloc_rect
     116                 :         208 :         (canvas::rect_t (canvas::coord_t (x + margin_width, y),
     117                 :         104 :                          canvas::size_t (get_alloc_w () - margin_width,
     118                 :         104 :                                          child->get_req_h ())));
     119                 :         104 :       y += child->get_req_h ();
     120                 :             :     }
     121                 :         116 : }
     122                 :             : 
     123                 :             : void
     124                 :         116 : tree_widget::paint_to_canvas (canvas &canvas)
     125                 :             : {
     126                 :         116 :   if (m_node)
     127                 :         116 :     m_node->paint_to_canvas (canvas);
     128                 :         116 :   const int min_x = get_min_x ();
     129                 :         116 :   const canvas::cell_t cell_child_non_final
     130                 :         116 :     (m_theme.get_cell (theme::cell_kind::TREE_CHILD_NON_FINAL, m_style_id));
     131                 :         116 :   const canvas::cell_t cell_child_final
     132                 :         116 :     (m_theme.get_cell (theme::cell_kind::TREE_CHILD_FINAL, m_style_id));
     133                 :         116 :   const canvas::cell_t cell_x_connector
     134                 :         116 :     (m_theme.get_cell (theme::cell_kind::TREE_X_CONNECTOR, m_style_id));
     135                 :         116 :   const canvas::cell_t cell_y_connector
     136                 :         116 :     (m_theme.get_cell (theme::cell_kind::TREE_Y_CONNECTOR, m_style_id));
     137                 :         116 :   size_t idx = 0;
     138                 :         220 :   for (auto &child : m_children)
     139                 :             :     {
     140                 :         104 :       child->paint_to_canvas (canvas);
     141                 :             : 
     142                 :         104 :       const bool last_child = (++idx == m_children.size ());
     143                 :         104 :       canvas.paint (canvas::coord_t (min_x + 1, child->get_min_y ()),
     144                 :             :                     cell_x_connector);
     145                 :         208 :       canvas.paint (canvas::coord_t (min_x, child->get_min_y ()),
     146                 :             :                     last_child ? cell_child_final : cell_child_non_final);
     147                 :         104 :       if (!last_child)
     148                 :         112 :         for (int y = child->get_min_y () + 1; y <= child ->get_max_y (); y++)
     149                 :          48 :           canvas.paint (canvas::coord_t (min_x, y), cell_y_connector);
     150                 :             :     }
     151                 :         116 : }
     152                 :             : 
     153                 :             : #if CHECKING_P
     154                 :             : 
     155                 :             : namespace selftest {
     156                 :             : 
     157                 :             : static std::unique_ptr<tree_widget>
     158                 :           8 : make_test_tree_widget (const dump_widget_info &dwi)
     159                 :             : {
     160                 :           8 :   std::unique_ptr<tree_widget> w
     161                 :           8 :     (tree_widget::from_fmt (dwi, nullptr, "Root"));
     162                 :          32 :   for (int i = 0; i < 3; i++)
     163                 :             :     {
     164                 :          24 :       std::unique_ptr<tree_widget> c
     165                 :          24 :         (tree_widget::from_fmt (dwi, nullptr, "Child %i", i));
     166                 :          96 :       for (int j = 0; j < 3; j++)
     167                 :         144 :         c->add_child (tree_widget::from_fmt (dwi, nullptr,
     168                 :             :                                              "Grandchild %i %i", i, j));
     169                 :          48 :       w->add_child (std::move (c));
     170                 :          24 :     }
     171                 :           8 :   return w;
     172                 :             : }
     173                 :             : 
     174                 :             : static void
     175                 :           4 : test_tree_widget ()
     176                 :             : {
     177                 :           4 :   style_manager sm;
     178                 :             : 
     179                 :           4 :   style::id_t default_style_id (sm.get_or_create_id (style ()));
     180                 :             : 
     181                 :           4 :   {
     182                 :           4 :     ascii_theme theme;
     183                 :           4 :     dump_widget_info dwi (sm, theme, default_style_id);
     184                 :           4 :     canvas c (make_test_tree_widget (dwi)->to_canvas (sm));
     185                 :           4 :     ASSERT_CANVAS_STREQ
     186                 :             :       (c, false,
     187                 :             :        ("Root\n"
     188                 :             :         "+- Child 0\n"
     189                 :             :         "|  +- Grandchild 0 0\n"
     190                 :             :         "|  +- Grandchild 0 1\n"
     191                 :             :         "|  `- Grandchild 0 2\n"
     192                 :             :         "+- Child 1\n"
     193                 :             :         "|  +- Grandchild 1 0\n"
     194                 :             :         "|  +- Grandchild 1 1\n"
     195                 :             :         "|  `- Grandchild 1 2\n"
     196                 :             :         "`- Child 2\n"
     197                 :             :         "   +- Grandchild 2 0\n"
     198                 :             :         "   +- Grandchild 2 1\n"
     199                 :             :         "   `- Grandchild 2 2\n"));
     200                 :           4 :   }
     201                 :             : 
     202                 :           4 :   {
     203                 :           4 :     unicode_theme theme;
     204                 :           4 :     dump_widget_info dwi (sm, theme, default_style_id);
     205                 :           4 :     canvas c (make_test_tree_widget (dwi)->to_canvas (sm));
     206                 :           4 :     ASSERT_CANVAS_STREQ
     207                 :             :       (c, false,
     208                 :             :        ("Root\n"
     209                 :             :         "├─ Child 0\n"
     210                 :             :         "│  ├─ Grandchild 0 0\n"
     211                 :             :         "│  ├─ Grandchild 0 1\n"
     212                 :             :         "│  ╰─ Grandchild 0 2\n"
     213                 :             :         "├─ Child 1\n"
     214                 :             :         "│  ├─ Grandchild 1 0\n"
     215                 :             :         "│  ├─ Grandchild 1 1\n"
     216                 :             :         "│  ╰─ Grandchild 1 2\n"
     217                 :             :         "╰─ Child 2\n"
     218                 :             :         "   ├─ Grandchild 2 0\n"
     219                 :             :         "   ├─ Grandchild 2 1\n"
     220                 :             :         "   ╰─ Grandchild 2 2\n"));
     221                 :           4 :   }
     222                 :           4 : }
     223                 :             : 
     224                 :             : /* Run all selftests in this file.  */
     225                 :             : 
     226                 :             : void
     227                 :           4 : text_art_tree_widget_cc_tests ()
     228                 :             : {
     229                 :           4 :   test_tree_widget ();
     230                 :           4 : }
     231                 :             : 
     232                 :             : } // namespace selftest
     233                 :             : 
     234                 :             : 
     235                 :             : #endif /* #if CHECKING_P */
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.