xref: /openbsd-src/gnu/usr.bin/cvs/contrib/clmerge.in (revision 43c1707e6f6829177cb1974ee6615ce6c1307689)
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