2002-11-21 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / sim / igen / filter.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3 Copyright 2002 Free Software Foundation, Inc.
4
5 Contributed by Andrew Cagney.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
23
24
25 #include <stdio.h>
26
27 #include "config.h"
28
29 #ifdef HAVE_STRING_H
30 #include <string.h>
31 #else
32 #ifdef HAVE_STRINGS_H
33 #include <strings.h>
34 #endif
35 #endif
36
37 #include "misc.h"
38 #include "lf.h"
39 #include "filter.h"
40
41 struct _filter {
42 char *member;
43 filter *next;
44 };
45
46
47 void
48 filter_parse (filter **filters,
49 const char *filt)
50 {
51 while (strlen (filt) > 0)
52 {
53 filter *new_filter;
54 filter **last;
55 /* break out a member of the filter list */
56 const char *flag = filt;
57 unsigned /*size_t*/ len;
58 filt = strchr (filt, ',');
59 if (filt == NULL)
60 {
61 filt = strchr (flag, '\0');
62 len = strlen (flag);
63 }
64 else
65 {
66 len = filt - flag;
67 filt = filt + 1;
68 }
69 /* find an insertion point - sorted order */
70 last = filters;
71 while (*last != NULL
72 && strncmp (flag, (*last)->member, len) > 0)
73 last = &(*last)->next;
74 if (*last != NULL
75 && strncmp (flag, (*last)->member, len) == 0
76 && strlen ((*last)->member) == len)
77 continue; /* duplicate */
78 /* create an entry for that member */
79 new_filter = ZALLOC (filter);
80 new_filter->member = NZALLOC (char, len + 1);
81 strncpy (new_filter->member, flag, len);
82 /* insert it */
83 new_filter->next = *last;
84 *last = new_filter;
85 }
86 }
87
88
89 void
90 filter_add (filter **set,
91 filter *add)
92 {
93 while (add != NULL)
94 {
95 int cmp;
96 if (*set == NULL)
97 cmp = 1; /* set->member > add->member */
98 else
99 cmp = strcmp ((*set)->member, add->member);
100 if (cmp > 0)
101 {
102 /* insert it here */
103 filter *new = ZALLOC (filter);
104 new->member = NZALLOC (char, strlen (add->member) + 1);
105 strcpy (new->member, add->member);
106 new->next = *set;
107 *set = new;
108 add = add->next;
109 }
110 else if (cmp == 0)
111 {
112 /* already in set */
113 add = add->next;
114 }
115 else /* cmp < 0 */
116 {
117 /* not reached insertion point */
118 set = &(*set)->next;
119 }
120 }
121 }
122
123
124 int
125 filter_is_subset (filter *superset,
126 filter *subset)
127 {
128 while (1)
129 {
130 int cmp;
131 if (subset == NULL)
132 return 1;
133 if (superset == NULL)
134 return 0; /* subset isn't finished */
135 cmp = strcmp (subset->member, superset->member);
136 if (cmp < 0)
137 return 0; /* not found */
138 else if (cmp == 0)
139 subset = subset->next; /* found */
140 else if (cmp > 0)
141 superset = superset->next; /* later in list? */
142 }
143 }
144
145
146 int
147 filter_is_common (filter *l,
148 filter *r)
149 {
150 while (1)
151 {
152 int cmp;
153 if (l == NULL)
154 return 0;
155 if (r == NULL)
156 return 0;
157 cmp = strcmp (l->member, r->member);
158 if (cmp < 0)
159 l = l->next;
160 else if (cmp == 0)
161 return 1; /* common member */
162 else if (cmp > 0)
163 r = r->next;
164 }
165 }
166
167
168 int
169 filter_is_member (filter *filt,
170 const char *flag)
171 {
172 int index = 1;
173 while (filt != NULL)
174 {
175 if (strcmp (flag, filt->member) == 0)
176 return index;
177 filt = filt->next;
178 index++;
179 }
180 return 0;
181 }
182
183
184 int
185 is_filtered_out (filter *filters,
186 const char *flags)
187 {
188 while (strlen(flags) > 0) {
189 int present;
190 filter *filt = filters;
191 /* break the string up */
192 char *end = strchr(flags, ',');
193 char *next;
194 unsigned /*size_t*/ len;
195 if (end == NULL) {
196 end = strchr(flags, '\0');
197 next = end;
198 }
199 else {
200 next = end + 1;
201 }
202 len = end - flags;
203 /* check that it is present */
204 present = 0;
205 filt = filters;
206 while (filt != NULL) {
207 if (strncmp(flags, filt->member, len) == 0
208 && strlen(filt->member) == len) {
209 present = 1;
210 break;
211 }
212 filt = filt->next;
213 }
214 if (!present)
215 return 1;
216 flags = next;
217 }
218 return 0;
219 }
220
221
222 #if 0
223 int
224 it_is (const char *flag,
225 const char *flags)
226 {
227 int flag_len = strlen(flag);
228 while (*flags != '\0') {
229 if (!strncmp(flags, flag, flag_len)
230 && (flags[flag_len] == ',' || flags[flag_len] == '\0'))
231 return 1;
232 while (*flags != ',') {
233 if (*flags == '\0')
234 return 0;
235 flags++;
236 }
237 flags++;
238 }
239 return 0;
240 }
241 #endif
242
243
244 char *
245 filter_next (filter *set,
246 char *member)
247 {
248 while (set != NULL)
249 {
250 if (strcmp (set->member, member) > 0)
251 return set->member;
252 set = set->next;
253 }
254 return NULL;
255 }
256
257
258 void
259 dump_filter (lf *file,
260 char *prefix,
261 filter *set,
262 char *suffix)
263 {
264 char *member;
265 lf_printf (file, "%s", prefix);
266 member = filter_next (set, "");
267 if (member != NULL)
268 {
269 while (1)
270 {
271 lf_printf (file, "%s", member);
272 member = filter_next (set, member);
273 if (member == NULL)
274 break;
275 lf_printf (file, ",");
276 }
277 }
278 lf_printf (file, "%s", suffix);
279 }
280
281
282 #ifdef MAIN
283 int
284 main(int argc, char **argv)
285 {
286 filter *subset = NULL;
287 filter *superset = NULL;
288 lf *l;
289 int i;
290 if (argc < 2) {
291 printf("Usage: filter <subset> <filter> ...\n");
292 exit (1);
293 }
294
295 /* load the filter up */
296 filter_parse (&subset, argv[1]);
297 for (i = 2; i < argc; i++)
298 filter_parse (&superset, argv[i]);
299
300 /* dump various info */
301 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-filter");
302 #if 0
303 if (is_filtered_out (argv[1], superset))
304 lf_printf (l, "excluded\n");
305 else
306 lf_printf (l, "included\n");
307 #endif
308 /* subset */
309 {
310 dump_filter (l, "{", subset, " }");
311 if (filter_is_subset (superset, subset))
312 lf_printf (l, " subset of ");
313 else
314 lf_printf (l, " !subset of ");
315 dump_filter (l, "{", superset, " }");
316 lf_printf (l, "\n");
317 }
318 /* intersection */
319 {
320 dump_filter (l, "{", subset, " }");
321 if (filter_is_common (subset, superset))
322 lf_printf (l, " intersects ");
323 else
324 lf_printf (l, " !intersects ");
325 dump_filter (l, "{", superset, " }");
326 lf_printf (l, "\n");
327 }
328 /* membership */
329 {
330 filter *memb = subset;
331 while (memb != NULL)
332 {
333 lf_printf (l, "%s", memb->member);
334 if (filter_is_member (superset, memb->member))
335 lf_printf (l, " in ");
336 else
337 lf_printf (l, " !in ");
338 dump_filter (l, "{", superset, " }");
339 lf_printf (l, "\n");
340 memb = memb->next;
341 }
342 }
343 /* addition */
344 {
345 filter *add = NULL;
346 filter_add (&add, superset);
347 filter_add (&add, subset);
348 dump_filter (l, "{", add, " }");
349 lf_printf (l, " = ");
350 dump_filter (l, "{", subset, " }");
351 lf_printf (l, " + ");
352 dump_filter (l, "{", superset, " }");
353 lf_printf (l, "\n");
354 }
355
356 return 0;
357 }
358 #endif
This page took 0.057588 seconds and 4 git commands to generate.