/* Gcov.c: prepend line execution counts and branch probabilities to a
   source file.
   Copyright (C) 1990-2023 Free Software Foundation, Inc.
   Contributed by James E. Wilson of Cygnus Support.
   Mangled by Bob Manson of Cygnus Support.
   Mangled further by Nathan Sidwell <nathan@codesourcery.com>

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 3, or (at your option)
any later version.

Gcov is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
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 COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* ??? Print a list of the ten blocks with the highest execution counts,
   and list the line numbers corresponding to those blocks.  Also, perhaps
   list the line numbers with the highest execution counts, only printing
   the first if there are several which are all listed in the same block.  */

/* ??? Should have an option to print the number of basic blocks, and the
   percent of them that are covered.  */

/* Need an option to show individual block counts, and show
   probabilities of fall through arcs.  */

#include "config.h"
#define INCLUDE_ALGORITHM
#define INCLUDE_VECTOR
#define INCLUDE_STRING
#define INCLUDE_MAP
#define INCLUDE_SET
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "intl.h"
#include "diagnostic.h"
#include "version.h"
#include "demangle.h"
#include "color-macros.h"
#include "pretty-print.h"
#include "json.h"

#include <zlib.h>
#include <getopt.h>

#include "md5.h"

using namespace std;

#define IN_GCOV 1
#include "gcov-io.h"
#include "gcov-io.cc"

#define GCOV_JSON_FORMAT_VERSION "2"

/* 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.  */

/* The functions in this file for creating and solution program flow graphs
   are very similar to functions in the gcc source file profile.cc.  In
   some places we make use of the knowledge of how profile.cc works to
   select particular algorithms here.  */

/* The code validates that the profile information read in corresponds
   to the code currently being compiled.  Rather than checking for
   identical files, the code below compares a checksum on the CFG
   (based on the order of basic blocks and the arcs in the CFG).  If
   the CFG checksum in the gcda file match the CFG checksum in the
   gcno file, the profile data will be used.  */

/* This is the size of the buffer used to read in source file lines.  */

class function_info;
class block_info;
class source_info;

/* Describes an arc between two basic blocks.  */

struct arc_info
{
  /* source and destination blocks.  */
  class block_info *src;
  class block_info *dst;

  /* transition counts.  */
  gcov_type count;
  /* used in cycle search, so that we do not clobber original counts.  */
  gcov_type cs_count;

  unsigned int count_valid : 1;
  unsigned int on_tree : 1;
  unsigned int fake : 1;
  unsigned int fall_through : 1;

  /* Arc to a catch handler.  */
  unsigned int is_throw : 1;

  /* Arc is for a function that abnormally returns.  */
  unsigned int is_call_non_return : 1;

  /* Arc is for catch/setjmp.  */
  unsigned int is_nonlocal_return : 1;

  /* Is an unconditional branch.  */
  unsigned int is_unconditional : 1;

  /* Loop making arc.  */
  unsigned int cycle : 1;

  /* Links to next arc on src and dst lists.  */
  struct arc_info *succ_next;
  struct arc_info *pred_next;
};

/* Describes which locations (lines and files) are associated with
   a basic block.  */

class block_location_info
{
public:
  block_location_info (unsigned _source_file_idx):
    source_file_idx (_source_file_idx)
  {}

  unsigned source_file_idx;
  vector<unsigned> lines;
};

/* Describes a basic block. Contains lists of arcs to successor and
   predecessor blocks.  */

class block_info
{
public:
  /* Constructor.  */
  block_info ();

  /* Chain of exit and entry arcs.  */
  arc_info *succ;
  arc_info *pred;

  /* Number of unprocessed exit and entry arcs.  */
  gcov_type num_succ;
  gcov_type num_pred;

  unsigned id;

  /* Block execution count.  */
  gcov_type count;
  unsigned count_valid : 1;
  unsigned valid_chain : 1;
  unsigned invalid_chain : 1;
  unsigned exceptional : 1;

  /* Block is a call instrumenting site.  */
  unsigned is_call_site : 1; /* Does the call.  */
  unsigned is_call_return : 1; /* Is the return.  */

  /* Block is a landing pad for longjmp or throw.  */
  unsigned is_nonlocal_return : 1;

  vector<block_location_info> locations;

  struct
  {
    /* Single line graph cycle workspace.  Used for all-blocks
       mode.  */
    arc_info *arc;
    unsigned ident;
  } cycle; /* Used in all-blocks mode, after blocks are linked onto
	     lines.  */

  /* Temporary chain for solving graph, and for chaining blocks on one
     line.  */
  class block_info *chain;

};

block_info::block_info (): succ (NULL), pred (NULL), num_succ (0), num_pred (0),
  id (0), count (0), count_valid (0), valid_chain (0), invalid_chain (0),
  exceptional (0), is_call_site (0), is_call_return (0), is_nonlocal_return (0),
  locations (), chain (NULL)
{
  cycle.arc = NULL;
}

/* Describes a single line of source.  Contains a chain of basic blocks
   with code on it.  */

class line_info
{
public:
  /* Default constructor.  */
  line_info ();

  /* Return true when NEEDLE is one of basic blocks the line belongs to.  */
  bool has_block (block_info *needle);

  /* Execution count.  */
  gcov_type count;

  /* Branches from blocks that end on this line.  */
  vector<arc_info *> branches;

  /* blocks which start on this line.  Used in all-blocks mode.  */
  vector<block_info *> blocks;

  unsigned exists : 1;
  unsigned unexceptional : 1;
  unsigned has_unexecuted_block : 1;
};

line_info::line_info (): count (0), branches (), blocks (), exists (false),
  unexceptional (0), has_unexecuted_block (0)
{
}

bool
line_info::has_block (block_info *needle)
{
  return std::find (blocks.begin (), blocks.end (), needle) != blocks.end ();
}

/* Output demangled function names.  */

static int flag_demangled_names = 0;

/* Describes a single function. Contains an array of basic blocks.  */

class function_info
{
public:
  function_info ();
  ~function_info ();

  /* Return true when line N belongs to the function in source file SRC_IDX.
     The line must be defined in body of the function, can't be inlined.  */
  bool group_line_p (unsigned n, unsigned src_idx);

  /* Function filter based on function_info::artificial variable.  */

  static inline bool
  is_artificial (function_info *fn)
  {
    return fn->artificial;
  }

  /* Name of function.  */
  char *m_name;
  char *m_demangled_name;
  unsigned ident;
  unsigned lineno_checksum;
  unsigned cfg_checksum;

  /* The graph contains at least one fake incoming edge.  */
  unsigned has_catch : 1;

  /* True when the function is artificial and does not exist
     in a source file.  */
  unsigned artificial : 1;

  /* True when multiple functions start at a line in a source file.  */
  unsigned is_group : 1;

  /* Array of basic blocks.  Like in GCC, the entry block is
     at blocks[0] and the exit block is at blocks[1].  */
#define ENTRY_BLOCK (0)
#define EXIT_BLOCK (1)
  vector<block_info> blocks;
  unsigned blocks_executed;

  /* Raw arc coverage counts.  */
  vector<gcov_type> counts;

  /* First line number.  */
  unsigned start_line;

  /* First line column.  */
  unsigned start_column;

  /* Last line number.  */
  unsigned end_line;

  /* Last line column.  */
  unsigned end_column;

  /* Index of source file where the function is defined.  */
  unsigned src;

  /* Vector of line information (used only for group functions).  */
  vector<line_info> lines;

  /* Next function.  */
  class function_info *next;

  /*  Get demangled name of a function.  The demangled name
      is converted when it is used for the first time.  */
  char *get_demangled_name ()
  {
    if (m_demangled_name == NULL)
      {
	m_demangled_name = cplus_demangle (m_name, DMGL_PARAMS);
	if (!m_demangled_name)
	  m_demangled_name = m_name;
      }

    return m_demangled_name;
  }

  /* Get name of the function based on flag_demangled_names.  */
  char *get_name ()
  {
    return flag_demangled_names ? get_demangled_name () : m_name;
  }

  /* Return number of basic blocks (without entry and exit block).  */
  unsigned get_block_count ()
  {
    return blocks.size () - 2;
  }
};

/* Function info comparer that will sort functions according to starting
   line.  */

struct function_line_start_cmp
{
  inline bool operator() (const function_info *lhs,
			  const function_info *rhs)
    {
      return (lhs->start_line == rhs->start_line
	      ? lhs->start_column < rhs->start_column
	      : lhs->start_line < rhs->start_line);
    }
};

/* Describes coverage of a file or function.  */

struct coverage_info
{
  int lines;
  int lines_executed;

  int branches;
  int branches_executed;
  int branches_taken;

  int calls;
  int calls_executed;

  char *name;
};

/* Describes a file mentioned in the block graph.  Contains an array
   of line info.  */

class source_info
{
public:
  /* Default constructor.  */
  source_info ();

  vector<function_info *> *get_functions_at_location (unsigned line_num) const;

  /* Register a new function.  */
  void add_function (function_info *fn);

  /* Debug the source file.  */
  void debug ();

  /* Index of the source_info in sources vector.  */
  unsigned index;

  /* Canonical name of source file.  */
  char *name;
  time_t file_time;

  /* Vector of line information.  */
  vector<line_info> lines;

  coverage_info coverage;

  /* Maximum line count in the source file.  */
  unsigned int maximum_count;

  /* Functions in this source file.  These are in ascending line
     number order.  */
  vector<function_info *> functions;

  /* Line number to functions map.  */
  vector<vector<function_info *> *> line_to_function_map;
};

source_info::source_info (): index (0), name (NULL), file_time (),
  lines (), coverage (), maximum_count (0), functions ()
{
}

/* Register a new function.  */
void
source_info::add_function (function_info *fn)
{
  functions.push_back (fn);

  if (fn->start_line >= line_to_function_map.size ())
    line_to_function_map.resize (fn->start_line + 1);

  vector<function_info *> **slot = &line_to_function_map[fn->start_line];
  if (*slot == NULL)
    *slot = new vector<function_info *> ();

  (*slot)->push_back (fn);
}

vector<function_info *> *
source_info::get_functions_at_location (unsigned line_num) const
{
  if (line_num >= line_to_function_map.size ())
    return NULL;

  vector<function_info *> *slot = line_to_function_map[line_num];
  if (slot != NULL)
    std::sort (slot->begin (), slot->end (), function_line_start_cmp ());

  return slot;
}

void source_info::debug ()
{
  fprintf (stderr, "source_info: %s\n", name);
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      fprintf (stderr, "  function_info: %s\n", fn->get_name ());
      for (vector<block_info>::iterator bit = fn->blocks.begin ();
	   bit != fn->blocks.end (); bit++)
	{
	  fprintf (stderr, "    block_info id=%d, count=%" PRId64 " \n",
		   bit->id, bit->count);
	}
    }

  for (unsigned lineno = 1; lineno < lines.size (); ++lineno)
    {
      line_info &line = lines[lineno];
      fprintf (stderr, "  line_info=%d, count=%" PRId64 "\n", lineno, line.count);
    }

  fprintf (stderr, "\n");
}

