summaryrefslogtreecommitdiff
path: root/sim/igen/filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/igen/filter.c')
-rw-r--r--sim/igen/filter.c355
1 files changed, 355 insertions, 0 deletions
diff --git a/sim/igen/filter.c b/sim/igen/filter.c
new file mode 100644
index 00000000000..afc51889724
--- /dev/null
+++ b/sim/igen/filter.c
@@ -0,0 +1,355 @@
+/* This file is part of the program psim.
+
+ Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+
+#include <stdio.h>
+
+#include "config.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
+#include "misc.h"
+#include "lf.h"
+#include "filter.h"
+
+struct _filter {
+ char *member;
+ filter *next;
+};
+
+
+void
+filter_parse (filter **filters,
+ const char *filt)
+{
+ while (strlen (filt) > 0)
+ {
+ filter *new_filter;
+ filter **last;
+ /* break out a member of the filter list */
+ const char *flag = filt;
+ unsigned /*size_t*/ len;
+ filt = strchr (filt, ',');
+ if (filt == NULL)
+ {
+ filt = strchr (flag, '\0');
+ len = strlen (flag);
+ }
+ else
+ {
+ len = filt - flag;
+ filt = filt + 1;
+ }
+ /* find an insertion point - sorted order */
+ last = filters;
+ while (*last != NULL
+ && strncmp (flag, (*last)->member, len) > 0)
+ last = &(*last)->next;
+ if (*last != NULL
+ && strncmp (flag, (*last)->member, len) == 0
+ && strlen ((*last)->member) == len)
+ continue; /* duplicate */
+ /* create an entry for that member */
+ new_filter = ZALLOC (filter);
+ new_filter->member = NZALLOC (char, len + 1);
+ strncpy (new_filter->member, flag, len);
+ /* insert it */
+ new_filter->next = *last;
+ *last = new_filter;
+ }
+}
+
+
+void
+filter_add (filter **set,
+ filter *add)
+{
+ while (add != NULL)
+ {
+ int cmp;
+ if (*set == NULL)
+ cmp = 1; /* set->member > add->member */
+ else
+ cmp = strcmp ((*set)->member, add->member);
+ if (cmp > 0)
+ {
+ /* insert it here */
+ filter *new = ZALLOC (filter);
+ new->member = NZALLOC (char, strlen (add->member) + 1);
+ strcpy (new->member, add->member);
+ new->next = *set;
+ *set = new;
+ add = add->next;
+ }
+ else if (cmp == 0)
+ {
+ /* already in set */
+ add = add->next;
+ }
+ else /* cmp < 0 */
+ {
+ /* not reached insertion point */
+ set = &(*set)->next;
+ }
+ }
+}
+
+
+int
+filter_is_subset (filter *superset,
+ filter *subset)
+{
+ while (1)
+ {
+ int cmp;
+ if (subset == NULL)
+ return 1;
+ if (superset == NULL)
+ return 0; /* subset isn't finished */
+ cmp = strcmp (subset->member, superset->member);
+ if (cmp < 0)
+ return 0; /* not found */
+ else if (cmp == 0)
+ subset = subset->next; /* found */
+ else if (cmp > 0)
+ superset = superset->next; /* later in list? */
+ }
+}
+
+
+int
+filter_is_common (filter *l,
+ filter *r)
+{
+ while (1)
+ {
+ int cmp;
+ if (l == NULL)
+ return 0;
+ if (r == NULL)
+ return 0;
+ cmp = strcmp (l->member, r->member);
+ if (cmp < 0)
+ l = l->next;
+ else if (cmp == 0)
+ return 1; /* common member */
+ else if (cmp > 0)
+ r = r->next;
+ }
+}
+
+
+int
+filter_is_member (filter *filt,
+ const char *flag)
+{
+ int index = 1;
+ while (filt != NULL)
+ {
+ if (strcmp (flag, filt->member) == 0)
+ return index;
+ filt = filt->next;
+ index++;
+ }
+ return 0;
+}
+
+
+int
+is_filtered_out (filter *filters,
+ const char *flags)
+{
+ while (strlen(flags) > 0) {
+ int present;
+ filter *filt = filters;
+ /* break the string up */
+ char *end = strchr(flags, ',');
+ char *next;
+ unsigned /*size_t*/ len;
+ if (end == NULL) {
+ end = strchr(flags, '\0');
+ next = end;
+ }
+ else {
+ next = end + 1;
+ }
+ len = end - flags;
+ /* check that it is present */
+ present = 0;
+ filt = filters;
+ while (filt != NULL) {
+ if (strncmp(flags, filt->member, len) == 0
+ && strlen(filt->member) == len) {
+ present = 1;
+ break;
+ }
+ filt = filt->next;
+ }
+ if (!present)
+ return 1;
+ flags = next;
+ }
+ return 0;
+}
+
+
+#if 0
+int
+it_is (const char *flag,
+ const char *flags)
+{
+ int flag_len = strlen(flag);
+ while (*flags != '\0') {
+ if (!strncmp(flags, flag, flag_len)
+ && (flags[flag_len] == ',' || flags[flag_len] == '\0'))
+ return 1;
+ while (*flags != ',') {
+ if (*flags == '\0')
+ return 0;
+ flags++;
+ }
+ flags++;
+ }
+ return 0;
+}
+#endif
+
+
+char *
+filter_next (filter *set,
+ char *member)
+{
+ while (set != NULL)
+ {
+ if (strcmp (set->member, member) > 0)
+ return set->member;
+ set = set->next;
+ }
+ return NULL;
+}
+
+
+void
+dump_filter (lf *file,
+ char *prefix,
+ filter *set,
+ char *suffix)
+{
+ char *member;
+ lf_printf (file, "%s", prefix);
+ member = filter_next (set, "");
+ if (member != NULL)
+ {
+ while (1)
+ {
+ lf_printf (file, "%s", member);
+ member = filter_next (set, member);
+ if (member == NULL)
+ break;
+ lf_printf (file, ",");
+ }
+ }
+ lf_printf (file, "%s", suffix);
+}
+
+
+#ifdef MAIN
+int
+main(int argc, char **argv)
+{
+ filter *subset = NULL;
+ filter *superset = NULL;
+ lf *l;
+ int i;
+ if (argc < 2) {
+ printf("Usage: filter <subset> <filter> ...\n");
+ exit (1);
+ }
+
+ /* load the filter up */
+ filter_parse (&subset, argv[1]);
+ for (i = 2; i < argc; i++)
+ filter_parse (&superset, argv[i]);
+
+ /* dump various info */
+ l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-filter");
+#if 0
+ if (is_filtered_out (argv[1], superset))
+ lf_printf (l, "excluded\n");
+ else
+ lf_printf (l, "included\n");
+#endif
+ /* subset */
+ {
+ dump_filter (l, "{", subset, " }");
+ if (filter_is_subset (superset, subset))
+ lf_printf (l, " subset of ");
+ else
+ lf_printf (l, " !subset of ");
+ dump_filter (l, "{", superset, " }");
+ lf_printf (l, "\n");
+ }
+ /* intersection */
+ {
+ dump_filter (l, "{", subset, " }");
+ if (filter_is_common (subset, superset))
+ lf_printf (l, " intersects ");
+ else
+ lf_printf (l, " !intersects ");
+ dump_filter (l, "{", superset, " }");
+ lf_printf (l, "\n");
+ }
+ /* membership */
+ {
+ filter *memb = subset;
+ while (memb != NULL)
+ {
+ lf_printf (l, "%s", memb->member);
+ if (filter_is_member (superset, memb->member))
+ lf_printf (l, " in ");
+ else
+ lf_printf (l, " !in ");
+ dump_filter (l, "{", superset, " }");
+ lf_printf (l, "\n");
+ memb = memb->next;
+ }
+ }
+ /* addition */
+ {
+ filter *add = NULL;
+ filter_add (&add, superset);
+ filter_add (&add, subset);
+ dump_filter (l, "{", add, " }");
+ lf_printf (l, " = ");
+ dump_filter (l, "{", subset, " }");
+ lf_printf (l, " + ");
+ dump_filter (l, "{", superset, " }");
+ lf_printf (l, "\n");
+ }
+
+ return 0;
+}
+#endif