merge from gcc
[binutils-gdb.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 }