This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / sim / igen / filter.c
1 /*  This file is part of the program psim.
2
3     Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  
19     */
20
21
22 #include <stdio.h>
23
24 #include "config.h"
25
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #else
29 #ifdef HAVE_STRINGS_H
30 #include <strings.h>
31 #endif
32 #endif
33
34 #include "misc.h"
35 #include "lf.h"
36 #include "filter.h"
37
38 struct _filter {
39   char *member;
40   filter *next;
41 };
42
43
44 void
45 filter_parse (filter **filters,
46               const char *filt)
47 {
48   while (strlen (filt) > 0)
49     {
50       filter *new_filter;
51       filter **last;
52       /* break out a member of the filter list */
53       const char *flag = filt;
54       unsigned /*size_t*/ len;
55       filt = strchr (filt, ',');
56       if (filt == NULL)
57         {
58           filt = strchr (flag, '\0');
59           len = strlen (flag);
60         }
61       else
62         {
63           len = filt - flag;
64           filt = filt + 1;
65         }
66       /* find an insertion point - sorted order */
67       last = filters;
68       while (*last != NULL
69              && 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,
88             filter *add)
89 {
90   while (add != NULL)
91     {
92       int cmp;
93       if (*set == NULL)
94         cmp = 1; /* set->member > add->member */
95       else
96         cmp = strcmp ((*set)->member, add->member);
97       if (cmp > 0)
98         {
99           /* insert it here */
100           filter *new = ZALLOC (filter);
101           new->member = NZALLOC (char, strlen (add->member) + 1);
102           strcpy (new->member, add->member);
103           new->next = *set;
104           *set = new;
105           add = add->next;
106         }
107       else if (cmp == 0)
108         {
109           /* already in set */
110           add = add->next;
111         }
112       else /* cmp < 0 */
113         {
114           /* not reached insertion point */
115           set = &(*set)->next;
116         }
117     }
118 }
119
120
121 int
122 filter_is_subset (filter *superset,
123                   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,
145                   filter *r)
146 {
147   while (1)
148     {
149       int cmp;
150       if (l == NULL)
151         return 0;
152       if (r == NULL)
153         return 0;
154       cmp = strcmp (l->member, r->member);
155       if (cmp < 0)
156         l = l->next;
157       else if (cmp == 0)
158         return 1; /* common member */
159       else if (cmp > 0)
160         r = r->next;
161     }
162 }
163
164
165 int
166 filter_is_member (filter *filt,
167                   const char *flag)
168 {
169   int index = 1;
170   while (filt != NULL)
171     {
172       if (strcmp (flag, filt->member) == 0)
173         return index;
174       filt = filt->next;
175       index++;
176     }
177   return 0;
178 }
179
180
181 int
182 is_filtered_out (filter *filters,
183                  const char *flags)
184 {
185   while (strlen(flags) > 0) {
186     int present;
187     filter *filt = filters;
188     /* break the string up */
189     char *end = strchr(flags, ',');
190     char *next;
191     unsigned /*size_t*/ len;
192     if (end == NULL) {
193       end = strchr(flags, '\0');
194       next = end;
195     }
196     else {
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       if (strncmp(flags, filt->member, len) == 0
205           && strlen(filt->member) == len) {
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,
222        const char *flags)
223 {
224   int flag_len = strlen(flag);
225   while (*flags != '\0') {
226     if (!strncmp(flags, flag, flag_len)
227         && (flags[flag_len] == ',' || flags[flag_len] == '\0'))
228       return 1;
229     while (*flags != ',') {
230       if (*flags == '\0')
231         return 0;
232       flags++;
233     }
234     flags++;
235   }
236   return 0;
237 }
238 #endif
239
240
241 char *
242 filter_next (filter *set,
243              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,
257              char *prefix, 
258              filter *set,
259              char *suffix)
260 {
261   char *member;
262   lf_printf (file, "%s", prefix);
263   member = filter_next (set, "");
264   if (member != NULL)
265     {
266       while (1)
267         {
268           lf_printf (file, "%s", member);
269           member = filter_next (set, member);
270           if (member == NULL)
271             break;
272           lf_printf (file, ",");
273         }
274     }
275   lf_printf (file, "%s", suffix);
276 }
277
278
279 #ifdef MAIN
280 int
281 main(int argc, char **argv)
282 {
283   filter *subset = NULL;
284   filter *superset = NULL;
285   lf *l;
286   int i;
287   if (argc < 2) {
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