/* Output generating routines for GDB CLI.

   Copyright (C) 1999-2013 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 "ui-out.h"
#include "cli-out.h"
#include "gdb_string.h"
#include "gdb_assert.h"
#include "vec.h"

typedef struct cli_ui_out_data cli_out_data;


/* Prototypes for local functions */

static void cli_text (struct ui_out *uiout, const char *string);

static void field_separator (void);

static void out_field_fmt (struct ui_out *uiout, int fldno,
			   const char *fldname,
			   const char *format,...) ATTRIBUTE_PRINTF (4, 5);

/* These are the CLI output functions */

/* Mark beginning of a table */

static void
cli_table_begin (struct ui_out *uiout, int nbrofcols,
		 int nr_rows,
		 const char *tblid)
{
  cli_out_data *data = ui_out_data (uiout);

  if (nr_rows == 0)
    data->suppress_output = 1;
  else
    /* Only the table suppresses the output and, fortunately, a table
       is not a recursive data structure.  */
    gdb_assert (data->suppress_output == 0);
}

/* Mark beginning of a table body */

static void
cli_table_body (struct ui_out *uiout)
{
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;
  /* first, close the table header line */
  cli_text (uiout, "\n");
}

/* Mark end of a table */

static void
cli_table_end (struct ui_out *uiout)
{
  cli_out_data *data = ui_out_data (uiout);

  data->suppress_output = 0;
}

/* Specify table header */

static void
cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
		  const char *col_name,
		  const char *colhdr)
{
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;

  /* Always go through the function pointer (virtual function call).
     We may have been extended.  */
  uo_field_string (uiout, 0, width, alignment, 0, colhdr);
}

/* Mark beginning of a list */

static void
cli_begin (struct ui_out *uiout,
	   enum ui_out_type type,
	   int level,
	   const char *id)
{
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;
}

/* Mark end of a list */

static void
cli_end (struct ui_out *uiout,
	 enum ui_out_type type,
	 int level)
{
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;
}

/* output an int field */

static void
cli_field_int (struct ui_out *uiout, int fldno, int width,
	       enum ui_align alignment,
	       const char *fldname, int value)
{
  char buffer[20];	/* FIXME: how many chars long a %d can become? */
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;
  xsnprintf (buffer, sizeof (buffer), "%d", value);

  /* Always go through the function pointer (virtual function call).
     We may have been extended.  */
  uo_field_string (uiout, fldno, width, alignment, fldname, buffer);
}

/* used to ommit a field */

static void
cli_field_skip (struct ui_out *uiout, int fldno, int width,
		enum ui_align alignment,
		const char *fldname)
{
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;

  /* Always go through the function pointer (virtual function call).
     We may have been extended.  */
  uo_field_string (uiout, fldno, width, alignment, fldname, "");
}

/* other specific cli_field_* end up here so alignment and field
   separators are both handled by cli_field_string */

static void
cli_field_string (struct ui_out *uiout,
		  int fldno,
		  int width,
		  enum ui_align align,
		  const char *fldname,
		  const char *string)
{
  int before = 0;
  int after = 0;
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;

  if ((align != ui_noalign) && string)
    {
      before = width - strlen (string);
      if (before <= 0)
	before = 0;
      else
	{
	  if (align == ui_right)
	    after = 0;
	  else if (align == ui_left)
	    {
	      after = before;
	      before = 0;
	    }
	  else
	    /* ui_center */
	    {
	      after = before / 2;
	      before -= after;
	    }
	}
    }

  if (before)
    ui_out_spaces (uiout, before);
  if (string)
    out_field_fmt (uiout, fldno, fldname, "%s", string);
  if (after)
    ui_out_spaces (uiout, after);

  if (align != ui_noalign)
    field_separator ();
}

/* This is the only field function that does not align.  */

static void ATTRIBUTE_PRINTF (6, 0)
cli_field_fmt (struct ui_out *uiout, int fldno,
	       int width, enum ui_align align,
	       const char *fldname,
	       const char *format,
	       va_list args)
{
  cli_out_data *data = ui_out_data (uiout);
  struct ui_file *stream;

  if (data->suppress_output)
    return;

  stream = VEC_last (ui_filep, data->streams);
  vfprintf_filtered (stream, format, args);

  if (align != ui_noalign)
    field_separator ();
}

