gdb: LoongArch: Handle special struct in dummy call
[binutils-gdb.git] / gdb / ui-file.c
index 10192a98cd04a9289bcd2cb14fae748d0a9993a6..e0814fe2b2dcb57a66ce9315f494ab47859c3f48 100644 (file)
@@ -1,6 +1,6 @@
 /* UI_FILE - a generic STDIO like output stream.
 
-   Copyright (C) 1999-2020 Free Software Foundation, Inc.
+   Copyright (C) 1999-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include "ui-file.h"
-#include "gdb_obstack.h"
-#include "gdb_select.h"
+#include "gdbsupport/gdb_obstack.h"
+#include "gdbsupport/gdb_select.h"
 #include "gdbsupport/filestuff.h"
+#include "cli-out.h"
 #include "cli/cli-style.h"
+#include <chrono>
 
 null_file null_stream;
 
@@ -40,32 +42,121 @@ ui_file::printf (const char *format, ...)
   va_list args;
 
   va_start (args, format);
-  vfprintf_unfiltered (this, format, args);
+  vprintf (format, args);
   va_end (args);
 }
 
 void
 ui_file::putstr (const char *str, int quoter)
 {
-  fputstr_unfiltered (str, quoter, this);
+  while (*str)
+    printchar (*str++, quoter, false);
 }
 
 void
-ui_file::putstrn (const char *str, int n, int quoter)
+ui_file::putstrn (const char *str, int n, int quoter, bool async_safe)
 {
-  fputstrn_unfiltered (str, n, quoter, fputc_unfiltered, this);
+  for (int i = 0; i < n; i++)
+    printchar (str[i], quoter, async_safe);
 }
 
-int
+void
 ui_file::putc (int c)
 {
-  return fputc_unfiltered (c, this);
+  char copy = (char) c;
+  write (&copy, 1);
 }
 
 void
 ui_file::vprintf (const char *format, va_list args)
 {
-  vfprintf_unfiltered (this, format, args);
+  ui_out_flags flags = disallow_ui_out_field;
+  cli_ui_out (this, flags).vmessage (m_applied_style, format, args);
+}
+
+/* See ui-file.h.  */
+
+void
+ui_file::emit_style_escape (const ui_file_style &style)
+{
+  if (can_emit_style_escape () && style != m_applied_style)
+    {
+      m_applied_style = style;
+      this->puts (style.to_ansi ().c_str ());
+    }
+}
+
+/* See ui-file.h.  */
+
+void
+ui_file::reset_style ()
+{
+  if (can_emit_style_escape ())
+    {
+      m_applied_style = ui_file_style ();
+      this->puts (m_applied_style.to_ansi ().c_str ());
+    }
+}
+
+/* See ui-file.h.  */
+
+void
+ui_file::printchar (int c, int quoter, bool async_safe)
+{
+  char buf[4];
+  int out = 0;
+
+  c &= 0xFF;                   /* Avoid sign bit follies */
+
+  if (c < 0x20                  /* Low control chars */
+      || (c >= 0x7F && c < 0xA0) /* DEL, High controls */
+      || (sevenbit_strings && c >= 0x80))
+    {                          /* high order bit set */
+      buf[out++] = '\\';
+
+      switch (c)
+       {
+       case '\n':
+         buf[out++] = 'n';
+         break;
+       case '\b':
+         buf[out++] = 'b';
+         break;
+       case '\t':
+         buf[out++] = 't';
+         break;
+       case '\f':
+         buf[out++] = 'f';
+         break;
+       case '\r':
+         buf[out++] = 'r';
+         break;
+       case '\033':
+         buf[out++] = 'e';
+         break;
+       case '\007':
+         buf[out++] = 'a';
+         break;
+       default:
+         {
+           buf[out++] = '0' + ((c >> 6) & 0x7);
+           buf[out++] = '0' + ((c >> 3) & 0x7);
+           buf[out++] = '0' + ((c >> 0) & 0x7);
+           break;
+         }
+       }
+    }
+  else
+    {
+      if (quoter != 0 && (c == '\\' || c == quoter))
+       buf[out++] = '\\';
+      buf[out++] = c;
+    }
+
+  if (async_safe)
+    this->write_async_safe (buf, out);
+  else
+    this->write (buf, out);
 }
 
 \f
