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>
Christian Couder committed
May 11, 2016 at 15:16 UTC
7a3eb9e2224d883df229fe4adce51e762165573a
1 file changed
+71
-55
builtin/apply.c
+71
-55
@@ -2242,6 +2242,74 @@ static void update_pre_post_images(struct image *preimage,
2242
postimage->nr -= reduced;
2243
}
2244
2245
+static int line_by_line_fuzzy_match(struct image *img,
2246
+ struct image *preimage,
2247
+ struct image *postimage,
2248
+ unsigned long try,
2249
+ int try_lno,
2250
+ int preimage_limit)
2251
+{
2252
+ int i;
2253
+ size_t imgoff = 0;
2254
+ size_t preoff = 0;
2255
+ size_t postlen = postimage->len;
2256
+ size_t extra_chars;
2257
+ char *buf;
2258
+ char *preimage_eof;
2259
+ char *preimage_end;
2260
+ struct strbuf fixed;
2261
+ char *fixed_buf;
2262
+ size_t fixed_len;
2263
+
2264
+ for (i = 0; i < preimage_limit; i++) {
2265
+ size_t prelen = preimage->line[i].len;
2266
+ size_t imglen = img->line[try_lno+i].len;
2267
+
2268
+ if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,
2269
+ preimage->buf + preoff, prelen))
2270
+ return 0;
2271
+ if (preimage->line[i].flag & LINE_COMMON)
2272
+ postlen += imglen - prelen;
2273
+ imgoff += imglen;
2274
+ preoff += prelen;
2275
+ }
2276
+
2277
+ /*
2278
+ * Ok, the preimage matches with whitespace fuzz.
2279
+ *
2280
+ * imgoff now holds the true length of the target that
2281
+ * matches the preimage before the end of the file.
2282
+ *
2283
+ * Count the number of characters in the preimage that fall
2284
+ * beyond the end of the file and make sure that all of them
2285
+ * are whitespace characters. (This can only happen if
2286
+ * we are removing blank lines at the end of the file.)
2287
+ */
2288
+ buf = preimage_eof = preimage->buf + preoff;
2289
+ for ( ; i < preimage->nr; i++)
2290
+ preoff += preimage->line[i].len;
2291
+ preimage_end = preimage->buf + preoff;
2292
+ for ( ; buf < preimage_end; buf++)
2293
+ if (!isspace(*buf))
2294
+ return 0;
2295
+
2296
+ /*
2297
+ * Update the preimage and the common postimage context
2298
+ * lines to use the same whitespace as the target.
2299
+ * If whitespace is missing in the target (i.e.
2300
+ * if the preimage extends beyond the end of the file),
2301
+ * use the whitespace from the preimage.
2302
+ */
2303
+ extra_chars = preimage_end - preimage_eof;
2304
+ strbuf_init(&fixed, imgoff + extra_chars);
2305
+ strbuf_add(&fixed, img->buf + try, imgoff);
2306
+ strbuf_add(&fixed, preimage_eof, extra_chars);
2307
+ fixed_buf = strbuf_detach(&fixed, &fixed_len);
2308
+ update_pre_post_images(preimage, postimage,
2309
+ fixed_buf, fixed_len, postlen);
2310
+ return 1;
2311
+}
2312
+
2313
static int match_fragment(struct image *img,
2314
struct image *preimage,
2315
struct image *postimage,
@@ -2331,61 +2399,9 @@ static int match_fragment(struct image *img,
2399
* fuzzy matching. We collect all the line length information because
2400
* we need it to adjust whitespace if we match.
2401
*/
2334
- if (ws_ignore_action == ignore_ws_change) {
2335
- size_t imgoff = 0;
2336
- size_t preoff = 0;
2337
- size_t postlen = postimage->len;
2338
- size_t extra_chars;
2339
- char *preimage_eof;
2340
- char *preimage_end;
2341
- for (i = 0; i < preimage_limit; i++) {
2342
- size_t prelen = preimage->line[i].len;
2343
- size_t imglen = img->line[try_lno+i].len;
2344
-
2345
- if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,
2346
- preimage->buf + preoff, prelen))
2347
- return 0;
2348
- if (preimage->line[i].flag & LINE_COMMON)
2349
- postlen += imglen - prelen;
2350
- imgoff += imglen;
2351
- preoff += prelen;
2352
- }
2353
-
2354
- /*
2355
- * Ok, the preimage matches with whitespace fuzz.
2356
- *
2357
- * imgoff now holds the true length of the target that
2358
- * matches the preimage before the end of the file.
2359
- *
2360
- * Count the number of characters in the preimage that fall
2361
- * beyond the end of the file and make sure that all of them
2362
- * are whitespace characters. (This can only happen if
2363
- * we are removing blank lines at the end of the file.)
2364
- */
2365
- buf = preimage_eof = preimage->buf + preoff;
2366
- for ( ; i < preimage->nr; i++)
2367
- preoff += preimage->line[i].len;
2368
- preimage_end = preimage->buf + preoff;
2369
- for ( ; buf < preimage_end; buf++)
2370
- if (!isspace(*buf))
2371
- return 0;
2372
-
2373
- /*
2374
- * Update the preimage and the common postimage context
2375
- * lines to use the same whitespace as the target.
2376
- * If whitespace is missing in the target (i.e.
2377
- * if the preimage extends beyond the end of the file),
2378
- * use the whitespace from the preimage.
2379
- */
2380
- extra_chars = preimage_end - preimage_eof;
2381
- strbuf_init(&fixed, imgoff + extra_chars);
2382
- strbuf_add(&fixed, img->buf + try, imgoff);
2383
- strbuf_add(&fixed, preimage_eof, extra_chars);
2384
- fixed_buf = strbuf_detach(&fixed, &fixed_len);
2385
- update_pre_post_images(preimage, postimage,
2386
- fixed_buf, fixed_len, postlen);
2387
- return 1;
2388
- }
2402
+ if (ws_ignore_action == ignore_ws_change)
2403
+ return line_by_line_fuzzy_match(img, preimage, postimage,
2404
+ try, try_lno, preimage_limit);
2405
2406
if (ws_error_action != correct_ws_error)
2407
return 0;