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