gcov.c (source_prefix, [...]): New globals.

* gcov.c (source_prefix, source_length): New globals.
	(flag_relative_only): Likewise.
	(print_usage, options, process_args): Update.
	(generate_results): Use coverage.name, check
	flag_relative_only. Adjust messages.
	(find_source): Check source_prefix.
	(output_lines): Use coverage.name, adjust messages.
	* doc/gcov.texi (Invoking Gcov): Document new options.

From-SVN: r181335
This commit is contained in:
Nathan Sidwell 2011-11-13 10:26:23 +00:00 committed by Nathan Sidwell
parent 2c6f792709
commit 1bec9caacb
3 changed files with 88 additions and 13 deletions

View File

@ -1,3 +1,14 @@
2011-11-13 Nathan Sidwell <nathan@acm.org>
* gcov.c (source_prefix, source_length): New globals.
(flag_relative_only): Likewise.
(print_usage, options, process_args): Update.
(generate_results): Use coverage.name, check
flag_relative_only. Adjust messages.
(find_source): Check source_prefix.
(output_lines): Use coverage.name, adjust messages.
* doc/gcov.texi (Invoking Gcov): Document new options.
2011-11-12 Jason Merrill <jason@redhat.com>
PR c++/51060

View File

@ -124,13 +124,16 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
[@option{-a}|@option{--all-blocks}]
[@option{-b}|@option{--branch-probabilities}]
[@option{-c}|@option{--branch-counts}]
[@option{-u}|@option{--unconditional-branches}]
[@option{-n}|@option{--no-output}]
[@option{-l}|@option{--long-file-names}]
[@option{-p}|@option{--preserve-paths}]
[@option{-r}|@option{--relative-only}]
[@option{-f}|@option{--function-summaries}]
[@option{-o}|@option{--object-directory} @var{directory|file}] @var{sourcefiles}
[@option{-u}|@option{--unconditional-branches}]
[@option{-o}|@option{--object-directory} @var{directory|file}]
[@option{-s}|@option{--source-prefix} @var{directory}]
[@option{-d}|@option{--display-progress}]
@var{files}
@c man end
@c man begin SEEALSO
gpl(7), gfdl(7), fsf-funding(7), gcc(1) and the Info entry for @file{gcc}.
@ -193,6 +196,13 @@ removed and unremoveable @file{..}
components renamed to @samp{^}. This is useful if sourcefiles are in several
different directories.
@item -r
@itemx --relative-only
Only output information about source files with a relative pathname
(after source prefix elision). Absolute paths are usually system
header files and coverage of any inline functions therein is normally
uninteresting.
@item -f
@itemx --function-summaries
Output summaries for each function in addition to the file level summary.
@ -207,6 +217,14 @@ is specified, the data files are in that directory and named after the
input file name, without its extension. If a file is specified here,
the data files are named after that file, without its extension.
@item -s @var{directory}
@itemx --source-prefix @var{directory}
A prefix for source file names to remove when generating the output
coverage files. This option is useful when building in a separate
directory, and the pathname to the source directory is not wanted when
determining the output file names. Note that this prefix detection is
applied before determining whether the source file is absolute.
@item -u
@itemx --unconditional-branches
When branch probabilities are given, include those of unconditional branches.

View File

