// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2021 Red Hat, Inc.

///@file

// In case we have a bad fts we include this before config.h because
// it can't handle _FILE_OFFSET_BITS.  Everything we need here is fine
// if its declarations just come first.  Also, include sys/types.h
// before fts. On some systems fts.h is not self contained.
#ifdef BAD_FTS
  #include <sys/types.h>
  #include <fts.h>
#endif

// For package configuration macros.
#include "config.h"

// In case we don't have a bad fts then we need to include fts.h after
// config.h.
#ifndef BAD_FTS
  #include <sys/types.h>
  #include <fts.h>
#endif

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <dirent.h>
#include <time.h>
#include <ctype.h>
#include <errno.h>
#include <libgen.h>

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <memory>
#include <sstream>

#include "abg-dwarf-reader.h"
#include "abg-internal.h"
#include "abg-regex.h"

// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS

#include <abg-ir.h>
#include "abg-config.h"
#include "abg-tools-utils.h"

ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>

using std::string;

namespace abigail
{

using namespace abigail::suppr;
using namespace abigail::ini;

/// @brief Namespace for a set of utility function used by tools based
/// on libabigail.
namespace tools_utils
{

/// Get the value of $libdir variable of the autotools build
/// system.  This is where shared libraries are usually installed.
///
/// @return a constant string (doesn't have to be free-ed by the
/// caller) that represent the value of the $libdir variable in the
/// autotools build system, or NULL if it's not set.
const char*
get_system_libdir()
{
#ifndef ABIGAIL_ROOT_SYSTEM_LIBDIR
#error the macro ABIGAIL_ROOT_SYSTEM_LIBDIR must be set at compile time
#endif

  static __thread const char* system_libdir(ABIGAIL_ROOT_SYSTEM_LIBDIR);
  return system_libdir;
}

/// The bitwise 'OR' operator for abidiff_status bit masks.
///
/// @param l the left hand side operand of the OR operator.
///
/// @param r the right hand side operand of the OR operator.
///
/// @return the result of the OR expression.
abidiff_status
operator|(abidiff_status l, abidiff_status r)
{return static_cast<abidiff_status>(static_cast<unsigned>(l)
				     | static_cast<unsigned>(r));}

/// The bitwise 'AND' operator for abidiff_status bit masks.
///
/// @param l the left hand side operand of the AND operator.
///
/// @param r the right hand side operand of the AND operator.
///
/// @return the result of the AND expression.
abidiff_status
operator&(abidiff_status l, abidiff_status r)
{return static_cast<abidiff_status>(static_cast<unsigned>(l)
				     & static_cast<unsigned>(r));}

/// The |= operator.
///
/// @param l the left hand side operand of the operator.
///
/// @param r the right hand side operand of the operator.
///
/// @param the resulting bit mask.
abidiff_status&
operator|=(abidiff_status&l, abidiff_status r)
{
  l = static_cast<abidiff_status>(static_cast<unsigned>(l)
				  | static_cast<unsigned>(r));
  return l;
}

/// Test if an instance of @param abidiff_status bits mask represents
/// an error.
///
/// This functions tests if the @ref ABIDIFF_ERROR bit is set in the
/// given bits mask.
///
/// @param s the bit mask to consider.
///
/// @return true iff @p s has its ABIDIFF_ERROR bit set.
bool
abidiff_status_has_error(abidiff_status s)
{return s & (ABIDIFF_ERROR | ABIDIFF_USAGE_ERROR);}

/// Test if an instance of @param abidiff_status bits mask represents
/// an abi change.
///
/// This functions tests if the @ref ABIDIFF_ABI_CHANGE bit is set in the
/// given bits mask.
///
/// @param s the bit mask to consider.
///
/// @return true iff @p s has its @ref ABIDIFF_ABI_CHANGE bit set.
bool
abidiff_status_has_abi_change(abidiff_status s)
{return s & ABIDIFF_ABI_CHANGE;}

/// Test if an instance of @param abidiff_status bits mask represents
/// an incompatible abi change.
///
/// This functions tests if the @ref ABIDIFF_INCOMPATIBLE_ABI_CHANGE
/// bit is set in the given bits mask.  Note that the this bit is set
/// then the bit @ref ABIDIFF_ABI_CHANGE must be set as well.
///
/// @param s the bit mask to consider.
///
/// @return true iff @p s has its @ref ABIDIFF_INCOMPATIBLE ABI_CHANGE
/// set.
bool
abidiff_status_has_incompatible_abi_change(abidiff_status s)
{return s & ABIDIFF_ABI_INCOMPATIBLE_CHANGE;}

#define DECLARE_STAT(st) \
  struct stat st; \
  memset(&st, 0, sizeof(st))

// <class timer stuff>

/// The private data type of the @ref timer class.
struct timer::priv
{
  timer::kind timer_kind;
  struct timeval begin_timeval;
  struct timeval end_timeval;