class name_map
{
public:
  name_map ()
  {
  }

  name_map (char *_name, unsigned _src): name (_name), src (_src)
  {
  }

  bool operator== (const name_map &rhs) const
  {
#if HAVE_DOS_BASED_FILE_SYSTEM
    return strcasecmp (this->name, rhs.name) == 0;
#else
    return strcmp (this->name, rhs.name) == 0;
#endif
  }

  bool operator< (const name_map &rhs) const
  {
#if HAVE_DOS_BASED_FILE_SYSTEM
    return strcasecmp (this->name, rhs.name) < 0;
#else
    return strcmp (this->name, rhs.name) < 0;
#endif
  }

  const char *name;  /* Source file name */
  unsigned src;  /* Source file */
};

/* Vector of all functions.  */
static vector<function_info *> functions;

/* Function ident to function_info * map.  */
static map<unsigned, function_info *> ident_to_fn;

/* Vector of source files.  */
static vector<source_info> sources;

/* Mapping of file names to sources */
static vector<name_map> names;

/* Record all processed files in order to warn about
   a file being read multiple times.  */
static vector<char *> processed_files;

/* This holds data summary information.  */

static unsigned object_runs;

static unsigned total_lines;
static unsigned total_executed;

/* Modification time of graph file.  */

static time_t bbg_file_time;

/* Name of the notes (gcno) output file.  The "bbg" prefix is for
   historical reasons, when the notes file contained only the
   basic block graph notes.  */

static char *bbg_file_name;

/* Stamp of the bbg file */
static unsigned bbg_stamp;

/* Supports has_unexecuted_blocks functionality.  */
static unsigned bbg_supports_has_unexecuted_blocks;

/* Working directory in which a TU was compiled.  */
static const char *bbg_cwd;

/* Name and file pointer of the input file for the count data (gcda).  */

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;

/* Show unconditional branches too.  */
static int flag_unconditional = 0;

/* Output a gcov file if this is true.  This is on by default, and can
   be turned off by the -n option.  */

static int flag_gcov_file = 1;

/* Output to stdout instead to a gcov file.  */

static int flag_use_stdout = 0;

/* Output progress indication if this is true.  This is off by default
   and can be turned on by the -d option.  */

static int flag_display_progress = 0;

/* Output *.gcov file in JSON intermediate format used by consumers.  */

static int flag_json_format = 0;

/* For included files, make the gcov output file name include the name
   of the input source file.  For example, if x.h is included in a.c,
   then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */

static int flag_long_names = 0;

/* For situations when a long name can potentially hit filesystem path limit,
   let's calculate md5sum of the path and append it to a file name.  */

static int flag_hash_filenames = 0;

/* Print verbose informations.  */

static int flag_verbose = 0;

/* Print colored output.  */

static int flag_use_colors = 0;

/* Use perf-like colors to indicate hot lines.  */

static int flag_use_hotness_colors = 0;

/* Output count information for every basic block, not merely those
   that contain line number information.  */

static int flag_all_blocks = 0;

/* Output human readable numbers.  */

static int flag_human_readable_numbers = 0;

/* Output summary info for each function.  */

static int flag_function_summary = 0;

/* Print debugging dumps.  */

static int flag_debug = 0;

/* Object directory file prefix.  This is the directory/file where the
   graph and data files are looked for, if nonzero.  */

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 '^'.  */

static int flag_preserve_paths = 0;

/* Output the number of times a branch was taken as opposed to the percentage
   of times it was taken.  */

static int flag_counts = 0;

/* Return code of the tool invocation.  */
static int return_code = 0;

/* Forward declarations.  */
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 process_all_functions (void);
static void generate_results (const char *);
static void create_file_names (const char *);
static char *canonicalize_name (const char *);
static unsigned find_source (const char *);
static void read_graph_file (void);
static int read_count_file (void);
static void solve_flow_graph (function_info *);
static void find_exception_blocks (function_info *);
static void add_branch_counts (coverage_info *, const arc_info *);
static void add_line_counts (coverage_info *, function_info *);
static void executed_summary (unsigned, unsigned);
static void function_summary (const coverage_info *);
static void file_summary (const coverage_info *);
static const char *format_gcov (gcov_type, gcov_type, int);
static void accumulate_line_counts (source_info *);
static void output_gcov_file (const char *, source_info *);
static int output_branch_count (FILE *, int, const arc_info *);
static void output_lines (FILE *, const source_info *);
static string make_gcov_file_name (const char *, const char *);
static char *mangle_name (const char *);
static void release_structures (void);
extern int main (int, char **);

function_info::function_info (): m_name (NULL), m_demangled_name (NULL),
  ident (0), lineno_checksum (0), cfg_checksum (0), has_catch (0),
  artificial (0), is_group (0),
  blocks (), blocks_executed (0), counts (),
  start_line (0), start_column (0), end_line (0), end_column (0),
  src (0), lines (), next (NULL)
{
}

function_info::~function_info ()
{
  for (int i = blocks.size () - 1; i >= 0; i--)
    {
      arc_info *arc, *arc_n;

      for (arc = blocks[i].succ; arc; arc = arc_n)
	{
	  arc_n = arc->succ_next;
	  free (arc);
	}
    }
  if (m_demangled_name != m_name)
    free (m_demangled_name);
  free (m_name);
}

bool function_info::group_line_p (unsigned n, unsigned src_idx)
{
  return is_group && src == src_idx && start_line <= n && n <= end_line;
}

/* Cycle detection!
   There are a bajillion algorithms that do this.  Boost's function is named
   hawick_cycles, so I used the algorithm by K. A. Hawick and H. A. James in
   "Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs"
   (url at <http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf>).

   The basic algorithm is simple: effectively, we're finding all simple paths
   in a subgraph (that shrinks every iteration).  Duplicates are filtered by
   "blocking" a path when a node is added to the path (this also prevents non-
   simple paths)--the node is unblocked only when it participates in a cycle.
   */

typedef vector<arc_info *> arc_vector_t;
typedef vector<const block_info *> block_vector_t;

/* Handle cycle identified by EDGES, where the function finds minimum cs_count
   and subtract the value from all counts.  The subtracted value is added
   to COUNT.  Returns type of loop.  */

static void
handle_cycle (const arc_vector_t &edges, int64_t &count)
{
  /* Find the minimum edge of the cycle, and reduce all nodes in the cycle by
     that amount.  */
  int64_t cycle_count = INTTYPE_MAXIMUM (int64_t);
  for (unsigned i = 0; i < edges.size (); i++)
    {
      int64_t ecount = edges[i]->cs_count;
      if (cycle_count > ecount)
	cycle_count = ecount;
    }
  count += cycle_count;
  for (unsigned i = 0; i < edges.size (); i++)
    edges[i]->cs_count -= cycle_count;

  gcc_assert (cycle_count > 0);
}

/* Unblock a block U from BLOCKED.  Apart from that, iterate all blocks
   blocked by U in BLOCK_LISTS.  */

static void
unblock (const block_info *u, block_vector_t &blocked,
	 vector<block_vector_t > &block_lists)
{
  block_vector_t::iterator it = find (blocked.begin (), blocked.end (), u);
  if (it == blocked.end ())
    return;

  unsigned index = it - blocked.begin ();
  blocked.erase (it);

  block_vector_t to_unblock (block_lists[index]);

  block_lists.erase (block_lists.begin () + index);

  for (block_vector_t::iterator it = to_unblock.begin ();
       it != to_unblock.end (); it++)
    unblock (*it, blocked, block_lists);
}

/* Return true when PATH contains a zero cycle arc count.  */

static bool
path_contains_zero_or_negative_cycle_arc (arc_vector_t &path)
{
  for (unsigned i = 0; i < path.size (); i++)
    if (path[i]->cs_count <= 0)
      return true;
  return false;
}

/* Find circuit going to block V, PATH is provisional seen cycle.
   BLOCKED is vector of blocked vertices, BLOCK_LISTS contains vertices
   blocked by a block.  COUNT is accumulated count of the current LINE.
   Returns what type of loop it contains.  */

static bool
circuit (block_info *v, arc_vector_t &path, block_info *start,
	 block_vector_t &blocked, vector<block_vector_t> &block_lists,
	 line_info &linfo, int64_t &count)
{
  bool loop_found = false;

  /* Add v to the block list.  */
  gcc_assert (find (blocked.begin (), blocked.end (), v) == blocked.end ());
  blocked.push_back (v);
  block_lists.push_back (block_vector_t ());

  for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
    {
      block_info *w = arc->dst;
      if (w < start
	  || arc->cs_count <= 0
	  || !linfo.has_block (w))
	continue;

      path.push_back (arc);
      if (w == start)
	{
	  /* Cycle has been found.  */
	  handle_cycle (path, count);
	  loop_found = true;
	}
      else if (!path_contains_zero_or_negative_cycle_arc (path)
	       &&  find (blocked.begin (), blocked.end (), w) == blocked.end ())
	loop_found |= circuit (w, path, start, blocked, block_lists, linfo,
			       count);

      path.pop_back ();
    }

  if (loop_found)
    unblock (v, blocked, block_lists);
  else
    for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
      {
	block_info *w = arc->dst;
	if (w < start
	    || arc->cs_count <= 0
	    || !linfo.has_block (w))
	  continue;

	size_t index
	  = find (blocked.begin (), blocked.end (), w) - blocked.begin ();
	gcc_assert (index < blocked.size ());
	block_vector_t &list = block_lists[index];
	if (find (list.begin (), list.end (), v) == list.end ())
	  list.push_back (v);
      }

  return loop_found;
}

/* Find cycles for a LINFO.  */

static gcov_type
get_cycles_count (line_info &linfo)
{
  /* Note that this algorithm works even if blocks aren't in sorted order.
     Each iteration of the circuit detection is completely independent
     (except for reducing counts, but that shouldn't matter anyways).
     Therefore, operating on a permuted order (i.e., non-sorted) only
     has the effect of permuting the output cycles.  */

  gcov_type count = 0;
  for (vector<block_info *>::iterator it = linfo.blocks.begin ();
       it != linfo.blocks.end (); it++)
    {
      arc_vector_t path;
      block_vector_t blocked;
      vector<block_vector_t > block_lists;
      circuit (*it, path, *it, blocked, block_lists, linfo, count);
    }

  return count;
}

