198944Sobrien/* Output generating routines for GDB CLI.
2130803Smarcel
3130803Smarcel   Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
4130803Smarcel
598944Sobrien   Contributed by Cygnus Solutions.
698944Sobrien   Written by Fernando Nasser for Cygnus.
798944Sobrien
898944Sobrien   This file is part of GDB.
998944Sobrien
1098944Sobrien   This program is free software; you can redistribute it and/or modify
1198944Sobrien   it under the terms of the GNU General Public License as published by
1298944Sobrien   the Free Software Foundation; either version 2 of the License, or
1398944Sobrien   (at your option) any later version.
1498944Sobrien
1598944Sobrien   This program is distributed in the hope that it will be useful,
1698944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1798944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1898944Sobrien   GNU General Public License for more details.
1998944Sobrien
2098944Sobrien   You should have received a copy of the GNU General Public License
2198944Sobrien   along with this program; if not, write to the Free Software
2298944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2398944Sobrien   Boston, MA 02111-1307, USA.  */
2498944Sobrien
2598944Sobrien#include "defs.h"
2698944Sobrien#include "ui-out.h"
2798944Sobrien#include "cli-out.h"
2898944Sobrien#include "gdb_string.h"
2998944Sobrien#include "gdb_assert.h"
3098944Sobrien
3198944Sobrienstruct ui_out_data
3298944Sobrien  {
3398944Sobrien    struct ui_file *stream;
34130803Smarcel    struct ui_file *original_stream;
3598944Sobrien    int suppress_output;
3698944Sobrien  };
37130803Smarceltypedef struct ui_out_data cli_out_data;
3898944Sobrien
3998944Sobrien/* These are the CLI output functions */
4098944Sobrien
4198944Sobrienstatic void cli_table_begin (struct ui_out *uiout, int nbrofcols,
4298944Sobrien			     int nr_rows, const char *tblid);
4398944Sobrienstatic void cli_table_body (struct ui_out *uiout);
4498944Sobrienstatic void cli_table_end (struct ui_out *uiout);
4598944Sobrienstatic void cli_table_header (struct ui_out *uiout, int width,
4698944Sobrien			      enum ui_align alig, const char *col_name,
4798944Sobrien			      const char *colhdr);
4898944Sobrienstatic void cli_begin (struct ui_out *uiout, enum ui_out_type type,
4998944Sobrien		       int level, const char *lstid);
5098944Sobrienstatic void cli_end (struct ui_out *uiout, enum ui_out_type type, int level);
5198944Sobrienstatic void cli_field_int (struct ui_out *uiout, int fldno, int width,
5298944Sobrien			   enum ui_align alig, const char *fldname, int value);
5398944Sobrienstatic void cli_field_skip (struct ui_out *uiout, int fldno, int width,
5498944Sobrien			    enum ui_align alig, const char *fldname);
5598944Sobrienstatic void cli_field_string (struct ui_out *uiout, int fldno, int width,
5698944Sobrien			      enum ui_align alig, const char *fldname,
5798944Sobrien			      const char *string);
5898944Sobrienstatic void cli_field_fmt (struct ui_out *uiout, int fldno,
5998944Sobrien			   int width, enum ui_align align,
6098944Sobrien			   const char *fldname, const char *format,
6198944Sobrien			   va_list args);
6298944Sobrienstatic void cli_spaces (struct ui_out *uiout, int numspaces);
6398944Sobrienstatic void cli_text (struct ui_out *uiout, const char *string);
6498944Sobrienstatic void cli_message (struct ui_out *uiout, int verbosity,
6598944Sobrien			 const char *format, va_list args);
6698944Sobrienstatic void cli_wrap_hint (struct ui_out *uiout, char *identstring);
6798944Sobrienstatic void cli_flush (struct ui_out *uiout);
68130803Smarcelstatic int cli_redirect (struct ui_out *uiout, struct ui_file *outstream);
6998944Sobrien
7098944Sobrien/* This is the CLI ui-out implementation functions vector */
7198944Sobrien
7298944Sobrien/* FIXME: This can be initialized dynamically after default is set to
7398944Sobrien   handle initial output in main.c */
7498944Sobrien
7598944Sobrienstatic struct ui_out_impl cli_ui_out_impl =
7698944Sobrien{
7798944Sobrien  cli_table_begin,
7898944Sobrien  cli_table_body,
7998944Sobrien  cli_table_end,
8098944Sobrien  cli_table_header,
8198944Sobrien  cli_begin,
8298944Sobrien  cli_end,
8398944Sobrien  cli_field_int,
8498944Sobrien  cli_field_skip,
8598944Sobrien  cli_field_string,
8698944Sobrien  cli_field_fmt,
8798944Sobrien  cli_spaces,
8898944Sobrien  cli_text,
8998944Sobrien  cli_message,
9098944Sobrien  cli_wrap_hint,
9198944Sobrien  cli_flush,
92130803Smarcel  cli_redirect,
9398944Sobrien  0, /* Does not need MI hacks (i.e. needs CLI hacks).  */
9498944Sobrien};
9598944Sobrien
9698944Sobrien/* Prototypes for local functions */
9798944Sobrien
9898944Sobrienextern void _initialize_cli_out (void);
9998944Sobrien
10098944Sobrienstatic void field_separator (void);
10198944Sobrien
10298944Sobrienstatic void out_field_fmt (struct ui_out *uiout, int fldno,
10398944Sobrien			   const char *fldname,
10498944Sobrien			   const char *format,...);
10598944Sobrien
10698944Sobrien/* local variables */
10798944Sobrien
10898944Sobrien/* (none yet) */
10998944Sobrien
11098944Sobrien/* Mark beginning of a table */
11198944Sobrien
11298944Sobrienvoid
11398944Sobriencli_table_begin (struct ui_out *uiout, int nbrofcols,
11498944Sobrien		 int nr_rows,
11598944Sobrien		 const char *tblid)
11698944Sobrien{
117130803Smarcel  cli_out_data *data = ui_out_data (uiout);
11898944Sobrien  if (nr_rows == 0)
11998944Sobrien    data->suppress_output = 1;
12098944Sobrien  else
121130803Smarcel    /* Only the table suppresses the output and, fortunately, a table
12298944Sobrien       is not a recursive data structure. */
12398944Sobrien    gdb_assert (data->suppress_output == 0);
12498944Sobrien}
12598944Sobrien
12698944Sobrien/* Mark beginning of a table body */
12798944Sobrien
12898944Sobrienvoid
12998944Sobriencli_table_body (struct ui_out *uiout)
13098944Sobrien{
131130803Smarcel  cli_out_data *data = ui_out_data (uiout);
13298944Sobrien  if (data->suppress_output)
13398944Sobrien    return;
13498944Sobrien  /* first, close the table header line */
13598944Sobrien  cli_text (uiout, "\n");
13698944Sobrien}
13798944Sobrien
13898944Sobrien/* Mark end of a table */
13998944Sobrien
14098944Sobrienvoid
14198944Sobriencli_table_end (struct ui_out *uiout)
14298944Sobrien{
143130803Smarcel  cli_out_data *data = ui_out_data (uiout);
14498944Sobrien  data->suppress_output = 0;
14598944Sobrien}
14698944Sobrien
14798944Sobrien/* Specify table header */
14898944Sobrien
14998944Sobrienvoid
15098944Sobriencli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
15198944Sobrien		  const char *col_name,
15298944Sobrien		  const char *colhdr)
15398944Sobrien{
154130803Smarcel  cli_out_data *data = ui_out_data (uiout);
15598944Sobrien  if (data->suppress_output)
15698944Sobrien    return;
15798944Sobrien  cli_field_string (uiout, 0, width, alignment, 0, colhdr);
15898944Sobrien}
15998944Sobrien
16098944Sobrien/* Mark beginning of a list */
16198944Sobrien
16298944Sobrienvoid
16398944Sobriencli_begin (struct ui_out *uiout,
16498944Sobrien	   enum ui_out_type type,
16598944Sobrien	   int level,
16698944Sobrien	   const char *id)
16798944Sobrien{
168130803Smarcel  cli_out_data *data = ui_out_data (uiout);
16998944Sobrien  if (data->suppress_output)
17098944Sobrien    return;
17198944Sobrien}
17298944Sobrien
17398944Sobrien/* Mark end of a list */
17498944Sobrien
17598944Sobrienvoid
17698944Sobriencli_end (struct ui_out *uiout,
17798944Sobrien	 enum ui_out_type type,
17898944Sobrien	 int level)
17998944Sobrien{
180130803Smarcel  cli_out_data *data = ui_out_data (uiout);
18198944Sobrien  if (data->suppress_output)
18298944Sobrien    return;
18398944Sobrien}
18498944Sobrien
18598944Sobrien/* output an int field */
18698944Sobrien
18798944Sobrienvoid
18898944Sobriencli_field_int (struct ui_out *uiout, int fldno, int width,
18998944Sobrien	       enum ui_align alignment,
19098944Sobrien	       const char *fldname, int value)
19198944Sobrien{
19298944Sobrien  char buffer[20];		/* FIXME: how many chars long a %d can become? */
19398944Sobrien
194130803Smarcel  cli_out_data *data = ui_out_data (uiout);
19598944Sobrien  if (data->suppress_output)
19698944Sobrien    return;
19798944Sobrien  sprintf (buffer, "%d", value);
19898944Sobrien  cli_field_string (uiout, fldno, width, alignment, fldname, buffer);
19998944Sobrien}
20098944Sobrien
20198944Sobrien/* used to ommit a field */
20298944Sobrien
20398944Sobrienvoid
20498944Sobriencli_field_skip (struct ui_out *uiout, int fldno, int width,
20598944Sobrien		enum ui_align alignment,
20698944Sobrien		const char *fldname)
20798944Sobrien{
208130803Smarcel  cli_out_data *data = ui_out_data (uiout);
20998944Sobrien  if (data->suppress_output)
21098944Sobrien    return;
21198944Sobrien  cli_field_string (uiout, fldno, width, alignment, fldname, "");
21298944Sobrien}
21398944Sobrien
21498944Sobrien/* other specific cli_field_* end up here so alignment and field
21598944Sobrien   separators are both handled by cli_field_string */
21698944Sobrien
21798944Sobrienvoid
21898944Sobriencli_field_string (struct ui_out *uiout,
21998944Sobrien		  int fldno,
22098944Sobrien		  int width,
22198944Sobrien		  enum ui_align align,
22298944Sobrien		  const char *fldname,
22398944Sobrien		  const char *string)
22498944Sobrien{
22598944Sobrien  int before = 0;
22698944Sobrien  int after = 0;
22798944Sobrien
228130803Smarcel  cli_out_data *data = ui_out_data (uiout);
22998944Sobrien  if (data->suppress_output)
23098944Sobrien    return;
23198944Sobrien
23298944Sobrien  if ((align != ui_noalign) && string)
23398944Sobrien    {
23498944Sobrien      before = width - strlen (string);
23598944Sobrien      if (before <= 0)
23698944Sobrien	before = 0;
23798944Sobrien      else
23898944Sobrien	{
23998944Sobrien	  if (align == ui_right)
24098944Sobrien	    after = 0;
24198944Sobrien	  else if (align == ui_left)
24298944Sobrien	    {
24398944Sobrien	      after = before;
24498944Sobrien	      before = 0;
24598944Sobrien	    }
24698944Sobrien	  else
24798944Sobrien	    /* ui_center */
24898944Sobrien	    {
24998944Sobrien	      after = before / 2;
25098944Sobrien	      before -= after;
25198944Sobrien	    }
25298944Sobrien	}
25398944Sobrien    }
25498944Sobrien
25598944Sobrien  if (before)
25698944Sobrien    ui_out_spaces (uiout, before);
25798944Sobrien  if (string)
25898944Sobrien    out_field_fmt (uiout, fldno, fldname, "%s", string);
25998944Sobrien  if (after)
26098944Sobrien    ui_out_spaces (uiout, after);
26198944Sobrien
26298944Sobrien  if (align != ui_noalign)
26398944Sobrien    field_separator ();
26498944Sobrien}
26598944Sobrien
26698944Sobrien/* This is the only field function that does not align */
26798944Sobrien
26898944Sobrienvoid
26998944Sobriencli_field_fmt (struct ui_out *uiout, int fldno,
27098944Sobrien	       int width, enum ui_align align,
27198944Sobrien	       const char *fldname,
27298944Sobrien	       const char *format,
27398944Sobrien	       va_list args)
27498944Sobrien{
275130803Smarcel  cli_out_data *data = ui_out_data (uiout);
27698944Sobrien  if (data->suppress_output)
27798944Sobrien    return;
27898944Sobrien
27998944Sobrien  vfprintf_filtered (data->stream, format, args);
28098944Sobrien
28198944Sobrien  if (align != ui_noalign)
28298944Sobrien    field_separator ();
28398944Sobrien}
28498944Sobrien
28598944Sobrienvoid
28698944Sobriencli_spaces (struct ui_out *uiout, int numspaces)
28798944Sobrien{
288130803Smarcel  cli_out_data *data = ui_out_data (uiout);
28998944Sobrien  if (data->suppress_output)
29098944Sobrien    return;
29198944Sobrien  print_spaces_filtered (numspaces, data->stream);
29298944Sobrien}
29398944Sobrien
29498944Sobrienvoid
29598944Sobriencli_text (struct ui_out *uiout, const char *string)
29698944Sobrien{
297130803Smarcel  cli_out_data *data = ui_out_data (uiout);
29898944Sobrien  if (data->suppress_output)
29998944Sobrien    return;
30098944Sobrien  fputs_filtered (string, data->stream);
30198944Sobrien}
30298944Sobrien
30398944Sobrienvoid
30498944Sobriencli_message (struct ui_out *uiout, int verbosity,
30598944Sobrien	     const char *format, va_list args)
30698944Sobrien{
307130803Smarcel  cli_out_data *data = ui_out_data (uiout);
30898944Sobrien  if (data->suppress_output)
30998944Sobrien    return;
31098944Sobrien  if (ui_out_get_verblvl (uiout) >= verbosity)
31198944Sobrien    vfprintf_unfiltered (data->stream, format, args);
31298944Sobrien}
31398944Sobrien
31498944Sobrienvoid
31598944Sobriencli_wrap_hint (struct ui_out *uiout, char *identstring)
31698944Sobrien{
317130803Smarcel  cli_out_data *data = ui_out_data (uiout);
31898944Sobrien  if (data->suppress_output)
31998944Sobrien    return;
32098944Sobrien  wrap_here (identstring);
32198944Sobrien}
32298944Sobrien
32398944Sobrienvoid
32498944Sobriencli_flush (struct ui_out *uiout)
32598944Sobrien{
326130803Smarcel  cli_out_data *data = ui_out_data (uiout);
32798944Sobrien  gdb_flush (data->stream);
32898944Sobrien}
32998944Sobrien
330130803Smarcelint
331130803Smarcelcli_redirect (struct ui_out *uiout, struct ui_file *outstream)
332130803Smarcel{
333130803Smarcel  struct ui_out_data *data = ui_out_data (uiout);
334130803Smarcel  if (outstream != NULL)
335130803Smarcel    {
336130803Smarcel      data->original_stream = data->stream;
337130803Smarcel      data->stream = outstream;
338130803Smarcel    }
339130803Smarcel  else if (data->original_stream != NULL)
340130803Smarcel    {
341130803Smarcel      data->stream = data->original_stream;
342130803Smarcel      data->original_stream = NULL;
343130803Smarcel    }
344130803Smarcel
345130803Smarcel  return 0;
346130803Smarcel}
347130803Smarcel
34898944Sobrien/* local functions */
34998944Sobrien
35098944Sobrien/* Like cli_field_fmt, but takes a variable number of args
35198944Sobrien   and makes a va_list and does not insert a separator */
35298944Sobrien
35398944Sobrien/* VARARGS */
35498944Sobrienstatic void
35598944Sobrienout_field_fmt (struct ui_out *uiout, int fldno,
35698944Sobrien	       const char *fldname,
35798944Sobrien	       const char *format,...)
35898944Sobrien{
359130803Smarcel  cli_out_data *data = ui_out_data (uiout);
36098944Sobrien  va_list args;
36198944Sobrien
36298944Sobrien  va_start (args, format);
36398944Sobrien  vfprintf_filtered (data->stream, format, args);
36498944Sobrien
36598944Sobrien  va_end (args);
36698944Sobrien}
36798944Sobrien
36898944Sobrien/* access to ui_out format private members */
36998944Sobrien
37098944Sobrienstatic void
37198944Sobrienfield_separator (void)
37298944Sobrien{
373130803Smarcel  cli_out_data *data = ui_out_data (uiout);
37498944Sobrien  fputc_filtered (' ', data->stream);
37598944Sobrien}
37698944Sobrien
37798944Sobrien/* initalize private members at startup */
37898944Sobrien
37998944Sobrienstruct ui_out *
38098944Sobriencli_out_new (struct ui_file *stream)
38198944Sobrien{
38298944Sobrien  int flags = ui_source_list;
38398944Sobrien
384130803Smarcel  cli_out_data *data = XMALLOC (cli_out_data);
38598944Sobrien  data->stream = stream;
386130803Smarcel  data->original_stream = NULL;
38798944Sobrien  data->suppress_output = 0;
38898944Sobrien  return ui_out_new (&cli_ui_out_impl, data, flags);
38998944Sobrien}
39098944Sobrien
391130803Smarcelstruct ui_file *
392130803Smarcelcli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
393130803Smarcel{
394130803Smarcel  cli_out_data *data = ui_out_data (uiout);
395130803Smarcel  struct ui_file *old = data->stream;
396130803Smarcel  data->stream = stream;
397130803Smarcel  return old;
398130803Smarcel}
399130803Smarcel
40098944Sobrien/* standard gdb initialization hook */
40198944Sobrienvoid
40298944Sobrien_initialize_cli_out (void)
40398944Sobrien{
40498944Sobrien  /* nothing needs to be done */
40598944Sobrien}
406