Add valgrind testing of parts of vpatch.
[wiggle/upstream.git] / wiggle.h
blob6541a27a86d16247e05634939a9a2c8f06d02ce9
1 /*
2 * wiggle - apply rejected patches
4 * Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Author: Neil Brown
22 * Email: <neilb@suse.de>
25 #include <stdio.h>
26 #include <string.h>
27 #include <memory.h>
28 #include <getopt.h>
29 #include <stdlib.h>
31 static inline void assert(int a)
33 if (!a)
34 abort();
37 struct stream {
38 char *body;
39 int len;
42 /* an 'elmnt' is a word or a line from the file.
43 * 'start' points into a 'body' in a stream.
44 * When a stream is made of 'diff' hunks, there is a special
45 * elmnt at the start of each hunk which starts with '\0' and
46 * records the line offsets of the hunk. These are 20 bytes long.
47 * "\0\d{5} \d{5} \d{5}\n\0"
48 * The 3 numbers are: chunk number, starting line, number if lines.
49 * An element with len==0 marks EOF.
51 struct elmnt {
52 char *start;
53 int hash;
54 int len;
57 static inline int match(struct elmnt *a, struct elmnt *b)
59 return
60 a->hash == b->hash &&
61 a->len == b->len &&
62 strncmp(a->start, b->start, a->len) == 0;
65 /* end-of-line is important for narrowing conflicts.
66 * In line mode, every element is a line and 'ends a line'
67 * In word mode, the newline element and the diff-hunk element
68 * end a line.
70 static inline int ends_line(struct elmnt e)
72 if (e.len == 20 && e.start[0] == 0)
73 return 1;
74 return e.len && e.start[e.len-1] == '\n';
77 static inline int ends_mline(struct elmnt e)
79 return e.len && (e.start[0] == '\n' || e.start[0] == 0);
82 struct csl {
83 int a, b;
84 int len;
87 struct file {
88 struct elmnt *list;
89 int elcnt;
92 /* The result of a merger is a series of text sections.
93 * Each section may occur in one or more of the three stream,
94 * and may be different in different stream (e.g. for changed text)
95 * or the same.
96 * When a conflict occurs we need to treat some surrounding
97 * sections as being involved in that conflict. For
98 * line-based merging, all surrounding sections until an Unchanged
99 * section are part of the conflict - the Unchanged isn't.
100 * For word-based merging, we need to find Unchanged sections
101 * that include a newline. Further, text within the unchanged
102 * section upto the newline (in whichever direction) is treated
103 * as part of the whole conflict.
104 * Actually... it is possibly for a 'Changed' section to bound
105 * a conflict as it indicates a successful match of A and B.
106 * For line-wise merges, any Changed or Unchanged section bounds a conflict
107 * For word-wise merges, any Changed or Unchanged section that matches
108 * a newline, or immediately follows a newline (in all files) can bound
109 * a conflict.
111 struct merge {
112 enum mergetype {
113 End, Unmatched, Unchanged, Extraneous,
114 Changed, Conflict, AlreadyApplied,
115 } type;
116 int a, b, c; /* start of ranges */
117 int al, bl, cl; /* length of ranges */
118 int c1, c2; /* this or next common-sequence */
119 int in_conflict;
120 int ignored;
121 int lo, hi; /* region of a Changed or Unchanged that is not involved
122 * in a conflict.
123 * These are distances from start of the "before" section,
124 * not indexes into any file.
129 /* plist stores a list of patched files in an array
130 * Each entry identifies a file, the range of the
131 * original patch which applies to this file, some
132 * statistics concerning how many conflicts etc, and
133 * some linkage information so the list can be viewed
134 * as a directory-tree.
136 struct plist {
137 char *file;
138 unsigned int start, end;
139 int parent;
140 int next, prev, last;
141 int open;
142 int chunks, wiggles, conflicts;
143 int calced;
144 int is_merge;
145 char *before, *after;
148 extern struct plist *sort_patches(struct plist *pl, int *np);
149 extern void plist_free(struct plist *pl, int num);
150 extern struct plist *parse_patch(FILE *f, FILE *of, int *np);
151 extern struct stream load_segment(FILE *f, unsigned int start,
152 unsigned int end);
153 extern int set_prefix(struct plist *pl, int n, int strip);
154 extern struct stream load_file(char *name);
155 extern int split_patch(struct stream, struct stream*, struct stream*);
156 extern int split_merge(struct stream, struct stream*, struct stream*,
157 struct stream*);
158 extern struct file split_stream(struct stream s, int type);
159 extern struct csl *pdiff(struct file a, struct file b, int chunks);
160 extern struct csl *diff(struct file a, struct file b);
161 extern struct csl *diff_patch(struct file a, struct file b);
162 extern struct csl *diff_partial(struct file a, struct file b,
163 int alo, int ahi, int blo, int bhi);
164 extern struct csl *worddiff(struct stream f1, struct stream f2,
165 struct file *fl1p, struct file *fl2p);
167 struct ci {
168 int conflicts, wiggles, ignored;
169 struct merge *merger;
171 extern void print_merge(FILE *out,
172 struct file *a, struct file *b, struct file *c,
173 int words, struct merge *merger);
174 extern void printword(FILE *f, struct elmnt e);
175 extern int save_merge(struct file a, struct file b, struct file c,
176 struct merge *merger, char *file, int backup);
178 extern int isolate_conflicts(struct file af, struct file bf, struct file cf,
179 struct csl *csl1, struct csl *csl2, int words,
180 struct merge *m, int show_wiggles);
181 extern struct ci make_merger(struct file a, struct file b, struct file c,
182 struct csl *c1, struct csl *c2, int words,
183 int ignore_already, int show_wiggles);
185 extern void die(void);
186 extern void *xmalloc(int len);
187 extern int do_trace;
189 extern int vpatch(int argc, char *argv[], int patch, int strip,
190 int reverse, int replace, int selftest);
192 extern char *Cmd;
193 extern char Version[];
194 extern char short_options[];
195 extern struct option long_options[];
196 enum other_options {
197 SELF_TEST = 300,
199 extern char Usage[];
200 extern char Help[];
201 extern char HelpExtract[];
202 extern char HelpDiff[];
203 extern char HelpMerge[];
204 extern char HelpBrowse[];
206 extern void cleanlist(struct file a, struct file b, struct csl *list);
208 enum {
209 ByLine,
210 ByWord,