[20/61] Introduce TUI window iterator

Message ID 20190704170311.15982-21-tom@tromey.com
State New
Headers show
Series
  • More TUI refactorings
Related show

Commit Message

Tom Tromey July 4, 2019, 5:02 p.m.
This introduces an iterator class and a range adapter to make it
simpler to iterate over TUI windows.

One explicit iteration remains, in tui-win.c, because that spot is
deleting windows as well.

2019-07-04  Tom Tromey  <tom@tromey.com>

	* tui/tui-wingeneral.h (tui_refresh_all): Update.
	* tui/tui-wingeneral.c (make_all_visible): Use foreach.
	(tui_refresh_all): Remove "list" parameter.  Use foreach.
	* tui/tui-win.c (window_name_completer): Use foreach.
	(tui_refresh_all_win, tui_rehighlight_all, tui_all_windows_info)
	(update_tab_width): Likewise.
	* tui/tui-layout.c (show_layout): Update.
	* tui/tui-data.h (class tui_window_iterator): New.
	(struct all_tui_windows): New.
	* tui/tui-data.c (tui_partial_win_by_name): Use foreach.
---
 gdb/ChangeLog            | 13 ++++++++
 gdb/tui/tui-data.c       | 22 ++++---------
 gdb/tui/tui-data.h       | 69 ++++++++++++++++++++++++++++++++++++++++
 gdb/tui/tui-layout.c     |  2 +-
 gdb/tui/tui-win.c        | 47 +++++++++++----------------
 gdb/tui/tui-wingeneral.c | 20 ++++--------
 gdb/tui/tui-wingeneral.h |  2 +-
 7 files changed, 116 insertions(+), 59 deletions(-)

-- 
2.17.2

Patch

diff --git a/gdb/tui/tui-data.c b/gdb/tui/tui-data.c
index a62dbf4d670..eacf174bbe7 100644
--- a/gdb/tui/tui-data.c
+++ b/gdb/tui/tui-data.c
@@ -294,27 +294,19 @@  tui_prev_win (struct tui_win_info *cur_win)
 struct tui_win_info *
 tui_partial_win_by_name (const char *name)
 {
-  struct tui_win_info *win_info = NULL;
-
   if (name != NULL)
     {
-      int i = 0;
-
-      while (i < MAX_MAJOR_WINDOWS && win_info == NULL)
+      for (tui_win_info *item : all_tui_windows ())
 	{
-          if (tui_win_list[i] != 0)
-            {
-              const char *cur_name = tui_win_list[i]->name ();
-
-              if (strlen (name) <= strlen (cur_name)
-		  && startswith (cur_name, name))
-                win_info = tui_win_list[i];
-            }
-	  i++;
+	  const char *cur_name = item->name ();
+
+	  if (strlen (name) <= strlen (cur_name)
+	      && startswith (cur_name, name))
+	    return item;
 	}
     }
 
-  return win_info;
+  return NULL;
 }
 
 
diff --git a/gdb/tui/tui-data.h b/gdb/tui/tui-data.h
index b3592e39133..76f6bc6102c 100644
--- a/gdb/tui/tui-data.h
+++ b/gdb/tui/tui-data.h
@@ -602,6 +602,75 @@  extern struct tui_win_info *tui_win_list[MAX_MAJOR_WINDOWS];
 #define TUI_DATA_WIN    ((tui_data_window *) tui_win_list[DATA_WIN])
 #define TUI_CMD_WIN     ((tui_cmd_window *) tui_win_list[CMD_WIN])
 
