add memmem()
memmem() is a nice GNU extension for searching a length limited string in another one. This compat version is based on the version found in glibc 2.2 (GPL 2); I only removed the optimization of checking the first char by hand, and generally tried to keep the code simple. We can add it back if memcmp shows up high in a profile, but for now I prefer to keep it (almost trivially) simple. Since I don't really know which platforms beside those with a glibc have their own memmem(), I used a heuristic: if NO_STRCASESTR is set, then NO_MEMMEM is set, too. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
89b4256cfb
commit
b21b9f1de3
11
Makefile
11
Makefile
@ -28,6 +28,8 @@ all::
|
||||
#
|
||||
# Define NO_STRCASESTR if you don't have strcasestr.
|
||||
#
|
||||
# Define NO_MEMMEM if you don't have memmem.
|
||||
#
|
||||
# Define NO_STRLCPY if you don't have strlcpy.
|
||||
#
|
||||
# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
|
||||
@ -402,6 +404,7 @@ ifeq ($(uname_S),SunOS)
|
||||
NEEDS_NSL = YesPlease
|
||||
SHELL_PATH = /bin/bash
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_HSTRERROR = YesPlease
|
||||
ifeq ($(uname_R),5.8)
|
||||
NEEDS_LIBICONV = YesPlease
|
||||
@ -424,6 +427,7 @@ ifeq ($(uname_O),Cygwin)
|
||||
NO_D_TYPE_IN_DIRENT = YesPlease
|
||||
NO_D_INO_IN_DIRENT = YesPlease
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_SYMLINK_HEAD = YesPlease
|
||||
NEEDS_LIBICONV = YesPlease
|
||||
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
|
||||
@ -442,6 +446,7 @@ ifeq ($(uname_S),FreeBSD)
|
||||
endif
|
||||
ifeq ($(uname_S),OpenBSD)
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NEEDS_LIBICONV = YesPlease
|
||||
BASIC_CFLAGS += -I/usr/local/include
|
||||
BASIC_LDFLAGS += -L/usr/local/lib
|
||||
@ -456,6 +461,7 @@ ifeq ($(uname_S),NetBSD)
|
||||
endif
|
||||
ifeq ($(uname_S),AIX)
|
||||
NO_STRCASESTR=YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_STRLCPY = YesPlease
|
||||
NEEDS_LIBICONV=YesPlease
|
||||
endif
|
||||
@ -467,6 +473,7 @@ ifeq ($(uname_S),IRIX64)
|
||||
NO_IPV6=YesPlease
|
||||
NO_SETENV=YesPlease
|
||||
NO_STRCASESTR=YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_STRLCPY = YesPlease
|
||||
NO_SOCKADDR_STORAGE=YesPlease
|
||||
SHELL_PATH=/usr/gnu/bin/bash
|
||||
@ -661,6 +668,10 @@ ifdef NO_HSTRERROR
|
||||
COMPAT_CFLAGS += -DNO_HSTRERROR
|
||||
COMPAT_OBJS += compat/hstrerror.o
|
||||
endif
|
||||
ifdef NO_MEMMEM
|
||||
COMPAT_CFLAGS += -DNO_MEMMEM
|
||||
COMPAT_OBJS += compat/memmem.o
|
||||
endif
|
||||
|
||||
ifeq ($(TCLTK_PATH),)
|
||||
NO_TCLTK=NoThanks
|
||||
|
29
compat/memmem.c
Normal file
29
compat/memmem.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "../git-compat-util.h"
|
||||
|
||||
void *gitmemmem(const void *haystack, size_t haystack_len,
|
||||
const void *needle, size_t needle_len)
|
||||
{
|
||||
const char *begin = haystack;
|
||||
const char *last_possible = begin + haystack_len - needle_len;
|
||||
|
||||
/*
|
||||
* The first occurrence of the empty string is deemed to occur at
|
||||
* the beginning of the string.
|
||||
*/
|
||||
if (needle_len == 0)
|
||||
return (void *)begin;
|
||||
|
||||
/*
|
||||
* Sanity check, otherwise the loop might search through the whole
|
||||
* memory.
|
||||
*/
|
||||
if (haystack_len < needle_len)
|
||||
return NULL;
|
||||
|
||||
for (; begin <= last_possible; begin++) {
|
||||
if (!memcmp(begin, needle, needle_len))
|
||||
return (void *)begin;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@ -172,6 +172,12 @@ extern uintmax_t gitstrtoumax(const char *, char **, int);
|
||||
extern const char *githstrerror(int herror);
|
||||
#endif
|
||||
|
||||
#ifdef NO_MEMMEM
|
||||
#define memmem gitmemmem
|
||||
void *gitmemmem(const void *haystack, size_t haystacklen,
|
||||
const void *needle, size_t needlelen);
|
||||
#endif
|
||||
|
||||
extern void release_pack_memory(size_t, int);
|
||||
|
||||
static inline char* xstrdup(const char *str)
|
||||
|
Loading…
Reference in New Issue
Block a user