  priv(timer::kind k)
    : timer_kind(k),
      begin_timeval(),
      end_timeval()
  {}
}; // end struct timer::priv

/// Constructor of the @ref timer type.
///
/// @param k the kind of timer to instantiate.
timer::timer(timer::kind k)
  : priv_(new timer::priv(k))
{
  if (priv_->timer_kind == START_ON_INSTANTIATION_TIMER_KIND)
    start();
}

/// Start the timer.
///
/// To stop the timer (and record the time elapsed since the timer was
/// started), call the timer::stop member function.
///
/// @return true upon successful completion.
bool
timer::start()
{
  if (gettimeofday(&priv_->begin_timeval, 0))
    return false;
  return true;
}

/// Stop the timer.
///
/// This records the time elapsed since the timer was started using
/// the timer::start member function.
///
/// @return true upon successful completion.
bool
timer::stop()
{
  if (gettimeofday(&priv_->end_timeval, 0))
    return false;
  return true;
}

/// Get the elapsed time in seconds.
///
/// @return the time elapsed between the invocation of the methods
/// timer::start() and timer::stop, in seconds.
time_t
timer::value_in_seconds() const
{return priv_->end_timeval.tv_sec - priv_->begin_timeval.tv_sec;}

/// Get the elapsed time in hour:minutes:seconds:milliseconds.
///
/// @param hours out parameter. This is set to the number of hours elapsed.
///
/// @param minutes out parameter.  This is set to the number of minutes
/// (passed the number of hours) elapsed.
///
/// @param seconds out parameter.  This is se to the number of
/// seconds (passed the number of hours and minutes) elapsed.
///
/// @param milliseconds.  This is set ot the number of milliseconds
/// (passed the number of hours, minutes and seconds) elapsed.
///
/// @return true upon successful completion.
bool
timer::value(time_t&		hours,
	     time_t&		minutes,
	     time_t&		seconds,
	     time_t&	milliseconds) const
{
  time_t elapsed_seconds =
    priv_->end_timeval.tv_sec - priv_->begin_timeval.tv_sec;
  suseconds_t elapsed_usecs =
    ((priv_->end_timeval.tv_sec * 1000000) + priv_->end_timeval.tv_usec)
    - ((priv_->begin_timeval.tv_sec * 1000000) + priv_->begin_timeval.tv_usec);

  milliseconds = 0;

  hours = elapsed_seconds / 3600;
  minutes = (elapsed_seconds % 3600) / 60;
  seconds = (elapsed_seconds % 3600) % 60;
  if (elapsed_seconds == 0)
    milliseconds = elapsed_usecs / 1000;

  return true;
}

/// Get the elapsed time as a human-readable string.
///
/// @return the elapsed time as a human-readable string.
string
timer::value_as_string() const
{
  time_t hours = 0, minutes = 0, seconds = 0;
  time_t msecs = 0;

  value(hours, minutes, seconds, msecs);

  std::ostringstream o;

  if (hours)
    o << hours << "h";

  if (minutes)
    o << minutes << "m";

  o << seconds << "s";

  if (msecs)
    o <<msecs <<"ms";

  return o.str();
}

/// Destructor of the @ref timer type.
timer::~timer()
{
}

/// Streaming operator for the @ref timer type.
///
/// Emit a string representing the elapsed time (in a human-readable
/// manner) to an output stream.
///
/// @param o the output stream to emit the elapsed time string to.
///
/// @param t the timer to consider.
///
/// @return the output stream considered.
ostream&
operator<<(ostream& o, const timer& t)
{
  o << t.value_as_string();
  return o;
}

/// Get the stat struct (as returned by the lstat() function of the C
/// library) of a file.  Note that the function uses lstat, so that
/// callers can detect symbolic links.
///
/// @param path the path to the function to stat.
///
/// @param s the resulting stat struct.
///
/// @return true iff the stat function completed successfully.
static bool
get_stat(const string& path,
	 struct stat* s)
{return (lstat(path.c_str(), s) == 0);}

/// Tests whether a path exists;
///
/// @param path the path to test for.
///
/// @return true iff the path at @p path exist.
bool
file_exists(const string& path)
{
  DECLARE_STAT(st);

  return get_stat(path, &st);
}

/// Test that a given directory exists.
///
/// @param path the path of the directory to consider.
///
/// @return true iff a directory exists with the name @p path
bool
dir_exists(const string &path)
{return file_exists(path) && is_dir(path);}

/// Test if a given directory exists and is empty.
///
/// @param path the path of the directory to consider
bool
dir_is_empty(const string &path)
{
  if (!dir_exists(path))
    return false;

  DIR* dir = opendir(path.c_str());
  if (!dir)
    return false;

  errno = 0;
  dirent *result = readdir(dir);
  if (result == NULL && errno != 0)
    return false;

  closedir(dir);

  return result == NULL;
}

/// Test if path is a path to a regular file or a symbolic link to a
/// regular file.
///
/// @param path the path to consider.
///
/// @return true iff path is a regular path.
bool
is_regular_file(const string& path)
{
  DECLARE_STAT(st);

  if (!get_stat(path, &st))
    return false;

  if (S_ISREG(st.st_mode))
    return true;

  string symlink_target_path;
  if (maybe_get_symlink_target_file_path(path, symlink_target_path))
    return is_regular_file(symlink_target_path);

  return false;
}

/// Tests if a given path is a directory or a symbolic link to a
/// directory.
///
/// @param path the path to test for.
///
/// @return true iff @p path is a directory.
bool
is_dir(const string& path)
{
  DECLARE_STAT(st);

  if (!get_stat(path, &st))
    return false;

  if (S_ISDIR(st.st_mode))
    return true;

  string symlink_target_path;
  if (maybe_get_symlink_target_file_path(path, symlink_target_path))
    return is_dir(symlink_target_path);

  return false;
}

static const char* ANONYMOUS_STRUCT_INTERNAL_NAME = "__anonymous_struct__";
static const char* ANONYMOUS_UNION_INTERNAL_NAME =  "__anonymous_union__";
static const char* ANONYMOUS_ENUM_INTERNAL_NAME =   "__anonymous_enum__";

static int ANONYMOUS_STRUCT_INTERNAL_NAME_LEN =
  strlen(ANONYMOUS_STRUCT_INTERNAL_NAME);

static int ANONYMOUS_UNION_INTERNAL_NAME_LEN =
  strlen(ANONYMOUS_UNION_INTERNAL_NAME);

static int ANONYMOUS_ENUM_INTERNAL_NAME_LEN =
  strlen(ANONYMOUS_ENUM_INTERNAL_NAME);

/// Getter of the prefix for the name of anonymous structs.
///
/// @reaturn the prefix for the name of anonymous structs.
const char*
get_anonymous_struct_internal_name_prefix()
{return ANONYMOUS_STRUCT_INTERNAL_NAME;}

/// Getter of the prefix for the name of anonymous unions.
///
/// @reaturn the prefix for the name of anonymous unions.
const char*
get_anonymous_union_internal_name_prefix()
{return ANONYMOUS_UNION_INTERNAL_NAME;}

/// Getter of the prefix for the name of anonymous enums.
///
/// @reaturn the prefix for the name of anonymous enums.
const char*
get_anonymous_enum_internal_name_prefix()
{return ANONYMOUS_ENUM_INTERNAL_NAME;}

/// Compare two fully qualified decl names by taking into account that
/// they might have compontents that are anonymous types/namespace names.
///
/// For instance:
///
/// __anonymous_struct__1::foo and __anonymous_struct__2::foo are
/// considered being equivalent qualified names because both are data
/// members that belong to anonymous structs.  The anonymous structs
/// are numbered so that we can tell them appart (and look them up)
/// where there are several of them in the same scope.  But during
/// comparison, for various purposes, we want to consider them as
/// equivalent.
///
/// Similarly, __anonymous_struct__1::foo::__anonymous_struct__2::bar
/// and __anonymous_struct__10::foo::__anonymous_struct__11::bar are
/// equivalent.
///
/// But __anonymous_struct__1::foo::__anonymous_struct__2::bar and
/// __anonymous_struct__10::foo::__anonymous_union__11::bar are not
/// equivalent because the former designates a member of an anonymous
/// struct and the latter designates a member of an anonymous union.
///
/// So this function handles those cases.
///
/// @param l the name of the first (left hand side) decl to consider.
///
/// @param r the name of the second (right hand side) decl to consider.
///
/// @return true iff @p l is equivalent to @p r when taking into
/// account the anonymous scopes that both might have and if they
/// might be anonymous themselves.
bool
decl_names_equal(const string& l, const string& r)
{
  string::size_type l_pos1 = 0, r_pos1 = 0;
  const string::size_type l_length = l.length(), r_length = r.length();

  while (l_pos1 < l_length && r_pos1 < r_length)
    {
      string::size_type l_pos2 = l.find("::", l_pos1);
      string::size_type r_pos2 = r.find("::", r_pos1);
      if (l_pos2 == string::npos)
	l_pos2 = l_length;
      if (r_pos2 == string::npos)
	r_pos2 = r_length;

      if (l.compare(l_pos1, l_pos2 - l_pos1, r,
		    r_pos1, r_pos2 - r_pos1)
	  && (l.compare(l_pos1,
			ANONYMOUS_STRUCT_INTERNAL_NAME_LEN,
			ANONYMOUS_STRUCT_INTERNAL_NAME)
	      || r.compare(r_pos1,
			   ANONYMOUS_STRUCT_INTERNAL_NAME_LEN,
			   ANONYMOUS_STRUCT_INTERNAL_NAME))
	  && (l.compare(l_pos1,
			ANONYMOUS_UNION_INTERNAL_NAME_LEN,
			ANONYMOUS_UNION_INTERNAL_NAME)
	      || r.compare(r_pos1,
			   ANONYMOUS_UNION_INTERNAL_NAME_LEN,
			   ANONYMOUS_UNION_INTERNAL_NAME))
	  && (l.compare(l_pos1,
			ANONYMOUS_ENUM_INTERNAL_NAME_LEN,
			ANONYMOUS_ENUM_INTERNAL_NAME)
	      || r.compare(r_pos1,
			   ANONYMOUS_ENUM_INTERNAL_NAME_LEN,
			   ANONYMOUS_ENUM_INTERNAL_NAME)))
	return false;

      l_pos1 = l_pos2 == l_length ? l_pos2 : l_pos2 + 2;
      r_pos1 = r_pos2 == r_length ? r_pos2 : r_pos2 + 2;
    }

  return (l_pos1 == l_length) == (r_pos1 == r_length);
}

/// If a given file is a symbolic link, get the canonicalized absolute
/// path to the target file.
///
/// @param file_path the path to the file to consider.
///
/// @param target_path this parameter is set by the function to the
/// canonicalized path to the target file, if @p file_path is a
/// symbolic link.  In that case, the function returns true.
///
/// @return true iff @p file_path is a symbolic link.  In that case,
/// the function sets @p target_path to the canonicalized absolute
/// path of the target file.
bool
maybe_get_symlink_target_file_path(const string& file_path,
				   string& target_path)
{
  DECLARE_STAT(st);

  if (!get_stat(file_path, &st))
    return false;

  if (!S_ISLNK(st.st_mode))
    return false;

  char *link_target_path = realpath(file_path.c_str(), NULL);
  if (!link_target_path)
    return false;

  target_path = link_target_path;
  free(link_target_path);
  return true;
}

/// Return the directory part of a file path.
///
/// @param path the file path to consider
///
/// @param dirnam the resulting directory part, or "." if the couldn't
/// figure out anything better (for now; maybe we should do something
/// better than this later ...).
///
/// @param keep_separator_at_end if true, then keep the separator at
/// the end of the resulting dir name.
///
/// @return true upon successful completion, false otherwise (okay,
/// for now it always return true, but that might change in the future).
bool
dir_name(string const& path,
	 string& dir_name,
	 bool keep_separator_at_end)
{
  if (path.empty())
    {
      dir_name = ".";
      return true;
    }

  char *p = strdup(path.c_str());
  char *r = ::dirname(p);
  dir_name = r;
  free(p);
  if (keep_separator_at_end
      && dir_name.length() < path.length())
    dir_name += "/";
  return true;
}

/// Return the file name part of a file part.
///
/// @param path the file path to consider.
///
/// @param file_name the name part of the file to consider.
///
///@return true upon successful completion, false otherwise (okay it
///always return true for now, but that might change in the future).
bool
base_name(string const &path,
	 string& file_name)
{
  if (path.empty())
    {
      file_name = ".";
      return true;
    }

  char *p = strdup(path.c_str());
  char *f = ::basename(p);
  file_name = f;
  free(p);
  return true;
}

/// Return the real path of a given path.
///
/// The real path of path 'foo_path' is the same path as foo_path, but
/// with symlinks and relative paths resolved.
///
/// @param path the path to consider.
///
/// @param result the computed real_path;
void
real_path(const string&path, string& result)
{
  if (path.empty())
    {
      result.clear();
      return;
    }

  char *realp = realpath(path.c_str(), NULL);
  if (realp)
    {
      result = realp;
      free(realp);
    }
}

/// Ensures #dir_path is a directory and is created.  If #dir_path is
/// not created, this function creates it.
///
/// \return true if #dir_path is a directory that is already present,
/// of if the function has successfuly created it.
bool
ensure_dir_path_created(const string& dir_path)
{
  struct stat st;
  memset(&st, 0, sizeof (st));

  int stat_result = 0;

  stat_result = stat(dir_path.c_str(), &st);
  if (stat_result == 0)
    {
      // A file or directory already exists with the same name.
      if (!S_ISDIR (st.st_mode))
	return false;
      return true;
    }

  string cmd;
  cmd = "mkdir -p " + dir_path;

  if (system(cmd.c_str()))
    return false;

  return true;
}

/// Ensures that the parent directory of #path is created.
///
/// \return true if the parent directory of #path is already present,
/// or if this function has successfuly created it.
bool
ensure_parent_dir_created(const string& path)
{
  bool is_ok = false;

  if (path.empty())
    return is_ok;

  string parent;
  if (dir_name(path, parent))
    is_ok = ensure_dir_path_created(parent);

  return is_ok;
}

/// Emit a prefix made of the name of the program which is emitting a
/// message to an output stream.
///
/// The prefix is a string which looks like:
///
///   "<program-name> : "
///
/// @param prog_name the name of the program to use in the prefix.
/// @param out the output stream where to emit the prefix.
///
/// @return the output stream where the prefix was emitted.
ostream&
emit_prefix(const string& prog_name, ostream& out)
{
  if (!prog_name.empty())
    out << prog_name << ": ";
  return out;
}

/// Check if a given path exists and is readable.
///
/// @param path the path to consider.
///
/// @param out the out stream to report errors to.
///
/// @return true iff path exists and is readable.
bool
check_file(const string& path, ostream& out, const string& prog_name)
{
  if (!file_exists(path))
    {
      emit_prefix(prog_name, out) << "file " << path << " does not exist\n";
      return false;
    }

  if (!is_regular_file(path))
    {
      emit_prefix(prog_name, out) << path << " is not a regular file\n";
      return false;
    }

  return true;
}

/// Check if a given path exists, is readable and is a directory.
///
/// @param path the path to consider.
///
/// @param out the out stream to report errors to.
///
/// @param prog_name the program name on behalf of which to report the
/// error, if any.
///
/// @return true iff @p path exists and is for a directory.
bool
check_dir(const string& path, ostream& out, const string& prog_name)
{
  if (!file_exists(path))
    {
      emit_prefix(prog_name, out) << "path " << path << " does not exist\n";
      return false;
    }

  if (!is_dir(path))
    {
      emit_prefix(prog_name, out) << path << " is not a directory\n";
      return false;
    }

  return true;
}

/// Test if a given string ends with a particular suffix.
///
/// @param str the string to consider.
///
/// @param suffix the suffix to test for.
///
/// @return true iff string @p str ends with suffix @p suffix.
bool
string_ends_with(const string& str, const string& suffix)
{
  string::size_type str_len = str.length(), suffix_len = suffix.length();

  if (str_len < suffix_len)
    return false;
  return str.compare(str_len - suffix_len, suffix_len, suffix) == 0;
}

/// Test if a given string begins with a particular prefix.
///
/// @param str the string consider.
///
/// @param prefix the prefix to look for.
///
/// @return true iff string @p str begins with prefix @p prefix.
bool
string_begins_with(const string& str, const string& prefix)
{
  if (str.empty())
    return false;

  if (prefix.empty())
    return true;

  string::size_type prefix_len = prefix.length();
  if (prefix_len > str.length())
    return false;

  return str.compare(0, prefix.length(), prefix) == 0;
}

/// Test if a string is made of ascii characters.
///
/// @param str the string to consider.
///
/// @return true iff @p str is made of ascii characters.
bool
string_is_ascii(const string& str)
{
  for (string::const_iterator i = str.begin(); i != str.end(); ++i)
    if (!isascii(*i))
      return false;

  return true;
}

/// Test if a string is made of ascii characters which are identifiers
/// acceptable in C or C++ programs.
///
///
/// In the C++ spec, [lex.charset]/2, we can read:
///
/// "if the hexadecimal value for a universal-character-name [...]  or
///  string literal corresponds to a control character (in either of
///  the ranges 0x00-0x1F or 0x7F-0x9F, both inclusive) [...] the
///  program is ill-formed."
///
/// @param str the string to consider.
///
/// @return true iff @p str is made of ascii characters, and is an
/// identifier.
bool
string_is_ascii_identifier(const string& str)
{
  for (string::const_iterator i = str.begin(); i != str.end(); ++i)
    {
      unsigned char c = *i;
    if (!isascii(c)
	|| (c <= 0x1F) // Rule out control characters
	|| (c >= 0x7F && c <= 0x9F)) // Rule out special extended
				     // ascii characters.
      return false;
    }

  return true;
}

/// Split a given string into substrings, given some delimiters.
///
/// @param input_string the input string to split.
///
/// @param delims a string containing the delimiters to consider.
///
/// @param result a vector of strings containing the splitted result.
///
/// @return true iff the function found delimiters in the input string
/// and did split it as a result.  Note that if no delimiter was found
/// in the input string, then the input string is added at the end of
/// the output vector of strings.
bool
split_string(const string& input_string,
	     const string& delims,
	     vector<string>& result)
{
  size_t current = 0, next;
  bool did_split = false;

  do
    {
      // Trim leading white spaces
      while (current < input_string.size() && isspace(input_string[current]))
	++current;

      if (current >= input_string.size())
	break;

      next = input_string.find_first_of(delims, current);
      if (next == string::npos)
	{
	  string s = input_string.substr(current);
	  if (!s.empty())
	    result.push_back(input_string.substr(current));
	  did_split = (current != 0);
	  break;
	}
      string s = input_string.substr(current, next - current);
      if (!s.empty())
	{
	  result.push_back(input_string.substr(current, next - current));
	  did_split = true;
	}
      current = next + 1;
    }
  while (next != string::npos);

  return did_split;
}

/// Get the suffix of a string, given a prefix to consider.
///
/// @param input_string the input string to consider.
///
/// @param prefix the prefix of the input string to consider.
///
/// @param suffix output parameter. This is set by the function to the
/// the computed suffix iff a suffix was found for prefix @p prefix.
///
/// @return true iff the function could find a prefix for the suffix
/// @p suffix in the input string @p input_string.
bool
string_suffix(const string& input_string,
	      const string& prefix,
	      string& suffix)
{
  // Some basic sanity check before we start hostilities.
  if (prefix.length() >= input_string.length())
    return false;

  if (input_string.compare(0, prefix.length(), prefix) != 0)
    // The input string does not start with the string contained in
    // the prefix parameter.
    return false;

  suffix = input_string.substr(prefix.length());
  return true;
}

/// Return the prefix that is common to two strings.
///
/// @param s1 the first input string to consider.
///
/// @param s2 the second input string to consider.
///
/// @param result output parameter.  The resulting common prefix found
/// between @p s1 and @p s2.  This is set iff the function returns
/// true.
///
/// @return true iff @p result was set by this function with the
/// common prefix of @p s1 and @p s2.
static bool
common_prefix(const string& s1, const string& s2, string &result)
{
  if (s1.length() == 0 || s2.length() == 0)
    return false;

  result.clear();
  for (size_t i = 0; i < s1.length() && i< s2.length(); ++i)
    if (s1[i] == s2[i])
      result += s1[i];
    else
      break;

  return !result.empty();
}

/// Find the prefix common to a *SORTED* vector of strings.
///
/// @param input_strings a lexycographically sorted vector of
/// strings.  Please note that this vector absolutely needs to be
/// sorted for the function to work correctly.  Otherwise the results
/// are going to be wrong.
///
/// @param prefix output parameter.  This is set by this function with
/// the prefix common to the strings found in @p input_strings, iff
/// the function returns true.
///
/// @return true iff the function could find a common prefix to the
/// strings in @p input_strings.
bool
sorted_strings_common_prefix(vector<string>& input_strings, string& prefix)
{
  string prefix_candidate;
  bool found_prefix = false;

  if (input_strings.size() == 1)
    {
      if (dir_name(input_strings.front(), prefix,
		   /*keep_separator_at_end=*/true))
	return true;
      return false;
    }

  string cur_str;
  for (vector<string>::const_iterator i = input_strings.begin();
       i != input_strings.end();
       ++i)
    {
      dir_name(*i, cur_str, /*keep_separator_at_end=*/true);
      if (prefix_candidate.empty())
	{
	  prefix_candidate = cur_str;
	  continue;
	}

      string s;
      if (common_prefix(prefix_candidate, cur_str, s))
	{
	  ABG_ASSERT(!s.empty());
	  prefix_candidate = s;
	  found_prefix = true;
	}
    }

  if (found_prefix)
    {
      prefix = prefix_candidate;
      return true;
    }

  return false;
}

/// Return the version string of the library.
///
/// @return the version string of the library.
string
get_library_version_string()
{
  string major, minor, revision, version_string, suffix;
  abigail::abigail_get_library_version(major, minor, revision, suffix);
  version_string = major + "." + minor + "." + revision + suffix;
  return version_string;
}

/// Return the version string for the ABIXML format.
///
/// @return the version string of the ABIXML format.
string
get_abixml_version_string()
{
  string major, minor, version_string;
  abigail::abigail_get_abixml_version(major, minor);
  version_string = major + "." + minor;
  return version_string;
}

/// Execute a shell command and returns its output.
///
/// @param cmd the shell command to execute.
///
/// @param lines output parameter.  This is set with the lines that
/// constitute the output of the process that executed the command @p
/// cmd.
///
/// @return true iff the command was executed properly and no error
/// was encountered.
bool
execute_command_and_get_output(const string& cmd, vector<string>& lines)
{
  if (cmd.empty())
    return false;

  FILE *stream=
    popen(cmd.c_str(),
	  /*open 'stream' in
	    read-only mode: type=*/"r");

  if (stream == NULL)
    return false;

  string result;

#define TMP_BUF_LEN 1024 + 1
  char tmp_buf[TMP_BUF_LEN];
  memset(tmp_buf, 0, TMP_BUF_LEN);

  while (fgets(tmp_buf, TMP_BUF_LEN, stream))
    {
      lines.push_back(tmp_buf);
      memset(tmp_buf, 0, TMP_BUF_LEN);
    }

  if (pclose(stream) == -1)
    return false;

  return true;
}

/// Get the SONAMEs of the DSOs advertised as being "provided" by a
/// given RPM.  That set can be considered as being the set of
/// "public" DSOs of the RPM.
///
/// This runs the command "rpm -qp --provides <rpm> | grep .so" and
/// filters its result.
///
/// @param rpm_path the path to the RPM to consider.
///
/// @param provided_dsos output parameter.  This is set to the set of
/// SONAMEs of the DSOs advertised as being provided by the RPM
/// designated by @p rpm_path.
///
/// @return true iff we could successfully query the RPM to see what
/// DSOs it provides.
bool
get_dsos_provided_by_rpm(const string& rpm_path, set<string>& provided_dsos)
{
  vector<string> query_output;
  // We don't check the return value of this command because on some
  // system, the command can issue errors but still emit a valid
  // output.  We'll rather rely on the fact that the command emits a
  // valid output or not.
  execute_command_and_get_output("rpm -qp --provides "
				 + rpm_path + " 2> /dev/null | grep .so",
				 query_output);

  for (vector<string>::const_iterator line = query_output.begin();
       line != query_output.end();
       ++line)
    {
      string dso = line->substr(0, line->find('('));
      dso = trim_white_space(dso);
      if (!dso.empty())
	provided_dsos.insert(dso);
    }
  return true;
}

/// Remove spaces at the beginning and at the end of a given string.
///
/// @param str the input string to consider.
///
/// @return the @p str string with leading and trailing white spaces removed.
string
trim_white_space(const string& str)
{
  if (str.empty())
    return "";

  string result;
  string::size_type start, end;
  for (start = 0; start < str.length(); ++start)
    if (!isspace(str[start]))
      break;

  for (end = str.length() - 1; end > 0; --end)
    if (!isspace(str[end]))
      break;

  result = str.substr(start, end - start + 1);
  return result;
}

/// Remove a string of pattern in front of a given string.
///
/// For instance, consider this string:
///    "../../../foo"
///
/// The pattern "../" is repeated three times in front of the
/// sub-string "foo".  Thus, the call:
///    trim_leading_string("../../../foo", "../")
/// will return the string "foo".
///
/// @param from the string to trim the leading repetition of pattern from.
///
/// @param to_trim the pattern to consider (and to trim).
///
/// @return the resulting string where the leading patter @p to_trim
/// has been removed from.
string
trim_leading_string(const string& from, const string& to_trim)
{
  string str = from;

  while (string_begins_with(str, to_trim))
    string_suffix(str, to_trim, str);
  return str;
}

/// Convert a vector<char*> into a vector<char**>.
///
/// @param char_stars the input vector.
///
/// @param char_star_stars the output vector.
void
convert_char_stars_to_char_star_stars(const vector<char*> &char_stars,
				      vector<char**>& char_star_stars)
{
  for (vector<char*>::const_iterator i = char_stars.begin();
       i != char_stars.end();
       ++i)
    char_star_stars.push_back(const_cast<char**>(&*i));
}

/// The private data of the @ref temp_file type.
struct temp_file::priv
{
  char*			   path_template_;
  int			   fd_;
  shared_ptr<std::fstream> fstream_;

