=pod

=head1 NAME

Algorithm::ApplyDiffs -- apply one or more Algorithm::Diff diffs

=head1 SYNOPSIS

        # Setup
	use Algorithm::Applydiffs qw{applydiffs};
        my @diff1 = generate_diff_somehow();
        my @diff2 = generate_diff_somehow();
        ...
        my @diffN = generate_diff_somehow();
        my @ary = generate_array_somwhow();

        # Usage:
        @newary = applydiffs(\@ary,
                             diff1_name => \@diff1,
                             diff2_name => \@diff2,
	                     ...
                             diffN_name => \@diffN);

        # or:
        @newary = applydiffs(\@ary, %named_diffs);

        # Scalar context:
        $newary = applydiffs(\@ary, %named_diffs);

        # Extension arguments:
        $newary = applydiffs(\@ary, {
                                 resolver => \&some_sub,
	                         opt1 => ...,
	                         opt2 => ...,
                             }, %named_diffs);

=head1 DESCRIPTION

This module contains subroutines for applying diff sequences generated
by B<Algorithm::Diff> to a target array in the hope of regenerating a
new array incorporating all the changes described by the diff
sequences.

If two hunks from different diff sequences happen to affect the same
line, conflicts are detected and handed off to a helper subroutine for
resolution.

=head2 applydiffs()

	@array_new    = applydiffs(\@array_old, %named_diffs);
        $arrayref_new = applydiffs(\@array_old, %named_diffs);

Returns an operated-on copy of @array_old with all the diff sequences
in I<%named_diffs> applied to it. In a scalar context, B<applydiffs()>
returns the new array as a reference instead of as an array.

	@array_new    = applydiffs(\@array_old, \%opts, %named_diffs);
        $arrayref_new = applydiffs(\@array_old, \%opts, %named_diffs);

A hash-reference containing extension options can be passed in as a
second argument. Currently recognised options to I<applydiffs()> are:

=over 4

=item resolver

This option can be used to supply a subroutine which will be called
when a conflict is detected. The job of this callback is to return
some kind of resolution of the conflicting sub-arrays. The sub is
called a little like this:

     @ret = $callback->(alt_txts => {
                            diff1_name => ['m', 'n', 'o'],
	                    diff3_name => [],
                        } );

The C<alt_txts> parameter is a hash ref keyed by (some of the) names
of the diffs being applied in the main applydiffs() call, whose values are
arrays containing alternative generated subsequences. Each of these
subsequences is the result of applying a set of hunks from the
corresponding diff to a copy of the slice of the source array where
the conflict happened.

A resolver callback is expected to return an array which is spliced
into the array that I<applydiffs()> is going to return.

There are a scad of other options too, but these are undocumented
because they're liable to change.

=back

=head2 mark_conflicts()

       mark_conflicts(alt_txts => {
	                  $diff1_name => \@alt1,
	                  $diff2_name => \@alt2,
                          ...,
                      });

This is the builtin C<resolver> callback, used by I<applydiffs()> by
default. It causes I<applydiffs()> to return arrays looking a bit
like:

       [ @part_before_conflict,
         ">>>>>> diff1_name\n",
         @lines_from_diff1_only,
         ">>>>>> diff2_name\n"
         @lines_from_diff2_only,
         "<<<<<<\n",
         @part_after_conflict,
       ]

Which is probably the right thing to do if your array is going to be
printed out one item per line.

=head1 BUGS AND TODO

This thing was going to be called I<Algorithm::Patch>, but that's far
too grandiose a description for the simplistic activity performed by
this module. For one thing, B<Algorithm::Diff> doesn't (yet) generate
contexts, so fuzzing would be out of the question.

B<Algorithm::ApplyDiffs> does not yet optimise identical or similar
change hunks from different diffs, although that is planned for the
future.

=head1 AUTHOR

Andrew Chadwick, I<andrewc-algoaplydiff@piffle.org>.

=head1 LICENCE

Copyright (c) 2003 Andrew Chadwick. This program is free software; you
may copy it, redistribute it, or modify it under the same terms as
Perl itself.

=cut

