Don't run ld-scripts/pr20302 on linuxaout
[external/binutils.git] / sim / igen / filter.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3    Copyright 2002-2016 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 char *
220 filter_next (filter *set, char *member)
221 {
222   while (set != NULL)
223     {
224       if (strcmp (set->member, member) > 0)
225         return set->member;
226       set = set->next;
227     }
228   return NULL;
229 }
230
231
232 void
233 dump_filter (lf *file, char *prefix, filter *set, char *suffix)
234 {
235   char *member;
236   lf_printf (file, "%s", prefix);
237   member = filter_next (set, "");
238   if (member != NULL)
239     {
240       while (1)
241         {
242           lf_printf (file, "%s", member);
243           member = filter_next (set, member);
244           if (member == NULL)
245             break;
246           lf_printf (file, ",");
247         }
248     }
249   lf_printf (file, "%s", suffix);
250 }
251
252
253 #ifdef MAIN
254 int
255 main (int argc, char **argv)
256 {
257   filter *subset = NULL;
258   filter *superset = NULL;
259   lf *l;
260   int i;
261   if (argc < 2)
262     {
263       printf ("Usage: filter <subset> <filter> ...\n");
264       exit (1);
265     }
266
267   /* load the filter up */
268   filter_parse (&subset, argv[1]);
269   for (i = 2; i < argc; i++)
270     filter_parse (&superset, argv[i]);
271
272   /* dump various info */
273   l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-filter");
274
275   /* subset */
276   {
277     dump_filter (l, "{", subset, " }");
278     if (filter_is_subset (superset, subset))
279       lf_printf (l, " subset of ");
280     else
281       lf_printf (l, " !subset of ");
282     dump_filter (l, "{", superset, " }");
283     lf_printf (l, "\n");
284   }
285   /* intersection */
286   {
287     dump_filter (l, "{", subset, " }");
288     if (filter_is_common (subset, superset))
289       lf_printf (l, " intersects ");
290     else
291       lf_printf (l, " !intersects ");
292     dump_filter (l, "{", superset, " }");
293     lf_printf (l, "\n");
294   }
295   /* membership */
296   {
297     filter *memb = subset;
298     while (memb != NULL)
299       {
300         lf_printf (l, "%s", memb->member);
301         if (filter_is_member (superset, memb->member))
302           lf_printf (l, " in ");
303         else
304           lf_printf (l, " !in ");
305         dump_filter (l, "{", superset, " }");
306         lf_printf (l, "\n");
307         memb = memb->next;
308       }
309   }
310   /* addition */
311   {
312     filter *add = NULL;
313     filter_add (&add, superset);
314     filter_add (&add, subset);
315     dump_filter (l, "{", add, " }");
316     lf_printf (l, " = ");
317     dump_filter (l, "{", subset, " }");
318     lf_printf (l, " + ");
319     dump_filter (l, "{", superset, " }");
320     lf_printf (l, "\n");
321   }
322
323   return 0;
324 }
325 #endif