• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisionee325b61cd4389506d2dd63294c1ce1c64cb9d9f (tree)
Time2020-02-23 03:48:31
AuthorTom Tromey <tom@trom...>
CommiterTom Tromey

Log Message

Add the "tui new-layout" command

This adds a new command, "tui new-layout". This command can be used
to define a new TUI window layout.

The command is used like:

(gdb) tui new-layout name src 1 regs 1 status 0 cmd 1

The first argument is the name of the layout. In this example, it is
"name", so the new layout could be seen by "layout name".

Subsequent arguments come in pairs, where the first item in a pair is
the name of a window, and the second item in a pair is the window's
weight. A weight is just an integer -- a window's allocated size is
proportional to the total of the weights given. So, in the above
example, all windows will have the same size (the status windows's
weight does not matter, because it has fixed height).

gdb/ChangeLog
2020-02-22 Tom Tromey <tom@tromey.com>

* NEWS: Add "tui new-layout" item.
* tui/tui-layout.c (add_layout_command): Return cmd_list_element.
Add new-layout command to help text.
(validate_window_name): New function.
(tui_new_layout_command): New function.
(_initialize_tui_layout): Register "new-layout".
(tui_layout_window::specification): New method.
(tui_layout_window::specification): New method.
* tui/tui-layout.h (class tui_layout_base) <specification>: New
method.
(class tui_layout_window) <specification>: New method.
(class tui_layout_split) <specification>: New method.

gdb/doc/ChangeLog
2020-02-22 Tom Tromey <tom@tromey.com>

* gdb.texinfo (TUI Overview): Mention user layouts.
(TUI Commands): Document "tui new-layout".

gdb/testsuite/ChangeLog
2020-02-22 Tom Tromey <tom@tromey.com>

* gdb.tui/new-layout.exp: New file.

Change-Id: Id7c3ace20ab1e8924f8f4ad788f40210f58a5c05

Change Summary

Incremental Difference