int
main (int argc, char **argv)
{
  int argno;
  int first_arg;
  const char *p;

  p = argv[0] + strlen (argv[0]);
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
    --p;
  progname = p;

  xmalloc_set_program_name (progname);

  /* Unlock the stdio streams.  */
  unlock_std_streams ();

  gcc_init_libintl ();

  diagnostic_initialize (global_dc, 0);

  /* Handle response files.  */
  expandargv (&argc, &argv);

  argno = process_args (argc, argv);
  if (optind == argc)
    print_usage (true);

  if (argc - argno > 1)
    multiple_files = 1;

  first_arg = argno;

  for (; argno != argc; argno++)
    {
      if (flag_display_progress)
	printf ("Processing file %d out of %d\n", argno - first_arg + 1,
		argc - first_arg);
      process_file (argv[argno]);

      if (flag_json_format || argno == argc - 1)
	{
	  process_all_functions ();
	  generate_results (argv[argno]);
	  release_structures ();
	}
    }

  if (!flag_use_stdout)
    executed_summary (total_lines, total_executed);

  return return_code;
}

/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
   otherwise the output of --help.  */

static void
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...] SOURCE|OBJ...\n\n");
  fnotice (file, "Print code coverage information.\n\n");
  fnotice (file, "  -a, --all-blocks                Show information for every basic block\n");
  fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
  fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
                                    rather than percentages\n");
  fnotice (file, "  -d, --display-progress          Display progress information\n");
  fnotice (file, "  -D, --debug			    Display debugging dumps\n");
  fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
  fnotice (file, "  -h, --help                      Print this help, then exit\n");
  fnotice (file, "  -j, --json-format               Output JSON intermediate format\n\
                                    into .gcov.json.gz file\n");
  fnotice (file, "  -H, --human-readable            Output human readable numbers\n");
  fnotice (file, "  -k, --use-colors                Emit colored output\n");
  fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
                                    source files\n");
  fnotice (file, "  -m, --demangled-names           Output demangled function names\n");
  fnotice (file, "  -n, --no-output                 Do not create an output file\n");
  fnotice (file, "  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
  fnotice (file, "  -p, --preserve-paths            Preserve all pathname components\n");
  fnotice (file, "  -q, --use-hotness-colors        Emit perf-like colored output for hot lines\n");
  fnotice (file, "  -r, --relative-only             Only show data for relative sources\n");
  fnotice (file, "  -s, --source-prefix DIR         Source prefix to elide\n");
  fnotice (file, "  -t, --stdout                    Output to stdout instead of a file\n");
  fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
  fnotice (file, "  -v, --version                   Print version number, then exit\n");
  fnotice (file, "  -w, --verbose                   Print verbose informations\n");
  fnotice (file, "  -x, --hash-filenames            Hash long pathnames\n");
  fnotice (file, "\nObsolete options:\n");
  fnotice (file, "  -i, --json-format               Replaced with -j, --json-format\n");
  fnotice (file, "  -j, --human-readable            Replaced with -H, --human-readable\n");
  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
	   bug_report_url);
  exit (status);
}

/* Print version information and exit.  */

static void
print_version (void)
{
  fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
  fnotice (stdout, "JSON format version: %s\n", GCOV_JSON_FORMAT_VERSION);
  fprintf (stdout, "Copyright %s 2023 Free Software Foundation, Inc.\n",
	   _("(C)"));
  fnotice (stdout,
	   _("This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
  exit (SUCCESS_EXIT_CODE);
}

static const struct option options[] =
{
  { "help",                 no_argument,       NULL, 'h' },
  { "version",              no_argument,       NULL, 'v' },
  { "verbose",              no_argument,       NULL, 'w' },
  { "all-blocks",           no_argument,       NULL, 'a' },
  { "branch-probabilities", no_argument,       NULL, 'b' },
  { "branch-counts",        no_argument,       NULL, 'c' },
  { "json-format",	    no_argument,       NULL, 'j' },
  { "human-readable",	    no_argument,       NULL, 'H' },
  { "no-output",            no_argument,       NULL, 'n' },
  { "long-file-names",      no_argument,       NULL, 'l' },
  { "function-summaries",   no_argument,       NULL, 'f' },
  { "demangled-names",      no_argument,       NULL, 'm' },
  { "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' },
  { "stdout",		    no_argument,       NULL, 't' },
  { "unconditional-branches", no_argument,     NULL, 'u' },
  { "display-progress",     no_argument,       NULL, 'd' },
  { "hash-filenames",	    no_argument,       NULL, 'x' },
  { "use-colors",	    no_argument,       NULL, 'k' },
  { "use-hotness-colors",   no_argument,       NULL, 'q' },
  { "debug",		    no_argument,       NULL, 'D' },
  { 0, 0, 0, 0 }
};

/* Process args, return index to first non-arg.  */

static int
process_args (int argc, char **argv)
{
  int opt;

  const char *opts = "abcdDfhHijklmno:pqrs:tuvwx";
  while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
    {
      switch (opt)
	{
	case 'a':
	  flag_all_blocks = 1;
	  break;
	case 'b':
	  flag_branches = 1;
	  break;
	case 'c':
	  flag_counts = 1;
	  break;
	case 'f':
	  flag_function_summary = 1;
	  break;
	case 'h':
	  print_usage (false);
	  /* print_usage will exit.  */
	case 'l':
	  flag_long_names = 1;
	  break;
	case 'H':
	  flag_human_readable_numbers = 1;
	  break;
	case 'k':
	  flag_use_colors = 1;
	  break;
	case 'q':
	  flag_use_hotness_colors = 1;
	  break;
	case 'm':
	  flag_demangled_names = 1;
	  break;
	case 'n':
	  flag_gcov_file = 0;
	  break;
	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;
	case 'u':
	  flag_unconditional = 1;
	  break;
	case 'i':
	case 'j':
	  flag_json_format = 1;
	  flag_gcov_file = 1;
	  break;
	case 'd':
	  flag_display_progress = 1;
	  break;
	case 'x':
	  flag_hash_filenames = 1;
	  break;
	case 'w':
	  flag_verbose = 1;
	  break;
	case 't':
	  flag_use_stdout = 1;
	  break;
	case 'D':
	  flag_debug = 1;
	  break;
	case 'v':
	  print_version ();
	  /* print_version will exit.  */
	default:
	  print_usage (true);
	  /* print_usage will exit.  */
	}
    }

  return optind;
}

/* Output intermediate LINE sitting on LINE_NUM to JSON OBJECT.
   Add FUNCTION_NAME to the LINE.  */

static void
output_intermediate_json_line (json::array *object,
			       line_info *line, unsigned line_num,
			       const char *function_name)
{
  if (!line->exists)
    return;

  json::object *lineo = new json::object ();
  lineo->set ("line_number", new json::integer_number (line_num));
  if (function_name != NULL)
    lineo->set ("function_name", new json::string (function_name));
  lineo->set ("count", new json::integer_number (line->count));
  lineo->set ("unexecuted_block",
	      new json::literal (line->has_unexecuted_block));

  json::array *bb_ids = new json::array ();
  for (const block_info *block : line->blocks)
    bb_ids->append (new json::integer_number (block->id));
  lineo->set ("block_ids", bb_ids);

  json::array *branches = new json::array ();
  lineo->set ("branches", branches);

  json::array *calls = new json::array ();
  lineo->set ("calls", calls);

  vector<arc_info *>::const_iterator it;
  if (flag_branches)
    for (it = line->branches.begin (); it != line->branches.end ();
	 it++)
      {
	if (!(*it)->is_unconditional && !(*it)->is_call_non_return)
	  {
	    json::object *branch = new json::object ();
	    branch->set ("count", new json::integer_number ((*it)->count));
	    branch->set ("throw", new json::literal ((*it)->is_throw));
	    branch->set ("fallthrough",
			 new json::literal ((*it)->fall_through));
	    branch->set ("source_block_id",
			 new json::integer_number ((*it)->src->id));
	    branch->set ("destination_block_id",
			 new json::integer_number ((*it)->dst->id));
	    branches->append (branch);
	  }
	else if ((*it)->is_call_non_return)
	  {
	    json::object *call = new json::object ();
	    gcov_type returns = (*it)->src->count - (*it)->count;
	    call->set ("source_block_id",
		       new json::integer_number ((*it)->src->id));
	    call->set ("destination_block_id",
		       new json::integer_number ((*it)->dst->id));
	    call->set ("returned", new json::integer_number (returns));
	    calls->append (call);
	  }
      }

  object->append (lineo);
}

/* Strip filename extension in STR.  */

static string
strip_extention (string str)
{
  string::size_type pos = str.rfind ('.');
  if (pos != string::npos)
    str = str.substr (0, pos);

  return str;
}

/* Calcualte md5sum for INPUT string and return it in hex string format.  */

static string
get_md5sum (const char *input)
{
  md5_ctx ctx;
  char md5sum[16];
  string str;

  md5_init_ctx (&ctx);
  md5_process_bytes (input, strlen (input), &ctx);
  md5_finish_ctx (&ctx, md5sum);

  for (unsigned i = 0; i < 16; i++)
    {
      char b[3];
      sprintf (b, "%02x", (unsigned char)md5sum[i]);
      str += b;
    }

  return str;
}

/* Get the name of the gcov file.  The return value must be free'd.

   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 string
get_gcov_intermediate_filename (const char *input_file_name)
{
  string base = basename (input_file_name);
  string str = strip_extention (base);

  if (flag_hash_filenames)
    {
      str += "##";
      str += get_md5sum (input_file_name);
    }
  else if (flag_preserve_paths && base != input_file_name)
    {
      str += "##";
      str += mangle_path (input_file_name);
      str = strip_extention (str);
    }

  str += ".gcov.json.gz";
  return str.c_str ();
}

/* Output the result in JSON intermediate format.
   Source info SRC is dumped into JSON_FILES which is JSON array.  */

static void
output_json_intermediate_file (json::array *json_files, source_info *src)
{
  json::object *root = new json::object ();
  json_files->append (root);

  root->set ("file", new json::string (src->name));

  json::array *functions = new json::array ();
  root->set ("functions", functions);

  std::sort (src->functions.begin (), src->functions.end (),
	     function_line_start_cmp ());
  for (vector<function_info *>::iterator it = src->functions.begin ();
       it != src->functions.end (); it++)
    {
      json::object *function = new json::object ();
      function->set ("name", new json::string ((*it)->m_name));
      function->set ("demangled_name",
		     new json::string ((*it)->get_demangled_name ()));
      function->set ("start_line",
		     new json::integer_number ((*it)->start_line));
      function->set ("start_column",
		     new json::integer_number ((*it)->start_column));
      function->set ("end_line", new json::integer_number ((*it)->end_line));
      function->set ("end_column",
		     new json::integer_number ((*it)->end_column));
      function->set ("blocks",
		     new json::integer_number ((*it)->get_block_count ()));
      function->set ("blocks_executed",
		     new json::integer_number ((*it)->blocks_executed));
      function->set ("execution_count",
		     new json::integer_number ((*it)->blocks[0].count));

      functions->append (function);
    }

  json::array *lineso = new json::array ();
  root->set ("lines", lineso);

  vector<function_info *> last_non_group_fns;

  for (unsigned line_num = 1; line_num <= src->lines.size (); line_num++)
    {
      vector<function_info *> *fns = src->get_functions_at_location (line_num);

      if (fns != NULL)
	/* Print info for all group functions that begin on the line.  */
	for (vector<function_info *>::iterator it2 = fns->begin ();
	     it2 != fns->end (); it2++)
	  {
	    if (!(*it2)->is_group)
	      last_non_group_fns.push_back (*it2);

	    vector<line_info> &lines = (*it2)->lines;
	    /* The LINES array is allocated only for group functions.  */
	    for (unsigned i = 0; i < lines.size (); i++)
	      {
		line_info *line = &lines[i];
		output_intermediate_json_line (lineso, line, line_num + i,
					       (*it2)->m_name);
	      }
	  }

      /* Follow with lines associated with the source file.  */
      if (line_num < src->lines.size ())
	{
	  unsigned size = last_non_group_fns.size ();
	  function_info *last_fn = size > 0 ? last_non_group_fns[size - 1] : NULL;
	  const char *fname = last_fn ? last_fn->m_name : NULL;
	  output_intermediate_json_line (lineso, &src->lines[line_num], line_num,
					 fname);

	  /* Pop ending function from stack.  */
	  if (last_fn != NULL && last_fn->end_line == line_num)
	    last_non_group_fns.pop_back ();
	}
    }
}

/* Function start pair.  */
struct function_start
{
  unsigned source_file_idx;
  unsigned start_line;
};

/* Traits class for function start hash maps below.  */

struct function_start_pair_hash : typed_noop_remove <function_start>
{
  typedef function_start value_type;
  typedef function_start compare_type;

  static hashval_t
  hash (const function_start &ref)
  {
    inchash::hash hstate (0);
    hstate.add_int (ref.source_file_idx);
    hstate.add_int (ref.start_line);
    return hstate.end ();
  }

  static bool
  equal (const function_start &ref1, const function_start &ref2)
  {
    return (ref1.source_file_idx == ref2.source_file_idx
	    && ref1.start_line == ref2.start_line);
  }

  static void
  mark_deleted (function_start &ref)
  {
    ref.start_line = ~1U;
  }

  static const bool empty_zero_p = false;

  static void
  mark_empty (function_start &ref)
  {
    ref.start_line = ~2U;
  }

  static bool
  is_deleted (const function_start &ref)
  {
    return ref.start_line == ~1U;
  }

  static bool
  is_empty (const function_start &ref)
  {
    return ref.start_line == ~2U;
  }
};

/* Process a single input file.  */

static void
process_file (const char *file_name)
{
  create_file_names (file_name);

  for (unsigned i = 0; i < processed_files.size (); i++)
    if (strcmp (da_file_name, processed_files[i]) == 0)
      {
	fnotice (stderr, "'%s' file is already processed\n",
		 file_name);
	return;
      }

  processed_files.push_back (xstrdup (da_file_name));

  read_graph_file ();
  read_count_file ();
}

/* Process all functions in all files.  */

static void
process_all_functions (void)
{
  hash_map<function_start_pair_hash, function_info *> fn_map;

  /* Identify group functions.  */
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    if (!(*it)->artificial)
      {
	function_start needle;
	needle.source_file_idx = (*it)->src;
	needle.start_line = (*it)->start_line;

	function_info **slot = fn_map.get (needle);
	if (slot)
	  {
	    (*slot)->is_group = 1;
	    (*it)->is_group = 1;
	  }
	else
	  fn_map.put (needle, *it);
      }

  /* Remove all artificial function.  */
  functions.erase (remove_if (functions.begin (), functions.end (),
			      function_info::is_artificial), functions.end ());

  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      unsigned src = fn->src;

      if (!fn->counts.empty () || no_data_file)
	{
	  source_info *s = &sources[src];
	  s->add_function (fn);

	  /* Mark last line in files touched by function.  */
	  for (unsigned block_no = 0; block_no != fn->blocks.size ();
	       block_no++)
	    {
	      block_info *block = &fn->blocks[block_no];
	      for (unsigned i = 0; i < block->locations.size (); i++)
		{
		  /* Sort lines of locations.  */
		  sort (block->locations[i].lines.begin (),
			block->locations[i].lines.end ());

		  if (!block->locations[i].lines.empty ())
		    {
		      s = &sources[block->locations[i].source_file_idx];
		      unsigned last_line
			= block->locations[i].lines.back ();

		      /* Record new lines for the function.  */
		      if (last_line >= s->lines.size ())
			{
			  s = &sources[block->locations[i].source_file_idx];
			  unsigned last_line
			    = block->locations[i].lines.back ();

			  /* Record new lines for the function.  */
			  if (last_line >= s->lines.size ())
			    {
			      /* Record new lines for a source file.  */
			      s->lines.resize (last_line + 1);
			    }
			}
		    }
		}
	    }

	  /* Allocate lines for group function, following start_line
	     and end_line information of the function.  */
	  if (fn->is_group)
	    fn->lines.resize (fn->end_line - fn->start_line + 1);

	  solve_flow_graph (fn);
	  if (fn->has_catch)
	    find_exception_blocks (fn);
	}
      else
	{
	  /* The function was not in the executable -- some other
	     instance must have been selected.  */
	}
    }
}

static void
output_gcov_file (const char *file_name, source_info *src)
{
  string gcov_file_name_str
    = make_gcov_file_name (file_name, src->coverage.name);
  const char *gcov_file_name = gcov_file_name_str.c_str ();

  if (src->coverage.lines)
    {
      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);
	      return_code = 6;
	    }
	  fclose (gcov_file);
	}
      else
	{
	  fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
	  return_code = 6;
	}
    }
  else
    {
      unlink (gcov_file_name);
      fnotice (stdout, "Removing '%s'\n", gcov_file_name);
    }
}

