Fix build failure on macOS
[deliverable/binutils-gdb.git] / gdb / ui-out.c
index dc978a711ac53b361c4adcf5eb56401873c79afc..2b3b7e4accb3087f577e3322679f5f2c00cd2665 100644 (file)
@@ -1,6 +1,6 @@
 /* Output generating routines for GDB.
 
-   Copyright (C) 1999-2016 Free Software Foundation, Inc.
+   Copyright (C) 1999-2019 Free Software Foundation, Inc.
 
    Contributed by Cygnus Solutions.
    Written by Fernando Nasser for Cygnus.
 #include "expression.h"                /* For language.h */
 #include "language.h"
 #include "ui-out.h"
+#include "gdbsupport/format.h"
+#include "cli/cli-style.h"
+#include "diagnostics.h"
 
 #include <vector>
 #include <memory>
 #include <string>
 
+namespace {
+
 /* A header of a ui_out_table.  */
 
 class ui_out_hdr
@@ -90,6 +95,8 @@ class ui_out_hdr
   std::string m_header;
 };
 
+} // namespace
+
 /* A level of nesting (either a list or a tuple) in a ui_out output.  */
 
 class ui_out_level
@@ -126,237 +133,278 @@ class ui_out_level
   int m_field_count;
 };
 
-
 /* Tables are special.  Maintain a separate structure that tracks
    their state.  At present an output can only contain a single table
    but that restriction might eventually be lifted.  */
 
-struct ui_out_table
+class ui_out_table
 {
-  /* If on, a table is being generated.  */
-  int flag;
+ public:
+
+  /* States (steps) of a table generation.  */
+
+  enum class state
+  {
+    /* We are generating the table headers.  */
+    HEADERS,
+
+    /* We are generating the table body.  */
+    BODY,
+  };
+
+  explicit ui_out_table (int entry_level, int nr_cols, const std::string &id)
+  : m_state (state::HEADERS),
+    m_entry_level (entry_level),
+    m_nr_cols (nr_cols),
+    m_id (id)
+  {
+  }
+
+  /* Start building the body of the table.  */
+
+  void start_body ();
+
+  /* Add a new header to the table.  */
 
-  /* If on, the body of a table is being generated.  If off, the table
-     header is being generated.  */
-  int body_flag;
+  void append_header (int width, ui_align alignment,
+                     const std::string &col_name, const std::string &col_hdr);
+
+  void start_row ();
+
+  /* Extract the format information for the next header and advance
+     the header iterator.  Return false if there was no next header.  */
+
+  bool get_next_header (int *colno, int *width, ui_align *alignment,
+                      const char **col_hdr);
+
+  bool query_field (int colno, int *width, int *alignment,
+                   const char **col_name) const;
+
+  state current_state () const;
+
+  int entry_level () const;
+
+ private:
+
+  state m_state;
 
   /* The level at which each entry of the table is to be found.  A row
      (a tuple) is made up of entries.  Consequently ENTRY_LEVEL is one
      above that of the table.  */
-  int entry_level;
+  int m_entry_level;
 
   /* Number of table columns (as specified in the table_begin call).  */
-  int columns;
+  int m_nr_cols;
 
   /* String identifying the table (as specified in the table_begin
      call).  */
-  std::string id;
+  std::string m_id;
 
   /* Pointers to the column headers.  */
-  std::vector<std::unique_ptr<ui_out_hdr>> headers;
+  std::vector<std::unique_ptr<ui_out_hdr>> m_headers;
 
   /* Iterator over the headers vector, used when printing successive fields.  */
-  std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator headers_iterator;
-
+  std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator;
 };
 
+/* See ui-out.h.  */
 
