1139749Simp/*	$NetBSD: gc.c,v 1.1.1.1 2016/01/14 00:11:29 christos Exp $	*/
253553Stanimura
353553Stanimura/* gc.c -- Functions to remember and garbage collect unused node contents.
453553Stanimura   Id: gc.c,v 1.3 2004/04/11 17:56:45 karl Exp
554377Stanimura
654377Stanimura   Copyright (C) 1993, 2004 Free Software Foundation, Inc.
754377Stanimura
854377Stanimura   This program is free software; you can redistribute it and/or modify
953553Stanimura   it under the terms of the GNU General Public License as published by
1053553Stanimura   the Free Software Foundation; either version 2, or (at your option)
1153553Stanimura   any later version.
1253553Stanimura
1353553Stanimura   This program is distributed in the hope that it will be useful,
1453553Stanimura   but WITHOUT ANY WARRANTY; without even the implied warranty of
1553553Stanimura   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1653553Stanimura   GNU General Public License for more details.
1753553Stanimura
1853553Stanimura   You should have received a copy of the GNU General Public License
1953553Stanimura   along with this program; if not, write to the Free Software
2053553Stanimura   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2153553Stanimura
2253553Stanimura   Written by Brian Fox (bfox@ai.mit.edu). */
2353553Stanimura
2453553Stanimura#include "info.h"
2553553Stanimura
2653553Stanimura/* Array of pointers to the contents of gc-able nodes.  A pointer on this
2753553Stanimura   list can be garbage collected when no info window contains a node whose
2853553Stanimura   contents member match the pointer. */
2953553Stanimurastatic char **gcable_pointers = (char **)NULL;
3053553Stanimurastatic int gcable_pointers_index = 0;
31193640Sariffstatic int gcable_pointers_slots = 0;
32193640Sariff
33193640Sariff/* Add POINTER to the list of garbage collectible pointers.  A pointer
34193640Sariff   is not actually garbage collected until no info window contains a node
3553553Stanimura   whose contents member is equal to the pointer. */
3653553Stanimuravoid
3753553Stanimuraadd_gcable_pointer (char *pointer)
3853553Stanimura{
3953553Stanimura  gc_pointers ();
4053553Stanimura  add_pointer_to_array (pointer, gcable_pointers_index, gcable_pointers,
41119287Simp			gcable_pointers_slots, 10, char *);
42119287Simp}
4353553Stanimura
4482180Scg/* Grovel the list of info windows and gc-able pointers finding those
4582180Scg   node->contents which are collectible, and free them. */
4677504Scgvoid
4777504Scggc_pointers (void)
4877504Scg{
4977504Scg  register int i, j, k;
5077504Scg  INFO_WINDOW *iw;
5153553Stanimura  char **new = (char **)NULL;
5253553Stanimura  int new_index = 0;
5353553Stanimura  int new_slots = 0;
5453553Stanimura
5553553Stanimura  if (!info_windows || !gcable_pointers_index)
5674763Scg    return;
5774763Scg
5853553Stanimura  for (i = 0; (iw = info_windows[i]); i++)
5977504Scg    {
6055321Stanimura      for (j = 0; j < iw->nodes_index; j++)
6153553Stanimura	{
6253553Stanimura	  NODE *node = iw->nodes[j];
6353553Stanimura
6453553Stanimura	  /* If this node->contents appears in our list of gcable_pointers,
6553553Stanimura	     it is not gc-able, so save it. */
6653553Stanimura	  for (k = 0; k < gcable_pointers_index; k++)
6755320Stanimura	    if (gcable_pointers[k] == node->contents)
6877504Scg	      {
6953553Stanimura		add_pointer_to_array
7077504Scg		  (node->contents, new_index, new, new_slots, 10, char *);
7153553Stanimura		break;
7253553Stanimura	      }
7353553Stanimura	}
7453553Stanimura    }
7553553Stanimura
76147626Sglebius  /* We have gathered all of the pointers which need to be saved.  Free any
77147626Sglebius     of the original pointers which do not appear in the new list. */
78147626Sglebius  for (i = 0; i < gcable_pointers_index; i++)
7953553Stanimura    {
8053553Stanimura      for (j = 0; j < new_index; j++)
8153553Stanimura	if (gcable_pointers[i] == new[j])
8253553Stanimura	  break;
8353553Stanimura
8453553Stanimura      /* If we got all the way through the new list, then the old pointer
8553553Stanimura	 can be garbage collected. */
8653553Stanimura      if (new && !new[j])
8753553Stanimura	free (gcable_pointers[i]);
8853553Stanimura    }
8953553Stanimura
9053553Stanimura  free (gcable_pointers);
9153553Stanimura  gcable_pointers = new;
9253553Stanimura  gcable_pointers_slots = new_slots;
93147626Sglebius  gcable_pointers_index = new_index;
9453553Stanimura}
9553553Stanimura