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];
72 f1->body = f2->body = NULL;
74 r1.body = xmalloc(f.len);
75 r2.body = xmalloc(f.len);
84 * 1 first half of context
85 * 2 second half of context
91 if (sscanf(cp, "@@ -%99s +%99s @@%99[^\n]", before, after, func) >= 2) {
93 if (sscanf(before, "%d,%d", &a, &b) == 2)
95 else if (sscanf(before, "%d", &a) == 1)
100 if (sscanf(after, "%d,%d", &c, &d) == 2)
102 else if (sscanf(after, "%d", &c) == 1)
110 } else if (sscanf(cp, "*** %d,%d ****", &a, &b) == 2) {
113 } else if (sscanf(cp, "--- %d,%d ----", &c, &d) == 2) {
117 sscanf(cp, "***************%99[^\n]", func);
120 if (state == 1 || state == 3) {
125 sprintf(buf+1, "%5d %5d %5d", chunks, a, acnt);
126 memcpy(r1.body+r1.len, buf, 18);
132 r1.body[r1.len++] = ' ';
133 strcpy(r1.body + r1.len, f);
136 r1.body[r1.len++] = '\n';
137 r1.body[r1.len++] = '\0';
139 if (state == 2 || state == 3) {
142 sprintf(buf+1, "%5d %5d %5d\n", chunks, c, bcnt);
143 memcpy(r2.body+r2.len, buf, 20);
150 if ((*cp == ' ' || *cp == '!' || *cp == '-' || *cp == '+')
153 copyline(&r1, &cp, end);
158 fprintf(stderr, "%s: bad context patch at line %d\n",
164 if ((*cp == ' ' || *cp == '!' || *cp == '-' || *cp == '+')
167 copyline(&r2, &cp, end);
172 fprintf(stderr, "%s: bad context patch/2 at line %d\n",
182 copyline(&r1, &cp, end);
183 copyline(&r2, &cp2, end);
185 } else if (*cp == '-') {
187 copyline(&r1, &cp, end);
189 } else if (*cp == '+') {
191 copyline(&r2, &cp, end);
194 fprintf(stderr, "%s: bad unified patch at line %d\n",
198 if (acnt <= 0 && bcnt <= 0)
203 if (r1.len > f.len || r2.len > f.len)
211 * extract parts of a "diff3 -m" or "wiggle -m" output
213 int split_merge(struct stream f, struct stream *f1, struct stream *f2, struct stream *f3)
217 struct stream r1, r2, r3;
221 r1.body = xmalloc(f.len);
222 r2.body = xmalloc(f.len);
223 r3.body = xmalloc(f.len);
224 r1.len = r2.len = r3.len = 0;
231 * 1 in file 1 of conflict
232 * 2 in file 2 of conflict
233 * 3 in file 3 of conflict
234 * 4 in file 2 but expecting 1/3 next
241 strncmp(cp, "<<<<<<<", 7) == 0 &&
242 (cp[7] == ' ' || cp[7] == '\n')
247 /* diff3 will do something a bit strange in
248 * the 1st and 3rd sections are the same.
255 * Without a ||||||| at all.
256 * so to know if we are in '1' or '2', skip forward
262 (peek[7] == ' ' || peek[7] == '\n')) {
263 if (strncmp(peek, "|||||||", 7) == 0 ||
264 strncmp(peek, ">>>>>>>", 7) == 0)
266 else if (strncmp(peek, "=======", 7) == 0) {
271 skip_eol(&peek, end);
275 copyline(&r1, &cp2, end);
277 copyline(&r2, &cp2, end);
278 copyline(&r3, &cp, end);
283 strncmp(cp, "|||||||", 7) == 0 &&
284 (cp[7] == ' ' || cp[7] == '\n')
289 copyline(&r1, &cp, end);
293 strncmp(cp, "=======", 7) == 0 &&
294 (cp[7] == ' ' || cp[7] == '\n')
299 copyline(&r2, &cp, end);
303 strncmp(cp, ">>>>>>>", 7) == 0 &&
304 (cp[7] == ' ' || cp[7] == '\n')
309 copyline(&r3, &cp, end);
313 strncmp(cp, "=======", 7) == 0 &&
314 (cp[7] == ' ' || cp[7] == '\n')
319 copyline(&r2, &cp, end);
323 strncmp(cp, ">>>>>>>", 7) == 0 &&
324 (cp[7] == ' ' || cp[7] == '\n')
330 copyline(&r1, &t, end);
331 copyline(&r3, &cp, end);