2002-11-21 Andrew Cagney <ac131313@redhat.com>
[external/binutils.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