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