From patchwork Sun Nov 13 10:30:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 125386 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id AA51EB71FB for ; Sun, 13 Nov 2011 21:30:34 +1100 (EST) Received: (qmail 547 invoked by alias); 13 Nov 2011 10:30:32 -0000 Received: (qmail 533 invoked by uid 22791); 13 Nov 2011 10:30:30 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-wy0-f175.google.com (HELO mail-wy0-f175.google.com) (74.125.82.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 13 Nov 2011 10:30:12 +0000 Received: by wyg8 with SMTP id 8so638153wyg.20 for ; Sun, 13 Nov 2011 02:30:11 -0800 (PST) Received: by 10.216.154.70 with SMTP id g48mr315437wek.13.1321180210110; Sun, 13 Nov 2011 02:30:10 -0800 (PST) Received: by 10.216.154.70 with SMTP id g48mr315428wek.13.1321180209206; Sun, 13 Nov 2011 02:30:09 -0800 (PST) Received: from [192.168.44.105] ([90.195.200.137]) by mx.google.com with ESMTPS id x9sm20567198wbn.2.2011.11.13.02.30.07 (version=SSLv3 cipher=OTHER); Sun, 13 Nov 2011 02:30:08 -0800 (PST) Message-ID: <4EBF9C2B.6030600@acm.org> Date: Sun, 13 Nov 2011 10:30:03 +0000 From: Nathan Sidwell User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.23) Gecko/20110922 Lightning/1.0b2 Thunderbird/3.1.15 MIME-Version: 1.0 To: GCC Patches Subject: gcov patch, source prefixes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org I've committed this patch to gcov, to add two new options. *) a --source-prefix (-s) option, which allows you to specify a source path prefix that you want eliding from source file names. You'd usually use this if you're building in a separate directory. *) a --relative-only (-r) option, which will elide information for source files with an absolute path (after detecting any source prefix). Usually absolute paths are system include files, and coverage of any inline functions they contain is uninteresting. tested on i686-pc-linux-gnu. nathan 2011-11-13 Nathan Sidwell * 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. Index: doc/gcov.texi =================================================================== --- doc/gcov.texi (revision 181309) +++ doc/gcov.texi (working copy) @@ -124,13 +124,16 @@ gcov [@option{-v}|@option{--version}] [@ [@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 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. Index: gcov.c =================================================================== --- gcov.c (revision 181309) +++ gcov.c (working copy) @@ -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 sou 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 sou 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)