* tui-hooks.c: New file, gdb hooks for tui.
[platform/upstream/binutils.git] / gdb / tui / tui-out.c
1 /* Output generating routines for GDB CLI.
2    Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4    Written by Fernando Nasser for Cygnus.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.  */
22
23 #include "defs.h"
24 #include "ui-out.h"
25 #include "tui.h"
26 #include "gdb_string.h"
27 #include "gdb_assert.h"
28
29 /* Convenience macro for allocting typesafe memory. */
30
31 #ifndef XMALLOC
32 #define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
33 #endif
34
35 struct ui_out_data
36   {
37     struct ui_file *stream;
38     int suppress_output;
39     int line;
40     int start_of_line;
41   };
42
43 /* These are the CLI output functions */
44
45 static void tui_table_begin (struct ui_out *uiout, int nbrofcols,
46                              int nr_rows, const char *tblid);
47 static void tui_table_body (struct ui_out *uiout);
48 static void tui_table_end (struct ui_out *uiout);
49 static void tui_table_header (struct ui_out *uiout, int width,
50                               enum ui_align alig, const char *col_name,
51                               const char *colhdr);
52 static void tui_begin (struct ui_out *uiout, enum ui_out_type type,
53                        int level, const char *lstid);
54 static void tui_end (struct ui_out *uiout, enum ui_out_type type, int level);
55 static void tui_field_int (struct ui_out *uiout, int fldno, int width,
56                            enum ui_align alig, const char *fldname, int value);
57 static void tui_field_skip (struct ui_out *uiout, int fldno, int width,
58                             enum ui_align alig, const char *fldname);
59 static void tui_field_string (struct ui_out *uiout, int fldno, int width,
60                               enum ui_align alig, const char *fldname,
61                               const char *string);
62 static void tui_field_fmt (struct ui_out *uiout, int fldno,
63                            int width, enum ui_align align,
64                            const char *fldname, const char *format,
65                            va_list args);
66 static void tui_spaces (struct ui_out *uiout, int numspaces);
67 static void tui_text (struct ui_out *uiout, const char *string);
68 static void tui_message (struct ui_out *uiout, int verbosity,
69                          const char *format, va_list args);
70 static void tui_wrap_hint (struct ui_out *uiout, char *identstring);
71 static void tui_flush (struct ui_out *uiout);
72
73 /* This is the CLI ui-out implementation functions vector */
74
75 /* FIXME: This can be initialized dynamically after default is set to
76    handle initial output in main.c */
77
78 static struct ui_out_impl tui_ui_out_impl =
79 {
80   tui_table_begin,
81   tui_table_body,
82   tui_table_end,
83   tui_table_header,
84   tui_begin,
85   tui_end,
86   tui_field_int,
87   tui_field_skip,
88   tui_field_string,
89   tui_field_fmt,
90   tui_spaces,
91   tui_text,
92   tui_message,
93   tui_wrap_hint,
94   tui_flush,
95   0, /* Does not need MI hacks (i.e. needs CLI hacks).  */
96 };
97
98 /* Prototypes for local functions */
99
100 extern void _initialize_tui_out (void);
101
102 static void field_separator (void);
103
104 static void out_field_fmt (struct ui_out *uiout, int fldno,
105                            const char *fldname,
106                            const char *format,...);
107
108 /* local variables */
109
110 /* (none yet) */
111
112 /* Mark beginning of a table */
113
114 void
115 tui_table_begin (struct ui_out *uiout, int nbrofcols,
116                  int nr_rows,
117                  const char *tblid)
118 {
119   struct ui_out_data *data = ui_out_data (uiout);
120   if (nr_rows == 0)
121     data->suppress_output = 1;
122   else
123     /* Only the table suppresses the output and, fortunatly, a table
124        is not a recursive data structure. */
125     gdb_assert (data->suppress_output == 0);
126 }
127
128 /* Mark beginning of a table body */
129
130 void
131 tui_table_body (struct ui_out *uiout)
132 {
133   struct ui_out_data *data = ui_out_data (uiout);
134   if (data->suppress_output)
135     return;
136   /* first, close the table header line */
137   tui_text (uiout, "\n");
138 }
139
140 /* Mark end of a table */
141
142 void
143 tui_table_end (struct ui_out *uiout)
144 {
145   struct ui_out_data *data = ui_out_data (uiout);
146   data->suppress_output = 0;
147 }
148
149 /* Specify table header */
150
151 void
152 tui_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
153                   const char *col_name,
154                   const char *colhdr)
155 {
156   struct ui_out_data *data = ui_out_data (uiout);
157   if (data->suppress_output)
158     return;
159   tui_field_string (uiout, 0, width, alignment, 0, colhdr);
160 }
161
162 /* Mark beginning of a list */
163
164 void
165 tui_begin (struct ui_out *uiout,
166            enum ui_out_type type,
167            int level,
168            const char *id)
169 {
170   struct ui_out_data *data = ui_out_data (uiout);
171   if (data->suppress_output)
172     return;
173 }
174
175 /* Mark end of a list */
176
177 void
178 tui_end (struct ui_out *uiout,
179          enum ui_out_type type,
180          int level)
181 {
182   struct ui_out_data *data = ui_out_data (uiout);
183   if (data->suppress_output)
184     return;
185 }
186
187 /* output an int field */
188
189 void
190 tui_field_int (struct ui_out *uiout, int fldno, int width,
191                enum ui_align alignment,
192                const char *fldname, int value)
193 {
194   char buffer[20];              /* FIXME: how many chars long a %d can become? */
195
196   struct ui_out_data *data = ui_out_data (uiout);
197   if (data->suppress_output)
198     return;
199
200   /* Don't print line number, keep it for later.  */
201   if (data->start_of_line == 0 && strcmp (fldname, "line") == 0)
202     {
203       data->start_of_line ++;
204       data->line = value;
205       return;
206     }
207   data->start_of_line ++;
208   sprintf (buffer, "%d", value);
209   tui_field_string (uiout, fldno, width, alignment, fldname, buffer);
210 }
211
212 /* used to ommit a field */
213
214 void
215 tui_field_skip (struct ui_out *uiout, int fldno, int width,
216                 enum ui_align alignment,
217                 const char *fldname)
218 {
219   struct ui_out_data *data = ui_out_data (uiout);
220   if (data->suppress_output)
221     return;
222   tui_field_string (uiout, fldno, width, alignment, fldname, "");
223 }
224
225 /* other specific tui_field_* end up here so alignment and field
226    separators are both handled by tui_field_string */
227
228 void
229 tui_field_string (struct ui_out *uiout,
230                   int fldno,
231                   int width,
232                   enum ui_align align,
233                   const char *fldname,
234                   const char *string)
235 {
236   int before = 0;
237   int after = 0;
238
239   struct ui_out_data *data = ui_out_data (uiout);
240   if (data->suppress_output)
241     return;
242
243   if (fldname && data->line > 0 && strcmp (fldname, "file") == 0)
244     {
245       data->start_of_line ++;
246       if (data->line > 0)
247         {
248           tui_show_source (string, data->line);
249         }
250       return;
251     }
252   
253   data->start_of_line ++;
254   if ((align != ui_noalign) && string)
255     {
256       before = width - strlen (string);
257       if (before <= 0)
258         before = 0;
259       else
260         {
261           if (align == ui_right)
262             after = 0;
263           else if (align == ui_left)
264             {
265               after = before;
266               before = 0;
267             }
268           else
269             /* ui_center */
270             {
271               after = before / 2;
272               before -= after;
273             }
274         }
275     }
276
277   if (before)
278     ui_out_spaces (uiout, before);
279   if (string)
280     out_field_fmt (uiout, fldno, fldname, "%s", string);
281   if (after)
282     ui_out_spaces (uiout, after);
283
284   if (align != ui_noalign)
285     field_separator ();
286 }
287
288 /* This is the only field function that does not align */
289
290 void
291 tui_field_fmt (struct ui_out *uiout, int fldno,
292                int width, enum ui_align align,
293                const char *fldname,
294                const char *format,
295                va_list args)
296 {
297   struct ui_out_data *data = ui_out_data (uiout);
298   if (data->suppress_output)
299     return;
300
301   data->start_of_line ++;
302   vfprintf_filtered (data->stream, format, args);
303
304   if (align != ui_noalign)
305     field_separator ();
306 }
307
308 void
309 tui_spaces (struct ui_out *uiout, int numspaces)
310 {
311   struct ui_out_data *data = ui_out_data (uiout);
312   if (data->suppress_output)
313     return;
314   print_spaces_filtered (numspaces, data->stream);
315 }
316
317 void
318 tui_text (struct ui_out *uiout, const char *string)
319 {
320   struct ui_out_data *data = ui_out_data (uiout);
321   if (data->suppress_output)
322     return;
323   data->start_of_line ++;
324   if (data->line > 0)
325     {
326       if (strchr (string, '\n') != 0)
327         {
328           data->line = -1;
329           data->start_of_line = 0;
330         }
331       return;
332     }
333   if (strchr (string, '\n'))
334     data->start_of_line = 0;
335   fputs_filtered (string, data->stream);
336 }
337
338 void
339 tui_message (struct ui_out *uiout, int verbosity,
340              const char *format, va_list args)
341 {
342   struct ui_out_data *data = ui_out_data (uiout);
343   if (data->suppress_output)
344     return;
345   if (ui_out_get_verblvl (uiout) >= verbosity)
346     vfprintf_unfiltered (data->stream, format, args);
347 }
348
349 void
350 tui_wrap_hint (struct ui_out *uiout, char *identstring)
351 {
352   struct ui_out_data *data = ui_out_data (uiout);
353   if (data->suppress_output)
354     return;
355   wrap_here (identstring);
356 }
357
358 void
359 tui_flush (struct ui_out *uiout)
360 {
361   struct ui_out_data *data = ui_out_data (uiout);
362   gdb_flush (data->stream);
363 }
364
365 /* local functions */
366
367 /* Like tui_field_fmt, but takes a variable number of args
368    and makes a va_list and does not insert a separator */
369
370 /* VARARGS */
371 static void
372 out_field_fmt (struct ui_out *uiout, int fldno,
373                const char *fldname,
374                const char *format,...)
375 {
376   struct ui_out_data *data = ui_out_data (uiout);
377   va_list args;
378
379   va_start (args, format);
380   vfprintf_filtered (data->stream, format, args);
381
382   va_end (args);
383 }
384
385 /* access to ui_out format private members */
386
387 static void
388 field_separator (void)
389 {
390   struct ui_out_data *data = ui_out_data (uiout);
391   fputc_filtered (' ', data->stream);
392 }
393
394 /* initalize private members at startup */
395
396 struct ui_out *
397 tui_out_new (struct ui_file *stream)
398 {
399   int flags = 0;
400
401   struct ui_out_data *data = XMALLOC (struct ui_out_data);
402   data->stream = stream;
403   data->suppress_output = 0;
404   data->line = -1;
405   data->start_of_line = 1;
406   return ui_out_new (&tui_ui_out_impl, data, flags);
407 }
408
409 /* standard gdb initialization hook */
410 void
411 _initialize_tui_out (void)
412 {
413   /* nothing needs to be done */
414 }