2 * wiggle - apply rejected patches
4 * Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
5 * Copyright (C) 2010 Neil Brown <neilb@suse.de>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 * Email: <neilb@suse.de>
27 * split patch or merge files.
33 /* skip 'cp' past the new '\n', or all the way to 'end' */
34 static void skip_eol(char **cp
, char *end
)
37 while (c
< end
&& *c
!= '\n')
44 /* copy one line, or to end, from 'cp' into the stream, extending
47 static void copyline(struct stream
*s
, char **cp
, char *end
)
50 char *to
= s
->body
+s
->len
;
52 while (from
< end
&& *from
!= '\n')
60 int split_patch(struct stream f
, struct stream
*f1
, struct stream
*f2
)
66 int acnt
= 0, bcnt
= 0;
69 char before
[100], after
[100];
71 f1
->body
= f2
->body
= NULL
;
73 r1
.body
= xmalloc(f
.len
);
74 r2
.body
= xmalloc(f
.len
);
82 * 1 first half of context
83 * 2 second half of context
89 if (sscanf(cp
, "@@ -%s +%s @@", before
, after
) == 2) {
91 if (sscanf(before
, "%d,%d", &a
, &b
) == 2)
93 else if (sscanf(before
, "%d", &a
) == 1)
98 if (sscanf(after
, "%d,%d", &c
, &d
) == 2)
100 else if (sscanf(after
, "%d", &c
) == 1)
108 } else if (sscanf(cp
, "*** %d,%d ****", &a
, &b
) == 2) {
111 } else if (sscanf(cp
, "--- %d,%d ----", &c
, &d
) == 2) {
116 if (state
== 1 || state
== 3) {
120 sprintf(buf
+1, "%5d %5d %5d\n", chunks
, a
, acnt
);
121 memcpy(r1
.body
+r1
.len
, buf
, 20);
124 if (state
== 2 || state
== 3) {
127 sprintf(buf
+1, "%5d %5d %5d\n", chunks
, c
, bcnt
);
128 memcpy(r2
.body
+r2
.len
, buf
, 20);
133 if ((*cp
== ' ' || *cp
== '!' || *cp
== '-' || *cp
== '+')
136 copyline(&r1
, &cp
, end
);
141 fprintf(stderr
, "%s: bad context patch at line %d\n",
147 if ((*cp
== ' ' || *cp
== '!' || *cp
== '-' || *cp
== '+')
150 copyline(&r2
, &cp
, end
);
155 fprintf(stderr
, "%s: bad context patch/2 at line %d\n",
165 copyline(&r1
, &cp
, end
);
166 copyline(&r2
, &cp2
, end
);
168 } else if (*cp
== '-') {
170 copyline(&r1
, &cp
, end
);
172 } else if (*cp
== '+') {
174 copyline(&r2
, &cp
, end
);
177 fprintf(stderr
, "%s: bad unified patch at line %d\n",
181 if (acnt
<= 0 && bcnt
<= 0)
186 if (r1
.len
> f
.len
|| r2
.len
> f
.len
)
194 * extract parts of a "diff3 -m" or "wiggle -m" output
196 int split_merge(struct stream f
, struct stream
*f1
, struct stream
*f2
, struct stream
*f3
)
201 struct stream r1
, r2
, r3
;
205 r1
.body
= xmalloc(f
.len
);
206 r2
.body
= xmalloc(f
.len
);
207 r3
.body
= xmalloc(f
.len
);
208 r1
.len
= r2
.len
= r3
.len
= 0;
215 * 1 in file 1 of conflict
216 * 2 in file 2 of conflict
217 * 3 in file 3 of conflict
218 * 4 in file 2 but expecting 1/3 next
226 strncmp(cp
, "<<<<<<<", 7) == 0 &&
227 (cp
[7] == ' ' || cp
[7] == '\n')
232 /* diff3 will do something a bit strange in
233 * the 1st and 3rd sections are the same.
240 * Without a ||||||| at all.
241 * so to know if we are in '1' or '2', skip forward
247 (peek
[7] == ' ' || peek
[7] == '\n')) {
248 if (strncmp(peek
, "|||||||", 7) == 0 ||
249 strncmp(peek
, ">>>>>>>", 7) == 0)
251 else if (strncmp(peek
, "=======", 7) == 0) {
256 skip_eol(&peek
, end
);
260 copyline(&r1
, &cp2
, end
);
262 copyline(&r2
, &cp2
, end
);
263 copyline(&r3
, &cp
, end
);
268 strncmp(cp
, "|||||||", 7) == 0 &&
269 (cp
[7] == ' ' || cp
[7] == '\n')
274 copyline(&r1
, &cp
, end
);
278 strncmp(cp
, "=======", 7) == 0 &&
279 (cp
[7] == ' ' || cp
[7] == '\n')
284 copyline(&r2
, &cp
, end
);
288 strncmp(cp
, ">>>>>>>", 7) == 0 &&
289 (cp
[7] == ' ' || cp
[7] == '\n')
294 copyline(&r3
, &cp
, end
);
298 strncmp(cp
, "=======", 7) == 0 &&
299 (cp
[7] == ' ' || cp
[7] == '\n')
304 copyline(&r2
, &cp
, end
);
308 strncmp(cp
, ">>>>>>>", 7) == 0 &&
309 (cp
[7] == ' ' || cp
[7] == '\n')
315 copyline(&r1
, &t
, end
);
316 copyline(&r3
, &cp
, end
);