/* The IGEN simulator generator for GDB, the GNU Debugger.

   Copyright 2002-2021 Free Software Foundation, Inc.

   Contributed by Andrew Cagney.

   This file is part of GDB.

   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 3 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, see <http://www.gnu.org/licenses/>.  */


#include <stdio.h>
#include <string.h>

#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;
}


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");

  /* 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
