+
+ if (depth > 0)
+ fputs_unfiltered ("}", output);
+}
+
+/* Destroy the layout associated with SELF. */
+
+static void
+destroy_layout (struct cmd_list_element *self, void *context)
+{
+ tui_layout_split *layout = (tui_layout_split *) context;
+ size_t index = find_layout (layout);
+ layouts.erase (layouts.begin () + index);
+}
+
+/* List holding the sub-commands of "layout". */
+
+static struct cmd_list_element *layout_list;
+
+/* Add a "layout" command with name NAME that switches to LAYOUT. */
+
+static struct cmd_list_element *
+add_layout_command (const char *name, tui_layout_split *layout)
+{
+ struct cmd_list_element *cmd;
+
+ string_file spec;
+ layout->specification (&spec, 0);
+
+ 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);
+ /* There is no API to set this. */
+ cmd->func = tui_apply_layout;
+ cmd->destroyer = destroy_layout;
+ cmd->doc_allocated = 1;
+ doc.release ();
+ layouts.emplace_back (layout);
+
+ return cmd;
+}
+
+/* Initialize the standard layouts. */
+
+static void
+initialize_layouts ()
+{
+ tui_layout_split *layout;
+
+ layout = new tui_layout_split ();
+ layout->add_window (SRC_NAME, 2);
+ layout->add_window (STATUS_NAME, 0);
+ layout->add_window (CMD_NAME, 1);
+ add_layout_command (SRC_NAME, layout);
+
+ layout = new tui_layout_split ();
+ layout->add_window (DISASSEM_NAME, 2);
+ layout->add_window (STATUS_NAME, 0);
+ layout->add_window (CMD_NAME, 1);
+ add_layout_command (DISASSEM_NAME, layout);
+
+ layout = new tui_layout_split ();
+ layout->add_window (SRC_NAME, 1);
+ layout->add_window (DISASSEM_NAME, 1);
+ layout->add_window (STATUS_NAME, 0);
+ layout->add_window (CMD_NAME, 1);
+ add_layout_command ("split", layout);
+
+ layout = new tui_layout_split ();
+ layout->add_window (DATA_NAME, 1);
+ layout->add_window (SRC_NAME, 1);
+ layout->add_window (STATUS_NAME, 0);
+ layout->add_window (CMD_NAME, 1);
+ layouts.emplace_back (layout);
+ src_regs_layout = layout;
+
+ layout = new tui_layout_split ();
+ layout->add_window (DATA_NAME, 1);
+ layout->add_window (DISASSEM_NAME, 1);
+ layout->add_window (STATUS_NAME, 0);
+ layout->add_window (CMD_NAME, 1);
+ layouts.emplace_back (layout);
+ asm_regs_layout = layout;
+}
+
+\f
+
+/* A helper function that returns true if NAME is the name of an
+ available window. */
+
+static bool
+validate_window_name (const std::string &name)
+{
+ auto iter = known_window_types->find (name);
+ return iter != known_window_types->end ();
+}
+
+/* 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 '-'"));
+
+ bool is_vertical = true;
+ spec = skip_spaces (spec);
+ if (check_for_argument (&spec, "-horizontal"))
+ is_vertical = false;
+
+ std::vector<std::unique_ptr<tui_layout_split>> splits;
+ splits.emplace_back (new tui_layout_split (is_vertical));
+ std::unordered_set<std::string> seen_windows;
+ while (true)