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 {
43   char *member;
44   filter *next;
45 };
46
47
48 void
49 filter_parse (filter **filters, 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 && strncmp (flag, (*last)->member, len) > 0)
72         last = &(*last)->next;
73       if (*last != NULL
74           && strncmp (flag, (*last)->member, len) == 0
75           && strlen ((*last)->member) == len)
76         continue;               /* duplicate */
77       /* create an entry for that member */
78       new_filter = ZALLOC (filter);
79       new_filter->member = NZALLOC (char, len + 1);
80       strncpy (new_filter->member, flag, len);
81       /* insert it */
82       new_filter->next = *last;
83       *last = new_filter;
84     }
85 }
86
87
88 void
89 filter_add (filter **set, filter *add)
90 {
91   while (add != NULL)
92     {
93       int cmp;
94       if (*set == NULL)
95         cmp = 1;                /* set->member > add->member */
96       else
97         cmp = strcmp ((*set)->member, add->member);
98       if (cmp > 0)
99         {
100           /* insert it here */
101           filter *new = ZALLOC (filter);
102           new->member = NZALLOC (char, strlen (add->member) + 1);
103           strcpy (new->member, add->member);
104           new->next = *set;
105           *set = new;
106           add = add->next;
107         }
108       else if (cmp == 0)
109         {
110           /* already in set */
111           add = add->next;
112         }
113       else                      /* cmp < 0 */
114         {
115           /* not reached insertion point */
116           set = &(*set)->next;
117         }
118     }
119 }
120
121
122 int
123 filter_is_subset (filter *superset, filter *subset)
124 {
125   while (1)
126     {
127       int cmp;
128       if (subset == NULL)
129         return 1;
130       if (superset == NULL)
131         return 0;               /* subset isn't finished */
132       cmp = strcmp (subset->member, superset->member);
133       if (cmp < 0)
134         return 0;               /* not found */
135       else if (cmp == 0)
136         subset = subset->next;  /* found */
137       else if (cmp > 0)
138         superset = superset->next;      /* later in list? */
139     }
140 }
141
142
143 int
144 filter_is_common (filter *l, filter *r)
145 {
146   while (1)
147     {
148       int cmp;
149       if (l == NULL)
150         return 0;
151       if (r == NULL)
152         return 0;
153       cmp = strcmp (l->member, r->member);
154       if (cmp < 0)
155         l = l->next;
156       else if (cmp == 0)
157         return 1;               /* common member */
158       else if (cmp > 0)
159         r = r->next;
160     }
161 }
162
163
164 int
165 filter_is_member (filter *filt, const char *flag)
166 {
167   int index = 1;
168   while (filt != NULL)
169     {
170       if (strcmp (flag, filt->member) == 0)
171         return index;
172       filt = filt->next;
173       index++;
174     }
175   return 0;
176 }
177
178
179 int
180 is_filtered_out (filter *filters, const char *flags)
181 {
182   while (strlen (flags) > 0)
183     {
184       int present;
185       filter *filt = filters;
186       /* break the string up */
187       char *end = strchr (flags, ',');
188       char *next;
189       unsigned /*size_t */ len;
190       if (end == NULL)
191         {
192           end = strchr (flags, '\0');
193           next = end;
194         }
195       else
196         {
197           next = end + 1;
198         }
199       len = end - flags;
200       /* check that it is present */
201       present = 0;
202       filt = filters;
203       while (filt != NULL)
204         {
205           if (strncmp (flags, filt->member, len) == 0
206               && strlen (filt->member) == len)
207             {
208               present = 1;
209               break;
210             }
211           filt = filt->next;
212         }
213       if (!present)
214         return 1;
215       flags = next;
216     }
217   return 0;
218 }
219
220
221 #if 0
222 int
223 it_is (const char *flag, const char *flags)
224 {
225   int flag_len = strlen (flag);
226   while (*flags != '\0')
227     {
228       if (!strncmp (flags, flag, flag_len)
229           && (flags[flag_len] == ',' || flags[flag_len] == '\0'))
230         return 1;
231       while (*flags != ',')
232         {
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, char *member)
246 {
247   while (set != NULL)
248     {
249       if (strcmp (set->member, member) > 0)
250         return set->member;
251       set = set->next;
252     }
253   return NULL;
254 }
255
256
257 void
258 dump_filter (lf *file, char *prefix, filter *set, char *suffix)
259 {
260   char *member;
261   lf_printf (file, "%s", prefix);
262   member = filter_next (set, "");
263   if (member != NULL)
264     {
265       while (1)
266         {
267           lf_printf (file, "%s", member);
268           member = filter_next (set, member);
269           if (member == NULL)
270             break;
271           lf_printf (file, ",");
272         }
273     }
274   lf_printf (file, "%s", suffix);
275 }
276
277
278 #ifdef MAIN
279 int
280 main (int argc, char **argv)
281 {
282   filter *subset = NULL;
283   filter *superset = NULL;
284   lf *l;
285   int i;
286   if (argc < 2)
287     {
288       printf ("Usage: filter <subset> <filter> ...\n");
289       exit (1);
290     }
291
292   /* load the filter up */
293   filter_parse (&subset, argv[1]);
294   for (i = 2; i < argc; i++)
295     filter_parse (&superset, argv[i]);
296
297   /* dump various info */
298   l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-filter");
299 #if 0
300   if (is_filtered_out (argv[1], superset))
301     lf_printf (l, "excluded\n");
302   else
303     lf_printf (l, "included\n");
304 #endif
305   /* subset */
306   {
307     dump_filter (l, "{", subset, " }");
308     if (filter_is_subset (superset, subset))
309       lf_printf (l, " subset of ");
310     else
311       lf_printf (l, " !subset of ");
312     dump_filter (l, "{", superset, " }");
313     lf_printf (l, "\n");
314   }
315   /* intersection */
316   {
317     dump_filter (l, "{", subset, " }");
318     if (filter_is_common (subset, superset))
319       lf_printf (l, " intersects ");
320     else
321       lf_printf (l, " !intersects ");
322     dump_filter (l, "{", superset, " }");
323     lf_printf (l, "\n");
324   }
325   /* membership */
326   {
327     filter *memb = subset;
328     while (memb != NULL)
329       {
330         lf_printf (l, "%s", memb->member);
331         if (filter_is_member (superset, memb->member))
332           lf_printf (l, " in ");
333         else
334           lf_printf (l, " !in ");
335         dump_filter (l, "{", superset, " }");
336         lf_printf (l, "\n");
337         memb = memb->next;
338       }
339   }
340   /* addition */
341   {
342     filter *add = NULL;
343     filter_add (&add, superset);
344     filter_add (&add, subset);
345     dump_filter (l, "{", add, " }");
346     lf_printf (l, " = ");
347     dump_filter (l, "{", subset, " }");
348     lf_printf (l, " + ");
349     dump_filter (l, "{", superset, " }");
350     lf_printf (l, "\n");
351   }
352
353   return 0;
354 }
355 #endif