-/* The ui_out structure */
+void ui_out_table::start_body ()
+{
+  if (m_state != state::HEADERS)
+    internal_error (__FILE__, __LINE__,
+                   _("extra table_body call not allowed; there must be only "
+                     "one table_body after a table_begin and before a "
+                     "table_end."));
 
-struct ui_out
-  {
-    int flags;
-    /* Specific implementation of ui-out.  */
-    const struct ui_out_impl *impl;
-    void *data;
+  /* Check if the number of defined headers matches the number of expected
+     columns.  */
+  if (m_headers.size () != m_nr_cols)
+    internal_error (__FILE__, __LINE__,
+                   _("number of headers differ from number of table "
+                     "columns."));
+
+  m_state = state::BODY;
+  m_headers_iterator = m_headers.begin ();
+}
+
+/* See ui-out.h.  */
+
+void ui_out_table::append_header (int width, ui_align alignment,
+                                 const std::string &col_name,
+                                 const std::string &col_hdr)
+{
+  if (m_state != state::HEADERS)
+    internal_error (__FILE__, __LINE__,
+                   _("table header must be specified after table_begin and "
+                     "before table_body."));
+
+  std::unique_ptr<ui_out_hdr> header (new ui_out_hdr (m_headers.size () + 1,
+                                                       width, alignment,
+                                                       col_name, col_hdr));
+
+  m_headers.push_back (std::move (header));
+}
+
+/* See ui-out.h.  */
+
+void ui_out_table::start_row ()
+{
+  m_headers_iterator = m_headers.begin ();
+}
+
+/* See ui-out.h.  */
+
+bool ui_out_table::get_next_header (int *colno, int *width, ui_align *alignment,
+                                   const char **col_hdr)
+{
+  /* There may be no headers at all or we may have used all columns.  */
+  if (m_headers_iterator == m_headers.end ())
+    return false;
+
+  ui_out_hdr *hdr = m_headers_iterator->get ();
+
+  *colno = hdr->number ();
+  *width = hdr->min_width ();
+  *alignment = hdr->alignment ();
+  *col_hdr = hdr->header ().c_str ();
 
-    /* Vector to store and track the ui-out levels.  */
-    std::vector<std::unique_ptr<ui_out_level>> levels;
+  /* Advance the header pointer to the next entry.  */
+  m_headers_iterator++;
+
+  return true;
+}
+
+/* See ui-out.h.  */
+
+bool ui_out_table::query_field (int colno, int *width, int *alignment,
+                               const char **col_name) const
+{
+  /* Column numbers are 1-based, so convert to 0-based index.  */
+  int index = colno - 1;
 
-    int level () const
+  if (index >= 0 && index < m_headers.size ())
     {
-      return this->levels.size ();
+      ui_out_hdr *hdr = m_headers[index].get ();
+
+      gdb_assert (colno == hdr->number ());
+
+      *width = hdr->min_width ();
+      *alignment = hdr->alignment ();
+      *col_name = hdr->name ().c_str ();
+
+      return true;
     }
+  else
+    return false;
+}
 
-    /* A table, if any.  At present only a single table is supported.  */
-    struct ui_out_table table;
-  };
+/* See ui-out.h.  */
+
+ui_out_table::state ui_out_table::current_state () const
+{
+  return m_state;
+}
+
+/* See ui-out.h.  */
+
+int ui_out_table::entry_level () const
+{
+  return m_entry_level;
+}
+
+int
+ui_out::level () const
+{
+  return m_levels.size ();
+}
 
 /* The current (inner most) level.  */
-static ui_out_level *
-current_level (struct ui_out *uiout)
+
+ui_out_level *
+ui_out::current_level () const
 {
-  return uiout->levels.back ().get ();
+  return m_levels.back ().get ();
 }
 
 /* Create a new level, of TYPE.  */
-static void
-push_level (struct ui_out *uiout,
-           enum ui_out_type type)
+void
+ui_out::push_level (ui_out_type type)
 {
   std::unique_ptr<ui_out_level> level (new ui_out_level (type));
 
-  uiout->levels.push_back (std::move (level));
+  m_levels.push_back (std::move (level));
 }
 
 /* Discard the current level.  TYPE is the type of the level being
    discarded.  */
-static void
-pop_level (struct ui_out *uiout,
-          enum ui_out_type type)
+void
+ui_out::pop_level (ui_out_type type)
 {
   /* We had better not underflow the buffer.  */
-  gdb_assert (uiout->level () > 0);
-  gdb_assert (current_level (uiout)->type () == type);
-
-  uiout->levels.pop_back ();
-}
-
-/* These are the interfaces to implementation functions.  */
-
-static void uo_table_begin (struct ui_out *uiout, int nbrofcols,
-                           int nr_rows, const char *tblid);
-static void uo_table_body (struct ui_out *uiout);
-static void uo_table_end (struct ui_out *uiout);
-static void uo_table_header (struct ui_out *uiout, int width,
-                            enum ui_align align,
-                            const std::string &col_name,
-                            const std::string &col_hdr);
-static void uo_begin (struct ui_out *uiout,
-                     enum ui_out_type type,
-                     const char *id);
-static void uo_end (struct ui_out *uiout,
-                   enum ui_out_type type);
-static void uo_field_int (struct ui_out *uiout, int fldno, int width,
-                         enum ui_align align, const char *fldname, int value);
-static void uo_field_skip (struct ui_out *uiout, int fldno, int width,
-                          enum ui_align align, const char *fldname);
-static void uo_field_fmt (struct ui_out *uiout, int fldno, int width,
-                         enum ui_align align, const char *fldname,
-                         const char *format, va_list args)
-     ATTRIBUTE_PRINTF (6, 0);
-static void uo_spaces (struct ui_out *uiout, int numspaces);
-static void uo_text (struct ui_out *uiout, const char *string);
-static void uo_message (struct ui_out *uiout,
-                       const char *format, va_list args)
-     ATTRIBUTE_PRINTF (2, 0);
-static void uo_wrap_hint (struct ui_out *uiout, const char *identstring);
-static void uo_flush (struct ui_out *uiout);
-static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream);
-
-/* Prototypes for local functions */
-
-static void append_header_to_list (struct ui_out *uiout, int width,
-                                  enum ui_align alignment,
-                                  const std::string &col_name,
-                                  const std::string &col_hdr);
-static int get_next_header (struct ui_out *uiout, int *colno, int *width,
-                           enum ui_align *alignment, const char **col_hdr);
-static void clear_header_list (struct ui_out *uiout);
-static void clear_table (struct ui_out *uiout);
-static void verify_field (struct ui_out *uiout, int *fldno, int *width,
-                         enum ui_align *align);
-
-/* exported functions (ui_out API) */
+  gdb_assert (m_levels.size () > 0);
+  gdb_assert (current_level ()->type () == type);
+
+  m_levels.pop_back ();
+}
 
 /* Mark beginning of a table.  */
 