static void
generate_results (const char *file_name)
{
  string gcov_intermediate_filename;

  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      coverage_info coverage;

      memset (&coverage, 0, sizeof (coverage));
      coverage.name = fn->get_name ();
      add_line_counts (flag_function_summary ? &coverage : NULL, fn);
      if (flag_function_summary)
	{
	  function_summary (&coverage);
	  fnotice (stdout, "\n");
	}
    }

  name_map needle;
  needle.name = file_name;
  vector<name_map>::iterator it
    = std::find (names.begin (), names.end (), needle);
  if (it != names.end ())
    file_name = sources[it->src].coverage.name;
  else
    file_name = canonicalize_name (file_name);

  gcov_intermediate_filename = get_gcov_intermediate_filename (file_name);

  json::object *root = new json::object ();
  root->set ("format_version", new json::string (GCOV_JSON_FORMAT_VERSION));
  root->set ("gcc_version", new json::string (version_string));

  if (bbg_cwd != NULL)
    root->set ("current_working_directory", new json::string (bbg_cwd));
  root->set ("data_file", new json::string (file_name));

  json::array *json_files = new json::array ();
  root->set ("files", json_files);

  for (vector<source_info>::iterator it = sources.begin ();
       it != sources.end (); it++)
    {
      source_info *src = &(*it);
      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);
      if (flag_debug)
	src->debug ();

      if (!flag_use_stdout)
	file_summary (&src->coverage);
      total_lines += src->coverage.lines;
      total_executed += src->coverage.lines_executed;
      if (flag_gcov_file)
	{
	  if (flag_json_format)
	    {
	      output_json_intermediate_file (json_files, src);
	      if (!flag_use_stdout)
		fnotice (stdout, "\n");
	    }
	  else
	    {
	      if (flag_use_stdout)
		{
		  if (src->coverage.lines)
		    output_lines (stdout, src);
		}
	      else
		{
		  output_gcov_file (file_name, src);
		  fnotice (stdout, "\n");
		}
	    }
	}
    }

  if (flag_gcov_file && flag_json_format)
    {
      if (flag_use_stdout)
	{
	  root->dump (stdout);
	  printf ("\n");
	}
      else
	{
	  pretty_printer pp;
	  root->print (&pp);
	  pp_formatted_text (&pp);

	  fnotice (stdout, "Creating '%s'\n",
		   gcov_intermediate_filename.c_str ());
	  gzFile output = gzopen (gcov_intermediate_filename.c_str (), "w");
	  if (output == NULL)
	    {
	      fnotice (stderr, "Cannot open JSON output file %s\n",
		       gcov_intermediate_filename.c_str ());
	      return_code = 6;
	      return;
	    }

	  if (gzputs (output, pp_formatted_text (&pp)) == EOF
	      || gzclose (output))
	    {
	      fnotice (stderr, "Error writing JSON output file %s\n",
		       gcov_intermediate_filename.c_str ());
	      return_code = 6;
	      return;
	    }
	}
    }
}

/* Release all memory used.  */

static void
release_structures (void)
{
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    delete (*it);

  sources.resize (0);
  names.resize (0);
  functions.resize (0);
  ident_to_fn.clear ();
}

/* Generate the names of the graph and data files.  If OBJECT_DIRECTORY
   is not specified, these are named from FILE_NAME sans extension.  If
   OBJECT_DIRECTORY is specified and is a directory, the files are in that
   directory, but named from the basename of the FILE_NAME, sans extension.
   Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
   and the data files are named from that.  */

static void
create_file_names (const char *file_name)
{
  char *cptr;
  char *name;
  int length = strlen (file_name);
  int base;

  /* Free previous file names.  */
  free (bbg_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 = XNEWVEC (char, length);
      name[0] = 0;

      base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
      strcat (name, object_directory);
      if (base && (!IS_DIR_SEPARATOR (name[strlen (name) - 1])))
	strcat (name, "/");
    }
  else
    {
      name = XNEWVEC (char, length + 1);
      strcpy (name, file_name);
      base = 0;
    }

  if (base)
    {
      /* Append source file name.  */
      const char *cptr = lbasename (file_name);
      strcat (name, cptr ? cptr : file_name);
    }

  /* Remove the extension.  */
  cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
  if (cptr)
    *cptr = 0;

  length = strlen (name);

  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 = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
  strcpy (da_file_name, name);
  strcpy (da_file_name + length, GCOV_DATA_SUFFIX);

  free (name);
  return;
}

/* Find or create a source file structure for FILE_NAME. Copies
   FILE_NAME on creation */

