]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/igen/filter.c
sim: clean up C11 header includes
[thirdparty/binutils-gdb.git] / sim / igen / filter.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3 Copyright 2002-2021 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 #include <string.h>
28
29 #include "misc.h"
30 #include "lf.h"
31 #include "filter.h"
32
33 struct _filter
34 {
35 char *member;
36 filter *next;
37 };
38
39
40 void
41 filter_parse (filter **filters, const char *filt)
42 {
43 while (strlen (filt) > 0)
44 {
45 filter *new_filter;
46 filter **last;
47 /* break out a member of the filter list */
48 const char *flag = filt;
49 unsigned /*size_t */ len;
50 filt = strchr (filt, ',');
51 if (filt == NULL)
52 {
53 filt = strchr (flag, '\0');
54 len = strlen (flag);
55 }
56 else
57 {
58 len = filt - flag;
59 filt = filt + 1;
60 }
61 /* find an insertion point - sorted order */
62 last = filters;
63 while (*last != NULL && strncmp (flag, (*last)->member, len) > 0)
64 last = &(*last)->next;
65 if (*last != NULL
66 && strncmp (flag, (*last)->member, len) == 0
67 && strlen ((*last)->member) == len)
68 continue; /* duplicate */
69 /* create an entry for that member */
70 new_filter = ZALLOC (filter);
71 new_filter->member = NZALLOC (char, len + 1);
72 strncpy (new_filter->member, flag, len);
73 /* insert it */
74 new_filter->next = *last;
75 *last = new_filter;
76 }
77 }
78
79
80 void
81 filter_add (filter **set, filter *add)
82 {
83 while (add != NULL)
84 {
85 int cmp;
86 if (*set == NULL)
87 cmp = 1; /* set->member > add->member */
88 else
89 cmp = strcmp ((*set)->member, add->member);
90 if (cmp > 0)
91 {
92 /* insert it here */
93 filter *new = ZALLOC (filter);
94 new->member = NZALLOC (char, strlen (add->member) + 1);
95 strcpy (new->member, add->member);
96 new->next = *set;
97 *set = new;
98 add = add->next;
99 }
100 else if (cmp == 0)
101 {
102 /* already in set */
103 add = add->next;
104 }
105 else /* cmp < 0 */
106 {
107 /* not reached insertion point */
108 set = &(*set)->next;
109 }
110 }
111 }
112
113
114 int
115 filter_is_subset (filter *superset, filter *subset)
116 {
117 while (1)
118 {
119 int cmp;
120 if (subset == NULL)
121 return 1;
122 if (superset == NULL)
123 return 0; /* subset isn't finished */
124 cmp = strcmp (subset->member, superset->member);
125 if (cmp < 0)
126 return 0; /* not found */
127 else if (cmp == 0)
128 subset = subset->next; /* found */
129 else if (cmp > 0)
130 superset = superset->next; /* later in list? */
131 }
132 }
133
134
135 int
136 filter_is_common (filter *l, filter *r)
137 {
138 while (1)
139 {
140 int cmp;
141 if (l == NULL)
142 return 0;
143 if (r == NULL)
144 return 0;
145 cmp = strcmp (l->member, r->member);
146 if (cmp < 0)
147 l = l->next;
148 else if (cmp == 0)
149 return 1; /* common member */
150 else if (cmp > 0)
151 r = r->next;
152 }
153 }
154
155
156 int
157 filter_is_member (filter *filt, const char *flag)
158 {
159 int index = 1;
160 while (filt != NULL)
161 {
162 if (strcmp (flag, filt->member) == 0)
163 return index;
164 filt = filt->next;
165 index++;
166 }
167 return 0;
168 }
169
170
171 int
172 is_filtered_out (filter *filters, const char *flags)
173 {
174 while (strlen (flags) > 0)
175 {
176 int present;
177 filter *filt = filters;
178 /* break the string up */
179 char *end = strchr (flags, ',');
180 char *next;
181 unsigned /*size_t */ len;
182 if (end == NULL)
183 {
184 end = strchr (flags, '\0');
185 next = end;
186 }
187 else
188 {
189 next = end + 1;
190 }
191 len = end - flags;
192 /* check that it is present */
193 present = 0;
194 filt = filters;
195 while (filt != NULL)
196 {
197 if (strncmp (flags, filt->member, len) == 0
198 && strlen (filt->member) == len)
199 {
200 present = 1;
201 break;
202 }
203 filt = filt->next;
204 }
205 if (!present)
206 return 1;
207 flags = next;
208 }
209 return 0;
210 }
211
212
213 char *
214 filter_next (filter *set, char *member)
215 {
216 while (set != NULL)
217 {
218 if (strcmp (set->member, member) > 0)
219 return set->member;
220 set = set->next;
221 }
222 return NULL;
223 }
224
225
226 void
227 dump_filter (lf *file, char *prefix, filter *set, char *suffix)
228 {
229 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