dbgcnt.c 3.39 KB
Newer Older
1 2 3 4 5 6 7
/* Debug counter for debugging support
   Copyright (C) 2006, 2007 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
8
Software Foundation; either version 3, or (at your option) any later
9 10 11 12 13 14 15 16
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
17 18
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  
19 20 21 22 23 24

See dbgcnt.def for usage information.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
25
#include "errors.h"
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

#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

#define DEBUG_COUNTER(a) UINT_MAX,
static unsigned int limit[debug_counter_number_of_counters] =
{
#include "dbgcnt.def"
};
#undef DEBUG_COUNTER

static unsigned int count[debug_counter_number_of_counters];

bool
dbg_cnt_is_enabled (enum debug_counter index)
{
  return count[index] <= limit[index];
}

bool
dbg_cnt (enum debug_counter index)
{
  count[index]++;
  return dbg_cnt_is_enabled (index);
}


static void
dbg_cnt_set_limit_by_index (enum debug_counter index, int value)
{
  limit[index] = value;

  fprintf (stderr, "dbg_cnt '%s' set to %d\n", map[index].name, value);
}

73
static bool
74 75 76 77 78 79 80 81
dbg_cnt_set_limit_by_name (const char *name, int len, int value)
{
  int i;
  for (i = debug_counter_number_of_counters - 1; i >= 0; i--)
    if (!strncmp (map[i].name, name, len))
      break;

  if (i < 0)
82
    return false;
83 84

  dbg_cnt_set_limit_by_index (i, value);
85
  return true;
86 87
}

88 89 90 91 92 93 94

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

static const char *
dbg_cnt_process_single_pair (const char *arg)
95 96
{
   char *colon = strchr (arg, ':');
97 98
   char *endptr = NULL;
   int value;
99 100
   
   if (colon == NULL)
101 102 103
     return NULL;

   value = strtol (colon + 1, &endptr, 10);
104

105 106 107 108 109 110
   if (endptr != NULL && endptr != colon + 1
       && dbg_cnt_set_limit_by_name (arg, colon - arg, value))
     return endptr;
   
   return NULL;
}
111

112 113 114 115 116 117 118 119 120 121 122 123
void
dbg_cnt_process_opt (const char *arg)
{
   const char *start = arg;
   const char *next;
   do {
     next = dbg_cnt_process_single_pair (arg);
     if (next == NULL)
       break;
   } while (*next == ',' && (arg = next + 1));

   if (next == NULL || *next != 0)
124
     {
125 126 127 128 129
       char *buffer = alloca (arg - start + 2);
       sprintf (buffer, "%*c", (int)(1 + (arg - start)), '^');
       error ("Can not find a valid counter:value pair:");
       error ("-fdbg-cnt=%s", start);
       error ("          %s", buffer);
130 131
     }
}
132 133 134 135 136 137 138 139 140 141 142 143 144

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

void dbg_cnt_list_all_counters (void)
{
  int i;
  printf ("  %-30s %-5s %-5s\n", "counter name",  "limit", "value");
  printf ("----------------------------------------------\n");
  for (i = 0; i < debug_counter_number_of_counters; i++)
    printf ("  %-30s %5d %5u\n",
            map[i].name, limit[map[i].counter], count[map[i].counter]);
  printf ("\n");
}