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

whitespace: replumb ws_fix_copy to take a strbuf *dst instead of char *dst

To implement --whitespace=fix for tab-in-indent, we have to allow for the possibility that whitespace can increase in size when it is fixed, expanding tabs to to multiple spaces in the initial indent. Signed-off-by: Chris Webb <chris@arachsys.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Chris Webb committed Apr 3, 2010 at 00:37 UTC d511bd330d66fe8f0be21855888e30af2f3e373b
3 files changed +48 -54
builtin/apply.c
+39 -42
@@ -1854,6 +1854,8 @@ static int match_fragment(struct image *img,
1854 {
1855 int i;
1856 char *fixed_buf, *buf, *orig, *target;
1857 + struct strbuf fixed;
1858 + size_t fixed_len;
1859 int preimage_limit;
1860
1861 if (preimage->nr + try_lno <= img->nr) {
@@ -1977,12 +1979,12 @@ static int match_fragment(struct image *img,
1979 * use the whitespace from the preimage.
1980 */
1981 extra_chars = preimage_end - preimage_eof;
1980 - fixed_buf = xmalloc(imgoff + extra_chars);
1981 - memcpy(fixed_buf, img->buf + try, imgoff);
1982 - memcpy(fixed_buf + imgoff, preimage_eof, extra_chars);
1983 - imgoff += extra_chars;
1982 + strbuf_init(&fixed, imgoff + extra_chars);
1983 + strbuf_add(&fixed, img->buf + try, imgoff);
1984 + strbuf_add(&fixed, preimage_eof, extra_chars);
1985 + fixed_buf = strbuf_detach(&fixed, &fixed_len);
1986 update_pre_post_images(preimage, postimage,
1985 - fixed_buf, imgoff, postlen);
1987 + fixed_buf, fixed_len, postlen);
1988 return 1;
1989 }
1990
@@ -1999,27 +2001,22 @@ static int match_fragment(struct image *img,
2001 * but in this loop we will only handle the part of the
2002 * preimage that falls within the file.
2003 */
2002 - fixed_buf = xmalloc(preimage->len + 1);
2003 - buf = fixed_buf;
2004 + strbuf_init(&fixed, preimage->len + 1);
2005 orig = preimage->buf;
2006 target = img->buf + try;
2007 for (i = 0; i < preimage_limit; i++) {
2007 - size_t fixlen; /* length after fixing the preimage */
2008 size_t oldlen = preimage->line[i].len;
2009 size_t tgtlen = img->line[try_lno + i].len;
2010 - size_t tgtfixlen; /* length after fixing the target line */
2011 - char tgtfixbuf[1024], *tgtfix;
2010 + size_t fixstart = fixed.len;
2011 + struct strbuf tgtfix;
2012 int match;
2013
2014 /* Try fixing the line in the preimage */
2015 - fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
2015 + ws_fix_copy(&fixed, orig, oldlen, ws_rule, NULL);
2016
2017 /* Try fixing the line in the target */
2018 - if (sizeof(tgtfixbuf) > tgtlen)
2019 - tgtfix = tgtfixbuf;
2020 - else
2021 - tgtfix = xmalloc(tgtlen);
2022 - tgtfixlen = ws_fix_copy(tgtfix, target, tgtlen, ws_rule, NULL);
2018 + strbuf_init(&tgtfix, tgtlen);
2019 + ws_fix_copy(&tgtfix, target, tgtlen, ws_rule, NULL);
2020
2021 /*
2022 * If they match, either the preimage was based on
@@ -2031,15 +2028,15 @@ static int match_fragment(struct image *img,
2028 * so we might as well take the fix together with their
2029 * real change.
2030 */
2034 - match = (tgtfixlen == fixlen && !memcmp(tgtfix, buf, fixlen));
2031 + match = (tgtfix.len == fixed.len - fixstart &&
2032 + !memcmp(tgtfix.buf, fixed.buf + fixstart,
2033 + fixed.len - fixstart));
2034
2036 - if (tgtfix != tgtfixbuf)
2037 - free(tgtfix);
2035 + strbuf_release(&tgtfix);
2036 if (!match)
2037 goto unmatch_exit;
2038
2039 orig += oldlen;
2042 - buf += fixlen;
2040 target += tgtlen;
2041 }
2042
@@ -2051,19 +2048,18 @@ static int match_fragment(struct image *img,
2048 * false).
2049 */
2050 for ( ; i < preimage->nr; i++) {
2054 - size_t fixlen; /* length after fixing the preimage */
2051 + size_t fixstart = fixed.len; /* start of the fixed preimage */
2052 size_t oldlen = preimage->line[i].len;
2053 int j;
2054
2055 /* Try fixing the line in the preimage */
2059 - fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
2056 + ws_fix_copy(&fixed, orig, oldlen, ws_rule, NULL);
2057
2061 - for (j = 0; j < fixlen; j++)
2062 - if (!isspace(buf[j]))
2058 + for (j = fixstart; j < fixed.len; j++)
2059 + if (!isspace(fixed.buf[j]))
2060 goto unmatch_exit;
2061
2062 orig += oldlen;
2066 - buf += fixlen;
2063 }
2064
2065 /*
@@ -2071,12 +2067,13 @@ static int match_fragment(struct image *img,
2067 * has whitespace breakages unfixed, and fixing them makes the
2068 * hunk match. Update the context lines in the postimage.
2069 */
2070 + fixed_buf = strbuf_detach(&fixed, &fixed_len);
2071 update_pre_post_images(preimage, postimage,
2075 - fixed_buf, buf - fixed_buf, 0);
2072 + fixed_buf, fixed_len, 0);
2073 return 1;
2074
2075 unmatch_exit:
2079 - free(fixed_buf);
2076 + strbuf_release(&fixed);
2077 return 0;
2078 }
2079
@@ -2244,7 +2241,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2241 int match_beginning, match_end;
2242 const char *patch = frag->patch;
2243 int size = frag->size;
2247 - char *old, *new, *oldlines, *newlines;
2244 + char *old, *oldlines;
2245 + struct strbuf newlines;
2246 int new_blank_lines_at_end = 0;
2247 unsigned long leading, trailing;
2248 int pos, applied_pos;
@@ -2254,16 +2252,16 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2252 memset(&preimage, 0, sizeof(preimage));
2253 memset(&postimage, 0, sizeof(postimage));
2254 oldlines = xmalloc(size);
2257 - newlines = xmalloc(size);
2255 + strbuf_init(&newlines, size);
2256
2257 old = oldlines;
2260 - new = newlines;
2258 while (size > 0) {
2259 char first;
2260 int len = linelen(patch, size);
2264 - int plen, added;
2261 + int plen;
2262 int added_blank_line = 0;
2263 int is_blank_context = 0;
2264 + size_t start;
2265
2266 if (!len)
2267 break;
@@ -2293,7 +2291,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2291 /* ... followed by '\No newline'; nothing */
2292 break;
2293 *old++ = '\n';
2296 - *new++ = '\n';
2294 + strbuf_addch(&newlines, '\n');
2295 add_line_info(&preimage, "\n", 1, LINE_COMMON);
2296 add_line_info(&postimage, "\n", 1, LINE_COMMON);
2297 is_blank_context = 1;
@@ -2315,18 +2313,17 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2313 if (first == '+' && no_add)
2314 break;
2315
2316 + start = newlines.len;
2317 if (first != '+' ||
2318 !whitespace_error ||
2319 ws_error_action != correct_ws_error) {
2321 - memcpy(new, patch + 1, plen);
2322 - added = plen;
2320 + strbuf_add(&newlines, patch + 1, plen);
2321 }
2322 else {
2325 - added = ws_fix_copy(new, patch + 1, plen, ws_rule, &applied_after_fixing_ws);
2323 + ws_fix_copy(&newlines, patch + 1, plen, ws_rule, &applied_after_fixing_ws);
2324 }
2327 - add_line_info(&postimage, new, added,
2325 + add_line_info(&postimage, newlines.buf + start, newlines.len - start,
2326 (first == '+' ? 0 : LINE_COMMON));
2329 - new += added;
2327 if (first == '+' &&
2328 (ws_rule & WS_BLANK_AT_EOF) &&
2329 ws_blank_line(patch + 1, plen, ws_rule))
@@ -2351,9 +2348,9 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2348 }
2349 if (inaccurate_eof &&
2350 old > oldlines && old[-1] == '\n' &&
2354 - new > newlines && new[-1] == '\n') {
2351 + newlines.len > 0 && newlines.buf[newlines.len - 1] == '\n') {
2352 old--;
2356 - new--;
2353 + strbuf_setlen(&newlines, newlines.len - 1);
2354 }
2355
2356 leading = frag->leading;
@@ -2385,8 +2382,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2382 pos = frag->newpos ? (frag->newpos - 1) : 0;
2383 preimage.buf = oldlines;
2384 preimage.len = old - oldlines;
2388 - postimage.buf = newlines;
2389 - postimage.len = new - newlines;
2385 + postimage.buf = newlines.buf;
2386 + postimage.len = newlines.len;
2387 preimage.line = preimage.line_allocated;
2388 postimage.line = postimage.line_allocated;
2389
@@ -2462,7 +2459,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
2459 }
2460
2461 free(oldlines);
2465 - free(newlines);
2462 + strbuf_release(&newlines);
2463 free(preimage.line_allocated);
2464 free(postimage.line_allocated);
2465
cache.h
+1 -1
@@ -1049,7 +1049,7 @@ extern unsigned parse_whitespace_rule(const char *);
1049 extern unsigned ws_check(const char *line, int len, unsigned ws_rule);
1050 extern void ws_check_emit(const char *line, int len, unsigned ws_rule, FILE *stream, const char *set, const char *reset, const char *ws);
1051 extern char *whitespace_error_string(unsigned ws);
1052 -extern int ws_fix_copy(char *, const char *, int, unsigned, int *);
1052 +extern void ws_fix_copy(struct strbuf *, const char *, int, unsigned, int *);
1053 extern int ws_blank_line(const char *line, int len, unsigned ws_rule);
1054
1055 /* ls-files */
ws.c
+8 -11
@@ -271,8 +271,8 @@ int ws_blank_line(const char *line, int len, unsigned ws_rule)
271 return 1;
272 }
273
274 -/* Copy the line to the buffer while fixing whitespaces */
275 -int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *error_count)
274 +/* Copy the line onto the end of the strbuf while fixing whitespaces */
275 +void ws_fix_copy(struct strbuf *dst, const char *src, int len, unsigned ws_rule, int *error_count)
276 {
277 /*
278 * len is number of bytes to be copied from src, starting
@@ -286,7 +286,6 @@ int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *erro
286 int last_tab_in_indent = -1;
287 int last_space_in_indent = -1;
288 int need_fix_leading_space = 0;
289 - char *buf;
289
290 /*
291 * Strip trailing whitespace
@@ -326,7 +325,6 @@ int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *erro
325 break;
326 }
327
329 - buf = dst;
328 if (need_fix_leading_space) {
329 /* Process indent ourselves */
330 int consecutive_spaces = 0;
@@ -348,28 +346,27 @@ int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *erro
346 char ch = src[i];
347 if (ch != ' ') {
348 consecutive_spaces = 0;
351 - *dst++ = ch;
349 + strbuf_addch(dst, ch);
350 } else {
351 consecutive_spaces++;
352 if (consecutive_spaces == 8) {
355 - *dst++ = '\t';
353 + strbuf_addch(dst, '\t');
354 consecutive_spaces = 0;
355 }
356 }
357 }
358 while (0 < consecutive_spaces--)
361 - *dst++ = ' ';
359 + strbuf_addch(dst, ' ');
360 len -= last;
361 src += last;
362 fixed = 1;
363 }
364
367 - memcpy(dst, src, len);
365 + strbuf_add(dst, src, len);
366 if (add_cr_to_tail)
369 - dst[len++] = '\r';
367 + strbuf_addch(dst, '\r');
368 if (add_nl_to_tail)
371 - dst[len++] = '\n';
369 + strbuf_addch(dst, '\n');
370 if (fixed && error_count)
371 (*error_count)++;
374 - return dst + len - buf;
372 }