static void
cli_spaces (struct ui_out *uiout, int numspaces)
{
  cli_out_data *data = ui_out_data (uiout);
  struct ui_file *stream;

  if (data->suppress_output)
    return;

  stream = VEC_last (ui_filep, data->streams);
  print_spaces_filtered (numspaces, stream);
}

static void
cli_text (struct ui_out *uiout, const char *string)
{
  cli_out_data *data = ui_out_data (uiout);
  struct ui_file *stream;

  if (data->suppress_output)
    return;

  stream = VEC_last (ui_filep, data->streams);
  fputs_filtered (string, stream);
}

static void ATTRIBUTE_PRINTF (3, 0)
cli_message (struct ui_out *uiout, int verbosity,
	     const char *format, va_list args)
{
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;

  if (ui_out_get_verblvl (uiout) >= verbosity)
    {
      struct ui_file *stream = VEC_last (ui_filep, data->streams);

      vfprintf_unfiltered (stream, format, args);
    }
}

static void
cli_wrap_hint (struct ui_out *uiout, char *identstring)
{
  cli_out_data *data = ui_out_data (uiout);

  if (data->suppress_output)
    return;
  wrap_here (identstring);
}

static void
cli_flush (struct ui_out *uiout)
{
  cli_out_data *data = ui_out_data (uiout);
  struct ui_file *stream = VEC_last (ui_filep, data->streams);

  gdb_flush (stream);
}

/* OUTSTREAM as non-NULL will push OUTSTREAM on the stack of output streams
   and make it therefore active.  OUTSTREAM as NULL will pop the last pushed
   output stream; it is an internal error if it does not exist.  */

static int
cli_redirect (struct ui_out *uiout, struct ui_file *outstream)
{
  cli_out_data *data = ui_out_data (uiout);

  if (outstream != NULL)
    VEC_safe_push (ui_filep, data->streams, outstream);
  else
    VEC_pop (ui_filep, data->streams);

  return 0;
}

/* local functions */

/* Like cli_field_fmt, but takes a variable number of args
   and makes a va_list and does not insert a separator.  */

/* VARARGS */
static void
out_field_fmt (struct ui_out *uiout, int fldno,
	       const char *fldname,
	       const char *format,...)
{
  cli_out_data *data = ui_out_data (uiout);
  struct ui_file *stream = VEC_last (ui_filep, data->streams);
  va_list args;

  va_start (args, format);
  vfprintf_filtered (stream, format, args);

  va_end (args);
}

/* Access to ui_out format private members.  */

static void
field_separator (void)
{
  cli_out_data *data = ui_out_data (current_uiout);
  struct ui_file *stream = VEC_last (ui_filep, data->streams);

  fputc_filtered (' ', stream);
}

/* This is the CLI ui-out implementation functions vector */

/* FIXME: This can be initialized dynamically after default is set to
   handle initial output in main.c */

struct ui_out_impl cli_ui_out_impl =
{
  cli_table_begin,
  cli_table_body,
  cli_table_end,
  cli_table_header,
  cli_begin,
  cli_end,
  cli_field_int,
  cli_field_skip,
  cli_field_string,
  cli_field_fmt,
  cli_spaces,
  cli_text,
  cli_message,
  cli_wrap_hint,
  cli_flush,
  cli_redirect,
  0,
  0, /* Does not need MI hacks (i.e. needs CLI hacks).  */
};

/* Constructor for a `cli_out_data' object.  */

void
cli_out_data_ctor (cli_out_data *self, struct ui_file *stream)
{
  gdb_assert (stream != NULL);

  self->streams = NULL;
  VEC_safe_push (ui_filep, self->streams, stream);

  self->suppress_output = 0;
}

/* Initialize private members at startup.  */

struct ui_out *
cli_out_new (struct ui_file *stream)
{
  int flags = ui_source_list;
  cli_out_data *data = XMALLOC (cli_out_data);

  cli_out_data_ctor (data, stream);
  return ui_out_new (&cli_ui_out_impl, data, flags);
}

struct ui_file *
cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
{
  cli_out_data *data = ui_out_data (uiout);
  struct ui_file *old;
  
  old = VEC_pop (ui_filep, data->streams);
  VEC_quick_push (ui_filep, data->streams, stream);

  return old;
}
