[binutils-gdb] Change two ui_file subclasses to templates

Tom Tromey via Gdb-cvs <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1d6655e45137faa4562400c4c5aa547e5b05e2ee

commit 1d6655e45137faa4562400c4c5aa547e5b05e2ee
Author: Tom Tromey <[email protected]>
Date:   Wed Jan 14 06:34:56 2026 -0700

    Change two ui_file subclasses to templates
    
    This patch changes escape_buffering_file and no_terminal_escape_file
    to be template classes.  Currently these both derive from stdio_file,
    but in a coming patch that won't be desirable.  This change makes it
    easy to instantiate these classes in a couple of different ways.
    
    The implementation is hidden and so explicit instantiations are done
    in ui-file.c.  This seems fine since in practice there aren't going to
    be many of these.

Diff:
---
 gdb/cli/cli-logging.c |  2 +-
 gdb/tui/tui-file.h    |  2 +-
 gdb/ui-file.c         | 30 ++++++++++++++++++++++++------
 gdb/ui-file.h         | 14 +++++++-------
 4 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index 38c16fbf18f..c9482d59199 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -235,7 +235,7 @@ handle_redirections (int from_tty)
       return;
     }
 
-  stdio_file_up log = std::make_unique<no_terminal_escape_file> ();
+  stdio_file_up log = std::make_unique<no_terminal_escape_file<stdio_file>> ();
   if (!log->open (logging_filename.c_str (), logging_overwrite ? "w" : "a"))
     perror_with_name (_("set logging"));
 
diff --git a/gdb/tui/tui-file.h b/gdb/tui/tui-file.h
index f82f97a4fc0..d0cdcbbb71a 100644
--- a/gdb/tui/tui-file.h
+++ b/gdb/tui/tui-file.h
@@ -23,7 +23,7 @@
 
 /* A STDIO-like output stream for the TUI.  */
 
-class tui_file : public escape_buffering_file
+class tui_file : public escape_buffering_file<stdio_file>
 {
 public:
   tui_file (FILE *stream, bool buffered)
diff --git a/gdb/ui-file.c b/gdb/ui-file.c
index 2bd692274f7..8830dcfdf8f 100644
--- a/gdb/ui-file.c
+++ b/gdb/ui-file.c
@@ -344,8 +344,9 @@ stderr_file::stderr_file (FILE *stream)
 
 /* See ui-file.h.  */
 
+template<typename T>
 void
-escape_buffering_file::write (const char *buf, long length_buf)
+escape_buffering_file<T>::write (const char *buf, long length_buf)
 {
   std::string copy (buf, length_buf);
   this->puts (copy.c_str ());
@@ -353,8 +354,9 @@ escape_buffering_file::write (const char *buf, long length_buf)
 
 /* See ui-file.h.  */
 
+template<typename T>
 void
-escape_buffering_file::puts (const char *buf)
+escape_buffering_file<T>::puts (const char *buf)
 {
   std::string local_buffer;
   if (!m_buffer.empty ())
@@ -406,8 +408,9 @@ escape_buffering_file::puts (const char *buf)
 
 /* See ui-file.h.  */
 
+template<typename T>
 void
-no_terminal_escape_file::do_puts (const char *buf)
+no_terminal_escape_file<T>::do_puts (const char *buf)
 {
   while (*buf != '\0')
     {
@@ -419,16 +422,25 @@ no_terminal_escape_file::do_puts (const char *buf)
       if (!skip_ansi_escape (esc, &n_read))
 	++esc;
 
-      this->stdio_file::write (buf, esc - buf);
+      /* The immediate superclass is escape_buffering_file, and
+	 calling its "write" would just end up in this function again.
+	 So perform the actual write using the "grandparent"
+	 class.  */
+      T::write (buf, esc - buf);
       buf = esc + n_read;
     }
 
   if (*buf != '\0')
-    this->stdio_file::write (buf, strlen (buf));
+    {
+      /* See comment above to understand which 'write' is being
+	 called.  */
+      T::write (buf, strlen (buf));
+    }
 }
 
+template<typename T>
 void
-no_terminal_escape_file::do_write (const char *buf, long len)
+no_terminal_escape_file<T>::do_write (const char *buf, long len)
 {
   std::string copy (buf, len);
   do_puts (copy.c_str ());
@@ -486,3 +498,9 @@ tab_expansion_file::write (const char *buf, long length_buf)
 	}
     }
 }
+
+/* Any necessary instantiations.  This is done here to avoid putting
+   all the logic in a header file, which seems fine in this case
+   because these classes aren't instantiated in very many ways.  */
+template class escape_buffering_file<stdio_file>;
+template class no_terminal_escape_file<stdio_file>;
diff --git a/gdb/ui-file.h b/gdb/ui-file.h
index 6da4eb7a231..6a1d3964335 100644
--- a/gdb/ui-file.h
+++ b/gdb/ui-file.h
@@ -338,12 +338,13 @@ public:
    an incomplete but potentially recognizable escape sequence is
    started.  */
 
-class escape_buffering_file : public stdio_file
+template<typename T>
+class escape_buffering_file : public T
 {
 public:
-  using stdio_file::stdio_file;
+  using T::T;
 
-  /* Like the stdio_file methods but these forward to do_write and
+  /* Like the superclass methods but these forward to do_write and
      do_puts, respectively.  */
   void write (const char *buf, long length_buf) override final;
   void puts (const char *linebuffer) override final;
@@ -370,12 +371,11 @@ private:
 /* A ui_file implementation that filters out terminal escape
    sequences.  */
 
-class no_terminal_escape_file : public escape_buffering_file
+template<typename T>
+class no_terminal_escape_file : public escape_buffering_file<T>
 {
 public:
-  no_terminal_escape_file ()
-  {
-  }
+  using escape_buffering_file<T>::escape_buffering_file;
 
   void emit_style_escape (const ui_file_style &style) override
   {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.