X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgcov.c;h=1c1403d927ddd4cc14dee5afdef22da8ef58e3dc;hb=cbbd336d40408f2034d63036fa0bf7c5d900d84c;hp=f95334a4319fcc2a287b80d6febad360794d344e;hpb=8b33208773a7a837a7d9ff7d2861cf4ab9d655cc;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/gcov.c b/gcc/gcov.c index f95334a4319..1c1403d927d 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -1,14 +1,15 @@ /* 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 Free Software Foundation, Inc. + Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by James E. Wilson of Cygnus Support. Mangled by Bob Manson of Cygnus Support. Mangled further by Nathan Sidwell Gcov 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 Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. Gcov is distributed in the hope that it will be useful, @@ -17,9 +18,8 @@ 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 -along with Gcov; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +along with Gcov; see the file COPYING3. If not see +. */ /* ??? Print a list of the ten blocks with the highest execution counts, and list the line numbers corresponding to those blocks. Also, perhaps @@ -29,15 +29,6 @@ Boston, MA 02111-1307, USA. */ /* ??? Should have an option to print the number of basic blocks, and the percent of them that are covered. */ -/* ??? Does not correctly handle the case where two .bb files refer to - the same included source file. For example, if one has a short - file containing only inline functions, which is then included in - two other files, then there will be two .bb files which refer to - the include file, but there is no way to get the total execution - counts for the included file, can only get execution counts for one - or the other of the including files. this can be fixed by --ratios - --long-file-names --preserve-paths and perl. */ - /* Need an option to show individual block counts, and show probabilities of fall through arcs. */ @@ -47,7 +38,6 @@ Boston, MA 02111-1307, USA. */ #include "tm.h" #include "intl.h" #include "version.h" -#undef abort #include @@ -55,7 +45,7 @@ Boston, MA 02111-1307, USA. */ #include "gcov-io.h" #include "gcov-io.c" -/* The bbg file is generated by -ftest-coverage option. The da file is +/* The gcno file is generated by -ftest-coverage option. The gcda file is generated by a program compiled with -fprofile-arcs. Their formats are documented in gcov-io.h. */ @@ -93,7 +83,7 @@ typedef struct arc_info /* Arc is for a function that abnormally returns. */ unsigned int is_call_non_return : 1; - /* Arc is for catch/setjump. */ + /* Arc is for catch/setjmp. */ unsigned int is_nonlocal_return : 1; /* Is an unconditional branch. */ @@ -235,6 +225,7 @@ typedef struct source_info /* Name of source file. */ char *name; unsigned index; + time_t file_time; /* Array of line information. */ line_t *lines; @@ -254,10 +245,15 @@ typedef struct source_info static function_t *functions; -/* This points to the head of the sourcefile structure list. */ +/* This points to the head of the sourcefile structure list. New elements + are always prepended. */ static source_t *sources; +/* Next index for a source file. */ + +static unsigned source_index; + /* This holds data summary information. */ static struct gcov_summary object_summary; @@ -278,6 +274,17 @@ static unsigned bbg_stamp; static char *da_file_name; +/* Data file is missing. */ + +static int no_data_file; + +/* If there is several input files, compute and display results after + reading all data files. This way if two or more gcda file refer to + the same source file (eg inline subprograms in a .h file), the + counts are added. */ + +static int multiple_files = 0; + /* Output branch probabilities. */ static int flag_branches = 0; @@ -327,6 +334,7 @@ static int process_args (int, char **); static void print_usage (int) ATTRIBUTE_NORETURN; static void print_version (void) ATTRIBUTE_NORETURN; static void process_file (const char *); +static void generate_results (const char *); static void create_file_names (const char *); static source_t *find_source (const char *); static int read_graph_file (void); @@ -348,42 +356,40 @@ main (int argc, char **argv) { int argno; + /* Unlock the stdio streams. */ + unlock_std_streams (); + gcc_init_libintl (); + /* Handle response files. */ + expandargv (&argc, &argv); + argno = process_args (argc, argv); if (optind == argc) print_usage (true); + if (argc - argno > 1) + multiple_files = 1; + for (; argno != argc; argno++) - { - release_structures (); + process_file (argv[argno]); - process_file (argv[argno]); - } + generate_results (multiple_files ? NULL : argv[argc - 1]); + + release_structures (); return 0; } static void -fnotice (FILE *file, const char *msgid, ...) +fnotice (FILE *file, const char *cmsgid, ...) { va_list ap; - va_start (ap, msgid); - vfprintf (file, _(msgid), ap); + va_start (ap, cmsgid); + vfprintf (file, _(cmsgid), ap); va_end (ap); } - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ -extern void fancy_abort (void) ATTRIBUTE_NORETURN; - -void -fancy_abort (void) -{ - fnotice (stderr, "Internal gcov abort.\n"); - exit (FATAL_EXIT_CODE); -} /* Print a usage message and exit. If ERROR_P is nonzero, this is an error, otherwise the output of --help. */ @@ -394,7 +400,7 @@ print_usage (int error_p) FILE *file = error_p ? stderr : stdout; int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE; - fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE\n\n"); + fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE...\n\n"); fnotice (file, "Print code coverage information.\n\n"); fnotice (file, " -h, --help Print this help, then exit\n"); fnotice (file, " -v, --version Print version number, then exit\n"); @@ -419,12 +425,13 @@ print_usage (int error_p) static void print_version (void) { - fnotice (stdout, "gcov (GCC) %s\n", version_string); - fnotice (stdout, "Copyright (C) 2003 Free Software Foundation, Inc.\n"); + fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string); + fprintf (stdout, "Copyright %s 2010 Free Software Foundation, Inc.\n", + _("(C)")); fnotice (stdout, - "This is free software; see the source for copying conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or \n" - "FITNESS FOR A PARTICULAR PURPOSE.\n\n"); + _("This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or \n" + "FITNESS FOR A PARTICULAR PURPOSE.\n\n")); exit (SUCCESS_EXIT_CODE); } @@ -503,8 +510,14 @@ process_args (int argc, char **argv) static void process_file (const char *file_name) { - source_t *src; function_t *fn; + function_t *fn_p; + function_t *old_functions; + + /* Save and clear the list of current functions. They will be appended + later. */ + old_functions = functions; + functions = NULL; create_file_names (file_name); if (read_graph_file ()) @@ -519,10 +532,21 @@ process_file (const char *file_name) if (read_count_file ()) return; - for (fn = functions; fn; fn = fn->next) + for (fn_p = NULL, fn = functions; fn; fn_p = fn, fn = fn->next) solve_flow_graph (fn); + + if (fn_p) + fn_p->next = old_functions; +} + +static void +generate_results (const char *file_name) +{ + source_t *src; + function_t *fn; + for (src = sources; src; src = src->next) - src->lines = xcalloc (src->num_lines, sizeof (line_t)); + src->lines = XCNEWVEC (line_t, src->num_lines); for (fn = functions; fn; fn = fn->next) { coverage_t coverage; @@ -548,16 +572,16 @@ process_file (const char *file_name) if (gcov_file) { - fnotice (stdout, "%s:creating `%s'\n", + fnotice (stdout, "%s:creating '%s'\n", src->name, gcov_file_name); output_lines (gcov_file, src); if (ferror (gcov_file)) - fnotice (stderr, "%s:error writing output file `%s'\n", + fnotice (stderr, "%s:error writing output file '%s'\n", src->name, gcov_file_name); fclose (gcov_file); } else - fnotice (stderr, "%s:could not open output file `%s'\n", + fnotice (stderr, "%s:could not open output file '%s'\n", src->name, gcov_file_name); free (gcov_file_name); } @@ -573,12 +597,6 @@ release_structures (void) function_t *fn; source_t *src; - free (bbg_file_name); - free (da_file_name); - da_file_name = bbg_file_name = NULL; - bbg_file_time = 0; - bbg_stamp = 0; - while ((src = sources)) { sources = src->next; @@ -624,22 +642,31 @@ create_file_names (const char *file_name) int length = strlen (file_name); int base; + /* Free previous file names. */ + if (bbg_file_name) + free (bbg_file_name); + if (da_file_name) + free (da_file_name); + da_file_name = bbg_file_name = NULL; + bbg_file_time = 0; + bbg_stamp = 0; + if (object_directory && object_directory[0]) { struct stat status; length += strlen (object_directory) + 2; - name = xmalloc (length); + name = XNEWVEC (char, length); name[0] = 0; base = !stat (object_directory, &status) && S_ISDIR (status.st_mode); strcat (name, object_directory); - if (base && name[strlen (name) - 1] != '/') + if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1]))) strcat (name, "/"); } else { - name = xmalloc (length + 1); + name = XNEWVEC (char, length + 1); name[0] = 0; base = 1; } @@ -647,8 +674,8 @@ create_file_names (const char *file_name) if (base) { /* Append source file name. */ - cptr = strrchr (file_name, '/'); - strcat (name, cptr ? cptr + 1 : file_name); + const char *cptr = lbasename (file_name); + strcat (name, cptr ? cptr : file_name); } /* Remove the extension. */ @@ -657,15 +684,16 @@ create_file_names (const char *file_name) *cptr = 0; length = strlen (name); - - bbg_file_name = xmalloc (length + strlen (GCOV_NOTE_SUFFIX) + 1); + + bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1); strcpy (bbg_file_name, name); strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX); - da_file_name = xmalloc (length + strlen (GCOV_DATA_SUFFIX) + 1); + da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1); strcpy (da_file_name, name); strcpy (da_file_name + length, GCOV_DATA_SUFFIX); + free (name); return; } @@ -676,20 +704,42 @@ static source_t * find_source (const char *file_name) { source_t *src; + struct stat status; if (!file_name) file_name = ""; for (src = sources; src; src = src->next) if (!strcmp (file_name, src->name)) - return src; + break; - src = xcalloc (1, sizeof (source_t)); - src->name = xstrdup (file_name); - src->coverage.name = src->name; - src->index = sources ? sources->index + 1 : 1; - src->next = sources; - sources = src; + if (!src) + { + src = XCNEW (source_t); + src->name = xstrdup (file_name); + src->coverage.name = src->name; + src->index = source_index++; + src->next = sources; + sources = src; + + if (!stat (file_name, &status)) + src->file_time = status.st_mtime; + } + + if (src->file_time > bbg_file_time) + { + static int info_emitted; + + fnotice (stderr, "%s:source file is newer than graph file '%s'\n", + src->name, bbg_file_name); + if (!info_emitted) + { + fnotice (stderr, + "(the message is only displayed one per source file)\n"); + info_emitted = 1; + } + src->file_time = 0; + } return src; } @@ -702,6 +752,7 @@ read_graph_file (void) unsigned version; unsigned current_tag = 0; struct function_info *fn = NULL; + function_t *old_functions_head = functions; source_t *src = NULL; unsigned ix; unsigned tag; @@ -727,7 +778,7 @@ read_graph_file (void) GCOV_UNSIGNED2STRING (v, version); GCOV_UNSIGNED2STRING (e, GCOV_VERSION); - fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n", + fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n", bbg_file_name, v, e); } bbg_stamp = gcov_read_unsigned (); @@ -750,7 +801,7 @@ read_graph_file (void) src = find_source (gcov_read_string ()); lineno = gcov_read_unsigned (); - fn = xcalloc (1, sizeof (function_t)); + fn = XCNEW (function_t); fn->name = function_name; fn->ident = ident; fn->checksum = checksum; @@ -779,14 +830,14 @@ read_graph_file (void) else if (fn && tag == GCOV_TAG_BLOCKS) { if (fn->blocks) - fnotice (stderr, "%s:already seen blocks for `%s'\n", + fnotice (stderr, "%s:already seen blocks for '%s'\n", bbg_file_name, fn->name); else { unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length); fn->num_blocks = num_blocks; - fn->blocks = xcalloc (fn->num_blocks, sizeof (block_t)); + fn->blocks = XCNEWVEC (block_t, fn->num_blocks); for (ix = 0; ix != num_blocks; ix++) fn->blocks[ix].flags = gcov_read_unsigned (); } @@ -807,7 +858,7 @@ read_graph_file (void) if (dest >= fn->num_blocks) goto corrupt; - arc = xcalloc (1, sizeof (arc_t)); + arc = XCNEW (arc_t); arc->dst = &fn->blocks[dest]; arc->src = &fn->blocks[src]; @@ -852,7 +903,7 @@ read_graph_file (void) else if (fn && tag == GCOV_TAG_LINES) { unsigned blockno = gcov_read_unsigned (); - unsigned *line_nos = xcalloc (length - 1, sizeof (unsigned)); + unsigned *line_nos = XCNEWVEC (unsigned, length - 1); if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding) goto corrupt; @@ -895,14 +946,12 @@ read_graph_file (void) } gcov_sync (base, length); if (gcov_is_error ()) - break; - } - if (!gcov_is_eof ()) - { - corrupt:; - fnotice (stderr, "%s:corrupted\n", bbg_file_name); - gcov_close (); - return 1; + { + corrupt:; + fnotice (stderr, "%s:corrupted\n", bbg_file_name); + gcov_close (); + return 1; + } } gcov_close (); @@ -925,7 +974,9 @@ read_graph_file (void) { function_t *fn, *fn_p, *fn_n; - for (fn_p = NULL, fn = functions; fn; fn_p = fn, fn = fn_n) + for (fn_p = old_functions_head, fn = functions; + fn != old_functions_head; + fn_p = fn, fn = fn_n) { unsigned ix; @@ -973,8 +1024,10 @@ read_count_file (void) if (!gcov_open (da_file_name, 1)) { - fnotice (stderr, "%s:cannot open data file\n", da_file_name); - return 1; + fnotice (stderr, "%s:cannot open data file, assuming not executed\n", + da_file_name); + no_data_file = 1; + return 0; } if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) { @@ -990,8 +1043,8 @@ read_count_file (void) GCOV_UNSIGNED2STRING (v, version); GCOV_UNSIGNED2STRING (e, GCOV_VERSION); - - fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n", + + fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n", da_file_name, v, e); } tag = gcov_read_unsigned (); @@ -1012,31 +1065,36 @@ read_count_file (void) program_count++; else if (tag == GCOV_TAG_FUNCTION) { - unsigned ident = gcov_read_unsigned (); - struct function_info *fn_n = functions; + { + unsigned ident = gcov_read_unsigned (); + struct function_info *fn_n = functions; - for (fn = fn ? fn->next : NULL; ; fn = fn->next) - { - if (fn) - ; - else if ((fn = fn_n)) - fn_n = NULL; - else - { - fnotice (stderr, "%s:unknown function `%u'\n", - da_file_name, ident); + /* Try to find the function in the list. + To speed up the search, first start from the last function + found. */ + for (fn = fn ? fn->next : NULL; ; fn = fn->next) + { + if (fn) + ; + else if ((fn = fn_n)) + fn_n = NULL; + else + { + fnotice (stderr, "%s:unknown function '%u'\n", + da_file_name, ident); + break; + } + if (fn->ident == ident) break; - } - if (fn->ident == ident) - break; - } + } + } if (!fn) ; else if (gcov_read_unsigned () != fn->checksum) { mismatch:; - fnotice (stderr, "%s:profile mismatch for `%s'\n", + fnotice (stderr, "%s:profile mismatch for '%s'\n", da_file_name, fn->name); goto cleanup; } @@ -1047,21 +1105,18 @@ read_count_file (void) goto mismatch; if (!fn->counts) - fn->counts = xcalloc (fn->num_counts, sizeof (gcov_type)); + fn->counts = XCNEWVEC (gcov_type, fn->num_counts); for (ix = 0; ix != fn->num_counts; ix++) fn->counts[ix] += gcov_read_counter (); } gcov_sync (base, length); if ((error = gcov_is_error ())) - break; - } - - if (!gcov_is_eof ()) - { - fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n", - da_file_name); - goto cleanup; + { + fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n", + da_file_name); + goto cleanup; + } } gcov_close (); @@ -1082,12 +1137,12 @@ solve_flow_graph (function_t *fn) block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */ if (fn->num_blocks < 2) - fnotice (stderr, "%s:`%s' lacks entry and/or exit blocks\n", + fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n", bbg_file_name, fn->name); else { if (fn->blocks[0].num_pred) - fnotice (stderr, "%s:`%s' has arcs to entry block\n", + fnotice (stderr, "%s:'%s' has arcs to entry block\n", bbg_file_name, fn->name); else /* We can't deduce the entry block counts from the lack of @@ -1095,7 +1150,7 @@ solve_flow_graph (function_t *fn) fn->blocks[0].num_pred = ~(unsigned)0; if (fn->blocks[fn->num_blocks - 1].num_succ) - fnotice (stderr, "%s:`%s' has arcs from exit block\n", + fnotice (stderr, "%s:'%s' has arcs from exit block\n", bbg_file_name, fn->name); else /* Likewise, we can't deduce exit block counts from the lack @@ -1303,7 +1358,7 @@ solve_flow_graph (function_t *fn) for (ix = 0; ix < fn->num_blocks; ix++) if (!fn->blocks[ix].count_valid) { - fnotice (stderr, "%s:graph is unsolvable for `%s'\n", + fnotice (stderr, "%s:graph is unsolvable for '%s'\n", bbg_file_name, fn->name); break; } @@ -1383,14 +1438,14 @@ format_gcov (gcov_type top, gcov_type bottom, int dp) static void function_summary (const coverage_t *coverage, const char *title) { - fnotice (stdout, "%s `%s'\n", title, coverage->name); + fnotice (stdout, "%s '%s'\n", title, coverage->name); if (coverage->lines) fnotice (stdout, "Lines executed:%s of %d\n", format_gcov (coverage->lines_executed, coverage->lines, 2), coverage->lines); else - fnotice (stdout, "No executable lines"); + fnotice (stdout, "No executable lines\n"); if (flag_branches) { @@ -1429,52 +1484,71 @@ function_summary (const coverage_t *coverage, const char *title) static char * make_gcov_file_name (const char *input_name, const char *src_name) { - char *cptr; - char *name = xmalloc (strlen (src_name) + strlen (input_name) + 10); + const char *cptr; + char *name; - name[0] = 0; - if (flag_long_names && strcmp (src_name, input_name)) + if (flag_long_names && input_name && strcmp (src_name, input_name)) { + name = XNEWVEC (char, strlen (src_name) + strlen (input_name) + 10); + name[0] = 0; /* Generate the input filename part. */ - cptr = flag_preserve_paths ? NULL : strrchr (input_name, '/'); - strcat (name, cptr ? cptr + 1 : input_name); + cptr = flag_preserve_paths ? NULL : lbasename (input_name); + strcat (name, cptr ? cptr : input_name); strcat (name, "##"); } + else + { + name = XNEWVEC (char, strlen (src_name) + 10); + name[0] = 0; + } /* Generate the source filename part. */ - cptr = flag_preserve_paths ? NULL : strrchr (src_name, '/'); - strcat (name, cptr ? cptr + 1 : src_name); + + cptr = flag_preserve_paths ? NULL : lbasename (src_name); + strcat (name, cptr ? cptr : src_name); if (flag_preserve_paths) { - /* Convert '/' to '#', remove '/./', convert '/../' to '/^/' */ - char *prev; + /* Convert '/' and '\' to '#', remove '/./', convert '/../' to '/^/', + convert ':' to '~' on DOS based file system. */ + char *pnew = name, *pold = name; - for (cptr = name; (cptr = strchr ((prev = cptr), '/'));) - { - unsigned shift = 0; + /* First check for leading drive separator. */ - if (prev + 1 == cptr && prev[0] == '.') + while (*pold != '\0') + { + if (*pold == '/' || *pold == '\\') { - /* Remove '.' */ - shift = 2; + *pnew++ = '#'; + pold++; } - else if (prev + 2 == cptr && prev[0] == '.' && prev[1] == '.') +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + else if (*pold == ':') { - /* Convert '..' */ - shift = 1; - prev[1] = '^'; + *pnew++ = '~'; + pold++; } - else - *cptr++ = '#'; - if (shift) +#endif + else if ((*pold == '/' && strstr (pold, "/./") == pold) + || (*pold == '\\' && strstr (pold, "\\.\\") == pold)) + pold += 3; + else if (*pold == '/' && strstr (pold, "/../") == pold) + { + strcpy (pnew, "/^/"); + pnew += 3; + pold += 4; + } + else if (*pold == '\\' && strstr (pold, "\\..\\") == pold) { - cptr = prev; - do - prev[0] = prev[shift]; - while (*prev++); + strcpy (pnew, "\\^\\"); + pnew += 3; + pold += 4; } + else + *pnew++ = *pold++; } + + *pnew = '\0'; } strcat (name, ".gcov"); @@ -1553,7 +1627,7 @@ add_line_counts (coverage_t *coverage, function_t *fn) } } if (!line) - fnotice (stderr, "%s:no lines for `%s'\n", bbg_file_name, fn->name); + fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name); } /* Accumulate the line counts of a file. */ @@ -1737,7 +1811,7 @@ accumulate_line_counts (source_t *src) } } -/* Ouput information about ARC number IX. Returns nonzero if +/* Output information about ARC number IX. Returns nonzero if anything is output. */ static int @@ -1790,13 +1864,17 @@ output_lines (FILE *gcov_file, const source_t *src) const line_t *line; /* current line info ptr. */ char string[STRING_SIZE]; /* line buffer. */ char const *retval = ""; /* status of source file reading. */ - function_t *fn = src->functions; + function_t *fn = NULL; fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name); - fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name); - fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0, da_file_name); - fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, - object_summary.ctrs[GCOV_COUNTER_ARCS].runs); + if (!multiple_files) + { + fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name); + fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0, + no_data_file ? "-" : da_file_name); + fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, + object_summary.ctrs[GCOV_COUNTER_ARCS].runs); + } fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count); source_file = fopen (src->name, "r"); @@ -1805,19 +1883,11 @@ output_lines (FILE *gcov_file, const source_t *src) fnotice (stderr, "%s:cannot open source file\n", src->name); retval = NULL; } - else - { - struct stat status; + else if (src->file_time == 0) + fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0); - if (!fstat (fileno (source_file), &status) - && status.st_mtime > bbg_file_time) - { - fnotice (stderr, "%s:source file is newer than graph file `%s'\n", - src->name, bbg_file_name); - fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", - "-", 0); - } - } + if (flag_branches) + fn = src->functions; for (line_num = 1, line = &src->lines[line_num]; line_num < src->num_lines; line_num++, line++)