X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=topbloke.git;a=blobdiff_plain;f=topbloke-merge-lists;h=ef87b13b01f070f287ba30e4455e21abe26bd7a3;hp=c717c4f149ba108c3bb7dac8f966976e637b273c;hb=494c30db6e5fd21d19e8dfc9a10fd37fe46529d0;hpb=6c32fd2ae5829439a93491f83e9739160d275bed diff --git a/topbloke-merge-lists b/topbloke-merge-lists index c717c4f..ef87b13 100755 --- a/topbloke-merge-lists +++ b/topbloke-merge-lists @@ -7,6 +7,8 @@ use IO::Handle; our %flag; our (@order, @order_final_maybe); our $verbose=0; +our $propsmode=0; +our $marker=5; # we don't use Getopt::Long because we want to be quick to start up # and we're not really a very user-facing utility @@ -14,13 +16,19 @@ our $verbose=0; while (@ARGV && $ARGV[0] =~ m/^\-/) { $_ = shift @ARGV; if (s/^-U//) { - $flag{$_}{Result} = 0; + $flag{$_}{ForceResult} = 1; + $flag{$_}{Result} = undef; push @order_final_maybe, $_; } elsif (s/^-D//) { - $flag{$_}{Result} = 1; + $flag{$_}{ForceResult} = 1; + $flag{$_}{Result} = ''; push @order_final_maybe, $_; } elsif (m/^-v$/) { $verbose = 1; + } elsif (m/^-P$/) { + $propsmode = 1; + } elsif (m/^-M(\d+)$/) { + $marker = $1; } elsif (m/^--$/) { last; } else { @@ -34,9 +42,9 @@ foreach my $ix (qw(0 1 2)) { open F, '<', $ARGV[$ix] or die "$ix $!"; while () { chomp or die; - $flag{$_}{Input}[$ix] = 1; - my $ff = $flag{$_}; - push @order, $_ unless $ff->{InOrder}++; + ($propsmode && m/ /) or m/$/; + $flag{$`}{Input}[$ix] = $'; #'; + push @order, $` unless $flag{$`}{InOrder}++; } F->error and die $!; close F or die $!; @@ -50,27 +58,55 @@ my $current = $ARGV[0]; open O, '>', "$current.tmp" or die "$current.tmp $!"; -foreach $_ (@order) { - my $ff = $flag{$_}; - if (!defined $ff->{Result}) { - my $s = ''; - foreach my $ix (qw(0 1 2)) { - $ff->{Input}[$ix] ||= 0; - $s .= $ff->{Input}[$ix]; - } - if ($verbose) { - print STDERR "MERGE-LISTS $s $_\n" or die $!; +sub prmark ($) { + print O $_[0] x $marker, "\n" or die $!; + } +sub prval ($) { + my $v = @_; + print O $v,"\n" or die $! if defined $v; +} + +our $f; + +if ($verbose) { + sub verb ($) { print STDERR "MERGE_LISTS $f @_\n" or die $!; } +} else { + sub verb { } +} + +our $conflicts = 0; + +foreach $f (@order) { + my $ff = $flag{$f}; + verb("BEGIN"); + if (defined $ff->{ForceResult}) { + verb("FORCE"); + } else { + my @in = @{ $ff->{Input} }; + verb(defined ? "DEF $_": "U") foreach @in; + if (iseq($in[0], $in[2])) { + verb("SAME"); + $ff->{Result} = [0]; + } elsif (iseq($in[0], $in[1])) { + verb("THEIRS"); + $ff->{Result} = $in[2]; + } elsif (iseq($in[2], $in[1])) { + verb("OURS"); + $ff->{Result} = $in[0]; + } else { + $conflicts++; + verb("CONFLICT"); + prmark('<'); + prval($in[0]); + prmark('='); + prval($in[2]); + prmark('>'); + next; } - $ff->{Result} = - $s eq '000' ? '000' : - $s eq '111' ? '111' : - !$ff->{Input}[1]; - } - if ($ff->{Result}) { - print O "$_\n" or die $!; } + prval($ff->{Result}); } close O or die $!; rename "$current.tmp", "$current" or die "$current $!"; -exit 0; +exit $conficts ? 1 :0;