xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/ui-style.h (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17f2ac410Schristos /* Styling for ui_file
2*6881a400Schristos    Copyright (C) 2018-2023 Free Software Foundation, Inc.
37f2ac410Schristos 
47f2ac410Schristos    This file is part of GDB.
57f2ac410Schristos 
67f2ac410Schristos    This program is free software; you can redistribute it and/or modify
77f2ac410Schristos    it under the terms of the GNU General Public License as published by
87f2ac410Schristos    the Free Software Foundation; either version 3 of the License, or
97f2ac410Schristos    (at your option) any later version.
107f2ac410Schristos 
117f2ac410Schristos    This program is distributed in the hope that it will be useful,
127f2ac410Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
137f2ac410Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
147f2ac410Schristos    GNU General Public License for more details.
157f2ac410Schristos 
167f2ac410Schristos    You should have received a copy of the GNU General Public License
177f2ac410Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
187f2ac410Schristos 
197f2ac410Schristos #ifndef UI_STYLE_H
207f2ac410Schristos #define UI_STYLE_H
217f2ac410Schristos 
227f2ac410Schristos /* Styles that can be applied to a ui_file.  */
237f2ac410Schristos struct ui_file_style
247f2ac410Schristos {
257f2ac410Schristos   /* One of the basic colors that can be handled by ANSI
267f2ac410Schristos      terminals.  */
277f2ac410Schristos   enum basic_color
287f2ac410Schristos   {
297f2ac410Schristos     NONE = -1,
307f2ac410Schristos     BLACK,
317f2ac410Schristos     RED,
327f2ac410Schristos     GREEN,
337f2ac410Schristos     YELLOW,
347f2ac410Schristos     BLUE,
357f2ac410Schristos     MAGENTA,
367f2ac410Schristos     CYAN,
377f2ac410Schristos     WHITE
387f2ac410Schristos   };
397f2ac410Schristos 
407f2ac410Schristos   /* Representation of a terminal color.  */
417f2ac410Schristos   class color
427f2ac410Schristos   {
437f2ac410Schristos   public:
447f2ac410Schristos 
457f2ac410Schristos     color (basic_color c)
467f2ac410Schristos       : m_simple (true),
477f2ac410Schristos 	m_value (c)
487f2ac410Schristos     {
497f2ac410Schristos     }
507f2ac410Schristos 
517f2ac410Schristos     color (int c)
527f2ac410Schristos       : m_simple (true),
537f2ac410Schristos 	m_value (c)
547f2ac410Schristos     {
557f2ac410Schristos       gdb_assert (c >= -1 && c <= 255);
567f2ac410Schristos     }
577f2ac410Schristos 
587f2ac410Schristos     color (uint8_t r, uint8_t g, uint8_t b)
597f2ac410Schristos       : m_simple (false),
607f2ac410Schristos 	m_red (r),
617f2ac410Schristos 	m_green (g),
627f2ac410Schristos 	m_blue (b)
637f2ac410Schristos     {
647f2ac410Schristos     }
657f2ac410Schristos 
667f2ac410Schristos     bool operator== (const color &other) const
677f2ac410Schristos     {
687f2ac410Schristos       if (m_simple != other.m_simple)
697f2ac410Schristos 	return false;
707f2ac410Schristos       if (m_simple)
717f2ac410Schristos 	return m_value == other.m_value;
727f2ac410Schristos       return (m_red == other.m_red && m_green == other.m_green
737f2ac410Schristos 	      && m_blue == other.m_blue);
747f2ac410Schristos     }
757f2ac410Schristos 
767f2ac410Schristos     bool operator< (const color &other) const
777f2ac410Schristos     {
787f2ac410Schristos       if (m_simple != other.m_simple)
797f2ac410Schristos 	return m_simple < other.m_simple;
807f2ac410Schristos       if (m_simple)
817f2ac410Schristos 	return m_value < other.m_value;
827f2ac410Schristos       if (m_red < other.m_red)
837f2ac410Schristos 	return true;
847f2ac410Schristos       if (m_red == other.m_red)
857f2ac410Schristos 	{
867f2ac410Schristos 	  if (m_green < other.m_green)
877f2ac410Schristos 	    return true;
887f2ac410Schristos 	  if (m_green == other.m_green)
897f2ac410Schristos 	    return m_blue < other.m_blue;
907f2ac410Schristos 	}
917f2ac410Schristos       return false;
927f2ac410Schristos     }
937f2ac410Schristos 
947f2ac410Schristos     /* Return true if this is the "NONE" color, false otherwise.  */
957f2ac410Schristos     bool is_none () const
967f2ac410Schristos     {
977f2ac410Schristos       return m_simple && m_value == NONE;
987f2ac410Schristos     }
997f2ac410Schristos 
1007f2ac410Schristos     /* Return true if this is one of the basic colors, false
1017f2ac410Schristos        otherwise.  */
1027f2ac410Schristos     bool is_basic () const
1037f2ac410Schristos     {
1047f2ac410Schristos       return m_simple && m_value >= BLACK && m_value <= WHITE;
1057f2ac410Schristos     }
1067f2ac410Schristos 
1077f2ac410Schristos     /* Return the value of a basic color.  */
1087f2ac410Schristos     int get_value () const
1097f2ac410Schristos     {
1107f2ac410Schristos       gdb_assert (is_basic ());
1117f2ac410Schristos       return m_value;
1127f2ac410Schristos     }
1137f2ac410Schristos 
1147f2ac410Schristos     /* Fill in RGB with the red/green/blue values for this color.
1157f2ac410Schristos        This may not be called for basic colors or for the "NONE"
1167f2ac410Schristos        color.  */
1177f2ac410Schristos     void get_rgb (uint8_t *rgb) const;
1187f2ac410Schristos 
1197f2ac410Schristos     /* Append the ANSI terminal escape sequence for this color to STR.
1207f2ac410Schristos        IS_FG indicates whether this is a foreground or background
1217f2ac410Schristos        color.  Returns true if any characters were written; returns
1227f2ac410Schristos        false otherwise (which can only happen for the "NONE"
1237f2ac410Schristos        color).  */
1247f2ac410Schristos     bool append_ansi (bool is_fg, std::string *str) const;
1257f2ac410Schristos 
1267f2ac410Schristos   private:
1277f2ac410Schristos 
1287f2ac410Schristos     bool m_simple;
1297d62b00eSchristos     union
1307d62b00eSchristos     {
1317f2ac410Schristos       int m_value;
1327d62b00eSchristos       struct
1337d62b00eSchristos       {
1347f2ac410Schristos 	uint8_t m_red, m_green, m_blue;
1357f2ac410Schristos       };
1367d62b00eSchristos     };
1377d62b00eSchristos   };
1387f2ac410Schristos 
1397f2ac410Schristos   /* Intensity settings that are available.  */
1407f2ac410Schristos   enum intensity
1417f2ac410Schristos   {
1427f2ac410Schristos     NORMAL = 0,
1437f2ac410Schristos     BOLD,
1447f2ac410Schristos     DIM
1457f2ac410Schristos   };
1467f2ac410Schristos 
1477f2ac410Schristos   ui_file_style () = default;
1487f2ac410Schristos 
1497f2ac410Schristos   ui_file_style (color f, color b, intensity i = NORMAL)
1507f2ac410Schristos     : m_foreground (f),
1517f2ac410Schristos       m_background (b),
1527f2ac410Schristos       m_intensity (i)
1537f2ac410Schristos   {
1547f2ac410Schristos   }
1557f2ac410Schristos 
1567f2ac410Schristos   bool operator== (const ui_file_style &other) const
1577f2ac410Schristos   {
1587f2ac410Schristos     return (m_foreground == other.m_foreground
1597f2ac410Schristos 	    && m_background == other.m_background
1607f2ac410Schristos 	    && m_intensity == other.m_intensity
1617f2ac410Schristos 	    && m_reverse == other.m_reverse);
1627f2ac410Schristos   }
1637f2ac410Schristos 
1647f2ac410Schristos   bool operator!= (const ui_file_style &other) const
1657f2ac410Schristos   {
1667f2ac410Schristos     return !(*this == other);
1677f2ac410Schristos   }
1687f2ac410Schristos 
1697f2ac410Schristos   /* Return the ANSI escape sequence for this style.  */
1707f2ac410Schristos   std::string to_ansi () const;
1717f2ac410Schristos 
1727f2ac410Schristos   /* Return true if this style is the default style; false
1737f2ac410Schristos      otherwise.  */
1747f2ac410Schristos   bool is_default () const
1757f2ac410Schristos   {
1767f2ac410Schristos     return (m_foreground == NONE
1777f2ac410Schristos 	    && m_background == NONE
1787f2ac410Schristos 	    && m_intensity == NORMAL
1797f2ac410Schristos 	    && !m_reverse);
1807f2ac410Schristos   }
1817f2ac410Schristos 
1827f2ac410Schristos   /* Return true if this style specified reverse display; false
1837f2ac410Schristos      otherwise.  */
1847f2ac410Schristos   bool is_reverse () const
1857f2ac410Schristos   {
1867f2ac410Schristos     return m_reverse;
1877f2ac410Schristos   }
1887f2ac410Schristos 
1897f2ac410Schristos   /* Set/clear the reverse display flag.  */
1907f2ac410Schristos   void set_reverse (bool reverse)
1917f2ac410Schristos   {
1927f2ac410Schristos     m_reverse = reverse;
1937f2ac410Schristos   }
1947f2ac410Schristos 
1957f2ac410Schristos   /* Return the foreground color of this style.  */
1967f2ac410Schristos   const color &get_foreground () const
1977f2ac410Schristos   {
1987f2ac410Schristos     return m_foreground;
1997f2ac410Schristos   }
2007f2ac410Schristos 
2017f2ac410Schristos   /* Set the foreground color of this style.  */
2027f2ac410Schristos   void set_fg (color c)
2037f2ac410Schristos   {
2047f2ac410Schristos     m_foreground = c;
2057f2ac410Schristos   }
2067f2ac410Schristos 
2077f2ac410Schristos   /* Return the background color of this style.  */
2087f2ac410Schristos   const color &get_background () const
2097f2ac410Schristos   {
2107f2ac410Schristos     return m_background;
2117f2ac410Schristos   }
2127f2ac410Schristos 
2137f2ac410Schristos   /* Set the background color of this style.  */
2147f2ac410Schristos   void set_bg (color c)
2157f2ac410Schristos   {
2167f2ac410Schristos     m_background = c;
2177f2ac410Schristos   }
2187f2ac410Schristos 
2197f2ac410Schristos   /* Return the intensity of this style.  */
2207f2ac410Schristos   intensity get_intensity () const
2217f2ac410Schristos   {
2227f2ac410Schristos     return m_intensity;
2237f2ac410Schristos   }
2247f2ac410Schristos 
2257f2ac410Schristos   /* Parse an ANSI escape sequence in BUF, modifying this style.  BUF
2267f2ac410Schristos      must begin with an ESC character.  Return true if an escape
2277f2ac410Schristos      sequence was successfully parsed; false otherwise.  In either
2287f2ac410Schristos      case, N_READ is updated to reflect the number of chars read from
2297f2ac410Schristos      BUF.  */
2307f2ac410Schristos   bool parse (const char *buf, size_t *n_read);
2317f2ac410Schristos 
2327d62b00eSchristos   /* We need this because we can't pass a reference via va_args.  */
2337d62b00eSchristos   const ui_file_style *ptr () const
2347d62b00eSchristos   {
2357d62b00eSchristos     return this;
2367d62b00eSchristos   }
2377d62b00eSchristos 
2387f2ac410Schristos private:
2397f2ac410Schristos 
2407f2ac410Schristos   color m_foreground = NONE;
2417f2ac410Schristos   color m_background = NONE;
2427f2ac410Schristos   intensity m_intensity = NORMAL;
2437f2ac410Schristos   bool m_reverse = false;
2447f2ac410Schristos };
2457f2ac410Schristos 
2467f2ac410Schristos /* Skip an ANSI escape sequence in BUF.  BUF must begin with an ESC
2477f2ac410Schristos    character.  Return true if an escape sequence was successfully
2487d62b00eSchristos    skipped; false otherwise.  If an escape sequence was skipped,
2497d62b00eSchristos    N_READ is updated to reflect the number of chars read from BUF.  */
2507f2ac410Schristos 
2517f2ac410Schristos extern bool skip_ansi_escape (const char *buf, int *n_read);
2527f2ac410Schristos 
2537f2ac410Schristos #endif /* UI_STYLE_H */
254