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