/* Gcov.c: prepend line execution counts and branch probabilities to a
source file.
- Copyright (C) 1990, 91-94, 96-99, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by James E. Wilson of Cygnus Support.
Mangled by Bob Manson of Cygnus Support.
#include "intl.h"
#undef abort
+typedef HOST_WIDEST_INT gcov_type;
#include "gcov-io.h"
/* The .bb file format consists of several lists of 4-byte integers
/* The functions in this file for creating and solution program flow graphs
are very similar to functions in the gcc source file profile.c. */
-char gcov_version_string[] = "GNU gcov version 1.5\n";
+static const char gcov_version_string[] = "GNU gcov version 1.5\n";
/* This is the size of the buffer used to read in source file lines. */
struct adj_list {
int source;
int target;
- int arc_count;
+ gcov_type arc_count;
unsigned int count_valid : 1;
unsigned int on_tree : 1;
unsigned int fake : 1;
struct bb_info {
struct adj_list *succ;
struct adj_list *pred;
- int succ_count;
- int pred_count;
- int exec_count;
+ gcov_type succ_count;
+ gcov_type pred_count;
+ gcov_type exec_count;
unsigned int count_valid : 1;
unsigned int on_tree : 1;
#if 0
struct arcdata
{
- int hits;
- int total;
+ gcov_type hits;
+ gcov_type total;
int call_insn;
struct arcdata *next;
};
/* Output the number of times a branch was taken as opposed to the percentage
of times it was taken. Turned on by the -c option */
-
+
static int output_branch_counts = 0;
/* Forward declarations. */
int argc;
char **argv;
{
+/* LC_CTYPE determines the character set used by the terminal so it has be set
+ to output messages correctly. */
+
#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_CTYPE, "");
setlocale (LC_MESSAGES, "");
+#else
+ setlocale (LC_ALL, "");
#endif
+
(void) bindtextdomain (PACKAGE, localedir);
(void) textdomain (PACKAGE);
static void
fnotice VPARAMS ((FILE *file, const char *msgid, ...))
{
-#ifndef ANSI_PROTOTYPES
- FILE *file;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- file = va_arg (ap, FILE *);
- msgid = va_arg (ap, const char *);
-#endif
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, FILE *, file);
+ VA_FIXEDARG (ap, const char *, msgid);
vfprintf (file, _(msgid), ap);
- va_end (ap);
+ VA_CLOSE (ap);
}
/* More 'friendly' abort that prints the line and file.
strcat (bbg_file_name, "/");
}
- cptr = rindex (input_file_name, '/');
+ cptr = strrchr (input_file_name, '/');
if (cptr)
{
strcat (da_file_name, cptr + 1);
strcpy (bbg_file_name, input_file_name);
}
- cptr = rindex (bb_file_name, '.');
+ cptr = strrchr (bb_file_name, '.');
if (cptr)
strcpy (cptr, ".bb");
else
strcat (bb_file_name, ".bb");
- cptr = rindex (da_file_name, '.');
+ cptr = strrchr (da_file_name, '.');
if (cptr)
strcpy (cptr, ".da");
else
strcat (da_file_name, ".da");
- cptr = rindex (bbg_file_name, '.');
+ cptr = strrchr (bbg_file_name, '.');
if (cptr)
strcpy (cptr, ".bbg");
else
fnotice (stderr, "Could not open data file %s.\n", da_file_name);
fnotice (stderr, "Assuming that all execution counts are zero.\n");
}
-
+
bbg_file = fopen (bbg_file_name, "rb");
if (bbg_file == NULL)
{
}
-/* Reverse the arcs on a arc list. */
+/* Reverse the arcs on an arc list. */
static struct adj_list *
reverse_arcs (arcptr)
for (arcptr = bb_graph[i].succ; arcptr; arcptr = arcptr->succ_next)
if (! arcptr->on_tree)
{
- long tmp_count = 0;
- if (da_file && __read_long (&tmp_count, da_file, 8))
+ gcov_type tmp_count = 0;
+ if (da_file && __read_gcov_type (&tmp_count, da_file, 8))
abort();
arcptr->arc_count = tmp_count;
bb_graph[arcptr->target].pred_count--;
}
}
-
+
static void
solve_program_flow_graph (bptr)
struct bb_info_list *bptr;
{
- int passes, changes, total;
+ int passes, changes;
+ gcov_type total;
int i;
struct adj_list *arcptr;
struct bb_info *bb_graph;
}
}
}
-
+
/* If the graph has been correctly solved, every block will have a
succ and pred count of zero. */
for (i = 0; i < num_blocks; i++)
bb_data = (char *) xmalloc ((unsigned) buf.st_size);
fread (bb_data, sizeof (char), buf.st_size, bb_file);
-
+
fclose (bb_file);
if (da_file)
fclose (da_file);
{
struct sourcefile *s_ptr = NULL;
char *ptr;
- int count;
+ long count;
long line_num;
/* Search the bb_data to find:
}
else if (line_num < 0)
{
- /* Don't know what this is, but it's garbage. */
+ /* Don't know what this is, but it's garbage. */
abort();
}
}
struct arcdata **branch_probs;
int last_line_num;
{
- int total;
+ gcov_type total;
struct adj_list *arcptr;
struct arcdata *end_ptr, *a_ptr;
if (arcptr->fall_through)
continue;
-
+
a_ptr = (struct arcdata *) xmalloc (sizeof (struct arcdata));
a_ptr->total = total;
if (total == 0)
int this_file;
/* An array indexed by line number which indicates how many times that line
was executed. */
- long *line_counts;
+ gcov_type *line_counts;
/* An array indexed by line number which indicates whether the line was
present in the bb file (i.e. whether it had code associate with it).
Lines never executed are those which both exist, and have zero execution
char *source_file_name;
FILE *source_file;
struct bb_info_list *current_graph;
- int count;
+ long count;
char *cptr;
long block_num;
long line_num;
else
source_file_name = s_ptr->name;
- line_counts = (long *) xcalloc (sizeof (long), s_ptr->maxlineno);
+ line_counts = (gcov_type *) xcalloc (sizeof (gcov_type), s_ptr->maxlineno);
line_exists = xcalloc (1, s_ptr->maxlineno);
if (output_branch_probs)
branch_probs = (struct arcdata **)
xcalloc (sizeof (struct arcdata *), s_ptr->maxlineno);
-
+
/* There will be a zero at the beginning of the bb info, before the
first list of line numbers, so must initialize block_num to 0. */
block_num = 0;
this_file = 0;
else
this_file = 1;
-
+
/* Scan past the file name. */
do {
count++;
function_name);
abort ();
}
-
+
if (output_branch_probs && this_file)
calculate_branch_probs (current_graph, block_num,
branch_probs, last_line_num);
/* Now the statistics are ready. Read in the source file one line
at a time, and output that line to the gcov file preceded by
its execution count if non zero. */
-
+
source_file = fopen (source_file_name, "r");
if (source_file == NULL)
{
}
count = strlen (source_file_name);
- cptr = rindex (s_ptr->name, '/');
+ cptr = strrchr (s_ptr->name, '/');
if (cptr)
cptr = cptr + 1;
else
if (output_long_names && strcmp (cptr, input_file_name))
{
gcov_file_name = xmalloc (count + 7 + strlen (input_file_name));
-
- cptr = rindex (input_file_name, '/');
+
+ cptr = strrchr (input_file_name, '/');
if (cptr)
strcpy (gcov_file_name, cptr + 1);
else
strcat (gcov_file_name, ".");
- cptr = rindex (source_file_name, '/');
+ cptr = strrchr (source_file_name, '/');
if (cptr)
strcat (gcov_file_name, cptr + 1);
else
else
{
gcov_file_name = xmalloc (count + 6);
- cptr = rindex (source_file_name, '/');
+ cptr = strrchr (source_file_name, '/');
if (cptr)
strcpy (gcov_file_name, cptr + 1);
else
if (line_exists[count])
{
if (line_counts[count])
- fprintf (gcov_file, "%12ld %s", line_counts[count],
- string);
+ {
+ char c[20];
+ sprintf (c, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)line_counts[count]);
+ fprintf (gcov_file, "%12s %s", c,
+ string);
+ }
else
fprintf (gcov_file, " ###### %s", string);
}
else
{
if (output_branch_counts)
- fnotice (gcov_file,
- "call %d returns = %d\n",
- i, a_ptr->total - a_ptr->hits);
+ {
+ char c[20];
+ sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+ a_ptr->total - a_ptr->hits);
+ fnotice (gcov_file,
+ "call %d returns = %s\n", i, c);
+ }
else
- fnotice (gcov_file,
- "call %d returns = %d%%\n",
- i, 100 - ((a_ptr->hits * 100) +
- (a_ptr->total >> 1))/a_ptr->total);
+ {
+ char c[20];
+ sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+ 100 - ((a_ptr->hits * 100)
+ + (a_ptr->total >> 1))
+ / a_ptr->total);
+ fnotice (gcov_file,
+ "call %d returns = %s%%\n", i, c);
+ }
}
}
else
else
{
if (output_branch_counts)
- fnotice (gcov_file,
- "branch %d taken = %d\n",
- i, a_ptr->hits);
+ {
+ char c[20];
+ sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+ a_ptr->hits);
+ fnotice (gcov_file,
+ "branch %d taken = %s\n", i, c);
+ }
else
+ {
+ char c[20];
+ sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+ ((a_ptr->hits * 100)
+ + (a_ptr->total >> 1))
+ / a_ptr->total);
fnotice (gcov_file,
- "branch %d taken = %d%%\n", i,
- ((a_ptr->hits * 100) +
- (a_ptr->total >> 1))/
- a_ptr->total);
-
+ "branch %d taken = %s%%\n", i, c);
+ }
}
}
}