For instance, on Mac OS X memrchr(3) is not provided by the C library.
)
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(net/pfkeyv2.h netipsec/ipsec.h netinet6/ipsec.h linux/udp.h)
}
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
*/
tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data));
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");
tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
suite_add_tcase(s, tc);
*/
void *memstr(const void *haystack, const char *needle, size_t n)
{
- unsigned const char *pos = haystack;
+ const u_char *pos = haystack;
size_t l;
if (!haystack || !needle || (l = strlen(needle)) == 0)
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.
*/
*/
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
* in 'from' and mapping them to characters in 'to'.