aboutsummaryrefslogtreecommitdiff
path: root/gdb/tui/tui-layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/tui/tui-layout.c')
-rw-r--r--gdb/tui/tui-layout.c103
1 files changed, 100 insertions, 3 deletions
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index e2ddbfb..8f5dd6e 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -27,7 +27,9 @@
#include "source.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
+#include "cli/cli-utils.h"
#include <ctype.h>
+#include <unordered_set>
#include "tui/tui.h"
#include "tui/tui-command.h"
@@ -397,6 +399,14 @@ tui_layout_window::replace_window (const char *name, const char *new_window)
/* See tui-layout.h. */
+void
+tui_layout_window::specification (ui_file *output)
+{
+ fputs_unfiltered (get_name (), output);
+}
+
+/* See tui-layout.h. */
+
tui_layout_split *
tui_layout_split::add_split (int weight)
{
@@ -698,6 +708,22 @@ tui_layout_split::replace_window (const char *name, const char *new_window)
item.layout->replace_window (name, new_window);
}
+/* See tui-layout.h. */
+
+void
+tui_layout_split::specification (ui_file *output)
+{
+ bool first = true;
+ for (auto &item : m_splits)
+ {
+ if (!first)
+ fputs_unfiltered (" ", output);
+ first = false;
+ item.layout->specification (output);
+ fprintf_unfiltered (output, " %d", item.weight);
+ }
+}
+
/* Destroy the layout associated with SELF. */
static void
@@ -714,13 +740,19 @@ static struct cmd_list_element *layout_list;
/* Add a "layout" command with name NAME that switches to LAYOUT. */
-static void
+static struct cmd_list_element *
add_layout_command (const char *name, tui_layout_split *layout)
{
struct cmd_list_element *cmd;
- gdb::unique_xmalloc_ptr<char> doc (xstrprintf (_("Apply the \"%s\" layout"),
- name));
+ string_file spec;
+ layout->specification (&spec);
+
+ gdb::unique_xmalloc_ptr<char> doc
+ (xstrprintf (_("Apply the \"%s\" layout.\n\
+This layout was created using:\n\
+ tui new-layout %s %s"),
+ name, name, spec.c_str ()));
cmd = add_cmd (name, class_tui, nullptr, doc.get (), &layout_list);
set_cmd_context (cmd, layout);
@@ -730,6 +762,8 @@ add_layout_command (const char *name, tui_layout_split *layout)
cmd->doc_allocated = 1;
doc.release ();
layouts.emplace_back (layout);
+
+ return cmd;
}
/* Initialize the standard layouts. */
@@ -777,6 +811,59 @@ initialize_layouts ()
+/* A helper function that returns true if NAME is the name of an
+ available window. */
+
+static bool
+validate_window_name (const std::string &name)
+{
+ return (name == "src" || name == "cmd"
+ || name == "regs" || name == "asm"
+ || name == "status");
+}
+
+/* Implementation of the "tui new-layout" command. */
+
+static void
+tui_new_layout_command (const char *spec, int from_tty)
+{
+ std::string new_name = extract_arg (&spec);
+ if (new_name.empty ())
+ error (_("No layout name specified"));
+ if (new_name[0] == '-')
+ error (_("Layout name cannot start with '-'"));
+
+ std::unique_ptr<tui_layout_split> new_layout (new tui_layout_split);
+ std::unordered_set<std::string> seen_windows;
+ while (true)
+ {
+ std::string 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 (seen_windows.empty ())
+ error (_("New layout does not contain any windows"));
+ if (seen_windows.find ("cmd") == seen_windows.end ())
+ error (_("New layout does not contain the \"cmd\" window"));
+
+ gdb::unique_xmalloc_ptr<char> cmd_name
+ = make_unique_xstrdup (new_name.c_str ());
+ struct cmd_list_element *cmd
+ = add_layout_command (cmd_name.get (), new_layout.get ());
+ cmd->name_allocated = 1;
+ cmd_name.release ();
+ new_layout.release ();
+}
+
/* Base command for "layout". */
static void
@@ -807,5 +894,15 @@ Usage: layout prev | next | LAYOUT-NAME"),
_("Apply the TUI register layout"),
&layout_list);
+ add_cmd ("new-layout", class_tui, tui_new_layout_command,
+ _("Create a new TUI layout.\n\
+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\
+Each WEIGHT is an integer, which holds the relative size\n\
+to be allocated to the window."),
+ tui_get_cmd_list ());
+
initialize_layouts ();
}