@@ -90,18 +181,6 @@ null_file::write_async_safe (const char *buf, long sizeof_buf)
 
 \f
 
-void
-gdb_flush (struct ui_file *file)
-{
-  file->flush ();
-}
-
-int
-ui_file_isatty (struct ui_file *file)
-{
-  return file->isatty ();
-}
-
 /* true if the gdb terminal supports styling, and styling is enabled.  */
 
 static bool
@@ -126,35 +205,6 @@ term_cli_styling ()
   return true;
 }
 
-
-void
-ui_file_write (struct ui_file *file,
-               const char *buf,
-               long length_buf)
-{
-  file->write (buf, length_buf);
-}
-
-void
-ui_file_write_async_safe (struct ui_file *file,
-                         const char *buf,
-                         long length_buf)
-{
-  file->write_async_safe (buf, length_buf);
-}
-
-long
-ui_file_read (struct ui_file *file, char *buf, long length_buf)
-{
-  return file->read (buf, length_buf);
-}
-
-void
-fputs_unfiltered (const char *buf, struct ui_file *file)
-{
-  file->puts (buf);
-}
-
 \f
 
 string_file::~string_file ()
@@ -302,8 +352,7 @@ stdio_file::isatty ()
 bool
 stdio_file::can_emit_style_escape ()
 {
-  return (this == gdb_stdout
-         && this->isatty ()
+  return (this->isatty ()
          && term_cli_styling ());
 }
 
@@ -315,7 +364,7 @@ stdio_file::can_emit_style_escape ()
 void
 stderr_file::write (const char *buf, long length_buf)
 {
-  gdb_flush (gdb_stdout);
+  gdb_stdout->flush ();
   stdio_file::write (buf, length_buf);
 }
 
@@ -325,7 +374,7 @@ stderr_file::write (const char *buf, long length_buf)
 void
 stderr_file::puts (const char *linebuffer)
 {
-  gdb_flush (gdb_stdout);
+  gdb_stdout->flush ();
   stdio_file::puts (linebuffer);
 }
 
@@ -335,9 +384,9 @@ stderr_file::stderr_file (FILE *stream)
 
 \f
 
-tee_file::tee_file (ui_file *one, ui_file_up &&two)
+tee_file::tee_file (ui_file *one, ui_file *two)
   : m_one (one),
-    m_two (std::move (two))
+    m_two (two)
 {}
 
 tee_file::~tee_file ()
@@ -391,8 +440,7 @@ tee_file::term_out ()
 bool
 tee_file::can_emit_style_escape ()
 {
-  return (this == gdb_stdout
-         && m_one->term_out ()
+  return (m_one->term_out ()
          && term_cli_styling ());
 }
 
@@ -427,3 +475,31 @@ no_terminal_escape_file::puts (const char *buf)
   if (*buf != '\0')
     this->stdio_file::write (buf, strlen (buf));
 }
+
+void
+timestamped_file::write (const char *buf, long len)
+{
+  if (debug_timestamp)
+    {
+      /* Print timestamp if previous print ended with a \n.  */
+      if (m_needs_timestamp)
+       {
+         using namespace std::chrono;
+
+         steady_clock::time_point now = steady_clock::now ();
+         seconds s = duration_cast<seconds> (now.time_since_epoch ());
+         microseconds us = duration_cast<microseconds> (now.time_since_epoch () - s);
+         std::string timestamp = string_printf ("%ld.%06ld ",
+                                                (long) s.count (),
+                                                (long) us.count ());
+         m_stream->puts (timestamp.c_str ());
+       }
+
+      /* Print the message.  */
+      m_stream->write (buf, len);
+
+      m_needs_timestamp = (len > 0 && buf[len - 1] == '\n');
+    }
+  else
+    m_stream->write (buf, len);
+}