1146515Sru/* gc.c -- Functions to remember and garbage collect unused node contents. 2146515Sru $Id: gc.c,v 1.3 2004/04/11 17:56:45 karl Exp $ 321495Sjmacd 4146515Sru Copyright (C) 1993, 2004 Free Software Foundation, Inc. 521495Sjmacd 621495Sjmacd This program is free software; you can redistribute it and/or modify 721495Sjmacd it under the terms of the GNU General Public License as published by 821495Sjmacd the Free Software Foundation; either version 2, or (at your option) 921495Sjmacd any later version. 1021495Sjmacd 1121495Sjmacd This program is distributed in the hope that it will be useful, 1221495Sjmacd but WITHOUT ANY WARRANTY; without even the implied warranty of 1321495Sjmacd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1421495Sjmacd GNU General Public License for more details. 1521495Sjmacd 1621495Sjmacd You should have received a copy of the GNU General Public License 1721495Sjmacd along with this program; if not, write to the Free Software 1821495Sjmacd Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1921495Sjmacd 2021495Sjmacd Written by Brian Fox (bfox@ai.mit.edu). */ 2121495Sjmacd 2221495Sjmacd#include "info.h" 2321495Sjmacd 2421495Sjmacd/* Array of pointers to the contents of gc-able nodes. A pointer on this 2521495Sjmacd list can be garbage collected when no info window contains a node whose 2621495Sjmacd contents member match the pointer. */ 2721495Sjmacdstatic char **gcable_pointers = (char **)NULL; 2821495Sjmacdstatic int gcable_pointers_index = 0; 2921495Sjmacdstatic int gcable_pointers_slots = 0; 3021495Sjmacd 3121495Sjmacd/* Add POINTER to the list of garbage collectible pointers. A pointer 3221495Sjmacd is not actually garbage collected until no info window contains a node 3321495Sjmacd whose contents member is equal to the pointer. */ 3421495Sjmacdvoid 35146515Sruadd_gcable_pointer (char *pointer) 3621495Sjmacd{ 3721495Sjmacd gc_pointers (); 3821495Sjmacd add_pointer_to_array (pointer, gcable_pointers_index, gcable_pointers, 3921495Sjmacd gcable_pointers_slots, 10, char *); 4021495Sjmacd} 4121495Sjmacd 4221495Sjmacd/* Grovel the list of info windows and gc-able pointers finding those 4321495Sjmacd node->contents which are collectible, and free them. */ 4421495Sjmacdvoid 45146515Srugc_pointers (void) 4621495Sjmacd{ 4721495Sjmacd register int i, j, k; 4821495Sjmacd INFO_WINDOW *iw; 4921495Sjmacd char **new = (char **)NULL; 5021495Sjmacd int new_index = 0; 5121495Sjmacd int new_slots = 0; 5221495Sjmacd 5321495Sjmacd if (!info_windows || !gcable_pointers_index) 5421495Sjmacd return; 5521495Sjmacd 5642660Smarkm for (i = 0; (iw = info_windows[i]); i++) 5721495Sjmacd { 5821495Sjmacd for (j = 0; j < iw->nodes_index; j++) 5921495Sjmacd { 6021495Sjmacd NODE *node = iw->nodes[j]; 6121495Sjmacd 6221495Sjmacd /* If this node->contents appears in our list of gcable_pointers, 6321495Sjmacd it is not gc-able, so save it. */ 6421495Sjmacd for (k = 0; k < gcable_pointers_index; k++) 6521495Sjmacd if (gcable_pointers[k] == node->contents) 6621495Sjmacd { 6721495Sjmacd add_pointer_to_array 6821495Sjmacd (node->contents, new_index, new, new_slots, 10, char *); 6921495Sjmacd break; 7021495Sjmacd } 7121495Sjmacd } 7221495Sjmacd } 7321495Sjmacd 7421495Sjmacd /* We have gathered all of the pointers which need to be saved. Free any 7521495Sjmacd of the original pointers which do not appear in the new list. */ 7621495Sjmacd for (i = 0; i < gcable_pointers_index; i++) 7721495Sjmacd { 7821495Sjmacd for (j = 0; j < new_index; j++) 7921495Sjmacd if (gcable_pointers[i] == new[j]) 8021495Sjmacd break; 8121495Sjmacd 8221495Sjmacd /* If we got all the way through the new list, then the old pointer 8321495Sjmacd can be garbage collected. */ 8421495Sjmacd if (new && !new[j]) 8521495Sjmacd free (gcable_pointers[i]); 8621495Sjmacd } 8721495Sjmacd 8821495Sjmacd free (gcable_pointers); 8921495Sjmacd gcable_pointers = new; 9021495Sjmacd gcable_pointers_slots = new_slots; 9121495Sjmacd gcable_pointers_index = new_index; 9221495Sjmacd} 93