summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2020-02-22 11:48:26 -0700
committerTom Tromey <tom@tromey.com>2020-02-22 11:48:38 -0700
commit0240c8f11b06a33a043bacbe2b9e723ae6ad573c (patch)
treee49c7e36b94e02187f30bf53047ac9f867ecee73
parentfdb01f0ce44653180af9d3d4f264c0ddb2d1261d (diff)
downloadbinutils-gdb-0240c8f11b06a33a043bacbe2b9e723ae6ad573c.tar.gz
Change how TUI windows are instantiated
This adds a new global that maps from window names to window constructor functions, and then changes tui_get_window_by_name and validate_window_name to use it. This is another step toward user-defined window types. gdb/ChangeLog 2020-02-22 Tom Tromey <tom@tromey.com> * tui/tui-layout.c (make_standard_window, get_locator_window): New functions. (known_window_types): New global. (tui_get_window_by_name): Reimplement. (initialize_known_windows): New function. (validate_window_name): Rewrite. (_initialize_tui_layout): Call initialize_known_windows. Change-Id: I9037aac550299b9d945899220a30c2d3af9dd0de
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/tui/tui-layout.c99
2 files changed, 77 insertions, 32 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index dc54fc40e63..fe869278263 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2020-02-22 Tom Tromey <tom@tromey.com>
+ * tui/tui-layout.c (make_standard_window, get_locator_window): New
+ functions.
+ (known_window_types): New global.
+ (tui_get_window_by_name): Reimplement.
+ (initialize_known_windows): New function.
+ (validate_window_name): Rewrite.
+ (_initialize_tui_layout): Call initialize_known_windows.
+
+2020-02-22 Tom Tromey <tom@tromey.com>
+
* tui/tui.h (enum tui_win_type) <LOCATOR_WIN, DATA_ITEM_WIN>:
Remove constants.
* tui/tui-winsource.h (struct tui_source_window_base)
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index c27a8d086e2..748a1067295 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -29,6 +29,7 @@
#include "cli/cli-decode.h"
#include "cli/cli-utils.h"
#include <ctype.h>
+#include <unordered_map>
#include <unordered_set>
#include "tui/tui.h"
@@ -322,40 +323,74 @@ tui_gen_win_info::resize (int height_, int width_,
+/* Helper function to create one of the built-in (non-locator)
+ windows. */
+
+template<enum tui_win_type V, class T>
+static tui_gen_win_info *
+make_standard_window (const char *)
+{
+ if (tui_win_list[V] == nullptr)
+ tui_win_list[V] = new T ();
+ return tui_win_list[V];
+}
+
+/* Helper function to wrap tui_locator_win_info_ptr for
+ tui_get_window_by_name. */
+
+static tui_gen_win_info *
+get_locator_window (const char *)
+{
+ return tui_locator_win_info_ptr ();
+}
+
+/* A map holding all the known window types, keyed by name. Note that
+ this is heap-allocated and "leaked" at gdb exit. This avoids
+ ordering issues with destroying elements in the map at shutdown.
+ In particular, destroying this map can occur after Python has been
+ shut down, causing crashes if any window destruction requires
+ running Python code. */
+
+static std::unordered_map<std::string, window_factory> *known_window_types;
+
/* Helper function that returns a TUI window, given its name. */
static tui_gen_win_info *
tui_get_window_by_name (const std::string &name)
{
- if (name == "src")
- {
- if (tui_win_list[SRC_WIN] == nullptr)
- tui_win_list[SRC_WIN] = new tui_source_window ();
- return tui_win_list[SRC_WIN];
- }
- else if (name == "cmd")
- {
- if (tui_win_list[CMD_WIN] == nullptr)
- tui_win_list[CMD_WIN] = new tui_cmd_window ();
- return tui_win_list[CMD_WIN];
- }
- else if (name == "regs")
- {
- if (tui_win_list[DATA_WIN] == nullptr)
- tui_win_list[DATA_WIN] = new tui_data_window ();
- return tui_win_list[DATA_WIN];
- }
- else if (name == "asm")
- {
- if (tui_win_list[DISASSEM_WIN] == nullptr)
- tui_win_list[DISASSEM_WIN] = new tui_disasm_window ();
- return tui_win_list[DISASSEM_WIN];
- }
- else
- {
- gdb_assert (name == "status");
- return tui_locator_win_info_ptr ();
- }
+ for (tui_win_info *window : saved_tui_windows)
+ if (name == window->name ())
+ return window;
+
+ auto iter = known_window_types->find (name);
+ if (iter == known_window_types->end ())
+ error (_("Unknown window type \"%s\""), name.c_str ());
+
+ tui_gen_win_info *result = iter->second (name.c_str ());
+ if (result == nullptr)
+ error (_("Could not create window \"%s\""), name.c_str ());
+ return result;
+}
+
+/* Initialize the known window types. */
+
+static void
+initialize_known_windows ()
+{
+ known_window_types = new std::unordered_map<std::string, window_factory>;
+
+ known_window_types->emplace ("src",
+ make_standard_window<SRC_WIN,
+ tui_source_window>);
+ known_window_types->emplace ("cmd",
+ make_standard_window<CMD_WIN, tui_cmd_window>);
+ known_window_types->emplace ("regs",
+ make_standard_window<DATA_WIN,
+ tui_data_window>);
+ known_window_types->emplace ("asm",
+ make_standard_window<DISASSEM_WIN,
+ tui_disasm_window>);
+ known_window_types->emplace ("status", get_locator_window);
}
/* See tui-layout.h. */
@@ -886,9 +921,8 @@ initialize_layouts ()
static bool
validate_window_name (const std::string &name)
{
- return (name == "src" || name == "cmd"
- || name == "regs" || name == "asm"
- || name == "status");
+ auto iter = known_window_types->find (name);
+ return iter != known_window_types->end ();
}
/* Implementation of the "tui new-layout" command. */
@@ -1023,4 +1057,5 @@ to be allocated to the window."),
tui_get_cmd_list ());
initialize_layouts ();
+ initialize_known_windows ();
}