  priv()
  {
    const char* templat = "/tmp/libabigail-tmp-file-XXXXXX";
    int s = strlen(templat);
    path_template_ = new char[s + 1];
    memset(path_template_, 0, s + 1);
    memcpy(path_template_, templat, s);

    fd_ = mkstemp(path_template_);
    if (fd_ == -1)
      return;

    fstream_.reset(new std::fstream(path_template_,
				    std::ios::trunc
				    | std::ios::in
				    | std::ios::out));
  }

  ~priv()
  {
    if (fd_ && fd_ != -1)
      {
	fstream_.reset();
	close(fd_);
	remove(path_template_);
      }
    delete [] path_template_;
  }
};

/// Default constructor of @ref temp_file.
///
/// It actually creates the temporary file.
temp_file::temp_file()
  : priv_(new priv)
{}

/// Test if the temporary file has been created and is usable.
///
/// @return true iff the temporary file has been created and is
/// useable.
bool
temp_file::is_good() const
{return priv_->fstream_->good();}

/// Return the path to the temporary file.
///
/// @return the path to the temporary file if it's usable, otherwise
/// return nil.
const char*
temp_file::get_path() const
{
  if (is_good())
    return priv_->path_template_;

  return 0;
}

/// Get the fstream to the temporary file.
///
/// Note that the current process is aborted if this member function
/// is invoked on an instance of @ref temp_file that is not usable.
/// So please test that the instance is usable by invoking the
/// temp_file::is_good() member function on it first.
///
/// @return the fstream to the temporary file.
std::fstream&
temp_file::get_stream()
{
  ABG_ASSERT(is_good());
  return *priv_->fstream_;
}

/// Create the temporary file and return it if it's usable.
///
/// @return the newly created temporary file if it's usable, nil
/// otherwise.
temp_file_sptr
temp_file::create()
{
  temp_file_sptr result(new temp_file);
  if (result->is_good())
    return result;

  return temp_file_sptr();
}

/// Get a pseudo random number.
///
/// @return a pseudo random number.
size_t
get_random_number()
{
  static __thread bool initialized = false;

  if (!initialized)
    {
      srand(time(NULL));
      initialized = true;
    }

  return rand();
}

/// Get a pseudo random number as string.
///
/// @return a pseudo random number as string.
string
get_random_number_as_string()
{
  std::ostringstream o;
  o << get_random_number();

  return o.str();
}

ostream&
operator<<(ostream& output,
	   file_type r)
{
  string repr;

  switch(r)
    {
    case FILE_TYPE_UNKNOWN:
      repr = "unknown file type";
      break;
    case FILE_TYPE_NATIVE_BI:
      repr = "native binary instrumentation file type";
      break;
    case FILE_TYPE_ELF:
      repr = "ELF file type";
      break;
    case FILE_TYPE_AR:
      repr = "archive file type";
      break;
    case FILE_TYPE_XML_CORPUS:
      repr = "native XML corpus file type";
      break;
    case FILE_TYPE_XML_CORPUS_GROUP:
      repr = "native XML corpus group file type";
      break;
    case FILE_TYPE_RPM:
      repr = "RPM file type";
      break;
    case FILE_TYPE_SRPM:
      repr = "SRPM file type";
      break;
    case FILE_TYPE_DEB:
      repr = "Debian binary file type";
      break;
    case FILE_TYPE_DIR:
      repr = "Directory type";
      break;
    case FILE_TYPE_TAR:
      repr = "GNU tar archive type";
      break;
    }

  output << repr;
  return output;
}

/// Guess the type of the content of an input stream.
///
/// @param in the input stream to guess the content type for.
///
/// @return the type of content guessed.
file_type
guess_file_type(istream& in)
{
  const unsigned BUF_LEN = 264;
  const unsigned NB_BYTES_TO_READ = 263;

  char buf[BUF_LEN];
  memset(buf, 0, BUF_LEN);

  std::streampos initial_pos = in.tellg();
  in.read(buf, NB_BYTES_TO_READ);
  in.seekg(initial_pos);

  if (in.gcount() < 4 || in.bad())
    return FILE_TYPE_UNKNOWN;

  if (buf[0] == 0x7f
      && buf[1] == 'E'
      && buf[2] == 'L'
      && buf[3] == 'F')
    return FILE_TYPE_ELF;

  if (buf[0] == '!'
      && buf[1] == '<'
      && buf[2] == 'a'
      && buf[3] == 'r'
      && buf[4] == 'c'
      && buf[5] == 'h'
      && buf[6] == '>')
    {
      if (strstr(buf, "debian-binary"))
	return FILE_TYPE_DEB;
      else
	return FILE_TYPE_AR;
    }

  if (buf[0] == '<'
      && buf[1] == 'a'
      && buf[2] == 'b'
      && buf[3] == 'i'
      && buf[4] == '-'
      && buf[5] == 'i'
      && buf[6] == 'n'
      && buf[7] == 's'
      && buf[8] == 't'
      && buf[9] == 'r'
      && buf[10] == ' ')
    return FILE_TYPE_NATIVE_BI;

  if (buf[0]     == '<'
      && buf[1]  == 'a'
      && buf[2]  == 'b'
      && buf[3]  == 'i'
      && buf[4]  == '-'
      && buf[5]  == 'c'
      && buf[6]  == 'o'
      && buf[7]  == 'r'
      && buf[8]  == 'p'
      && buf[9]  == 'u'
      && buf[10] == 's'
      && buf[11] == '-'
      && buf[12] == 'g'
      && buf[13] == 'r'
      && buf[14] == 'o'
      && buf[15] == 'u'
      && buf[16] == 'p'
      && buf[17] == ' ')
    return FILE_TYPE_XML_CORPUS_GROUP;

  if (buf[0]     == '<'
      && buf[1]  == 'a'
      && buf[2]  == 'b'
      && buf[3]  == 'i'
      && buf[4]  == '-'
      && buf[5]  == 'c'
      && buf[6]  == 'o'
      && buf[7]  == 'r'
      && buf[8]  == 'p'
      && buf[9]  == 'u'
      && buf[10] == 's'
      && buf[11] == ' ')
    return FILE_TYPE_XML_CORPUS;

  if ((unsigned char) buf[0]    == 0xed
      && (unsigned char) buf[1] == 0xab
      && (unsigned char) buf[2] == 0xee
      && (unsigned char) buf[3] == 0xdb)
    {
        if (buf[7] == 0x00)
          return FILE_TYPE_RPM;
        else if (buf[7] == 0x01)
          return FILE_TYPE_SRPM;
        else
          return FILE_TYPE_UNKNOWN;
    }

  if (buf[257]    == 'u'
      && buf[258] == 's'
      && buf[259] == 't'
      && buf[260] == 'a'
      && buf[261] == 'r')
    return FILE_TYPE_TAR;

  return FILE_TYPE_UNKNOWN;
}

/// Guess the type of the content of an file.
///
/// @param file_path the path to the file to consider.
///
/// @return the type of content guessed.
file_type
guess_file_type(const string& file_path)
{
  if (is_dir(file_path))
    return FILE_TYPE_DIR;

  if (string_ends_with(file_path, ".tar")
      || string_ends_with(file_path, ".tar.gz")
      || string_ends_with(file_path, ".tgz")
      || string_ends_with(file_path, ".tar.bz2")
      || string_ends_with(file_path, ".tbz2")
      || string_ends_with(file_path, ".tbz")
      || string_ends_with(file_path, ".tb2")
      || string_ends_with(file_path, ".tar.xz")
      || string_ends_with(file_path, ".txz")
      || string_ends_with(file_path, ".tar.lzma")
      || string_ends_with(file_path, ".tar.lz")
      || string_ends_with(file_path, ".tlz")
      || string_ends_with(file_path, ".tar.Z")
      || string_ends_with(file_path, ".taz")
      || string_ends_with(file_path, ".tz"))
    return FILE_TYPE_TAR;

  ifstream in(file_path.c_str(), ifstream::binary);
  file_type r = guess_file_type(in);
  in.close();
  return r;
}

/// Get the package name of a .deb package.
///
/// @param str the string containing the .deb NVR.
///
/// @param name output parameter.  This is set with the package name
/// of the .deb package iff the function returns true.
///
/// @return true iff the function successfully finds the .deb package
/// name.
bool
get_deb_name(const string& str, string& name)
{
  if (str.empty() || str[0] == '_')
    return false;

  string::size_type str_len = str.length(), i = 0 ;

  for (; i < str_len; ++i)
    {
      if (str[i] == '_')
	break;
    }

  if (i == str_len)
    return false;

  name = str.substr(0, i);
  return true;
}

/// Get the package name of an rpm package.
///
/// @param str the string containing the NVR of the rpm.
///
/// @param name output parameter.  This is set with the package name
/// of the rpm package iff the function returns true.
///
/// @return true iff the function successfully finds the rpm package
/// name.
bool
get_rpm_name(const string& str, string& name)
{
  if (str.empty() || str[0] == '-')
    return false;

  string::size_type str_len = str.length(), i = 0;
  string::value_type c;

  for (; i < str_len; ++i)
    {
      c = str[i];
      string::size_type next_index = i + 1;
      if ((next_index < str_len) && c == '-' && isdigit(str[next_index]))
	break;
    }

  if (i == str_len)
    return false;

  name = str.substr(0, i);

  return true;
}

/// Get the architecture string from the NVR of an rpm.
///
/// @param str the NVR to consider.
///
/// @param arch output parameter.  Is set to the resulting
/// archirecture string iff the function returns true.
///
/// @return true iff the function could find the architecture string
/// from the NVR.
bool
get_rpm_arch(const string& str, string& arch)
{
  if (str.empty())
    return false;

  if (!string_ends_with(str, ".rpm"))
    return false;

  string::size_type str_len = str.length(), i = 0;
  string::value_type c;
  string::size_type last_dot_index = 0, dot_before_last_index = 0;

  for (i = str_len - 1; i > 0; --i)
    {
      c = str[i];
      if (c == '.')
	{
	  last_dot_index = i;
	  break;
	}
    }

  if (i == 0)
    return false;

  for(--i; i > 0; --i)
    {
      c = str[i];
      if (c == '.')
	{
	  dot_before_last_index = i;
	  break;
	}
    }

  if (i == 0)
    return false;

  arch = str.substr(dot_before_last_index + 1,
		    last_dot_index - dot_before_last_index - 1);

  return true;
}

/// Tests if a given file name designates a kernel package.
///
/// @param file_name the file name to consider.
///
/// @param file_type the type of the file @p file_name.
///
/// @return true iff @p file_name of kind @p file_type designates a
/// kernel package.
bool
file_is_kernel_package(const string& file_name, file_type file_type)
{
  bool result = false;
  string package_name;

  if (file_type == FILE_TYPE_RPM)
    {
      if (!get_rpm_name(file_name, package_name))
	return false;
      result = (package_name == "kernel");
    }
  else if (file_type == FILE_TYPE_DEB)
    {
      if (!get_deb_name(file_name, package_name))
	return false;
      result = (string_begins_with(package_name, "linux-image"));
    }

  return result;
}

/// Tests if a given file name designates a kernel debuginfo package.
///
/// @param file_name the file name to consider.
///
/// @param file_type the type of the file @p file_name.
///
/// @return true iff @p file_name of kind @p file_type designates a
/// kernel debuginfo package.
bool
file_is_kernel_debuginfo_package(const string& file_name, file_type file_type)
{
  bool result = false;
  string package_name;

  if (file_type == FILE_TYPE_RPM)
    {
      if (!get_rpm_name(file_name, package_name))
	return false;
      result = (package_name == "kernel-debuginfo");
    }
  else if (file_type == FILE_TYPE_DEB)
    {
      if (!get_deb_name(file_name, package_name))
	return false;
      result = (string_begins_with(package_name, "linux-image")
		&& (string_ends_with(package_name, "-dbg")
		    || string_ends_with(package_name, "-dbgsyms")));
    }

  return result;
}

/// The delete functor of a char buffer that has been created using
/// malloc.
struct malloced_char_star_deleter
{
  void
  operator()(char* ptr)
  {free(ptr);}
};

/// Return a copy of the path given in argument, turning it into an
/// absolute path by prefixing it with the concatenation of the result
/// of get_current_dir_name() and the '/' character.
///
/// The result being an shared_ptr to char*, it should manage its
/// memory by itself and the user shouldn't need to wory too much for
/// that.
///
/// @param p the path to turn into an absolute path.
///
/// @return a shared pointer to the resulting absolute path.
std::shared_ptr<char>
make_path_absolute(const char*p)
{
  using std::shared_ptr;

  shared_ptr<char> result;

  if (p && p[0] != '/')
    {
      shared_ptr<char> pwd(get_current_dir_name(),
			   malloced_char_star_deleter());
      string s = string(pwd.get()) + "/" + p;
      result.reset(strdup(s.c_str()), malloced_char_star_deleter());
    }
  else
    result.reset(strdup(p), malloced_char_star_deleter());

  return result;
}

/// Return a copy of the path given in argument, turning it into an
/// absolute path by prefixing it with the concatenation of the result
/// of get_current_dir_name() and the '/' character.
///
/// The result being a pointer to an allocated memory region, it must
/// be freed by the caller.
///
/// @param p the path to turn into an absolute path.
///
/// @return a pointer to the resulting absolute path.  It must be
/// freed by the caller.
char*
make_path_absolute_to_be_freed(const char*p)
{
    char* result = 0;

  if (p && p[0] != '/')
    {
      char* pwd = get_current_dir_name();
      string s = string(pwd) + "/" + p;
      free(pwd);
      result = strdup(s.c_str());
    }
  else
    result = strdup(p);

  return result;
}

/// This is a sub-routine of gen_suppr_spec_from_headers and
/// handle_fts_entry.
///
/// It setups a type suppression which is meant to keep types defined
/// in a given file and suppress all other types.
///
/// @param file_path the path to the file that defines types that are
/// meant to be kept by the type suppression.  All other types defined
/// in other files are to be suppressed.  Note that this file path is
/// added to the vector returned by
/// type_suppression::get_source_locations_to_keep()
///
/// @param suppr the type suppression to setup.  If this smart pointer
/// is nil then a new instance @ref type_suppression is created and
/// this variable is made to point to it.
static void
handle_file_entry(const string& file_path,
		  type_suppression_sptr& suppr)
{
  if (!suppr)
    {
      suppr.reset(new type_suppression(get_private_types_suppr_spec_label(),
				       /*type_name_regexp=*/"",
				       /*type_name=*/""));

      // Types that are defined in system headers are usually
      // OK to be considered as public types.
      suppr->set_source_location_to_keep_regex_str("^/usr/include/");
      suppr->set_is_artificial(true);
    }

  // And types that are defined in header files that are under
  // the header directory file we are looking are to be
  // considered public types too.
  suppr->get_source_locations_to_keep().insert(file_path);
}

/// This is a sub-routine of gen_suppr_spec_from_headers.
///
/// @param entry if this file represents a regular (or symlink) file,
/// then its file name is going to be added to the vector returned by
/// type_suppression::get_source_locations_to_keep().
///
/// @param if @p entry represents a file, then its file name is going
/// to be added to the vector returned by the method
/// type_suppression::get_source_locations_to_keep of this instance.
/// If this smart pointer is nil then a new instance @ref
/// type_suppression is created and this variable is made to point to
/// it.
static void
handle_fts_entry(const FTSENT *entry,
		 type_suppression_sptr& suppr)
{
  if (entry == NULL
      || (entry->fts_info != FTS_F && entry->fts_info != FTS_SL)
      || entry->fts_info == FTS_ERR
      || entry->fts_info == FTS_NS)
    return;

  string fname = entry->fts_name;
  if (!fname.empty())
    {
      if (string_ends_with(fname, ".h")
	  || string_ends_with(fname, ".hpp")
	  || string_ends_with(fname, ".hxx"))
	handle_file_entry (fname, suppr);
    }
}

/// Populate a type_supression from header files found in a given
/// directory tree.
///
/// The suppression suppresses types defined in source files that are
/// *NOT* found in the directory tree.
///
/// This is a subroutine for gen_suppr_spect_from_headers.
///
/// @param headers_root_dir the directory tree to consider for header
/// files.
///
/// @param result the type_supression to populate from the content of
/// @p headers_root_dir.
static void
gen_suppr_spec_from_headers_root_dir(const string& headers_root_dir,
				     type_suppression_sptr &result)
{
  if (!headers_root_dir.empty())
    {
      char* paths[] = {const_cast<char*>(headers_root_dir.c_str()), 0};

      if (FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL))
	{
	  FTSENT *entry;
	  while ((entry = fts_read(file_hierarchy)))
	    handle_fts_entry(entry, result);
	  fts_close(file_hierarchy);
	}
    }
}

/// Generate a type suppression specification that suppresses ABI
/// changes for types defined in source files that are neither in a
/// given set of header root directories nor in a set of header
/// files.
///
/// @param headers_root_dirs ABI changes in types defined in files
/// *NOT* found in these directory trees are going be suppressed.
///
/// @param header_files a set of additional header files that define
/// types that are to be kept (not supressed) by the returned type
/// suppression.
///
/// @return the resulting type suppression generated, if any file was
/// found in the directory tree @p headers_root_dir.
type_suppression_sptr
gen_suppr_spec_from_headers(const vector<string>& headers_root_dirs,
			    const vector<string>& header_files)
{
  type_suppression_sptr result;

  for (vector<string>::const_iterator root_dir = headers_root_dirs.begin();
       root_dir != headers_root_dirs.end();
       ++root_dir)
    gen_suppr_spec_from_headers_root_dir(*root_dir, result);

  for (vector<string>::const_iterator file = header_files.begin();
       file != header_files.end();
       ++file)
    handle_file_entry(*file, result);

  return result;
}

/// Generate a type suppression specification that suppresses ABI
/// changes for types defined in source files that are neither in a
/// given header root dir, not in a set of header files.
///
/// @param headers_root_dir ABI changes in types defined in files
/// *NOT* found in this directory tree are going be suppressed.
///
/// @param header_files a set of additional header files that define
/// types that are to be kept (not supressed) by the returned type
/// suppression.
///
/// @return the resulting type suppression generated, if any file was
/// found in the directory tree @p headers_root_dir.
type_suppression_sptr
gen_suppr_spec_from_headers(const string& headers_root_dir,
			    const vector<string>& header_files)
{
  type_suppression_sptr result;
  vector<string> root_dirs;

  if (!headers_root_dir.empty())
    root_dirs.push_back(headers_root_dir);

  return gen_suppr_spec_from_headers(root_dirs, header_files);
}

/// Generate a type suppression specification that suppresses ABI
/// changes for types defined in source files that are not in a given
/// header root dir.
///
/// @param headers_root_dir ABI changes in types defined in files
/// *NOT* found in this directory tree are going be suppressed.
///
/// @return the resulting type suppression generated, if any file was
/// found in the directory tree @p headers_root_dir.
type_suppression_sptr
gen_suppr_spec_from_headers(const string& headers_root_dir)
{
  // We don't list individual files, just look under the headers_path.
  vector<string> header_files;
  return gen_suppr_spec_from_headers(headers_root_dir, header_files);
}

/// Generate a suppression specification from kernel abi whitelist
/// files.
///
/// A kernel ABI whitelist file is an INI file that usually has only
/// one section.  The name of the section is a string that ends up
/// with the sub-string "symbol_list" or "whitelist".  For instance
/// RHEL7_x86_64_symbol_list.
///
/// Then the content of the section is a set of function or variable
/// names, one name per line.  Each function or variable name is the
/// name of a function or a variable whose changes are to be keept.
///
/// A whitelist file can have multiple sections (adhering to the naming
/// conventions and multiple files can be passed. The suppression that
/// is created takes all whitelist sections from all files into account.
/// Symbols (or expression of such) are deduplicated in the final
/// suppression expression.
///
/// This function reads the white lists and generates a
/// function_suppression_sptr and variable_suppression_sptr and returns
/// a vector containing those.
///
/// @param abi_whitelist_paths a vector of KMI whitelist paths
///
/// @return a vector or suppressions
suppressions_type
gen_suppr_spec_from_kernel_abi_whitelists
   (const std::vector<std::string>& abi_whitelist_paths)
{

  std::vector<std::string> whitelisted_names;
  for (std::vector<std::string>::const_iterator
	   path_iter = abi_whitelist_paths.begin(),
	   path_end = abi_whitelist_paths.end();
       path_iter != path_end;
       ++path_iter)
    {

      abigail::ini::config whitelist;
      if (!read_config(*path_iter, whitelist))
	continue;

      const ini::config::sections_type& whitelist_sections =
	  whitelist.get_sections();

      for (ini::config::sections_type::const_iterator
	       section_iter = whitelist_sections.begin(),
	       section_end = whitelist_sections.end();
	   section_iter != section_end;
	   ++section_iter)
	{
	  std::string section_name = (*section_iter)->get_name();
	  if (!string_ends_with(section_name, "symbol_list")
	      && !string_ends_with(section_name, "whitelist"))
	    continue;
	  for (ini::config::properties_type::const_iterator
		   prop_iter = (*section_iter)->get_properties().begin(),
		   prop_end = (*section_iter)->get_properties().end();
	       prop_iter != prop_end;
	       ++prop_iter)
	    {
	      if (const simple_property_sptr& prop =
		      is_simple_property(*prop_iter))
		if (prop->has_empty_value())
		  {
		    const std::string& name = prop->get_name();
		    if (!name.empty())
		      whitelisted_names.push_back(name);
		  }
	    }
	}
    }

  suppressions_type result;
  if (!whitelisted_names.empty())
    {
      // Drop duplicates to simplify the regex we are generating
      std::sort(whitelisted_names.begin(), whitelisted_names.end());
      whitelisted_names.erase(std::unique(whitelisted_names.begin(),
					  whitelisted_names.end()),
			      whitelisted_names.end());

      // Build a regular expression representing the union of all
      // the function and variable names expressed in the white list.
      const std::string regex = regex::generate_from_strings(whitelisted_names);

      // Build a suppression specification which *keeps* functions
      // whose ELF symbols match the regular expression contained
      // in function_names_regexp.  This will also keep the ELF
      // symbols (not designated by any debug info) whose names
      // match this regexp.
      function_suppression_sptr fn_suppr(new function_suppression);
      fn_suppr->set_label("whitelist");
      fn_suppr->set_symbol_name_not_regex_str(regex);
      fn_suppr->set_drops_artifact_from_ir(true);
      result.push_back(fn_suppr);

      // Build a suppression specification which *keeps* variables
      // whose ELF symbols match the regular expression contained
      // in function_names_regexp.  This will also keep the ELF
      // symbols (not designated by any debug info) whose names
      // match this regexp.
      variable_suppression_sptr var_suppr(new variable_suppression);
      var_suppr->set_label("whitelist");
      var_suppr->set_symbol_name_not_regex_str(regex);
      var_suppr->set_drops_artifact_from_ir(true);
      result.push_back(var_suppr);
    }
  return result;
}

/// Get the path to the default system suppression file.
///
/// @return a copy of the default system suppression file.
string
get_default_system_suppression_file_path()
{
  string default_system_suppr_path;

  const char *s = getenv("LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE");
  if (s)
    default_system_suppr_path = s;

  if (default_system_suppr_path.empty())
    default_system_suppr_path =
      get_system_libdir() + string("/libabigail/default.abignore");

  return default_system_suppr_path;
}

/// Get the path to the default user suppression file.
///
/// @return a copy of the default user suppression file.
string
get_default_user_suppression_file_path()
{
  string default_user_suppr_path;
  const char *s = getenv("LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE");

  if (s == NULL)
    {
      s = getenv("HOME");
      if (s == NULL)
	return "";
      default_user_suppr_path  = s;
      if (default_user_suppr_path.empty())
	default_user_suppr_path = "~";
      default_user_suppr_path += "/.abignore";
    }
  else
    default_user_suppr_path = s;

  return default_user_suppr_path;
}

/// Load the default system suppression specification file and
/// populate a vector of @ref suppression_sptr with its content.
///
/// The default system suppression file is located at
/// $libdir/libabigail/default-libabigail.abignore.
///
/// @param supprs the vector to add the suppression specifications
/// read from the file to.
void
load_default_system_suppressions(suppr::suppressions_type& supprs)
{
  string default_system_suppr_path =
    get_default_system_suppression_file_path();

  read_suppressions(default_system_suppr_path, supprs);
}

/// Load the default user suppression specification file and populate
/// a vector of @ref suppression_sptr with its content.
///
/// The default user suppression file is located at $HOME~/.abignore.
///
/// @param supprs the vector to add the suppression specifications
/// read from the file to.
void
load_default_user_suppressions(suppr::suppressions_type& supprs)
{
  string default_user_suppr_path =
    get_default_user_suppression_file_path();

  read_suppressions(default_user_suppr_path, supprs);
}

/// Test if a given FTSENT* denotes a file with a given name.
///
/// @param entry the FTSENT* to consider.
///
/// @param fname the file name (or end of path) to consider.
///
/// @return true iff @p entry denotes a file which path ends with @p
/// fname.
static bool
entry_of_file_with_name(const FTSENT *entry,
			const string& fname)
{
  if (entry == NULL
      || (entry->fts_info != FTS_F && entry->fts_info != FTS_SL)
      || entry->fts_info == FTS_ERR
      || entry->fts_info == FTS_NS)
    return false;

  string fpath = entry->fts_path;
  if (string_ends_with(fpath, fname))
    return true;
  return false;
}

/// Find a given file under a root directory and return its absolute
/// path.
///
/// @param root_dir the root directory under which to look for.
///
/// @param file_path_to_look_for the file to look for under the
/// directory @p root_dir.
///
/// @param result the resulting path to @p file_path_to_look_for.
/// This is set iff the file has been found.
bool
find_file_under_dir(const string& root_dir,
		    const string& file_path_to_look_for,
		    string& result)
{
  char* paths[] = {const_cast<char*>(root_dir.c_str()), 0};

  FTS *file_hierarchy = fts_open(paths,
				 FTS_PHYSICAL|FTS_NOCHDIR|FTS_XDEV, 0);
  if (!file_hierarchy)
    return false;

  FTSENT *entry;
  while ((entry = fts_read(file_hierarchy)))
    {
      // Skip descendents of symbolic links.
      if (entry->fts_info == FTS_SL || entry->fts_info == FTS_SLNONE)
	{
	  fts_set(file_hierarchy, entry, FTS_SKIP);
	  continue;
	}
      if (entry_of_file_with_name(entry, file_path_to_look_for))
	{
	  result = entry->fts_path;
	  return true;
	}
    }

  fts_close(file_hierarchy);
  return false;
}
/// If we were given suppression specification files or kabi whitelist
/// files, this function parses those, come up with suppression
/// specifications as a result, and set them to the read context.
///
/// @param read_ctxt the read context to consider.
///
/// @param suppr_paths paths to suppression specification files that
/// we were given.  If empty, it means we were not given any
/// suppression specification path.
///
/// @param kabi_whitelist_paths paths to kabi whitelist files that we
/// were given.  If empty, it means we were not given any kabi
/// whitelist.
///
/// @param supprs the suppressions specifications resulting from
/// parsing the suppression specification files at @p suppr_paths and
/// the kabi whitelist at @p kabi_whitelist_paths.
///
/// @param opts the options to consider.
static void
load_generate_apply_suppressions(dwarf_reader::read_context &read_ctxt,
				 vector<string>& suppr_paths,
				 vector<string>& kabi_whitelist_paths,
				 suppressions_type& supprs)
{
  if (supprs.empty())
    {
      for (vector<string>::const_iterator i = suppr_paths.begin();
	   i != suppr_paths.end();
	   ++i)
	read_suppressions(*i, supprs);

      const suppressions_type& wl_suppr =
	  gen_suppr_spec_from_kernel_abi_whitelists(kabi_whitelist_paths);

      supprs.insert(supprs.end(), wl_suppr.begin(), wl_suppr.end());
    }

  abigail::dwarf_reader::add_read_context_suppressions(read_ctxt, supprs);
}

/// Test if an FTSENT pointer (resulting from fts_read) represents the
/// vmlinux binary.
///
/// @param entry the FTSENT to consider.
///
/// @return true iff @p entry is for a vmlinux binary.
static bool
is_vmlinux(const FTSENT *entry)
{
  if (entry == NULL
      || (entry->fts_info != FTS_F && entry->fts_info != FTS_SL)
      || entry->fts_info == FTS_ERR
      || entry->fts_info == FTS_NS)
    return false;

  string fname = entry->fts_name;

  if (fname == "vmlinux")
    {
      string dirname;
      dir_name(entry->fts_path, dirname);
      if (string_ends_with(dirname, "compressed"))
	return false;

      return true;
    }

  return false;
}

/// Test if an FTSENT pointer (resulting from fts_read) represents a a
/// linux kernel module binary.
///
/// @param entry the FTSENT to consider.
///
/// @return true iff @p entry is for a linux kernel module binary.
static bool
is_kernel_module(const FTSENT *entry)
{
    if (entry == NULL
      || (entry->fts_info != FTS_F && entry->fts_info != FTS_SL)
      || entry->fts_info == FTS_ERR
      || entry->fts_info == FTS_NS)
    return false;

  string fname = entry->fts_name;
  if (string_ends_with(fname, ".ko")
      || string_ends_with(fname, ".ko.xz")
      || string_ends_with(fname, ".ko.gz"))
    return true;

  return false;
}

/// Find a vmlinux and its kernel modules in a given directory tree.
///
/// @param from the directory tree to start looking from.
///
/// @param vmlinux_path output parameter.  This is set to the path
/// where the vmlinux binary is found.  This is set iff the returns
/// true and if this argument was empty to begin with.
///
/// @param module_paths output parameter.  This is set to the paths of
/// the linux kernel module binaries.
///
/// @return true iff at least the vmlinux binary was found.
static bool
find_vmlinux_and_module_paths(const string&	from,
			      string		&vmlinux_path,
			      vector<string>	&module_paths)
{
  char* path[] = {const_cast<char*>(from.c_str()), 0};

  FTS *file_hierarchy = fts_open(path, FTS_PHYSICAL|FTS_NOCHDIR|FTS_XDEV, 0);
  if (!file_hierarchy)
    return false;

  bool found_vmlinux = !vmlinux_path.empty();
  FTSENT *entry;
  while ((entry = fts_read(file_hierarchy)))
    {
      // Skip descendents of dead symbolic links.
      if (entry->fts_info == FTS_SLNONE)
	{
	  fts_set(file_hierarchy, entry, FTS_SKIP);
	  continue;
	}

      if (!found_vmlinux && is_vmlinux(entry))
	{
	  vmlinux_path = entry->fts_path;
	  found_vmlinux = true;
	}
      else if (is_kernel_module(entry))
	module_paths.push_back(entry->fts_path);
    }

  fts_close(file_hierarchy);

  return found_vmlinux;
}

/// Find a vmlinux binary in a given directory tree.
///
/// @param from the directory tree to start looking from.
///
/// @param vmlinux_path output parameter
///
/// return true iff the vmlinux binary was found
static bool
find_vmlinux_path(const string&	from,
		  string		&vmlinux_path)
{
  char* path[] = {const_cast<char*>(from.c_str()), 0};

  FTS *file_hierarchy = fts_open(path, FTS_PHYSICAL|FTS_NOCHDIR|FTS_XDEV, 0);
  if (!file_hierarchy)
    return false;

  bool found_vmlinux = false;
  FTSENT *entry;
  while ((entry = fts_read(file_hierarchy)))
    {
      // Skip descendents of symbolic links.
      if (entry->fts_info == FTS_SL || entry->fts_info == FTS_SLNONE)
	{
	  fts_set(file_hierarchy, entry, FTS_SKIP);
	  continue;
	}

      if (!found_vmlinux && is_vmlinux(entry))
	{
	  vmlinux_path = entry->fts_path;
	  found_vmlinux = true;
	  break;
	}
    }

  fts_close(file_hierarchy);

  return found_vmlinux;
}

/// Get the paths of the vmlinux and kernel module binaries under
/// given directory.
///
/// @param dist_root the directory under which to look for.
///
/// @param debug_info_root_path the path to the directory under which
/// debug info is going to be found for binaries under @p dist_root.
///
/// @param vmlinux_path output parameter.  The path of the vmlinux
/// binary that was found.
///
/// @param module_paths output parameter.  The paths of the kernel
/// module binaries that were found, sorted to impose a deterministic
/// ordering.
///
/// @return true if at least the path to the vmlinux binary was found.
bool
get_binary_paths_from_kernel_dist(const string&	dist_root,
				  const string&	debug_info_root_path,
				  string&		vmlinux_path,
				  vector<string>&	module_paths)
{
  if (!dir_exists(dist_root))
    return false;

  // For now, we assume either an Enterprise Linux or a Fedora kernel
  // distribution directory.
  //
  // We also take into account split debug info package for these.  In
  // this case, the content split debug info package is installed
  // under the 'debug_info_root_path' directory and its content is
  // accessible from <debug_info_root_path>/usr/lib/debug directory.

  string kernel_modules_root;
  string debug_info_root;
  if (dir_exists(dist_root + "/lib/modules"))
    {
      dist_root + "/lib/modules";
      debug_info_root = debug_info_root_path.empty()
	? dist_root
	: debug_info_root_path;
      debug_info_root += "/usr/lib/debug";
    }

  if (dir_is_empty(debug_info_root))
    debug_info_root.clear();

  bool found = false;
  string from = dist_root;
  if (find_vmlinux_and_module_paths(from, vmlinux_path, module_paths))
    found = true;

  std::sort(module_paths.begin(), module_paths.end());

  return found;
}

/// Get the path of the vmlinux binary under the given directory, that
/// must have been generated either from extracting a package.
///
/// @param from the directory under which to look for.
///
/// @param vmlinux_path output parameter.  The path of the vmlinux
/// binary that was found.
///
/// @return true if the path to the vmlinux binary was found.
bool
get_vmlinux_path_from_kernel_dist(const string&	from,
				  string&		vmlinux_path)
{
    if (!dir_exists(from))
    return false;

  // For now, we assume the possibility of having either an Enterprise
  // Linux or a Fedora kernel distribution directory.  In those cases,
  // the vmlinux binary is located under the /lib/modules
  // sub-directory.  So we might as well save some time by picking it
  // from there directly.

    string dist_root = from;
  if (dir_exists(dist_root + "/lib/modules"))
    dist_root += "/lib/modules";

  bool found = false;
  if (find_vmlinux_path(dist_root, vmlinux_path))
    found = true;

  return found;
}

/// Get the paths of the vmlinux and kernel module binaries under
/// given directory.
///
/// @param dist_root the directory under which to look for.
///
/// @param vmlinux_path output parameter.  The path of the vmlinux
/// binary that was found.
///
/// @param module_paths output parameter.  The paths of the kernel
/// module binaries that were found.
///
/// @return true if at least the path to the vmlinux binary was found.
bool
get_binary_paths_from_kernel_dist(const string&	dist_root,
				  string&		vmlinux_path,
				  vector<string>&	module_paths)
{
  string debug_info_root_path;
  return get_binary_paths_from_kernel_dist(dist_root,
					   debug_info_root_path,
					   vmlinux_path,
					   module_paths);
}

/// Walk a given directory and build an instance of @ref corpus_group
/// from the vmlinux kernel binary and the linux kernel modules found
/// under that directory and under its sub-directories, recursively.
///
/// The main corpus of the @ref corpus_group is made of the vmlinux
/// binary.  The other corpora are made of the linux kernel binaries.
///
/// @param root the path of the directory under which the kernel
/// kernel modules are to be found.  The vmlinux can also be found
/// somewhere under that directory, but if it's not in there, its path
/// can be set to the @p vmlinux_path parameter.
///
/// @param debug_info_root the directory under which debug info is to
/// be found for binaries under director @p root.
///
/// @param vmlinux_path the path to the vmlinux binary, if that binary
/// is not under the @p root directory.  If this is empty, then it
/// means the vmlinux binary is to be found under the @p root
/// directory.
///
/// @param suppr_paths the paths to the suppression specifications to
/// apply while loading the binaries.
///
/// @param kabi_wl_path the paths to the kabi whitelist files to take
/// into account while loading the binaries.
///
/// @param supprs the suppressions resulting from parsing the
/// suppression specifications at @p suppr_paths.  This is set by this
/// function.
///
/// @param verbose true if the function has to emit some verbose
/// messages.
///
/// @param env the environment to create the corpus_group in.
corpus_group_sptr
build_corpus_group_from_kernel_dist_under(const string&	root,
					  const string		debug_info_root,
					  const string&	vmlinux_path,
					  vector<string>&	suppr_paths,
					  vector<string>&	kabi_wl_paths,
					  suppressions_type&	supprs,
					  bool			verbose,
					  environment_sptr&	env)
{
  string vmlinux = vmlinux_path;
  corpus_group_sptr result;
  vector<string> modules;

  if (verbose)
    std::cerr << "Analysing kernel dist root '"
	      << root << "' ... " << std::flush;

  timer t;

  t.start();
  bool got_binary_paths =
    get_binary_paths_from_kernel_dist(root, debug_info_root, vmlinux, modules);
  t.stop();

  if (verbose)
    std::cerr << "DONE: " << t << "\n";

  dwarf_reader::read_context_sptr ctxt;
  if (got_binary_paths)
    {
      shared_ptr<char> di_root =
	make_path_absolute(debug_info_root.c_str());
      char *di_root_ptr = di_root.get();
      vector<char**> di_roots;
      di_roots.push_back(&di_root_ptr);
      abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
      corpus_group_sptr group;
      if (!vmlinux.empty())
	{
	  ctxt =
	    dwarf_reader::create_read_context(vmlinux, di_roots ,env.get(),
					      /*read_all_types=*/false,
					      /*linux_kernel_mode=*/true);
	  dwarf_reader::set_do_log(*ctxt, verbose);

	  t.start();
	  load_generate_apply_suppressions(*ctxt, suppr_paths,
					   kabi_wl_paths, supprs);
	  t.stop();

	  if (verbose)
	    std::cerr << "loaded white list and generated suppr spec in: "
		      << t
		      << "\n";

	  group.reset(new corpus_group(env.get(), root));

	  set_read_context_corpus_group(*ctxt, group);

	  if (verbose)
	    std::cerr << "reading kernel binary '"
		      << vmlinux << "' ...\n" << std::flush;

	  // Read the vmlinux corpus and add it to the group.
	  t.start();
	  read_and_add_corpus_to_group_from_elf(*ctxt, *group, status);
	  t.stop();

	  if (verbose)
	    std::cerr << vmlinux
		      << " reading DONE:"
		      << t << "\n";
	}

      if (!group->is_empty())
	{
	  // Now add the corpora of the modules to the corpus group.
	  int total_nb_modules = modules.size();
	  int cur_module_index = 1;
	  for (vector<string>::const_iterator m = modules.begin();
	       m != modules.end();
	       ++m, ++cur_module_index)
	    {
	      if (verbose)
		std::cerr << "reading module '"
			  << *m << "' ("
			  << cur_module_index
			  << "/" << total_nb_modules
			  << ") ... " << std::flush;

	      reset_read_context(ctxt, *m, di_roots, env.get(),
				 /*read_all_types=*/false,
				 /*linux_kernel_mode=*/true);

	      load_generate_apply_suppressions(*ctxt, suppr_paths,
					       kabi_wl_paths, supprs);

	      set_read_context_corpus_group(*ctxt, group);

	      t.start();
	      read_and_add_corpus_to_group_from_elf(*ctxt,
						    *group, status);
	      t.stop();
	      if (verbose)
		std::cerr << "module '"
			  << *m
			  << "' reading DONE: "
			  << t << "\n";
	    }

	  result = group;
	}
    }

  return result;
}

}//end namespace tools_utils

