cli-script: use unique_ptr to not leak next struct
[binutils-gdb.git] / gdb / cli / cli-style.c
1 /* CLI colorizing
2
3 Copyright (C) 2018-2021 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "cli/cli-cmds.h"
22 #include "cli/cli-setshow.h"
23 #include "cli/cli-style.h"
24 #include "source-cache.h"
25 #include "observable.h"
26
27 /* True if styling is enabled. */
28
29 #if defined (__MSDOS__)
30 bool cli_styling = false;
31 #else
32 bool cli_styling = true;
33 #endif
34
35 /* True if source styling is enabled. Note that this is only
36 consulted when cli_styling is true. */
37
38 bool source_styling = true;
39
40 /* Name of colors; must correspond to ui_file_style::basic_color. */
41 static const char * const cli_colors[] = {
42 "none",
43 "black",
44 "red",
45 "green",
46 "yellow",
47 "blue",
48 "magenta",
49 "cyan",
50 "white",
51 nullptr
52 };
53
54 /* Names of intensities; must correspond to
55 ui_file_style::intensity. */
56 static const char * const cli_intensities[] = {
57 "normal",
58 "bold",
59 "dim",
60 nullptr
61 };
62
63 /* See cli-style.h. */
64
65 cli_style_option file_name_style ("filename", ui_file_style::GREEN);
66
67 /* See cli-style.h. */
68
69 cli_style_option function_name_style ("function", ui_file_style::YELLOW);
70
71 /* See cli-style.h. */
72
73 cli_style_option variable_name_style ("variable", ui_file_style::CYAN);
74
75 /* See cli-style.h. */
76
77 cli_style_option address_style ("address", ui_file_style::BLUE);
78
79 /* See cli-style.h. */
80
81 cli_style_option highlight_style ("highlight", ui_file_style::RED);
82
83 /* See cli-style.h. */
84
85 cli_style_option title_style ("title", ui_file_style::BOLD);
86
87 /* See cli-style.h. */
88
89 cli_style_option tui_border_style ("tui-border", ui_file_style::CYAN);
90
91 /* See cli-style.h. */
92
93 cli_style_option tui_active_border_style ("tui-active-border",
94 ui_file_style::CYAN);
95
96 /* See cli-style.h. */
97
98 cli_style_option metadata_style ("metadata", ui_file_style::DIM);
99
100 /* See cli-style.h. */
101
102 cli_style_option version_style ("version", ui_file_style::MAGENTA,
103 ui_file_style::BOLD);
104
105 /* See cli-style.h. */
106
107 cli_style_option::cli_style_option (const char *name,
108 ui_file_style::basic_color fg,
109 ui_file_style::intensity intensity)
110 : changed (name),
111 m_name (name),
112 m_foreground (cli_colors[fg - ui_file_style::NONE]),
113 m_background (cli_colors[0]),
114 m_intensity (cli_intensities[intensity])
115 {
116 }
117
118 /* See cli-style.h. */
119
120 cli_style_option::cli_style_option (const char *name,
121 ui_file_style::intensity i)
122 : changed (name),
123 m_name (name),
124 m_foreground (cli_colors[0]),
125 m_background (cli_colors[0]),
126 m_intensity (cli_intensities[i])
127 {
128 }
129
130 /* Return the color number corresponding to COLOR. */
131
132 static int
133 color_number (const char *color)
134 {
135 for (int i = 0; i < ARRAY_SIZE (cli_colors); ++i)
136 {
137 if (color == cli_colors[i])
138 return i - 1;
139 }
140 gdb_assert_not_reached ("color not found");
141 }
142
143 /* See cli-style.h. */
144
145 ui_file_style
146 cli_style_option::style () const
147 {
148 int fg = color_number (m_foreground);
149 int bg = color_number (m_background);
150 ui_file_style::intensity intensity = ui_file_style::NORMAL;
151
152 for (int i = 0; i < ARRAY_SIZE (cli_intensities); ++i)
153 {
154 if (m_intensity == cli_intensities[i])
155 {
156 intensity = (ui_file_style::intensity) i;
157 break;
158 }
159 }
160
161 return ui_file_style (fg, bg, intensity);
162 }
163
164 /* See cli-style.h. */
165
166 void
167 cli_style_option::do_set_value (const char *ignore, int from_tty,
168 struct cmd_list_element *cmd)
169 {
170 cli_style_option *cso = (cli_style_option *) get_cmd_context (cmd);
171 cso->changed.notify ();
172 }
173
174 /* Implements the cli_style_option::do_show_* functions.
175 WHAT and VALUE are the property and value to show.
176 The style for which WHAT is shown is retrieved from CMD context. */
177
178 static void
179 do_show (const char *what, struct ui_file *file,
180 struct cmd_list_element *cmd,
181 const char *value)
182 {
183 cli_style_option *cso = (cli_style_option *) get_cmd_context (cmd);
184 fputs_filtered (_("The "), file);
185 fprintf_styled (file, cso->style (), _("\"%s\" style"), cso->name ());
186 fprintf_filtered (file, _(" %s is: %s\n"), what, value);
187 }
188
189 /* See cli-style.h. */
190
191 void
192 cli_style_option::do_show_foreground (struct ui_file *file, int from_tty,
193 struct cmd_list_element *cmd,
194 const char *value)
195 {
196 do_show (_("foreground color"), file, cmd, value);
197 }
198
199 /* See cli-style.h. */
200
201 void
202 cli_style_option::do_show_background (struct ui_file *file, int from_tty,
203 struct cmd_list_element *cmd,
204 const char *value)
205 {
206 do_show (_("background color"), file, cmd, value);
207 }
208
209 /* See cli-style.h. */
210
211 void
212 cli_style_option::do_show_intensity (struct ui_file *file, int from_tty,
213 struct cmd_list_element *cmd,
214 const char *value)
215 {
216 do_show (_("display intensity"), file, cmd, value);
217 }
218
219 /* See cli-style.h. */
220
221 void
222 cli_style_option::add_setshow_commands (enum command_class theclass,
223 const char *prefix_doc,
224 struct cmd_list_element **set_list,
225 struct cmd_list_element **show_list,
226 bool skip_intensity)
227 {
228 add_basic_prefix_cmd (m_name, no_class, prefix_doc, &m_set_list,
229 0, set_list);
230 add_show_prefix_cmd (m_name, no_class, prefix_doc, &m_show_list,
231 0, show_list);
232
233 add_setshow_enum_cmd ("foreground", theclass, cli_colors,
234 &m_foreground,
235 _("Set the foreground color for this property."),
236 _("Show the foreground color for this property."),
237 nullptr,
238 do_set_value,
239 do_show_foreground,
240 &m_set_list, &m_show_list, (void *) this);
241 add_setshow_enum_cmd ("background", theclass, cli_colors,
242 &m_background,
243 _("Set the background color for this property."),
244 _("Show the background color for this property."),
245 nullptr,
246 do_set_value,
247 do_show_background,
248 &m_set_list, &m_show_list, (void *) this);
249 if (!skip_intensity)
250 add_setshow_enum_cmd ("intensity", theclass, cli_intensities,
251 &m_intensity,
252 _("Set the display intensity for this property."),
253 _("Show the display intensity for this property."),
254 nullptr,
255 do_set_value,
256 do_show_intensity,
257 &m_set_list, &m_show_list, (void *) this);
258 }
259
260 static cmd_list_element *style_set_list;
261 static cmd_list_element *style_show_list;
262
263 static void
264 set_style_enabled (const char *args, int from_tty, struct cmd_list_element *c)
265 {
266 g_source_cache.clear ();
267 gdb::observers::source_styling_changed.notify ();
268 }
269
270 static void
271 show_style_enabled (struct ui_file *file, int from_tty,
272 struct cmd_list_element *c, const char *value)
273 {
274 if (cli_styling)
275 fprintf_filtered (file, _("CLI output styling is enabled.\n"));
276 else
277 fprintf_filtered (file, _("CLI output styling is disabled.\n"));
278 }
279
280 static void
281 show_style_sources (struct ui_file *file, int from_tty,
282 struct cmd_list_element *c, const char *value)
283 {
284 if (source_styling)
285 fprintf_filtered (file, _("Source code styling is enabled.\n"));
286 else
287 fprintf_filtered (file, _("Source code styling is disabled.\n"));
288 }
289
290 void _initialize_cli_style ();
291 void
292 _initialize_cli_style ()
293 {
294 add_basic_prefix_cmd ("style", no_class, _("\
295 Style-specific settings.\n\
296 Configure various style-related variables, such as colors"),
297 &style_set_list, 0, &setlist);
298 add_show_prefix_cmd ("style", no_class, _("\
299 Style-specific settings.\n\
300 Configure various style-related variables, such as colors"),
301 &style_show_list, 0, &showlist);
302
303 add_setshow_boolean_cmd ("enabled", no_class, &cli_styling, _("\
304 Set whether CLI styling is enabled."), _("\
305 Show whether CLI is enabled."), _("\
306 If enabled, output to the terminal is styled."),
307 set_style_enabled, show_style_enabled,
308 &style_set_list, &style_show_list);
309
310 add_setshow_boolean_cmd ("sources", no_class, &source_styling, _("\
311 Set whether source code styling is enabled."), _("\
312 Show whether source code styling is enabled."), _("\
313 If enabled, source code is styled.\n"
314 #ifdef HAVE_SOURCE_HIGHLIGHT
315 "Note that source styling only works if styling in general is enabled,\n\
316 see \"show style enabled\"."
317 #else
318 "Source highlighting may be disabled in this installation of gdb, because\n\
319 it was not linked against GNU Source Highlight. However, it might still be\n\
320 available if the appropriate extension is available at runtime."
321 #endif
322 ), set_style_enabled, show_style_sources,
323 &style_set_list, &style_show_list);
324
325 file_name_style.add_setshow_commands (no_class, _("\
326 Filename display styling.\n\
327 Configure filename colors and display intensity."),
328 &style_set_list, &style_show_list,
329 false);
330
331 function_name_style.add_setshow_commands (no_class, _("\
332 Function name display styling.\n\
333 Configure function name colors and display intensity"),
334 &style_set_list, &style_show_list,
335 false);
336
337 variable_name_style.add_setshow_commands (no_class, _("\
338 Variable name display styling.\n\
339 Configure variable name colors and display intensity"),
340 &style_set_list, &style_show_list,
341 false);
342
343 address_style.add_setshow_commands (no_class, _("\
344 Address display styling.\n\
345 Configure address colors and display intensity"),
346 &style_set_list, &style_show_list,
347 false);
348
349 title_style.add_setshow_commands (no_class, _("\
350 Title display styling.\n\
351 Configure title colors and display intensity\n\
352 Some commands (such as \"apropos -v REGEXP\") use the title style to improve\n\
353 readability."),
354 &style_set_list, &style_show_list,
355 false);
356
357 highlight_style.add_setshow_commands (no_class, _("\
358 Highlight display styling.\n\
359 Configure highlight colors and display intensity\n\
360 Some commands use the highlight style to draw the attention to a part\n\
361 of their output."),
362 &style_set_list, &style_show_list,
363 false);
364
365 metadata_style.add_setshow_commands (no_class, _("\
366 Metadata display styling.\n\
367 Configure metadata colors and display intensity\n\
368 The \"metadata\" style is used when GDB displays information about\n\
369 your data, for example \"<unavailable>\""),
370 &style_set_list, &style_show_list,
371 false);
372
373 tui_border_style.add_setshow_commands (no_class, _("\
374 TUI border display styling.\n\
375 Configure TUI border colors\n\
376 The \"tui-border\" style is used when GDB displays the border of a\n\
377 TUI window that does not have the focus."),
378 &style_set_list, &style_show_list,
379 true);
380
381 tui_active_border_style.add_setshow_commands (no_class, _("\
382 TUI active border display styling.\n\
383 Configure TUI active border colors\n\
384 The \"tui-active-border\" style is used when GDB displays the border of a\n\
385 TUI window that does have the focus."),
386 &style_set_list,
387 &style_show_list,
388 true);
389
390 version_style.add_setshow_commands (no_class, _("\
391 Version string display styling.\n\
392 Configure colors used to display the GDB version string."),
393 &style_set_list, &style_show_list,
394 false);
395 }