static unsigned
find_source (const char *file_name)
{
  char *canon;
  unsigned idx;
  struct stat status;

  if (!file_name)
    file_name = "<unknown>";

  name_map needle;
  needle.name = file_name;

  vector<name_map>::iterator it = std::find (names.begin (), names.end (),
					     needle);
  if (it != names.end ())
    {
      idx = it->src;
      goto check_date;
    }

  /* Not found, try the canonical name. */
  canon = canonicalize_name (file_name);
  needle.name = canon;
  it = std::find (names.begin (), names.end (), needle);
  if (it == names.end ())
    {
      /* Not found with canonical name, create a new source.  */
      source_info *src;

      idx = sources.size ();
      needle = name_map (canon, idx);
      names.push_back (needle);

      sources.push_back (source_info ());
      src = &sources.back ();
      src->name = canon;
      src->coverage.name = src->name;
      src->index = idx;
      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;
    }
  else
    idx = it->src;

  needle.name = file_name;
  if (std::find (names.begin (), names.end (), needle) == names.end ())
    {
      /* Append the non-canonical name.  */
      names.push_back (name_map (xstrdup (file_name), idx));
    }

  /* Resort the name map.  */
  std::sort (names.begin (), names.end ());

 check_date:
  if (sources[idx].file_time > bbg_file_time)
    {
      static int info_emitted;

      fnotice (stderr, "%s:source file is newer than notes file '%s'\n",
	       file_name, bbg_file_name);
      if (!info_emitted)
	{
	  fnotice (stderr,
		   "(the message is displayed only once per source file)\n");
	  info_emitted = 1;
	}
      sources[idx].file_time = 0;
    }

  return idx;
}

/* Read the notes file.  Save functions to FUNCTIONS global vector.  */

static void
read_graph_file (void)
{
  unsigned version;
  unsigned current_tag = 0;
  unsigned tag;

  if (!gcov_open (bbg_file_name, 1))
    {
      fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
      return_code = 1;
      return;
    }
  bbg_file_time = gcov_time ();
  if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
    {
      fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
      return_code = 2;
      gcov_close ();
      return;
    }

  version = gcov_read_unsigned ();
  if (version != GCOV_VERSION)
    {
      char v[4], e[4];

      GCOV_UNSIGNED2STRING (v, version);
      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);

      fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
	       bbg_file_name, v, e);
      return_code = 3;
    }
  bbg_stamp = gcov_read_unsigned ();
  /* Read checksum.  */
  gcov_read_unsigned ();
  bbg_cwd = xstrdup (gcov_read_string ());
  bbg_supports_has_unexecuted_blocks = gcov_read_unsigned ();

  function_info *fn = NULL;
  while ((tag = gcov_read_unsigned ()))
    {
      unsigned length = gcov_read_unsigned ();
      gcov_position_t base = gcov_position ();

      if (tag == GCOV_TAG_FUNCTION)
	{
	  char *function_name;
	  unsigned ident;
	  unsigned lineno_checksum, cfg_checksum;

	  ident = gcov_read_unsigned ();
	  lineno_checksum = gcov_read_unsigned ();
	  cfg_checksum = gcov_read_unsigned ();
	  function_name = xstrdup (gcov_read_string ());
	  unsigned artificial = gcov_read_unsigned ();
	  unsigned src_idx = find_source (gcov_read_string ());
	  unsigned start_line = gcov_read_unsigned ();
	  unsigned start_column = gcov_read_unsigned ();
	  unsigned end_line = gcov_read_unsigned ();
	  unsigned end_column = gcov_read_unsigned ();

	  fn = new function_info ();
	  functions.push_back (fn);
	  ident_to_fn[ident] = fn;

	  fn->m_name = function_name;
	  fn->ident = ident;
	  fn->lineno_checksum = lineno_checksum;
	  fn->cfg_checksum = cfg_checksum;
	  fn->src = src_idx;
	  fn->start_line = start_line;
	  fn->start_column = start_column;
	  fn->end_line = end_line;
	  fn->end_column = end_column;
	  fn->artificial = artificial;

	  current_tag = tag;
	}
      else if (fn && tag == GCOV_TAG_BLOCKS)
	{
	  if (!fn->blocks.empty ())
	    fnotice (stderr, "%s:already seen blocks for '%s'\n",
		     bbg_file_name, fn->get_name ());
	  else
	    fn->blocks.resize (gcov_read_unsigned ());
	}
      else if (fn && tag == GCOV_TAG_ARCS)
	{
	  unsigned src = gcov_read_unsigned ();
	  fn->blocks[src].id = src;
	  unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
	  block_info *src_blk = &fn->blocks[src];
	  unsigned mark_catches = 0;
	  struct arc_info *arc;

	  if (src >= fn->blocks.size () || fn->blocks[src].succ)
	    goto corrupt;

	  while (num_dests--)
	    {
	      unsigned dest = gcov_read_unsigned ();
	      unsigned flags = gcov_read_unsigned ();

	      if (dest >= fn->blocks.size ())
		goto corrupt;
	      arc = XCNEW (arc_info);

	      arc->dst = &fn->blocks[dest];
	      /* Set id in order to find EXIT_BLOCK.  */
	      arc->dst->id = dest;
	      arc->src = src_blk;

	      arc->count = 0;
	      arc->count_valid = 0;
	      arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
	      arc->fake = !!(flags & GCOV_ARC_FAKE);
	      arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);

	      arc->succ_next = src_blk->succ;
	      src_blk->succ = arc;
	      src_blk->num_succ++;

	      arc->pred_next = fn->blocks[dest].pred;
	      fn->blocks[dest].pred = arc;
	      fn->blocks[dest].num_pred++;

	      if (arc->fake)
		{
		  if (src)
		    {
		      /* Exceptional exit from this function, the
			 source block must be a call.  */
		      fn->blocks[src].is_call_site = 1;
		      arc->is_call_non_return = 1;
		      mark_catches = 1;
		    }
		  else
		    {
		      /* Non-local return from a callee of this
			 function.  The destination block is a setjmp.  */
		      arc->is_nonlocal_return = 1;
		      fn->blocks[dest].is_nonlocal_return = 1;
		    }
		}

	      if (!arc->on_tree)
		fn->counts.push_back (0);
	    }

	  if (mark_catches)
	    {
	      /* We have a fake exit from this block.  The other
		 non-fall through exits must be to catch handlers.
		 Mark them as catch arcs.  */

	      for (arc = src_blk->succ; arc; arc = arc->succ_next)
		if (!arc->fake && !arc->fall_through)
		  {
		    arc->is_throw = 1;
		    fn->has_catch = 1;
		  }
	    }
	}
      else if (fn && tag == GCOV_TAG_LINES)
	{
	  unsigned blockno = gcov_read_unsigned ();
	  block_info *block = &fn->blocks[blockno];

	  if (blockno >= fn->blocks.size ())
	    goto corrupt;

	  while (true)
	    {
	      unsigned lineno = gcov_read_unsigned ();

	      if (lineno)
		block->locations.back ().lines.push_back (lineno);
	      else
		{
		  const char *file_name = gcov_read_string ();

		  if (!file_name)
		    break;
		  block->locations.push_back (block_location_info
					      (find_source (file_name)));
		}
	    }
	}
      else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
	{
	  fn = NULL;
	  current_tag = 0;
	}
      gcov_sync (base, length);
      if (gcov_is_error ())
	{
	corrupt:;
	  fnotice (stderr, "%s:corrupted\n", bbg_file_name);
	  return_code = 4;
	  break;
	}
    }
  gcov_close ();

  if (functions.empty ())
    fnotice (stderr, "%s:no functions found\n", bbg_file_name);
}

/* Reads profiles from the count file and attach to each
   function. Return nonzero if fatal error.  */

static int
read_count_file (void)
{
  unsigned ix;
  unsigned version;
  unsigned tag;
  function_info *fn = NULL;
  int error = 0;
  map<unsigned, function_info *>::iterator it;

  if (!gcov_open (da_file_name, 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))
    {
      fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
      return_code = 2;
    cleanup:;
      gcov_close ();
      return 1;
    }
  version = gcov_read_unsigned ();
  if (version != GCOV_VERSION)
    {
      char v[4], e[4];

      GCOV_UNSIGNED2STRING (v, version);
      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);

      fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
	       da_file_name, v, e);
      return_code = 3;
    }
  tag = gcov_read_unsigned ();
  if (tag != bbg_stamp)
    {
      fnotice (stderr, "%s:stamp mismatch with notes file\n", da_file_name);
      return_code = 5;
      goto cleanup;
    }

  /* Read checksum.  */
  gcov_read_unsigned ();

  while ((tag = gcov_read_unsigned ()))
    {
      unsigned length = gcov_read_unsigned ();
      int read_length = (int)length;
      unsigned long base = gcov_position ();

      if (tag == GCOV_TAG_OBJECT_SUMMARY)
	{
	  struct gcov_summary summary;
	  gcov_read_summary (&summary);
	  object_runs = summary.runs;
	}
      else if (tag == GCOV_TAG_FUNCTION && !length)
	; /* placeholder  */
      else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
	{
	  unsigned ident;
	  ident = gcov_read_unsigned ();
	  fn = NULL;
	  it = ident_to_fn.find (ident);
	  if (it != ident_to_fn.end ())
	    fn = it->second;

	  if (!fn)
	    ;
	  else if (gcov_read_unsigned () != fn->lineno_checksum
		   || gcov_read_unsigned () != fn->cfg_checksum)
	    {
	    mismatch:;
	      fnotice (stderr, "%s:profile mismatch for '%s'\n",
		       da_file_name, fn->get_name ());
	      goto cleanup;
	    }
	}
      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
	{
	  length = abs (read_length);
	  if (length != GCOV_TAG_COUNTER_LENGTH (fn->counts.size ()))
	    goto mismatch;

	  if (read_length > 0)
	    for (ix = 0; ix != fn->counts.size (); ix++)
	      fn->counts[ix] += gcov_read_counter ();
	}
      if (read_length < 0)
	read_length = 0;
      gcov_sync (base, read_length);
      if ((error = gcov_is_error ()))
	{
	  fnotice (stderr,
		   error < 0
		   ? N_("%s:overflowed\n")
		   : N_("%s:corrupted\n"),
		   da_file_name);
	  return_code = 4;
	  goto cleanup;
	}
    }

  gcov_close ();
  return 0;
}

/* Solve the flow graph. Propagate counts from the instrumented arcs
   to the blocks and the uninstrumented arcs.  */

static void
solve_flow_graph (function_info *fn)
{
  unsigned ix;
  arc_info *arc;
  gcov_type *count_ptr = &fn->counts.front ();
  block_info *blk;
  block_info *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
  block_info *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */

  /* The arcs were built in reverse order.  Fix that now.  */
  for (ix = fn->blocks.size (); ix--;)
    {
      arc_info *arc_p, *arc_n;

      for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
	   arc_p = arc, arc = arc_n)
	{
	  arc_n = arc->succ_next;
	  arc->succ_next = arc_p;
	}
      fn->blocks[ix].succ = arc_p;

      for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
	   arc_p = arc, arc = arc_n)
	{
	  arc_n = arc->pred_next;
	  arc->pred_next = arc_p;
	}
      fn->blocks[ix].pred = arc_p;
    }

  if (fn->blocks.size () < 2)
    fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
	     bbg_file_name, fn->get_name ());
  else
    {
      if (fn->blocks[ENTRY_BLOCK].num_pred)
	fnotice (stderr, "%s:'%s' has arcs to entry block\n",
		 bbg_file_name, fn->get_name ());
      else
	/* We can't deduce the entry block counts from the lack of
	   predecessors.  */
	fn->blocks[ENTRY_BLOCK].num_pred = ~(unsigned)0;

      if (fn->blocks[EXIT_BLOCK].num_succ)
	fnotice (stderr, "%s:'%s' has arcs from exit block\n",
		 bbg_file_name, fn->get_name ());
      else
	/* Likewise, we can't deduce exit block counts from the lack
	   of its successors.  */
	fn->blocks[EXIT_BLOCK].num_succ = ~(unsigned)0;
    }

  /* Propagate the measured counts, this must be done in the same
     order as the code in profile.cc  */
  for (unsigned i = 0; i < fn->blocks.size (); i++)
    {
      blk = &fn->blocks[i];
      block_info const *prev_dst = NULL;
      int out_of_order = 0;
      int non_fake_succ = 0;

      for (arc = blk->succ; arc; arc = arc->succ_next)
	{
	  if (!arc->fake)
	    non_fake_succ++;

	  if (!arc->on_tree)
	    {
	      if (count_ptr)
		arc->count = *count_ptr++;
	      arc->count_valid = 1;
	      blk->num_succ--;
	      arc->dst->num_pred--;
	    }
	  if (prev_dst && prev_dst > arc->dst)
	    out_of_order = 1;
	  prev_dst = arc->dst;
	}
      if (non_fake_succ == 1)
	{
	  /* If there is only one non-fake exit, it is an
	     unconditional branch.  */
	  for (arc = blk->succ; arc; arc = arc->succ_next)
	    if (!arc->fake)
	      {
		arc->is_unconditional = 1;
		/* If this block is instrumenting a call, it might be
		   an artificial block. It is not artificial if it has
		   a non-fallthrough exit, or the destination of this
		   arc has more than one entry.  Mark the destination
		   block as a return site, if none of those conditions
		   hold.  */
		if (blk->is_call_site && arc->fall_through
		    && arc->dst->pred == arc && !arc->pred_next)
		  arc->dst->is_call_return = 1;
	      }
	}

      /* Sort the successor arcs into ascending dst order. profile.cc
	 normally produces arcs in the right order, but sometimes with
	 one or two out of order.  We're not using a particularly
	 smart sort.  */
      if (out_of_order)
	{
	  arc_info *start = blk->succ;
	  unsigned changes = 1;

	  while (changes)
	    {
	      arc_info *arc, *arc_p, *arc_n;

	      changes = 0;
	      for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
		{
		  if (arc->dst > arc_n->dst)
		    {
		      changes = 1;
		      if (arc_p)
			arc_p->succ_next = arc_n;
		      else
			start = arc_n;
		      arc->succ_next = arc_n->succ_next;
		      arc_n->succ_next = arc;
		      arc_p = arc_n;
		    }
		  else
		    {
		      arc_p = arc;
		      arc = arc_n;
		    }
		}
	    }
	  blk->succ = start;
	}

      /* Place it on the invalid chain, it will be ignored if that's
	 wrong.  */
      blk->invalid_chain = 1;
      blk->chain = invalid_blocks;
      invalid_blocks = blk;
    }

  while (invalid_blocks || valid_blocks)
    {
      while ((blk = invalid_blocks))
	{
	  gcov_type total = 0;
	  const arc_info *arc;

	  invalid_blocks = blk->chain;
	  blk->invalid_chain = 0;
	  if (!blk->num_succ)
	    for (arc = blk->succ; arc; arc = arc->succ_next)
	      total += arc->count;
	  else if (!blk->num_pred)
	    for (arc = blk->pred; arc; arc = arc->pred_next)
	      total += arc->count;
	  else
	    continue;

	  blk->count = total;
	  blk->count_valid = 1;
	  blk->chain = valid_blocks;
	  blk->valid_chain = 1;
	  valid_blocks = blk;
	}
      while ((blk = valid_blocks))
	{
	  gcov_type total;
	  arc_info *arc, *inv_arc;

	  valid_blocks = blk->chain;
	  blk->valid_chain = 0;
	  if (blk->num_succ == 1)
	    {
	      block_info *dst;

	      total = blk->count;
	      inv_arc = NULL;
	      for (arc = blk->succ; arc; arc = arc->succ_next)
		{
		  total -= arc->count;
		  if (!arc->count_valid)
		    inv_arc = arc;
		}
	      dst = inv_arc->dst;
	      inv_arc->count_valid = 1;
	      inv_arc->count = total;
	      blk->num_succ--;
	      dst->num_pred--;
	      if (dst->count_valid)
		{
		  if (dst->num_pred == 1 && !dst->valid_chain)
		    {
		      dst->chain = valid_blocks;
		      dst->valid_chain = 1;
		      valid_blocks = dst;
		    }
		}
	      else
		{
		  if (!dst->num_pred && !dst->invalid_chain)
		    {
		      dst->chain = invalid_blocks;
		      dst->invalid_chain = 1;
		      invalid_blocks = dst;
		    }
		}
	    }
	  if (blk->num_pred == 1)
	    {
	      block_info *src;

	      total = blk->count;
	      inv_arc = NULL;
	      for (arc = blk->pred; arc; arc = arc->pred_next)
		{
		  total -= arc->count;
		  if (!arc->count_valid)
		    inv_arc = arc;
		}
	      src = inv_arc->src;
	      inv_arc->count_valid = 1;
	      inv_arc->count = total;
	      blk->num_pred--;
	      src->num_succ--;
	      if (src->count_valid)
		{
		  if (src->num_succ == 1 && !src->valid_chain)
		    {
		      src->chain = valid_blocks;
		      src->valid_chain = 1;
		      valid_blocks = src;
		    }
		}
	      else
		{
		  if (!src->num_succ && !src->invalid_chain)
		    {
		      src->chain = invalid_blocks;
		      src->invalid_chain = 1;
		      invalid_blocks = src;
		    }
		}
	    }
	}
    }

  /* If the graph has been correctly solved, every block will have a
     valid count.  */
  for (unsigned i = 0; ix < fn->blocks.size (); i++)
    if (!fn->blocks[i].count_valid)
      {
	fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
		 bbg_file_name, fn->get_name ());
	break;
      }
}

/* Mark all the blocks only reachable via an incoming catch.  */

static void
find_exception_blocks (function_info *fn)
{
  unsigned ix;
  block_info **queue = XALLOCAVEC (block_info *, fn->blocks.size ());

  /* First mark all blocks as exceptional.  */
  for (ix = fn->blocks.size (); ix--;)
    fn->blocks[ix].exceptional = 1;

  /* Now mark all the blocks reachable via non-fake edges */
  queue[0] = &fn->blocks[0];
  queue[0]->exceptional = 0;
  for (ix = 1; ix;)
    {
      block_info *block = queue[--ix];
      const arc_info *arc;

      for (arc = block->succ; arc; arc = arc->succ_next)
	if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
	  {
	    arc->dst->exceptional = 0;
	    queue[ix++] = arc->dst;
	  }
    }
}


/* Increment totals in COVERAGE according to arc ARC.  */

static void
add_branch_counts (coverage_info *coverage, const arc_info *arc)
{
  if (arc->is_call_non_return)
    {
      coverage->calls++;
      if (arc->src->count)
	coverage->calls_executed++;
    }
  else if (!arc->is_unconditional)
    {
      coverage->branches++;
      if (arc->src->count)
	coverage->branches_executed++;
      if (arc->count)
	coverage->branches_taken++;
    }
}

/* Format COUNT, if flag_human_readable_numbers is set, return it human
   readable format.  */

static char const *
format_count (gcov_type count)
{
  static char buffer[64];
  const char *units = " kMGTPEZY";

  if (count < 1000 || !flag_human_readable_numbers)
    {
      sprintf (buffer, "%" PRId64, count);
      return buffer;
    }

  unsigned i;
  gcov_type divisor = 1;
  for (i = 0; units[i+1]; i++, divisor *= 1000)
    {
      if (count + divisor / 2 < 1000 * divisor)
	break;
    }
  float r = 1.0f * count / divisor;
  sprintf (buffer, "%.1f%c", r, units[i]);
  return buffer;
}

/* Format a GCOV_TYPE integer as either a percent ratio, or absolute
   count.  If DECIMAL_PLACES >= 0, format TOP/BOTTOM * 100 to DECIMAL_PLACES.
   If DECIMAL_PLACES is zero, no decimal point is printed. Only print 100% when
   TOP==BOTTOM and only print 0% when TOP=0.  If DECIMAL_PLACES < 0, then simply
   format TOP.  Return pointer to a static string.  */

static char const *
format_gcov (gcov_type top, gcov_type bottom, int decimal_places)
{
  static char buffer[20];

  if (decimal_places >= 0)
    {
      float ratio = bottom ? 100.0f * top / bottom: 0;

      /* Round up to 1% if there's a small non-zero value.  */
      if (ratio > 0.0f && ratio < 0.5f && decimal_places == 0)
	ratio = 1.0f;
      sprintf (buffer, "%.*f%%", decimal_places, ratio);
    }
  else
    return format_count (top);

  return buffer;
}

/* Summary of execution */

static void
executed_summary (unsigned lines, unsigned executed)
{
  if (lines)
    fnotice (stdout, "Lines executed:%s of %d\n",
	     format_gcov (executed, lines, 2), lines);
  else
    fnotice (stdout, "No executable lines\n");
}

/* Output summary info for a function.  */

static void
function_summary (const coverage_info *coverage)
{
  fnotice (stdout, "%s '%s'\n", "Function", coverage->name);
  executed_summary (coverage->lines, coverage->lines_executed);
}

/* Output summary info for a file.  */

static void
file_summary (const coverage_info *coverage)
{
  fnotice (stdout, "%s '%s'\n", "File", coverage->name);
  executed_summary (coverage->lines, coverage->lines_executed);

  if (flag_branches)
    {
      if (coverage->branches)
	{
	  fnotice (stdout, "Branches executed:%s of %d\n",
		   format_gcov (coverage->branches_executed,
				coverage->branches, 2),
		   coverage->branches);
	  fnotice (stdout, "Taken at least once:%s of %d\n",
		   format_gcov (coverage->branches_taken,
				coverage->branches, 2),
		   coverage->branches);
	}
      else
	fnotice (stdout, "No branches\n");
      if (coverage->calls)
	fnotice (stdout, "Calls executed:%s of %d\n",
		 format_gcov (coverage->calls_executed, coverage->calls, 2),
		 coverage->calls);
      else
	fnotice (stdout, "No calls\n");
    }
}

