/* General utility routines for GDB, the GNU debugger.
- Copyright (C) 1986-2016 Free Software Foundation, Inc.
+ Copyright (C) 1986-2017 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "dyn-string.h"
#include <ctype.h>
#include "gdb_wait.h"
#include "event-top.h"
#endif
#include <signal.h>
-#include "timeval-utils.h"
#include "gdbcmd.h"
#include "serial.h"
#include "bfd.h"
#include "readline/readline.h"
-#include "gdb_sys_time.h"
-#include <time.h>
+#include <chrono>
#include "gdb_usleep.h"
#include "interps.h"
Modified in prompt_for_continue and defaulted_query.
Used in report_command_stats. */
-static struct timeval prompt_for_continue_wait_time;
+static std::chrono::steady_clock::duration prompt_for_continue_wait_time;
/* A flag indicating whether to timestamp debugging messages. */
return make_cleanup (do_freeargv, arg);
}
-static void
-do_dyn_string_delete (void *arg)
-{
- dyn_string_delete ((dyn_string_t) arg);
-}
-
-struct cleanup *
-make_cleanup_dyn_string_delete (dyn_string_t arg)
-{
- return make_cleanup (do_dyn_string_delete, arg);
-}
-
static void
do_bfd_close_cleanup (void *arg)
{
{
struct ui_out *uiout = (struct ui_out *) arg;
- if (ui_out_redirect (uiout, NULL) < 0)
- warning (_("Cannot restore redirection of the current output protocol"));
+ uiout->redirect (NULL);
}
/* Return a new cleanup that pops the last redirection by ui_out_redirect
return make_cleanup (do_htab_delete_cleanup, htab);
}
-struct restore_ui_out_closure
-{
- struct ui_out **variable;
- struct ui_out *value;
-};
-
-static void
-do_restore_ui_out (void *p)
-{
- struct restore_ui_out_closure *closure
- = (struct restore_ui_out_closure *) p;
-
- *(closure->variable) = closure->value;
-}
-
-/* Remember the current value of *VARIABLE and make it restored when
- the cleanup is run. */
-
-struct cleanup *
-make_cleanup_restore_ui_out (struct ui_out **variable)
-{
- struct restore_ui_out_closure *c = XNEW (struct restore_ui_out_closure);
-
- c->variable = variable;
- c->value = *variable;
-
- return make_cleanup_dtor (do_restore_ui_out, (void *) c, xfree);
-}
-
-struct restore_ui_file_closure
-{
- struct ui_file **variable;
- struct ui_file *value;
-};
-
-static void
-do_restore_ui_file (void *p)
-{
- struct restore_ui_file_closure *closure
- = (struct restore_ui_file_closure *) p;
-
- *(closure->variable) = closure->value;
-}
-
-/* Remember the current value of *VARIABLE and make it restored when
- the cleanup is run. */
-
-struct cleanup *
-make_cleanup_restore_ui_file (struct ui_file **variable)
-{
- struct restore_ui_file_closure *c = XNEW (struct restore_ui_file_closure);
-
- c->variable = variable;
- c->value = *variable;
-
- return make_cleanup_dtor (do_restore_ui_file, (void *) c, xfree);
-}
-
/* Helper for make_cleanup_value_free_to_mark. */
static void
void
error_stream (struct ui_file *stream)
{
- char *message = ui_file_xstrdup (stream, NULL);
+ std::string message = ui_file_as_string (stream);
- make_cleanup (xfree, message);
- error (("%s"), message);
+ error (("%s"), message.c_str ());
}
/* Emit a message and abort. */
return make_regfree_cleanup (pattern);
}
+/* A cleanup that simply calls ui_unregister_input_event_handler. */
+
+static void
+ui_unregister_input_event_handler_cleanup (void *ui)
+{
+ ui_unregister_input_event_handler ((struct ui *) ui);
+}
+
+/* Set up to handle input. */
+
+static struct cleanup *
+prepare_to_handle_input (void)
+{
+ struct cleanup *old_chain;
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours ();
+
+ ui_register_input_event_handler (current_ui);
+ if (current_ui->prompt_state == PROMPT_BLOCKED)
+ make_cleanup (ui_unregister_input_event_handler_cleanup, current_ui);
+
+ make_cleanup_override_quit_handler (default_quit_handler);
+
+ return old_chain;
+}
+
\f
/* This function supports the query, nquery, and yquery functions.
int def_value;
char def_answer, not_def_answer;
char *y_string, *n_string, *question, *prompt;
- /* Used to add duration we waited for user to respond to
- prompt_for_continue_wait_time. */
- struct timeval prompt_started, prompt_ended, prompt_delta;
struct cleanup *old_chain;
/* Set up according to which answer is the default. */
if (!confirm || server_command)
return def_value;
- old_chain = make_cleanup_restore_target_terminal ();
-
/* If input isn't coming from the user directly, just say what
question we're asking, and then answer the default automatically. This
way, important error messages don't get lost when talking to GDB
if (current_ui->instream != current_ui->stdin_stream
|| !input_interactive_p (current_ui))
{
+ old_chain = make_cleanup_restore_target_terminal ();
+
target_terminal_ours_for_output ();
wrap_here ("");
vfprintf_filtered (gdb_stdout, ctlstr, args);
{
int res;
+ old_chain = make_cleanup_restore_target_terminal ();
res = deprecated_query_hook (ctlstr, args);
do_cleanups (old_chain);
return res;
/* Format the question outside of the loop, to avoid reusing args. */
question = xstrvprintf (ctlstr, args);
- make_cleanup (xfree, question);
+ old_chain = make_cleanup (xfree, question);
prompt = xstrprintf (_("%s%s(%s or %s) %s"),
annotation_level > 1 ? "\n\032\032pre-query\n" : "",
question, y_string, n_string,
annotation_level > 1 ? "\n\032\032query\n" : "");
make_cleanup (xfree, prompt);
- /* Used for calculating time spend waiting for user. */
- gettimeofday (&prompt_started, NULL);
+ /* Used to add duration we waited for user to respond to
+ prompt_for_continue_wait_time. */
+ using namespace std::chrono;
+ steady_clock::time_point prompt_started = steady_clock::now ();
- /* We'll need to handle input. */
- target_terminal_ours ();
- make_cleanup_override_quit_handler (default_quit_handler);
+ prepare_to_handle_input ();
while (1)
{
}
/* Add time spend in this routine to prompt_for_continue_wait_time. */
- gettimeofday (&prompt_ended, NULL);
- timeval_sub (&prompt_delta, &prompt_ended, &prompt_started);
- timeval_add (&prompt_for_continue_wait_time,
- &prompt_for_continue_wait_time, &prompt_delta);
+ prompt_for_continue_wait_time += steady_clock::now () - prompt_started;
if (annotation_level > 1)
printf_filtered (("\n\032\032post-query\n"));
/* String to indent by if the wrap occurs. Must not be NULL if wrap_column
is non-zero. */
-static char *wrap_indent;
+static const char *wrap_indent;
/* Column number on the screen where wrap_buffer begins, or 0 if wrapping
is not in effect. */
static int wrap_column;
\f
-/* Inialize the number of lines per page and chars per line. */
+/* Initialize the number of lines per page and chars per line. */
void
init_page_info (void)
{
char *ignore;
char cont_prompt[120];
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
/* Used to add duration we waited for user to respond to
prompt_for_continue_wait_time. */
- struct timeval prompt_started, prompt_ended, prompt_delta;
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
-
- gettimeofday (&prompt_started, NULL);
+ using namespace std::chrono;
+ steady_clock::time_point prompt_started = steady_clock::now ();
if (annotation_level > 1)
printf_unfiltered (("\n\032\032pre-prompt-for-continue\n"));
beyond the end of the screen. */
reinitialize_more_filter ();
- /* We'll need to handle input. */
- make_cleanup_restore_target_terminal ();
- target_terminal_ours ();
- make_cleanup_override_quit_handler (default_quit_handler);
+ prepare_to_handle_input ();
/* Call gdb_readline_wrapper, not readline, in order to keep an
event loop running. */
make_cleanup (xfree, ignore);
/* Add time spend in this routine to prompt_for_continue_wait_time. */
- gettimeofday (&prompt_ended, NULL);
- timeval_sub (&prompt_delta, &prompt_ended, &prompt_started);
- timeval_add (&prompt_for_continue_wait_time,
- &prompt_for_continue_wait_time, &prompt_delta);
+ prompt_for_continue_wait_time += steady_clock::now () - prompt_started;
if (annotation_level > 1)
printf_unfiltered (("\n\032\032post-prompt-for-continue\n"));
do_cleanups (old_chain);
}
-/* Initalize timer to keep track of how long we waited for the user. */
+/* Initialize timer to keep track of how long we waited for the user. */
void
reset_prompt_for_continue_wait_time (void)
{
- static const struct timeval zero_timeval = { 0 };
+ using namespace std::chrono;
- prompt_for_continue_wait_time = zero_timeval;
+ prompt_for_continue_wait_time = steady_clock::duration::zero ();
}
/* Fetch the cumulative time spent in prompt_for_continue. */
-struct timeval
-get_prompt_for_continue_wait_time (void)
+std::chrono::steady_clock::duration
+get_prompt_for_continue_wait_time ()
{
return prompt_for_continue_wait_time;
}
used to force out output from the wrap_buffer. */
void
-wrap_here (char *indent)
+wrap_here (const char *indent)
{
/* This should have been allocated, but be paranoid anyway. */
if (!wrap_buffer)
|| batch_flag
|| (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
|| top_level_interpreter () == NULL
- || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
+ || interp_ui_out (top_level_interpreter ())->is_mi_like_p ())
{
fputs_unfiltered (linebuffer, stream);
return;
old_cleanups = make_cleanup (xfree, linebuffer);
if (debug_timestamp && stream == gdb_stdlog)
{
- struct timeval tm;
- char *timestamp;
+ using namespace std::chrono;
int len, need_nl;
- gettimeofday (&tm, NULL);
+ steady_clock::time_point now = steady_clock::now ();
+ seconds s = duration_cast<seconds> (now.time_since_epoch ());
+ microseconds us = duration_cast<microseconds> (now.time_since_epoch () - s);
len = strlen (linebuffer);
need_nl = (len > 0 && linebuffer[len - 1] != '\n');
- timestamp = xstrprintf ("%ld:%ld %s%s",
- (long) tm.tv_sec, (long) tm.tv_usec,
- linebuffer,
- need_nl ? "\n": "");
- make_cleanup (xfree, timestamp);
- fputs_unfiltered (timestamp, stream);
+ std::string timestamp = string_printf ("%ld.%06ld %s%s",
+ (long) s.count (),
+ (long) us.count (),
+ linebuffer, need_nl ? "\n": "");
+ fputs_unfiltered (timestamp.c_str (), stream);
}
else
fputs_unfiltered (linebuffer, stream);
if (minor == NULL)
minor = &min;
- /* Skip any identifier after "GNU " - such as "C11" "C++" or "Java".
+ /* Skip any identifier after "GNU " - such as "C11" or "C++".
A full producer string might look like:
"GNU C 4.7.2"
"GNU Fortran 4.8.2 20140120 (Red Hat 4.8.2-16) -mtune=generic ..."