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
This commit is contained in:
Tom Tromey
2020-02-22 11:48:26 -07:00
parent fdb01f0ce4
commit 0240c8f11b
2 changed files with 77 additions and 32 deletions

View File

@ -1,3 +1,13 @@
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> 2020-02-22 Tom Tromey <tom@tromey.com>
* tui/tui.h (enum tui_win_type) <LOCATOR_WIN, DATA_ITEM_WIN>: * tui/tui.h (enum tui_win_type) <LOCATOR_WIN, DATA_ITEM_WIN>:

View File

@ -29,6 +29,7 @@
#include "cli/cli-decode.h" #include "cli/cli-decode.h"
#include "cli/cli-utils.h" #include "cli/cli-utils.h"
#include <ctype.h> #include <ctype.h>
#include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include "tui/tui.h" #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. */ /* Helper function that returns a TUI window, given its name. */
static tui_gen_win_info * static tui_gen_win_info *
tui_get_window_by_name (const std::string &name) tui_get_window_by_name (const std::string &name)
{ {
if (name == "src") for (tui_win_info *window : saved_tui_windows)
{ if (name == window->name ())
if (tui_win_list[SRC_WIN] == nullptr) return window;
tui_win_list[SRC_WIN] = new tui_source_window ();
return tui_win_list[SRC_WIN]; auto iter = known_window_types->find (name);
} if (iter == known_window_types->end ())
else if (name == "cmd") error (_("Unknown window type \"%s\""), name.c_str ());
{
if (tui_win_list[CMD_WIN] == nullptr) tui_gen_win_info *result = iter->second (name.c_str ());
tui_win_list[CMD_WIN] = new tui_cmd_window (); if (result == nullptr)
return tui_win_list[CMD_WIN]; error (_("Could not create window \"%s\""), name.c_str ());
} return result;
else if (name == "regs") }
{
if (tui_win_list[DATA_WIN] == nullptr) /* Initialize the known window types. */
tui_win_list[DATA_WIN] = new tui_data_window ();
return tui_win_list[DATA_WIN]; static void
} initialize_known_windows ()
else if (name == "asm") {
{ known_window_types = new std::unordered_map<std::string, window_factory>;
if (tui_win_list[DISASSEM_WIN] == nullptr)
tui_win_list[DISASSEM_WIN] = new tui_disasm_window (); known_window_types->emplace ("src",
return tui_win_list[DISASSEM_WIN]; make_standard_window<SRC_WIN,
} tui_source_window>);
else known_window_types->emplace ("cmd",
{ make_standard_window<CMD_WIN, tui_cmd_window>);
gdb_assert (name == "status"); known_window_types->emplace ("regs",
return tui_locator_win_info_ptr (); 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. */ /* See tui-layout.h. */
@ -886,9 +921,8 @@ initialize_layouts ()
static bool static bool
validate_window_name (const std::string &name) validate_window_name (const std::string &name)
{ {
return (name == "src" || name == "cmd" auto iter = known_window_types->find (name);
|| name == "regs" || name == "asm" return iter != known_window_types->end ();
|| name == "status");
} }
/* Implementation of the "tui new-layout" command. */ /* Implementation of the "tui new-layout" command. */
@ -1023,4 +1057,5 @@ to be allocated to the window."),
tui_get_cmd_list ()); tui_get_cmd_list ());
initialize_layouts (); initialize_layouts ();
initialize_known_windows ();
} }