From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH 09/24] Allow TUI sub-layouts in "new-layout" command
Date: Sat, 04 Jan 2020 18:34:00 -0000 [thread overview]
Message-ID: <20200104183410.17114-10-tom@tromey.com> (raw)
In-Reply-To: <20200104183410.17114-1-tom@tromey.com>
The new TUI layout engine has support for "sub-layouts" -- this is a
layout that includes another layout as a child. A sub-layout is
treated as a unit when allocating space.
There's not a very strong reason to use sub-layouts currently. This
patch exists to introduce the idea, and to simplify the subsequent
patch that adds horizontal layouts -- where sub-layouts are needed.
Because this patch won't go in on its own, I chose to defer
documenting this change until the subsequent horizontal layout patch.
gdb/ChangeLog
2020-01-04 Tom Tromey <tom@tromey.com>
* tui/tui-layout.h (class tui_layout_split) <add_split>: Change
parameter and return types.
(class tui_layout_base) <specification>: Add "depth".
(class tui_layout_window) <specification>: Add "depth".
(class tui_layout_split) <specification>: Add "depth".
* tui/tui-layout.c (tui_layout_split::add_split): Change parameter
and return types.
(tui_new_layout_command): Parse sub-layouts.
(_initialize_tui_layout): Update help string.
(tui_layout_window::specification): Add "depth".
(add_layout_command): Update.
gdb/testsuite/ChangeLog
2020-01-04 Tom Tromey <tom@tromey.com>
* gdb.tui/new-layout.exp: Add sub-layout tests.
Change-Id: Iddf52d067a552c168b8a67f29caf7ac86404b10c
---
gdb/ChangeLog | 14 +++++
gdb/testsuite/ChangeLog | 4 ++
gdb/testsuite/gdb.tui/new-layout.exp | 11 ++++
gdb/tui/tui-layout.c | 84 +++++++++++++++++++++-------
gdb/tui/tui-layout.h | 11 ++--
5 files changed, 100 insertions(+), 24 deletions(-)
diff --git a/gdb/testsuite/gdb.tui/new-layout.exp b/gdb/testsuite/gdb.tui/new-layout.exp
index 8475a9db295..406d9b25f08 100644
--- a/gdb/testsuite/gdb.tui/new-layout.exp
+++ b/gdb/testsuite/gdb.tui/new-layout.exp
@@ -35,12 +35,23 @@ gdb_test "tui new-layout example src 1 src 1" \
"Window \"src\" seen twice in layout"
gdb_test "tui new-layout example src 1" \
"New layout does not contain the \"cmd\" window"
+gdb_test "tui new-layout example src 1}" \
+ "Extra '}' in layout specification"
+gdb_test "tui new-layout example {src 1} 1}" \
+ "Extra '}' in layout specification"
+gdb_test "tui new-layout example {src 1" \
+ "Missing '}' in layout specification"
gdb_test_no_output "tui new-layout example asm 1 locator 0 cmd 1"
gdb_test "help layout example" \
"Apply the \"example\" layout.*tui new-layout example asm 1 locator 0 cmd 1"
+gdb_test_no_output "tui new-layout example2 {asm 1 locator 0} 1 cmd 1"
+
+gdb_test "help layout example2" \
+ "Apply the \"example2\" layout.*tui new-layout example2 {asm 1 locator 0} 1 cmd 1"
+
if {![Term::enter_tui]} {
unsupported "TUI not supported"
}
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index 438a3a03828..3604d7e06bc 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -400,20 +400,19 @@ tui_layout_window::replace_window (const char *name, const char *new_window)
/* See tui-layout.h. */
void
-tui_layout_window::specification (ui_file *output)
+tui_layout_window::specification (ui_file *output, int depth)
{
fputs_unfiltered (get_name (), output);
}
/* See tui-layout.h. */
-tui_layout_split *
-tui_layout_split::add_split (int weight)
+void
+tui_layout_split::add_split (std::unique_ptr<tui_layout_split> &&layout,
+ int weight)
{
- tui_layout_split *result = new tui_layout_split ();
- split s = {weight, std::unique_ptr<tui_layout_base> (result)};
+ split s = {weight, std::move (layout)};
m_splits.push_back (std::move (s));
- return result;
}
/* See tui-layout.h. */
@@ -711,17 +710,23 @@ tui_layout_split::replace_window (const char *name, const char *new_window)
/* See tui-layout.h. */
void
-tui_layout_split::specification (ui_file *output)
+tui_layout_split::specification (ui_file *output, int depth)
{
+ if (depth > 0)
+ fputs_unfiltered ("{", output);
+
bool first = true;
for (auto &item : m_splits)
{
if (!first)
fputs_unfiltered (" ", output);
first = false;
- item.layout->specification (output);
+ item.layout->specification (output, depth + 1);
fprintf_unfiltered (output, " %d", item.weight);
}
+
+ if (depth > 0)
+ fputs_unfiltered ("}", output);
}
/* Destroy the layout associated with SELF. */
@@ -746,7 +751,7 @@ add_layout_command (const char *name, tui_layout_split *layout)
struct cmd_list_element *cmd;
string_file spec;
- layout->specification (&spec);
+ layout->specification (&spec, 0);
gdb::unique_xmalloc_ptr<char> doc
(xstrprintf (_("Apply the \"%s\" layout.\n\
@@ -833,23 +838,60 @@ tui_new_layout_command (const char *spec, int from_tty)
if (new_name[0] == '-')
error (_("Layout name cannot start with '-'"));
- std::unique_ptr<tui_layout_split> new_layout (new tui_layout_split);
+ std::vector<std::unique_ptr<tui_layout_split>> splits;
+ splits.emplace_back (new tui_layout_split);
std::unordered_set<std::string> seen_windows;
while (true)
{
- std::string name = extract_arg (&spec);
- if (name.empty ())
+ spec = skip_spaces (spec);
+ if (spec[0] == '\0')
break;
- if (!validate_window_name (name))
- error (_("Unknown window \"%s\""), name.c_str ());
- if (seen_windows.find (name) != seen_windows.end ())
- error (_("Window \"%s\" seen twice in layout"), name.c_str ());
- ULONGEST weight = get_ulongest (&spec);
+
+ if (spec[0] == '{')
+ {
+ splits.emplace_back (new tui_layout_split);
+ ++spec;
+ continue;
+ }
+
+ bool is_close = false;
+ std::string name;
+ if (spec[0] == '}')
+ {
+ is_close = true;
+ ++spec;
+ if (splits.size () == 1)
+ error (_("Extra '}' in layout specification"));
+ }
+ else
+ {
+ name = extract_arg (&spec);
+ if (name.empty ())
+ break;
+ if (!validate_window_name (name))
+ error (_("Unknown window \"%s\""), name.c_str ());
+ if (seen_windows.find (name) != seen_windows.end ())
+ error (_("Window \"%s\" seen twice in layout"), name.c_str ());
+ }
+
+ ULONGEST weight = get_ulongest (&spec, '}');
if ((int) weight != weight)
error (_("Weight out of range: %s"), pulongest (weight));
- new_layout->add_window (name.c_str (), weight);
- seen_windows.insert (name);
+ if (is_close)
+ {
+ std::unique_ptr<tui_layout_split> last_split
+ = std::move (splits.back ());
+ splits.pop_back ();
+ splits.back ()->add_split (std::move (last_split), weight);
+ }
+ else
+ {
+ splits.back ()->add_window (name.c_str (), weight);
+ seen_windows.insert (name);
+ }
}
+ if (splits.size () > 1)
+ error (_("Missing '}' in layout specification"));
if (seen_windows.empty ())
error (_("New layout does not contain any windows"));
if (seen_windows.find ("cmd") == seen_windows.end ())
@@ -857,6 +899,7 @@ tui_new_layout_command (const char *spec, int from_tty)
gdb::unique_xmalloc_ptr<char> cmd_name
= make_unique_xstrdup (new_name.c_str ());
+ std::unique_ptr<tui_layout_split> new_layout = std::move (splits.back ());
struct cmd_list_element *cmd
= add_layout_command (cmd_name.get (), new_layout.get ());
cmd->name_allocated = 1;
@@ -899,6 +942,9 @@ Usage: tui new-layout NAME WINDOW WEIGHT [WINDOW WEIGHT]...\n\
Create a new TUI layout. The new layout will be named NAME,\n\
and can be accessed using \"layout NAME\".\n\
The windows will be displayed in the specified order.\n\
+A WINDOW can also be of the form:\n\
+ { NAME WEIGHT [NAME WEIGHT]... }\n\
+This form indicates a sub-frame.\n\
Each WEIGHT is an integer, which holds the relative size\n\
to be allocated to the window."),
tui_get_cmd_list ());
diff --git a/gdb/tui/tui-layout.h b/gdb/tui/tui-layout.h
index c2249a783f8..4351e260720 100644
--- a/gdb/tui/tui-layout.h
+++ b/gdb/tui/tui-layout.h
@@ -74,8 +74,9 @@ public:
NEW_WINDOW. */
virtual void replace_window (const char *name, const char *new_window) = 0;
- /* Append the specification to this window to OUTPUT. */
- virtual void specification (ui_file *output) = 0;
+ /* Append the specification to this window to OUTPUT. DEPTH is the
+ depth of this layout in the hierarchy (zero-based). */
+ virtual void specification (ui_file *output, int depth) = 0;
/* The most recent space allocation. */
int x = 0;
@@ -125,7 +126,7 @@ public:
void replace_window (const char *name, const char *new_window) override;
- void specification (ui_file *output) override;
+ void specification (ui_file *output, int depth) override;
protected:
@@ -153,7 +154,7 @@ public:
/* Add a new split layout to this layout. WEIGHT is the desired
size, which is relative to the other weights given in this
layout. */
- tui_layout_split *add_split (int weight);
+ void add_split (std::unique_ptr<tui_layout_split> &&layout, int weight);
/* Add a new window to this layout. NAME is the name of the window
to add. WEIGHT is the desired size, which is relative to the
@@ -174,7 +175,7 @@ public:
void replace_window (const char *name, const char *new_window) override;
- void specification (ui_file *output) override;
+ void specification (ui_file *output, int depth) override;
protected:
--
2.17.2
next prev parent reply other threads:[~2020-01-04 18:34 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-04 18:34 [PATCH 00/24] Horizontal TUI layout + windows in Python Tom Tromey
2020-01-04 18:34 ` [PATCH 03/24] Fix latent display bug in tui_data_window Tom Tromey
2020-01-04 18:34 ` [PATCH 16/24] TUI windows do not need to store their type Tom Tromey
2020-01-04 18:34 ` [PATCH 13/24] Reimplement tui_next_win and tui_prev_win Tom Tromey
2020-01-04 18:34 ` [PATCH 05/24] Reimplement TUI "C-x 1" binding Tom Tromey
2020-01-04 18:34 ` [PATCH 18/24] Remove tui_set_win_focus_to Tom Tromey
2020-01-04 18:34 ` [PATCH 24/24] Fix cast in TUI_DISASM_WIN Tom Tromey
2020-01-04 18:34 ` [PATCH 22/24] Use error_no_arg in TUI Tom Tromey
2020-01-04 18:34 ` [PATCH 08/24] Add the "tui new-layout" command Tom Tromey
2020-01-04 18:44 ` Eli Zaretskii
2020-01-04 18:34 ` [PATCH 14/24] Handle ambiguity in tui_partial_win_by_name Tom Tromey
2020-01-04 18:34 ` [PATCH 23/24] Add "usage" text to all TUI command help Tom Tromey
2020-01-04 18:34 ` [PATCH 21/24] Make some tui_source_window_base members "protected" Tom Tromey
2020-01-04 18:34 ` [PATCH 01/24] Use TUI_DISASM_WIN instead of tui_win_list array Tom Tromey
2020-01-04 18:34 ` [PATCH 07/24] Remove hard-coded TUI layouts Tom Tromey
2020-01-04 18:34 ` Tom Tromey [this message]
2020-01-04 18:34 ` [PATCH 02/24] Simplify tui_add_win_to_layout Tom Tromey
2020-01-04 18:34 ` [PATCH 19/24] Remove the TUI annotation hack Tom Tromey
2020-01-04 18:34 ` [PATCH 15/24] Remove tui_delete_invisible_windows and tui_make_all_invisible Tom Tromey
2020-01-04 18:34 ` [PATCH 12/24] Change TUI window iteration Tom Tromey
2020-01-04 18:34 ` [PATCH 11/24] Add horizontal splitting to TUI layout Tom Tromey
2020-01-04 18:47 ` Eli Zaretskii
2020-01-04 18:34 ` [PATCH 06/24] Reimplement "tui reg" command Tom Tromey
2020-01-04 18:34 ` [PATCH 10/24] Change return type of tui_layout_base::adjust_size Tom Tromey
2020-01-04 18:34 ` [PATCH 04/24] Simplify TUI C-x 2 binding Tom Tromey
2020-01-04 18:34 ` [PATCH 20/24] Allow TUI windows in Python Tom Tromey
2020-01-04 18:57 ` Eli Zaretskii
2020-02-22 19:57 ` Tom Tromey
2020-02-22 20:18 ` Eli Zaretskii
2020-03-10 22:23 ` Simon Marchi
2020-03-11 0:23 ` Tom Tromey
2020-03-11 4:47 ` Simon Marchi
2020-03-11 5:07 ` Simon Marchi
2020-03-11 18:05 ` Tom Tromey
2020-01-04 18:54 ` [PATCH 17/24] Change how TUI windows are instantiated Tom Tromey
2020-02-22 20:22 ` [PATCH 00/24] Horizontal TUI layout + windows in Python Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200104183410.17114-10-tom@tromey.com \
--to=tom@tromey.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox