+ It appends the '.gcov' extension to the *basename* of the file.
+ The resulting file name will be in PWD.
+
+ e.g.,
+ input: foo.da, output: foo.da.gcov
+ input: a/b/foo.cc, output: foo.cc.gcov */
+
+static char *
+get_gcov_intermediate_filename (const char *file_name)
+{
+ const char *gcov = ".gcov";
+ char *result;
+ const char *cptr;
+
+ /* Find the 'basename'. */
+ cptr = lbasename (file_name);
+
+ result = XNEWVEC (char, strlen (cptr) + strlen (gcov) + 1);
+ sprintf (result, "%s%s", cptr, gcov);
+
+ return result;
+}
+
+/* Output the result in intermediate format used by 'lcov'.
+
+The intermediate format contains a single file named 'foo.cc.gcov',
+with no source code included. A sample output is
+
+file:foo.cc
+function:5,1,_Z3foov
+function:13,1,main
+function:19,1,_GLOBAL__sub_I__Z3foov
+function:19,1,_Z41__static_initialization_and_destruction_0ii
+lcount:5,1
+lcount:7,9
+lcount:9,8
+lcount:11,1
+file:/.../iostream
+lcount:74,1
+file:/.../basic_ios.h
+file:/.../ostream
+file:/.../ios_base.h
+function:157,0,_ZStorSt12_Ios_IostateS_
+lcount:157,0
+file:/.../char_traits.h
+function:258,0,_ZNSt11char_traitsIcE6lengthEPKc
+lcount:258,0
+...
+
+The default gcov outputs multiple files: 'foo.cc.gcov',
+'iostream.gcov', 'ios_base.h.gcov', etc. with source code
+included. Instead the intermediate format here outputs only a single
+file 'foo.cc.gcov' similar to the above example. */
+
+static void
+output_intermediate_file (FILE *gcov_file, source_t *src)
+{
+ unsigned line_num; /* current line number. */
+ const line_t *line; /* current line info ptr. */
+ function_t *fn; /* current function info ptr. */
+
+ fprintf (gcov_file, "file:%s\n", src->name); /* source file name */
+
+ for (fn = src->functions; fn; fn = fn->line_next)
+ {
+ /* function:<name>,<line_number>,<execution_count> */
+ fprintf (gcov_file, "function:%d,%s,%s\n", fn->line,
+ format_gcov (fn->blocks[0].count, 0, -1),
+ flag_demangled_names ? fn->demangled_name : fn->name);
+ }
+
+ for (line_num = 1, line = &src->lines[line_num];
+ line_num < src->num_lines;
+ line_num++, line++)
+ {
+ arc_t *arc;
+ if (line->exists)
+ fprintf (gcov_file, "lcount:%u,%s\n", line_num,
+ format_gcov (line->count, 0, -1));
+ if (flag_branches)
+ for (arc = line->u.branches; arc; arc = arc->line_next)
+ {
+ if (!arc->is_unconditional && !arc->is_call_non_return)
+ {
+ const char *branch_type;
+ /* branch:<line_num>,<branch_coverage_type>
+ branch_coverage_type
+ : notexec (Branch not executed)
+ : taken (Branch executed and taken)
+ : nottaken (Branch executed, but not taken)
+ */
+ if (arc->src->count)
+ branch_type = (arc->count > 0) ? "taken" : "nottaken";
+ else
+ branch_type = "notexec";
+ fprintf (gcov_file, "branch:%d,%s\n", line_num, branch_type);
+ }
+ }
+ }