diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-06-29 02:15:52 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-06-29 02:16:56 +0300 |
commit | 23abfa7a31bf5dedd09cd0963da7dc4a291631eb (patch) | |
tree | f6b892f1b0c2932bacea14e6ff92529f2f8bbfd0 | |
parent | eb6e7c7cee0c998f5b403074201992c22383a553 (diff) | |
download | cflow-23abfa7a31bf5dedd09cd0963da7dc4a291631eb.tar.gz cflow-23abfa7a31bf5dedd09cd0963da7dc4a291631eb.tar.bz2 |
Use doubly-linked lists to keep statics and autos.
* src/Makefile.am (cflow_SOURCES): Order sources.
* src/cflow.h (struct linked_list_entry): Add new member: list.
(struct symbol): New members: owner, entry
(install_ident, ident_change_storage): New prototypes.
(linked_list_iterate, linked_list_unlink)
(data_in_list): New prototypes.
* src/linked-list.c (linked_list_append)
(linked_list_iterate): Update for doubly-linked lists.
(linked_list_unlink): New function.
(linked_list_prepend): Comment out: not used this far.
* src/parser.c: Use install_ident and ident_change_storage.
* src/symbol.c: Keep information about automatic
variables/parameters (on a per-function basis) and static
identifiers (on a per-module basis) in two separate linked
lists. This speeds up cleanup procedures.
-rw-r--r-- | src/Makefile.am | 15 | ||||
-rw-r--r-- | src/cflow.h | 15 | ||||
-rw-r--r-- | src/linked-list.c | 148 | ||||
-rw-r--r-- | src/parser.c | 44 | ||||
-rw-r--r-- | src/symbol.c | 312 |
5 files changed, 329 insertions, 205 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2ca13e5..7252ff8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -22,16 +22,17 @@ INCLUDES = -I$(top_srcdir)/lib -I../ -I../lib | |||
22 | 22 | ||
23 | bin_PROGRAMS = cflow | 23 | bin_PROGRAMS = cflow |
24 | cflow_SOURCES = \ | 24 | cflow_SOURCES = \ |
25 | main.c\ | ||
26 | rc.c\ | ||
27 | parser.c\ | ||
28 | c.l\ | 25 | c.l\ |
29 | output.c\ | ||
30 | symbol.c\ | ||
31 | cflow.h\ | 26 | cflow.h\ |
32 | parser.h\ | ||
33 | gnu.c\ | 27 | gnu.c\ |
34 | posix.c | 28 | linked-list.c\ |
29 | main.c\ | ||
30 | output.c\ | ||
31 | parser.c\ | ||
32 | parser.h\ | ||
33 | posix.c\ | ||
34 | rc.c\ | ||
35 | symbol.c | ||
35 | 36 | ||
36 | localedir = $(datadir)/locale | 37 | localedir = $(datadir)/locale |
37 | 38 | ||
diff --git a/src/cflow.h b/src/cflow.h index c6712c9..d933750 100644 --- a/src/cflow.h +++ b/src/cflow.h | |||
@@ -46,7 +46,8 @@ | |||
46 | #define NUMITEMS(a) sizeof(a)/sizeof((a)[0]) | 46 | #define NUMITEMS(a) sizeof(a)/sizeof((a)[0]) |
47 | 47 | ||
48 | struct linked_list_entry { | 48 | struct linked_list_entry { |
49 | struct linked_list_entry *next; | 49 | struct linked_list_entry *next, *prev; |
50 | struct linked_list *list; | ||
50 | void *data; | 51 | void *data; |
51 | }; | 52 | }; |
52 | 53 | ||
@@ -88,7 +89,10 @@ enum symbol_flag { | |||
88 | typedef struct symbol Symbol; | 89 | typedef struct symbol Symbol; |
89 | 90 | ||
90 | struct symbol { | 91 | struct symbol { |
92 | struct table_entry *owner; | ||
91 | Symbol *next; /* Next symbol with the same hash */ | 93 | Symbol *next; /* Next symbol with the same hash */ |
94 | struct linked_list_entry *entry; | ||
95 | |||
92 | enum symtype type; /* Type of the symbol */ | 96 | enum symtype type; /* Type of the symbol */ |
93 | char *name; /* Identifier */ | 97 | char *name; /* Identifier */ |
94 | enum symbol_flag flag; /* Specific flag */ | 98 | enum symbol_flag flag; /* Specific flag */ |
@@ -162,6 +166,8 @@ extern unsigned input_file_count; | |||
162 | 166 | ||
163 | Symbol *lookup(char*); | 167 | Symbol *lookup(char*); |
164 | Symbol *install(char*); | 168 | Symbol *install(char*); |
169 | Symbol *install_ident(char *name, enum storage storage); | ||
170 | void ident_change_storage(Symbol *sp, enum storage storage); | ||
165 | void delete_autos(int level); | 171 | void delete_autos(int level); |
166 | void delete_statics(void); | 172 | void delete_statics(void); |
167 | void delete_parms(int level); | 173 | void delete_parms(int level); |
@@ -171,7 +177,12 @@ struct linked_list *linked_list_create(linked_list_free_data_fp fun); | |||
171 | void linked_list_destroy(struct linked_list **plist); | 177 | void linked_list_destroy(struct linked_list **plist); |
172 | void linked_list_append(struct linked_list **plist, void *data); | 178 | void linked_list_append(struct linked_list **plist, void *data); |
173 | void linked_list_prepend(struct linked_list **plist, void *data); | 179 | void linked_list_prepend(struct linked_list **plist, void *data); |
174 | int symbol_in_list(Symbol *sym, struct linked_list *list); | 180 | void linked_list_iterate(struct linked_list **plist, |
181 | int (*itr) (void *, void *), void *data); | ||
182 | void linked_list_unlink(struct linked_list *list, | ||
183 | struct linked_list_entry *ent); | ||
184 | |||
185 | int data_in_list(void *data, struct linked_list *list); | ||
175 | 186 | ||
176 | int get_token(void); | 187 | int get_token(void); |
177 | int source(char *name); | 188 | int source(char *name); |
diff --git a/src/linked-list.c b/src/linked-list.c new file mode 100644 index 0000000..b7266ad --- /dev/null +++ b/src/linked-list.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* This file is part of GNU cflow | ||
2 | Copyright (C) 1997, 2005, 2006, 2007, 2009 Sergey Poznyakoff | ||
3 | |||
4 | GNU cflow is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | GNU cflow is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public | ||
15 | License along with GNU cflow; if not, write to the Free Software | ||
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | MA 02110-1301 USA */ | ||
18 | |||
19 | #include <cflow.h> | ||
20 | |||
21 | static struct linked_list * | ||
22 | deref_linked_list (struct linked_list **plist) | ||
23 | { | ||
24 | if (!*plist) { | ||
25 | struct linked_list *list = xmalloc(sizeof(*list)); | ||
26 | list->free_data = NULL; | ||
27 | list->head = list->tail = NULL; | ||
28 | *plist = list; | ||
29 | } | ||
30 | return *plist; | ||
31 | } | ||
32 | |||
33 | |||
34 | struct linked_list * | ||
35 | linked_list_create(linked_list_free_data_fp fun) | ||
36 | { | ||
37 | struct linked_list *list = xmalloc(sizeof(*list)); | ||
38 | list->free_data = fun; | ||
39 | list->head = list->tail = NULL; | ||
40 | return list; | ||
41 | } | ||
42 | |||
43 | void | ||
44 | linked_list_append(struct linked_list **plist, void *data) | ||
45 | { | ||
46 | struct linked_list *list = deref_linked_list (plist); | ||
47 | struct linked_list_entry *entry = xmalloc(sizeof(*entry)); | ||
48 | |||
49 | entry->list = list; | ||
50 | entry->data = data; | ||
51 | entry->next = NULL; | ||
52 | entry->prev = list->tail; | ||
53 | if (list->tail) | ||
54 | list->tail->next = entry; | ||
55 | else | ||
56 | list->head = entry; | ||
57 | list->tail = entry; | ||
58 | } | ||
59 | |||
60 | #if 0 | ||
61 | void | ||
62 | linked_list_prepend(struct linked_list **plist, void *data) | ||
63 | { | ||
64 | struct linked_list *list = deref_linked_list (plist); | ||
65 | struct linked_list_entry *entry = xmalloc(sizeof(*entry)); | ||
66 | |||
67 | entry->list = list; | ||
68 | entry->data = data; | ||
69 | if (list->head) | ||
70 | list->head->prev = entry; | ||
71 | entry->next = list->head; | ||
72 | entry->prev = NULL; | ||
73 | list->head = entry; | ||
74 | if (!list->tail) | ||
75 | list->tail = entry; | ||
76 | } | ||
77 | #endif | ||
78 | |||
79 | void | ||
80 | linked_list_destroy(struct linked_list **plist) | ||
81 | { | ||
82 | if (plist && *plist) { | ||
83 | struct linked_list *list = *plist; | ||
84 | struct linked_list_entry *p; | ||
85 | |||
86 | for (p = list->head; p; ) { | ||
87 | struct linked_list_entry *next = p->next; | ||
88 | if (list->free_data) | ||
89 | list->free_data(p->data); | ||
90 | free(p); | ||
91 | p = next; | ||
92 | } | ||
93 | free(list); | ||
94 | *plist = NULL; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | void | ||
99 | linked_list_unlink(struct linked_list *list, struct linked_list_entry *ent) | ||
100 | { | ||
101 | struct linked_list_entry *p; | ||
102 | |||
103 | if (p = ent->prev) | ||
104 | p->next = ent->next; | ||
105 | else | ||
106 | list->head = ent->next; | ||
107 | |||
108 | if (p = ent->next) | ||
109 | p->prev = ent->prev; | ||
110 | else | ||
111 | list->tail = ent->prev; | ||
112 | if (list->free_data) | ||
113 | list->free_data(ent->data); | ||
114 | free(ent); | ||
115 | } | ||
116 | |||
117 | void | ||
118 | linked_list_iterate(struct linked_list **plist, | ||
119 | int (*itr) (void *, void *), void *data) | ||
120 | { | ||
121 | struct linked_list *list; | ||
122 | struct linked_list_entry *p; | ||
123 | |||
124 | if (!*plist) | ||
125 | return; | ||
126 | list = *plist; | ||
127 | for (p = linked_list_head(list); p; ) { | ||
128 | struct linked_list_entry *next = p->next; | ||
129 | |||
130 | if (itr(p->data, data)) | ||
131 | linked_list_unlink(list, p); | ||
132 | p = next; | ||
133 | } | ||
134 | if (!list->head) | ||
135 | linked_list_destroy(&list); | ||
136 | *plist = list; | ||
137 | } | ||
138 | |||
139 | int | ||
140 | data_in_list(void *data, struct linked_list *list) | ||
141 | { | ||
142 | struct linked_list_entry *p; | ||
143 | |||
144 | for (p = linked_list_head(list); p; p = p->next) | ||
145 | if (p->data == data) | ||
146 | return 1; | ||
147 | return 0; | ||
148 | } | ||
diff --git a/src/parser.c b/src/parser.c index 26ac25d..c918b43 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -43,7 +43,6 @@ int parmdcl(Ident*); | |||
43 | int dirdcl(Ident*); | 43 | int dirdcl(Ident*); |