171
|
1 /* gc.c -- Functions to remember and garbage collect unused node contents. */ |
|
2 |
|
3 /* This file is part of GNU Info, a program for reading online documentation |
|
4 stored in Info format. |
|
5 |
|
6 Copyright (C) 1993 Free Software Foundation, Inc. |
|
7 |
|
8 This program is free software; you can redistribute it and/or modify |
|
9 it under the terms of the GNU General Public License as published by |
|
10 the Free Software Foundation; either version 2, or (at your option) |
|
11 any later version. |
|
12 |
|
13 This program is distributed in the hope that it will be useful, |
|
14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 GNU General Public License for more details. |
|
17 |
|
18 You should have received a copy of the GNU General Public License |
|
19 along with this program; if not, write to the Free Software |
|
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
21 |
|
22 Written by Brian Fox (bfox@ai.mit.edu). */ |
|
23 |
|
24 #include "info.h" |
|
25 |
|
26 /* Array of pointers to the contents of gc-able nodes. A pointer on this |
|
27 list can be garbage collected when no info window contains a node whose |
|
28 contents member match the pointer. */ |
|
29 static char **gcable_pointers = (char **)NULL; |
|
30 static int gcable_pointers_index = 0; |
|
31 static int gcable_pointers_slots = 0; |
|
32 |
|
33 /* Add POINTER to the list of garbage collectible pointers. A pointer |
|
34 is not actually garbage collected until no info window contains a node |
|
35 whose contents member is equal to the pointer. */ |
|
36 void |
|
37 add_gcable_pointer (pointer) |
|
38 char *pointer; |
|
39 { |
|
40 gc_pointers (); |
|
41 add_pointer_to_array (pointer, gcable_pointers_index, gcable_pointers, |
|
42 gcable_pointers_slots, 10, char *); |
|
43 } |
|
44 |
|
45 /* Grovel the list of info windows and gc-able pointers finding those |
|
46 node->contents which are collectible, and free them. */ |
|
47 void |
|
48 gc_pointers () |
|
49 { |
|
50 register int i, j, k; |
|
51 INFO_WINDOW *iw; |
|
52 char **new = (char **)NULL; |
|
53 int new_index = 0; |
|
54 int new_slots = 0; |
|
55 |
|
56 if (!info_windows || !gcable_pointers_index) |
|
57 return; |
|
58 |
|
59 for (i = 0; iw = info_windows[i]; i++) |
|
60 { |
|
61 for (j = 0; j < iw->nodes_index; j++) |
|
62 { |
|
63 NODE *node = iw->nodes[j]; |
|
64 |
|
65 /* If this node->contents appears in our list of gcable_pointers, |
|
66 it is not gc-able, so save it. */ |
|
67 for (k = 0; k < gcable_pointers_index; k++) |
|
68 if (gcable_pointers[k] == node->contents) |
|
69 { |
|
70 add_pointer_to_array |
|
71 (node->contents, new_index, new, new_slots, 10, char *); |
|
72 break; |
|
73 } |
|
74 } |
|
75 } |
|
76 |
|
77 /* We have gathered all of the pointers which need to be saved. Free any |
|
78 of the original pointers which do not appear in the new list. */ |
|
79 for (i = 0; i < gcable_pointers_index; i++) |
|
80 { |
|
81 for (j = 0; j < new_index; j++) |
|
82 if (gcable_pointers[i] == new[j]) |
|
83 break; |
|
84 |
|
85 /* If we got all the way through the new list, then the old pointer |
|
86 can be garbage collected. */ |
|
87 if (new && !new[j]) |
|
88 free (gcable_pointers[i]); |
|
89 } |
|
90 |
|
91 free (gcable_pointers); |
|
92 gcable_pointers = new; |
|
93 gcable_pointers_slots = new_slots; |
|
94 gcable_pointers_index = new_index; |
|
95 } |