--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,20 @@
11 2020-02-22 Tom Tromey <tom@tromey.com>
22
3+ * NEWS: Add "tui new-layout" item.
4+ * tui/tui-layout.c (add_layout_command): Return cmd_list_element.
5+ Add new-layout command to help text.
6+ (validate_window_name): New function.
7+ (tui_new_layout_command): New function.
8+ (_initialize_tui_layout): Register "new-layout".
9+ (tui_layout_window::specification): New method.
10+ (tui_layout_window::specification): New method.
11+ * tui/tui-layout.h (class tui_layout_base) <specification>: New
12+ method.
13+ (class tui_layout_window) <specification>: New method.
14+ (class tui_layout_split) <specification>: New method.
15+
16+2020-02-22 Tom Tromey <tom@tromey.com>
17+
318 * tui/tui.c (tui_enable): Call tui_set_initial_layout.
419 * tui/tui-win.c (window_name_completer): Update comment.
520 * tui/tui-layout.h (class tui_layout_base) <replace_window>:
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -30,6 +30,10 @@ show exec-file-mismatch -- Show exec-file-mismatch handling (ask|warn|off).
3030 whether to load the process executable file; if 'warn', just display
3131 a warning; if 'off', don't attempt to detect a mismatch.
3232
33+tui new-layout NAME WINDOW WEIGHT [WINDOW WEIGHT]...
34+ Define a new TUI layout, specifying its name and the windows that
35+ will be displayed.
36+
3337 * New targets
3438
3539 GNU/Linux/RISC-V (gdbserver) riscv*-*-linux*
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
1+2020-02-22 Tom Tromey <tom@tromey.com>
2+
3+ * gdb.texinfo (TUI Overview): Mention user layouts.
4+ (TUI Commands): Document "tui new-layout".
5+
16 2020-01-26 Tom Tromey <tromey@adacore.com>
27
38 * gdb.texinfo (M68K Features): Document floating-point feature
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -27755,6 +27755,8 @@ source and registers, or
2775527755 assembly and registers.
2775627756 @end itemize
2775727757
27758+These are the standard layouts, but other layouts can be defined.
27759+
2775827760 A status line above the command window shows the following information:
2775927761
2776027762 @table @emph
@@ -27991,11 +27993,40 @@ Disable TUI mode, returning to the console interpreter.
2799127993 @kindex info win
2799227994 List and give the size of all displayed windows.
2799327995
27996+@item tui new-layout @var{name} @var{window} @var{weight} @r{[}@var{window} @var{weight}@dots{}@r{]}
27997+@kindex tui new-layout
27998+Create a new TUI layout. The new layout will be named @var{name}, and
27999+can be accessed using the @code{layout} command (see below).
28000+
28001+Each @var{window} parameter is the name of a window to display. The
28002+windows will be displayed from top to bottom in the order listed. The
28003+names of the windows are the same as the ones given to the
28004+@code{focus} command (see below); additional, the @code{status}
28005+window can be specified.
28006+
28007+Each @var{weight} is an integer. It is the weight of this window
28008+relative to all the other windows in the layout. These numbers are
28009+used to calculate how much of the screen is given to each window.
28010+
28011+For example:
28012+
28013+@example
28014+(gdb) tui new-layout example src 1 regs 1 status 0 cmd 1
28015+@end example
28016+
28017+Here, the new layout is called @samp{example}. It shows the source
28018+and register windows, followed by the status window, and then finally
28019+the command window. The non-status windows all have the same weight,
28020+so the terminal will be split into three roughly equal sections.
28021+
2799428022 @item layout @var{name}
2799528023 @kindex layout
27996-Changes which TUI windows are displayed. In each layout the command
27997-window is always displayed, the @var{name} parameter controls which
27998-additional windows are displayed, and can be any of the following:
28024+Changes which TUI windows are displayed. The @var{name} parameter
28025+controls which layout is shown. It can be either one of the built-in
28026+layout names, or the name of a layout defined by the user using
28027+@code{tui new-layout}.
28028+
28029+The built-in layouts are as follows:
2799928030
2800028031 @table @code
2800128032 @item next
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
11 2020-02-22 Tom Tromey <tom@tromey.com>
22
3+ * gdb.tui/new-layout.exp: New file.
4+
5+2020-02-22 Tom Tromey <tom@tromey.com>
6+
37 * gdb.rust/rust-style.rs: New file.
48 * gdb.rust/rust-style.exp: New file.
59 * gdb.base/style.exp: Test structure printing.
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/new-layout.exp
@@ -0,0 +1,54 @@
1+# Copyright 2020 Free Software Foundation, Inc.
2+
3+# This program is free software; you can redistribute it and/or modify
4+# it under the terms of the GNU General Public License as published by
5+# the Free Software Foundation; either version 3 of the License, or
6+# (at your option) any later version.
7+#
8+# This program is distributed in the hope that it will be useful,
9+# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+# GNU General Public License for more details.
12+#
13+# You should have received a copy of the GNU General Public License
14+# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
16+# Test "tui new-layout".
17+
18+load_lib "tuiterm.exp"
19+
20+standard_testfile tui-layout.c
21+
22+if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
23+ return -1
24+}
25+
26+Term::clean_restart 24 80 $testfile
27+
28+gdb_test "tui new-layout" \
29+ "No layout name specified"
30+gdb_test "tui new-layout example" \
31+ "New layout does not contain any windows"
32+gdb_test "tui new-layout example zzq" \
33+ "Unknown window \"zzq\""
34+gdb_test "tui new-layout example src 1 src 1" \
35+ "Window \"src\" seen twice in layout"
36+gdb_test "tui new-layout example src 1" \
37+ "New layout does not contain the \"cmd\" window"
38+
39+gdb_test_no_output "tui new-layout example asm 1 status 0 cmd 1"
40+
41+gdb_test "help layout example" \
42+ "Apply the \"example\" layout.*tui new-layout example asm 1 status 0 cmd 1"
43+
44+if {![Term::enter_tui]} {
45+ unsupported "TUI not supported"
46+}
47+
48+set text [Term::get_all_lines]
49+gdb_assert {![string match "No Source Available" $text]} \
50+ "initial source listing"
51+
52+Term::command "layout example"
53+Term::check_contents "example layout shows assembly" \
54+ "No Assembly Available"
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -27,7 +27,9 @@
2727 #include "source.h"
2828 #include "cli/cli-cmds.h"
2929 #include "cli/cli-decode.h"
30+#include "cli/cli-utils.h"
3031 #include <ctype.h>
32+#include <unordered_set>
3133
3234 #include "tui/tui.h"
3335 #include "tui/tui-command.h"
@@ -397,6 +399,14 @@ tui_layout_window::replace_window (const char *name, const char *new_window)
397399
398400 /* See tui-layout.h. */
399401
402+void
403+tui_layout_window::specification (ui_file *output)
404+{
405+ fputs_unfiltered (get_name (), output);
406+}
407+
408+/* See tui-layout.h. */
409+
400410 tui_layout_split *
401411 tui_layout_split::add_split (int weight)
402412 {
@@ -698,6 +708,22 @@ tui_layout_split::replace_window (const char *name, const char *new_window)
698708 item.layout->replace_window (name, new_window);
699709 }
700710
711+/* See tui-layout.h. */
712+
713+void
714+tui_layout_split::specification (ui_file *output)
715+{
716+ bool first = true;
717+ for (auto &item : m_splits)
718+ {
719+ if (!first)
720+ fputs_unfiltered (" ", output);
721+ first = false;
722+ item.layout->specification (output);
723+ fprintf_unfiltered (output, " %d", item.weight);
724+ }
725+}
726+
701727 /* Destroy the layout associated with SELF. */
702728
703729 static void
@@ -714,13 +740,19 @@ static struct cmd_list_element *layout_list;
714740
715741 /* Add a "layout" command with name NAME that switches to LAYOUT. */
716742
717-static void
743+static struct cmd_list_element *
718744 add_layout_command (const char *name, tui_layout_split *layout)
719745 {
720746 struct cmd_list_element *cmd;
721747
722- gdb::unique_xmalloc_ptr<char> doc (xstrprintf (_("Apply the \"%s\" layout"),
723- name));
748+ string_file spec;
749+ layout->specification (&spec);
750+
751+ gdb::unique_xmalloc_ptr<char> doc
752+ (xstrprintf (_("Apply the \"%s\" layout.\n\
753+This layout was created using:\n\
754+ tui new-layout %s %s"),
755+ name, name, spec.c_str ()));
724756
725757 cmd = add_cmd (name, class_tui, nullptr, doc.get (), &layout_list);
726758 set_cmd_context (cmd, layout);
@@ -730,6 +762,8 @@ add_layout_command (const char *name, tui_layout_split *layout)
730762 cmd->doc_allocated = 1;
731763 doc.release ();
732764 layouts.emplace_back (layout);
765+
766+ return cmd;
733767 }
734768
735769 /* Initialize the standard layouts. */
@@ -777,6 +811,59 @@ initialize_layouts ()
777811
778812
779813
814+/* A helper function that returns true if NAME is the name of an
815+ available window. */
816+
817+static bool
818+validate_window_name (const std::string &name)
819+{
820+ return (name == "src" || name == "cmd"
821+ || name == "regs" || name == "asm"
822+ || name == "status");
823+}
824+
825+/* Implementation of the "tui new-layout" command. */
826+
827+static void
828+tui_new_layout_command (const char *spec, int from_tty)
829+{
830+ std::string new_name = extract_arg (&spec);
831+ if (new_name.empty ())
832+ error (_("No layout name specified"));
833+ if (new_name[0] == '-')
834+ error (_("Layout name cannot start with '-'"));
835+
836+ std::unique_ptr<tui_layout_split> new_layout (new tui_layout_split);
837+ std::unordered_set<std::string> seen_windows;
838+ while (true)
839+ {
840+ std::string name = extract_arg (&spec);
841+ if (name.empty ())
842+ break;
843+ if (!validate_window_name (name))
844+ error (_("Unknown window \"%s\""), name.c_str ());
845+ if (seen_windows.find (name) != seen_windows.end ())
846+ error (_("Window \"%s\" seen twice in layout"), name.c_str ());
847+ ULONGEST weight = get_ulongest (&spec);
848+ if ((int) weight != weight)
849+ error (_("Weight out of range: %s"), pulongest (weight));
850+ new_layout->add_window (name.c_str (), weight);
851+ seen_windows.insert (name);
852+ }
853+ if (seen_windows.empty ())
854+ error (_("New layout does not contain any windows"));
855+ if (seen_windows.find ("cmd") == seen_windows.end ())
856+ error (_("New layout does not contain the \"cmd\" window"));
857+
858+ gdb::unique_xmalloc_ptr<char> cmd_name
859+ = make_unique_xstrdup (new_name.c_str ());
860+ struct cmd_list_element *cmd
861+ = add_layout_command (cmd_name.get (), new_layout.get ());
862+ cmd->name_allocated = 1;
863+ cmd_name.release ();
864+ new_layout.release ();
865+}
866+
780867 /* Base command for "layout". */
781868
782869 static void
@@ -807,5 +894,15 @@ Usage: layout prev | next | LAYOUT-NAME"),
807894 _("Apply the TUI register layout"),
808895 &layout_list);
809896
897+ add_cmd ("new-layout", class_tui, tui_new_layout_command,
898+ _("Create a new TUI layout.\n\
899+Usage: tui new-layout NAME WINDOW WEIGHT [WINDOW WEIGHT]...\n\
900+Create a new TUI layout. The new layout will be named NAME,\n\
901+and can be accessed using \"layout NAME\".\n\
902+The windows will be displayed in the specified order.\n\
903+Each WEIGHT is an integer, which holds the relative size\n\
904+to be allocated to the window."),
905+ tui_get_cmd_list ());
906+
810907 initialize_layouts ();
811908 }
--- a/gdb/tui/tui-layout.h
+++ b/gdb/tui/tui-layout.h
@@ -22,6 +22,8 @@
2222 #ifndef TUI_TUI_LAYOUT_H
2323 #define TUI_TUI_LAYOUT_H
2424
25+#include "ui-file.h"
26+
2527 #include "tui/tui.h"
2628 #include "tui/tui-data.h"
2729
@@ -72,6 +74,9 @@ public:
7274 NEW_WINDOW. */
7375 virtual void replace_window (const char *name, const char *new_window) = 0;
7476
77+ /* Append the specification to this window to OUTPUT. */
78+ virtual void specification (ui_file *output) = 0;
79+
7580 /* The most recent space allocation. */
7681 int x = 0;
7782 int y = 0;
@@ -120,6 +125,8 @@ public:
120125
121126 void replace_window (const char *name, const char *new_window) override;
122127
128+ void specification (ui_file *output) override;
129+
123130 protected:
124131
125132 void get_sizes (int *min_height, int *max_height) override;
@@ -167,6 +174,8 @@ public:
167174
168175 void replace_window (const char *name, const char *new_window) override;
169176
177+ void specification (ui_file *output) override;
178+
170179 protected:
171180
172181 void get_sizes (int *min_height, int *max_height) override;