LCOV - code coverage report
Current view: top level - gcc/text-art - style.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.0 % 298 289
Test Date: 2024-12-21 13:15:12 Functions: 94.4 % 18 17
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Classes for styling text cells (color, URLs).
       2                 :             :    Copyright (C) 2023-2024 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_ALGORITHM
      23                 :             : #define INCLUDE_VECTOR
      24                 :             : #include "system.h"
      25                 :             : #include "coretypes.h"
      26                 :             : #include "make-unique.h"
      27                 :             : #include "pretty-print.h"
      28                 :             : #include "intl.h"
      29                 :             : #include "selftest.h"
      30                 :             : #include "text-art/selftests.h"
      31                 :             : #include "text-art/types.h"
      32                 :             : #include "color-macros.h"
      33                 :             : #include "diagnostic-color.h"
      34                 :             : 
      35                 :             : using namespace text_art;
      36                 :             : 
      37                 :             : /* class text_art::style.  */
      38                 :             : 
      39                 :             : style &
      40                 :          24 : style::set_style_url (const char *url)
      41                 :             : {
      42                 :          24 :   m_url.clear ();
      43                 :         672 :   while (*url)
      44                 :         648 :     m_url.push_back (*(url++));
      45                 :          24 :   return *this;
      46                 :             : }
      47                 :             : 
      48                 :             : /* class text_art::style::color.  */
      49                 :             : 
      50                 :             : bool
      51                 :       10218 : style::color::operator== (const style::color &other) const
      52                 :             : {
      53                 :       10218 :   if (m_kind != other.m_kind)
      54                 :             :     return false;
      55                 :        9250 :   switch (m_kind)
      56                 :             :     {
      57                 :           0 :     default:
      58                 :           0 :       gcc_unreachable ();
      59                 :        7900 :     case kind::NAMED:
      60                 :        7900 :       return (u.m_named.m_name == other.u.m_named.m_name
      61                 :        7900 :               && u.m_named.m_bright == other.u.m_named.m_bright);
      62                 :           8 :     case kind::BITS_8:
      63                 :           8 :       return u.m_8bit == other.u.m_8bit;
      64                 :        1342 :     case kind::BITS_24:
      65                 :        1342 :       return (u.m_24bit.r == other.u.m_24bit.r
      66                 :             :               && u.m_24bit.g == other.u.m_24bit.g
      67                 :        1342 :               && u.m_24bit.b == other.u.m_24bit.b);
      68                 :             :     }
      69                 :             : }
      70                 :             : 
      71                 :             : static void
      72                 :         516 : ensure_separator (pretty_printer *pp, bool &need_separator)
      73                 :             : {
      74                 :           0 :   if (need_separator)
      75                 :         112 :     pp_string (pp, COLOR_SEPARATOR);
      76                 :         516 :   need_separator = true;
      77                 :           0 : }
      78                 :             : 
      79                 :             : void
      80                 :        1056 : style::color::print_sgr (pretty_printer *pp,
      81                 :             :                          bool fg,
      82                 :             :                          bool &need_separator) const
      83                 :             : {
      84                 :        1056 :   switch (m_kind)
      85                 :             :     {
      86                 :           0 :     default:
      87                 :           0 :       gcc_unreachable ();
      88                 :         808 :     case kind::NAMED:
      89                 :         808 :       {
      90                 :         808 :         static const char * const fg_normal[] = {"", // reset, for DEFAULT
      91                 :             :                                                  COLOR_FG_BLACK,
      92                 :             :                                                  COLOR_FG_RED,
      93                 :             :                                                  COLOR_FG_GREEN,
      94                 :             :                                                  COLOR_FG_YELLOW,
      95                 :             :                                                  COLOR_FG_BLUE,
      96                 :             :                                                  COLOR_FG_MAGENTA,
      97                 :             :                                                  COLOR_FG_CYAN,
      98                 :             :                                                  COLOR_FG_WHITE};
      99                 :         808 :         static const char * const fg_bright[] = {"", // reset, for DEFAULT
     100                 :             :                                                  COLOR_FG_BRIGHT_BLACK,
     101                 :             :                                                  COLOR_FG_BRIGHT_RED,
     102                 :             :                                                  COLOR_FG_BRIGHT_GREEN,
     103                 :             :                                                  COLOR_FG_BRIGHT_YELLOW,
     104                 :             :                                                  COLOR_FG_BRIGHT_BLUE,
     105                 :             :                                                  COLOR_FG_BRIGHT_MAGENTA,
     106                 :             :                                                  COLOR_FG_BRIGHT_CYAN,
     107                 :             :                                                  COLOR_FG_BRIGHT_WHITE};
     108                 :         808 :         static const char * const bg_normal[] = {"", // reset, for DEFAULT
     109                 :             :                                                  COLOR_BG_BLACK,
     110                 :             :                                                  COLOR_BG_RED,
     111                 :             :                                                  COLOR_BG_GREEN,
     112                 :             :                                                  COLOR_BG_YELLOW,
     113                 :             :                                                  COLOR_BG_BLUE,
     114                 :             :                                                  COLOR_BG_MAGENTA,
     115                 :             :                                                  COLOR_BG_CYAN,
     116                 :             :                                                  COLOR_BG_WHITE};
     117                 :         808 :         static const char * const bg_bright[] = {"", // reset, for DEFAULT
     118                 :             :                                                  COLOR_BG_BRIGHT_BLACK,
     119                 :             :                                                  COLOR_BG_BRIGHT_RED,
     120                 :             :                                                  COLOR_BG_BRIGHT_GREEN,
     121                 :             :                                                  COLOR_BG_BRIGHT_YELLOW,
     122                 :             :                                                  COLOR_BG_BRIGHT_BLUE,
     123                 :             :                                                  COLOR_BG_BRIGHT_MAGENTA,
     124                 :             :                                                  COLOR_BG_BRIGHT_CYAN,
     125                 :             :                                                  COLOR_BG_BRIGHT_WHITE};
     126                 :         808 :         STATIC_ASSERT (ARRAY_SIZE (fg_normal) == ARRAY_SIZE (fg_bright));
     127                 :         808 :         STATIC_ASSERT (ARRAY_SIZE (fg_normal) == ARRAY_SIZE (bg_normal));
     128                 :         808 :         STATIC_ASSERT (ARRAY_SIZE (fg_normal) == ARRAY_SIZE (bg_bright));
     129                 :         808 :         gcc_assert ((size_t)u.m_named.m_name < ARRAY_SIZE (fg_normal));
     130                 :         808 :         const char *const *arr;
     131                 :         808 :         if (fg)
     132                 :         436 :           arr = u.m_named.m_bright ? fg_bright : fg_normal;
     133                 :             :         else
     134                 :         372 :           arr = u.m_named.m_bright ? bg_bright : bg_normal;
     135                 :         808 :         const char *str = arr[(size_t)u.m_named.m_name];
     136                 :         808 :         if (strlen (str) > 0)
     137                 :             :           {
     138                 :         236 :             ensure_separator (pp, need_separator);
     139                 :         236 :             pp_string (pp, str);
     140                 :             :           }
     141                 :             :       }
     142                 :             :       break;
     143                 :          48 :     case kind::BITS_8:
     144                 :          48 :       {
     145                 :          48 :         ensure_separator (pp, need_separator);
     146                 :          48 :         if (fg)
     147                 :          24 :           pp_string (pp, "38");
     148                 :             :         else
     149                 :          24 :           pp_string (pp, "48");
     150                 :          48 :         pp_printf (pp, ";5;%i", (int)u.m_8bit);
     151                 :             :       }
     152                 :          48 :       break;
     153                 :         200 :     case kind::BITS_24:
     154                 :         200 :       {
     155                 :         200 :         ensure_separator (pp, need_separator);
     156                 :         200 :         if (fg)
     157                 :          68 :           pp_string (pp, "38");
     158                 :             :         else
     159                 :         132 :           pp_string (pp, "48");
     160                 :         200 :         pp_printf (pp, ";2;%i;%i;%i",
     161                 :         200 :                    (int)u.m_24bit.r,
     162                 :         200 :                    (int)u.m_24bit.g,
     163                 :         200 :                    (int)u.m_24bit.b);
     164                 :             :       }
     165                 :         200 :       break;
     166                 :             :     }
     167                 :        1056 : }
     168                 :             : 
     169                 :             : /* class text_art::style.  */
     170                 :             : 
     171                 :             : /* See https://www.ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf
     172                 :             :    GRCM - GRAPHIC RENDITION COMBINATION MODE can be "REPLACING" or
     173                 :             :    "CUMULATIVE", which affects whether we need to respecify all attributes
     174                 :             :    at each SGR, or can accumulate them.  Looks like we can't rely on the value
     175                 :             :    of this, so we have to emit a single SGR for all changes, with a "0" reset
     176                 :             :    at the front, forcing it to be effectively replacing.  */
     177                 :             : 
     178                 :             : void
     179                 :        4958 : style::print_changes (pretty_printer *pp,
     180                 :             :                       const style &old_style,
     181                 :             :                       const style &new_style)
     182                 :             : {
     183                 :        4958 :   if (pp_show_color (pp))
     184                 :             :     {
     185                 :         568 :       bool needs_sgr = ((old_style.m_bold != new_style.m_bold)
     186                 :             :                         || (old_style.m_underscore != new_style.m_underscore)
     187                 :         568 :                         || (old_style.m_blink != new_style.m_blink)
     188                 :         504 :                         || (old_style.m_fg_color != new_style.m_fg_color)
     189                 :         832 :                         || (old_style.m_bg_color != new_style.m_bg_color));
     190                 :         528 :       if (needs_sgr)
     191                 :             :         {
     192                 :        1056 :           bool emit_reset = (old_style.m_bold
     193                 :         504 :                              || new_style.m_bold
     194                 :         480 :                              || old_style.m_underscore
     195                 :         476 :                              || new_style.m_underscore
     196                 :         472 :                              || old_style.m_blink
     197                 :         996 :                              || new_style.m_blink);
     198                 :         528 :           bool need_separator = false;
     199                 :             : 
     200                 :         528 :           pp_string (pp, SGR_START);
     201                 :         528 :           if (emit_reset)
     202                 :             :             {
     203                 :          64 :               pp_string (pp, COLOR_NONE);
     204                 :          64 :               need_separator = true;
     205                 :             :             }
     206                 :         528 :           if (new_style.m_bold)
     207                 :             :             {
     208                 :          24 :               gcc_assert (emit_reset);
     209                 :          24 :               ensure_separator (pp, need_separator);
     210                 :          24 :               pp_string (pp, COLOR_BOLD);
     211                 :             :             }
     212                 :         528 :           if (new_style.m_underscore)
     213                 :             :             {
     214                 :           4 :               gcc_assert (emit_reset);
     215                 :           4 :               ensure_separator (pp, need_separator);
     216                 :           4 :               pp_string (pp, COLOR_UNDERSCORE);
     217                 :             :             }
     218                 :         528 :           if (new_style.m_blink)
     219                 :             :             {
     220                 :           4 :               gcc_assert (emit_reset);
     221                 :           4 :               ensure_separator (pp, need_separator);
     222                 :           4 :               pp_string (pp, COLOR_BLINK);
     223                 :             :             }
     224                 :         528 :           new_style.m_fg_color.print_sgr (pp, true, need_separator);
     225                 :         528 :           new_style.m_bg_color.print_sgr (pp, false, need_separator);
     226                 :         528 :           pp_string (pp, SGR_END);
     227                 :             :         }
     228                 :             :     }
     229                 :             : 
     230                 :        4958 :   if (old_style.m_url != new_style.m_url)
     231                 :             :     {
     232                 :          48 :       if (!old_style.m_url.empty ())
     233                 :          24 :         pp_end_url (pp);
     234                 :          48 :       if (pp->supports_urls_p ()
     235                 :          48 :           && !new_style.m_url.empty ())
     236                 :             :         {
     237                 :             :           /* Adapted from pp_begin_url, but encoding the
     238                 :             :              chars to UTF-8 on the fly, rather than converting
     239                 :             :              to a buffer.  */
     240                 :          16 :           pp_string (pp, "\33]8;;");
     241                 :         448 :           for (auto ch : new_style.m_url)
     242                 :         432 :             pp_unicode_character (pp, ch);
     243                 :          16 :           switch (pp->get_url_format ())
     244                 :             :             {
     245                 :           0 :             default:
     246                 :           0 :             case URL_FORMAT_NONE:
     247                 :           0 :               gcc_unreachable ();
     248                 :           8 :             case URL_FORMAT_ST:
     249                 :           8 :               pp_string (pp, "\33\\");
     250                 :           8 :               break;
     251                 :           8 :             case URL_FORMAT_BEL:
     252                 :           8 :               pp_string (pp, "\a");
     253                 :           8 :               break;
     254                 :             :             }
     255                 :             :         }
     256                 :             :     }
     257                 :        4958 : }
     258                 :             : 
     259                 :             : /* Look up the current SGR codes for a color capability NAME
     260                 :             :    (from GCC_COLORS or the defaults), and convert them to
     261                 :             :    a text_art::style.  */
     262                 :             : 
     263                 :             : style
     264                 :         148 : text_art::get_style_from_color_cap_name (const char *name)
     265                 :             : {
     266                 :         148 :   const char *sgr_codes = colorize_start (true, name);
     267                 :         148 :   gcc_assert (sgr_codes);
     268                 :             : 
     269                 :             :   /* Parse the sgr codes.  We expect the resulting styled_string to be
     270                 :             :      empty; we're interested in the final style created during parsing.  */
     271                 :         148 :   style_manager sm;
     272                 :         148 :   styled_string styled_str (sm, sgr_codes);
     273                 :         148 :   return sm.get_style (sm.get_num_styles () - 1);
     274                 :         148 : }
     275                 :             : 
     276                 :             : /* class text_art::style_manager.  */
     277                 :             : 
     278                 :        9100 : style_manager::style_manager ()
     279                 :             : {
     280                 :             :   // index 0 will be the default style
     281                 :        9100 :   m_styles.push_back (style ());
     282                 :        9100 : }
     283                 :             : 
     284                 :             : style::id_t
     285                 :        2188 : style_manager::get_or_create_id (const style &s)
     286                 :             : {
     287                 :             :   // For now, linear search
     288                 :        2188 :   std::vector<style>::iterator existing
     289                 :        2188 :     (std::find (m_styles.begin (), m_styles.end (), s));
     290                 :             : 
     291                 :             :   /* If found, return index of slot.  */
     292                 :        2188 :   if (existing != m_styles.end ())
     293                 :        1381 :     return std::distance (m_styles.begin (), existing);
     294                 :             : 
     295                 :             :   /* Not found.  */
     296                 :             : 
     297                 :             :   /* styled_str uses 7 bits for style information, so we can only support
     298                 :             :      up to 128 different style combinations.
     299                 :             :      Gracefully fail by turning off styling when this limit is reached.  */
     300                 :         807 :   if (m_styles.size () >= 127)
     301                 :             :     return 0;
     302                 :             : 
     303                 :         807 :   m_styles.push_back (s);
     304                 :         807 :   return m_styles.size () - 1;
     305                 :             : }
     306                 :             : 
     307                 :             : void
     308                 :        6927 : style_manager::print_any_style_changes (pretty_printer *pp,
     309                 :             :                                         style::id_t old_id,
     310                 :             :                                         style::id_t new_id) const
     311                 :             : {
     312                 :        6927 :   gcc_assert (pp);
     313                 :        6927 :   if (old_id == new_id)
     314                 :             :     return;
     315                 :             : 
     316                 :        4734 :   const style &old_style = m_styles[old_id];
     317                 :        4734 :   const style &new_style = m_styles[new_id];
     318                 :        4734 :   gcc_assert (!(old_style == new_style));
     319                 :        4734 :   style::print_changes (pp, old_style, new_style);
     320                 :             : }
     321                 :             : 
     322                 :             : #if CHECKING_P
     323                 :             : 
     324                 :             : namespace selftest {
     325                 :             : 
     326                 :             : void
     327                 :         224 : assert_style_change_streq (const location &loc,
     328                 :             :                            const style &old_style,
     329                 :             :                            const style &new_style,
     330                 :             :                            const char *expected_str)
     331                 :             : {
     332                 :         224 :   pretty_printer pp;
     333                 :         224 :   pp_show_color (&pp) = true;
     334                 :         224 :   style::print_changes (&pp, old_style, new_style);
     335                 :         224 :   ASSERT_STREQ_AT (loc, pp_formatted_text (&pp), expected_str);
     336                 :         224 : }
     337                 :             : 
     338                 :             : #define ASSERT_STYLE_CHANGE_STREQ(OLD_STYLE, NEW_STYLE, EXPECTED_STR) \
     339                 :             :   SELFTEST_BEGIN_STMT                                                 \
     340                 :             :     assert_style_change_streq ((SELFTEST_LOCATION),                   \
     341                 :             :                                (OLD_STYLE),                           \
     342                 :             :                                (NEW_STYLE),                           \
     343                 :             :                                (EXPECTED_STR));                       \
     344                 :             :   SELFTEST_END_STMT
     345                 :             : 
     346                 :             : static void
     347                 :           4 : test_bold ()
     348                 :             : {
     349                 :           4 :   style_manager sm;
     350                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     351                 :             : 
     352                 :           4 :   style plain;
     353                 :           4 :   ASSERT_EQ (sm.get_or_create_id (plain), 0);
     354                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     355                 :             : 
     356                 :           4 :   style bold;
     357                 :           4 :   bold.m_bold = true;
     358                 :             : 
     359                 :           4 :   ASSERT_EQ (sm.get_or_create_id (bold), 1);
     360                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     361                 :           4 :   ASSERT_EQ (sm.get_or_create_id (bold), 1);
     362                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     363                 :             : 
     364                 :           4 :   ASSERT_STYLE_CHANGE_STREQ (plain, bold, "\33[00;01m\33[K");
     365                 :           4 :   ASSERT_STYLE_CHANGE_STREQ (bold, plain, "\33[00m\33[K");
     366                 :           4 : }
     367                 :             : 
     368                 :             : static void
     369                 :           4 : test_underscore ()
     370                 :             : {
     371                 :           4 :   style_manager sm;
     372                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     373                 :             : 
     374                 :           4 :   style plain;
     375                 :           4 :   ASSERT_EQ (sm.get_or_create_id (plain), 0);
     376                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     377                 :             : 
     378                 :           4 :   style underscore;
     379                 :           4 :   underscore.m_underscore = true;
     380                 :             : 
     381                 :           4 :   ASSERT_EQ (sm.get_or_create_id (underscore), 1);
     382                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     383                 :           4 :   ASSERT_EQ (sm.get_or_create_id (underscore), 1);
     384                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     385                 :             : 
     386                 :           4 :   ASSERT_STYLE_CHANGE_STREQ (plain, underscore, "\33[00;04m\33[K");
     387                 :           4 :   ASSERT_STYLE_CHANGE_STREQ (underscore, plain, "\33[00m\33[K");
     388                 :           4 : }
     389                 :             : 
     390                 :             : static void
     391                 :           4 : test_blink ()
     392                 :             : {
     393                 :           4 :   style_manager sm;
     394                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     395                 :             : 
     396                 :           4 :   style plain;
     397                 :           4 :   ASSERT_EQ (sm.get_or_create_id (plain), 0);
     398                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     399                 :             : 
     400                 :           4 :   style blink;
     401                 :           4 :   blink.m_blink = true;
     402                 :             : 
     403                 :           4 :   ASSERT_EQ (sm.get_or_create_id (blink), 1);
     404                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     405                 :           4 :   ASSERT_EQ (sm.get_or_create_id (blink), 1);
     406                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     407                 :             : 
     408                 :           4 :   ASSERT_STYLE_CHANGE_STREQ (plain, blink, "\33[00;05m\33[K");
     409                 :           4 :   ASSERT_STYLE_CHANGE_STREQ (blink, plain, "\33[00m\33[K");
     410                 :           4 : }
     411                 :             : 
     412                 :             : #define ASSERT_NAMED_COL_STREQ(NAMED_COLOR, FG, BRIGHT, EXPECTED_STR) \
     413                 :             :   SELFTEST_BEGIN_STMT                                                 \
     414                 :             :   {                                                                   \
     415                 :             :     style plain;                                                      \
     416                 :             :     style s;                                                          \
     417                 :             :     if (FG)                                                           \
     418                 :             :       s.m_fg_color = style::color ((NAMED_COLOR), (BRIGHT));          \
     419                 :             :     else                                                              \
     420                 :             :       s.m_bg_color = style::color ((NAMED_COLOR), (BRIGHT));          \
     421                 :             :     assert_style_change_streq ((SELFTEST_LOCATION),                   \
     422                 :             :                                plain,                                 \
     423                 :             :                                s,                                     \
     424                 :             :                                (EXPECTED_STR));                       \
     425                 :             :   }                                                                   \
     426                 :             :   SELFTEST_END_STMT
     427                 :             : 
     428                 :             : static void
     429                 :           4 : test_named_colors ()
     430                 :             : {
     431                 :             :   /* Foreground colors.  */
     432                 :           4 :   {
     433                 :           4 :     const bool fg = true;
     434                 :           4 :     {
     435                 :           4 :       const bool bright = false;
     436                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::DEFAULT, fg, bright, "");
     437                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLACK, fg, bright,
     438                 :             :                               "");
     439                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::RED, fg, bright,
     440                 :             :                               "");
     441                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::GREEN, fg, bright,
     442                 :             :                               "");
     443                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::YELLOW, fg, bright,
     444                 :             :                               "");
     445                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLUE, fg, bright,
     446                 :             :                               "");
     447                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::MAGENTA, fg, bright,
     448                 :             :                               "");
     449                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::CYAN, fg, bright,
     450                 :             :                               "");
     451                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::WHITE, fg, bright,
     452                 :             :                               "");
     453                 :             :     }
     454                 :           4 :     {
     455                 :           4 :       const bool bright = true;
     456                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::DEFAULT, fg, bright,
     457                 :             :                               "");
     458                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLACK, fg, bright,
     459                 :             :                               "");
     460                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::RED, fg, bright,
     461                 :             :                               "");
     462                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::GREEN, fg, bright,
     463                 :             :                               "");
     464                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::YELLOW, fg, bright,
     465                 :             :                               "");
     466                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLUE, fg, bright,
     467                 :             :                               "");
     468                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::MAGENTA, fg, bright,
     469                 :             :                               "");
     470                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::CYAN, fg, bright,
     471                 :             :                               "");
     472                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::WHITE, fg, bright,
     473                 :             :                               "");
     474                 :             :     }
     475                 :             :   }
     476                 :             : 
     477                 :             :   /* Background colors.  */
     478                 :           4 :   {
     479                 :           4 :     const bool fg = false;
     480                 :           4 :     {
     481                 :           4 :       const bool bright = false;
     482                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::DEFAULT, fg, bright, "");
     483                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLACK, fg, bright,
     484                 :             :                               "");
     485                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::RED, fg, bright,
     486                 :             :                               "");
     487                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::GREEN, fg, bright,
     488                 :             :                               "");
     489                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::YELLOW, fg, bright,
     490                 :             :                               "");
     491                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLUE, fg, bright,
     492                 :             :                               "");
     493                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::MAGENTA, fg, bright,
     494                 :             :                               "");
     495                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::CYAN, fg, bright,
     496                 :             :                               "");
     497                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::WHITE, fg, bright,
     498                 :             :                               "");
     499                 :             :     }
     500                 :           4 :     {
     501                 :           4 :       const bool bright = true;
     502                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::DEFAULT, fg, bright,
     503                 :             :                               "");
     504                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLACK, fg, bright,
     505                 :             :                               "");
     506                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::RED, fg, bright,
     507                 :             :                               "");
     508                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::GREEN, fg, bright,
     509                 :             :                               "");
     510                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::YELLOW, fg, bright,
     511                 :             :                               "");
     512                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::BLUE, fg, bright,
     513                 :             :                               "");
     514                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::MAGENTA, fg, bright,
     515                 :             :                               "");
     516                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::CYAN, fg, bright,
     517                 :             :                               "");
     518                 :           4 :       ASSERT_NAMED_COL_STREQ (style::named_color::WHITE, fg, bright,
     519                 :             :                               "");
     520                 :             :     }
     521                 :             :   }
     522                 :           4 : }
     523                 :             : 
     524                 :             : #define ASSERT_8_BIT_COL_STREQ(COL_VAL, FG, EXPECTED_STR) \
     525                 :             :   SELFTEST_BEGIN_STMT                                                 \
     526                 :             :   {                                                                   \
     527                 :             :     style plain;                                                      \
     528                 :             :     style s;                                                          \
     529                 :             :     if (FG)                                                           \
     530                 :             :       s.m_fg_color = style::color (COL_VAL);                          \
     531                 :             :     else                                                              \
     532                 :             :       s.m_bg_color = style::color (COL_VAL);                          \
     533                 :             :     assert_style_change_streq ((SELFTEST_LOCATION),                   \
     534                 :             :                                plain,                                 \
     535                 :             :                                s,                                     \
     536                 :             :                                (EXPECTED_STR));                       \
     537                 :             :   }                                                                   \
     538                 :             :   SELFTEST_END_STMT
     539                 :             : 
     540                 :             : static void
     541                 :           4 : test_8_bit_colors ()
     542                 :             : {
     543                 :             :   /* Foreground colors.  */
     544                 :           4 :   {
     545                 :           4 :     const bool fg = true;
     546                 :             :     /* 0-15: standard and high-intensity standard colors.  */
     547                 :           4 :     ASSERT_8_BIT_COL_STREQ (0, fg, "");
     548                 :           4 :     ASSERT_8_BIT_COL_STREQ (15, fg, "");
     549                 :             :     /* 16-231: 6x6x6 color cube.  */
     550                 :           4 :     ASSERT_8_BIT_COL_STREQ (16, fg, "");
     551                 :           4 :     ASSERT_8_BIT_COL_STREQ (231, fg, "");
     552                 :             :     /* 232-255: grayscale.  */
     553                 :           4 :     ASSERT_8_BIT_COL_STREQ (232, fg, "");
     554                 :           4 :     ASSERT_8_BIT_COL_STREQ (255, fg, "");
     555                 :             :   }
     556                 :             :   /* Background colors.  */
     557                 :           4 :   {
     558                 :           4 :     const bool fg = false;
     559                 :             :     /* 0-15: standard and high-intensity standard colors.  */
     560                 :           4 :     ASSERT_8_BIT_COL_STREQ (0, fg, "");
     561                 :           4 :     ASSERT_8_BIT_COL_STREQ (15, fg, "");
     562                 :             :     /* 16-231: 6x6x6 color cube.  */
     563                 :           4 :     ASSERT_8_BIT_COL_STREQ (16, fg, "");
     564                 :           4 :     ASSERT_8_BIT_COL_STREQ (231, fg, "");
     565                 :             :     /* 232-255: grayscale.  */
     566                 :           4 :     ASSERT_8_BIT_COL_STREQ (232, fg, "");
     567                 :           4 :     ASSERT_8_BIT_COL_STREQ (255, fg, "");
     568                 :             :   }
     569                 :           4 : }
     570                 :             : 
     571                 :             : #define ASSERT_24_BIT_COL_STREQ(R, G, B, FG, EXPECTED_STR)            \
     572                 :             :   SELFTEST_BEGIN_STMT                                                 \
     573                 :             :   {                                                                   \
     574                 :             :     style plain;                                                      \
     575                 :             :     style s;                                                          \
     576                 :             :     if (FG)                                                           \
     577                 :             :       s.m_fg_color = style::color ((R), (G), (B));                    \
     578                 :             :     else                                                              \
     579                 :             :       s.m_bg_color = style::color ((R), (G), (B));                    \
     580                 :             :     assert_style_change_streq ((SELFTEST_LOCATION),                   \
     581                 :             :                                plain,                                 \
     582                 :             :                                s,                                     \
     583                 :             :                                (EXPECTED_STR));                       \
     584                 :             :   }                                                                   \
     585                 :             :   SELFTEST_END_STMT
     586                 :             : 
     587                 :             : static void
     588                 :           4 : test_24_bit_colors ()
     589                 :             : {
     590                 :             :   /* Foreground colors.  */
     591                 :           4 :   {
     592                 :           4 :     const bool fg = true;
     593                 :             :     // #F3FAF2:
     594                 :           4 :     ASSERT_24_BIT_COL_STREQ (0xf3, 0xfa, 0xf2, fg,
     595                 :             :                              "");
     596                 :             :   }
     597                 :             :   /* Background colors.  */
     598                 :           4 :   {
     599                 :           4 :     const bool fg = false;
     600                 :             :     // #FDF7E7
     601                 :           4 :     ASSERT_24_BIT_COL_STREQ (0xfd, 0xf7, 0xe7, fg,
     602                 :             :                              "");
     603                 :             :   }
     604                 :           4 : }
     605                 :             : 
     606                 :             : static void
     607                 :           4 : test_style_combinations ()
     608                 :             : {
     609                 :           4 :   style_manager sm;
     610                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     611                 :             : 
     612                 :           4 :   style plain;
     613                 :           4 :   ASSERT_EQ (sm.get_or_create_id (plain), 0);
     614                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 1);
     615                 :             : 
     616                 :           4 :   style bold;
     617                 :           4 :   bold.m_bold = true;
     618                 :             : 
     619                 :           4 :   ASSERT_EQ (sm.get_or_create_id (bold), 1);
     620                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     621                 :           4 :   ASSERT_EQ (sm.get_or_create_id (bold), 1);
     622                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 2);
     623                 :             : 
     624                 :           4 :   style magenta_on_blue;
     625                 :           4 :   magenta_on_blue.m_fg_color = style::named_color::MAGENTA;
     626                 :           4 :   magenta_on_blue.m_bg_color = style::named_color::BLUE;
     627                 :           4 :   ASSERT_EQ (sm.get_or_create_id (magenta_on_blue), 2);
     628                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 3);
     629                 :           4 :   ASSERT_EQ (sm.get_or_create_id (magenta_on_blue), 2);
     630                 :           4 :   ASSERT_EQ (sm.get_num_styles (), 3);
     631                 :           4 : }
     632                 :             : 
     633                 :             : /* Run all selftests in this file.  */
     634                 :             : 
     635                 :             : void
     636                 :           4 : text_art_style_cc_tests ()
     637                 :             : {
     638                 :           4 :   test_bold ();
     639                 :           4 :   test_underscore ();
     640                 :           4 :   test_blink ();
     641                 :           4 :   test_named_colors ();
     642                 :           4 :   test_8_bit_colors ();
     643                 :           4 :   test_24_bit_colors ();
     644                 :           4 :   test_style_combinations ();
     645                 :           4 : }
     646                 :             : 
     647                 :             : } // namespace selftest
     648                 :             : 
     649                 :             : 
     650                 :             : #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.