-static void
-ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
-                   int nr_rows, const std::string &tblid)
+void
+ui_out::table_begin (int nr_cols, int nr_rows, const std::string &tblid)
 {
-  if (uiout->table.flag)
+  if (m_table_up != nullptr)
     internal_error (__FILE__, __LINE__,
                    _("tables cannot be nested; table_begin found before \
 previous table_end."));
 
-  uiout->table.flag = 1;
-  uiout->table.body_flag = 0;
-  uiout->table.entry_level = uiout->level () + 1;
-  uiout->table.columns = nbrofcols;
-  uiout->table.id = tblid;
+  m_table_up.reset (new ui_out_table (level () + 1, nr_cols, tblid));
 
-  clear_header_list (uiout);
-
-  uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id.c_str ());
+  do_table_begin (nr_cols, nr_rows, tblid.c_str ());
 }
 
 void
-ui_out_table_body (struct ui_out *uiout)
+ui_out::table_header (int width, ui_align alignment,
+                     const std::string &col_name, const std::string &col_hdr)
 {
-  if (!uiout->table.flag)
-    internal_error (__FILE__, __LINE__,
-                   _("table_body outside a table is not valid; it must be \
-after a table_begin and before a table_end."));
-  if (uiout->table.body_flag)
-    internal_error (__FILE__, __LINE__,
-                   _("extra table_body call not allowed; there must be \
-only one table_body after a table_begin and before a table_end."));
-  if (uiout->table.headers.size () != uiout->table.columns)
+  if (m_table_up == nullptr)
     internal_error (__FILE__, __LINE__,
-                   _("number of headers differ from number of table \
-columns."));
+                   _("table_header outside a table is not valid; it must be \
+after a table_begin and before a table_body."));
 
-  uiout->table.body_flag = 1;
+  m_table_up->append_header (width, alignment, col_name, col_hdr);
 
-  uo_table_body (uiout);
+  do_table_header (width, alignment, col_name, col_hdr);
 }
 
-static void
-ui_out_table_end (struct ui_out *uiout)
+void
+ui_out::table_body ()
 {
-  if (!uiout->table.flag)
+  if (m_table_up == nullptr)
     internal_error (__FILE__, __LINE__,
-                   _("misplaced table_end or missing table_begin."));
+                   _("table_body outside a table is not valid; it must be "
+                     "after a table_begin and before a table_end."));
 
-  uiout->table.entry_level = 0;
-  uiout->table.body_flag = 0;
-  uiout->table.flag = 0;
+  m_table_up->start_body ();
 
-  uo_table_end (uiout);
-  clear_table (uiout);
+  do_table_body ();
 }
 
 void
-ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
-                    const std::string &col_name, const std::string &col_hdr)
+ui_out::table_end ()
 {
-  if (!uiout->table.flag || uiout->table.body_flag)
+  if (m_table_up == nullptr)
     internal_error (__FILE__, __LINE__,
-                   _("table header must be specified after table_begin \
-and before table_body."));
-
-  append_header_to_list (uiout, width, alignment, col_name, col_hdr);
-
-  uo_table_header (uiout, width, alignment, col_name, col_hdr);
-}
+                   _("misplaced table_end or missing table_begin."));
 
-static void
-do_cleanup_table_end (void *data)
-{
-  struct ui_out *ui_out = (struct ui_out *) data;
+  do_table_end ();
 
-  ui_out_table_end (ui_out);
-}
-
-struct cleanup *
-make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, int nr_cols,
-                                     int nr_rows, const char *tblid)
-{
-  ui_out_table_begin (ui_out, nr_cols, nr_rows, tblid);
-  return make_cleanup (do_cleanup_table_end, ui_out);
+  m_table_up = nullptr;
 }
 
 void
