diff options
author | Tom Tromey <tom@tromey.com> | 2020-12-16 18:18:40 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2020-12-16 18:18:40 +0100 |
commit | 2f2287318b33ddf855a692fcc191f6b25caf4644 (patch) | |
tree | a4ed9af701499455d0eb659a29e912117b565a1e /gdb/cli-out.c | |
parent | 1e61189d0ab0905178002120eb0a380858ed6dc0 (diff) | |
download | gdb-2f2287318b33ddf855a692fcc191f6b25caf4644.zip gdb-2f2287318b33ddf855a692fcc191f6b25caf4644.tar.gz gdb-2f2287318b33ddf855a692fcc191f6b25caf4644.tar.bz2 |
[gdb/cli] Add a progress meter
Add a progress meter. It's not used anywhere yet.
gdb/ChangeLog:
2020-12-16 Tom Tromey <tom@tromey.com>
Tom Tromey <tromey@redhat.com>
Tom de Vries <tdevries@suse.de>
* utils.h (get_chars_per_line): Declare.
* utils.c (get_chars_per_line): New function.
(fputs_maybe_filtered): Handle '\r'.
* ui-out.h (ui_out::progress_meter): New class.
(ui_out::progress, ui_out::do_progress_start)
(ui_out::do_progress_notify, ui_out::do_progress_end): New
methods.
* ui-out.c (do_progress_end)
(make_cleanup_ui_out_progress_begin_end, ui_out_progress): New
functions.
* mi/mi-out.h (mi_ui_out::do_progress_start)
(mi_ui_out::do_progress_notify, mi_ui_out::do_progress_end): New
methods.
* cli-out.h (struct cli_ui_out) <do_progress_start,
do_progress_notify, do_progress_end>: New methods.
<enum meter_stat, struct cli_progress_info>: New.
<m_meters>: New member.
* cli-out.c (cli_ui_out::do_progress_start)
(cli_ui_out::do_progress_notify, cli_ui_out::do_progress_end): New
methods.
Diffstat (limited to 'gdb/cli-out.c')
-rw-r--r-- | gdb/cli-out.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/gdb/cli-out.c b/gdb/cli-out.c index e47272a..7722ecc 100644 --- a/gdb/cli-out.c +++ b/gdb/cli-out.c @@ -265,6 +265,107 @@ cli_ui_out::do_redirect (ui_file *outstream) m_streams.pop_back (); } +/* The cli_ui_out::do_progress_* functions result in the following: + - printed for tty, SHOULD_PRINT == true: + <NAME + [##### ]\r> + - printed for tty, SHOULD_PRINT == false: + <> + - printed for not-a-tty: + <NAME...done. + > +*/ + +void +cli_ui_out::do_progress_start (const std::string &name, bool should_print) +{ + struct ui_file *stream = m_streams.back (); + cli_progress_info meter; + + meter.last_value = 0; + meter.name = name; + if (!stream->isatty ()) + { + fprintf_unfiltered (stream, "%s...", meter.name.c_str ()); + gdb_flush (stream); + meter.printing = WORKING; + } + else + { + /* Don't actually emit anything until the first call notifies us + of progress. This makes it so a second progress message can + be started before the first one has been notified, without + messy output. */ + meter.printing = should_print ? START : NO_PRINT; + } + + m_meters.push_back (std::move (meter)); +} + +void +cli_ui_out::do_progress_notify (double howmuch) +{ + struct ui_file *stream = m_streams.back (); + cli_progress_info &meter (m_meters.back ()); + + if (meter.printing == NO_PRINT) + return; + + if (meter.printing == START) + { + fprintf_unfiltered (stream, "%s\n", meter.name.c_str ()); + gdb_flush (stream); + meter.printing = WORKING; + } + + if (meter.printing == WORKING && howmuch >= 1.0) + return; + + if (!stream->isatty ()) + return; + + int chars_per_line = get_chars_per_line (); + if (chars_per_line > 0) + { + int i, max; + int width = chars_per_line - 3; + + max = width * howmuch; + fprintf_unfiltered (stream, "\r["); + for (i = 0; i < width; ++i) + fprintf_unfiltered (stream, i < max ? "#" : " "); + fprintf_unfiltered (stream, "]"); + gdb_flush (stream); + meter.printing = PROGRESS; + } +} + +void +cli_ui_out::do_progress_end () +{ + struct ui_file *stream = m_streams.back (); + cli_progress_info &meter = m_meters.back (); + + if (!stream->isatty ()) + { + fprintf_unfiltered (stream, "done.\n"); + gdb_flush (stream); + } + else if (meter.printing == PROGRESS) + { + int i; + int width = get_chars_per_line () - 3; + + fprintf_unfiltered (stream, "\r"); + for (i = 0; i < width + 2; ++i) + fprintf_unfiltered (stream, " "); + fprintf_unfiltered (stream, "\r"); + gdb_flush (stream); + } + + m_meters.pop_back (); +} + /* local functions */ void |