/* Styling for ui_file Copyright (C) 2018-2019 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef UI_STYLE_H #define UI_STYLE_H /* Styles that can be applied to a ui_file. */ struct ui_file_style { /* One of the basic colors that can be handled by ANSI terminals. */ enum basic_color { NONE = -1, BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; /* Representation of a terminal color. */ class color { public: color (basic_color c) : m_simple (true), m_value (c) { } color (int c) : m_simple (true), m_value (c) { gdb_assert (c >= -1 && c <= 255); } color (uint8_t r, uint8_t g, uint8_t b) : m_simple (false), m_red (r), m_green (g), m_blue (b) { } bool operator== (const color &other) const { if (m_simple != other.m_simple) return false; if (m_simple) return m_value == other.m_value; return (m_red == other.m_red && m_green == other.m_green && m_blue == other.m_blue); } bool operator< (const color &other) const { if (m_simple != other.m_simple) return m_simple < other.m_simple; if (m_simple) return m_value < other.m_value; if (m_red < other.m_red) return true; if (m_red == other.m_red) { if (m_green < other.m_green) return true; if (m_green == other.m_green) return m_blue < other.m_blue; } return false; } /* Return true if this is the "NONE" color, false otherwise. */ bool is_none () const { return m_simple && m_value == NONE; } /* Return true if this is one of the basic colors, false otherwise. */ bool is_basic () const { return m_simple && m_value >= BLACK && m_value <= WHITE; } /* Return the value of a basic color. */ int get_value () const { gdb_assert (is_basic ()); return m_value; } /* Fill in RGB with the red/green/blue values for this color. This may not be called for basic colors or for the "NONE" color. */ void get_rgb (uint8_t *rgb) const; /* Append the ANSI terminal escape sequence for this color to STR. IS_FG indicates whether this is a foreground or background color. Returns true if any characters were written; returns false otherwise (which can only happen for the "NONE" color). */ bool append_ansi (bool is_fg, std::string *str) const; private: bool m_simple; int m_value; uint8_t m_red, m_green, m_blue; }; /* Intensity settings that are available. */ enum intensity { NORMAL = 0, BOLD, DIM }; ui_file_style () = default; ui_file_style (color f, color b, intensity i = NORMAL) : m_foreground (f), m_background (b), m_intensity (i) { } bool operator== (const ui_file_style &other) const { return (m_foreground == other.m_foreground && m_background == other.m_background && m_intensity == other.m_intensity && m_reverse == other.m_reverse); } bool operator!= (const ui_file_style &other) const { return !(*this == other); } /* Return the ANSI escape sequence for this style. */ std::string to_ansi () const; /* Return true if this style is the default style; false otherwise. */ bool is_default () const { return (m_foreground == NONE && m_background == NONE && m_intensity == NORMAL && !m_reverse); } /* Return true if this style specified reverse display; false otherwise. */ bool is_reverse () const { return m_reverse; } /* Set/clear the reverse display flag. */ void set_reverse (bool reverse) { m_reverse = reverse; } /* Return the foreground color of this style. */ const color &get_foreground () const { return m_foreground; } /* Set the foreground color of this style. */ void set_fg (color c) { m_foreground = c; } /* Return the background color of this style. */ const color &get_background () const { return m_background; } /* Set the background color of this style. */ void set_bg (color c) { m_background = c; } /* Return the intensity of this style. */ intensity get_intensity () const { return m_intensity; } /* Parse an ANSI escape sequence in BUF, modifying this style. BUF must begin with an ESC character. Return true if an escape sequence was successfully parsed; false otherwise. In either case, N_READ is updated to reflect the number of chars read from BUF. */ bool parse (const char *buf, size_t *n_read); private: color m_foreground = NONE; color m_background = NONE; intensity m_intensity = NORMAL; bool m_reverse = false; }; /* Skip an ANSI escape sequence in BUF. BUF must begin with an ESC character. Return true if an escape sequence was successfully skipped; false otherwise. In either case, N_READ is updated to reflect the number of chars read from BUF. */ extern bool skip_ansi_escape (const char *buf, int *n_read); #endif /* UI_STYLE_H */