-ui_out_begin (struct ui_out *uiout,
-             enum ui_out_type type,
-             const char *id)
+ui_out::begin (ui_out_type type, const char *id)
 {
-  if (uiout->table.flag && !uiout->table.body_flag)
-    internal_error (__FILE__, __LINE__,
-                   _("table header or table_body expected; lists must be \
-specified after table_body."));
-
   /* Be careful to verify the ``field'' before the new tuple/list is
      pushed onto the stack.  That way the containing list/table/row is
      verified and not the newly created tuple/list.  This verification
@@ -367,469 +415,441 @@ specified after table_body."));
   {
     int fldno;
     int width;
-    enum ui_align align;
+    ui_align align;
 
-    verify_field (uiout, &fldno, &width, &align);
+    verify_field (&fldno, &width, &align);
   }
 
-  push_level (uiout, type);
+  push_level (type);
 
   /* If the push puts us at the same level as a table row entry, we've
      got a new table row.  Put the header pointer back to the start.  */
-  if (uiout->table.body_flag
-      && uiout->table.entry_level == uiout->level ())
-    uiout->table.headers_iterator = uiout->table.headers.begin ();
+  if (m_table_up != nullptr
+      && m_table_up->current_state () == ui_out_table::state::BODY
+      && m_table_up->entry_level () == level ())
+    m_table_up->start_row ();
 
-  uo_begin (uiout, type, id);
+  do_begin (type, id);
 }
 
 void
-ui_out_end (struct ui_out *uiout,
-           enum ui_out_type type)
-{
-  pop_level (uiout, type);
-
-  uo_end (uiout, type);
-}
-
-struct ui_out_end_cleanup_data
-{
-  struct ui_out *uiout;
-  enum ui_out_type type;
-};
-
-static void
-do_cleanup_end (void *data)
+ui_out::end (ui_out_type type)
 {
-  struct ui_out_end_cleanup_data *end_cleanup_data
-    = (struct ui_out_end_cleanup_data *) data;
+  pop_level (type);
 
-  ui_out_end (end_cleanup_data->uiout, end_cleanup_data->type);
-  xfree (end_cleanup_data);
+  do_end (type);
 }
 
-static struct cleanup *
-make_cleanup_ui_out_end (struct ui_out *uiout,
-                        enum ui_out_type type)
+void
+ui_out::field_signed (const char *fldname, LONGEST value)
 {
-  struct ui_out_end_cleanup_data *end_cleanup_data;
-
-  end_cleanup_data = XNEW (struct ui_out_end_cleanup_data);
-  end_cleanup_data->uiout = uiout;
-  end_cleanup_data->type = type;
-  return make_cleanup (do_cleanup_end, end_cleanup_data);
-}
+  int fldno;
+  int width;
+  ui_align align;
 
-struct cleanup *
-make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout,
-                                    const char *id)
-{
-  ui_out_begin (uiout, ui_out_type_tuple, id);
-  return make_cleanup_ui_out_end (uiout, ui_out_type_tuple);
-}
+  verify_field (&fldno, &width, &align);
 
-struct cleanup *
-make_cleanup_ui_out_list_begin_end (struct ui_out *uiout,
-                                   const char *id)
-{
-  ui_out_begin (uiout, ui_out_type_list, id);
-  return make_cleanup_ui_out_end (uiout, ui_out_type_list);
+  do_field_signed (fldno, width, align, fldname, value);
 }
 
 void
-ui_out_field_int (struct ui_out *uiout,
-                 const char *fldname,
-                 int value)
+ui_out::field_fmt_signed (int input_width, ui_align input_align,
+                         const char *fldname, LONGEST value)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_int (uiout, fldno, width, align, fldname, value);
+  do_field_signed (fldno, input_width, input_align, fldname, value);
 }
 
+/* See ui-out.h.  */
+
 void
-ui_out_field_fmt_int (struct ui_out *uiout,
-                      int input_width,
-                      enum ui_align input_align,
-                     const char *fldname,
-                     int value)
+ui_out::field_unsigned (const char *fldname, ULONGEST value)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_int (uiout, fldno, input_width, input_align, fldname, value);
+  do_field_unsigned (fldno, width, align, fldname, value);
 }
 
 /* Documented in ui-out.h.  */
 
 void
-ui_out_field_core_addr (struct ui_out *uiout,
-                       const char *fldname,
-                       struct gdbarch *gdbarch,
-                       CORE_ADDR address)
+ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch,
+                        CORE_ADDR address)
 {
-  ui_out_field_string (uiout, fldname,
-                      print_core_address (gdbarch, address));
+  field_string (fldname, print_core_address (gdbarch, address),
+               address_style.style ());
 }
 
 void
