From eedeedd2a50d121af466ddfa9e897212defbf079 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 9 Nov 2018 17:29:50 -0700 Subject: Introduce ui_file_style This introduces the new ui_file_style class and various helpers. This class represents a terminal style and provides methods for parsing and emitting the corresponding ANSI terminal escape sequences. gdb/ChangeLog 2018-12-28 Tom Tromey * unittests/style-selftests.c: New file. * ui-style.c: New file. * ui-style.h: New file. * ui-file.h: Include ui-style.h. * Makefile.in (COMMON_SFILES): Add ui-style.c. (HFILES_NO_SRCDIR): Add ui-style.h. (SUBDIR_UNITTESTS_SRCS): Add style-selftests.c. --- gdb/ui-style.h | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 gdb/ui-style.h (limited to 'gdb/ui-style.h') diff --git a/gdb/ui-style.h b/gdb/ui-style.h new file mode 100644 index 0000000..2d0e516 --- /dev/null +++ b/gdb/ui-style.h @@ -0,0 +1,213 @@ +/* Styling for ui_file + Copyright (C) 2018 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 specified reverse display; false + otherwise. */ + bool is_reverse () const + { + return m_reverse; + } + + /* Return the foreground color of this style. */ + const color &get_foreground () const + { + return m_foreground; + } + + /* Return the background color of this style. */ + const color &get_background () const + { + return m_background; + } + + /* 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 */ -- cgit v1.1