GDB (xrefs)
Loading...
Searching...
No Matches
cli-out.c
Go to the documentation of this file.
1/* Output generating routines for GDB CLI.
2
3 Copyright (C) 1999-2023 Free Software Foundation, Inc.
4
5 Contributed by Cygnus Solutions.
6 Written by Fernando Nasser for Cygnus.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22
23#include "defs.h"
24#include "ui-out.h"
25#include "cli-out.h"
26#include "completer.h"
27#include "readline/readline.h"
28#include "cli/cli-style.h"
29#include "ui.h"
30
31/* These are the CLI output functions */
32
33/* Mark beginning of a table */
34
35void
36cli_ui_out::do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
37{
38 if (nr_rows == 0)
39 m_suppress_output = true;
40 else
41 /* Only the table suppresses the output and, fortunately, a table
42 is not a recursive data structure. */
43 gdb_assert (!m_suppress_output);
44}
45
46/* Mark beginning of a table body */
47
48void
50{
52 return;
53
54 /* first, close the table header line */
55 text ("\n");
56}
57
58/* Mark end of a table */
59
60void
65
66/* Specify table header */
67
68void
70 const std::string &col_name,
71 const std::string &col_hdr)
72{
74 return;
75
76 do_field_string (0, width, alignment, 0, col_hdr.c_str (),
77 ui_file_style ());
78}
79
80/* Mark beginning of a list */
81
82void
84{
85}
86
87/* Mark end of a list */
88
89void
93
94/* output an int field */
95
96void
97cli_ui_out::do_field_signed (int fldno, int width, ui_align alignment,
98 const char *fldname, LONGEST value)
99{
101 return;
102
103 do_field_string (fldno, width, alignment, fldname, plongest (value),
104 ui_file_style ());
105}
106
107/* output an unsigned field */
108
109void
111 const char *fldname, ULONGEST value)
112{
114 return;
115
116 do_field_string (fldno, width, alignment, fldname, pulongest (value),
117 ui_file_style ());
118}
119
120/* used to omit a field */
121
122void
123cli_ui_out::do_field_skip (int fldno, int width, ui_align alignment,
124 const char *fldname)
125{
127 return;
128
129 do_field_string (fldno, width, alignment, fldname, "",
130 ui_file_style ());
131}
132
133/* other specific cli_field_* end up here so alignment and field
134 separators are both handled by cli_field_string */
135
136void
138 const char *fldname, const char *string,
139 const ui_file_style &style)
140{
141 int before = 0;
142 int after = 0;
143
145 return;
146
147 if ((align != ui_noalign) && string)
148 {
149 before = width - strlen (string);
150 if (before <= 0)
151 before = 0;
152 else
153 {
154 if (align == ui_right)
155 after = 0;
156 else if (align == ui_left)
157 {
158 after = before;
159 before = 0;
160 }
161 else
162 /* ui_center */
163 {
164 after = before / 2;
165 before -= after;
166 }
167 }
168 }
169
170 if (before)
171 spaces (before);
172
173 if (string)
174 {
175 ui_file *stream = m_streams.back ();
176 stream->emit_style_escape (style);
177 stream->puts (string);
178 stream->emit_style_escape (ui_file_style ());
179 }
180
181 if (after)
182 spaces (after);
183
184 if (align != ui_noalign)
186}
187
188/* Output field containing ARGS using printf formatting in FORMAT. */
189
190void
192 const char *fldname, const ui_file_style &style,
193 const char *format, va_list args)
194{
196 return;
197
198 std::string str = string_vprintf (format, args);
199
200 do_field_string (fldno, width, align, fldname, str.c_str (), style);
201}
202
203void
205{
207 return;
208
209 print_spaces (numspaces, m_streams.back ());
210}
211
212void
213cli_ui_out::do_text (const char *string)
214{
216 return;
217
218 gdb_puts (string, m_streams.back ());
219}
220
221void
223 const char *format, va_list args)
224{
226 return;
227
228 std::string str = string_vprintf (format, args);
229 if (!str.empty ())
230 {
231 ui_file *stream = m_streams.back ();
232 stream->emit_style_escape (style);
233 stream->puts (str.c_str ());
234 stream->emit_style_escape (ui_file_style ());
235 }
236}
237
238void
240{
242 return;
243
244 m_streams.back ()->wrap_here (indent);
245}
246
247void
249{
250 gdb_flush (m_streams.back ());
251}
252
253/* OUTSTREAM as non-NULL will push OUTSTREAM on the stack of output streams
254 and make it therefore active. OUTSTREAM as NULL will pop the last pushed
255 output stream; it is an internal error if it does not exist. */
256
257void
259{
260 if (outstream != NULL)
261 m_streams.push_back (outstream);
262 else
263 m_streams.pop_back ();
264}
265
266/* Initialize a progress update to be displayed with
267 cli_ui_out::do_progress_notify. */
268
269void
271{
272 m_progress_info.emplace_back ();
273}
274
275#define MIN_CHARS_PER_LINE 50
276#define MAX_CHARS_PER_LINE 4096
277
278/* Print a progress update. MSG is a string to be printed on the line above
279 the progress bar. TOTAL is the size of the download whose progress is
280 being displayed. UNIT should be the unit of TOTAL (ex. "K"). If HOWMUCH
281 is between 0.0 and 1.0, a progress bar is displayed indicating the percentage
282 of completion and the download size. If HOWMUCH is negative, a progress
283 indicator will tick across the screen. If the output stream is not a tty
284 then only MSG is printed.
285
286 - printed for tty, HOWMUCH between 0.0 and 1.0:
287 <MSG
288 [######### ] HOWMUCH*100% (TOTAL UNIT)\r>
289 - printed for tty, HOWMUCH < 0.0:
290 <MSG
291 [ ### ]\r>
292 - printed for not-a-tty:
293 <MSG...\n>
294*/
295
296void
297cli_ui_out::do_progress_notify (const std::string &msg,
298 const char *unit,
299 double howmuch, double total)
300{
302 struct ui_file *stream = m_streams.back ();
303 cli_progress_info &info (m_progress_info.back ());
304
307
308 if (info.state == progress_update::START)
309 {
310 if (stream->isatty ()
313 {
314 gdb_printf (stream, "%s\n", msg.c_str ());
315 info.state = progress_update::BAR;
316 }
317 else
318 {
319 gdb_printf (stream, "%s...\n", msg.c_str ());
320 info.state = progress_update::WORKING;
321 }
322 }
323
324 if (info.state != progress_update::BAR
326 return;
327
328 if (total > 0 && howmuch >= 0 && howmuch <= 1.0)
329 {
330 std::string progress = string_printf (" %3.f%% (%.2f %s)",
331 howmuch * 100, total,
332 unit);
333 int width = chars_per_line - progress.size () - 4;
334 int max = width * howmuch;
335
336 std::string display = "\r[";
337
338 for (int i = 0; i < width; ++i)
339 if (i < max)
340 display += "#";
341 else
342 display += " ";
343
344 display += "]" + progress;
345 gdb_printf (stream, "%s", display.c_str ());
346 gdb_flush (stream);
347 }
348 else
349 {
350 using namespace std::chrono;
351 milliseconds diff = duration_cast<milliseconds>
352 (steady_clock::now () - info.last_update);
353
354 /* Advance the progress indicator at a rate of 1 tick every
355 every 0.5 seconds. */
356 if (diff.count () >= 500)
357 {
358 int width = chars_per_line - 4;
359
360 gdb_printf (stream, "\r[");
361 for (int i = 0; i < width; ++i)
362 {
363 if (i == info.pos % width
364 || i == (info.pos + 1) % width
365 || i == (info.pos + 2) % width)
366 gdb_printf (stream, "#");
367 else
368 gdb_printf (stream, " ");
369 }
370
371 gdb_printf (stream, "]");
372 gdb_flush (stream);
373 info.last_update = steady_clock::now ();
374 info.pos++;
375 }
376 }
377
378 return;
379}
380
381/* Clear do_progress_notify output from the current line. Overwrites the
382 notification with whitespace. */
383
384void
386{
387 struct ui_file *stream = m_streams.back ();
389
390 scoped_restore save_pagination
391 = make_scoped_restore (&pagination_enabled, false);
392
393 if (!stream->isatty ()
396 return;
397
400
401 gdb_printf (stream, "\r");
402 for (int i = 0; i < chars_per_line; ++i)
403 gdb_printf (stream, " ");
404 gdb_printf (stream, "\r");
405
406 gdb_flush (stream);
407}
408
409/* Remove the most recent progress update from the progress_info stack
410 and overwrite the current line with whitespace. */
411
412void
414{
415 struct ui_file *stream = m_streams.back ();
416 m_progress_info.pop_back ();
417
418 if (stream->isatty ())
420}
421
422/* local functions */
423
424void
426{
427 gdb_putc (' ', m_streams.back ());
428}
429
430/* Constructor for cli_ui_out. */
431
432cli_ui_out::cli_ui_out (ui_file *stream, ui_out_flags flags)
433: ui_out (flags),
434 m_suppress_output (false)
435{
436 gdb_assert (stream != NULL);
437
438 m_streams.push_back (stream);
439}
440
444
445ui_file *
447{
448 ui_file *old;
449
450 old = m_streams.back ();
451 m_streams.back () = stream;
452
453 return old;
454}
455
456bool
458{
459 return m_streams.back ()->can_emit_style_escape ();
460}
461
462/* CLI interface to display tab-completion matches. */
463
464/* CLI version of displayer.crlf. */
465
466static void
467cli_mld_crlf (const struct match_list_displayer *displayer)
468{
469 rl_crlf ();
470}
471
472/* CLI version of displayer.putch. */
473
474static void
475cli_mld_putch (const struct match_list_displayer *displayer, int ch)
476{
477 putc (ch, rl_outstream);
478}
479
480/* CLI version of displayer.puts. */
481
482static void
483cli_mld_puts (const struct match_list_displayer *displayer, const char *s)
484{
485 fputs (s, rl_outstream);
486}
487
488/* CLI version of displayer.flush. */
489
490static void
491cli_mld_flush (const struct match_list_displayer *displayer)
492{
493 fflush (rl_outstream);
494}
495
496EXTERN_C void _rl_erase_entire_line (void);
497
498/* CLI version of displayer.erase_entire_line. */
499
500static void
502{
504}
505
506/* CLI version of displayer.beep. */
507
508static void
509cli_mld_beep (const struct match_list_displayer *displayer)
510{
511 rl_ding ();
512}
513
514/* CLI version of displayer.read_key. */
515
516static int
517cli_mld_read_key (const struct match_list_displayer *displayer)
518{
519 return rl_read_key ();
520}
521
522/* CLI version of rl_completion_display_matches_hook.
523 See gdb_display_match_list for a description of the arguments. */
524
525void
526cli_display_match_list (char **matches, int len, int max)
527{
528 struct match_list_displayer displayer;
529
530 rl_get_screen_size (&displayer.height, &displayer.width);
531 displayer.crlf = cli_mld_crlf;
532 displayer.putch = cli_mld_putch;
533 displayer.puts = cli_mld_puts;
534 displayer.flush = cli_mld_flush;
536 displayer.beep = cli_mld_beep;
537 displayer.read_key = cli_mld_read_key;
538
539 gdb_display_match_list (matches, len, max, &displayer);
540 rl_forced_update_display ();
541}
void field_separator()
Definition cli-out.c:425
virtual void do_flush() override
Definition cli-out.c:248
bool can_emit_style_escape() const override
Definition cli-out.c:457
virtual void do_table_body() override
Definition cli-out.c:49
std::vector< cli_progress_info > m_progress_info
Definition cli-out.h:106
cli_ui_out(ui_file *stream, ui_out_flags flags=ui_source_list)
Definition cli-out.c:432
virtual void do_begin(ui_out_type type, const char *id) override
Definition cli-out.c:83
virtual void do_table_end() override
Definition cli-out.c:61
virtual void do_table_header(int width, ui_align align, const std::string &col_name, const std::string &col_hdr) override
Definition cli-out.c:69
void clear_progress_notify()
Definition cli-out.c:385
virtual void do_progress_start() override
Definition cli-out.c:270
virtual void virtual void do_spaces(int numspaces) override
Definition cli-out.c:204
virtual void do_field_string(int fldno, int width, ui_align align, const char *fldname, const char *string, const ui_file_style &style) override
Definition cli-out.c:137
virtual void do_field_signed(int fldno, int width, ui_align align, const char *fldname, LONGEST value) override
Definition cli-out.c:97
virtual void do_message(const ui_file_style &style, const char *format, va_list args) override ATTRIBUTE_PRINTF(3
Definition cli-out.c:222
virtual void do_progress_end() override
Definition cli-out.c:413
virtual void do_field_fmt(int fldno, int width, ui_align align, const char *fldname, const ui_file_style &style, const char *format, va_list args) override ATTRIBUTE_PRINTF(7
Definition cli-out.c:191
bool m_suppress_output
Definition cli-out.h:88
virtual void virtual void do_wrap_hint(int indent) override
Definition cli-out.c:239
std::vector< ui_file * > m_streams
Definition cli-out.h:87
virtual void do_text(const char *string) override
Definition cli-out.c:213
virtual ~cli_ui_out()
Definition cli-out.c:441
virtual void do_table_begin(int nbrofcols, int nr_rows, const char *tblid) override
Definition cli-out.c:36
ui_file * set_stream(ui_file *stream)
Definition cli-out.c:446
virtual void do_field_unsigned(int fldno, int width, ui_align align, const char *fldname, ULONGEST value) override
Definition cli-out.c:110
virtual void do_end(ui_out_type type) override
Definition cli-out.c:90
virtual void do_field_skip(int fldno, int width, ui_align align, const char *fldname) override
Definition cli-out.c:123
virtual void do_redirect(struct ui_file *outstream) override
Definition cli-out.c:258
virtual void do_progress_notify(const std::string &, const char *, double, double) override
Definition cli-out.c:297
virtual bool can_emit_style_escape()
Definition ui-file.h:93
virtual void puts(const char *str)
Definition ui-file.h:76
virtual bool isatty()
Definition ui-file.h:82
virtual void emit_style_escape(const ui_file_style &style)
Definition ui-file.c:80
void putc(int c)
Definition ui-file.c:64
void void void spaces(int numspaces)
Definition ui-out.c:560
void text(const char *string)
Definition ui-out.c:566
#define MAX_CHARS_PER_LINE
Definition cli-out.c:276
#define MIN_CHARS_PER_LINE
Definition cli-out.c:275
static void cli_mld_puts(const struct match_list_displayer *displayer, const char *s)
Definition cli-out.c:483
void cli_display_match_list(char **matches, int len, int max)
Definition cli-out.c:526
static void cli_mld_erase_entire_line(const struct match_list_displayer *displayer)
Definition cli-out.c:501
static void cli_mld_putch(const struct match_list_displayer *displayer, int ch)
Definition cli-out.c:475
static void cli_mld_beep(const struct match_list_displayer *displayer)
Definition cli-out.c:509
static int cli_mld_read_key(const struct match_list_displayer *displayer)
Definition cli-out.c:517
static void cli_mld_flush(const struct match_list_displayer *displayer)
Definition cli-out.c:491
static void cli_mld_crlf(const struct match_list_displayer *displayer)
Definition cli-out.c:467
EXTERN_C void _rl_erase_entire_line(void)
void gdb_display_match_list(char **matches, int len, int max, const struct match_list_displayer *displayer)
Definition completer.c:2947
mach_port_t kern_return_t mach_port_t mach_msg_type_name_t msgportsPoly mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int flags
Definition gnu-nat.c:1861
mld_puts_ftype * puts
Definition completer.h:51
mld_erase_entire_line_ftype * erase_entire_line
Definition completer.h:58
mld_read_key_ftype * read_key
Definition completer.h:64
mld_putch_ftype * putch
Definition completer.h:48
mld_beep_ftype * beep
Definition completer.h:61
mld_flush_ftype * flush
Definition completer.h:54
mld_crlf_ftype * crlf
Definition completer.h:45
bool input_interactive_p() const
Definition ui.c:97
Definition value.h:130
ui_out_type
Definition ui-out.h:70
ui_align
Definition ui-out.h:44
@ ui_noalign
Definition ui-out.h:48
@ ui_right
Definition ui-out.h:47
@ ui_left
Definition ui-out.h:45
struct ui * current_ui
Definition ui.c:35
void print_spaces(int n, struct ui_file *stream)
Definition utils.c:1968
bool pagination_enabled
Definition utils.c:122
void gdb_putc(int c)
Definition utils.c:1862
void gdb_printf(struct ui_file *stream, const char *format,...)
Definition utils.c:1886
int get_chars_per_line()
Definition utils.c:1506
void gdb_flush(struct ui_file *stream)
Definition utils.c:1498
void gdb_puts(const char *linebuffer, struct ui_file *stream)
Definition utils.c:1809
static unsigned int chars_per_line
Definition utils.c:1083