/* Gcov.c: prepend line execution counts and branch probabilities to a
source file.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by James E. Wilson of Cygnus Support.
Mangled by Bob Manson of Cygnus Support.
/* This is the size of the buffer used to read in source file lines. */
-#define STRING_SIZE 200
-
struct function_info;
struct block_info;
struct source_info;
static unsigned object_runs;
static unsigned program_count;
+static unsigned total_lines;
+static unsigned total_executed;
+
/* Modification time of graph file. */
static time_t bbg_file_time;
static void find_exception_blocks (function_t *);
static void add_branch_counts (coverage_t *, const arc_t *);
static void add_line_counts (coverage_t *, function_t *);
+static void executed_summary (unsigned, unsigned);
static void function_summary (const coverage_t *, const char *);
static const char *format_gcov (gcov_type, gcov_type, int);
static void accumulate_line_counts (source_t *);
print_version (void)
{
fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
- fprintf (stdout, "Copyright %s 2011 Free Software Foundation, Inc.\n",
+ fprintf (stdout, "Copyright %s 2012 Free Software Foundation, Inc.\n",
_("(C)"));
fnotice (stdout,
_("This is free software; see the source for copying conditions.\n"
accumulate_line_counts (src);
function_summary (&src->coverage, "File");
- if (flag_gcov_file && src->coverage.lines)
+ total_lines += src->coverage.lines;
+ total_executed += src->coverage.lines_executed;
+ if (flag_gcov_file)
{
char *gcov_file_name
= make_gcov_file_name (file_name, src->coverage.name);
- FILE *gcov_file = fopen (gcov_file_name, "w");
- if (gcov_file)
+ if (src->coverage.lines)
{
- fnotice (stdout, "Creating '%s'\n", gcov_file_name);
- output_lines (gcov_file, src);
- if (ferror (gcov_file))
+ FILE *gcov_file = fopen (gcov_file_name, "w");
+
+ if (gcov_file)
+ {
+ fnotice (stdout, "Creating '%s'\n", gcov_file_name);
+ output_lines (gcov_file, src);
+ if (ferror (gcov_file))
fnotice (stderr, "Error writing output file '%s'\n",
gcov_file_name);
- fclose (gcov_file);
+ fclose (gcov_file);
+ }
+ else
+ fnotice (stderr, "Could not open output file '%s'\n",
+ gcov_file_name);
}
else
- fnotice (stderr, "Could not open output file '%s'\n",
- gcov_file_name);
+ {
+ unlink (gcov_file_name);
+ fnotice (stdout, "Removing '%s'\n", gcov_file_name);
+ }
free (gcov_file_name);
}
fnotice (stdout, "\n");
}
+
+ if (!file_name)
+ executed_summary (total_lines, total_executed);
}
/* Release a function structure */
return buffer;
}
-
-/* Output summary info for a function. */
+/* Summary of execution */
static void
-function_summary (const coverage_t *coverage, const char *title)
+executed_summary (unsigned lines, unsigned executed)
{
- fnotice (stdout, "%s '%s'\n", title, coverage->name);
-
- if (coverage->lines)
+ if (lines)
fnotice (stdout, "Lines executed:%s of %d\n",
- format_gcov (coverage->lines_executed, coverage->lines, 2),
- coverage->lines);
+ format_gcov (executed, lines, 2), lines);
else
fnotice (stdout, "No executable lines\n");
+}
+
+/* Output summary info for a function or file. */
+
+static void
+function_summary (const coverage_t *coverage, const char *title)
+{
+ fnotice (stdout, "%s '%s'\n", title, coverage->name);
+ executed_summary (coverage->lines, coverage->lines_executed);
if (flag_branches)
{
}
+static const char *
+read_line (FILE *file)
+{
+ static char *string;
+ static size_t string_len;
+ size_t pos = 0;
+ char *ptr;
+
+ if (!string_len)
+ {
+ string_len = 200;
+ string = XNEWVEC (char, string_len);
+ }
+
+ while ((ptr = fgets (string + pos, string_len - pos, file)))
+ {
+ size_t len = strlen (string + pos);
+
+ if (string[pos + len - 1] == '\n')
+ {
+ string[pos + len - 1] = 0;
+ return string;
+ }
+ pos += len;
+ ptr = XNEWVEC (char, string_len * 2);
+ if (ptr)
+ {
+ memcpy (ptr, string, pos);
+ string = ptr;
+ string_len += 2;
+ }
+ else
+ pos = 0;
+ }
+
+ return pos ? string : NULL;
+}
+
/* Read in the source file one line at a time, and output that line to
the gcov file preceded by its execution count and other
information. */
FILE *source_file;
unsigned line_num; /* current line number. */
const line_t *line; /* current line info ptr. */
- char string[STRING_SIZE]; /* line buffer. */
- char const *retval = ""; /* status of source file reading. */
+ const char *retval = ""; /* status of source file reading. */
function_t *fn = NULL;
fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
fprintf (gcov_file, "\n");
}
+ if (retval)
+ retval = read_line (source_file);
+
/* For lines which don't exist in the .bb file, print '-' before
the source line. For lines which exist but were never
- executed, print '#####' before the source line. Otherwise,
- print the execution count before the source line. There are
- 16 spaces of indentation added before the source line so that
- tabs won't be messed up. */
- fprintf (gcov_file, "%9s:%5u:",
+ executed, print '#####' or '=====' before the source line.
+ Otherwise, print the execution count before the source line.
+ There are 16 spaces of indentation added before the source
+ line so that tabs won't be messed up. */
+ fprintf (gcov_file, "%9s:%5u:%s\n",
!line->exists ? "-" : line->count
? format_gcov (line->count, 0, -1)
- : line->unexceptional ? "#####" : "=====", line_num);
-
- if (retval)
- {
- /* Copy source line. */
- do
- {
- retval = fgets (string, STRING_SIZE, source_file);
- if (!retval)
- break;
- fputs (retval, gcov_file);
- }
- while (!retval[0] || retval[strlen (retval) - 1] != '\n');
- }
- if (!retval)
- fputs ("/*EOF*/\n", gcov_file);
+ : line->unexceptional ? "#####" : "=====", line_num,
+ retval ? retval : "/*EOF*/");
if (flag_all_blocks)
{
last line of code. */
if (retval)
{
- for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
- {
- fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
-
- while (!retval[0] || retval[strlen (retval) - 1] != '\n')
- {
- retval = fgets (string, STRING_SIZE, source_file);
- if (!retval)
- break;
- fputs (retval, gcov_file);
- }
- }
+ for (; (retval = read_line (source_file)); line_num++)
+ fprintf (gcov_file, "%9s:%5u:%s\n", "-", line_num, retval);
}
if (source_file)