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