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