-ui_out_field_stream (struct ui_out *uiout,
-                    const char *fldname,
-                    struct ui_file *stream)
+ui_out::field_stream (const char *fldname, string_file &stream,
+                     const ui_file_style &style)
 {
-  std::string buffer = ui_file_as_string (stream);
-
-  if (!buffer.empty ())
-    ui_out_field_string (uiout, fldname, buffer.c_str ());
+  if (!stream.empty ())
+    field_string (fldname, stream.c_str (), style);
   else
-    ui_out_field_skip (uiout, fldname);
-  ui_file_rewind (stream);
+    field_skip (fldname);
+  stream.clear ();
 }
 
 /* Used to omit a field.  */
 
 void
-ui_out_field_skip (struct ui_out *uiout,
-                  const char *fldname)
+ui_out::field_skip (const char *fldname)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_skip (uiout, fldno, width, align, fldname);
+  do_field_skip (fldno, width, align, fldname);
 }
 
 void
-ui_out_field_string (struct ui_out *uiout,
-                    const char *fldname,
-                    const char *string)
+ui_out::field_string (const char *fldname, const char *string,
+                     const ui_file_style &style)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_string (uiout, fldno, width, align, fldname, string);
+  do_field_string (fldno, width, align, fldname, string, style);
+}
+
+void
+ui_out::field_string (const char *fldname, const std::string &string)
+{
+  field_string (fldname, string.c_str ());
 }
 
 /* VARARGS */
 void
-ui_out_field_fmt (struct ui_out *uiout,
-                 const char *fldname,
-                 const char *format, ...)
+ui_out::field_fmt (const char *fldname, const char *format, ...)
 {
   va_list args;
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  /* Will not align, but has to call anyway.  */
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
   va_start (args, format);
 
-  uo_field_fmt (uiout, fldno, width, align, fldname, format, args);
+  do_field_fmt (fldno, width, align, fldname, ui_file_style (), format, args);
 
   va_end (args);
 }
 
 void
-ui_out_spaces (struct ui_out *uiout, int numspaces)
-{
-  uo_spaces (uiout, numspaces);
-}
-
-void
-ui_out_text (struct ui_out *uiout,
-            const char *string)
-{
-  uo_text (uiout, string);
-}
-
-void
-ui_out_message (struct ui_out *uiout, const char *format, ...)
+ui_out::field_fmt (const char *fldname, const ui_file_style &style,
+                  const char *format, ...)
 {
   va_list args;
+  int fldno;
+  int width;
+  ui_align align;
 
-  va_start (args, format);
-  uo_message (uiout, format, args);
-  va_end (args);
-}
-
-void
-ui_out_wrap_hint (struct ui_out *uiout, const char *identstring)
-{
-  uo_wrap_hint (uiout, identstring);
-}
-
-void
-ui_out_flush (struct ui_out *uiout)
-{
-  uo_flush (uiout);
-}
-
-int
-ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream)
-{
-  return uo_redirect (uiout, outstream);
-}
-
-/* Test the flags against the mask given.  */
-int
-ui_out_test_flags (struct ui_out *uiout, int mask)
-{
-  return (uiout->flags & mask);
-}
+  verify_field (&fldno, &width, &align);
 
-int
-ui_out_is_mi_like_p (struct ui_out *uiout)
-{
-  return uiout->impl->is_mi_like_p;
-}
+  va_start (args, format);
 
-/* Interface to the implementation functions.  */
+  do_field_fmt (fldno, width, align, fldname, style, format, args);
 
-void
-uo_table_begin (struct ui_out *uiout, int nbrofcols,
-               int nr_rows,
-               const char *tblid)
-{
-  if (!uiout->impl->table_begin)
-    return;
-  uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid);
+  va_end (args);
 }
 
 void
-uo_table_body (struct ui_out *uiout)
+ui_out::spaces (int numspaces)
 {
-  if (!uiout->impl->table_body)
-    return;
-  uiout->impl->table_body (uiout);
+  do_spaces (numspaces);
 }
 
 void
-uo_table_end (struct ui_out *uiout)
+ui_out::text (const char *string)
 {
-  if (!uiout->impl->table_end)
-    return;
-  uiout->impl->table_end (uiout);
+  do_text (string);
 }
 
 void
-uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
-                const std::string &col_name, const std::string &col_hdr)
+ui_out::call_do_message (const ui_file_style &style, const char *format,
+                        ...)
 {
-  if (!uiout->impl->table_header)
-    return;
-  uiout->impl->table_header (uiout, width, align, col_name, col_hdr);
-}
-
-/* Clear the table associated with UIOUT.  */
+  va_list args;
 
