utils: Add memrchr(3) replacement for platforms that don't support it
For instance, on Mac OS X memrchr(3) is not provided by the C library.
This commit is contained in:
+1
-1
@@ -533,7 +533,7 @@ AC_CHECK_FUNC(
|
|||||||
)
|
)
|
||||||
|
|
||||||
AC_CHECK_FUNCS(prctl mallinfo getpass closefrom getpwnam_r getgrnam_r getpwuid_r)
|
AC_CHECK_FUNCS(prctl mallinfo getpass closefrom getpwnam_r getgrnam_r getpwuid_r)
|
||||||
AC_CHECK_FUNCS(fmemopen funopen mmap)
|
AC_CHECK_FUNCS(fmemopen funopen mmap memrchr)
|
||||||
|
|
||||||
AC_CHECK_HEADERS(sys/sockio.h glob.h net/if_tun.h linux/fib_rules.h)
|
AC_CHECK_HEADERS(sys/sockio.h glob.h net/if_tun.h linux/fib_rules.h)
|
||||||
AC_CHECK_HEADERS(net/pfkeyv2.h netipsec/ipsec.h netinet6/ipsec.h linux/udp.h)
|
AC_CHECK_HEADERS(net/pfkeyv2.h netipsec/ipsec.h netinet6/ipsec.h linux/udp.h)
|
||||||
|
|||||||
@@ -345,6 +345,46 @@ START_TEST(test_memstr)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* utils_memrchr
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char *s;
|
||||||
|
int c;
|
||||||
|
size_t n;
|
||||||
|
int offset;
|
||||||
|
} memrchr_data[] = {
|
||||||
|
{NULL, 'f', 0, -1},
|
||||||
|
{NULL, 'f', 3, -1},
|
||||||
|
{"", 'f', 0, -1},
|
||||||
|
{"", '\0', 1, 0},
|
||||||
|
{"foo", '\0', 3, -1},
|
||||||
|
{"foo", '\0', 4, 3},
|
||||||
|
{"foo", 'f', 3, 0},
|
||||||
|
{"foo", 'o', 3, 2},
|
||||||
|
{"foo", 'o', 2, 1},
|
||||||
|
{"foo", 'o', 1, -1},
|
||||||
|
{"foo", 'o', 0, -1},
|
||||||
|
{"foo", 'x', 3, -1},
|
||||||
|
};
|
||||||
|
|
||||||
|
START_TEST(test_utils_memrchr)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
ret = utils_memrchr(memrchr_data[_i].s, memrchr_data[_i].c, memrchr_data[_i].n);
|
||||||
|
if (memrchr_data[_i].offset >= 0)
|
||||||
|
{
|
||||||
|
ck_assert(ret == memrchr_data[_i].s + memrchr_data[_i].offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ck_assert(ret == NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* translate
|
* translate
|
||||||
*/
|
*/
|
||||||
@@ -673,6 +713,10 @@ Suite *utils_suite_create()
|
|||||||
tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data));
|
tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data));
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
tc = tcase_create("utils_memrchr");
|
||||||
|
tcase_add_loop_test(tc, test_utils_memrchr, 0, countof(memrchr_data));
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("translate");
|
tc = tcase_create("translate");
|
||||||
tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
|
tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ void memwipe_noinline(void *ptr, size_t n)
|
|||||||
*/
|
*/
|
||||||
void *memstr(const void *haystack, const char *needle, size_t n)
|
void *memstr(const void *haystack, const char *needle, size_t n)
|
||||||
{
|
{
|
||||||
unsigned const char *pos = haystack;
|
const u_char *pos = haystack;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
if (!haystack || !needle || (l = strlen(needle)) == 0)
|
if (!haystack || !needle || (l = strlen(needle)) == 0)
|
||||||
@@ -120,6 +120,28 @@ void *memstr(const void *haystack, const char *needle, size_t n)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
void *utils_memrchr(const void *s, int c, size_t n)
|
||||||
|
{
|
||||||
|
const u_char *pos;
|
||||||
|
|
||||||
|
if (!s || !n)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pos = s + n - 1; pos >= (u_char*)s; pos--)
|
||||||
|
{
|
||||||
|
if (*pos == (u_char)c)
|
||||||
|
{
|
||||||
|
return (void*)pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -464,6 +464,20 @@ static inline void memwipe(void *ptr, size_t n)
|
|||||||
*/
|
*/
|
||||||
void *memstr(const void *haystack, const char *needle, size_t n);
|
void *memstr(const void *haystack, const char *needle, size_t n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replacement for memrchr(3) if it is not provided by the C library.
|
||||||
|
*
|
||||||
|
* @param s start of the memory area to search
|
||||||
|
* @param c character to search
|
||||||
|
* @param n length of memory area to search
|
||||||
|
* @return pointer to the found character or NULL
|
||||||
|
*/
|
||||||
|
void *utils_memrchr(const void *s, int c, size_t n);
|
||||||
|
|
||||||
|
#ifndef HAVE_MEMRCHR
|
||||||
|
#define memrchr(s,c,n) utils_memrchr(s,c,n)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates the characters in the given string, searching for characters
|
* Translates the characters in the given string, searching for characters
|
||||||
* in 'from' and mapping them to characters in 'to'.
|
* in 'from' and mapping them to characters in 'to'.
|
||||||
|
|||||||
Reference in New Issue
Block a user