/* Output generating routines for GDB.

   Copyright (C) 1999-2024 Free Software Foundation, Inc.

   Contributed by Cygnus Solutions.
   Written by Fernando Nasser for Cygnus.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "expression.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
{
 public:

  explicit ui_out_hdr (int number, int min_width, ui_align alignment,
		       const std::string &name, const std::string &header)
  : m_number (number),
    m_min_width (min_width),
    m_alignment (alignment),
    m_name (name),
    m_header (header)
  {
  }

  int number () const
  {
    return m_number;
  }

  int min_width () const
  {
    return m_min_width;
  }

  ui_align alignment () const
  {
    return m_alignment;
  }

  const std::string &header () const
  {
    return m_header;
  }

  const std::string &name () const
  {
    return m_name;
  }

 private:

  /* The number of the table column this header represents, 1-based.  */
  int m_number;

  /* Minimal column width in characters.  May or may not be applicable,
     depending on the actual implementation of ui_out.  */
  int m_min_width;

  /* Alignment of the content in the column.  May or may not be applicable,
     depending on the actual implementation of ui_out.  */
  ui_align m_alignment;

  /* Internal column name, used to internally refer to the column.  */
  std::string m_name;

  /* Printed header text of the column.  */
  std::string m_header;
};

} // namespace

/* A level of nesting (either a list or a tuple) in a ui_out output.  */

class ui_out_level
{
 public:

  explicit ui_out_level (ui_out_type type)
  : m_type (type),
    m_field_count (0)
  {
  }

  ui_out_type type () const
  {
    return m_type;
  }

  int field_count () const
  {
    return m_field_count;
  }

  void inc_field_count ()
  {
    m_field_count++;
  }

 private:

  /* The type of this level.  */
  ui_out_type m_type;

  /* Count each field; the first element is for non-list fields.  */
  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.  */

class ui_out_table
{
 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.  */

  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 m_entry_level;

  /* Number of table columns (as specified in the table_begin call).  */
  int m_nr_cols;

  /* String identifying the table (as specified in the table_begin
     call).  */
  std::string m_id;

