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

[PATCH v2] compat: add memrchr()

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Oct 15, 2010, 15:26 UTC
Message-ID
<20101015152608.GA9450@burratino>
In-Reply-To
<loom.20101015T105350-205@post.gmane.org>

Reimplement another handy convenience function from glibc. memrchr() searches from the end of a memory area for a particular character. It is similar to strrchr() but takes a length argument and is binary-safe.

The whole-directory rename detection patch could use this to find the last '/' in a (possibly truncated) pathname.

The system memrchr() is used on glibc systems to provide a sanity check that our code works with a non-custom implementation. Yes, the various BSDs have their own highly optimized memrchr(), too. The planned use of memrchr in git is for clarity, not speed, so it is not obvious that the makefile+autoconf magic to use libc's implementation on a wide variety of operating systems would be worth the time.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Ludvig Strigeus wrote:
Show 5 quoted lines
> System memrchr uses a byte comparison rather than an int comparison.
> 
> "The memchr() function scans the first n bytes of the memory area pointed to by
> s for the character c. The first byte to match c (interpreted as an unsigned
> character) stops the operation. "
Oh, right.  (strchr() uses char, memchr() uses unsigned char.)
 git-compat-util.h |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/git-compat-util.h b/git-compat-util.h
index 2af8d3e..6de9dee 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -366,6 +366,9 @@ extern int git_vsnprintf(char *str, size_t maxsize,
 #define HAVE_STRCHRNUL
 #define HAVE_MEMPCPY
 #endif
+#if __GLIBC_PREREQ(2, 2)
+#define HAVE_MEMRCHR
+#endif
 #endif
 
 #ifndef HAVE_STRCHRNUL
@@ -386,6 +389,19 @@ static inline void *gitmempcpy(void *dest, const void *src, size_t n)
 }
 #endif
 
+#ifndef HAVE_MEMRCHR
+#define memrchr gitmemrchr
+static inline void *gitmemrchr(const void *s, int c, size_t n)
+{
+	const unsigned char *p = s;
+	p += n;
+	while (p != s)
+		if (*--p == (unsigned char) c)
+			return p;
+	return NULL;
+}
+#endif
+
 extern void release_pack_memory(size_t, int);
 
 typedef void (*try_to_free_t)(size_t);
-- 
1.7.2.3
Previous: Ludvig StrigeusNext: Erik Faye-Lund
Message 15 of 17 in “Detection of directory renames”
  1. 0/5 Detection of directory renamesYann Dirson, Oct 14, 2010
  2. 1/5 Introduce bulk-move detection in diffcore.Yann Dirson, Oct 14, 2010
  3. 2/5 Add testcases for the --detect-bulk-moves diffcore flag.Yann Dirson, Oct 14, 2010
  4. 3/5 [RFC] Handle the simpler case of a subdir invalidating bulk move.Yann Dirson, Oct 14, 2010
  5. 4/5 [RFC] Consider all parents of a file as candidates for bulk rename.Yann Dirson, Oct 14, 2010
  6. 5/5 [WIP] Allow hiding renames of individual files involved in a directory rename.Yann Dirson, Oct 14, 2010
  7. [RFC] Consider all parents of a file as candidates for bulk rename.Yann Dirson, Oct 17, 2010
  8. compat: add memrchr()Jonathan Nieder, Oct 15, 2010
  9. Ævar Arnfjörð BjarmasonOct 15, 2010
  10. Jonathan NiederOct 15, 2010
  11. Ævar Arnfjörð BjarmasonOct 15, 2010
  12. Junio C HamanoOct 15, 2010
  13. Johannes SixtOct 15, 2010
  14. Ludvig StrigeusOct 15, 2010
  15. compat: add memrchr()Jonathan Nieder, Oct 15, 2010
  16. Erik Faye-LundOct 15, 2010
  17. Johannes SixtOct 15, 2010

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.