/* Output generating routines for GDB.

   Copyright (C) 1999-2021 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 "defs.h"
#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
{
 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 (__FILE__, __LINE__,
		    _("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 (__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 ();

  /* 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)
{
  std::unique_ptr<ui_out_level> level (new 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 (__FILE__, __LINE__,
		    _("tables cannot be nested; table_begin found before \
previous table_end."));

  m_table_up.reset (new 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 (__FILE__, __LINE__,
		    _("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 (__FILE__, __LINE__,
		    _("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 (__FILE__, __LINE__,
		    _("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)
{
  int fldno;
  int width;
  ui_align align;

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

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

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

/* 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::spaces (int numspaces)
{
  do_spaces (numspaces);
}

void
ui_out::text (const char *string)
{
  do_text (string);
}

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 (__FILE__, __LINE__,
			  _("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);
}

void
ui_out::wrap_hint (const char *identstring)
{
  do_wrap_hint (identstring);
}

void
ui_out::flush ()
{
  do_flush ();
}

void
ui_out::redirect (ui_file *outstream)
{
  do_redirect (outstream);
}

/* Test the flags against the mask given.  */
ui_out_flags
ui_out::test_flags (ui_out_flags mask)
{
  return m_flags & mask;
}

bool
ui_out::is_mi_like_p () const
{
  return do_is_mi_like_p ();
}

/* 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 (__FILE__, __LINE__,
		      _("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 (__FILE__, __LINE__,
			_("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 ()
{
}
