git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 03/13] builtin-apply.c: push match-beginning/end logic down

From
Junio C Hamano <gitster@pobox.com>
Date
Feb 2, 2008, 10:54 UTC
Message-ID
<1201949659-27725-4-git-send-email-gitster@pobox.com>
In-Reply-To
<1201949659-27725-3-git-send-email-gitster@pobox.com>

This moves the logic to force match at the beginning and/or at the end of the buffer to the actual function that finds the match from its caller. This is a necessary preparation for the next step to allow matching disregarding certain differences, such as whitespace changes.

We probably could optimize this even more by taking advantage of the fact that match_beginning and match_end forces the match to be at an exact location (anchored at the beginning and/or the end), but that's for another commit.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-apply.c |   46 ++++++++++++++++++++++++++++++++--------------
 1 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 0a304ab..f84a405 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1439,18 +1439,36 @@ static int read_old_data(struct stat *st, const char *path, struct strbuf *buf)
 
 static int match_fragment(const char *buf, unsigned long size,
 			  unsigned long try,
-			  const char *fragment, unsigned long fragsize)
+			  const char *fragment, unsigned long fragsize,
+			  int match_beginning, int match_end)
 {
-	if (try + fragsize > size)
+	if (match_beginning && try)
 		return 0;
-	if (memcmp(buf + try, fragment, fragsize))
-		return 0;
-	return 1;
+
+	/*
+	 * Do we have an exact match?  If we were told to match
+	 * at the end, size must be exactly at try+fragsize,
+	 * otherwise try+fragsize must be still within the preimage,
+	 * and either case, the old piece should match the preimage
+	 * exactly.
+	 */
+	if ((match_end
+	     ? (try + fragsize == size)
+	     : (try + fragsize <= size)) &&
+	    !memcmp(buf + try, fragment, fragsize))
+		return 1;
+
+	/*
+	 * NEEDSWORK: We can optionally match fuzzily here, but
+	 * that is for a later round.
+	 */
+	return 0;
 }
 
 static int find_offset(const char *buf, unsigned long size,
 		       const char *fragment, unsigned long fragsize,
-		       int line, int *lines)
+		       int line, int *lines,
+		       int match_beginning, int match_end)
 {
 	int i, no_more_backwards, no_more_forwards;
 	unsigned long start, backwards, forwards, try;
@@ -1483,7 +1501,8 @@ static int find_offset(const char *buf, unsigned long size,
 		no_more_backwards = !backwards;
 		no_more_forwards = (forwards + fragsize > size);
 
-		if (match_fragment(buf, size, try, fragment, fragsize)) {
+		if (match_fragment(buf, size, try, fragment, fragsize,
+				   match_beginning, match_end)) {
 			int shift = ((i+1) >> 1);
 			if (i & 1)
 				shift = -shift;
@@ -1765,17 +1784,16 @@ static int apply_one_fragment(struct strbuf *buf, struct fragment *frag,
 	pos = frag->newpos;
 	for (;;) {
 		offset = find_offset(buf->buf, buf->len,
-				     oldlines, oldsize, pos, &lines);
-		if (match_end && offset + oldsize != buf->len)
-			offset = -1;
-		if (match_beginning && offset)
-			offset = -1;
+				     oldlines, oldsize, pos, &lines,
+				     match_beginning, match_end);
 		if (offset >= 0) {
 			if (ws_error_action == correct_ws_error &&
-			    (buf->len - oldsize - offset == 0)) /* end of file? */
+			    (buf->len - oldsize - offset == 0))
+				/* end of file? */
 				newsize -= new_blank_lines_at_end;
 
-			/* Warn if it was necessary to reduce the number
+			/*
+			 * Warn if it was necessary to reduce the number
 			 * of context lines.
 			 */
 			if ((leading != frag->leading) ||
-- 
1.5.4.2.g41ac4
Previous: Junio C HamanoNext: Junio C Hamano
Message 4 of 14 in “git-apply --whitespace=fix updates”
  1. 00/13 git-apply --whitespace=fix updatesJunio C Hamano, Feb 2, 2008
  2. 01/13 builtin-apply.c: refactor small part that matches contextJunio C Hamano, Feb 2, 2008
  3. 02/13 builtin-apply.c: restructure "offset" matchingJunio C Hamano, Feb 2, 2008
  4. 03/13 builtin-apply.c: push match-beginning/end logic downJunio C Hamano, Feb 2, 2008
  5. 04/13 builtin-apply.c: make it more line orientedJunio C Hamano, Feb 2, 2008
  6. 05/13 builtin-apply.c: optimize match_beginning/end processing a bit.Junio C Hamano, Feb 2, 2008
  7. 06/13 builtin-apply.c: mark common context lines in lineinfo structure.Junio C Hamano, Feb 2, 2008
  8. 07/13 builtin-apply.c: clean-up apply_one_fragment()Junio C Hamano, Feb 2, 2008
  9. 08/13 builtin-apply.c: simplify calling site to apply_line()Junio C Hamano, Feb 2, 2008
  10. 09/13 builtin-apply.c: do not feed copy_wsfix() leading '+'Junio C Hamano, Feb 2, 2008
  11. 10/13 builtin-apply.c: move copy_wsfix() function a bit higher.Junio C Hamano, Feb 2, 2008
  12. 11/13 builtin-apply.c: pass ws_rule down to match_fragment()Junio C Hamano, Feb 2, 2008
  13. 12/13 git-apply --whitespace=fix: fix whitespace fuzz introduced by previous runJunio C Hamano, Feb 2, 2008
  14. 13/13 core.whitespace: cr-at-eolJunio C Hamano, Feb 2, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.