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