/* Debug counter for debugging support
   Copyright (C) 2006-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.

See dbgcnt.def for usage information.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "dumpfile.h"
#include "selftest.h"
#include "intl.h"

#include "dbgcnt.h"

struct string2counter_map {
  const char *name;
  enum debug_counter counter;
};

#define DEBUG_COUNTER(a) { #a , a },

static struct string2counter_map map[debug_counter_number_of_counters] =
{
#include "dbgcnt.def"
};
#undef DEBUG_COUNTER

typedef std::pair<unsigned int, unsigned int> limit_tuple;

static vec<limit_tuple> limits[debug_counter_number_of_counters];
static vec<limit_tuple> original_limits[debug_counter_number_of_counters];

static unsigned int count[debug_counter_number_of_counters];

static void
print_limit_reach (const char *counter, int limit, bool upper_p)
{
  char buffer[128];
  sprintf (buffer, "***dbgcnt: %s limit %d reached for %s.***\n",
	   upper_p ? "upper" : "lower", limit, counter);
  fputs (buffer, stderr);
  if (dump_file)
    fputs (buffer, dump_file);
}

bool
dbg_cnt (enum debug_counter index)
{
  unsigned v = ++count[index];

  if (!limits[index].exists ())
    return true;
  else if (limits[index].is_empty ())
    return false;

  unsigned last = limits[index].length () - 1;
  unsigned int min = limits[index][last].first;
  unsigned int max = limits[index][last].second;

  if (v < min)
    return false;
  else if (v == min)
    {
      print_limit_reach (map[index].name, v, false);
      if (min == max)
	{
	  print_limit_reach (map[index].name, v, true);
	  limits[index].pop ();
	}
      return true;
    }
  else if (v < max)
    return true;
  else if (v == max)
    {
      print_limit_reach (map[index].name, v, true);
      limits[index].pop ();
      return true;
    }
  else
    return false;
}

/* Compare limit_tuple intervals by first item in descending order.  */

static int
cmp_tuples (const void *ptr1, const void *ptr2)
{
  const limit_tuple *p1 = (const limit_tuple *)ptr1;
  const limit_tuple *p2 = (const limit_tuple *)ptr2;

  if (p1->first < p2->first)
    return 1;
  else if (p1->first > p2->first)
    return -1;
  return 0;
}

static bool
dbg_cnt_set_limit_by_index (enum debug_counter index, const char *name,
			    unsigned int low, unsigned int high)
{
  if (!limits[index].exists ())
    limits[index].create (1);

  limits[index].safe_push (limit_tuple (low, high));
  limits[index].qsort (cmp_tuples);

  for (unsigned i = 0; i < limits[index].length () - 1; i++)
    {
      limit_tuple t1 = limits[index][i];
      limit_tuple t2 = limits[index][i + 1];
      if (t1.first <= t2.second)
	{
	  error ("Interval overlap of %<-fdbg-cnt=%s%>: [%u, %u] and "
		 "[%u, %u]", name, t2.first, t2.second, t1.first, t1.second);
	  return false;
	}
    }

  original_limits[index] = limits[index].copy ();

  return true;
}

static bool
dbg_cnt_set_limit_by_name (const char *name, unsigned int low,
			   unsigned int high)
{
  if (high < low)
    {
      error ("%<-fdbg-cnt=%s:%d-%d%> has smaller upper limit than the lower",
	     name, low, high);
      return false;
    }

  int i;
  for (i = debug_counter_number_of_counters - 1; i >= 0; i--)
    if (strcmp (map[i].name, name) == 0)
      break;

  if (i < 0)
    {
      error ("cannot find a valid counter name %qs of %<-fdbg-cnt=%> option",
	     name);
      return false;
    }

  return dbg_cnt_set_limit_by_index ((enum debug_counter) i, name, low, high);
}

/* Process a single "low:high" pair.
   Returns NULL if there's no valid pair is found.
   Otherwise returns a pointer to the end of the pair. */

static bool
dbg_cnt_process_single_pair (char *name, char *str)
{
  char *value1 = strtok (str, "-");
  char *value2 = strtok (NULL, "-");

  unsigned int high, low;

  if (value1 == NULL)
    return false;

  if (value2 == NULL)
    {
      high = strtol (value1, NULL, 10);
      /* Let's allow 0:0.  */
      low = high == 0 ? 0 : 1;
    }
  else
    {
      low = strtol (value1, NULL, 10);
      high = strtol (value2, NULL, 10);
    }

  return dbg_cnt_set_limit_by_name (name, low, high);
}

void
dbg_cnt_process_opt (const char *arg)
{
  char *str = xstrdup (arg);
  unsigned int start = 0;

  auto_vec<char *> tokens;
  for (char *next = strtok (str, ","); next != NULL; next = strtok (NULL, ","))
    tokens.safe_push (next);

  unsigned i;
  for (i = 0; i < tokens.length (); i++)
    {
      auto_vec<char *> ranges;
      char *name = strtok (tokens[i], ":");
      for (char *part = strtok (NULL, ":"); part; part = strtok (NULL, ":"))
	ranges.safe_push (part);

      for (unsigned j = 0; j < ranges.length (); j++)
	{
	  if (!dbg_cnt_process_single_pair (name, ranges[j]))
	    break;
	}
      start += strlen (tokens[i]) + 1;
    }
}

/* Print name, limit and count of all counters.   */

void
dbg_cnt_list_all_counters (void)
{
  int i;
  fprintf (stderr, "  %-30s%-15s   %s\n", G_("counter name"),
	   G_("counter value"), G_("closed intervals"));
  fprintf (stderr, "-----------------------------------------------------------------\n");
  for (i = 0; i < debug_counter_number_of_counters; i++)
    {
      fprintf (stderr, "  %-30s%-15d   ", map[i].name, count[i]);
      if (original_limits[i].exists ())
	{
	  for (int j = original_limits[i].length () - 1; j >= 0; j--)
	    {
	      fprintf (stderr, "[%u, %u]", original_limits[i][j].first,
		       original_limits[i][j].second);
	      if (j > 0)
		fprintf (stderr, ", ");
	    }
	  fprintf (stderr, "\n");
	}
      else
	fprintf (stderr, "unset\n");
    }
  fprintf (stderr, "\n");
}

#if CHECKING_P

namespace selftest {

/* Selftests.  */

static void
test_sorted_dbg_counters ()
{
  for (unsigned i = 0; i < debug_counter_number_of_counters - 1; i++)
    ASSERT_LT (strcmp (map[i].name, map[i + 1].name), 0);
}

void
dbgcnt_c_tests ()
{
  test_sorted_dbg_counters ();
}

} // namespace selftest

#endif /* #if CHECKING_P */
