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=42737e0e1199ef0db7bb6374eb7e8e4702d1bd84;hb=3e8d721402b8e907a2658ef86ce9c05756f85c56;hpb=89cc7b48d4486441fcd6f589b5e344993b522fe7 diff --git a/topbloke-merge-lists b/topbloke-merge-lists index 42737e0..ef87b13 100755 --- a/topbloke-merge-lists +++ b/topbloke-merge-lists @@ -5,16 +5,30 @@ use warnings; use IO::Handle; our %flag; -our @order, @order_final_maybe; +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 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 { @@ -28,38 +42,71 @@ 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 $!; } foreach $_ (@order_final_maybe) { - push @order, $_ unless $flags{$_}{InOrder}++; + push @order, $_ unless $flag{$_}{InOrder}++; } +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] ||= 1; - $s .= $ff->{Input}[$ix]; +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;