/* Canonicalize the filename NAME by canonicalizing directory
   separators, eliding . components and resolving .. components
   appropriately.  Always returns a unique string.  */

static char *
canonicalize_name (const char *name)
{
  /* The canonical name cannot be longer than the incoming name.  */
  char *result = XNEWVEC (char, strlen (name) + 1);
  const char *base = name, *probe;
  char *ptr = result;
  char *dd_base;
  int slash = 0;

#if HAVE_DOS_BASED_FILE_SYSTEM
  if (base[0] && base[1] == ':')
    {
      result[0] = base[0];
      result[1] = ':';
      base += 2;
      ptr += 2;
    }
#endif
  for (dd_base = ptr; *base; base = probe)
    {
      size_t len;

      for (probe = base; *probe; probe++)
	if (IS_DIR_SEPARATOR (*probe))
	  break;

      len = probe - base;
      if (len == 1 && base[0] == '.')
	/* Elide a '.' directory */
	;
      else if (len == 2 && base[0] == '.' && base[1] == '.')
	{
	  /* '..', we can only elide it and the previous directory, if
	     we're not a symlink.  */
	  struct stat ATTRIBUTE_UNUSED buf;

	  *ptr = 0;
	  if (dd_base == ptr
#if defined (S_ISLNK)
	      /* S_ISLNK is not POSIX.1-1996.  */
	      || stat (result, &buf) || S_ISLNK (buf.st_mode)
#endif
		)
	    {
	      /* Cannot elide, or unreadable or a symlink.  */
	      dd_base = ptr + 2 + slash;
	      goto regular;
	    }
	  while (ptr != dd_base && *ptr != '/')
	    ptr--;
	  slash = ptr != result;
	}
      else
	{
	regular:
	  /* Regular pathname component.  */
	  if (slash)
	    *ptr++ = '/';
	  memcpy (ptr, base, len);
	  ptr += len;
	  slash = 1;
	}

      for (; IS_DIR_SEPARATOR (*probe); probe++)
	continue;
    }
  *ptr = 0;

  return result;
}

/* Generate an output file name. INPUT_NAME is the canonicalized main
   input file and SRC_NAME is the canonicalized file name.
   LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation.  With
   long_output_names we prepend the processed name of the input file
   to each output name (except when the current source file is the
   input file, so you don't get a double concatenation). The two
   components are separated by '##'.  With preserve_paths we create a
   filename from all path components of the source file, replacing '/'
   with '#', and .. with '^', without it we simply take the basename
   component.  (Remember, the canonicalized name will already have
   elided '.' components and converted \\ separators.)  */

static string
make_gcov_file_name (const char *input_name, const char *src_name)
{
  string str;

  /* When hashing filenames, we shorten them by only using the filename
     component and appending a hash of the full (mangled) pathname.  */
  if (flag_hash_filenames)
    str = (string (mangle_name (src_name)) + "##"
	   + get_md5sum (src_name) + ".gcov");
  else
    {
      if (flag_long_names && input_name && strcmp (src_name, input_name) != 0)
	{
	  str += mangle_name (input_name);
	  str += "##";
	}

      str += mangle_name (src_name);
      str += ".gcov";
    }

  return str;
}

/* Mangle BASE name, copy it at the beginning of PTR buffer and
   return address of the \0 character of the buffer.  */

static char *
mangle_name (char const *base)
{
  /* Generate the source filename part.  */
  if (!flag_preserve_paths)
    return xstrdup (lbasename (base));
  else
    return mangle_path (base);
}

/* Scan through the bb_data for each line in the block, increment
   the line number execution count indicated by the execution count of
   the appropriate basic block.  */

static void
add_line_counts (coverage_info *coverage, function_info *fn)
{
  bool has_any_line = false;
  /* Scan each basic block.  */
  for (unsigned ix = 0; ix != fn->blocks.size (); ix++)
    {
      line_info *line = NULL;
      block_info *block = &fn->blocks[ix];
      if (block->count && ix && ix + 1 != fn->blocks.size ())
	fn->blocks_executed++;
      for (unsigned i = 0; i < block->locations.size (); i++)
	{
	  unsigned src_idx = block->locations[i].source_file_idx;
	  vector<unsigned> &lines = block->locations[i].lines;

	  block->cycle.arc = NULL;
	  block->cycle.ident = ~0U;

	  for (unsigned j = 0; j < lines.size (); j++)
	    {
	      unsigned ln = lines[j];

	      /* Line belongs to a function that is in a group.  */
	      if (fn->group_line_p (ln, src_idx))
		{
		  gcc_assert (lines[j] - fn->start_line < fn->lines.size ());
		  line = &(fn->lines[lines[j] - fn->start_line]);
		  if (coverage)
		    {
		      if (!line->exists)
			coverage->lines++;
		      if (!line->count && block->count)
			coverage->lines_executed++;
		    }
		  line->exists = 1;
		  if (!block->exceptional)
		    {
		      line->unexceptional = 1;
		      if (block->count == 0)
			line->has_unexecuted_block = 1;
		    }
		  line->count += block->count;
		}
	      else
		{
		  gcc_assert (ln < sources[src_idx].lines.size ());
		  line = &(sources[src_idx].lines[ln]);
		  if (coverage)
		    {
		      if (!line->exists)
			coverage->lines++;
		      if (!line->count && block->count)
			coverage->lines_executed++;
		    }
		  line->exists = 1;
		  if (!block->exceptional)
		    {
		      line->unexceptional = 1;
		      if (block->count == 0)
			line->has_unexecuted_block = 1;
		    }
		  line->count += block->count;
		}
	    }

	  has_any_line = true;

	  if (!ix || ix + 1 == fn->blocks.size ())
	    /* Entry or exit block.  */;
	  else if (line != NULL)
	    {
	      line->blocks.push_back (block);

	      if (flag_branches)
		{
		  arc_info *arc;

		  for (arc = block->succ; arc; arc = arc->succ_next)
		    line->branches.push_back (arc);
		}
	    }
	}
    }

  if (!has_any_line)
    fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name,
	     fn->get_name ());
}

/* Accumulate info for LINE that belongs to SRC source file.  If ADD_COVERAGE
   is set to true, update source file summary.  */

static void accumulate_line_info (line_info *line, source_info *src,
				  bool add_coverage)
{
  if (add_coverage)
    for (vector<arc_info *>::iterator it = line->branches.begin ();
	 it != line->branches.end (); it++)
      add_branch_counts (&src->coverage, *it);

  if (!line->blocks.empty ())
    {
      /* The user expects the line count to be the number of times
	 a line has been executed.  Simply summing the block count
	 will give an artificially high number.  The Right Thing
	 is to sum the entry counts to the graph of blocks on this
	 line, then find the elementary cycles of the local graph
	 and add the transition counts of those cycles.  */
      gcov_type count = 0;

      /* Cycle detection.  */
      for (vector<block_info *>::iterator it = line->blocks.begin ();
	   it != line->blocks.end (); it++)
	{
	  for (arc_info *arc = (*it)->pred; arc; arc = arc->pred_next)
	    if (!line->has_block (arc->src))
	      count += arc->count;
	  for (arc_info *arc = (*it)->succ; arc; arc = arc->succ_next)
	    arc->cs_count = arc->count;
	}

      /* Now, add the count of loops entirely on this line.  */
      count += get_cycles_count (*line);
      line->count = count;

      if (line->count > src->maximum_count)
	src->maximum_count = line->count;
    }

  if (line->exists && add_coverage)
    {
      src->coverage.lines++;
      if (line->count)
	src->coverage.lines_executed++;
    }
}

/* Accumulate the line counts of a file.  */

static void
accumulate_line_counts (source_info *src)
{
  /* First work on group functions.  */
  for (vector<function_info *>::iterator it = src->functions.begin ();
       it != src->functions.end (); it++)
    {
      function_info *fn = *it;

      if (fn->src != src->index || !fn->is_group)
	continue;

      for (vector<line_info>::iterator it2 = fn->lines.begin ();
	   it2 != fn->lines.end (); it2++)
	  {
	    line_info *line = &(*it2);
	    accumulate_line_info (line, src, true);
	  }
    }

  /* Work on global lines that line in source file SRC.  */
  for (vector<line_info>::iterator it = src->lines.begin ();
       it != src->lines.end (); it++)
    accumulate_line_info (&(*it), src, true);

  /* If not using intermediate mode, sum lines of group functions and
     add them to lines that live in a source file.  */
  if (!flag_json_format)
    for (vector<function_info *>::iterator it = src->functions.begin ();
	 it != src->functions.end (); it++)
      {
	function_info *fn = *it;

	if (fn->src != src->index || !fn->is_group)
	  continue;

	for (unsigned i = 0; i < fn->lines.size (); i++)
	  {
	    line_info *fn_line = &fn->lines[i];
	    if (fn_line->exists)
	      {
		unsigned ln = fn->start_line + i;
		line_info *src_line = &src->lines[ln];

		if (!src_line->exists)
		  src->coverage.lines++;
		if (!src_line->count && fn_line->count)
		  src->coverage.lines_executed++;

		src_line->count += fn_line->count;
		src_line->exists = 1;

		if (fn_line->has_unexecuted_block)
		  src_line->has_unexecuted_block = 1;

		if (fn_line->unexceptional)
		  src_line->unexceptional = 1;
	      }
	  }
      }
}

/* Output information about ARC number IX.  Returns nonzero if
   anything is output.  */

static int
output_branch_count (FILE *gcov_file, int ix, const arc_info *arc)
{
  if (arc->is_call_non_return)
    {
      if (arc->src->count)
	{
	  fnotice (gcov_file, "call   %2d returned %s\n", ix,
		   format_gcov (arc->src->count - arc->count,
				arc->src->count, -flag_counts));
	}
      else
	fnotice (gcov_file, "call   %2d never executed\n", ix);
    }
  else if (!arc->is_unconditional)
    {
      if (arc->src->count)
	fnotice (gcov_file, "branch %2d taken %s%s", ix,
		 format_gcov (arc->count, arc->src->count, -flag_counts),
		 arc->fall_through ? " (fallthrough)"
		 : arc->is_throw ? " (throw)" : "");
      else
	fnotice (gcov_file, "branch %2d never executed%s", ix,
		 (arc->fall_through ? " (fallthrough)"
		  : arc->is_throw ? " (throw)" : ""));

      if (flag_verbose)
	fnotice (gcov_file, " (BB %d)", arc->dst->id);

      fnotice (gcov_file, "\n");
    }
  else if (flag_unconditional && !arc->dst->is_call_return)
    {
      if (arc->src->count)
	fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
		 format_gcov (arc->count, arc->src->count, -flag_counts));
      else
	fnotice (gcov_file, "unconditional %2d never executed\n", ix);
    }
  else
    return 0;
  return 1;
}

