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@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.
52if ($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.
69while (<>) {
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@creche.colorado.edu)
146# 0123456789012345678901234567890
147#
148sub 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