-static void
-clear_table (struct ui_out *uiout)
-{
-  uiout->table.id.clear ();
-  clear_header_list (uiout);
-}
+  va_start (args, format);
 
-void
-uo_begin (struct ui_out *uiout,
-         enum ui_out_type type,
-         const char *id)
-{
-  if (uiout->impl->begin == NULL)
-    return;
-  uiout->impl->begin (uiout, type, id);
-}
+  /* Since call_do_message is only used as a helper of vmessage, silence the
+     warning here once instead of at all call sites in vmessage, if we were
+     to put a "format" attribute on call_do_message.  */
+  DIAGNOSTIC_PUSH
+  DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+  do_message (style, format, args);
+  DIAGNOSTIC_POP
 
-void
-uo_end (struct ui_out *uiout,
-       enum ui_out_type type)
-{
-  if (uiout->impl->end == NULL)
-    return;
-  uiout->impl->end (uiout, type);
+  va_end (args);
 }
 
 void
-uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-             const char *fldname,
-             int value)
+ui_out::vmessage (const ui_file_style &in_style, const char *format,
+                 va_list args)
 {
-  if (!uiout->impl->field_int)
-    return;
-  uiout->impl->field_int (uiout, fldno, width, align, fldname, value);
-}
+  format_pieces fpieces (&format, true);
 
-void
-uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-              const char *fldname)
-{
-  if (!uiout->impl->field_skip)
-    return;
-  uiout->impl->field_skip (uiout, fldno, width, align, fldname);
-}
+  ui_file_style style = in_style;
 
-void
-uo_field_string (struct ui_out *uiout, int fldno, int width,
-                enum ui_align align,
-                const char *fldname,
-                const char *string)
-{
-  if (!uiout->impl->field_string)
-    return;
-  uiout->impl->field_string (uiout, fldno, width, align, fldname, string);
+  for (auto &&piece : fpieces)
+    {
+      const char *current_substring = piece.string;
+
+      gdb_assert (piece.n_int_args >= 0 && piece.n_int_args <= 2);
+      int intvals[2] = { 0, 0 };
+      for (int i = 0; i < piece.n_int_args; ++i)
+       intvals[i] = va_arg (args, int);
+
+      /* The only ones we support for now.  */
+      gdb_assert (piece.n_int_args == 0
+                 || piece.argclass == string_arg
+                 || piece.argclass == int_arg
+                 || piece.argclass == long_arg);
+
+      switch (piece.argclass)
+       {
+       case string_arg:
+         {
+           const char *str = va_arg (args, const char *);
+           switch (piece.n_int_args)
+             {
+             case 0:
+               call_do_message (style, current_substring, str);
+               break;
+             case 1:
+               call_do_message (style, current_substring, intvals[0], str);
+               break;
+             case 2:
+               call_do_message (style, current_substring,
+                                intvals[0], intvals[1], str);
+               break;
+             }
+         }
+         break;
+       case wide_string_arg:
+         gdb_assert_not_reached (_("wide_string_arg not supported in vmessage"));
+         break;
+       case wide_char_arg:
+         gdb_assert_not_reached (_("wide_char_arg not supported in vmessage"));
+         break;
+       case long_long_arg:
+         call_do_message (style, current_substring, va_arg (args, long long));
+         break;
+       case int_arg:
+         {
+           int val = va_arg (args, int);
+           switch (piece.n_int_args)
+             {
+             case 0:
+               call_do_message (style, current_substring, val);
+               break;
+             case 1:
+               call_do_message (style, current_substring, intvals[0], val);
+               break;
+             case 2:
+               call_do_message (style, current_substring,
+                                intvals[0], intvals[1], val);
+               break;
+             }
+         }
+         break;
+       case long_arg:
+         {
+           long val = va_arg (args, long);
+           switch (piece.n_int_args)
+             {
+             case 0:
+               call_do_message (style, current_substring, val);
+               break;
+             case 1:
+               call_do_message (style, current_substring, intvals[0], val);
+               break;
+             case 2:
+               call_do_message (style, current_substring,
+                                intvals[0], intvals[1], val);
+               break;
+             }
+         }
+         break;
+       case size_t_arg:
+         {
+           size_t val = va_arg (args, size_t);
+           switch (piece.n_int_args)
+             {
+             case 0:
+               call_do_message (style, current_substring, val);
+               break;
+             case 1:
+               call_do_message (style, current_substring, intvals[0], val);
+               break;
+             case 2:
+               call_do_message (style, current_substring,
+                                intvals[0], intvals[1], val);
+               break;
+             }
+         }
+         break;
+       case double_arg:
+         call_do_message (style, current_substring, va_arg (args, double));
+         break;
+       case long_double_arg:
+         gdb_assert_not_reached (_("long_double_arg not supported in vmessage"));
+         break;
+       case dec32float_arg:
+         gdb_assert_not_reached (_("dec32float_arg not supported in vmessage"));
+         break;
+       case dec64float_arg:
+         gdb_assert_not_reached (_("dec64float_arg not supported in vmessage"));
+         break;
+       case dec128float_arg:
+         gdb_assert_not_reached (_("dec128float_arg not supported in vmessage"));
+         break;
+       case ptr_arg:
+         switch (current_substring[2])
+           {
+           case 'F':
+             {
+               gdb_assert (!test_flags (disallow_ui_out_field));
+               base_field_s *bf = va_arg (args, base_field_s *);
+               switch (bf->kind)
+                 {
+                 case field_kind::FIELD_SIGNED:
+                   {
+                     auto *f = (signed_field_s *) bf;
+                     field_signed (f->name, f->val);
+                   }
+                   break;
+                 case field_kind::FIELD_STRING:
+                   {
+                     auto *f = (string_field_s *) bf;
+                     field_string (f->name, f->str);
+                   }
+                   break;
+                 }
+             }
+             break;
+           case 's':
+             {
+               styled_string_s *ss = va_arg (args, styled_string_s *);
+               call_do_message (ss->style, "%s", ss->str);
+             }
+             break;
+           case '[':
+             style = *va_arg (args, const ui_file_style *);
+             break;
+           case ']':
+             {
+               void *arg = va_arg (args, void *);
+               gdb_assert (arg == nullptr);
+
+               style = {};
+             }
+             break;
+           default:
+             call_do_message (style, current_substring, va_arg (args, void *));
+             break;
+           }
+         break;
+       case literal_piece:
+         /* Print a portion of the format string that has no
+            directives.  Note that this will not include any ordinary
+            %-specs, but it might include "%%".  That is why we use
+            call_do_message here.  Also, we pass a dummy argument
+            because some platforms have modified GCC to include
+            -Wformat-security by default, which will warn here if
+            there is no argument.  */
+         call_do_message (style, current_substring, 0);
+         break;
+       default:
+         internal_error (__FILE__, __LINE__,
+                         _("failed internal consistency check"));
+       }
+    }
 }
 
 void
-uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-             const char *fldname,
-             const char *format,
-             va_list args)
+ui_out::message (const char *format, ...)
 {
-  if (!uiout->impl->field_fmt)
-    return;
-  uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args);
-}
+  va_list args;
+  va_start (args, format);
 
-void
-uo_spaces (struct ui_out *uiout, int numspaces)
-{
-  if (!uiout->impl->spaces)
-    return;
-  uiout->impl->spaces (uiout, numspaces);
-}
+  vmessage (ui_file_style (), format, args);
 
-void
-uo_text (struct ui_out *uiout,
-        const char *string)
-{
-  if (!uiout->impl->text)
-    return;
-  uiout->impl->text (uiout, string);
+  va_end (args);
 }
 
 void
-uo_message (struct ui_out *uiout,
-           const char *format,
-           va_list args)
+ui_out::wrap_hint (const char *identstring)
 {
-  if (!uiout->impl->message)
-    return;
-  uiout->impl->message (uiout, format, args);
+  do_wrap_hint (identstring);
 }
 
 void
-uo_wrap_hint (struct ui_out *uiout, const char *identstring)
+ui_out::flush ()
 {
-  if (!uiout->impl->wrap_hint)
-    return;
-  uiout->impl->wrap_hint (uiout, identstring);
+  do_flush ();
 }
 
 void
-uo_flush (struct ui_out *uiout)
+ui_out::redirect (ui_file *outstream)
 {
-  if (!uiout->impl->flush)
-    return;
-  uiout->impl->flush (uiout);
+  do_redirect (outstream);
 }
 
-int
-uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
-{
-  if (!uiout->impl->redirect)
-    return -1;
-  return uiout->impl->redirect (uiout, outstream);
-}
-
-/* local functions */
-
-/* List of column headers manipulation routines.  */
-
-static void
-clear_header_list (struct ui_out *uiout)
+/* Test the flags against the mask given.  */
+ui_out_flags
+ui_out::test_flags (ui_out_flags mask)
 {
-  uiout->table.headers.clear ();
-  uiout->table.headers_iterator = uiout->table.headers.end ();
+  return m_flags & mask;
 }
 
