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