  /* Pointers to the column 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 m_headers_iterator;
};

/* See ui-out.h.  */

void ui_out_table::start_body ()
{
  if (m_state != state::HEADERS)
    internal_error (_("extra table_body call not allowed; there must be only "
		      "one table_body after a table_begin and before a "
		      "table_end."));

  /* Check if the number of defined headers matches the number of expected
     columns.  */
  if (m_headers.size () != m_nr_cols)
    internal_error (_("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 (_("table header must be specified after table_begin and "
		      "before table_body."));

  auto header = std::make_unique<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 ();

  /* 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;

  if (index >= 0 && index < m_headers.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;
}

/* 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.  */

ui_out_level *
ui_out::current_level () const
{
  return m_levels.back ().get ();
}

/* Create a new level, of TYPE.  */
void
ui_out::push_level (ui_out_type type)
{
  auto level = std::make_unique<ui_out_level> (type);

  m_levels.push_back (std::move (level));
}

/* Discard the current level.  TYPE is the type of the level being
   discarded.  */
void
ui_out::pop_level (ui_out_type type)
{
  /* We had better not underflow the buffer.  */
  gdb_assert (m_levels.size () > 0);
  gdb_assert (current_level ()->type () == type);

  m_levels.pop_back ();
}

/* Mark beginning of a table.  */

void
ui_out::table_begin (int nr_cols, int nr_rows, const std::string &tblid)
{
  if (m_table_up != nullptr)
    internal_error (_("tables cannot be nested; table_begin found before \
previous table_end."));

  m_table_up = std::make_unique<ui_out_table> (level () + 1, nr_cols, tblid);

  do_table_begin (nr_cols, nr_rows, tblid.c_str ());
}

void
ui_out::table_header (int width, ui_align alignment,
		      const std::string &col_name, const std::string &col_hdr)
{
  if (m_table_up == nullptr)
    internal_error (_("table_header outside a table is not valid; it must be \
after a table_begin and before a table_body."));

  m_table_up->append_header (width, alignment, col_name, col_hdr);

  do_table_header (width, alignment, col_name, col_hdr);
}

void
ui_out::table_body ()
{
  if (m_table_up == nullptr)
    internal_error (_("table_body outside a table is not valid; it must be "
		      "after a table_begin and before a table_end."));

  m_table_up->start_body ();

  do_table_body ();
}

void
ui_out::table_end ()
{
  if (m_table_up == nullptr)
    internal_error (_("misplaced table_end or missing table_begin."));

  do_table_end ();

  m_table_up = nullptr;
}

void
ui_out::begin (ui_out_type type, const char *id)
{
  /* 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
     is needed (at least) for the case where a table row entry
     contains either a tuple/list.  For that case bookkeeping such as
     updating the column count or advancing to the next heading still
     needs to be performed.  */
  {
    int fldno;
    int width;
    ui_align align;

    verify_field (&fldno, &width, &align);
  }

  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 (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 ();

  do_begin (type, id);
}

void
ui_out::end (ui_out_type type)
{
  pop_level (type);

  do_end (type);
}

void
ui_out::field_signed (const char *fldname, LONGEST value,
		      const ui_file_style &style)
{
  int fldno;
  int width;
  ui_align align;

  verify_field (&fldno, &width, &align);

  do_field_signed (fldno, width, align, fldname, value, style);
}

void
ui_out::field_fmt_signed (int input_width, ui_align input_align,
			  const char *fldname, LONGEST value)
{
  int fldno;
  int width;
  ui_align align;

  verify_field (&fldno, &width, &align);

  do_field_signed (fldno, input_width, input_align, fldname, value,
		   ui_file_style ());
}

/* See ui-out.h.  */

void
ui_out::field_unsigned (const char *fldname, ULONGEST value)
{
  int fldno;
  int width;
  ui_align align;

  verify_field (&fldno, &width, &align);

  do_field_unsigned (fldno, width, align, fldname, value);
}

/* Documented in ui-out.h.  */

void
ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch,
			 CORE_ADDR address)
{
  field_string (fldname, print_core_address (gdbarch, address),
		address_style.style ());
}

void
ui_out::field_stream (const char *fldname, string_file &stream,
		      const ui_file_style &style)
{
  if (!stream.empty ())
    field_string (fldname, stream.c_str (), style);
  else
    field_skip (fldname);
  stream.clear ();
}

/* Used to omit a field.  */

void
ui_out::field_skip (const char *fldname)
{
  int fldno;
  int width;
  ui_align align;

  verify_field (&fldno, &width, &align);

  do_field_skip (fldno, width, align, fldname);
}

void
ui_out::field_string (const char *fldname, const char *string,
		      const ui_file_style &style)
{
  int fldno;
  int width;
  ui_align align;

  verify_field (&fldno, &width, &align);

  do_field_string (fldno, width, align, fldname, string, style);
}

/* VARARGS */
void
ui_out::field_fmt (const char *fldname, const char *format, ...)
{
  va_list args;
  int fldno;
  int width;
  ui_align align;

  verify_field (&fldno, &width, &align);

  va_start (args, format);

  do_field_fmt (fldno, width, align, fldname, ui_file_style (), format, args);

  va_end (args);
}

void
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;

  verify_field (&fldno, &width, &align);

  va_start (args, format);

  do_field_fmt (fldno, width, align, fldname, style, format, args);

  va_end (args);
}

void
ui_out::call_do_message (const ui_file_style &style, const char *format,
			 ...)
{
  va_list args;

  va_start (args, format);

  /* 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

  va_end (args);
}

void
ui_out::vmessage (const ui_file_style &in_style, const char *format,
		  va_list args)
{
  format_pieces fpieces (&format, true);

  ui_file_style style = in_style;

  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 (_("failed internal consistency check"));
	}
    }
}

void
ui_out::message (const char *format, ...)
{
  va_list args;
  va_start (args, format);

  vmessage (ui_file_style (), format, args);

  va_end (args);
}

/* Verify that the field/tuple/list is correctly positioned.  Return
   the field number and corresponding alignment (if
   available/applicable).  */

void
ui_out::verify_field (int *fldno, int *width, ui_align *align)
{
  ui_out_level *current = current_level ();
  const char *text;

  if (m_table_up != nullptr
      && m_table_up->current_state () != ui_out_table::state::BODY)
    {
      internal_error (_("table_body missing; table fields must be \
specified after table_body and inside a list."));
    }

  current->inc_field_count ();

  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 (_("ui-out internal error in handling headers."));
    }
  else
    {
      *width = 0;
      *align = ui_noalign;
      *fldno = current->field_count ();
    }
}

/* Access table field parameters.  */

bool
ui_out::query_table_field (int colno, int *width, int *alignment,
			   const char **col_name)
{
  if (m_table_up == nullptr)
    return false;

  return m_table_up->query_field (colno, width, alignment, col_name);
}

/* The constructor.  */

ui_out::ui_out (ui_out_flags flags)
: m_flags (flags)
{
  /* Create the ui-out level #1, the default level.  */
  push_level (ui_out_type_tuple);
}

ui_out::~ui_out ()
{
}

/* See ui-out.h.  */

void
buffer_group::output_unit::flush () const
{
  if (!m_msg.empty ())
    m_stream->puts (m_msg.c_str ());

  if (m_wrap_hint >= 0)
    m_stream->wrap_here (m_wrap_hint);

  if (m_flush)
    m_stream->flush ();
}

/* See ui-out.h.  */

void
buffer_group::write (const char *buf, long length_buf, ui_file *stream)
{
  /* Record each line separately.  */
  for (size_t prev = 0, cur = 0; cur < length_buf; ++cur)
    if (buf[cur] == '\n' || cur == length_buf - 1)
      {
	std::string msg (buf + prev, cur - prev + 1);

	if (m_buffered_output.size () > 0
	    && m_buffered_output.back ().m_wrap_hint == -1
	    && m_buffered_output.back ().m_stream == stream
	    && m_buffered_output.back ().m_msg.size () > 0
	    && m_buffered_output.back ().m_msg.back () != '\n')
	  m_buffered_output.back ().m_msg.append (msg);
	else
	  m_buffered_output.emplace_back (msg).m_stream = stream;
	prev = cur + 1;
      }
}

/* See ui-out.h.  */

void
buffer_group::wrap_here (int indent, ui_file *stream)
{
  m_buffered_output.emplace_back ("", indent).m_stream = stream;
}

/* See ui-out.h.  */

void
buffer_group::flush_here (ui_file *stream)
{
  m_buffered_output.emplace_back ("", -1, true).m_stream = stream;
}

/* See ui-out.h.  */

ui_file *
get_unbuffered (ui_file *stream)
{
  buffering_file *buf = dynamic_cast<buffering_file *> (stream);

  if (buf == nullptr)
    return stream;

  return get_unbuffered (buf->stream ());
}

buffered_streams::buffered_streams (buffer_group *group, ui_out *uiout)
  : m_buffered_stdout (group, gdb_stdout),
    m_buffered_stderr (group, gdb_stderr),
    m_buffered_stdlog (group, gdb_stdlog),
    m_buffered_stdtarg (group, gdb_stdtarg),
    m_uiout (uiout)
{
  gdb_stdout = &m_buffered_stdout;
  gdb_stderr = &m_buffered_stderr;
  gdb_stdlog = &m_buffered_stdlog;
  gdb_stdtarg = &m_buffered_stdtarg;

  ui_file *stream = current_uiout->current_stream ();
  if (stream != nullptr)
    {
      m_buffered_current_uiout.emplace (group, stream);
      current_uiout->redirect (&(*m_buffered_current_uiout));
    }

  stream = m_uiout->current_stream ();
  if (stream != nullptr && current_uiout != m_uiout)
    {
      m_buffered_uiout.emplace (group, stream);
      m_uiout->redirect (&(*m_buffered_uiout));
    }

  m_buffers_in_place = true;
}

/* See ui-out.h.  */

void
buffered_streams::remove_buffers ()
{
  if (!m_buffers_in_place)
    return;

  m_buffers_in_place = false;

  gdb_stdout = m_buffered_stdout.stream ();
  gdb_stderr = m_buffered_stderr.stream ();
  gdb_stdlog = m_buffered_stdlog.stream ();
  gdb_stdtarg = m_buffered_stdtarg.stream ();

  if (m_buffered_current_uiout.has_value ())
    current_uiout->redirect (nullptr);

  if (m_buffered_uiout.has_value ())
    m_uiout->redirect (nullptr);
}

buffer_group::buffer_group (ui_out *uiout)
  : m_buffered_streams (new buffered_streams (this, uiout))
{ /* Nothing.  */ }

/* See ui-out.h.  */

void
buffer_group::flush () const
{
  m_buffered_streams->remove_buffers ();

  for (const output_unit &ou : m_buffered_output)
    ou.flush ();
}