using abigail::ir::function_decl;

/// Dump (to the standard error stream) two sequences of strings where
/// each string represent one of the functions in the two sequences of
/// functions given in argument to this function.
///
/// @param a_begin the begin iterator for the first input sequence of
/// functions.
///
/// @parm a_end the end iterator for the first input sequence of
/// functions.
///
/// @param b_begin the begin iterator for the second input sequence of
/// functions.
///
/// @param b_end the end iterator for the second input sequence of functions.
void
dump_functions_as_string(std::vector<function_decl*>::const_iterator a_begin,
			 std::vector<function_decl*>::const_iterator a_end,
			 std::vector<function_decl*>::const_iterator b_begin,
			 std::vector<function_decl*>::const_iterator b_end)
{abigail::fns_to_str(a_begin, a_end, b_begin, b_end, std::cerr);}

/// Dump (to the standard error output stream) a pretty representation
/// of the signatures of two sequences of functions.
///
/// @param a_begin the start iterator of the first input sequence of functions.
///
/// @param a_end the end iterator of the first input sequence of functions.
///
/// @param b_begin the start iterator of the second input sequence of functions.
///
/// @param b_end the end iterator of the second input sequence of functions.
void
dump_function_names(std::vector<function_decl*>::const_iterator a_begin,
		    std::vector<function_decl*>::const_iterator a_end,
		    std::vector<function_decl*>::const_iterator b_begin,
		    std::vector<function_decl*>::const_iterator b_end)
{
  std::vector<function_decl*>::const_iterator i;
  std::ostream& o = std::cerr;
  for (i = a_begin; i != a_end; ++i)
    o << (*i)->get_pretty_representation() << "\n";

  o << "  ->|<-  \n";
  for (i = b_begin; i != b_end; ++i)
    o << (*i)->get_pretty_representation() << "\n";
  o << "\n";
}

/// Compare two functions that are in a vector of functions.
///
/// @param an iterator to the beginning of the the sequence of functions.
///
/// @param f1_index the index of the first function to compare.
///
/// @param f2_inde the index of the second function to compare
bool
compare_functions(vector<function_decl*>::const_iterator base,
		  unsigned f1_index, unsigned f2_index)
{
  function_decl* fn1 = base[f1_index];
  function_decl* fn2 = base[f2_index];

  return *fn1 == *fn2;
}

}//end namespace abigail