@ -333,6 +333,17 @@ static int flag_function_summary = 0;
static char *object_directory = 0;
/* Source directory prefix. This is removed from source pathnames
that match, when generating the output file name. */
static char *source_prefix = 0;
static size_t source_length = 0;
/* Only show data for sources with relative pathnames. Absolute ones
usually indicate a system header file, which although it may
contain inline functions, is usually uninteresting. */
static int flag_relative_only = 0;
/* Preserve all pathname components. Needed when object files and
source files are in subdirectories. '/' is mangled as '#', '.' is
elided and '..' mangled to '^'. */
@ -441,6 +452,8 @@ print_usage (int error_p)
source files\n");
fnotice (file, " -f, --function-summaries Output summaries for each function\n");
fnotice (file, " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
fnotice (file, " -s, --source-prefix DIR Source prefix to elide\n");
fnotice (file, " -r, --relative-only Only show data for relative sources\n");
fnotice (file, " -p, --preserve-paths Preserve all pathname components\n");
fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
fnotice (file, " -d, --display-progress Display progress information\n");
@ -475,8 +488,10 @@ static const struct option options[] =
{ "long-file-names", no_argument, NULL, 'l' },
{ "function-summaries", no_argument, NULL, 'f' },
{ "preserve-paths", no_argument, NULL, 'p' },
{ "relative-only", no_argument, NULL, 'r' },
{ "object-directory", required_argument, NULL, 'o' },
{ "object-file", required_argument, NULL, 'o' },
{ "source-prefix", required_argument, NULL, 's' },
{ "unconditional-branches", no_argument, NULL, 'u' },
{ "display-progress", no_argument, NULL, 'd' },
{ 0, 0, 0, 0 }
@ -489,7 +504,7 @@ process_args (int argc, char **argv)
{
int opt;
while ((opt = getopt_long (argc, argv, "abcdfhlno:puv", options, NULL)) != -1)
while ((opt = getopt_long (argc, argv, "abcdfhlno:s:pruv", options, NULL)) != -1)
{
switch (opt)
{
@ -517,6 +532,13 @@ process_args (int argc, char **argv)
case 'o':
object_directory = optarg;
break;
case 's':
source_prefix = optarg;
source_length = strlen (source_prefix);
break;
case 'r':
flag_relative_only = 1;
break;
case 'p':
flag_preserve_paths = 1;
break;
@ -641,33 +663,47 @@ generate_results (const char *file_name)
name_map_t *name_map = (name_map_t *)bsearch
(file_name, names, n_names, sizeof (*names), name_search);
if (name_map)
file_name = sources[name_map->src].name;
file_name = sources[name_map->src].coverage.name;
else
file_name = canonicalize_name (file_name);
}
for (ix = n_sources, src = sources; ix--; src++)
{
if (flag_relative_only)
{
/* Ignore this source, if it is an absolute path (after
source prefix removal). */
char first = src->coverage.name[0];
#if HAVE_DOS_BASED_FILE_SYSTEM
if (first && src->coverage.name[1] == ':')
first = src->coverage.name[2]
#endif
if (IS_DIR_SEPARATOR (first))
continue;
}
accumulate_line_counts (src);
function_summary (&src->coverage, "File");
if (flag_gcov_file && src->coverage.lines)
{
char *gcov_file_name = make_gcov_file_name (file_name, src->name);
char *gcov_file_name
= make_gcov_file_name (file_name, src->coverage.name);
FILE *gcov_file = fopen (gcov_file_name, "w");
if (gcov_file)
{
fnotice (stdout, "%s:creating '%s'\n",
src->name, gcov_file_name);
fnotice (stdout, "Creating '%s'\n", gcov_file_name);
output_lines (gcov_file, src);
if (ferror (gcov_file))
fnotice (stderr, "%s:error writing output file '%s'\n",
src->name, gcov_file_name);
fnotice (stderr, "Error writing output file '%s'\n",
gcov_file_name);
fclose (gcov_file);
}
else
fnotice (stderr, "%s:could not open output file '%s'\n",
src->name, gcov_file_name);
fnotice (stderr, "Could not open output file '%s'\n",
gcov_file_name);
free (gcov_file_name);
}
fnotice (stdout, "\n");
@ -877,6 +913,16 @@ find_source (const char *file_name)
memset (src, 0, sizeof (*src));
src->name = canon;
src->coverage.name = src->name;
if (source_length
#if HAVE_DOS_BASED_FILE_SYSTEM
/* You lose if separators don't match exactly in the
prefix. */
&& !strncasecmp (source_prefix, src->coverage.name, source_length)
#else
&& !strncmp (source_prefix, src->coverage.name, source_length)
#endif
&& IS_DIR_SEPARATOR (src->coverage.name[source_length]))
src->coverage.name += source_length + 1;
if (!stat (src->name, &status))
src->file_time = status.st_mtime;
}
@ -2079,7 +2125,7 @@ output_lines (FILE *gcov_file, const source_t *src)
char const *retval = ""; /* status of source file reading. */
function_t *fn = NULL;
fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
if (!multiple_files)
{
fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
@ -2092,7 +2138,7 @@ output_lines (FILE *gcov_file, const source_t *src)
source_file = fopen (src->name, "r");
if (!source_file)
{
fnotice (stderr, "%s:cannot open source file\n", src->name);
fnotice (stderr, "Cannot open source file %s\n", src->name);
retval = NULL;
}
else if (src->file_time == 0)