static const char *
read_line (FILE *file)
{
  static char *string;
  static size_t string_len;
  size_t pos = 0;

  if (!string_len)
    {
      string_len = 200;
      string = XNEWVEC (char, string_len);
    }

  while (fgets (string + pos, string_len - pos, file))
    {
      size_t len = strlen (string + pos);

      if (len && string[pos + len - 1] == '\n')
	{
	  string[pos + len - 1] = 0;
	  return string;
	}
      pos += len;
      /* If the file contains NUL characters or an incomplete
	 last line, which can happen more than once in one run,
	 we have to avoid doubling the STRING_LEN unnecessarily.  */
      if (pos > string_len / 2)
	{
	  string_len *= 2;
	  string = XRESIZEVEC (char, string, string_len);
	}
    }

  return pos ? string : NULL;
}

/* Pad string S with spaces from left to have total width equal to 9.  */

static void
pad_count_string (string &s)
{
  if (s.size () < 9)
    s.insert (0, 9 - s.size (), ' ');
}

/* Print GCOV line beginning to F stream.  If EXISTS is set to true, the
   line exists in source file.  UNEXCEPTIONAL indicated that it's not in
   an exceptional statement.  The output is printed for LINE_NUM of given
   COUNT of executions.  EXCEPTIONAL_STRING and UNEXCEPTIONAL_STRING are
   used to indicate non-executed blocks.  */

static void
output_line_beginning (FILE *f, bool exists, bool unexceptional,
		       bool has_unexecuted_block,
		       gcov_type count, unsigned line_num,
		       const char *exceptional_string,
		       const char *unexceptional_string,
		       unsigned int maximum_count)
{
  string s;
  if (exists)
    {
      if (count > 0)
	{
	  s = format_gcov (count, 0, -1);
	  if (has_unexecuted_block
	      && bbg_supports_has_unexecuted_blocks)
	    {
	      if (flag_use_colors)
		{
		  pad_count_string (s);
		  s.insert (0, SGR_SEQ (COLOR_BG_MAGENTA
					COLOR_SEPARATOR COLOR_FG_WHITE));
		  s += SGR_RESET;
		}
	      else
		s += "*";
	    }
	  pad_count_string (s);
	}
      else
	{
	  if (flag_use_colors)
	    {
	      s = "0";
	      pad_count_string (s);
	      if (unexceptional)
		s.insert (0, SGR_SEQ (COLOR_BG_RED
				      COLOR_SEPARATOR COLOR_FG_WHITE));
	      else
		s.insert (0, SGR_SEQ (COLOR_BG_CYAN
				      COLOR_SEPARATOR COLOR_FG_WHITE));
	      s += SGR_RESET;
	    }
	  else
	    {
	      s = unexceptional ? unexceptional_string : exceptional_string;
	      pad_count_string (s);
	    }
	}
    }
  else
    {
      s = "-";
      pad_count_string (s);
    }

  /* Format line number in output.  */
  char buffer[16];
  sprintf (buffer, "%5u", line_num);
  string linestr (buffer);

  if (flag_use_hotness_colors && maximum_count)
    {
      if (count * 2 > maximum_count) /* > 50%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_RED));
      else if (count * 5 > maximum_count) /* > 20%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_YELLOW));
      else if (count * 10 > maximum_count) /* > 10%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_GREEN));
      linestr += SGR_RESET;
    }

  fprintf (f, "%s:%s", s.c_str (), linestr.c_str ());
}

static void
print_source_line (FILE *f, const vector<const char *> &source_lines,
		   unsigned line)
{
  gcc_assert (line >= 1);
  gcc_assert (line <= source_lines.size ());

  fprintf (f, ":%s\n", source_lines[line - 1]);
}

/* Output line details for LINE and print it to F file.  LINE lives on
   LINE_NUM.  */

static void
output_line_details (FILE *f, const line_info *line, unsigned line_num)
{
  if (flag_all_blocks)
    {
      arc_info *arc;
      int jx = 0;
      for (vector<block_info *>::const_iterator it = line->blocks.begin ();
	   it != line->blocks.end (); it++)
	{
	  if (!(*it)->is_call_return)
	    {
	      output_line_beginning (f, line->exists,
				     (*it)->exceptional, false,
				     (*it)->count, line_num,
				     "%%%%%", "$$$$$", 0);
	      fprintf (f, "-block %d", (*it)->id);
	      if (flag_verbose)
		fprintf (f, " (BB %u)", (*it)->id);
	      fprintf (f, "\n");
	    }
	  if (flag_branches)
	    for (arc = (*it)->succ; arc; arc = arc->succ_next)
	      jx += output_branch_count (f, jx, arc);
	}
    }
  else if (flag_branches)
    {
      int ix;

      ix = 0;
      for (vector<arc_info *>::const_iterator it = line->branches.begin ();
	   it != line->branches.end (); it++)
	ix += output_branch_count (f, ix, (*it));
    }
}

/* Output detail statistics about function FN to file F.  */

static void
output_function_details (FILE *f, function_info *fn)
{
  if (!flag_branches)
    return;

  arc_info *arc = fn->blocks[EXIT_BLOCK].pred;
  gcov_type return_count = fn->blocks[EXIT_BLOCK].count;
  gcov_type called_count = fn->blocks[ENTRY_BLOCK].count;

  for (; arc; arc = arc->pred_next)
    if (arc->fake)
      return_count -= arc->count;

  fprintf (f, "function %s", fn->get_name ());
  fprintf (f, " called %s",
	   format_gcov (called_count, 0, -1));
  fprintf (f, " returned %s",
	   format_gcov (return_count, called_count, 0));
  fprintf (f, " blocks executed %s",
	   format_gcov (fn->blocks_executed, fn->get_block_count (), 0));
  fprintf (f, "\n");
}

/* 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.  */

static void
output_lines (FILE *gcov_file, const source_info *src)
{
#define  DEFAULT_LINE_START "        -:    0:"
#define FN_SEPARATOR "------------------\n"

  FILE *source_file;
  const char *retval;

  /* Print colorization legend.  */
  if (flag_use_colors)
    fprintf (gcov_file, "%s",
	     DEFAULT_LINE_START "Colorization: profile count: " \
	     SGR_SEQ (COLOR_BG_CYAN) "zero coverage (exceptional)" SGR_RESET \
	     " " \
	     SGR_SEQ (COLOR_BG_RED) "zero coverage (unexceptional)" SGR_RESET \
	     " " \
	     SGR_SEQ (COLOR_BG_MAGENTA) "unexecuted block" SGR_RESET "\n");

  if (flag_use_hotness_colors)
    fprintf (gcov_file, "%s",
	     DEFAULT_LINE_START "Colorization: line numbers: hotness: " \
	     SGR_SEQ (COLOR_BG_RED) "> 50%" SGR_RESET " " \
	     SGR_SEQ (COLOR_BG_YELLOW) "> 20%" SGR_RESET " " \
	     SGR_SEQ (COLOR_BG_GREEN) "> 10%" SGR_RESET "\n");

  fprintf (gcov_file, DEFAULT_LINE_START "Source:%s\n", src->coverage.name);
  if (!multiple_files)
    {
      fprintf (gcov_file, DEFAULT_LINE_START "Graph:%s\n", bbg_file_name);
      fprintf (gcov_file, DEFAULT_LINE_START "Data:%s\n",
	       no_data_file ? "-" : da_file_name);
      fprintf (gcov_file, DEFAULT_LINE_START "Runs:%u\n", object_runs);
    }

  source_file = fopen (src->name, "r");
  if (!source_file)
    fnotice (stderr, "Cannot open source file %s\n", src->name);
  else if (src->file_time == 0)
    fprintf (gcov_file, DEFAULT_LINE_START "Source is newer than graph\n");

  vector<const char *> source_lines;
  if (source_file)
    while ((retval = read_line (source_file)) != NULL)
      source_lines.push_back (xstrdup (retval));

  unsigned line_start_group = 0;
  vector<function_info *> *fns;

  for (unsigned line_num = 1; line_num <= source_lines.size (); line_num++)
    {
      if (line_num >= src->lines.size ())
	{
	  fprintf (gcov_file, "%9s:%5u", "-", line_num);
	  print_source_line (gcov_file, source_lines, line_num);
	  continue;
	}

      const line_info *line = &src->lines[line_num];

      if (line_start_group == 0)
	{
	  fns = src->get_functions_at_location (line_num);
	  if (fns != NULL && fns->size () > 1)
	    {
	      /* It's possible to have functions that partially overlap,
		 thus take the maximum end_line of functions starting
		 at LINE_NUM.  */
	      for (unsigned i = 0; i < fns->size (); i++)
		if ((*fns)[i]->end_line > line_start_group)
		  line_start_group = (*fns)[i]->end_line;
	    }
	  else if (fns != NULL && fns->size () == 1)
	    {
	      function_info *fn = (*fns)[0];
	      output_function_details (gcov_file, fn);
	    }
	}

      /* For lines which don't exist in the .bb file, print '-' before
	 the source line.  For lines which exist but were never
	 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.  */
      output_line_beginning (gcov_file, line->exists, line->unexceptional,
			     line->has_unexecuted_block, line->count,
			     line_num, "=====", "#####", src->maximum_count);

      print_source_line (gcov_file, source_lines, line_num);
      output_line_details (gcov_file, line, line_num);

      if (line_start_group == line_num)
	{
	  for (vector<function_info *>::iterator it = fns->begin ();
	       it != fns->end (); it++)
	    {
	      function_info *fn = *it;
	      vector<line_info> &lines = fn->lines;

	      fprintf (gcov_file, FN_SEPARATOR);

	      string fn_name = fn->get_name ();
	      if (flag_use_colors)
		{
		  fn_name.insert (0, SGR_SEQ (COLOR_FG_CYAN));
		  fn_name += SGR_RESET;
		}

	      fprintf (gcov_file, "%s:\n", fn_name.c_str ());

	      output_function_details (gcov_file, fn);

	      /* Print all lines covered by the function.  */
	      for (unsigned i = 0; i < lines.size (); i++)
		{
		  line_info *line = &lines[i];
		  unsigned l = fn->start_line + i;

		  /* For lines which don't exist in the .bb file, print '-'
		     before the source line.  For lines which exist but
		     were never 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.  */
		  output_line_beginning (gcov_file, line->exists,
					 line->unexceptional,
					 line->has_unexecuted_block,
					 line->count,
					 l, "=====", "#####",
					 src->maximum_count);

		  print_source_line (gcov_file, source_lines, l);
		  output_line_details (gcov_file, line, l);
		}
	    }

	  fprintf (gcov_file, FN_SEPARATOR);
	  line_start_group = 0;
	}
    }

  if (source_file)
    fclose (source_file);
}
