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