1 /* TUI data manipulation routines. 2 3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 4 2009, 2010 Free Software Foundation, Inc. 5 6 Contributed by Hewlett-Packard Company. 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 "symtab.h" 25 #include "tui/tui.h" 26 #include "tui/tui-data.h" 27 #include "tui/tui-wingeneral.h" 28 29 #include "gdb_string.h" 30 #include "gdb_curses.h" 31 32 /**************************** 33 ** GLOBAL DECLARATIONS 34 ****************************/ 35 struct tui_win_info *(tui_win_list[MAX_MAJOR_WINDOWS]); 36 37 /*************************** 38 ** Private data 39 ****************************/ 40 static enum tui_layout_type current_layout = UNDEFINED_LAYOUT; 41 static int term_height, term_width; 42 static struct tui_gen_win_info _locator; 43 static struct tui_gen_win_info exec_info[2]; 44 static struct tui_win_info *src_win_list[2]; 45 static struct tui_list source_windows = {src_win_list, 0}; 46 static int default_tab_len = DEFAULT_TAB_LEN; 47 static struct tui_win_info *win_with_focus = (struct tui_win_info *) NULL; 48 static struct tui_layout_def layout_def = { 49 SRC_WIN, /* DISPLAY_MODE */ 50 FALSE, /* SPLIT */ 51 TUI_UNDEFINED_REGS, /* REGS_DISPLAY_TYPE */ 52 TUI_SFLOAT_REGS}; /* FLOAT_REGS_DISPLAY_TYPE */ 53 54 static int win_resized = FALSE; 55 56 57 /********************************* 58 ** Static function forward decls 59 **********************************/ 60 static void free_content (tui_win_content, 61 int, 62 enum tui_win_type); 63 static void free_content_elements (tui_win_content, 64 int, 65 enum tui_win_type); 66 67 68 69 /********************************* 70 ** PUBLIC FUNCTIONS 71 **********************************/ 72 73 int 74 tui_win_is_source_type (enum tui_win_type win_type) 75 { 76 return (win_type == SRC_WIN || win_type == DISASSEM_WIN); 77 } 78 79 int 80 tui_win_is_auxillary (enum tui_win_type win_type) 81 { 82 return (win_type > MAX_MAJOR_WINDOWS); 83 } 84 85 int 86 tui_win_has_locator (struct tui_win_info *win_info) 87 { 88 return (win_info != NULL 89 && win_info->detail.source_info.has_locator); 90 } 91 92 void 93 tui_set_win_highlight (struct tui_win_info *win_info, 94 int highlight) 95 { 96 if (win_info != NULL) 97 win_info->is_highlighted = highlight; 98 } 99 100 /****************************************** 101 ** ACCESSORS & MUTATORS FOR PRIVATE DATA 102 ******************************************/ 103 104 /* Answer a whether the terminal window has been resized or not. */ 105 int 106 tui_win_resized (void) 107 { 108 return win_resized; 109 } 110 111 112 /* Set a whether the terminal window has been resized or not. */ 113 void 114 tui_set_win_resized_to (int resized) 115 { 116 win_resized = resized; 117 } 118 119 120 /* Answer a pointer to the current layout definition. */ 121 struct tui_layout_def * 122 tui_layout_def (void) 123 { 124 return &layout_def; 125 } 126 127 128 /* Answer the window with the logical focus. */ 129 struct tui_win_info * 130 tui_win_with_focus (void) 131 { 132 return win_with_focus; 133 } 134 135 136 /* Set the window that has the logical focus. */ 137 void 138 tui_set_win_with_focus (struct tui_win_info *win_info) 139 { 140 win_with_focus = win_info; 141 } 142 143 144 /* Answer the length in chars, of tabs. */ 145 int 146 tui_default_tab_len (void) 147 { 148 return default_tab_len; 149 } 150 151 152 /* Set the length in chars, of tabs. */ 153 void 154 tui_set_default_tab_len (int len) 155 { 156 default_tab_len = len; 157 } 158 159 160 /* Accessor for the current source window. Usually there is only one 161 source window (either source or disassembly), but both can be 162 displayed at the same time. */ 163 struct tui_list * 164 tui_source_windows (void) 165 { 166 return &source_windows; 167 } 168 169 170 /* Clear the list of source windows. Usually there is only one source 171 window (either source or disassembly), but both can be displayed at 172 the same time. */ 173 void 174 tui_clear_source_windows (void) 175 { 176 source_windows.list[0] = NULL; 177 source_windows.list[1] = NULL; 178 source_windows.count = 0; 179 } 180 181 182 /* Clear the pertinant detail in the source windows. */ 183 void 184 tui_clear_source_windows_detail (void) 185 { 186 int i; 187 188 for (i = 0; i < (tui_source_windows ())->count; i++) 189 tui_clear_win_detail ((tui_source_windows ())->list[i]); 190 } 191 192 193 /* Add a window to the list of source windows. Usually there is only 194 one source window (either source or disassembly), but both can be 195 displayed at the same time. */ 196 void 197 tui_add_to_source_windows (struct tui_win_info *win_info) 198 { 199 if (source_windows.count < 2) 200 source_windows.list[source_windows.count++] = (void *) win_info; 201 } 202 203 204 /* Clear the pertinant detail in the windows. */ 205 void 206 tui_clear_win_detail (struct tui_win_info *win_info) 207 { 208 if (win_info != NULL) 209 { 210 switch (win_info->generic.type) 211 { 212 case SRC_WIN: 213 case DISASSEM_WIN: 214 win_info->detail.source_info.gdbarch = NULL; 215 win_info->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS; 216 win_info->detail.source_info.start_line_or_addr.u.addr = 0; 217 win_info->detail.source_info.horizontal_offset = 0; 218 break; 219 case CMD_WIN: 220 win_info->detail.command_info.cur_line = 221 win_info->detail.command_info.curch = 0; 222 break; 223 case DATA_WIN: 224 win_info->detail.data_display_info.data_content = 225 (tui_win_content) NULL; 226 win_info->detail.data_display_info.data_content_count = 0; 227 win_info->detail.data_display_info.regs_content = 228 (tui_win_content) NULL; 229 win_info->detail.data_display_info.regs_content_count = 0; 230 win_info->detail.data_display_info.regs_display_type = 231 TUI_UNDEFINED_REGS; 232 win_info->detail.data_display_info.regs_column_count = 1; 233 win_info->detail.data_display_info.display_regs = FALSE; 234 break; 235 default: 236 break; 237 } 238 } 239 } 240 241 242 /* Accessor for the source execution info ptr. */ 243 struct tui_gen_win_info * 244 tui_source_exec_info_win_ptr (void) 245 { 246 return &exec_info[0]; 247 } 248 249 250 /* Accessor for the disassem execution info ptr. */ 251 struct tui_gen_win_info * 252 tui_disassem_exec_info_win_ptr (void) 253 { 254 return &exec_info[1]; 255 } 256 257 258 /* Accessor for the locator win info. Answers a pointer to the static 259 locator win info struct. */ 260 struct tui_gen_win_info * 261 tui_locator_win_info_ptr (void) 262 { 263 return &_locator; 264 } 265 266 267 /* Accessor for the term_height. */ 268 int 269 tui_term_height (void) 270 { 271 return term_height; 272 } 273 274 275 /* Mutator for the term height. */ 276 void 277 tui_set_term_height_to (int h) 278 { 279 term_height = h; 280 } 281 282 283 /* Accessor for the term_width. */ 284 int 285 tui_term_width (void) 286 { 287 return term_width; 288 } 289 290 291 /* Mutator for the term_width. */ 292 void 293 tui_set_term_width_to (int w) 294 { 295 term_width = w; 296 } 297 298 299 /* Accessor for the current layout. */ 300 enum tui_layout_type 301 tui_current_layout (void) 302 { 303 return current_layout; 304 } 305 306 307 /* Mutator for the current layout. */ 308 void 309 tui_set_current_layout_to (enum tui_layout_type new_layout) 310 { 311 current_layout = new_layout; 312 } 313 314 315 /* Set the origin of the window. */ 316 void 317 set_gen_win_origin (struct tui_gen_win_info *win_info, 318 int x, int y) 319 { 320 win_info->origin.x = x; 321 win_info->origin.y = y; 322 } 323 324 325 /***************************** 326 ** OTHER PUBLIC FUNCTIONS 327 *****************************/ 328 329 330 /* Answer the next window in the list, cycling back to the top if 331 necessary. */ 332 struct tui_win_info * 333 tui_next_win (struct tui_win_info *cur_win) 334 { 335 enum tui_win_type type = cur_win->generic.type; 336 struct tui_win_info *next_win = (struct tui_win_info *) NULL; 337 338 if (cur_win->generic.type == CMD_WIN) 339 type = SRC_WIN; 340 else 341 type = cur_win->generic.type + 1; 342 while (type != cur_win->generic.type && (next_win == NULL)) 343 { 344 if (tui_win_list[type] 345 && tui_win_list[type]->generic.is_visible) 346 next_win = tui_win_list[type]; 347 else 348 { 349 if (type == CMD_WIN) 350 type = SRC_WIN; 351 else 352 type++; 353 } 354 } 355 356 return next_win; 357 } 358 359 360 /* Answer the prev window in the list, cycling back to the bottom if 361 necessary. */ 362 struct tui_win_info * 363 tui_prev_win (struct tui_win_info *cur_win) 364 { 365 enum tui_win_type type = cur_win->generic.type; 366 struct tui_win_info *prev = (struct tui_win_info *) NULL; 367 368 if (cur_win->generic.type == SRC_WIN) 369 type = CMD_WIN; 370 else 371 type = cur_win->generic.type - 1; 372 while (type != cur_win->generic.type && (prev == NULL)) 373 { 374 if (tui_win_list[type] 375 && tui_win_list[type]->generic.is_visible) 376 prev = tui_win_list[type]; 377 else 378 { 379 if (type == SRC_WIN) 380 type = CMD_WIN; 381 else 382 type--; 383 } 384 } 385 386 return prev; 387 } 388 389 390 /* Answer the window represented by name. */ 391 struct tui_win_info * 392 tui_partial_win_by_name (char *name) 393 { 394 struct tui_win_info *win_info = (struct tui_win_info *) NULL; 395 396 if (name != (char *) NULL) 397 { 398 int i = 0; 399 400 while (i < MAX_MAJOR_WINDOWS && win_info == NULL) 401 { 402 if (tui_win_list[i] != 0) 403 { 404 char *cur_name = tui_win_name (&tui_win_list[i]->generic); 405 406 if (strlen (name) <= strlen (cur_name) 407 && strncmp (name, cur_name, strlen (name)) == 0) 408 win_info = tui_win_list[i]; 409 } 410 i++; 411 } 412 } 413 414 return win_info; 415 } 416 417 418 /* Answer the name of the window. */ 419 char * 420 tui_win_name (struct tui_gen_win_info *win_info) 421 { 422 char *name = (char *) NULL; 423 424 switch (win_info->type) 425 { 426 case SRC_WIN: 427 name = SRC_NAME; 428 break; 429 case CMD_WIN: 430 name = CMD_NAME; 431 break; 432 case DISASSEM_WIN: 433 name = DISASSEM_NAME; 434 break; 435 case DATA_WIN: 436 name = DATA_NAME; 437 break; 438 default: 439 name = ""; 440 break; 441 } 442 443 return name; 444 } 445 446 447 void 448 tui_initialize_static_data (void) 449 { 450 tui_init_generic_part (tui_source_exec_info_win_ptr ()); 451 tui_init_generic_part (tui_disassem_exec_info_win_ptr ()); 452 tui_init_generic_part (tui_locator_win_info_ptr ()); 453 } 454 455 456 struct tui_gen_win_info * 457 tui_alloc_generic_win_info (void) 458 { 459 struct tui_gen_win_info *win; 460 461 if ((win = XMALLOC (struct tui_gen_win_info)) != NULL) 462 tui_init_generic_part (win); 463 464 return win; 465 } 466 467 468 void 469 tui_init_generic_part (struct tui_gen_win_info *win) 470 { 471 win->width = 472 win->height = 473 win->origin.x = 474 win->origin.y = 475 win->viewport_height = 476 win->content_size = 477 win->last_visible_line = 0; 478 win->handle = (WINDOW *) NULL; 479 win->content = NULL; 480 win->content_in_use = 481 win->is_visible = FALSE; 482 win->title = 0; 483 } 484 485 486 /* init_content_element(). 487 */ 488 static void 489 init_content_element (struct tui_win_element *element, 490 enum tui_win_type type) 491 { 492 element->highlight = FALSE; 493 switch (type) 494 { 495 case SRC_WIN: 496 case DISASSEM_WIN: 497 element->which_element.source.line = (char *) NULL; 498 element->which_element.source.line_or_addr.loa = LOA_LINE; 499 element->which_element.source.line_or_addr.u.line_no = 0; 500 element->which_element.source.is_exec_point = FALSE; 501 element->which_element.source.has_break = FALSE; 502 break; 503 case DATA_WIN: 504 tui_init_generic_part (&element->which_element.data_window); 505 element->which_element.data_window.type = DATA_ITEM_WIN; 506 ((struct tui_gen_win_info *) & element->which_element.data_window)->content = 507 (void **) tui_alloc_content (1, DATA_ITEM_WIN); 508 ((struct tui_gen_win_info *) 509 & element->which_element.data_window)->content_size = 1; 510 break; 511 case CMD_WIN: 512 element->which_element.command.line = (char *) NULL; 513 break; 514 case DATA_ITEM_WIN: 515 element->which_element.data.name = (char *) NULL; 516 element->which_element.data.type = TUI_REGISTER; 517 element->which_element.data.item_no = UNDEFINED_ITEM; 518 element->which_element.data.value = NULL; 519 element->which_element.data.highlight = FALSE; 520 element->which_element.data.content = (char*) NULL; 521 break; 522 case LOCATOR_WIN: 523 element->which_element.locator.file_name[0] = 524 element->which_element.locator.proc_name[0] = (char) 0; 525 element->which_element.locator.line_no = 0; 526 element->which_element.locator.addr = 0; 527 break; 528 case EXEC_INFO_WIN: 529 memset(element->which_element.simple_string, ' ', 530 sizeof(element->which_element.simple_string)); 531 break; 532 default: 533 break; 534 } 535 } 536 537 static void 538 init_win_info (struct tui_win_info *win_info) 539 { 540 tui_init_generic_part (&win_info->generic); 541 win_info->can_highlight = 542 win_info->is_highlighted = FALSE; 543 switch (win_info->generic.type) 544 { 545 case SRC_WIN: 546 case DISASSEM_WIN: 547 win_info->detail.source_info.execution_info = (struct tui_gen_win_info *) NULL; 548 win_info->detail.source_info.has_locator = FALSE; 549 win_info->detail.source_info.horizontal_offset = 0; 550 win_info->detail.source_info.gdbarch = NULL; 551 win_info->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS; 552 win_info->detail.source_info.start_line_or_addr.u.addr = 0; 553 win_info->detail.source_info.filename = 0; 554 break; 555 case DATA_WIN: 556 win_info->detail.data_display_info.data_content = (tui_win_content) NULL; 557 win_info->detail.data_display_info.data_content_count = 0; 558 win_info->detail.data_display_info.regs_content = (tui_win_content) NULL; 559 win_info->detail.data_display_info.regs_content_count = 0; 560 win_info->detail.data_display_info.regs_display_type = 561 TUI_UNDEFINED_REGS; 562 win_info->detail.data_display_info.regs_column_count = 1; 563 win_info->detail.data_display_info.display_regs = FALSE; 564 win_info->detail.data_display_info.current_group = 0; 565 break; 566 case CMD_WIN: 567 win_info->detail.command_info.cur_line = 0; 568 win_info->detail.command_info.curch = 0; 569 break; 570 default: 571 win_info->detail.opaque = NULL; 572 break; 573 } 574 } 575 576 577 struct tui_win_info * 578 tui_alloc_win_info (enum tui_win_type type) 579 { 580 struct tui_win_info *win_info; 581 582 win_info = XMALLOC (struct tui_win_info); 583 if (win_info != NULL) 584 { 585 win_info->generic.type = type; 586 init_win_info (win_info); 587 } 588 589 return win_info; 590 } 591 592 593 /* Allocates the content and elements in a block. */ 594 tui_win_content 595 tui_alloc_content (int num_elements, enum tui_win_type type) 596 { 597 tui_win_content content; 598 char *element_block_ptr; 599 int i; 600 601 content = xmalloc (sizeof (struct tui_win_element *) *num_elements); 602 if (content != NULL) 603 { 604 /* 605 * All windows, except the data window, can allocate the 606 * elements in a chunk. The data window cannot because items 607 * can be added/removed from the data display by the user at any 608 * time. 609 */ 610 if (type != DATA_WIN) 611 { 612 element_block_ptr = 613 xmalloc (sizeof (struct tui_win_element) * num_elements); 614 if (element_block_ptr != NULL) 615 { 616 for (i = 0; i < num_elements; i++) 617 { 618 content[i] = (struct tui_win_element *) element_block_ptr; 619 init_content_element (content[i], type); 620 element_block_ptr += sizeof (struct tui_win_element); 621 } 622 } 623 else 624 { 625 xfree (content); 626 content = (tui_win_content) NULL; 627 } 628 } 629 } 630 631 return content; 632 } 633 634 635 /* Adds the input number of elements to the windows's content. If no 636 content has been allocated yet, alloc_content() is called to do 637 this. The index of the first element added is returned, unless 638 there is a memory allocation error, in which case, (-1) is 639 returned. */ 640 int 641 tui_add_content_elements (struct tui_gen_win_info *win_info, 642 int num_elements) 643 { 644 struct tui_win_element *element_ptr; 645 int i, index_start; 646 647 if (win_info->content == NULL) 648 { 649 win_info->content = (void **) tui_alloc_content (num_elements, win_info->type); 650 index_start = 0; 651 } 652 else 653 index_start = win_info->content_size; 654 if (win_info->content != NULL) 655 { 656 for (i = index_start; (i < num_elements + index_start); i++) 657 { 658 if ((element_ptr = XMALLOC (struct tui_win_element)) != NULL) 659 { 660 win_info->content[i] = (void *) element_ptr; 661 init_content_element (element_ptr, win_info->type); 662 win_info->content_size++; 663 } 664 else /* Things must be really hosed now! We ran out of 665 memory!? */ 666 return (-1); 667 } 668 } 669 670 return index_start; 671 } 672 673 674 /* Delete all curses windows associated with win_info, leaving 675 everything else intact. */ 676 void 677 tui_del_window (struct tui_win_info *win_info) 678 { 679 struct tui_gen_win_info *generic_win; 680 681 switch (win_info->generic.type) 682 { 683 case SRC_WIN: 684 case DISASSEM_WIN: 685 generic_win = tui_locator_win_info_ptr (); 686 if (generic_win != (struct tui_gen_win_info *) NULL) 687 { 688 tui_delete_win (generic_win->handle); 689 generic_win->handle = (WINDOW *) NULL; 690 generic_win->is_visible = FALSE; 691 } 692 if (win_info->detail.source_info.filename) 693 { 694 xfree (win_info->detail.source_info.filename); 695 win_info->detail.source_info.filename = 0; 696 } 697 generic_win = win_info->detail.source_info.execution_info; 698 if (generic_win != (struct tui_gen_win_info *) NULL) 699 { 700 tui_delete_win (generic_win->handle); 701 generic_win->handle = (WINDOW *) NULL; 702 generic_win->is_visible = FALSE; 703 } 704 break; 705 case DATA_WIN: 706 if (win_info->generic.content != NULL) 707 { 708 tui_del_data_windows (win_info->detail.data_display_info.regs_content, 709 win_info->detail.data_display_info.regs_content_count); 710 tui_del_data_windows (win_info->detail.data_display_info.data_content, 711 win_info->detail.data_display_info.data_content_count); 712 } 713 break; 714 default: 715 break; 716 } 717 if (win_info->generic.handle != (WINDOW *) NULL) 718 { 719 tui_delete_win (win_info->generic.handle); 720 win_info->generic.handle = (WINDOW *) NULL; 721 win_info->generic.is_visible = FALSE; 722 } 723 } 724 725 726 void 727 tui_free_window (struct tui_win_info *win_info) 728 { 729 struct tui_gen_win_info *generic_win; 730 731 switch (win_info->generic.type) 732 { 733 case SRC_WIN: 734 case DISASSEM_WIN: 735 generic_win = tui_locator_win_info_ptr (); 736 if (generic_win != (struct tui_gen_win_info *) NULL) 737 { 738 tui_delete_win (generic_win->handle); 739 generic_win->handle = (WINDOW *) NULL; 740 } 741 tui_free_win_content (generic_win); 742 if (win_info->detail.source_info.filename) 743 { 744 xfree (win_info->detail.source_info.filename); 745 win_info->detail.source_info.filename = 0; 746 } 747 generic_win = win_info->detail.source_info.execution_info; 748 if (generic_win != (struct tui_gen_win_info *) NULL) 749 { 750 tui_delete_win (generic_win->handle); 751 generic_win->handle = (WINDOW *) NULL; 752 tui_free_win_content (generic_win); 753 } 754 break; 755 case DATA_WIN: 756 if (win_info->generic.content != NULL) 757 { 758 tui_free_data_content (win_info->detail.data_display_info.regs_content, 759 win_info->detail.data_display_info.regs_content_count); 760 win_info->detail.data_display_info.regs_content = 761 (tui_win_content) NULL; 762 win_info->detail.data_display_info.regs_content_count = 0; 763 tui_free_data_content (win_info->detail.data_display_info.data_content, 764 win_info->detail.data_display_info.data_content_count); 765 win_info->detail.data_display_info.data_content = 766 (tui_win_content) NULL; 767 win_info->detail.data_display_info.data_content_count = 0; 768 win_info->detail.data_display_info.regs_display_type = 769 TUI_UNDEFINED_REGS; 770 win_info->detail.data_display_info.regs_column_count = 1; 771 win_info->detail.data_display_info.display_regs = FALSE; 772 win_info->generic.content = NULL; 773 win_info->generic.content_size = 0; 774 } 775 break; 776 default: 777 break; 778 } 779 if (win_info->generic.handle != (WINDOW *) NULL) 780 { 781 tui_delete_win (win_info->generic.handle); 782 win_info->generic.handle = (WINDOW *) NULL; 783 tui_free_win_content (&win_info->generic); 784 } 785 if (win_info->generic.title) 786 xfree (win_info->generic.title); 787 xfree (win_info); 788 } 789 790 791 void 792 tui_free_all_source_wins_content (void) 793 { 794 int i; 795 796 for (i = 0; i < (tui_source_windows ())->count; i++) 797 { 798 struct tui_win_info *win_info = (tui_source_windows ())->list[i]; 799 800 if (win_info != NULL) 801 { 802 tui_free_win_content (&(win_info->generic)); 803 tui_free_win_content (win_info->detail.source_info.execution_info); 804 } 805 } 806 } 807 808 809 void 810 tui_free_win_content (struct tui_gen_win_info *win_info) 811 { 812 if (win_info->content != NULL) 813 { 814 free_content ((tui_win_content) win_info->content, 815 win_info->content_size, 816 win_info->type); 817 win_info->content = NULL; 818 } 819 win_info->content_size = 0; 820 } 821 822 823 void 824 tui_del_data_windows (tui_win_content content, 825 int content_size) 826 { 827 int i; 828 829 /* Remember that data window content elements are of type struct 830 tui_gen_win_info *, each of which whose single element is a data 831 element. */ 832 for (i = 0; i < content_size; i++) 833 { 834 struct tui_gen_win_info *generic_win = &content[i]->which_element.data_window; 835 836 if (generic_win != (struct tui_gen_win_info *) NULL) 837 { 838 tui_delete_win (generic_win->handle); 839 generic_win->handle = (WINDOW *) NULL; 840 generic_win->is_visible = FALSE; 841 } 842 } 843 } 844 845 846 void 847 tui_free_data_content (tui_win_content content, 848 int content_size) 849 { 850 int i; 851 852 /* Remember that data window content elements are of type struct 853 tui_gen_win_info *, each of which whose single element is a data 854 element. */ 855 for (i = 0; i < content_size; i++) 856 { 857 struct tui_gen_win_info *generic_win = &content[i]->which_element.data_window; 858 859 if (generic_win != (struct tui_gen_win_info *) NULL) 860 { 861 tui_delete_win (generic_win->handle); 862 generic_win->handle = (WINDOW *) NULL; 863 tui_free_win_content (generic_win); 864 } 865 } 866 free_content (content, 867 content_size, 868 DATA_WIN); 869 } 870 871 872 /********************************** 873 ** LOCAL STATIC FUNCTIONS ** 874 **********************************/ 875 876 877 static void 878 free_content (tui_win_content content, 879 int content_size, 880 enum tui_win_type win_type) 881 { 882 if (content != (tui_win_content) NULL) 883 { 884 free_content_elements (content, content_size, win_type); 885 xfree (content); 886 } 887 } 888 889 890 /* free_content_elements(). 891 */ 892 static void 893 free_content_elements (tui_win_content content, 894 int content_size, 895 enum tui_win_type type) 896 { 897 if (content != (tui_win_content) NULL) 898 { 899 int i; 900 901 if (type == SRC_WIN || type == DISASSEM_WIN) 902 { 903 /* Free whole source block. */ 904 xfree (content[0]->which_element.source.line); 905 } 906 else 907 { 908 for (i = 0; i < content_size; i++) 909 { 910 struct tui_win_element *element; 911 912 element = content[i]; 913 if (element != (struct tui_win_element *) NULL) 914 { 915 switch (type) 916 { 917 case DATA_WIN: 918 xfree (element); 919 break; 920 case DATA_ITEM_WIN: 921 /* Note that data elements are not allocated in 922 a single block, but individually, as 923 needed. */ 924 if (element->which_element.data.type != TUI_REGISTER) 925 xfree ((void *)element->which_element.data.name); 926 xfree (element->which_element.data.value); 927 xfree (element->which_element.data.content); 928 xfree (element); 929 break; 930 case CMD_WIN: 931 xfree (element->which_element.command.line); 932 break; 933 default: 934 break; 935 } 936 } 937 } 938 } 939 if (type != DATA_WIN && type != DATA_ITEM_WIN) 940 xfree (content[0]); /* Free the element block. */ 941 } 942 } 943