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