@matheusbsbs / matheus-bagliano / commits / c330fdd42d
Fork 0

builtin-apply.c: mark common context lines in lineinfo structure.

This updates the way preimage and postimage in a patch hunk is parsed and prepared for applying. By looking at image->line[n].flag, the code can tell if it is a common context line that is the same between the preimage and the postimage. This matters when we actually start applying a patch with contexts that have whitespace breakages that have already been fixed in the target file.

Junio C Hamano committed Jan 29, 2008 at 00:17 UTC c330fdd42dc57127272534cd2a8dd9569334b219
1 file changed +32 -25
builtin-apply.c
+32 -25
@@ -170,6 +170,7 @@ struct line {
170 size_t len;
171 unsigned hash : 24;
172 unsigned flag : 8;
173 +#define LINE_COMMON 1
174 };
175
176 /*
@@ -179,6 +180,7 @@ struct image {
180 char *buf;
181 size_t len;
182 size_t nr;
183 + size_t alloc;
184 struct line *line_allocated;
185 struct line *line;
186 };
@@ -195,49 +197,39 @@ static uint32_t hash_line(const char *cp, size_t len)
197 return h;
198 }
199
200 +static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag)
201 +{
202 + ALLOC_GROW(img->line_allocated, img->nr + 1, img->alloc);
203 + img->line_allocated[img->nr].len = len;
204 + img->line_allocated[img->nr].hash = hash_line(bol, len);
205 + img->line_allocated[img->nr].flag = flag;
206 + img->nr++;
207 +}
208 +
209 static void prepare_image(struct image *image, char *buf, size_t len,
210 int prepare_linetable)
211 {
212 const char *cp, *ep;
202 - int n;
213
214 + memset(image, 0, sizeof(*image));
215 image->buf = buf;
216 image->len = len;
217
207 - if (!prepare_linetable) {
208 - image->line = NULL;
209 - image->line_allocated = NULL;
210 - image->nr = 0;
218 + if (!prepare_linetable)
219 return;
212 - }
220
221 ep = image->buf + image->len;
215 -
216 - /* First count lines */
222 cp = image->buf;
218 - n = 0;
219 - while (cp < ep) {
220 - cp = strchrnul(cp, '\n');
221 - n++;
222 - cp++;
223 - }
224 -
225 - image->line_allocated = xcalloc(n, sizeof(struct line));
226 - image->line = image->line_allocated;
227 - image->nr = n;
228 - cp = image->buf;
229 - n = 0;
223 while (cp < ep) {
224 const char *next;
225 for (next = cp; next < ep && *next != '\n'; next++)
226 ;
227 if (next < ep)
228 next++;
236 - image->line[n].len = next - cp;
237 - image->line[n].hash = hash_line(cp, next - cp);
229 + add_line_info(image, cp, next - cp, 0);
230 cp = next;
239 - n++;
231 }
232 + image->line = image->line_allocated;
233 }
234
235 static void clear_image(struct image *image)
@@ -1822,6 +1814,9 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1814 struct image preimage;
1815 struct image postimage;
1816
1817 + memset(&preimage, 0, sizeof(preimage));
1818 + memset(&postimage, 0, sizeof(postimage));
1819 +
1820 while (size > 0) {
1821 char first;
1822 int len = linelen(patch, size);
@@ -1857,10 +1852,14 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1852 break;
1853 old[oldsize++] = '\n';
1854 new[newsize++] = '\n';
1855 + add_line_info(&preimage, "\n", 1, LINE_COMMON);
1856 + add_line_info(&postimage, "\n", 1, LINE_COMMON);
1857 break;
1858 case ' ':
1859 case '-':
1860 memcpy(old + oldsize, patch + 1, plen);
1861 + add_line_info(&preimage, old + oldsize, plen,
1862 + (first == ' ' ? LINE_COMMON : 0));
1863 oldsize += plen;
1864 if (first == '-')
1865 break;
@@ -1869,6 +1868,9 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1868 if (first != '+' || !no_add) {
1869 int added = apply_line(new + newsize, patch,
1870 plen, ws_rule);
1871 + add_line_info(&postimage, new + newsize, added,
1872 + (first == '+' ? 0 : LINE_COMMON));
1873 +
1874 newsize += added;
1875 if (first == '+' &&
1876 added == 1 && new[newsize-1] == '\n')
@@ -1921,8 +1923,13 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1923 }
1924
1925 pos = frag->newpos ? (frag->newpos - 1) : 0;
1924 - prepare_image(&preimage, oldlines, oldsize, 1);
1925 - prepare_image(&postimage, newlines, newsize, 1);
1926 + preimage.buf = old;
1927 + preimage.len = oldsize;
1928 + postimage.buf = new;
1929 + postimage.len = newsize;
1930 + preimage.line = preimage.line_allocated;
1931 + postimage.line = postimage.line_allocated;
1932 +
1933 for (;;) {
1934
1935 applied_pos = find_pos(img, &preimage, &postimage,