+/* An iterator that iterates over all windows.  */
+
+class tui_window_iterator
+{
+public:
+
+  typedef tui_window_iterator self_type;
+  typedef struct tui_win_info *value_type;
+  typedef struct tui_win_info *&reference;
+  typedef struct tui_win_info **pointer;
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+
+  explicit tui_window_iterator (enum tui_win_type type)
+    : m_type (type)
+  {
+    advance ();
+  }
+
+  tui_window_iterator ()
+    : m_type (MAX_MAJOR_WINDOWS)
+  {
+  }
+
+  bool operator!= (const self_type &other) const
+  {
+    return m_type != other.m_type;
+  }
+
+  value_type operator* () const
+  {
+    gdb_assert (m_type < MAX_MAJOR_WINDOWS);
+    return tui_win_list[m_type];
+  }
+
+  self_type &operator++ ()
+  {
+    ++m_type;
+    advance ();
+    return *this;
+  }
+
+private:
+
+  void advance ()
+  {
+    while (m_type < MAX_MAJOR_WINDOWS && tui_win_list[m_type] == nullptr)
+      ++m_type;
+  }
+
+  int m_type;
+};
+
+/* A range adapter for iterating over TUI windows.  */
+
+struct all_tui_windows
+{
+  tui_window_iterator begin () const
+  {
+    return tui_window_iterator (SRC_WIN);
+  }
+
+  tui_window_iterator end () const
+  {
+    return tui_window_iterator ();
+  }
+};
+
+
 /* Data Manipulation Functions.  */
 extern void tui_initialize_static_data (void);
 extern struct tui_win_info *tui_partial_win_by_name (const char *);
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index 9e683cfa919..a3ded203736 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -86,7 +86,7 @@  show_layout (enum tui_layout_type layout)
 	  || layout == DISASSEM_DATA_COMMAND)
 	{
 	  show_data (layout);
-	  tui_refresh_all (tui_win_list);
+	  tui_refresh_all ();
 	}
       else
 	{
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index ee03cf38e14..f83281f7902 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -364,18 +364,16 @@  window_name_completer (completion_tracker &tracker,
 		       const char *text, const char *word)
 {
   std::vector<const char *> completion_name_vec;
-  int win_type;
 
-  for (win_type = SRC_WIN; win_type < MAX_MAJOR_WINDOWS; win_type++)
+  for (tui_win_info *win_info : all_tui_windows ())
     {
       const char *completion_name = NULL;
 
       /* We can't focus on an invisible window.  */
-      if (tui_win_list[win_type] == NULL
-	  || !tui_win_list[win_type]->is_visible)
+      if (!win_info->is_visible)
 	continue;
 
-      completion_name = tui_win_list[win_type]->name ();
+      completion_name = win_info->name ();
       gdb_assert (completion_name != NULL);
       completion_name_vec.push_back (completion_name);
     }
@@ -518,14 +516,12 @@  tui_source_window_base::refresh_all ()
 void
 tui_refresh_all_win (void)
 {
-  int type;
-
   clearok (curscr, TRUE);
-  tui_refresh_all (tui_win_list);
-  for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
+  tui_refresh_all ();
+  for (tui_win_info *win_info : all_tui_windows ())
     {
-      if (tui_win_list[type] && tui_win_list[type]->is_visible)
-	tui_win_list[type]->refresh_all ();
+      if (win_info->is_visible)
+	win_info->refresh_all ();
     }
   tui_show_locator_content ();
 }
@@ -533,10 +529,8 @@  tui_refresh_all_win (void)
 void
 tui_rehighlight_all (void)
 {
-  int type;
-
-  for (type = SRC_WIN; type < MAX_MAJOR_WINDOWS; type++)
-    tui_check_and_display_highlight_if_needed (tui_win_list[type]);
+  for (tui_win_info *win_info : all_tui_windows ())
+    tui_check_and_display_highlight_if_needed (win_info);
 }
 
 /* Resize all the windows based on the terminal size.  This function
@@ -885,21 +879,19 @@  tui_set_focus_command (const char *arg, int from_tty)
 static void
 tui_all_windows_info (const char *arg, int from_tty)
 {
-  int type;
   struct tui_win_info *win_with_focus = tui_win_with_focus ();
 
-  for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
-    if (tui_win_list[type] 
-	&& tui_win_list[type]->is_visible)
+  for (tui_win_info *win_info : all_tui_windows ())
+    if (win_info->is_visible)
       {
-	if (win_with_focus == tui_win_list[type])
+	if (win_with_focus == win_info)
 	  printf_filtered ("        %s\t(%d lines)  <has focus>\n",
-			   tui_win_list[type]->name (),
-			   tui_win_list[type]->height);
+			   win_info->name (),
+			   win_info->height);
 	else
 	  printf_filtered ("        %s\t(%d lines)\n",
-			   tui_win_list[type]->name (),
-			   tui_win_list[type]->height);
+			   win_info->name (),
+			   win_info->height);
       }
 }
 
@@ -940,11 +932,10 @@  tui_source_window_base::update_tab_width ()
 static void
 update_tab_width ()
 {
-  for (int win_type = SRC_WIN; win_type < MAX_MAJOR_WINDOWS; win_type++)
+  for (tui_win_info *win_info : all_tui_windows ())
     {
-      if (tui_win_list[win_type] != NULL
-	  && tui_win_list[win_type]->is_visible)
-	tui_win_list[win_type]->update_tab_width ();
+      if (win_info->is_visible)
+	win_info->update_tab_width ();
     }
 }
 
diff --git a/gdb/tui/tui-wingeneral.c b/gdb/tui/tui-wingeneral.c
index c15739c594b..22f841eb88c 100644
--- a/gdb/tui/tui-wingeneral.c
+++ b/gdb/tui/tui-wingeneral.c
@@ -212,15 +212,8 @@  tui_source_window_base::make_visible (bool visible)
 static void
 make_all_visible (bool visible)
 {
-  int i;
-
-  for (i = 0; i < MAX_MAJOR_WINDOWS; i++)
-    {
-      if (tui_win_list[i] != NULL)
-	tui_win_list[i]->make_visible (visible);
-    }
-
-  return;
+  for (tui_win_info *win_info : all_tui_windows ())
+    win_info->make_visible (visible);
 }
 
 void
@@ -257,15 +250,14 @@  tui_source_window_base::refresh ()
 /* Function to refresh all the windows currently displayed.  */
 
 void
-tui_refresh_all (struct tui_win_info **list)
+tui_refresh_all ()
 {
-  int type;
   struct tui_locator_window *locator = tui_locator_win_info_ptr ();
 
-  for (type = SRC_WIN; (type < MAX_MAJOR_WINDOWS); type++)
+  for (tui_win_info *win_info : all_tui_windows ())
     {
-      if (list[type] && list[type]->is_visible)
-	list[type]->refresh ();
+      if (win_info->is_visible)
+	win_info->refresh ();
     }
   if (locator->is_visible)
     {
diff --git a/gdb/tui/tui-wingeneral.h b/gdb/tui/tui-wingeneral.h
index e925606229c..20b7f21c7c0 100644
--- a/gdb/tui/tui-wingeneral.h
+++ b/gdb/tui/tui-wingeneral.h
@@ -37,7 +37,7 @@  extern struct tui_win_info *tui_copy_win (struct tui_win_info *);
 extern void tui_box_win (struct tui_gen_win_info *, int);
 extern void tui_highlight_win (struct tui_win_info *);
 extern void tui_check_and_display_highlight_if_needed (struct tui_win_info *);
-extern void tui_refresh_all (struct tui_win_info **);
+extern void tui_refresh_all ();
 extern void tui_delete_win (WINDOW *window);
 
 #endif /* TUI_TUI_WINGENERAL_H */