1*43c1707eStholo#! @PERL@ 2*43c1707eStholo 3*43c1707eStholo# Merge conflicted ChangeLogs 4*43c1707eStholo# tromey Mon Aug 15 1994 5*43c1707eStholo 6*43c1707eStholo# Usage is: 7*43c1707eStholo# 8*43c1707eStholo# cl-merge [-i] file ... 9*43c1707eStholo# 10*43c1707eStholo# With -i, it works in place (backups put in a ~ file). Otherwise the 11*43c1707eStholo# merged ChangeLog is printed to stdout. 12*43c1707eStholo 13*43c1707eStholo# Please report any bugs to me. I wrote this yesterday, so there are no 14*43c1707eStholo# guarantees about its performance. I recommend checking its output 15*43c1707eStholo# carefully. If you do send a bug report, please include the failing 16*43c1707eStholo# ChangeLog, so I can include it in my test suite. 17*43c1707eStholo# 18*43c1707eStholo# Tom 19*43c1707eStholo# --- 20*43c1707eStholo# tromey@busco.lanl.gov Member, League for Programming Freedom 21*43c1707eStholo# Sadism and farce are always inexplicably linked. 22*43c1707eStholo# -- Alexander Theroux 23*43c1707eStholo 24*43c1707eStholo 25*43c1707eStholo# Month->number mapping. Used for sorting. 26*43c1707eStholo%months = ('Jan', 0, 27*43c1707eStholo 'Feb', 1, 28*43c1707eStholo 'Mar', 2, 29*43c1707eStholo 'Apr', 3, 30*43c1707eStholo 'May', 4, 31*43c1707eStholo 'Jun', 5, 32*43c1707eStholo 'Jul', 6, 33*43c1707eStholo 'Aug', 7, 34*43c1707eStholo 'Sep', 8, 35*43c1707eStholo 'Oct', 9, 36*43c1707eStholo 'Nov', 10, 37*43c1707eStholo 'Dec', 11); 38*43c1707eStholo 39*43c1707eStholo# If '-i' is given, do it in-place. 40*43c1707eStholoif ($ARGV[0] eq '-i') { 41*43c1707eStholo shift (@ARGV); 42*43c1707eStholo $^I = '~'; 43*43c1707eStholo} 44*43c1707eStholo 45*43c1707eStholo$lastkey = ''; 46*43c1707eStholo$lastval = ''; 47*43c1707eStholo$conf = 0; 48*43c1707eStholo%conflist = (); 49*43c1707eStholo 50*43c1707eStholo$tjd = 0; 51*43c1707eStholo 52*43c1707eStholo# Simple state machine. The states: 53*43c1707eStholo# 54*43c1707eStholo# 0 Not in conflict. Just copy input to output. 55*43c1707eStholo# 1 Beginning an entry. Next non-blank line is key. 56*43c1707eStholo# 2 In entry. Entry beginner transitions to state 1. 57*43c1707eStholowhile (<>) { 58*43c1707eStholo if (/^<<<</ || /^====/) { 59*43c1707eStholo # Start of a conflict. 60*43c1707eStholo 61*43c1707eStholo # Copy last key into array. 62*43c1707eStholo if ($lastkey ne '') { 63*43c1707eStholo $conflist{$lastkey} = $lastval; 64*43c1707eStholo 65*43c1707eStholo $lastkey = ''; 66*43c1707eStholo $lastval = ''; 67*43c1707eStholo } 68*43c1707eStholo 69*43c1707eStholo $conf = 1; 70*43c1707eStholo } elsif (/^>>>>/) { 71*43c1707eStholo # End of conflict. Output. 72*43c1707eStholo 73*43c1707eStholo # Copy last key into array. 74*43c1707eStholo if ($lastkey ne '') { 75*43c1707eStholo $conflist{$lastkey} = $lastval; 76*43c1707eStholo 77*43c1707eStholo $lastkey = ''; 78*43c1707eStholo $lastval = ''; 79*43c1707eStholo } 80*43c1707eStholo 81*43c1707eStholo foreach (reverse sort clcmp keys %conflist) { 82*43c1707eStholo print STDERR "doing $_" if $tjd; 83*43c1707eStholo print $_; 84*43c1707eStholo print $conflist{$_}; 85*43c1707eStholo } 86*43c1707eStholo 87*43c1707eStholo $lastkey = ''; 88*43c1707eStholo $lastval = ''; 89*43c1707eStholo $conf = 0; 90*43c1707eStholo %conflist = (); 91*43c1707eStholo } elsif ($conf == 1) { 92*43c1707eStholo # Beginning an entry. Skip empty lines. Error if not a real 93*43c1707eStholo # beginner. 94*43c1707eStholo if (/^$/) { 95*43c1707eStholo # Empty line; just skip at this point. 96*43c1707eStholo } elsif (/^[MTWFS]/) { 97*43c1707eStholo # Looks like the name of a day; assume opener and move to 98*43c1707eStholo # "in entry" state. 99*43c1707eStholo $lastkey = $_; 100*43c1707eStholo $conf = 2; 101*43c1707eStholo print STDERR "found $_" if $tjd; 102*43c1707eStholo } else { 103*43c1707eStholo die ("conflict crosses entry boundaries: $_"); 104*43c1707eStholo } 105*43c1707eStholo } elsif ($conf == 2) { 106*43c1707eStholo # In entry. Copy into variable until we see beginner line. 107*43c1707eStholo if (/^[MTWFS]/) { 108*43c1707eStholo # Entry beginner line. 109*43c1707eStholo 110*43c1707eStholo # Copy last key into array. 111*43c1707eStholo if ($lastkey ne '') { 112*43c1707eStholo $conflist{$lastkey} = $lastval; 113*43c1707eStholo 114*43c1707eStholo $lastkey = ''; 115*43c1707eStholo $lastval = ''; 116*43c1707eStholo } 117*43c1707eStholo 118*43c1707eStholo $lastkey = $_; 119*43c1707eStholo print STDERR "found $_" if $tjd; 120*43c1707eStholo $lastval = ''; 121*43c1707eStholo } else { 122*43c1707eStholo $lastval .= $_; 123*43c1707eStholo } 124*43c1707eStholo } else { 125*43c1707eStholo # Just copy. 126*43c1707eStholo print; 127*43c1707eStholo } 128*43c1707eStholo} 129*43c1707eStholo 130*43c1707eStholo# Compare ChangeLog time strings like <=>. 131*43c1707eStholo# 132*43c1707eStholo# 0 1 2 3 133*43c1707eStholo# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu) 134*43c1707eStholo# 0123456789012345678901234567890 135*43c1707eStholo# 136*43c1707eStholosub clcmp { 137*43c1707eStholo # First check year. 138*43c1707eStholo $r = substr ($a, 20, 4) <=> substr ($b, 20, 4); 139*43c1707eStholo 140*43c1707eStholo # Now check month. 141*43c1707eStholo $r = $months{substr ($a, 4, 3)} <=> $months{substr ($b, 4, 3)} if !$r; 142*43c1707eStholo 143*43c1707eStholo # Now check day. 144*43c1707eStholo $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r; 145*43c1707eStholo 146*43c1707eStholo # Now check time (3 parts). 147*43c1707eStholo $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r; 148*43c1707eStholo $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r; 149*43c1707eStholo $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r; 150*43c1707eStholo 151*43c1707eStholo $r; 152*43c1707eStholo} 153