/* Output generating routines for GDB CLI.

   Copyright (C) 1999-2014 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 <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;
}
