Cleanup ui-out table impl. Add struct ui_out_table. Rename
[external/binutils.git] / gdb / ui-out.c
1 /* Output generating routines for GDB.
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 "gdb_string.h"
25 #include "expression.h"         /* For language.h */
26 #include "language.h"
27 #include "ui-out.h"
28 #include "gdb_assert.h"
29
30 /* Convenience macro for allocting typesafe memory. */
31
32 #undef XMALLOC
33 #define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
34
35 /* table header structures */
36
37 struct ui_out_hdr
38   {
39     int colno;
40     int width;
41     int alignment;
42     char *col_name;
43     char *colhdr;
44     struct ui_out_hdr *next;
45   };
46
47 /* Maintain a stack so that the info applicable to the inner most list
48    is always available.  Stack/nested level 0 is reserved for the
49    top-level result. */
50
51 enum { MAX_UI_OUT_LEVELS = 5 };
52
53 struct ui_out_level
54   {
55     /* Count each field; the first element is for non-list fields */
56     int field_count;
57     /* The type of this level. */
58     enum ui_out_type type;
59   };
60
61 /* Tables are special.  Maintain a separate structure that tracks
62    their state.  At present an output can only contain a single table
63    but that restriction might eventually be lifted.  */
64
65 struct ui_out_table
66 {
67   /* If on, a table is being generated.  */
68   int flag;
69
70   /* If on, the body of a table is being generated.  If off, the table
71      header is being generated.  */
72   int body_flag;
73
74   /* Number of table columns (as specified in the table_begin call).  */
75   int columns;
76
77   /* String identifying the table (as specified in the table_begin
78      call).  */
79   char *id;
80
81   /* Points to the first table header (if any).  */
82   struct ui_out_hdr *header_first;
83
84   /* Points to the last table header (if any).  */
85   struct ui_out_hdr *header_last;
86
87   /* Points to header of NEXT column to format.  */
88   struct ui_out_hdr *header_next;
89
90 };
91
92
93 /* The ui_out structure */
94 /* Any change here requires a corresponding one in the initialization
95    of the default uiout, which is statically initialized */
96
97 struct ui_out
98   {
99     int flags;
100     /* specific implementation of ui-out */
101     struct ui_out_impl *impl;
102     struct ui_out_data *data;
103
104     /* Sub structure tracking the ui-out depth.  */
105     int level;
106     struct ui_out_level levels[MAX_UI_OUT_LEVELS];
107
108     /* A table, if any.  At present only a single table is supported.  */
109     struct ui_out_table table;
110   };
111
112 /* The current (inner most) level. */
113 static struct ui_out_level *
114 current_level (struct ui_out *uiout)
115 {
116   return &uiout->levels[uiout->level];
117 }
118
119 /* Create a new level, of TYPE.  Return the new level's index. */
120 static int
121 push_level (struct ui_out *uiout,
122             enum ui_out_type type,
123             const char *id)
124 {
125   struct ui_out_level *current;
126   /* We had better not overflow the buffer. */
127   uiout->level++;
128   gdb_assert (uiout->level >= 0 && uiout->level < MAX_UI_OUT_LEVELS);
129   current = current_level (uiout);
130   current->field_count = 0;
131   current->type = type;
132   return uiout->level;
133 }
134
135 /* Discard the current level, return the discarded level's index.
136    TYPE is the type of the level being discarded. */
137 static int
138 pop_level (struct ui_out *uiout,
139            enum ui_out_type type)
140 {
141   /* We had better not underflow the buffer. */
142   gdb_assert (uiout->level > 0 && uiout->level < MAX_UI_OUT_LEVELS);
143   gdb_assert (current_level (uiout)->type == type);
144   uiout->level--;
145   return uiout->level + 1;
146 }
147
148
149 /* These are the default implementation functions */
150
151 static void default_table_begin (struct ui_out *uiout, int nbrofcols,
152                                  int nr_rows, const char *tblid);
153 static void default_table_body (struct ui_out *uiout);
154 static void default_table_end (struct ui_out *uiout);
155 static void default_table_header (struct ui_out *uiout, int width,
156                                   enum ui_align alig, const char *col_name,
157                                   const char *colhdr);
158 static void default_begin (struct ui_out *uiout,
159                            enum ui_out_type type,
160                            int level, const char *id);
161 static void default_end (struct ui_out *uiout,
162                          enum ui_out_type type,
163                          int level);
164 static void default_field_int (struct ui_out *uiout, int fldno, int width,
165                                enum ui_align alig,
166                                const char *fldname,
167                                int value);
168 static void default_field_skip (struct ui_out *uiout, int fldno, int width,
169                                 enum ui_align alig,
170                                 const char *fldname);
171 static void default_field_string (struct ui_out *uiout, int fldno, int width,
172                                   enum ui_align align,
173                                   const char *fldname,
174                                   const char *string);
175 static void default_field_fmt (struct ui_out *uiout, int fldno,
176                                int width, enum ui_align align,
177                                const char *fldname,
178                                const char *format,
179                                va_list args);
180 static void default_spaces (struct ui_out *uiout, int numspaces);
181 static void default_text (struct ui_out *uiout, const char *string);
182 static void default_message (struct ui_out *uiout, int verbosity,
183                              const char *format,
184                              va_list args);
185 static void default_wrap_hint (struct ui_out *uiout, char *identstring);
186 static void default_flush (struct ui_out *uiout);
187
188 /* This is the default ui-out implementation functions vector */
189
190 struct ui_out_impl default_ui_out_impl =
191 {
192   default_table_begin,
193   default_table_body,
194   default_table_end,
195   default_table_header,
196   default_begin,
197   default_end,
198   default_field_int,
199   default_field_skip,
200   default_field_string,
201   default_field_fmt,
202   default_spaces,
203   default_text,
204   default_message,
205   default_wrap_hint,
206   default_flush,
207   0, /* Does not need MI hacks.  */
208 };
209
210 /* The default ui_out */
211
212 struct ui_out def_uiout =
213 {
214   0,                            /* flags */
215   &default_ui_out_impl,         /* impl */
216 };
217
218 /* Pointer to current ui_out */
219 /* FIXME: This should not be a global, but something passed down from main.c
220    or top.c */
221
222 struct ui_out *uiout = &def_uiout;
223
224 /* These are the interfaces to implementation functions */
225
226 static void uo_table_begin (struct ui_out *uiout, int nbrofcols,
227                             int nr_rows, const char *tblid);
228 static void uo_table_body (struct ui_out *uiout);
229 static void uo_table_end (struct ui_out *uiout);
230 static void uo_table_header (struct ui_out *uiout, int width,
231                              enum ui_align align, const char *col_name,
232                              const char *colhdr);
233 static void uo_begin (struct ui_out *uiout,
234                       enum ui_out_type type,
235                       int level, const char *id);
236 static void uo_end (struct ui_out *uiout,
237                     enum ui_out_type type,
238                     int level);
239 static void uo_field_int (struct ui_out *uiout, int fldno, int width,
240                           enum ui_align align, const char *fldname, int value);
241 static void uo_field_skip (struct ui_out *uiout, int fldno, int width,
242                            enum ui_align align, const char *fldname);
243 static void uo_field_string (struct ui_out *uiout, int fldno, int width,
244                              enum ui_align align, const char *fldname,
245                              const char *string);
246 static void uo_field_fmt (struct ui_out *uiout, int fldno, int width,
247                           enum ui_align align, const char *fldname,
248                           const char *format, va_list args);
249 static void uo_spaces (struct ui_out *uiout, int numspaces);
250 static void uo_text (struct ui_out *uiout, const char *string);
251 static void uo_message (struct ui_out *uiout, int verbosity,
252                         const char *format, va_list args);
253 static void uo_wrap_hint (struct ui_out *uiout, char *identstring);
254 static void uo_flush (struct ui_out *uiout);
255
256 /* Prototypes for local functions */
257
258 extern void _initialize_ui_out (void);
259 static void append_header_to_list (struct ui_out *uiout, int width,
260                                    int alignment, const char *col_name,
261                                    const char *colhdr);
262 static int get_next_header (struct ui_out *uiout, int *colno, int *width,
263                             int *alignment, char **colhdr);
264 static void clear_header_list (struct ui_out *uiout);
265 static void verify_field_proper_position (struct ui_out *uiout);
266 static void verify_field_alignment (struct ui_out *uiout, int fldno, int *width, int *alignment);
267
268 static void init_ui_out_state (struct ui_out *uiout);
269
270 /* exported functions (ui_out API) */
271
272 /* Mark beginning of a table */
273
274 void
275 ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
276                     int nr_rows,
277                     const char *tblid)
278 {
279   if (uiout->table.flag)
280     internal_error (__FILE__, __LINE__,
281                     "tables cannot be nested; table_begin found before \
282 previous table_end.");
283
284   uiout->table.flag = 1;
285   uiout->table.body_flag = 0;
286   uiout->table.columns = nbrofcols;
287   if (tblid != NULL)
288     uiout->table.id = xstrdup (tblid);
289   else
290     uiout->table.id = NULL;
291   clear_header_list (uiout);
292
293   uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id);
294 }
295
296 void
297 ui_out_table_body (struct ui_out *uiout)
298 {
299   if (!uiout->table.flag)
300     internal_error (__FILE__, __LINE__,
301                     "table_body outside a table is not valid; it must be \
302 after a table_begin and before a table_end.");
303   if (uiout->table.body_flag)
304     internal_error (__FILE__, __LINE__,
305                     "extra table_body call not allowed; there must be \
306 only one table_body after a table_begin and before a table_end.");
307   if (uiout->table.header_next->colno != uiout->table.columns)
308     internal_error (__FILE__, __LINE__,
309                     "number of headers differ from number of table \
310 columns.");
311
312   uiout->table.body_flag = 1;
313   uiout->table.header_next = uiout->table.header_first;
314
315   uo_table_body (uiout);
316 }
317
318 void
319 ui_out_table_end (struct ui_out *uiout)
320 {
321   if (!uiout->table.flag)
322     internal_error (__FILE__, __LINE__,
323                     "misplaced table_end or missing table_begin.");
324
325   uiout->table.body_flag = 0;
326   uiout->table.flag = 0;
327
328   uo_table_end (uiout);
329
330   if (uiout->table.id)
331     xfree (uiout->table.id);
332   clear_header_list (uiout);
333 }
334
335 void
336 ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
337                      const char *col_name,
338                      const char *colhdr)
339 {
340   if (!uiout->table.flag || uiout->table.body_flag)
341     internal_error (__FILE__, __LINE__,
342                     "table header must be specified after table_begin \
343 and before table_body.");
344
345   append_header_to_list (uiout, width, alignment, col_name, colhdr);
346
347   uo_table_header (uiout, width, alignment, col_name, colhdr);
348 }
349
350 void
351 ui_out_begin (struct ui_out *uiout,
352               enum ui_out_type type,
353               const char *id)
354 {
355   int new_level;
356   if (uiout->table.flag && !uiout->table.body_flag)
357     internal_error (__FILE__, __LINE__,
358                     "table header or table_body expected; lists must be \
359 specified after table_body.");
360   new_level = push_level (uiout, type, id);
361   if (uiout->table.flag && (new_level == 1))
362     uiout->table.header_next = uiout->table.header_first;
363   uo_begin (uiout, type, new_level, id);
364 }
365
366 void
367 ui_out_list_begin (struct ui_out *uiout,
368                    const char *id)
369 {
370   ui_out_begin (uiout, ui_out_type_list, id);
371 }
372
373 void
374 ui_out_tuple_begin (struct ui_out *uiout, const char *id)
375 {
376   ui_out_begin (uiout, ui_out_type_tuple, id);
377 }
378
379 void
380 ui_out_end (struct ui_out *uiout,
381             enum ui_out_type type)
382 {
383   int old_level = pop_level (uiout, type);
384   uo_end (uiout, type, old_level);
385 }
386
387 void
388 ui_out_list_end (struct ui_out *uiout)
389 {
390   ui_out_end (uiout, ui_out_type_list);
391 }
392
393 void
394 ui_out_tuple_end (struct ui_out *uiout)
395 {
396   ui_out_end (uiout, ui_out_type_tuple);
397 }
398
399 struct ui_out_end_cleanup_data
400 {
401   struct ui_out *uiout;
402   enum ui_out_type type;
403 };
404
405 static void
406 do_cleanup_end (void *data)
407 {
408   struct ui_out_end_cleanup_data *end_cleanup_data = data;
409   ui_out_end (end_cleanup_data->uiout, end_cleanup_data->type);
410   xfree (end_cleanup_data);
411 }
412
413 static struct cleanup *
414 make_cleanup_ui_out_end (struct ui_out *uiout,
415                          enum ui_out_type type)
416 {
417   struct ui_out_end_cleanup_data *end_cleanup_data;
418   end_cleanup_data = XMALLOC (struct ui_out_end_cleanup_data);
419   end_cleanup_data->uiout = uiout;
420   end_cleanup_data->type = type;
421   return make_cleanup (do_cleanup_end, end_cleanup_data);
422 }
423
424 struct cleanup *
425 make_cleanup_ui_out_begin_end (struct ui_out *uiout,
426                                enum ui_out_type type,
427                                const char *id)
428 {
429   ui_out_begin (uiout, type, id);
430   return make_cleanup_ui_out_end (uiout, type);
431 }
432
433 struct cleanup *
434 make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout,
435                                      const char *id)
436 {
437   ui_out_tuple_begin (uiout, id);
438   return make_cleanup_ui_out_end (uiout, ui_out_type_tuple);
439 }
440
441 struct cleanup *
442 make_cleanup_ui_out_list_begin_end (struct ui_out *uiout,
443                                     const char *id)
444 {
445   ui_out_list_begin (uiout, id);
446   return make_cleanup_ui_out_end (uiout, ui_out_type_list);
447 }
448
449 void
450 ui_out_field_int (struct ui_out *uiout,
451                   const char *fldname,
452                   int value)
453 {
454   int fldno;
455   int width;
456   int align;
457   struct ui_out_level *current = current_level (uiout);
458
459   verify_field_proper_position (uiout);
460
461   current->field_count += 1;
462   fldno = current->field_count;
463
464   verify_field_alignment (uiout, fldno, &width, &align);
465
466   uo_field_int (uiout, fldno, width, align, fldname, value);
467 }
468
469 void
470 ui_out_field_core_addr (struct ui_out *uiout,
471                         const char *fldname,
472                         CORE_ADDR address)
473 {
474   char addstr[20];
475
476   /* FIXME-32x64: need a print_address_numeric with field width */
477   /* print_address_numeric (address, 1, local_stream); */
478   strcpy (addstr, local_hex_string_custom ((unsigned long) address, "08l"));
479
480   ui_out_field_string (uiout, fldname, addstr);
481 }
482
483 void
484 ui_out_field_stream (struct ui_out *uiout,
485                      const char *fldname,
486                      struct ui_stream *buf)
487 {
488   long length;
489   char *buffer = ui_file_xstrdup (buf->stream, &length);
490   struct cleanup *old_cleanup = make_cleanup (xfree, buffer);
491   if (length > 0)
492     ui_out_field_string (uiout, fldname, buffer);
493   else
494     ui_out_field_skip (uiout, fldname);
495   ui_file_rewind (buf->stream);
496   do_cleanups (old_cleanup);
497 }
498
499 /* used to ommit a field */
500
501 void
502 ui_out_field_skip (struct ui_out *uiout,
503                    const char *fldname)
504 {
505   int fldno;
506   int width;
507   int align;
508   struct ui_out_level *current = current_level (uiout);
509
510   verify_field_proper_position (uiout);
511
512   current->field_count += 1;
513   fldno = current->field_count;
514
515   verify_field_alignment (uiout, fldno, &width, &align);
516
517   uo_field_skip (uiout, fldno, width, align, fldname);
518 }
519
520 void
521 ui_out_field_string (struct ui_out *uiout,
522                      const char *fldname,
523                      const char *string)
524 {
525   int fldno;
526   int width;
527   int align;
528   struct ui_out_level *current = current_level (uiout);
529
530   verify_field_proper_position (uiout);
531
532   current->field_count += 1;
533   fldno = current->field_count;
534
535   verify_field_alignment (uiout, fldno, &width, &align);
536
537   uo_field_string (uiout, fldno, width, align, fldname, string);
538 }
539
540 /* VARARGS */
541 void
542 ui_out_field_fmt (struct ui_out *uiout,
543                   const char *fldname,
544                   const char *format, ...)
545 {
546   va_list args;
547   int fldno;
548   int width;
549   int align;
550   struct ui_out_level *current = current_level (uiout);
551
552   verify_field_proper_position (uiout);
553
554   current->field_count += 1;
555   fldno = current->field_count;
556
557   /* will not align, but has to call anyway */
558   verify_field_alignment (uiout, fldno, &width, &align);
559
560   va_start (args, format);
561
562   uo_field_fmt (uiout, fldno, width, align, fldname, format, args);
563
564   va_end (args);
565 }
566
567 void
568 ui_out_spaces (struct ui_out *uiout, int numspaces)
569 {
570   uo_spaces (uiout, numspaces);
571 }
572
573 void
574 ui_out_text (struct ui_out *uiout,
575              const char *string)
576 {
577   uo_text (uiout, string);
578 }
579
580 void
581 ui_out_message (struct ui_out *uiout, int verbosity,
582                 const char *format,...)
583 {
584   va_list args;
585
586   va_start (args, format);
587
588   uo_message (uiout, verbosity, format, args);
589
590   va_end (args);
591 }
592
593 struct ui_stream *
594 ui_out_stream_new (struct ui_out *uiout)
595 {
596   struct ui_stream *tempbuf;
597
598   tempbuf = XMALLOC (struct ui_stream);
599   tempbuf->uiout = uiout;
600   tempbuf->stream = mem_fileopen ();
601   return tempbuf;
602 }
603
604 void
605 ui_out_stream_delete (struct ui_stream *buf)
606 {
607   ui_file_delete (buf->stream);
608   xfree (buf);
609 }
610
611 static void
612 do_stream_delete (void *buf)
613 {
614   ui_out_stream_delete (buf);
615 }
616
617 struct cleanup *
618 make_cleanup_ui_out_stream_delete (struct ui_stream *buf)
619 {
620   return make_cleanup (do_stream_delete, buf);
621 }
622
623
624 void
625 ui_out_wrap_hint (struct ui_out *uiout, char *identstring)
626 {
627   uo_wrap_hint (uiout, identstring);
628 }
629
630 void
631 ui_out_flush (struct ui_out *uiout)
632 {
633   uo_flush (uiout);
634 }
635
636 /* set the flags specified by the mask given */
637 int
638 ui_out_set_flags (struct ui_out *uiout, int mask)
639 {
640   int oldflags = uiout->flags;
641
642   uiout->flags |= mask;
643
644   return oldflags;
645 }
646
647 /* clear the flags specified by the mask given */
648 int
649 ui_out_clear_flags (struct ui_out *uiout, int mask)
650 {
651   int oldflags = uiout->flags;
652
653   uiout->flags &= ~mask;
654
655   return oldflags;
656 }
657
658 /* test the flags against the mask given */
659 int
660 ui_out_test_flags (struct ui_out *uiout, int mask)
661 {
662   return (uiout->flags & mask);
663 }
664
665 /* obtain the current verbosity level (as stablished by the
666    'set verbositylevel' command */
667
668 int
669 ui_out_get_verblvl (struct ui_out *uiout)
670 {
671   /* FIXME: not implemented yet */
672   return 0;
673 }
674
675 #if 0
676 void
677 ui_out_result_begin (struct ui_out *uiout, char *class)
678 {
679 }
680
681 void
682 ui_out_result_end (struct ui_out *uiout)
683 {
684 }
685
686 void
687 ui_out_info_begin (struct ui_out *uiout, char *class)
688 {
689 }
690
691 void
692 ui_out_info_end (struct ui_out *uiout)
693 {
694 }
695
696 void
697 ui_out_notify_begin (struct ui_out *uiout, char *class)
698 {
699 }
700
701 void
702 ui_out_notify_end (struct ui_out *uiout)
703 {
704 }
705
706 void
707 ui_out_error_begin (struct ui_out *uiout, char *class)
708 {
709 }
710
711 void
712 ui_out_error_end (struct ui_out *uiout)
713 {
714 }
715 #endif
716
717 #if 0
718 void
719 gdb_error (ui_out * uiout, int severity, char *format,...)
720 {
721   va_list args;
722 }
723
724 void
725 gdb_query (struct ui_out *uiout, int qflags, char *qprompt)
726 {
727 }
728 #endif
729
730 int
731 ui_out_is_mi_like_p (struct ui_out *uiout)
732 {
733   return uiout->impl->is_mi_like_p;
734 }
735
736 /* default gdb-out hook functions */
737
738 static void
739 default_table_begin (struct ui_out *uiout, int nbrofcols,
740                      int nr_rows,
741                      const char *tblid)
742 {
743 }
744
745 static void
746 default_table_body (struct ui_out *uiout)
747 {
748 }
749
750 static void
751 default_table_end (struct ui_out *uiout)
752 {
753 }
754
755 static void
756 default_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
757                       const char *col_name,
758                       const char *colhdr)
759 {
760 }
761
762 static void
763 default_begin (struct ui_out *uiout,
764                enum ui_out_type type,
765                int level,
766                const char *id)
767 {
768 }
769
770 static void
771 default_end (struct ui_out *uiout,
772              enum ui_out_type type,
773              int level)
774 {
775 }
776
777 static void
778 default_field_int (struct ui_out *uiout, int fldno, int width,
779                    enum ui_align align,
780                    const char *fldname, int value)
781 {
782 }
783
784 static void
785 default_field_skip (struct ui_out *uiout, int fldno, int width,
786                     enum ui_align align, const char *fldname)
787 {
788 }
789
790 static void
791 default_field_string (struct ui_out *uiout,
792                       int fldno,
793                       int width,
794                       enum ui_align align,
795                       const char *fldname,
796                       const char *string)
797 {
798 }
799
800 static void
801 default_field_fmt (struct ui_out *uiout, int fldno, int width,
802                    enum ui_align align,
803                    const char *fldname,
804                    const char *format,
805                    va_list args)
806 {
807 }
808
809 static void
810 default_spaces (struct ui_out *uiout, int numspaces)
811 {
812 }
813
814 static void
815 default_text (struct ui_out *uiout, const char *string)
816 {
817 }
818
819 static void
820 default_message (struct ui_out *uiout, int verbosity,
821                  const char *format,
822                  va_list args)
823 {
824 }
825
826 static void
827 default_wrap_hint (struct ui_out *uiout, char *identstring)
828 {
829 }
830
831 static void
832 default_flush (struct ui_out *uiout)
833 {
834 }
835
836 /* Interface to the implementation functions */
837
838 void
839 uo_table_begin (struct ui_out *uiout, int nbrofcols,
840                 int nr_rows,
841                 const char *tblid)
842 {
843   if (!uiout->impl->table_begin)
844     return;
845   uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid);
846 }
847
848 void
849 uo_table_body (struct ui_out *uiout)
850 {
851   if (!uiout->impl->table_body)
852     return;
853   uiout->impl->table_body (uiout);
854 }
855
856 void
857 uo_table_end (struct ui_out *uiout)
858 {
859   if (!uiout->impl->table_end)
860     return;
861   uiout->impl->table_end (uiout);
862 }
863
864 void
865 uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
866                  const char *col_name,
867                  const char *colhdr)
868 {
869   if (!uiout->impl->table_header)
870     return;
871   uiout->impl->table_header (uiout, width, align, col_name, colhdr);
872 }
873
874 void
875 uo_begin (struct ui_out *uiout,
876           enum ui_out_type type,
877           int level,
878           const char *id)
879 {
880   if (uiout->impl->begin == NULL)
881     return;
882   uiout->impl->begin (uiout, type, level, id);
883 }
884
885 void
886 uo_end (struct ui_out *uiout,
887         enum ui_out_type type,
888         int level)
889 {
890   if (uiout->impl->end == NULL)
891     return;
892   uiout->impl->end (uiout, type, level);
893 }
894
895 void
896 uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align,
897               const char *fldname,
898               int value)
899 {
900   if (!uiout->impl->field_int)
901     return;
902   uiout->impl->field_int (uiout, fldno, width, align, fldname, value);
903 }
904
905 void
906 uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align,
907                const char *fldname)
908 {
909   if (!uiout->impl->field_skip)
910     return;
911   uiout->impl->field_skip (uiout, fldno, width, align, fldname);
912 }
913
914 void
915 uo_field_string (struct ui_out *uiout, int fldno, int width,
916                  enum ui_align align,
917                  const char *fldname,
918                  const char *string)
919 {
920   if (!uiout->impl->field_string)
921     return;
922   uiout->impl->field_string (uiout, fldno, width, align, fldname, string);
923 }
924
925 void
926 uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align,
927               const char *fldname,
928               const char *format,
929               va_list args)
930 {
931   if (!uiout->impl->field_fmt)
932     return;
933   uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args);
934 }
935
936 void
937 uo_spaces (struct ui_out *uiout, int numspaces)
938 {
939   if (!uiout->impl->spaces)
940     return;
941   uiout->impl->spaces (uiout, numspaces);
942 }
943
944 void
945 uo_text (struct ui_out *uiout,
946          const char *string)
947 {
948   if (!uiout->impl->text)
949     return;
950   uiout->impl->text (uiout, string);
951 }
952
953 void
954 uo_message (struct ui_out *uiout, int verbosity,
955             const char *format,
956             va_list args)
957 {
958   if (!uiout->impl->message)
959     return;
960   uiout->impl->message (uiout, verbosity, format, args);
961 }
962
963 void
964 uo_wrap_hint (struct ui_out *uiout, char *identstring)
965 {
966   if (!uiout->impl->wrap_hint)
967     return;
968   uiout->impl->wrap_hint (uiout, identstring);
969 }
970
971 void
972 uo_flush (struct ui_out *uiout)
973 {
974   if (!uiout->impl->flush)
975     return;
976   uiout->impl->flush (uiout);
977 }
978
979 /* local functions */
980
981 /* list of column headers manipulation routines */
982
983 static void
984 clear_header_list (struct ui_out *uiout)
985 {
986   while (uiout->table.header_first != NULL)
987     {
988       uiout->table.header_next = uiout->table.header_first;
989       uiout->table.header_first = uiout->table.header_first->next;
990       if (uiout->table.header_next->colhdr != NULL)
991         xfree (uiout->table.header_next->colhdr);
992       xfree (uiout->table.header_next);
993     }
994   gdb_assert (uiout->table.header_first == NULL);
995   uiout->table.header_last = NULL;
996   uiout->table.header_next = NULL;
997 }
998
999 static void
1000 append_header_to_list (struct ui_out *uiout,
1001                        int width,
1002                        int alignment,
1003                        const char *col_name,
1004                        const char *colhdr)
1005 {
1006   struct ui_out_hdr *temphdr;
1007
1008   temphdr = XMALLOC (struct ui_out_hdr);
1009   temphdr->width = width;
1010   temphdr->alignment = alignment;
1011   /* we have to copy the column title as the original may be an automatic */
1012   if (colhdr != NULL)
1013     temphdr->colhdr = xstrdup (colhdr);
1014   else
1015     temphdr->colhdr = NULL;
1016   if (col_name != NULL)
1017     temphdr->col_name = xstrdup (colhdr);
1018   else
1019     temphdr->col_name = xstrdup (colhdr);
1020   temphdr->next = NULL;
1021   if (uiout->table.header_first == NULL)
1022     {
1023       temphdr->colno = 1;
1024       uiout->table.header_first = temphdr;
1025       uiout->table.header_last = temphdr;
1026     }
1027   else
1028     {
1029       temphdr->colno = uiout->table.header_last->colno + 1;
1030       uiout->table.header_last->next = temphdr;
1031       uiout->table.header_last = temphdr;
1032     }
1033   uiout->table.header_next = uiout->table.header_last;
1034 }
1035
1036 /* Extract the format information for the NEXT header and and advance
1037    the header pointer.  Return 0 if there was no next header.  */
1038
1039 static int
1040 get_next_header (struct ui_out *uiout,
1041                  int *colno,
1042                  int *width,
1043                  int *alignment,
1044                  char **colhdr)
1045 {
1046   /* There may be no headers at all or we may have used all columns.  */
1047   if (uiout->table.header_next == NULL)
1048     return 0;
1049   *colno = uiout->table.header_next->colno;
1050   *width = uiout->table.header_next->width;
1051   *alignment = uiout->table.header_next->alignment;
1052   *colhdr = uiout->table.header_next->colhdr;
1053   /* Advance the header pointer to the next entry.  */
1054   uiout->table.header_next = uiout->table.header_next->next;
1055   return 1;
1056 }
1057
1058 /* makes sure the field_* calls were properly placed */
1059
1060 static void
1061 verify_field_proper_position (struct ui_out *uiout)
1062 {
1063   if (uiout->table.flag)
1064     {
1065       if (!uiout->table.body_flag)
1066         internal_error (__FILE__, __LINE__,
1067                         "table_body missing; table fields must be \
1068 specified after table_body and inside a list.");
1069       if (uiout->level == 0)
1070         internal_error (__FILE__, __LINE__,
1071                         "list_begin missing; table fields must be \
1072 specified after table_body and inside a list.");
1073     }
1074 }
1075
1076 /* determines what is the alignment policy */
1077
1078 static void
1079 verify_field_alignment (struct ui_out *uiout,
1080                         int fldno,
1081                         int *width,
1082                         int *align)
1083 {
1084   int colno;
1085   char *text;
1086
1087   if (uiout->table.flag
1088       && get_next_header (uiout, &colno, width, align, &text))
1089     {
1090       if (fldno != colno)
1091         internal_error (__FILE__, __LINE__,
1092                         "ui-out internal error in handling headers.");
1093     }
1094   else
1095     {
1096       *width = 0;
1097       *align = ui_noalign;
1098     }
1099 }
1100
1101 /* access to ui_out format private members */
1102
1103 void
1104 ui_out_get_field_separator (struct ui_out *uiout)
1105 {
1106 }
1107
1108 /* Access to ui-out members data */
1109
1110 struct ui_out_data *
1111 ui_out_data (struct ui_out *uiout)
1112 {
1113   return uiout->data;
1114 }
1115
1116 /* initalize private members at startup */
1117
1118 struct ui_out *
1119 ui_out_new (struct ui_out_impl *impl,
1120             struct ui_out_data *data,
1121             int flags)
1122 {
1123   struct ui_out *uiout = XMALLOC (struct ui_out);
1124   uiout->data = data;
1125   uiout->impl = impl;
1126   uiout->flags = flags;
1127   uiout->table.flag = 0;
1128   uiout->table.body_flag = 0;
1129   uiout->level = 0;
1130   memset (uiout->levels, 0, sizeof (uiout->levels));
1131   uiout->table.header_first = NULL;
1132   uiout->table.header_last = NULL;
1133   uiout->table.header_next = NULL;
1134   return uiout;
1135 }
1136
1137 /* standard gdb initialization hook */
1138
1139 void
1140 _initialize_ui_out (void)
1141 {
1142   /* nothing needs to be done */
1143 }