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