Alien-wxWidgets

 view release on metacpan or  search on metacpan

inc/bin/patch  view on Meta::CPAN


use vars qw/$ERROR/;

# Class data.
BEGIN {
    $ERROR = 0;
}

sub import {
    no strict 'refs';
    *{caller() . '::throw'} = \&throw;
    @{caller() . '::ISA'}   = 'Patch';
}

# Simple throw/catch error handling.
sub throw {
    $@ = join '', @_;
    $@ .= sprintf " at %s line %d\n", (caller)[1..2] unless $@ =~ /\n\z/;
    goto CATCH;
}

# Prints a prompt message and returns response.
sub prompt {
    print @_;
    local $_ = <STDIN>;
    chomp;

inc/bin/patch  view on Meta::CPAN

    my $self = shift;
    return $self->{suffix}              if $self->{suffix};
    return $ENV{SIMPLE_BACKUP_SUFFIX}   if $ENV{SIMPLE_BACKUP_SUFFIX};
    return '.orig';
}

# Apply a patch hunk.  The default assumes a unified diff.
sub apply {
    my ($self, $i_start, $o_start, @hunk) = @_;

    $self->{skip} and throw 'SKIP...ignore this patch';

    if ($self->{reverse}) {
        my $not = { qw/ + - - + / };
        s/^([+-])/$not->{$1}/ for @hunk;
    }

    my @context = map /^[ -](.*)/s, @hunk;
    my $position;
    my $fuzz = 0;

inc/bin/patch  view on Meta::CPAN

                if ($position) {
                    unless ($self->{batch}) {
                        local $_ = prompt (
                            'Reversed (or previously applied) patch detected!',
                            '  Assume -R? [y] '
                        );
                        if (/^[nN]/) {
                            $self->{reverse} = 0;
                            $position = 0;
                            prompt ('Apply anyway? [n] ') =~ /^[yY]/
                                or throw 'SKIP...ignore this patch';
                        }
                    }
                } else {
                    throw 'SKIP...ignore this patch' if $self->{forward};
                }
            } else {
                unless ($position || $self->{reverse} || $self->{force}) {
                    $self->{reverse_check} = 1;
                    $self->{reverse} = 1;
                    shift;
                    return $self->apply(@_);
                }
            }
        }
        $position or throw "Couldn't find anywhere to put hunk.\n";
    } else {
        # No context.  Use given position.
        $position = [$i_start - $self->{i_lines} - 1]
    }

    my $in  = $self->{i_fh};
    my $out = $self->{o_fh};
    my $def = $self->{d_fh};
    my $ifdef = $self->{ifdef};

    # Make sure we're where we left off.
    seek $in, $self->{i_pos}, 0 or throw "Couldn't seek INFILE: $!";

    my $line = $self->{o_lines} + $position->[0] + 1;
    my $off  = $line - $o_start;

    # Set to new position.
    $self->{i_lines} += $position->[0];
    $self->{o_lines} += $position->[0];

    print $out scalar <$in> while $position->[0]--;

inc/bin/patch  view on Meta::CPAN

# Find where an array of lines matches in a file after a given position.
#   $match  => [array of lines]
#   $pos    => search after this position and...
#   $lines  => ...after this many lines after $pos
# Returns the position of the match and the number of lines between the
# starting and matching positions.
sub index {
    my ($self, $match, $pos, $lines) = @_;
    my $in = $self->{i_fh};

    seek $in, $pos, 0 or throw "Couldn't seek INFILE [$in, 0, $pos]: $!";
    <$in> while $lines--;

    if ($self->{'ignore-whitespace'}) {
        s/\s+/ /g for @$match;
    }

    my $tell = tell $in;
    my $line = 0;

    while (<$in>) {
        s/\s+/ /g if $self->{'ignore-whitespace'};
        if ($_ eq $match->[0]) {
            my $fail;
            for (1..$#$match) {
                my $line = <$in>;
                $line =~ s/\s+/ /g if $self->{'ignore-whitespace'};
                $line eq $match->[$_] or $fail++, last;
            }
            if ($fail) {
                seek $in, $tell, 0 or throw "Couldn't seek INFILE: $!";
                <$in>;
            } else {
                return ($tell, $line);
            }
        }
        $line++;
        $tell = tell $in;
    }

    return;

inc/bin/patch  view on Meta::CPAN



package Patch::Ed;

BEGIN { Patch->import }

# Pipe ed script to ed or try to manually process.
sub apply {
    my ($self, @cmd) = @_;

    $self->{skip} and throw 'SKIP...ignore this patch';

    my $out = $self->{o_fh};

    $self->{check} and goto PLAN_J;

    # We start out by adding a magic line to our output.  If this line
    # is still there after piping to ed, then ed failed.  We do this
    # because win32 will silently fail if there is no ed program.
    my $magic = "#!/i/want/a/moogle/stuffy\n";
    print $out $magic;

inc/bin/patch  view on Meta::CPAN

        close ED                             or die "Couldn't close ed: $?";
    };

    # Did pipe to ed work?
    unless ($@ or <$out> ne $magic) {
        $self->note("Hunk #$self->{hunk} succeeded at 1.\n");
        return 1;
    }

    # Erase any trace of magic line.
    truncate $out, 0 or throw "Couldn't truncate OUT: $!";
    seek $out, 0, 0  or throw "Couldn't seek OUT: $!";

    # Try to apply ed script by hand.
    $self->note("Pipe to ed failed.  Switching to Plan J...\n");

    PLAN_J:

    # Pre-process each ed command.  Ed diffs are reversed (so that each
    # command doesn't end up changing the line numbers of subsequent
    # commands).  But we need to apply diffs in a forward direction because
    # our filehandles are oriented that way.  So we calculate the @offset
    # in line number that this will cause as we go.
    my @offset;
    for (my $i = 0; $i < @cmd; $i++) {
        my @hunk = @{$cmd[$i]};

        shift(@hunk) =~ m!^(\d+)(?:,(\d+))?([acds])!
            or throw "Unable to parse ed script.";

        my ($start, $end, $cmd) = ($1, $2 || $1, $3);

        # We don't parse substitution commands and assume they all mean
        # s/\.\././ even if they really mean s/\s+// or such.  And we
        # blindly apply the command to the previous hunk.
        if ($cmd eq 's') {
            $cmd[$i] = '';
            s/\.\././ for @{$cmd[$i-1][3]};
            next;



( run in 0.407 second using v1.01-cache-2.11-cpan-496ff517765 )