1130803Smarcel/* Output generating routines for GDB CLI.
2130803Smarcel
3130803Smarcel   Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
4130803Smarcel   Inc.
5130803Smarcel
6130803Smarcel   Contributed by Cygnus Solutions.
7130803Smarcel   Written by Fernando Nasser for Cygnus.
8130803Smarcel
9130803Smarcel   This file is part of GDB.
10130803Smarcel
11130803Smarcel   This program is free software; you can redistribute it and/or modify
12130803Smarcel   it under the terms of the GNU General Public License as published by
13130803Smarcel   the Free Software Foundation; either version 2 of the License, or
14130803Smarcel   (at your option) any later version.
15130803Smarcel
16130803Smarcel   This program is distributed in the hope that it will be useful,
17130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
18130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19130803Smarcel   GNU General Public License for more details.
20130803Smarcel
21130803Smarcel   You should have received a copy of the GNU General Public License
22130803Smarcel   along with this program; if not, write to the Free Software
23130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
24130803Smarcel   Boston, MA 02111-1307, USA.  */
25130803Smarcel
26130803Smarcel#include "defs.h"
27130803Smarcel#include "ui-out.h"
28130803Smarcel#include "tui.h"
29130803Smarcel#include "gdb_string.h"
30130803Smarcel#include "gdb_assert.h"
31130803Smarcel
32130803Smarcelstruct ui_out_data
33130803Smarcel  {
34130803Smarcel    struct ui_file *stream;
35130803Smarcel    int suppress_output;
36130803Smarcel    int line;
37130803Smarcel    int start_of_line;
38130803Smarcel  };
39130803Smarceltypedef struct ui_out_data tui_out_data;
40130803Smarcel
41130803Smarcel/* These are the CLI output functions */
42130803Smarcel
43130803Smarcelstatic void tui_table_begin (struct ui_out *uiout, int nbrofcols,
44130803Smarcel			     int nr_rows, const char *tblid);
45130803Smarcelstatic void tui_table_body (struct ui_out *uiout);
46130803Smarcelstatic void tui_table_end (struct ui_out *uiout);
47130803Smarcelstatic void tui_table_header (struct ui_out *uiout, int width,
48130803Smarcel			      enum ui_align alig, const char *col_name,
49130803Smarcel			      const char *colhdr);
50130803Smarcelstatic void tui_begin (struct ui_out *uiout, enum ui_out_type type,
51130803Smarcel		       int level, const char *lstid);
52130803Smarcelstatic void tui_end (struct ui_out *uiout, enum ui_out_type type, int level);
53130803Smarcelstatic void tui_field_int (struct ui_out *uiout, int fldno, int width,
54130803Smarcel			   enum ui_align alig, const char *fldname, int value);
55130803Smarcelstatic void tui_field_skip (struct ui_out *uiout, int fldno, int width,
56130803Smarcel			    enum ui_align alig, const char *fldname);
57130803Smarcelstatic void tui_field_string (struct ui_out *uiout, int fldno, int width,
58130803Smarcel			      enum ui_align alig, const char *fldname,
59130803Smarcel			      const char *string);
60130803Smarcelstatic void tui_field_fmt (struct ui_out *uiout, int fldno,
61130803Smarcel			   int width, enum ui_align align,
62130803Smarcel			   const char *fldname, const char *format,
63130803Smarcel			   va_list args);
64130803Smarcelstatic void tui_spaces (struct ui_out *uiout, int numspaces);
65130803Smarcelstatic void tui_text (struct ui_out *uiout, const char *string);
66130803Smarcelstatic void tui_message (struct ui_out *uiout, int verbosity,
67130803Smarcel			 const char *format, va_list args);
68130803Smarcelstatic void tui_wrap_hint (struct ui_out *uiout, char *identstring);
69130803Smarcelstatic void tui_flush (struct ui_out *uiout);
70130803Smarcel
71130803Smarcel/* This is the CLI ui-out implementation functions vector */
72130803Smarcel
73130803Smarcel/* FIXME: This can be initialized dynamically after default is set to
74130803Smarcel   handle initial output in main.c */
75130803Smarcel
76130803Smarcelstatic struct ui_out_impl tui_ui_out_impl =
77130803Smarcel{
78130803Smarcel  tui_table_begin,
79130803Smarcel  tui_table_body,
80130803Smarcel  tui_table_end,
81130803Smarcel  tui_table_header,
82130803Smarcel  tui_begin,
83130803Smarcel  tui_end,
84130803Smarcel  tui_field_int,
85130803Smarcel  tui_field_skip,
86130803Smarcel  tui_field_string,
87130803Smarcel  tui_field_fmt,
88130803Smarcel  tui_spaces,
89130803Smarcel  tui_text,
90130803Smarcel  tui_message,
91130803Smarcel  tui_wrap_hint,
92130803Smarcel  tui_flush,
93130803Smarcel  NULL,
94130803Smarcel  0, /* Does not need MI hacks (i.e. needs CLI hacks).  */
95130803Smarcel};
96130803Smarcel
97130803Smarcel/* Prototypes for local functions */
98130803Smarcel
99130803Smarcelextern void _initialize_tui_out (void);
100130803Smarcel
101130803Smarcelstatic void field_separator (void);
102130803Smarcel
103130803Smarcelstatic void out_field_fmt (struct ui_out *uiout, int fldno,
104130803Smarcel			   const char *fldname,
105130803Smarcel			   const char *format,...);
106130803Smarcel
107130803Smarcel/* local variables */
108130803Smarcel
109130803Smarcel/* (none yet) */
110130803Smarcel
111130803Smarcel/* Mark beginning of a table */
112130803Smarcel
113130803Smarcelvoid
114130803Smarceltui_table_begin (struct ui_out *uiout, int nbrofcols,
115130803Smarcel		 int nr_rows,
116130803Smarcel		 const char *tblid)
117130803Smarcel{
118130803Smarcel  tui_out_data *data = ui_out_data (uiout);
119130803Smarcel  if (nr_rows == 0)
120130803Smarcel    data->suppress_output = 1;
121130803Smarcel  else
122130803Smarcel    /* Only the table suppresses the output and, fortunately, a table
123130803Smarcel       is not a recursive data structure. */
124130803Smarcel    gdb_assert (data->suppress_output == 0);
125130803Smarcel}
126130803Smarcel
127130803Smarcel/* Mark beginning of a table body */
128130803Smarcel
129130803Smarcelvoid
130130803Smarceltui_table_body (struct ui_out *uiout)
131130803Smarcel{
132130803Smarcel  tui_out_data *data = ui_out_data (uiout);
133130803Smarcel  if (data->suppress_output)
134130803Smarcel    return;
135130803Smarcel  /* first, close the table header line */
136130803Smarcel  tui_text (uiout, "\n");
137130803Smarcel}
138130803Smarcel
139130803Smarcel/* Mark end of a table */
140130803Smarcel
141130803Smarcelvoid
142130803Smarceltui_table_end (struct ui_out *uiout)
143130803Smarcel{
144130803Smarcel  tui_out_data *data = ui_out_data (uiout);
145130803Smarcel  data->suppress_output = 0;
146130803Smarcel}
147130803Smarcel
148130803Smarcel/* Specify table header */
149130803Smarcel
150130803Smarcelvoid
151130803Smarceltui_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
152130803Smarcel		  const char *col_name,
153130803Smarcel		  const char *colhdr)
154130803Smarcel{
155130803Smarcel  tui_out_data *data = ui_out_data (uiout);
156130803Smarcel  if (data->suppress_output)
157130803Smarcel    return;
158130803Smarcel  tui_field_string (uiout, 0, width, alignment, 0, colhdr);
159130803Smarcel}
160130803Smarcel
161130803Smarcel/* Mark beginning of a list */
162130803Smarcel
163130803Smarcelvoid
164130803Smarceltui_begin (struct ui_out *uiout,
165130803Smarcel	   enum ui_out_type type,
166130803Smarcel	   int level,
167130803Smarcel	   const char *id)
168130803Smarcel{
169130803Smarcel  tui_out_data *data = ui_out_data (uiout);
170130803Smarcel  if (data->suppress_output)
171130803Smarcel    return;
172130803Smarcel}
173130803Smarcel
174130803Smarcel/* Mark end of a list */
175130803Smarcel
176130803Smarcelvoid
177130803Smarceltui_end (struct ui_out *uiout,
178130803Smarcel	 enum ui_out_type type,
179130803Smarcel	 int level)
180130803Smarcel{
181130803Smarcel  tui_out_data *data = ui_out_data (uiout);
182130803Smarcel  if (data->suppress_output)
183130803Smarcel    return;
184130803Smarcel}
185130803Smarcel
186130803Smarcel/* output an int field */
187130803Smarcel
188130803Smarcelvoid
189130803Smarceltui_field_int (struct ui_out *uiout, int fldno, int width,
190130803Smarcel	       enum ui_align alignment,
191130803Smarcel	       const char *fldname, int value)
192130803Smarcel{
193130803Smarcel  char buffer[20];		/* FIXME: how many chars long a %d can become? */
194130803Smarcel
195130803Smarcel  tui_out_data *data = ui_out_data (uiout);
196130803Smarcel  if (data->suppress_output)
197130803Smarcel    return;
198130803Smarcel
199130803Smarcel  /* Don't print line number, keep it for later.  */
200130803Smarcel  if (data->start_of_line == 0 && strcmp (fldname, "line") == 0)
201130803Smarcel    {
202130803Smarcel      data->start_of_line ++;
203130803Smarcel      data->line = value;
204130803Smarcel      return;
205130803Smarcel    }
206130803Smarcel  data->start_of_line ++;
207130803Smarcel  sprintf (buffer, "%d", value);
208130803Smarcel  tui_field_string (uiout, fldno, width, alignment, fldname, buffer);
209130803Smarcel}
210130803Smarcel
211130803Smarcel/* used to ommit a field */
212130803Smarcel
213130803Smarcelvoid
214130803Smarceltui_field_skip (struct ui_out *uiout, int fldno, int width,
215130803Smarcel		enum ui_align alignment,
216130803Smarcel		const char *fldname)
217130803Smarcel{
218130803Smarcel  tui_out_data *data = ui_out_data (uiout);
219130803Smarcel  if (data->suppress_output)
220130803Smarcel    return;
221130803Smarcel  tui_field_string (uiout, fldno, width, alignment, fldname, "");
222130803Smarcel}
223130803Smarcel
224130803Smarcel/* other specific tui_field_* end up here so alignment and field
225130803Smarcel   separators are both handled by tui_field_string */
226130803Smarcel
227130803Smarcelvoid
228130803Smarceltui_field_string (struct ui_out *uiout,
229130803Smarcel		  int fldno,
230130803Smarcel		  int width,
231130803Smarcel		  enum ui_align align,
232130803Smarcel		  const char *fldname,
233130803Smarcel		  const char *string)
234130803Smarcel{
235130803Smarcel  int before = 0;
236130803Smarcel  int after = 0;
237130803Smarcel
238130803Smarcel  tui_out_data *data = ui_out_data (uiout);
239130803Smarcel  if (data->suppress_output)
240130803Smarcel    return;
241130803Smarcel
242130803Smarcel  if (fldname && data->line > 0 && strcmp (fldname, "file") == 0)
243130803Smarcel    {
244130803Smarcel      data->start_of_line ++;
245130803Smarcel      if (data->line > 0)
246130803Smarcel        {
247130803Smarcel          tui_show_source (string, data->line);
248130803Smarcel        }
249130803Smarcel      return;
250130803Smarcel    }
251130803Smarcel
252130803Smarcel  data->start_of_line ++;
253130803Smarcel  if ((align != ui_noalign) && string)
254130803Smarcel    {
255130803Smarcel      before = width - strlen (string);
256130803Smarcel      if (before <= 0)
257130803Smarcel	before = 0;
258130803Smarcel      else
259130803Smarcel	{
260130803Smarcel	  if (align == ui_right)
261130803Smarcel	    after = 0;
262130803Smarcel	  else if (align == ui_left)
263130803Smarcel	    {
264130803Smarcel	      after = before;
265130803Smarcel	      before = 0;
266130803Smarcel	    }
267130803Smarcel	  else
268130803Smarcel	    /* ui_center */
269130803Smarcel	    {
270130803Smarcel	      after = before / 2;
271130803Smarcel	      before -= after;
272130803Smarcel	    }
273130803Smarcel	}
274130803Smarcel    }
275130803Smarcel
276130803Smarcel  if (before)
277130803Smarcel    ui_out_spaces (uiout, before);
278130803Smarcel  if (string)
279130803Smarcel    out_field_fmt (uiout, fldno, fldname, "%s", string);
280130803Smarcel  if (after)
281130803Smarcel    ui_out_spaces (uiout, after);
282130803Smarcel
283130803Smarcel  if (align != ui_noalign)
284130803Smarcel    field_separator ();
285130803Smarcel}
286130803Smarcel
287130803Smarcel/* This is the only field function that does not align */
288130803Smarcel
289130803Smarcelvoid
290130803Smarceltui_field_fmt (struct ui_out *uiout, int fldno,
291130803Smarcel	       int width, enum ui_align align,
292130803Smarcel	       const char *fldname,
293130803Smarcel	       const char *format,
294130803Smarcel	       va_list args)
295130803Smarcel{
296130803Smarcel  tui_out_data *data = ui_out_data (uiout);
297130803Smarcel  if (data->suppress_output)
298130803Smarcel    return;
299130803Smarcel
300130803Smarcel  data->start_of_line ++;
301130803Smarcel  vfprintf_filtered (data->stream, format, args);
302130803Smarcel
303130803Smarcel  if (align != ui_noalign)
304130803Smarcel    field_separator ();
305130803Smarcel}
306130803Smarcel
307130803Smarcelvoid
308130803Smarceltui_spaces (struct ui_out *uiout, int numspaces)
309130803Smarcel{
310130803Smarcel  tui_out_data *data = ui_out_data (uiout);
311130803Smarcel  if (data->suppress_output)
312130803Smarcel    return;
313130803Smarcel  print_spaces_filtered (numspaces, data->stream);
314130803Smarcel}
315130803Smarcel
316130803Smarcelvoid
317130803Smarceltui_text (struct ui_out *uiout, const char *string)
318130803Smarcel{
319130803Smarcel  tui_out_data *data = ui_out_data (uiout);
320130803Smarcel  if (data->suppress_output)
321130803Smarcel    return;
322130803Smarcel  data->start_of_line ++;
323130803Smarcel  if (data->line > 0)
324130803Smarcel    {
325130803Smarcel      if (strchr (string, '\n') != 0)
326130803Smarcel        {
327130803Smarcel          data->line = -1;
328130803Smarcel          data->start_of_line = 0;
329130803Smarcel        }
330130803Smarcel      return;
331130803Smarcel    }
332130803Smarcel  if (strchr (string, '\n'))
333130803Smarcel    data->start_of_line = 0;
334130803Smarcel  fputs_filtered (string, data->stream);
335130803Smarcel}
336130803Smarcel
337130803Smarcelvoid
338130803Smarceltui_message (struct ui_out *uiout, int verbosity,
339130803Smarcel	     const char *format, va_list args)
340130803Smarcel{
341130803Smarcel  tui_out_data *data = ui_out_data (uiout);
342130803Smarcel  if (data->suppress_output)
343130803Smarcel    return;
344130803Smarcel  if (ui_out_get_verblvl (uiout) >= verbosity)
345130803Smarcel    vfprintf_unfiltered (data->stream, format, args);
346130803Smarcel}
347130803Smarcel
348130803Smarcelvoid
349130803Smarceltui_wrap_hint (struct ui_out *uiout, char *identstring)
350130803Smarcel{
351130803Smarcel  tui_out_data *data = ui_out_data (uiout);
352130803Smarcel  if (data->suppress_output)
353130803Smarcel    return;
354130803Smarcel  wrap_here (identstring);
355130803Smarcel}
356130803Smarcel
357130803Smarcelvoid
358130803Smarceltui_flush (struct ui_out *uiout)
359130803Smarcel{
360130803Smarcel  tui_out_data *data = ui_out_data (uiout);
361130803Smarcel  gdb_flush (data->stream);
362130803Smarcel}
363130803Smarcel
364130803Smarcel/* local functions */
365130803Smarcel
366130803Smarcel/* Like tui_field_fmt, but takes a variable number of args
367130803Smarcel   and makes a va_list and does not insert a separator */
368130803Smarcel
369130803Smarcel/* VARARGS */
370130803Smarcelstatic void
371130803Smarcelout_field_fmt (struct ui_out *uiout, int fldno,
372130803Smarcel	       const char *fldname,
373130803Smarcel	       const char *format,...)
374130803Smarcel{
375130803Smarcel  tui_out_data *data = ui_out_data (uiout);
376130803Smarcel  va_list args;
377130803Smarcel
378130803Smarcel  va_start (args, format);
379130803Smarcel  vfprintf_filtered (data->stream, format, args);
380130803Smarcel
381130803Smarcel  va_end (args);
382130803Smarcel}
383130803Smarcel
384130803Smarcel/* access to ui_out format private members */
385130803Smarcel
386130803Smarcelstatic void
387130803Smarcelfield_separator (void)
388130803Smarcel{
389130803Smarcel  tui_out_data *data = ui_out_data (uiout);
390130803Smarcel  fputc_filtered (' ', data->stream);
391130803Smarcel}
392130803Smarcel
393130803Smarcel/* initalize private members at startup */
394130803Smarcel
395130803Smarcelstruct ui_out *
396130803Smarceltui_out_new (struct ui_file *stream)
397130803Smarcel{
398130803Smarcel  int flags = 0;
399130803Smarcel
400130803Smarcel  tui_out_data *data = XMALLOC (tui_out_data);
401130803Smarcel  data->stream = stream;
402130803Smarcel  data->suppress_output = 0;
403130803Smarcel  data->line = -1;
404130803Smarcel  data->start_of_line = 0;
405130803Smarcel  return ui_out_new (&tui_ui_out_impl, data, flags);
406130803Smarcel}
407130803Smarcel
408130803Smarcel/* standard gdb initialization hook */
409130803Smarcelvoid
410130803Smarcel_initialize_tui_out (void)
411130803Smarcel{
412130803Smarcel  /* nothing needs to be done */
413130803Smarcel}
414