aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-06-29 02:15:52 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-06-29 02:16:56 +0300
commit23abfa7a31bf5dedd09cd0963da7dc4a291631eb (patch)
treef6b892f1b0c2932bacea14e6ff92529f2f8bbfd0
parenteb6e7c7cee0c998f5b403074201992c22383a553 (diff)
downloadcflow-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.am15
-rw-r--r--src/cflow.h15
-rw-r--r--src/linked-list.c148
-rw-r--r--src/parser.c44
-rw-r--r--src/symbol.c312
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
23bin_PROGRAMS = cflow 23bin_PROGRAMS = cflow
24cflow_SOURCES = \ 24cflow_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
36localedir = $(datadir)/locale 37localedir = $(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
48struct linked_list_entry { 48struct 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 {
88typedef struct symbol Symbol; 89typedef struct symbol Symbol;
89 90
90struct symbol { 91struct 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
163Symbol *lookup(char*); 167Symbol *lookup(char*);
164Symbol *install(char*); 168Symbol *install(char*);
169Symbol *install_ident(char *name, enum storage storage);
170void ident_change_storage(Symbol *sp, enum storage storage);
165void delete_autos(int level); 171void delete_autos(int level);
166void delete_statics(void); 172void delete_statics(void);
167void delete_parms(int level); 173void delete_parms(int level);
@@ -171,7 +177,12 @@ struct linked_list *linked_list_create(linked_list_free_data_fp fun);
171void linked_list_destroy(struct linked_list **plist); 177void linked_list_destroy(struct linked_list **plist);
172void linked_list_append(struct linked_list **plist, void *data); 178void linked_list_append(struct linked_list **plist, void *data);
173void linked_list_prepend(struct linked_list **plist, void *data); 179void linked_list_prepend(struct linked_list **plist, void *data);
174int symbol_in_list(Symbol *sym, struct linked_list *list); 180void linked_list_iterate(struct linked_list **plist,
181 int (*itr) (void *, void *), void *data);
182void linked_list_unlink(struct linked_list *list,
183 struct linked_list_entry *ent);
184
185int data_in_list(void *data, struct linked_list *list);
175 186
176int get_token(void); 187int get_token(void);
177int source(char *name); 188int 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
21static struct linked_list *
22deref_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
34struct linked_list *
35linked_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
43void
44linked_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
61void
62linked_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
79void
80linked_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
98void
99linked_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
117void
118linked_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
139int
140data_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*);
43int dirdcl(Ident*); 43int dirdcl(Ident*);