-static void
-append_header_to_list (struct ui_out *uiout,
-                      int width,
-                      enum ui_align alignment,
-                      const std::string &col_name,
-                      const std::string &col_hdr)
+bool
+ui_out::is_mi_like_p () const
 {
-  std::unique_ptr<ui_out_hdr> temphdr(
-    new ui_out_hdr (uiout->table.headers.size () + 1, width,
-                   alignment, col_name, col_hdr));
-
-  uiout->table.headers.push_back (std::move (temphdr));
+  return do_is_mi_like_p ();
 }
 
-/* Extract the format information for the NEXT header and advance
-   the header pointer.  Return 0 if there was no next header.  */
-
-static int
-get_next_header (struct ui_out *uiout,
-                int *colno,
-                int *width,
-                enum ui_align *alignment,
-                const char **col_hdr)
-{
-  /* There may be no headers at all or we may have used all columns.  */
-  if (uiout->table.headers_iterator == uiout->table.headers.end ())
-    return 0;
-
-  ui_out_hdr *hdr = uiout->table.headers_iterator->get ();
-
-  *colno = hdr->number ();
-  *width = hdr->min_width ();
-  *alignment = hdr->alignment ();
-  *col_hdr = hdr->header ().c_str ();
-
-  /* Advance the header pointer to the next entry.  */
-  uiout->table.headers_iterator++;
-
-  return 1;
-}
-
-
 /* Verify that the field/tuple/list is correctly positioned.  Return
    the field number and corresponding alignment (if
    available/applicable).  */
 
-static void
-verify_field (struct ui_out *uiout, int *fldno, int *width,
-             enum ui_align *align)
+void
+ui_out::verify_field (int *fldno, int *width, ui_align *align)
 {
-  ui_out_level *current = current_level (uiout);
+  ui_out_level *current = current_level ();
   const char *text;
 
-  if (uiout->table.flag)
+  if (m_table_up != nullptr
+      && m_table_up->current_state () != ui_out_table::state::BODY)
     {
-      if (!uiout->table.body_flag)
-       internal_error (__FILE__, __LINE__,
-                       _("table_body missing; table fields must be \
+      internal_error (__FILE__, __LINE__,
+                     _("table_body missing; table fields must be \
 specified after table_body and inside a list."));
     }
 
   current->inc_field_count ();
 
-  if (uiout->table.body_flag
-      && uiout->table.entry_level == uiout->level ()
-      && get_next_header (uiout, fldno, width, align, &text))
+  if (m_table_up != nullptr
+      && m_table_up->current_state () == ui_out_table::state::BODY
+      && m_table_up->entry_level () == level ()
+      && m_table_up->get_next_header (fldno, width, align, &text))
     {
       if (*fldno != current->field_count ())
        internal_error (__FILE__, __LINE__,
@@ -843,60 +863,27 @@ specified after table_body and inside a list."));
     }
 }
 
-
-/* Access to ui-out members data.  */
-
-void *
-ui_out_data (struct ui_out *uiout)
-{
-  return uiout->data;
-}
-
 /* Access table field parameters.  */
-int
-ui_out_query_field (struct ui_out *uiout, int colno,
-                   int *width, int *alignment, const char **col_name)
-{
-  if (!uiout->table.flag)
-    return 0;
 
-  /* Column numbers are 1-based, so convert to 0-based index.  */
-  int index = colno - 1;
-
-  if (index >= 0 && index < uiout->table.headers.size ())
-    {
-      ui_out_hdr *hdr = uiout->table.headers[index].get ();
-
-      gdb_assert (colno == hdr->number ());
-
-      *width = hdr->min_width ();
-      *alignment = hdr->alignment ();
-      *col_name = hdr->name ().c_str ();
+bool
+ui_out::query_table_field (int colno, int *width, int *alignment,
+                          const char **col_name)
+{
+  if (m_table_up == nullptr)
+    return false;
 
-      return 1;
-    }
-  else
-    return 0;
+  return m_table_up->query_field (colno, width, alignment, col_name);
 }
 
-/* Initialize private members at startup.  */
+/* The constructor.  */
 
-struct ui_out *
-ui_out_new (const struct ui_out_impl *impl, void *data,
-           int flags)
+ui_out::ui_out (ui_out_flags flags)
+: m_flags (flags)
 {
-  struct ui_out *uiout = new ui_out ();
-
-  uiout->data = data;
-  uiout->impl = impl;
-  uiout->flags = flags;
-  uiout->table.flag = 0;
-  uiout->table.body_flag = 0;
-
   /* Create the ui-out level #1, the default level.  */
-  push_level (uiout, ui_out_type_tuple);
-
-  uiout->table.headers_iterator = uiout->table.headers.end ();
+  push_level (ui_out_type_tuple);
+}
 
-  return uiout;
+ui_out::~ui_out ()
+{
 }
This page took 0.036036 seconds and 4 git commands to generate.