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

/* Return the counter for INDEX.  */

unsigned
dbg_cnt_counter (enum debug_counter index)
{
  return count[index];
}

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