There are few non-ASCII characters in various code comments. A few are
typos and the rest have obvious ASCII equivalents. This commit
replaces them all with ASCII characters.
* include/abg-diff-utils.h: Replace "’’" with "'".
* src/abg-elf-helpers.cc: Replace "⋅" with ".".
* src/abg-ini.cc: Replace "@êef" with "@ref".
* src/abg-ir.cc: Ditto.
* src/abg-tools-utils.cc: Replace "–" with "-".
Signed-off-by: Giuliano Procida <gprocida@google.com>
Found with -D_GLIBCXX_DEBUG. You cannot go before the start of an
RandomAccessOutputIterator. Iterator -1 + 1 might seem to work,
but is actually undefined behaviour.
* include/abg-diff-utils.h (compute_diff): Put brackets around
p[ux].[xy]() + 1 calculation.
Signed-off-by: Mark Wielaard <mark@klomp.org>
This patch adds the ability to compare all types of a binary,
including those types that are not reachable from global functions and
variables.
This implies that for types that are not reachable from public
interfaces, we want compare them against each others directly, without
first comparing global functions/variables and walking the graph of
reachable types from there.
The patch adds the --non-reachable-types option to abidiff and
abipkgdiff, instructing them to also compare types that are
non-reachable from global variables and functions.
Using that option, for instance, here is what the summary of
abipkgdiff now looks like, in the test case attached added by this
patch:
================ changes of 'libflatpak.so.0.10204.0'===============
Functions changes summary: 0 Removed, 0 Changed (16 filtered out), 16 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
Unreachable types summary: 3 removed (2 filtered out), 1 changed (15 filtered out), 3 added (1 filtered out) types
You can see that there is a new summary line which starts with the
string: "Unreachable types summary:"
Then in the body of the report, those unreachable types are reported
separately.
In practise, we want to limit the unreachable types to compare
somehow, otherwise we'll end up comparing all the types of the types
of the binary and that can be huge. So we want to limit the
unreachable type analysis to types that are defined in public headers.
So, for abipkgdiff, one can limit the analysis of non-reachable types
to those defined in public headers by supplying the --devel{1,2}
options that specifies the development packages that contain said
public headers. For abidiff however, you'll want to use the
--headers-dir{1,2} options for that.
The patch comes with appropriate regression tests.
* include/abg-comparison.h (string_type_base_sptr_map): Define new
typedef.
(diff_context::show_unreachable_types): Declare new member
functions.
(corpus_diff::{deleted_unreachable_types,
deleted_unreachable_types_sorted, added_unreachable_types,
added_unreachable_types_sorted, changed_unreachable_types,
changed_unreachable_types_sorted}): Likewise.
(maybe_report_unreachable_type_changes): Declare this function a
friend of class corpus_diff.
(corpus_diff::diff_stats::{num_added_unreachable_types,
num_added_unreachable_types_filtered_out,
net_num_added_unreachable_types, num_removed_unreachable_types,
num_removed_unreachable_types_filtered_out,
net_num_removed_unreachable_types, num_changed_unreachable_types,
num_changed_unreachable_types_filtered_out,
net_num_changed_unreachable_types}): Likewise.
* src/abg-comparison-priv.h
(diff_context::priv::show_unreachable_types_): Define new data
member.
(diff_context::priv::priv): Initialize the new data member.
(diff_comp::operator()): Use pretty representation of diff
subjects to sort them, rather than just their name. Also, add
comment to the other member functions of diff_comp.
(corpus_diff::{unreachable_types_edit_script_,
deleted_unreachable_types_, deleted_unreachable_types_sorted_,
suppressed_deleted_unreachable_types_, added_unreachable_types_,
added_unreachable_types_sorted_,
suppressed_added_unreachable_types_, changed_unreachable_types_,
changed_unreachable_types_sorted_}): Define new data members.
(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
Changed the name of
corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars into
this.
(corpus_diff::priv::{added_unreachable_type_is_suppressed,
deleted_unreachable_type_is_suppressed,
changed_unreachable_types_sorted, count_unreachable_types}):
Declare new member functions.
(corpus_diff::diff_stats::priv::{num_added_unreachable_types,
num_added_unreachable_types_filtered_out,
num_removed_unreachable_types,
num_removed_unreachable_types_filtered_out,
num_changed_unreachable_types,
num_changed_unreachable_types_filtered_out}): Define new data
members.
(sort_string_type_base_sptr_map): Declare new function.
* src/abg-comparison.cc (sort_string_type_base_sptr_map)
(diff_context::show_unreachable_types): Define new functions.
(corpus_diff::diff_stats::{num_added_unreachable_types,
num_added_unreachable_types_filtered_out,
net_num_added_unreachable_types,
net_num_removed_unreachable_types,
num_removed_unreachable_types_filtered_out,
num_removed_unreachable_types}): Define new member functions.
(diff_maps::insert_diff_node): Do not update the map "diff ->
impacted interfaces" if the current impacted interface is nil.
This happens if we are looking at a diff node for a change on a
type that is not reachable from any interfaces.
(corpus_diff::priv::ensure_lookup_tables_populated): Handle the
edit script for unreachable types.
(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
Rename
corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars
into this. Apply suppression specifications to added and removed
unreachable types as well.
(corpus_diff::priv::{added,deleted}_unreachable_type_is_suppressed):
Define new member functions.
(corpus_diff::priv::{count_unreachable_types,
changed_unreachable_types_sorted}): Likewise.
(corpus_diff::priv::apply_filters_and_compute_diff_stats): Update
statistics (including walking changed unreachable types to apply
categorization and redundancy filters to them) related to
unreachable types.
(corpus_diff::priv::emit_diff_stats): Emit diff stats related to
unreachable types.
(corpus_diff::priv::maybe_dump_diff_tree): Dump diff tree nodes
related to unreachable types.
(corpus_diff::{deleted_unreachable_types,
deleted_unreachable_types_sorted, added_unreachable_types,
added_unreachable_types_sorted, changed_unreachable_types,
changed_unreachable_types_sorted): Define new member functions.
(corpus_diff::has_changes): Take deleted/added/changed unreachable
types into account.
(corpus_diff::has_incompatible_changes): Take net removed/changed
unreachable types into account.
(corpus_diff::has_net_subtype_changes): Take net removed and
changed unreachable types into account.
(corpus_diff::has_net_changes): Take net removed/added/changed
unreachable types into account.
(corpus_diff::traverse): When traversing the components of a
corpus_diff node, make sure to traverse the changed unreachable
types of the corpus.
(leaf_diff_node_marker_visitor::visit_begin): Arrange for the fact
that the current topmost interface can be nil if we are looking at
types not reachable from global functions/variables. Also, make
sure that only leaf nodes that are reachable from a global
function/variable are recorded as leaf nodes.
(compute_diff): In the overload for corpus_sptr, compute the
changes between types not reachable from global functions and
variables, if the user wishes that we do so. Also, add more
comments.
(apply_suppressions): Update for the name change of the function
apply_suppressions_to_added_removed_fns_vars to
apply_supprs_to_added_removed_fns_vars_unreachable_types.
* include/abg-corpus.h
(corpus::{record_type_as_reachable_from_public_interfaces,
type_is_reachable_from_public_interfaces,
get_types_not_reachable_from_public_interfaces}): Declare new
member functions.
(corpus::recording_types_reachable_from_public_interface_supported):
Declare new virtual member function.
(corpus_group::get_public_types_pretty_representations): Declare
new member functons.
(corpus_group::recording_types_reachable_from_public_interface_supported):
Declare new virtual member function.
* src/abg-corpus-priv.h
(corpus::priv::{types_not_reachable_from_pub_ifaces_,
pub_type_pretty_reprs_}): Define new data members.
(corpus::priv::priv): Initialize the pub_type_pretty_reprs_ data
member because it's a pointer.
(corpus::priv::get_public_types_pretty_representations): Declare
new member function.
(corpus::priv::~priv): Declare a destructor.
* src/abg-corpus.cc
(corpus::priv::get_public_types_pretty_representations): Define
new member function.
(corpus::priv::~priv): Define new destructor to delete the new
pub_type_pretty_reprs_ member pointer.
(corpus::{record_type_as_reachable_from_public_interfaces,
type_is_reachable_from_public_interfaces,
get_types_not_reachable_from_public_interfaces,
recording_types_reachable_from_public_interface_supported}):
Define new member functions
(corpus_group::get_public_types_pretty_representations): Likewise.
* include/abg-diff-utils.h (struct deep_ptr_eq_functor): Document
the equality operator. Also, add an overload to the equality
operator, for weak_ptr<T>. The existing equality operator
overload was just for shared_ptr<T>.
* include/abg-fwd.h (is_user_defined_type): Declare function.
* include/abg-ir.h (operator!=(const decl_base_sptr&, const
decl_base_sptr&)): Declare new operator.
(type_maps::get_types_sorted_by_name): Declare
new member function.
(decl_base::{g,s}et_is_artificial): Declare new member function.
(function_decl::parameter::{g,s}et_artificial): Remove these
member functions.
* src/abg-ir.cc (operator!=(const decl_base_sptr&, const
decl_base_sptr&)): Define new operator.
(decl_base::priv::is_artificial_): Define new data
member.
(type_maps::priv::sorted_types_): Define new data member.
(struct type_name_comp): Define new comparison functor to sort
types based on their pretty representations.
(decl_base::priv::priv): Initialize it.
(decl_base::{g,s}et_is_artificial): Define new member functions.
(type_maps::get_types_sorted_by_name): Define new member function.
(is_user_defined_type): Define new function overloads.
(strip_typedef, function_type::{function_type, set_parameters}):
Adjust using decl_base::get_is_artificial rather than
function_decl::parameter::get_artificial.
(function_decl::parameter::priv::artificial_): Remove this data
member.
(function_decl::parameter::priv::priv): Adjust to the removal of
function_decl::parameter::priv::artificial_. This constructor
does not take an "is_artificial" flag anymore.
(function_decl::parameter::parameter): Adjust to the removal of
the is_artificial flag from the arguments of the constructor of
function_decl::parameter::parameter::priv.
(function_decl::parameter::get_artificial): Remove this member
function.
* src/abg-reporter-priv.h (maybe_report_unreachable_type_changes):
Declare new function.
* src/abg-reporter-priv.cc
(maybe_report_unreachable_type_changes): Define new function.
* src/abg-default-reporter.cc (default_reporter::report): In the
overload for corpus_diff&, report added/removed/changed types that
are not reachable from global functions and variables using the
new function maybe_report_unreachable_type_changes.
* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
overload for corpus_diff, report changes to types unreachable from
global functions or variables, using the new function
maybe_report_unreachable_type_changes.
* src/abg-dwarf-reader.cc (build_ir_node_from_die): When the user
requests that all types be loaded, record relevant types as
reachable from global functions and variables.
(build_enum_type, add_or_update_class_type)
(add_or_update_union_type): Read the 'is-artificial' DWARF
attribute and set the corresponding decl_base property
accordingly.
(finish_member_function_reading, strip_typedef)
(function_type::function_type): Adjust using
decl_base::get_is_artificial, rather than
function_decl::parameter::get_artificial.
* include/abg-reader.h
(consider_types_not_reachable_from_public_interfaces): Declare new
function.
* src/abg-reader.cc
(read_context::m_tracking_non_reachable_types): Add new data
member.
(read_context::read_context): Initialize it.
(read_context::tracking_non_reachable_types): Define accessors for
the new data member above.
(read_is_declaration_only): Re-indent.
(read_is_artificial): Define new helper function.
(build_function_parameter): Use the new read_is_artificial
function here, rather than open-coding it.
(build_enum_type_decl, build_class_decl, build_union_decl):
Support reading the 'is-artificial' property by using the new
read_is_artificial function.
(read_corpus_from_input): If the user wants us to take
non-reachable types into account, then make sure we do so.
(read_tracking_non_reachable_types, read_is_non_reachable_type):
Define new static functions.
(handle_element_node, build_type): Read the "is-non-reachable"
attribute on type element nodes if the user wants us to track
non-reachable types.
(consider_types_not_reachable_from_public_interfaces): Define new
function.
* src/abg-writer.cc (write_is_artificial): Define new static
helper function.
(annotate): Adjust using decl_base::get_is_artificial rather than
function_decl::parameter::get_artificial.
(write_enum_type_decl, write_class_decl_opening_tag)
(write_union_decl_opening_tag): Support writing the
"is-artificial" property, using the new write_is_artificial
function.
(write_function_type): Adjust this to use the new
write_is_artificial rather than open-coding writing the
'is-artificial' attribute.
(write_is_non_reachable)
(write_tracking_non_reachable_types): Define new static functions.
(write_enum_type_decl, write_class_decl_opening_tag)
(write_union_decl_opening_tag): Write the 'is-no-reachable'
attribute when applicable.
(write_corpus, write_corpus_group): Write the
'tracking-non-reachable-types' attribute when applicable.
* tools/abidiff.cc (options::options): Initialize ...
(options::show_all_types): ... new data member.
(display_usage): Add help string from the new
--non-reachable-types option.
(parse_command_line): Parse the new --non-reachable-types option.
(set_diff_context_from_opts): Set the
dwarf_reader::read_context::show_unreachable_types property.
(set_native_xml_reader_options): Define new
static function.
(main): Load all types when analyzing the DWARF or the ABIXML
files, if the user wants us to do so.
* tools/abipkgdiff.cc (options::show_all_types): Define new data
member.
(options::options): Initialize it.
(parse_command_line): Parse the --non-reachable-types option to
set the options::show_all_types data member.
(display_usage): Add a help string for the new
--non-reachable-types option.
(set_diff_context_from_opts): Set the
dwarf_reader::read_context::show_unreachable_types property based
on the options::show_all_type data member.
(compare): Configure the read context to load all types while
analyzing the DWARF info, depending on the options::show_all_type
data member.
* doc/manuals/abidiff.rst: Document the new --non-reachable-types
option added to abidiff above.
* doc/manuals/abipkgdiff.rst: Add documentation for the
--non-reachable-types option.
* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.c:
Source code files of test binary input.
* tests/data/test-diff-suppr/test47-non-reachable-types-suppr-{1,2,3,4,5}.txt:
New test input files.
* tests/data/test-diff-suppr/test47-non-reachable-types-report-{1,2,3,4,5,6,7,8,9,10}.txt:
New test reference output files.
* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.o.alltypes.abixml:
New test input abixml.
* tests/data/Makefile.am: Add the new test material to source
distribution.
* tests/test-diff-suppr.cc (in_out_specs): Add the new tests above
to this test harness.
* tests/data/test-abidiff/test-struct1-report.txt: Adjust.
* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.2.4-3.fc30.x86_64.rpm:
New input binary RPM.
* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.4.0-1.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.2.4-3.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.4.0-1.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.2.4-3.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.4.0-1.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.2.4-3.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.4.0-1.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/PR24690/PR24690-report-0.txt: New test
reference output.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-diff-pkg.cc (in_out_specs): Add the new test material
above to this test harness.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Introduce a compatibility layer for C++11 code by adding
include/abg-cxx-compat.h. abg-cxx-compat defines a new namespace
abg_compat and defines
abg_compat::hash
abg_compat::shared_ptr
abg_compat::weak_ptr
abg_compat::dynamic_pointer_cast
abg_compat::static_pointer_cast
abg_compat::unordered_map
abg_compat::unordered_set
based on definitions from std::tr1 (std=gnu++98) or std:: (std=gnu++11).
I decided for introducing abg_compat:: rather than polluting abigail::
to allow an easier transition to C++11 at a later time and to not subtly
break existing code.
As the shared_ptr in C++11 defines shared_ptr::operator bool() explicit,
some locations where a shared_ptr is assigned to boolean, needed to be
adjusted to explicitly cast to bool.
* include/abg-cxx-compat.h: new file introducing the abg_compat
namespace to provide C++11 functionality from either std::tr1
or std::
* include/Makefile.am: Add the new abg-cxx-compat.h to source
distribution.
* include/abg-comparison.h: replace std::tr1 usage by abg_compat
and adjust includes accordingly: likewise
* include/abg-diff-utils.h: likewise
* include/abg-fwd.h: likewise
* include/abg-ini.h: likewise
* include/abg-interned-str.h: likewise
* include/abg-ir.h: likewise
* include/abg-libxml-utils.h: likewise
* include/abg-libzip-utils.h: likewise
* include/abg-reporter.h: likewise
* include/abg-sptr-utils.h: likewise
* include/abg-suppression.h: likewise
* include/abg-tools-utils.h: likewise
* include/abg-workers.h: likewise
* src/abg-comp-filter.cc: likewise
* src/abg-comparison-priv.h: likewise
* src/abg-corpus.cc: likewise
* src/abg-dwarf-reader.cc: likewise
* src/abg-hash.cc: likewise
* src/abg-ir.cc: likewise
* src/abg-reader.cc: likewise
* src/abg-suppression.cc: likewise
* src/abg-tools-utils.cc: likewise
* src/abg-writer.cc: likewise
* tests/test-diff-filter.cc: likewise
* tests/test-diff-pkg.cc: likewise
* tests/test-read-dwarf.cc: likewise
* tests/test-read-write.cc: likewise
* tests/test-types-stability.cc: likewise
* tests/test-write-read-archive.cc: likewise
* tools/abicompat.cc: likewise
* tools/abidiff.cc: likewise
* tools/abidw.cc: likewise
* tools/abilint.cc: likewise
* tools/abipkgdiff.cc: likewise
Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The postfix increment / decrement operators were implemented by calling
themselves recursively. Fix that by implementing these in terms of their
prefix counter parts.
* include/abg-diff-utils.h: fix postfix dec/inc operator
Signed-off-by: Matthias Maennich <maennich@google.com>
There are lots of spots in libabigail's source code where the argument
of the assert() call does have side effects. This is a problem
because when the code is compiled with the NDEBUG macro defined, the
assert call does nothing, so the side effects of its argument are then
suppressed, changing the behaviour of the program.
To handle this issue, this patch introduces the ABG_ASSERT macro which
is a wrapper around the assert call that enable the use of side
effects in its argument. The patch now uses that ABG_ASSERT macro
instead of using the assert call directly.
The patch also makes it so that the configure option accepts the
--disable-assert option so that the user can build libabigail with the
NDEBUG macro defined.
Tested by running the testsuite with and without the --disable-assert
option to configure.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (print_snake): pass argument of type
snake by const reference.
* include/abg-ir.h (location::operator{==,<}): Likewise.
* include/abg-viz-dot.h (node_base::{node_base,parent_node,child_node}):
Likewise.
* include/abg-viz-svg.h (svg::svg) Likewise.
* src/abg-config.cc (config::config): Member initialization in ctor body.
* src/abg-dwarf-reader.cc (class_decl_sptr::add_or_update_class_type):
Initial value never used.
* src/abg-ir.cc: (decl_base::priv::priv) Member initialization in ctor body,
pass argument of type location by const reference.
(equals): Variable initial value never used.
* src/abg-reader.cc (read_corpus_from_input): Initial variable
value never used.
(build_elf_symbol_db): Use pre-increment.
* src/abg-suppression-priv.h
(suppression_matches_type_location): Pass argument of type
location by const reference.
* src/abg-suppression.cc: Likewise.
Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
* configure.ac: Define a new --enable-cxx11 switch to control the
use of the C++-11 compiler. Define a WITH_CXX11 C macro and an
automake ENABLE_CXX11 variable.
* config.h.in: Initialize the new WITH_CXX11 C macro.
* src/Makefile.am: Include the files coded in C++-11 only if the
ENABLE_CXX11 automake variable is defined.
* tests/Makefile.am: Likewise, build the runtestsvg test program
only if C++-11 usage is enabled.
* include/abg-diff-utils.h (class d_path_vec): Remove useless
usage of the 'typename' keyword.
* include/abg-fwd.h (is_enum_type): Renamed is_enum into this,
because of a name clash with a tr1 function when not using C++-11.
(is_pointer_type): Likewise, renamed is_pointer into this because
of a name clash with a tr1 function when not using C++-11.
* src/abg-comp-filter.cc (has_harmless_name_change): Adjust for
the is_enum -> is_enum_type change.
* src/abg-comparison.cc (type_suppression::suppresses_diff):
Likewise.
(class function_suppression::priv): Add a missing "class" keyword
in friend declaration.
(diff_context::diff_has_been_traversed)
(diff_context::mark_diff_as_traversed): Do not use the C++-11
specific type uintptr_t.
* src/abg-dwarf-reader.cc (create_default_dwfl): Do not use
designated initializers. Sigh. This is handy though.
(expr_result::abs): Cast the argument of std::abs to avoid
ambiguous call.
(finish_member_function_reading): Adjust for the is_pointer ->
is_pointer_type renaming.
* src/abg-hash.cc (scope_decl:#️⃣:operator)
(class_decl::base_spec:#️⃣:operator)
(type_composition:#️⃣:operator): Use std::tr1::hash string,
rather than the C++-11 specific std::hash function.
* src/abg-ini.cc (read_sections, write_sections): Make
std::ifstream constructor take a const char* rather than a string.
* src/abg-ir.cc (is_enum_type, is_pointer_type): Renamed is_enum
into is_enum_type and is_pointer into is_pointer_type.
* src/abg-writer.cc (write_translation_unit): Remove useless
typename keyword. Make ofstream take a const char* rather than a
string.
(write_namespace_decl): Remove useless typename keyword.
(write_corpus_to_native_xml_file): Make ofstream take a const
char* rather than a string.
* tests/test-abidiff.cc (main): Make ofstream take a const char*
rather than a string.
* tests/test-diff-dwarf.cc (main): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (namespace diff_utils): Add comment.
(compute_diff): Update comments for some overloads where they were
missing.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (d_path_vec::max_d): Avoid using member
functions. This is relevant only when compiling w/o optimization.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (d_path_vec::d_path_vec): Do not
forget to allocate enough data for reverse vectors as well. The
comment of the constructor is accurate.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (compute_diff): Add asserts on for the
length of the shortest edit script during the divide and conquer
part of the diff algorithm.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (end_of_frr_d_path_in_k_plus_delta):
Favour moving left when the two abscissas at the previous steps
are equal.
(compute_diff): Update the length of the shortest edit script when
the size of one of the inputs is zero.
* tests/test-core-diff.cc (in_out_spec): Add a new input to diff
two sequences for regression testing.
* tests/data/test-core-diff/report13.txt: New reference for
the comparison of the new regression test above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-comparison.h (string_function_ptr_map)
(changed_function_ptr, string_changed_function_ptr_map)
(corpus_diff_sptr): New convenience typedefs.
(translation_unit_diff): Add comments.
(class corpus_diff): New type.
(compute_diff): New overload for corpus_diff.
* include/abg-corpus.h (corpus::{functions, variables}): New
typedefs.
(corpus::{operator==, get_functions, get_variables}): New members.
* include/abg-diff-utils.h (struct deep_ptr_eq_functor): New
functor.
* include/abg-ir.h (translation_unit::operator==): New member
equality operator.
* src/abg-comparison.cc (struct corpus_diff::priv): New private
struct holding the private members of corpus_diff.
(corpus_diff::priv::{lookup_tables_empty, clear_lookup_tables,
ensure_lookup_tables_populated}): Define new private member functions.
(corpus_diff::{corpus_diff, first_corpus, second_corpus,
function_changes, variable_changes, length, report}): New public members.
(struct noop_deleter): New struct.
(compute_diff): New implementation for corpus_diff.
* src/abg-corpus.cc (struct corpus::priv): Renamed corpus::impl
into this. Add new fns, vars and is_symbol_table_built data
members.
(corpus::priv::build_symbol_table): New member function.
(class symtab_build_visitor_type): New visitor type to build the
symbol table.
(struct func_comp, struct var_comp): New comparison functors.
(corpus::priv::build_symbol_table): Define new member function.
(corpus::{corpus, add, get_translation_units, operator==,
get_functions, get_variables}): Define new members.
* src/abg-ir.cc (translation_unit::operator==): Define new member
equality operator.
(operator==(translation_unit_sptr l, translation_unit_sptr r)):
Define new equality operator.
* tools/abg-tools-utils.h (enum file_type): New enum.
(guess_file_type): Declare new function.
* tools/abg-tools-utils.cc (guess_file_type): define new function.
* tools/bidiff.cc (main): Guess the type of the files given in
input and support elf files reading and diffing.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (struct default_eq_functor): New
equality functor.
(end_of_fr_d_path_in_k, end_of_frr_d_path_in_k_plus_delta): Add a
new equality functor template parameter and document it. Use it
to compare the elements of the sequences given in argument.
(compute_middle_snake, ses_len, compute_diff): Add a new equality
functor template parameter and document it. Adjust call to
end_of_frr_d_path_in_k_plus_delta, end_of_fr_d_path_in_k and
compute_middle_snake.
(ses_len, compute_diff): Add a new overload that uses a
default_eq_functor as comparison functor, to avoid breaking
existing client code.
* src/abg-diff-utils.cc (compute_middle_snake): Adjust the call to
the compute_middle_snake.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (point::set): New overload..
(point::{add, operator<, operator>, operator<=, operator>=}): New
methods.
(point::operator!=): Constify.
(point::operator==): Constify. Cleanup.
(point::operator=): Keep emptiness.
(class snake): New class definition
(d_path_vec::{over_bounds, offset}): New methods.
(d_path_vec::check_index_against_bound): Don't take a bound
parameter anymore. Use the new over_bound method above. Fix up
error reporting.
(d_path_vec::d_path_vec): Fix d_path_vec size allocation.
(d_path_vec::operator[]): Use the d_path_vec::at method to check
all accesses against the bounds. This is slower, but at least we
can expect to have something that is more robust. We can remove
the bound checking later when we are sure the code has been tested
enough. Also use the new offset() method.
(d_path_vec::at): Take long long.
(ends_of_furthest_d_paths_overlap): Constify input parameters.
(end_of_fr_d_path_in_k, end_of_frr_d_path_in_k_plus_delta): Take
an instance of the new snake in parameter, rather than a bare end
point that wasn't carrying enough information about the snake.
Record the snake which consists of up to four points: a begin
point, an intermediate point, a diagonal start point and an end
point. Return that snake upon successful completion.
(compute_middle_snake): Take an instance of snake, rather than the
two points that were supposed to represent a snake and with which
we were loosing information before. Revisit/simplify the logic of
this function; this literally goes forward or in reverse, gets the
resulting snake returned by the end_of_fr_d_path_in_k and
end_of_frr_d_path_in_k_plus_delta functions, detect if these snakes
overlap and just return the current snake. Much simpler. The
caller now gets a snake, which has much more information than the
previous snake approximation made of just two points. Bonus
point, this follows almost to the word, what the paper says.
(maybe_record_match_point, find_snake_start_point): Remove these
as there are not used by compute_middle_snake anymore.
(print_snake, ses_len): Update these to take/handle a snake.
(snake_end_points): New declaration.
(compute_diff): When we are getting an empty first sequence, this
means that we are inserting the second sequence *before* the
beginning of the first sequence; keep this information by setting
the insertion point index to -1, rather than zero. Update this to
get/handle snakes, rather than free points vaguely representing
snakes. Now that compute_middle_snake returns real snakes, handle
the information we are getting. Basically for edit scripts of
length equal to 1, as the snake carries all the necessary
information about the non-diagonal edge (as well as the diagonal
edges), we (can) now precisely update the current edit script (as
well as the longest common sub-sequence). For edit scripts of
length greater than 1, better at which points to divide the
problem and consequently, at which points to conquer it back --
better following The Paper to the letter.
(display_edit_script): Update this for the use of instances of
snake.
* src/abg-diff-utils.cc (ends_of_furthest_d_paths_overlap): Update
for constification of inputs.
(snake_end_points): Define new function.
(compute_middle_snake): Adapt for the taking an instance of snake.
* tests/test-diff2.cc (main): Update for using instances of snake.
* tests/test-core-diff.cc: Add new tests.
* tests/data/test-core-diff/report0.txt: Update for output
adaptation.
* tests/data/test-core-diff/report6.txt: Likewise.
* tests/data/test-core-diff/report7.txt: Likewise.
* tests/data/test-core-diff/report8.txt: New test data.
* tests/data/test-core-diff/report9.txt: Likewise.
* tests/data/test-core-diff/report10.txt: Likewise.
* tests/data/test-core-diff/report11.txt: Likewise.
* tests/data/test-core-diff/report12.txt: Likewise.
* tests/data/test-core-diff/report3.txt: Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (compute_middle_snake): After the
overlap determination happened, finding the middle snake can
require keep on building the current path until the "end". The
end meaning reaching the max of D. And that max is (M + N)/2 + 1.
In the extreme cases were middle snake was on the very last step
(M + N) + 1, we were not finding the middle snake. Fix this.
(compute_diff): When d == 1 and the first edge on the edit graph
is a non-diagonal edge and when a_base != a_begin, we were failing
to properly initialize x,y to find that non-diagonal edge. Also
we were failing to correctly compute the size of the sequence.
Fix these.
* tests/test-core-diff.cc: Add a new regression test for the two
cases above.
* tests/data/test-core-diff/report7.txt: New reference data for
the new regression test.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (insertion::inserted_): Changed the
type of this from vector<int> to vector<unsigned>.
(insertion::{insertion, inserted_indexes}): Adjust.
(compute_diff): Add two new simpler overloads. Implement them in
term of the former more complex overload.
(compute_lcs): Adjust for the vector<int> -> vector<unsigned>
change.
* src/abg-diff-utils.cc (compute_lcs, compute_ses): Adjust for the
compute_diff change above.
* src/abg-comparison.cc (compute_diff, report_changes): Adjust for
the compute_diff & vector<unsigned> changes above..
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h (point::{operator!=,operator==}): New
operators.
(end_of_fr_d_path_in_k, end_of_frr_d_path_in_k_plus_delta): Allow
the initial point (-1,-1) that is not a point addressing elements
of the input sequences, but that is the starting point of the
forward paths and the ending point of reverse paths in the "Linear
Refinement" of the algorithm.
(is_match_point, maybe_record_match_point)
(find_snake_start_point): New functions.
(find_last_snake_in_path): Remove this. It's not used anymore.
(compute_middle_snake): Allow checking for overlapping paths even
on points that are outside of the edit graph boundaries. Once the
overlap is detected, if a non-empty snake has been seen already,
report it as the middle snake. Otherwise, keep building the path
until the end and report the last snake encountered as the middle
snake. Add comments.
(compute_diff): For the d == 1 case, fix the logic of the finding
the non-diagonal edge. Fix typos. Add comments.
(display_edit_script): Fix report glitches.
* tests/data/test-core-diff/report3.txt: Update as per the report
glitch above.
* tests/data/test-core-diff/report4.txt: Likewise.
* tests/data/test-core-diff/report5.txt: Likewise.
* tests/data/test-core-diff/report6.txt: New reference report for
a new test.
* tests/test-core-diff.cc: Add a new test for negative delta.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* diff2.h (point::point): New copy constructor.
(point::{operator+=, operator=}): Use point::set.
(point::{operator--, operator++,}): New operators.
(d_path_vec::{a_size_, b_size_}): New members.
(d_path_vec::max_d_): Remove this member.
(d_path_vec::max_d): Compute this, now that max_d_ was removed.
(point_is_valid_in_graph): Declare this new function.
(end_of_fr_d_path_in_k, ): Return
a bool when the end of furthest reaching past found is within the
bounds of the edit graph. Add comments.
(end_of_frr_d_path_in_k_plus_delta): Likewise. Also, delta can be
negative; support that. Do not cross the boundaries of the edit
graph when following a diagonal edge.
(find_last_snake_in_path): New function.
(compute_middle_snake): Make forward/reverse d_path_vec be big
enough to hold paths for M+N differences. Normally M+N/2 should
be enough, but we were getting weird out of bound errors. Let's
handle it this way for now. Do not require that we check for
overlap only when we are on a diagonal edge. Once we detected an
overlap, use the new find_last_snake_in_path to find the
boundaries of the snake.
(ses_len): Delta can be negative.
(display_edit): Small minor English nit.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-diff-utils.h: New file.
* src/abg-diff-utils.cc: Likewise. Implement the code diffing
algorithms from Eugene Myers.
* include/abg-comparison.h: New file. First short at defining the
basic APIs to compute the diff of two classes.
* src/abg-comparison.cc: New file. Start the implementation of
the above header.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>