1 /* Output generating routines for GDB. 2 3 Copyright (C) 1999-2013 Free Software Foundation, Inc. 4 5 Contributed by Cygnus Solutions. 6 Written by Fernando Nasser for Cygnus. 7 8 This file is part of GDB. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 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 /* table header structures */ 31 32 struct ui_out_hdr 33 { 34 int colno; 35 int width; 36 int alignment; 37 char *col_name; 38 char *colhdr; 39 struct ui_out_hdr *next; 40 }; 41 42 /* Maintain a stack so that the info applicable to the inner most list 43 is always available. Stack/nested level 0 is reserved for the 44 top-level result. */ 45 46 enum { MAX_UI_OUT_LEVELS = 8 }; 47 48 struct ui_out_level 49 { 50 /* Count each field; the first element is for non-list fields. */ 51 int field_count; 52 /* The type of this level. */ 53 enum ui_out_type type; 54 }; 55 56 /* Tables are special. Maintain a separate structure that tracks 57 their state. At present an output can only contain a single table 58 but that restriction might eventually be lifted. */ 59 60 struct ui_out_table 61 { 62 /* If on, a table is being generated. */ 63 int flag; 64 65 /* If on, the body of a table is being generated. If off, the table 66 header is being generated. */ 67 int body_flag; 68 69 /* The level at which each entry of the table is to be found. A row 70 (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one 71 above that of the table. */ 72 int entry_level; 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 void *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 127 /* We had better not overflow the buffer. */ 128 uiout->level++; 129 gdb_assert (uiout->level >= 0 && uiout->level < MAX_UI_OUT_LEVELS); 130 current = current_level (uiout); 131 current->field_count = 0; 132 current->type = type; 133 return uiout->level; 134 } 135 136 /* Discard the current level, return the discarded level's index. 137 TYPE is the type of the level being discarded. */ 138 static int 139 pop_level (struct ui_out *uiout, 140 enum ui_out_type type) 141 { 142 /* We had better not underflow the buffer. */ 143 gdb_assert (uiout->level > 0 && uiout->level < MAX_UI_OUT_LEVELS); 144 gdb_assert (current_level (uiout)->type == type); 145 uiout->level--; 146 return uiout->level + 1; 147 } 148 149 150 /* These are the default implementation functions. */ 151 152 static void default_table_begin (struct ui_out *uiout, int nbrofcols, 153 int nr_rows, const char *tblid); 154 static void default_table_body (struct ui_out *uiout); 155 static void default_table_end (struct ui_out *uiout); 156 static void default_table_header (struct ui_out *uiout, int width, 157 enum ui_align alig, const char *col_name, 158 const char *colhdr); 159 static void default_begin (struct ui_out *uiout, 160 enum ui_out_type type, 161 int level, const char *id); 162 static void default_end (struct ui_out *uiout, 163 enum ui_out_type type, 164 int level); 165 static void default_field_int (struct ui_out *uiout, int fldno, int width, 166 enum ui_align alig, 167 const char *fldname, 168 int value); 169 static void default_field_skip (struct ui_out *uiout, int fldno, int width, 170 enum ui_align alig, 171 const char *fldname); 172 static void default_field_string (struct ui_out *uiout, int fldno, int width, 173 enum ui_align align, 174 const char *fldname, 175 const char *string); 176 static void default_field_fmt (struct ui_out *uiout, int fldno, 177 int width, enum ui_align align, 178 const char *fldname, 179 const char *format, 180 va_list args) ATTRIBUTE_PRINTF (6, 0); 181 static void default_spaces (struct ui_out *uiout, int numspaces); 182 static void default_text (struct ui_out *uiout, const char *string); 183 static void default_message (struct ui_out *uiout, int verbosity, 184 const char *format, 185 va_list args) ATTRIBUTE_PRINTF (3, 0); 186 static void default_wrap_hint (struct ui_out *uiout, char *identstring); 187 static void default_flush (struct ui_out *uiout); 188 static void default_data_destroy (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 default_data_destroy, 211 0, /* Does not need MI hacks. */ 212 }; 213 214 /* The default ui_out */ 215 216 struct ui_out def_uiout = 217 { 218 0, /* flags */ 219 &default_ui_out_impl, /* impl */ 220 }; 221 222 /* Pointer to current ui_out */ 223 /* FIXME: This should not be a global, but something passed down from main.c 224 or top.c. */ 225 226 struct ui_out *current_uiout = &def_uiout; 227 228 /* These are the interfaces to implementation functions. */ 229 230 static void uo_table_begin (struct ui_out *uiout, int nbrofcols, 231 int nr_rows, const char *tblid); 232 static void uo_table_body (struct ui_out *uiout); 233 static void uo_table_end (struct ui_out *uiout); 234 static void uo_table_header (struct ui_out *uiout, int width, 235 enum ui_align align, const char *col_name, 236 const char *colhdr); 237 static void uo_begin (struct ui_out *uiout, 238 enum ui_out_type type, 239 int level, const char *id); 240 static void uo_end (struct ui_out *uiout, 241 enum ui_out_type type, 242 int level); 243 static void uo_field_int (struct ui_out *uiout, int fldno, int width, 244 enum ui_align align, const char *fldname, int value); 245 static void uo_field_skip (struct ui_out *uiout, int fldno, int width, 246 enum ui_align align, const char *fldname); 247 static void uo_field_fmt (struct ui_out *uiout, int fldno, int width, 248 enum ui_align align, const char *fldname, 249 const char *format, va_list args) 250 ATTRIBUTE_PRINTF (6, 0); 251 static void uo_spaces (struct ui_out *uiout, int numspaces); 252 static void uo_text (struct ui_out *uiout, const char *string); 253 static void uo_message (struct ui_out *uiout, int verbosity, 254 const char *format, va_list args) 255 ATTRIBUTE_PRINTF (3, 0); 256 static void uo_wrap_hint (struct ui_out *uiout, char *identstring); 257 static void uo_flush (struct ui_out *uiout); 258 static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream); 259 static void uo_data_destroy (struct ui_out *uiout); 260 261 /* Prototypes for local functions */ 262 263 extern void _initialize_ui_out (void); 264 static void append_header_to_list (struct ui_out *uiout, int width, 265 int alignment, const char *col_name, 266 const char *colhdr); 267 static int get_next_header (struct ui_out *uiout, int *colno, int *width, 268 int *alignment, char **colhdr); 269 static void clear_header_list (struct ui_out *uiout); 270 static void clear_table (struct ui_out *uiout); 271 static void verify_field (struct ui_out *uiout, int *fldno, int *width, 272 int *align); 273 274 /* exported functions (ui_out API) */ 275 276 /* Mark beginning of a table. */ 277 278 static void 279 ui_out_table_begin (struct ui_out *uiout, int nbrofcols, 280 int nr_rows, 281 const char *tblid) 282 { 283 if (uiout->table.flag) 284 internal_error (__FILE__, __LINE__, 285 _("tables cannot be nested; table_begin found before \ 286 previous table_end.")); 287 288 uiout->table.flag = 1; 289 uiout->table.body_flag = 0; 290 uiout->table.entry_level = uiout->level + 1; 291 uiout->table.columns = nbrofcols; 292 if (tblid != NULL) 293 uiout->table.id = xstrdup (tblid); 294 else 295 uiout->table.id = NULL; 296 clear_header_list (uiout); 297 298 uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id); 299 } 300 301 void 302 ui_out_table_body (struct ui_out *uiout) 303 { 304 if (!uiout->table.flag) 305 internal_error (__FILE__, __LINE__, 306 _("table_body outside a table is not valid; it must be \ 307 after a table_begin and before a table_end.")); 308 if (uiout->table.body_flag) 309 internal_error (__FILE__, __LINE__, 310 _("extra table_body call not allowed; there must be \ 311 only one table_body after a table_begin and before a table_end.")); 312 if (uiout->table.header_next->colno != uiout->table.columns) 313 internal_error (__FILE__, __LINE__, 314 _("number of headers differ from number of table \ 315 columns.")); 316 317 uiout->table.body_flag = 1; 318 uiout->table.header_next = uiout->table.header_first; 319 320 uo_table_body (uiout); 321 } 322 323 static void 324 ui_out_table_end (struct ui_out *uiout) 325 { 326 if (!uiout->table.flag) 327 internal_error (__FILE__, __LINE__, 328 _("misplaced table_end or missing table_begin.")); 329 330 uiout->table.entry_level = 0; 331 uiout->table.body_flag = 0; 332 uiout->table.flag = 0; 333 334 uo_table_end (uiout); 335 clear_table (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 /* Documented in ui-out.h. */ 490 491 void 492 ui_out_field_core_addr (struct ui_out *uiout, 493 const char *fldname, 494 struct gdbarch *gdbarch, 495 CORE_ADDR address) 496 { 497 ui_out_field_string (uiout, fldname, 498 print_core_address (gdbarch, address)); 499 } 500 501 void 502 ui_out_field_stream (struct ui_out *uiout, 503 const char *fldname, 504 struct ui_file *stream) 505 { 506 long length; 507 char *buffer = ui_file_xstrdup (stream, &length); 508 struct cleanup *old_cleanup = make_cleanup (xfree, buffer); 509 510 if (length > 0) 511 ui_out_field_string (uiout, fldname, buffer); 512 else 513 ui_out_field_skip (uiout, fldname); 514 ui_file_rewind (stream); 515 do_cleanups (old_cleanup); 516 } 517 518 /* Used to omit a field. */ 519 520 void 521 ui_out_field_skip (struct ui_out *uiout, 522 const char *fldname) 523 { 524 int fldno; 525 int width; 526 int align; 527 528 verify_field (uiout, &fldno, &width, &align); 529 530 uo_field_skip (uiout, fldno, width, align, fldname); 531 } 532 533 void 534 ui_out_field_string (struct ui_out *uiout, 535 const char *fldname, 536 const char *string) 537 { 538 int fldno; 539 int width; 540 int align; 541 542 verify_field (uiout, &fldno, &width, &align); 543 544 uo_field_string (uiout, fldno, width, align, fldname, string); 545 } 546 547 /* VARARGS */ 548 void 549 ui_out_field_fmt (struct ui_out *uiout, 550 const char *fldname, 551 const char *format, ...) 552 { 553 va_list args; 554 int fldno; 555 int width; 556 int align; 557 558 /* Will not align, but has to call anyway. */ 559 verify_field (uiout, &fldno, &width, &align); 560 561 va_start (args, format); 562 563 uo_field_fmt (uiout, fldno, width, align, fldname, format, args); 564 565 va_end (args); 566 } 567 568 void 569 ui_out_spaces (struct ui_out *uiout, int numspaces) 570 { 571 uo_spaces (uiout, numspaces); 572 } 573 574 void 575 ui_out_text (struct ui_out *uiout, 576 const char *string) 577 { 578 uo_text (uiout, string); 579 } 580 581 void 582 ui_out_message (struct ui_out *uiout, int verbosity, 583 const char *format,...) 584 { 585 va_list args; 586 587 va_start (args, format); 588 uo_message (uiout, verbosity, format, args); 589 va_end (args); 590 } 591 592 void 593 ui_out_wrap_hint (struct ui_out *uiout, char *identstring) 594 { 595 uo_wrap_hint (uiout, identstring); 596 } 597 598 void 599 ui_out_flush (struct ui_out *uiout) 600 { 601 uo_flush (uiout); 602 } 603 604 int 605 ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream) 606 { 607 return uo_redirect (uiout, outstream); 608 } 609 610 /* Set the flags specified by the mask given. */ 611 int 612 ui_out_set_flags (struct ui_out *uiout, int mask) 613 { 614 int oldflags = uiout->flags; 615 616 uiout->flags |= mask; 617 return oldflags; 618 } 619 620 /* Clear the flags specified by the mask given. */ 621 int 622 ui_out_clear_flags (struct ui_out *uiout, int mask) 623 { 624 int oldflags = uiout->flags; 625 626 uiout->flags &= ~mask; 627 return oldflags; 628 } 629 630 /* Test the flags against the mask given. */ 631 int 632 ui_out_test_flags (struct ui_out *uiout, int mask) 633 { 634 return (uiout->flags & mask); 635 } 636 637 /* Obtain the current verbosity level (as stablished by the 638 'set verbositylevel' command. */ 639 640 int 641 ui_out_get_verblvl (struct ui_out *uiout) 642 { 643 /* FIXME: not implemented yet. */ 644 return 0; 645 } 646 647 int 648 ui_out_is_mi_like_p (struct ui_out *uiout) 649 { 650 return uiout->impl->is_mi_like_p; 651 } 652 653 /* Default gdb-out hook functions. */ 654 655 static void 656 default_table_begin (struct ui_out *uiout, int nbrofcols, 657 int nr_rows, 658 const char *tblid) 659 { 660 } 661 662 static void 663 default_table_body (struct ui_out *uiout) 664 { 665 } 666 667 static void 668 default_table_end (struct ui_out *uiout) 669 { 670 } 671 672 static void 673 default_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 674 const char *col_name, 675 const char *colhdr) 676 { 677 } 678 679 static void 680 default_begin (struct ui_out *uiout, 681 enum ui_out_type type, 682 int level, 683 const char *id) 684 { 685 } 686 687 static void 688 default_end (struct ui_out *uiout, 689 enum ui_out_type type, 690 int level) 691 { 692 } 693 694 static void 695 default_field_int (struct ui_out *uiout, int fldno, int width, 696 enum ui_align align, 697 const char *fldname, int value) 698 { 699 } 700 701 static void 702 default_field_skip (struct ui_out *uiout, int fldno, int width, 703 enum ui_align align, const char *fldname) 704 { 705 } 706 707 static void 708 default_field_string (struct ui_out *uiout, 709 int fldno, 710 int width, 711 enum ui_align align, 712 const char *fldname, 713 const char *string) 714 { 715 } 716 717 static void 718 default_field_fmt (struct ui_out *uiout, int fldno, int width, 719 enum ui_align align, 720 const char *fldname, 721 const char *format, 722 va_list args) 723 { 724 } 725 726 static void 727 default_spaces (struct ui_out *uiout, int numspaces) 728 { 729 } 730 731 static void 732 default_text (struct ui_out *uiout, const char *string) 733 { 734 } 735 736 static void 737 default_message (struct ui_out *uiout, int verbosity, 738 const char *format, 739 va_list args) 740 { 741 } 742 743 static void 744 default_wrap_hint (struct ui_out *uiout, char *identstring) 745 { 746 } 747 748 static void 749 default_flush (struct ui_out *uiout) 750 { 751 } 752 753 static void 754 default_data_destroy (struct ui_out *uiout) 755 { 756 } 757 758 /* Interface to the implementation functions. */ 759 760 void 761 uo_table_begin (struct ui_out *uiout, int nbrofcols, 762 int nr_rows, 763 const char *tblid) 764 { 765 if (!uiout->impl->table_begin) 766 return; 767 uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid); 768 } 769 770 void 771 uo_table_body (struct ui_out *uiout) 772 { 773 if (!uiout->impl->table_body) 774 return; 775 uiout->impl->table_body (uiout); 776 } 777 778 void 779 uo_table_end (struct ui_out *uiout) 780 { 781 if (!uiout->impl->table_end) 782 return; 783 uiout->impl->table_end (uiout); 784 } 785 786 void 787 uo_table_header (struct ui_out *uiout, int width, enum ui_align align, 788 const char *col_name, 789 const char *colhdr) 790 { 791 if (!uiout->impl->table_header) 792 return; 793 uiout->impl->table_header (uiout, width, align, col_name, colhdr); 794 } 795 796 /* Clear the table associated with UIOUT. */ 797 798 static void 799 clear_table (struct ui_out *uiout) 800 { 801 if (uiout->table.id) 802 xfree (uiout->table.id); 803 clear_header_list (uiout); 804 } 805 806 void 807 uo_begin (struct ui_out *uiout, 808 enum ui_out_type type, 809 int level, 810 const char *id) 811 { 812 if (uiout->impl->begin == NULL) 813 return; 814 uiout->impl->begin (uiout, type, level, id); 815 } 816 817 void 818 uo_end (struct ui_out *uiout, 819 enum ui_out_type type, 820 int level) 821 { 822 if (uiout->impl->end == NULL) 823 return; 824 uiout->impl->end (uiout, type, level); 825 } 826 827 void 828 uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align, 829 const char *fldname, 830 int value) 831 { 832 if (!uiout->impl->field_int) 833 return; 834 uiout->impl->field_int (uiout, fldno, width, align, fldname, value); 835 } 836 837 void 838 uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align, 839 const char *fldname) 840 { 841 if (!uiout->impl->field_skip) 842 return; 843 uiout->impl->field_skip (uiout, fldno, width, align, fldname); 844 } 845 846 void 847 uo_field_string (struct ui_out *uiout, int fldno, int width, 848 enum ui_align align, 849 const char *fldname, 850 const char *string) 851 { 852 if (!uiout->impl->field_string) 853 return; 854 uiout->impl->field_string (uiout, fldno, width, align, fldname, string); 855 } 856 857 void 858 uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align, 859 const char *fldname, 860 const char *format, 861 va_list args) 862 { 863 if (!uiout->impl->field_fmt) 864 return; 865 uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args); 866 } 867 868 void 869 uo_spaces (struct ui_out *uiout, int numspaces) 870 { 871 if (!uiout->impl->spaces) 872 return; 873 uiout->impl->spaces (uiout, numspaces); 874 } 875 876 void 877 uo_text (struct ui_out *uiout, 878 const char *string) 879 { 880 if (!uiout->impl->text) 881 return; 882 uiout->impl->text (uiout, string); 883 } 884 885 void 886 uo_message (struct ui_out *uiout, int verbosity, 887 const char *format, 888 va_list args) 889 { 890 if (!uiout->impl->message) 891 return; 892 uiout->impl->message (uiout, verbosity, format, args); 893 } 894 895 void 896 uo_wrap_hint (struct ui_out *uiout, char *identstring) 897 { 898 if (!uiout->impl->wrap_hint) 899 return; 900 uiout->impl->wrap_hint (uiout, identstring); 901 } 902 903 void 904 uo_flush (struct ui_out *uiout) 905 { 906 if (!uiout->impl->flush) 907 return; 908 uiout->impl->flush (uiout); 909 } 910 911 int 912 uo_redirect (struct ui_out *uiout, struct ui_file *outstream) 913 { 914 if (!uiout->impl->redirect) 915 return -1; 916 uiout->impl->redirect (uiout, outstream); 917 return 0; 918 } 919 920 void 921 uo_data_destroy (struct ui_out *uiout) 922 { 923 if (!uiout->impl->data_destroy) 924 return; 925 926 uiout->impl->data_destroy (uiout); 927 } 928 929 /* local functions */ 930 931 /* List of column headers manipulation routines. */ 932 933 static void 934 clear_header_list (struct ui_out *uiout) 935 { 936 while (uiout->table.header_first != NULL) 937 { 938 uiout->table.header_next = uiout->table.header_first; 939 uiout->table.header_first = uiout->table.header_first->next; 940 xfree (uiout->table.header_next->colhdr); 941 xfree (uiout->table.header_next->col_name); 942 xfree (uiout->table.header_next); 943 } 944 gdb_assert (uiout->table.header_first == NULL); 945 uiout->table.header_last = NULL; 946 uiout->table.header_next = NULL; 947 } 948 949 static void 950 append_header_to_list (struct ui_out *uiout, 951 int width, 952 int alignment, 953 const char *col_name, 954 const char *colhdr) 955 { 956 struct ui_out_hdr *temphdr; 957 958 temphdr = XMALLOC (struct ui_out_hdr); 959 temphdr->width = width; 960 temphdr->alignment = alignment; 961 /* We have to copy the column title as the original may be an 962 automatic. */ 963 if (colhdr != NULL) 964 temphdr->colhdr = xstrdup (colhdr); 965 else 966 temphdr->colhdr = NULL; 967 968 if (col_name != NULL) 969 temphdr->col_name = xstrdup (col_name); 970 else if (colhdr != NULL) 971 temphdr->col_name = xstrdup (colhdr); 972 else 973 temphdr->col_name = NULL; 974 975 temphdr->next = NULL; 976 if (uiout->table.header_first == NULL) 977 { 978 temphdr->colno = 1; 979 uiout->table.header_first = temphdr; 980 uiout->table.header_last = temphdr; 981 } 982 else 983 { 984 temphdr->colno = uiout->table.header_last->colno + 1; 985 uiout->table.header_last->next = temphdr; 986 uiout->table.header_last = temphdr; 987 } 988 uiout->table.header_next = uiout->table.header_last; 989 } 990 991 /* Extract the format information for the NEXT header and advance 992 the header pointer. Return 0 if there was no next header. */ 993 994 static int 995 get_next_header (struct ui_out *uiout, 996 int *colno, 997 int *width, 998 int *alignment, 999 char **colhdr) 1000 { 1001 /* There may be no headers at all or we may have used all columns. */ 1002 if (uiout->table.header_next == NULL) 1003 return 0; 1004 *colno = uiout->table.header_next->colno; 1005 *width = uiout->table.header_next->width; 1006 *alignment = uiout->table.header_next->alignment; 1007 *colhdr = uiout->table.header_next->colhdr; 1008 /* Advance the header pointer to the next entry. */ 1009 uiout->table.header_next = uiout->table.header_next->next; 1010 return 1; 1011 } 1012 1013 1014 /* Verify that the field/tuple/list is correctly positioned. Return 1015 the field number and corresponding alignment (if 1016 available/applicable). */ 1017 1018 static void 1019 verify_field (struct ui_out *uiout, int *fldno, int *width, int *align) 1020 { 1021 struct ui_out_level *current = current_level (uiout); 1022 char *text; 1023 1024 if (uiout->table.flag) 1025 { 1026 if (!uiout->table.body_flag) 1027 internal_error (__FILE__, __LINE__, 1028 _("table_body missing; table fields must be \ 1029 specified after table_body and inside a list.")); 1030 /* NOTE: cagney/2001-12-08: There was a check here to ensure 1031 that this code was only executed when uiout->level was 1032 greater than zero. That no longer applies - this code is run 1033 before each table row tuple is started and at that point the 1034 level is zero. */ 1035 } 1036 1037 current->field_count += 1; 1038 1039 if (uiout->table.body_flag 1040 && uiout->table.entry_level == uiout->level 1041 && get_next_header (uiout, fldno, width, align, &text)) 1042 { 1043 if (*fldno != current->field_count) 1044 internal_error (__FILE__, __LINE__, 1045 _("ui-out internal error in handling headers.")); 1046 } 1047 else 1048 { 1049 *width = 0; 1050 *align = ui_noalign; 1051 *fldno = current->field_count; 1052 } 1053 } 1054 1055 1056 /* Access to ui-out members data. */ 1057 1058 void * 1059 ui_out_data (struct ui_out *uiout) 1060 { 1061 return uiout->data; 1062 } 1063 1064 /* Access table field parameters. */ 1065 int 1066 ui_out_query_field (struct ui_out *uiout, int colno, 1067 int *width, int *alignment, char **col_name) 1068 { 1069 struct ui_out_hdr *hdr; 1070 1071 if (!uiout->table.flag) 1072 return 0; 1073 1074 for (hdr = uiout->table.header_first; hdr; hdr = hdr->next) 1075 if (hdr->colno == colno) 1076 { 1077 *width = hdr->width; 1078 *alignment = hdr->alignment; 1079 *col_name = hdr->col_name; 1080 return 1; 1081 } 1082 1083 return 0; 1084 } 1085 1086 /* Initalize private members at startup. */ 1087 1088 struct ui_out * 1089 ui_out_new (struct ui_out_impl *impl, void *data, 1090 int flags) 1091 { 1092 struct ui_out *uiout = XMALLOC (struct ui_out); 1093 1094 uiout->data = data; 1095 uiout->impl = impl; 1096 uiout->flags = flags; 1097 uiout->table.flag = 0; 1098 uiout->table.body_flag = 0; 1099 uiout->level = 0; 1100 memset (uiout->levels, 0, sizeof (uiout->levels)); 1101 uiout->table.header_first = NULL; 1102 uiout->table.header_last = NULL; 1103 uiout->table.header_next = NULL; 1104 return uiout; 1105 } 1106 1107 /* Free UIOUT and the memory areas it references. */ 1108 1109 void 1110 ui_out_destroy (struct ui_out *uiout) 1111 { 1112 uo_data_destroy (uiout); 1113 clear_table (uiout); 1114 xfree (uiout); 1115 } 1116 1117 /* Standard gdb initialization hook. */ 1118 1119 void 1120 _initialize_ui_out (void) 1121 { 1122 /* nothing needs to be done */ 1123 } 1124