+2016-10-21 Tom Tromey <tom@tromey.com>
+
+ * common/scoped_restore.h: New file.
+ * utils.h: Include scoped_restore.h.
+ * top.c (execute_command_to_string): Use scoped_restore.
+ * python/python.c (python_interactive_command): Use
+ scoped_restore.
+ (python_command, execute_gdb_command): Likewise.
+ * printcmd.c (do_one_display): Use scoped_restore.
+ * mi/mi-main.c (exec_continue): Use scoped_restore.
+ * mi/mi-cmd-var.c (mi_cmd_var_assign): Use scoped_restore.
+ * linux-fork.c (checkpoint_command): Use scoped_restore.
+ * infrun.c (restore_execution_direction): Remove.
+ (fetch_inferior_event): Use scoped_restore.
+ * compile/compile.c (compile_file_command): Use
+ scoped_restore.
+ (compile_code_command, compile_print_command): Likewise.
+ * cli/cli-script.c (execute_user_command): Use
+ scoped_restore.
+ (while_command, if_command, script_from_file): Likewise.
+ * arm-tdep.c (arm_insert_single_step_breakpoint): Use
+ scoped_restore.
+
2016-10-21 Tom Tromey <tom@tromey.com>
* xcoffread.c (read_xcoff_symtab): Make "filestring" const.
struct address_space *aspace,
CORE_ADDR pc)
{
- struct cleanup *old_chain
- = make_cleanup_restore_integer (&arm_override_mode);
-
- arm_override_mode = IS_THUMB_ADDR (pc);
+ scoped_restore save_override_mode
+ = make_scoped_restore (&arm_override_mode,
+ (int) IS_THUMB_ADDR (pc));
pc = gdbarch_addr_bits_remove (gdbarch, pc);
insert_single_step_breakpoint (gdbarch, aspace, pc);
-
- do_cleanups (old_chain);
}
/* Given BUF, which is OLD_LEN bytes ending at ENDADDR, expand
not confused with Insight. */
in_user_command = 1;
- make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
command_nest_depth++;
while (cmdlines)
while_command (char *arg, int from_tty)
{
struct command_line *command = NULL;
- struct cleanup *old_chain;
control_level = 1;
command = get_command_line (while_control, arg);
if (command == NULL)
return;
- old_chain = make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
execute_control_command_untraced (command);
free_command_lines (&command);
-
- do_cleanups (old_chain);
}
/* "if" command support. Execute either the true or false arm depending
if (command == NULL)
return;
- old_chain = make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
execute_control_command_untraced (command);
free_command_lines (&command);
-
- do_cleanups (old_chain);
}
/* Cleanup */
source_line_number = 0;
source_file_name = file;
- make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
-
{
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
TRY
{
--- /dev/null
+/* scoped_restore, a simple class for saving and restoring a value
+
+ Copyright (C) 2016 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef SCOPED_RESTORE_H
+#define SCOPED_RESTORE_H
+
+/* Base class for scoped_restore_tmpl. */
+struct scoped_restore_base
+{
+};
+
+/* A convenience typedef. Users of make_scoped_restore declare the
+ local RAII object as having this type. */
+typedef const scoped_restore_base &scoped_restore;
+
+/* An RAII-based object that saves a variable's value, and then
+ restores it again when this object is destroyed. */
+template<typename T>
+class scoped_restore_tmpl : public scoped_restore_base
+{
+ public:
+
+ /* Create a new scoped_restore object that saves the current value
+ of *VAR. *VAR will be restored when this scoped_restore object
+ is destroyed. */
+ scoped_restore_tmpl (T *var)
+ : m_saved_var (var),
+ m_saved_value (*var)
+ {
+ }
+
+ /* Create a new scoped_restore object that saves the current value
+ of *VAR, and sets *VAR to VALUE. *VAR will be restored when this
+ scoped_restore object is destroyed. */
+ scoped_restore_tmpl (T *var, T value)
+ : m_saved_var (var),
+ m_saved_value (*var)
+ {
+ *var = value;
+ }
+
+ scoped_restore_tmpl (const scoped_restore_tmpl<T> &other)
+ : m_saved_var (other.m_saved_var),
+ m_saved_value (other.m_saved_value)
+ {
+ other.m_saved_var = NULL;
+ }
+
+ ~scoped_restore_tmpl ()
+ {
+ if (m_saved_var != NULL)
+ *m_saved_var = m_saved_value;
+ }
+
+ private:
+
+ /* No need for this. It is intentionally not defined anywhere. */
+ scoped_restore_tmpl &operator= (const scoped_restore_tmpl &);
+
+ /* The saved variable. */
+ mutable T *m_saved_var;
+
+ /* The saved value. */
+ const T m_saved_value;
+};
+
+/* Make a scoped_restore. This is useful because it lets template
+ argument deduction work. */
+template<typename T>
+scoped_restore_tmpl<T> make_scoped_restore (T *var)
+{
+ return scoped_restore_tmpl<T> (var);
+}
+
+/* Make a scoped_restore. This is useful because it lets template
+ argument deduction work. */
+template<typename T>
+scoped_restore_tmpl<T> make_scoped_restore (T *var, T value)
+{
+ return scoped_restore_tmpl<T> (var, value);
+}
+
+#endif /* SCOPED_RESTORE_H */
char *buffer;
struct cleanup *cleanup;
- cleanup = make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
/* Check the user did not just <enter> after command. */
if (arg == NULL)
arg = skip_spaces (arg);
arg = gdb_abspath (arg);
- make_cleanup (xfree, arg);
+ cleanup = make_cleanup (xfree, arg);
buffer = xstrprintf ("#include \"%s\"\n", arg);
make_cleanup (xfree, buffer);
eval_compile_command (NULL, buffer, scope, NULL);
static void
compile_code_command (char *arg, int from_tty)
{
- struct cleanup *cleanup;
enum compile_i_scope_types scope = COMPILE_I_SIMPLE_SCOPE;
- cleanup = make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
if (arg != NULL && check_raw_argument (&arg))
{
else
{
struct command_line *l = get_command_line (compile_control, "");
+ struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
- make_cleanup_free_command_lines (&l);
l->control_u.compile.scope = scope;
execute_control_command_untraced (l);
+ do_cleanups (cleanup);
}
-
- do_cleanups (cleanup);
}
/* Callback for compile_print_command. */
compile_print_command (char *arg_param, int from_tty)
{
const char *arg = arg_param;
- struct cleanup *cleanup;
enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE;
struct format_data fmt;
- cleanup = make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
/* Passing &FMT as SCOPE_DATA is safe as do_module_cleanup will not
touch the stale pointer if compile_object_run has already quit. */
else
{
struct command_line *l = get_command_line (compile_control, "");
+ struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
- make_cleanup_free_command_lines (&l);
l->control_u.compile.scope = scope;
l->control_u.compile.scope_data = &fmt;
execute_control_command_untraced (l);
+ do_cleanups (cleanup);
}
-
- do_cleanups (cleanup);
}
/* A cleanup function to remove a directory and all its contents. */
}
}
-/* A cleanup that restores the execution direction to the value saved
- in *ARG. */
-
-static void
-restore_execution_direction (void *arg)
-{
- enum exec_direction_kind *save_exec_dir = (enum exec_direction_kind *) arg;
-
- execution_direction = *save_exec_dir;
-}
-
/* Asynchronous version of wait_for_inferior. It is called by the
event loop whenever a change of state is detected on the file
descriptor corresponding to the target. It can be called more than
struct execution_control_state *ecs = &ecss;
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
struct cleanup *ts_old_chain;
- enum exec_direction_kind save_exec_dir = execution_direction;
int cmd_done = 0;
ptid_t waiton_ptid = minus_one_ptid;
event. */
target_dcache_invalidate ();
- make_cleanup (restore_execution_direction, &save_exec_dir);
- execution_direction = target_execution_direction ();
+ scoped_restore save_exec_dir
+ = make_scoped_restore (&execution_direction, target_execution_direction ());
ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
target_can_async_p () ? TARGET_WNOHANG : 0);
struct value *fork_fn = NULL, *ret;
struct fork_info *fp;
pid_t retpid;
- struct cleanup *old_chain;
if (!target_has_execution)
error (_("The program is not being run."));
ret = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
/* Tell linux-nat.c that we're checkpointing this inferior. */
- old_chain = make_cleanup_restore_integer (&checkpointing_pid);
- checkpointing_pid = ptid_get_pid (inferior_ptid);
+ {
+ scoped_restore save_pid
+ = make_scoped_restore (&checkpointing_pid, ptid_get_pid (inferior_ptid));
+
+ ret = call_function_by_hand (fork_fn, 0, &ret);
+ }
- ret = call_function_by_hand (fork_fn, 0, &ret);
- do_cleanups (old_chain);
if (!ret) /* Probably can't happen. */
error (_("checkpoint: call_function_by_hand returned null."));
struct ui_out *uiout = current_uiout;
struct varobj *var;
char *expression, *val;
- struct cleanup *cleanup;
if (argc != 2)
error (_("-var-assign: Usage: NAME EXPRESSION."));
/* MI command '-var-assign' may write memory, so suppress memory
changed notification if it does. */
- cleanup
- = make_cleanup_restore_integer (&mi_suppress_notification.memory);
- mi_suppress_notification.memory = 1;
+ scoped_restore save_suppress
+ = make_scoped_restore (&mi_suppress_notification.memory, 1);
if (!varobj_set_value (var, expression))
error (_("-var-assign: Could not assign "
val = varobj_get_value (var);
ui_out_field_string (uiout, "value", val);
xfree (val);
-
- do_cleanups (cleanup);
}
/* Type used for parameters passing to mi_cmd_var_update_iter. */
}
else
{
- struct cleanup *back_to = make_cleanup_restore_integer (&sched_multi);
+ scoped_restore save_multi = make_scoped_restore (&sched_multi);
if (current_context->all)
{
same. */
continue_1 (1);
}
- do_cleanups (back_to);
}
}
static void
do_one_display (struct display *d)
{
- struct cleanup *old_chain;
int within_current_scope;
if (d->enabled_p == 0)
if (!within_current_scope)
return;
- old_chain = make_cleanup_restore_integer (¤t_display_number);
- current_display_number = d->number;
+ scoped_restore save_display_number
+ = make_scoped_restore (¤t_display_number, d->number);
annotate_display_begin ();
printf_filtered ("%d", d->number);
annotate_display_end ();
gdb_flush (gdb_stdout);
- do_cleanups (old_chain);
}
/* Display all of the values on the auto-display chain which can be
python_interactive_command (char *arg, int from_tty)
{
struct ui *ui = current_ui;
- struct cleanup *cleanup;
int err;
- cleanup = make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
arg = skip_spaces (arg);
gdbpy_print_stack ();
error (_("Error while executing Python code."));
}
-
- do_cleanups (cleanup);
}
/* A wrapper around PyRun_SimpleFile. FILE is the Python script to run
cleanup = ensure_python_env (get_current_arch (), current_language);
- make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
arg = skip_spaces (arg);
if (arg && *arg)
struct cleanup *cleanup = make_cleanup (xfree, copy);
struct interp *interp;
- make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
make_cleanup_restore_current_uiout ();
restoration callbacks. */
cleanup = set_batch_flag_and_make_cleanup_restore_page_info ();
- make_cleanup_restore_integer (¤t_ui->async);
- current_ui->async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
str_file = mem_fileopen ();
#define UTILS_H
#include "exceptions.h"
+#include "common/scoped_restore.h"
extern void initialize_utils (void);