mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
builtin/apply: extract line_by_line_fuzzy_match() from match_fragment()
The match_fragment() function is very big and contains a big special case algorithm that does line by line fuzzy matching. So let's extract this algorithm in a separate line_by_line_fuzzy_match() function. Reviewed-by: Stefan Beller <sbeller@google.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
bb0ba99743
commit
7a3eb9e222
126
builtin/apply.c
126
builtin/apply.c
|
@ -2242,6 +2242,74 @@ static void update_pre_post_images(struct image *preimage,
|
|||
postimage->nr -= reduced;
|
||||
}
|
||||
|
||||
static int line_by_line_fuzzy_match(struct image *img,
|
||||
struct image *preimage,
|
||||
struct image *postimage,
|
||||
unsigned long try,
|
||||
int try_lno,
|
||||
int preimage_limit)
|
||||
{
|
||||
int i;
|
||||
size_t imgoff = 0;
|
||||
size_t preoff = 0;
|
||||
size_t postlen = postimage->len;
|
||||
size_t extra_chars;
|
||||
char *buf;
|
||||
char *preimage_eof;
|
||||
char *preimage_end;
|
||||
struct strbuf fixed;
|
||||
char *fixed_buf;
|
||||
size_t fixed_len;
|
||||
|
||||
for (i = 0; i < preimage_limit; i++) {
|
||||
size_t prelen = preimage->line[i].len;
|
||||
size_t imglen = img->line[try_lno+i].len;
|
||||
|
||||
if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,
|
||||
preimage->buf + preoff, prelen))
|
||||
return 0;
|
||||
if (preimage->line[i].flag & LINE_COMMON)
|
||||
postlen += imglen - prelen;
|
||||
imgoff += imglen;
|
||||
preoff += prelen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, the preimage matches with whitespace fuzz.
|
||||
*
|
||||
* imgoff now holds the true length of the target that
|
||||
* matches the preimage before the end of the file.
|
||||
*
|
||||
* Count the number of characters in the preimage that fall
|
||||
* beyond the end of the file and make sure that all of them
|
||||
* are whitespace characters. (This can only happen if
|
||||
* we are removing blank lines at the end of the file.)
|
||||
*/
|
||||
buf = preimage_eof = preimage->buf + preoff;
|
||||
for ( ; i < preimage->nr; i++)
|
||||
preoff += preimage->line[i].len;
|
||||
preimage_end = preimage->buf + preoff;
|
||||
for ( ; buf < preimage_end; buf++)
|
||||
if (!isspace(*buf))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Update the preimage and the common postimage context
|
||||
* lines to use the same whitespace as the target.
|
||||
* If whitespace is missing in the target (i.e.
|
||||
* if the preimage extends beyond the end of the file),
|
||||
* use the whitespace from the preimage.
|
||||
*/
|
||||
extra_chars = preimage_end - preimage_eof;
|
||||
strbuf_init(&fixed, imgoff + extra_chars);
|
||||
strbuf_add(&fixed, img->buf + try, imgoff);
|
||||
strbuf_add(&fixed, preimage_eof, extra_chars);
|
||||
fixed_buf = strbuf_detach(&fixed, &fixed_len);
|
||||
update_pre_post_images(preimage, postimage,
|
||||
fixed_buf, fixed_len, postlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int match_fragment(struct image *img,
|
||||
struct image *preimage,
|
||||
struct image *postimage,
|
||||
|
@ -2331,61 +2399,9 @@ static int match_fragment(struct image *img,
|
|||
* fuzzy matching. We collect all the line length information because
|
||||
* we need it to adjust whitespace if we match.
|
||||
*/
|
||||
if (ws_ignore_action == ignore_ws_change) {
|
||||
size_t imgoff = 0;
|
||||
size_t preoff = 0;
|
||||
size_t postlen = postimage->len;
|
||||
size_t extra_chars;
|
||||
char *preimage_eof;
|
||||
char *preimage_end;
|
||||
for (i = 0; i < preimage_limit; i++) {
|
||||
size_t prelen = preimage->line[i].len;
|
||||
size_t imglen = img->line[try_lno+i].len;
|
||||
|
||||
if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,
|
||||
preimage->buf + preoff, prelen))
|
||||
return 0;
|
||||
if (preimage->line[i].flag & LINE_COMMON)
|
||||
postlen += imglen - prelen;
|
||||
imgoff += imglen;
|
||||
preoff += prelen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, the preimage matches with whitespace fuzz.
|
||||
*
|
||||
* imgoff now holds the true length of the target that
|
||||
* matches the preimage before the end of the file.
|
||||
*
|
||||
* Count the number of characters in the preimage that fall
|
||||
* beyond the end of the file and make sure that all of them
|
||||
* are whitespace characters. (This can only happen if
|
||||
* we are removing blank lines at the end of the file.)
|
||||
*/
|
||||
buf = preimage_eof = preimage->buf + preoff;
|
||||
for ( ; i < preimage->nr; i++)
|
||||
preoff += preimage->line[i].len;
|
||||
preimage_end = preimage->buf + preoff;
|
||||
for ( ; buf < preimage_end; buf++)
|
||||
if (!isspace(*buf))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Update the preimage and the common postimage context
|
||||
* lines to use the same whitespace as the target.
|
||||
* If whitespace is missing in the target (i.e.
|
||||
* if the preimage extends beyond the end of the file),
|
||||
* use the whitespace from the preimage.
|
||||
*/
|
||||
extra_chars = preimage_end - preimage_eof;
|
||||
strbuf_init(&fixed, imgoff + extra_chars);
|
||||
strbuf_add(&fixed, img->buf + try, imgoff);
|
||||
strbuf_add(&fixed, preimage_eof, extra_chars);
|
||||
fixed_buf = strbuf_detach(&fixed, &fixed_len);
|
||||
update_pre_post_images(preimage, postimage,
|
||||
fixed_buf, fixed_len, postlen);
|
||||
return 1;
|
||||
}
|
||||
if (ws_ignore_action == ignore_ws_change)
|
||||
return line_by_line_fuzzy_match(img, preimage, postimage,
|
||||
try, try_lno, preimage_limit);
|
||||
|
||||
if (ws_error_action != correct_ws_error)
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue