1 /* Output generating routines for GDB. 2 3 Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009, 2010 4 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 char addstr[20]; 496 int addr_bit = gdbarch_addr_bit (gdbarch); 497 498 if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) 499 address &= ((CORE_ADDR) 1 << addr_bit) - 1; 500 501 /* FIXME: cagney/2002-05-03: Need local_address_string() function 502 that returns the language localized string formatted to a width 503 based on gdbarch_addr_bit. */ 504 if (addr_bit <= 32) 505 strcpy (addstr, hex_string_custom (address, 8)); 506 else 507 strcpy (addstr, hex_string_custom (address, 16)); 508 509 ui_out_field_string (uiout, fldname, addstr); 510 } 511 512 void 513 ui_out_field_stream (struct ui_out *uiout, 514 const char *fldname, 515 struct ui_stream *buf) 516 { 517 long length; 518 char *buffer = ui_file_xstrdup (buf->stream, &length); 519 struct cleanup *old_cleanup = make_cleanup (xfree, buffer); 520 521 if (length > 0) 522 ui_out_field_string (uiout, fldname, buffer); 523 else 524 ui_out_field_skip (uiout, fldname); 525 ui_file_rewind (buf->stream); 526 do_cleanups (old_cleanup); 527 } 528 529 /* used to ommit a field */ 530 531 void 532 ui_out_field_skip (struct ui_out *uiout, 533 const char *fldname) 534 { 535 int fldno; 536 int width; 537 int align; 538 539 verify_field (uiout, &fldno, &width, &align); 540 541 uo_field_skip (uiout, fldno, width, align, fldname); 542 } 543 544 void 545 ui_out_field_string (struct ui_out *uiout, 546 const char *fldname, 547 const char *string) 548 { 549 int fldno; 550 int width; 551 int align; 552 553 verify_field (uiout, &fldno, &width, &align); 554 555 uo_field_string (uiout, fldno, width, align, fldname, string); 556 } 557 558 /* VARARGS */ 559 void 560 ui_out_field_fmt (struct ui_out *uiout, 561 const char *fldname, 562 const char *format, ...) 563 { 564 va_list args; 565 int fldno; 566 int width; 567 int align; 568 569 /* will not align, but has to call anyway */ 570 verify_field (uiout, &fldno, &width, &align); 571 572 va_start (args, format); 573 574 uo_field_fmt (uiout, fldno, width, align, fldname, format, args); 575 576 va_end (args); 577 } 578 579 void 580 ui_out_spaces (struct ui_out *uiout, int numspaces) 581 { 582 uo_spaces (uiout, numspaces); 583 } 584 585 void 586 ui_out_text (struct ui_out *uiout, 587 const char *string) 588 { 589 uo_text (uiout, string); 590 } 591 592 void 593 ui_out_message (struct ui_out *uiout, int verbosity, 594 const char *format,...) 595 { 596 va_list args; 597 598 va_start (args, format); 599 uo_message (uiout, verbosity, format, args); 600 va_end (args); 601 } 602 603 struct ui_stream * 604 ui_out_stream_new (struct ui_out *uiout) 605 { 606 struct ui_stream *tempbuf; 607 608 tempbuf = XMALLOC (struct ui_stream); 609 tempbuf->uiout = uiout; 610 tempbuf->stream = mem_fileopen (); 611 return tempbuf; 612 } 613 614 void 615 ui_out_stream_delete (struct ui_stream *buf) 616 { 617 ui_file_delete (buf->stream); 618 xfree (buf); 619 } 620 621 static void 622 do_stream_delete (void *buf) 623 { 624 ui_out_stream_delete (buf); 625 } 626 627 struct cleanup * 628 make_cleanup_ui_out_stream_delete (struct ui_stream *buf) 629 { 630 return make_cleanup (do_stream_delete, buf); 631 } 632 633 634 void 635 ui_out_wrap_hint (struct ui_out *uiout, char *identstring) 636 { 637 uo_wrap_hint (uiout, identstring); 638 } 639 640 void 641 ui_out_flush (struct ui_out *uiout) 642 { 643 uo_flush (uiout); 644 } 645 646 int 647 ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream) 648 { 649 return uo_redirect (uiout, outstream); 650 } 651 652 /* set the flags specified by the mask given */ 653 int 654 ui_out_set_flags (struct ui_out *uiout, int mask) 655 { 656 int oldflags = uiout->flags; 657 658 uiout->flags |= mask; 659 return oldflags; 660 } 661 662 /* clear the flags specified by the mask given */ 663 int 664 ui_out_clear_flags (struct ui_out *uiout, int mask) 665 { 666 int oldflags = uiout->flags; 667 668 uiout->flags &= ~mask; 669 return oldflags; 670 } 671 672 /* test the flags against the mask given */ 673 int 674 ui_out_test_flags (struct ui_out *uiout, int mask) 675 { 676 return (uiout->flags & mask); 677 } 678 679 /* obtain the current verbosity level (as stablished by the 680 'set verbositylevel' command */ 681 682 int 683 ui_out_get_verblvl (struct ui_out *uiout) 684 { 685 /* FIXME: not implemented yet */ 686 return 0; 687 } 688 689 #if 0 690 void 691 ui_out_result_begin (struct ui_out *uiout, char *class) 692 { 693 } 694 695 void 696 ui_out_result_end (struct ui_out *uiout) 697 { 698 } 699 700 void 701 ui_out_info_begin (struct ui_out *uiout, char *class) 702 { 703 } 704 705 void 706 ui_out_info_end (struct ui_out *uiout) 707 { 708 } 709 710 void 711 ui_out_notify_begin (struct ui_out *uiout, char *class) 712 { 713 } 714 715 void 716 ui_out_notify_end (struct ui_out *uiout) 717 { 718 } 719 720 void 721 ui_out_error_begin (struct ui_out *uiout, char *class) 722 { 723 } 724 725 void 726 ui_out_error_end (struct ui_out *uiout) 727 { 728 } 729 #endif 730 731 #if 0 732 void 733 gdb_error (ui_out * uiout, int severity, char *format,...) 734 { 735 va_list args; 736 } 737 738 void 739 gdb_query (struct ui_out *uiout, int qflags, char *qprompt) 740 { 741 } 742 #endif 743 744 int 745 ui_out_is_mi_like_p (struct ui_out *uiout) 746 { 747 return uiout->impl->is_mi_like_p; 748 } 749 750 /* default gdb-out hook functions */ 751 752 static void 753 default_table_begin (struct ui_out *uiout, int nbrofcols, 754 int nr_rows, 755 const char *tblid) 756 { 757 } 758 759 static void 760 default_table_body (struct ui_out *uiout) 761 { 762 } 763 764 static void 765 default_table_end (struct ui_out *uiout) 766 { 767 } 768 769 static void 770 default_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 771 const char *col_name, 772 const char *colhdr) 773 { 774 } 775 776 static void 777 default_begin (struct ui_out *uiout, 778 enum ui_out_type type, 779 int level, 780 const char *id) 781 { 782 } 783 784 static void 785 default_end (struct ui_out *uiout, 786 enum ui_out_type type, 787 int level) 788 { 789 } 790 791 static void 792 default_field_int (struct ui_out *uiout, int fldno, int width, 793 enum ui_align align, 794 const char *fldname, int value) 795 { 796 } 797 798 static void 799 default_field_skip (struct ui_out *uiout, int fldno, int width, 800 enum ui_align align, const char *fldname) 801 { 802 } 803 804 static void 805 default_field_string (struct ui_out *uiout, 806 int fldno, 807 int width, 808 enum ui_align align, 809 const char *fldname, 810 const char *string) 811 { 812 } 813 814 static void 815 default_field_fmt (struct ui_out *uiout, int fldno, int width, 816 enum ui_align align, 817 const char *fldname, 818 const char *format, 819 va_list args) 820 { 821 } 822 823 static void 824 default_spaces (struct ui_out *uiout, int numspaces) 825 { 826 } 827 828 static void 829 default_text (struct ui_out *uiout, const char *string) 830 { 831 } 832 833 static void 834 default_message (struct ui_out *uiout, int verbosity, 835 const char *format, 836 va_list args) 837 { 838 } 839 840 static void 841 default_wrap_hint (struct ui_out *uiout, char *identstring) 842 { 843 } 844 845 static void 846 default_flush (struct ui_out *uiout) 847 { 848 } 849 850 /* Interface to the implementation functions */ 851 852 void 853 uo_table_begin (struct ui_out *uiout, int nbrofcols, 854 int nr_rows, 855 const char *tblid) 856 { 857 if (!uiout->impl->table_begin) 858 return; 859 uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid); 860 } 861 862 void 863 uo_table_body (struct ui_out *uiout) 864 { 865 if (!uiout->impl->table_body) 866 return; 867 uiout->impl->table_body (uiout); 868 } 869 870 void 871 uo_table_end (struct ui_out *uiout) 872 { 873 if (!uiout->impl->table_end) 874 return; 875 uiout->impl->table_end (uiout); 876 } 877 878 void 879 uo_table_header (struct ui_out *uiout, int width, enum ui_align align, 880 const char *col_name, 881 const char *colhdr) 882 { 883 if (!uiout->impl->table_header) 884 return; 885 uiout->impl->table_header (uiout, width, align, col_name, colhdr); 886 } 887 888 void 889 uo_begin (struct ui_out *uiout, 890 enum ui_out_type type, 891 int level, 892 const char *id) 893 { 894 if (uiout->impl->begin == NULL) 895 return; 896 uiout->impl->begin (uiout, type, level, id); 897 } 898 899 void 900 uo_end (struct ui_out *uiout, 901 enum ui_out_type type, 902 int level) 903 { 904 if (uiout->impl->end == NULL) 905 return; 906 uiout->impl->end (uiout, type, level); 907 } 908 909 void 910 uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align, 911 const char *fldname, 912 int value) 913 { 914 if (!uiout->impl->field_int) 915 return; 916 uiout->impl->field_int (uiout, fldno, width, align, fldname, value); 917 } 918 919 void 920 uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align, 921 const char *fldname) 922 { 923 if (!uiout->impl->field_skip) 924 return; 925 uiout->impl->field_skip (uiout, fldno, width, align, fldname); 926 } 927 928 void 929 uo_field_string (struct ui_out *uiout, int fldno, int width, 930 enum ui_align align, 931 const char *fldname, 932 const char *string) 933 { 934 if (!uiout->impl->field_string) 935 return; 936 uiout->impl->field_string (uiout, fldno, width, align, fldname, string); 937 } 938 939 void 940 uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align, 941 const char *fldname, 942 const char *format, 943 va_list args) 944 { 945 if (!uiout->impl->field_fmt) 946 return; 947 uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args); 948 } 949 950 void 951 uo_spaces (struct ui_out *uiout, int numspaces) 952 { 953 if (!uiout->impl->spaces) 954 return; 955 uiout->impl->spaces (uiout, numspaces); 956 } 957 958 void 959 uo_text (struct ui_out *uiout, 960 const char *string) 961 { 962 if (!uiout->impl->text) 963 return; 964 uiout->impl->text (uiout, string); 965 } 966 967 void 968 uo_message (struct ui_out *uiout, int verbosity, 969 const char *format, 970 va_list args) 971 { 972 if (!uiout->impl->message) 973 return; 974 uiout->impl->message (uiout, verbosity, format, args); 975 } 976 977 void 978 uo_wrap_hint (struct ui_out *uiout, char *identstring) 979 { 980 if (!uiout->impl->wrap_hint) 981 return; 982 uiout->impl->wrap_hint (uiout, identstring); 983 } 984 985 void 986 uo_flush (struct ui_out *uiout) 987 { 988 if (!uiout->impl->flush) 989 return; 990 uiout->impl->flush (uiout); 991 } 992 993 int 994 uo_redirect (struct ui_out *uiout, struct ui_file *outstream) 995 { 996 if (!uiout->impl->redirect) 997 return -1; 998 uiout->impl->redirect (uiout, outstream); 999 return 0; 1000 } 1001 1002 /* local functions */ 1003 1004 /* list of column headers manipulation routines */ 1005 1006 static void 1007 clear_header_list (struct ui_out *uiout) 1008 { 1009 while (uiout->table.header_first != NULL) 1010 { 1011 uiout->table.header_next = uiout->table.header_first; 1012 uiout->table.header_first = uiout->table.header_first->next; 1013 if (uiout->table.header_next->colhdr != NULL) 1014 xfree (uiout->table.header_next->colhdr); 1015 xfree (uiout->table.header_next); 1016 } 1017 gdb_assert (uiout->table.header_first == NULL); 1018 uiout->table.header_last = NULL; 1019 uiout->table.header_next = NULL; 1020 } 1021 1022 static void 1023 append_header_to_list (struct ui_out *uiout, 1024 int width, 1025 int alignment, 1026 const char *col_name, 1027 const char *colhdr) 1028 { 1029 struct ui_out_hdr *temphdr; 1030 1031 temphdr = XMALLOC (struct ui_out_hdr); 1032 temphdr->width = width; 1033 temphdr->alignment = alignment; 1034 /* We have to copy the column title as the original may be an 1035 automatic. */ 1036 if (colhdr != NULL) 1037 temphdr->colhdr = xstrdup (colhdr); 1038 else 1039 temphdr->colhdr = NULL; 1040 1041 if (col_name != NULL) 1042 temphdr->col_name = xstrdup (col_name); 1043 else if (colhdr != NULL) 1044 temphdr->col_name = xstrdup (colhdr); 1045 else 1046 temphdr->col_name = NULL; 1047 1048 temphdr->next = NULL; 1049 if (uiout->table.header_first == NULL) 1050 { 1051 temphdr->colno = 1; 1052 uiout->table.header_first = temphdr; 1053 uiout->table.header_last = temphdr; 1054 } 1055 else 1056 { 1057 temphdr->colno = uiout->table.header_last->colno + 1; 1058 uiout->table.header_last->next = temphdr; 1059 uiout->table.header_last = temphdr; 1060 } 1061 uiout->table.header_next = uiout->table.header_last; 1062 } 1063 1064 /* Extract the format information for the NEXT header and and advance 1065 the header pointer. Return 0 if there was no next header. */ 1066 1067 static int 1068 get_next_header (struct ui_out *uiout, 1069 int *colno, 1070 int *width, 1071 int *alignment, 1072 char **colhdr) 1073 { 1074 /* There may be no headers at all or we may have used all columns. */ 1075 if (uiout->table.header_next == NULL) 1076 return 0; 1077 *colno = uiout->table.header_next->colno; 1078 *width = uiout->table.header_next->width; 1079 *alignment = uiout->table.header_next->alignment; 1080 *colhdr = uiout->table.header_next->colhdr; 1081 /* Advance the header pointer to the next entry. */ 1082 uiout->table.header_next = uiout->table.header_next->next; 1083 return 1; 1084 } 1085 1086 1087 /* Verify that the field/tuple/list is correctly positioned. Return 1088 the field number and corresponding alignment (if 1089 available/applicable). */ 1090 1091 static void 1092 verify_field (struct ui_out *uiout, int *fldno, int *width, int *align) 1093 { 1094 struct ui_out_level *current = current_level (uiout); 1095 char *text; 1096 1097 if (uiout->table.flag) 1098 { 1099 if (!uiout->table.body_flag) 1100 internal_error (__FILE__, __LINE__, 1101 _("table_body missing; table fields must be \ 1102 specified after table_body and inside a list.")); 1103 /* NOTE: cagney/2001-12-08: There was a check here to ensure 1104 that this code was only executed when uiout->level was 1105 greater than zero. That no longer applies - this code is run 1106 before each table row tuple is started and at that point the 1107 level is zero. */ 1108 } 1109 1110 current->field_count += 1; 1111 1112 if (uiout->table.body_flag 1113 && uiout->table.entry_level == uiout->level 1114 && get_next_header (uiout, fldno, width, align, &text)) 1115 { 1116 if (*fldno != current->field_count) 1117 internal_error (__FILE__, __LINE__, 1118 _("ui-out internal error in handling headers.")); 1119 } 1120 else 1121 { 1122 *width = 0; 1123 *align = ui_noalign; 1124 *fldno = current->field_count; 1125 } 1126 } 1127 1128 1129 /* access to ui_out format private members */ 1130 1131 void 1132 ui_out_get_field_separator (struct ui_out *uiout) 1133 { 1134 } 1135 1136 /* Access to ui-out members data */ 1137 1138 void * 1139 ui_out_data (struct ui_out *uiout) 1140 { 1141 return uiout->data; 1142 } 1143 1144 /* initalize private members at startup */ 1145 1146 struct ui_out * 1147 ui_out_new (struct ui_out_impl *impl, void *data, 1148 int flags) 1149 { 1150 struct ui_out *uiout = XMALLOC (struct ui_out); 1151 1152 uiout->data = data; 1153 uiout->impl = impl; 1154 uiout->flags = flags; 1155 uiout->table.flag = 0; 1156 uiout->table.body_flag = 0; 1157 uiout->level = 0; 1158 memset (uiout->levels, 0, sizeof (uiout->levels)); 1159 uiout->table.header_first = NULL; 1160 uiout->table.header_last = NULL; 1161 uiout->table.header_next = NULL; 1162 return uiout; 1163 } 1164 1165 /* standard gdb initialization hook */ 1166 1167 void 1168 _initialize_ui_out (void) 1169 { 1170 /* nothing needs to be done */ 1171 } 1172