From 447a5983ec46196da215e0db4cfa34c4e33f591b Mon Sep 17 00:00:00 2001 From: Stian Skjelstad Date: Wed, 25 Dec 2024 12:59:22 +0100 Subject: [PATCH] Not all systems provide memrchr, example are some MacOS/OSX variants. --- config.h.in | 2 ++ configure | 7 +++++++ configure.ac | 1 + stuff/Makefile | 1 + stuff/compat-test.c | 33 +++++++++++++++++++++++++++++++++ stuff/compat.h | 15 +++++++++++++++ stuff/file.c | 1 + 7 files changed, 60 insertions(+) diff --git a/config.h.in b/config.h.in index 7490b61b..8c7c48f1 100644 --- a/config.h.in +++ b/config.h.in @@ -241,6 +241,8 @@ #undef HAVE_MEMMEM +#undef HAVE_MEMRCHR + #undef HAVE_QSORT #undef HAVE_STRUPR diff --git a/configure b/configure index 538fc786..ba09cfc4 100755 --- a/configure +++ b/configure @@ -8226,6 +8226,13 @@ then : fi +ac_fn_c_check_func "$LINENO" "memrchr" "ac_cv_func_memrchr" +if test "x$ac_cv_func_memrchr" = xyes +then : + printf "%s\n" "#define HAVE_MEMRCHR 1" >>confdefs.h + +fi + ac_fn_c_check_func "$LINENO" "getopt" "ac_cv_func_getopt" if test "x$ac_cv_func_getopt" = xyes then : diff --git a/configure.ac b/configure.ac index 3e0eeb3f..0dc8cd56 100644 --- a/configure.ac +++ b/configure.ac @@ -267,6 +267,7 @@ AC_LINK_IFELSE( ) AC_CHECK_FUNCS([memmem]) +AC_CHECK_FUNCS([memrchr]) AC_CHECK_FUNCS([getopt]) AC_CHECK_FUNCS([getpwuid]) AC_CHECK_FUNCS([popen]) diff --git a/stuff/Makefile b/stuff/Makefile index 04dc0650..88514abe 100644 --- a/stuff/Makefile +++ b/stuff/Makefile @@ -51,6 +51,7 @@ file.o: file.c \ ../config.h \ ../types.h \ ../boot/psetting.h \ + ../stuff/compat.h \ ../stuff/file.h $(CC) $< -o $@ -c diff --git a/stuff/compat-test.c b/stuff/compat-test.c index 9da0a2a9..d27ea03d 100644 --- a/stuff/compat-test.c +++ b/stuff/compat-test.c @@ -1,10 +1,15 @@ #include "config.h" #include "types.h" +#undef HAVE_MEMRCHR +#define memrchr ocp_memrchr + #include "compat.h" #include "compat.c" +#undef memrchr + #include #include @@ -276,6 +281,32 @@ static int test_splitpath42 (void) return failed; } +int test_memrchr (const char *s, const char c, size_t n, const char *e, const char *d) +{ + char *r = ocp_memrchr (s, c, n); + printf("%s: %s\n", d, (r != e) ? "failed" : "ok"); + return r != e; +} + +int do_test_memchr (void) +{ + const char *ooo = "ooo"; + const char *ofo = "ofo"; + + const char *oooo = "oooo"; + const char *foobarfoo = "foobarfoo"; + + int retval = 0; + retval |= test_memrchr ("foo", 'a', 3, 0, "memrchr(\"foo\", 'a', 3) => NULL"); + retval |= test_memrchr (ooo+1, 'o', 0, 0, "memrchr(\"ooo\" + 1, 'o', 0) => NULL"); + retval |= test_memrchr (ooo+1, 'o', 1, ooo+1, "memrchr(\"ooo\" + 1, 'o') => \"ooo\" + 1"); + retval |= test_memrchr (ofo+1, 'o', 1, 0, "memrchr(\"ofo\" + 1, 'o') => NULL"); + retval |= test_memrchr (oooo+1, 'o', 2, oooo+2, "memrchr(\"oooo\" + 1, 'o') => \"oooo\" + 2"); + retval |= test_memrchr (foobarfoo, 'r', 9, foobarfoo + 5, "memrchr(\"foobarfoo\", 'r') => \"rfoo\""); + + return retval; +} + int main(int argc, char *argv[]) { int retval = 0; @@ -284,6 +315,8 @@ int main(int argc, char *argv[]) retval |= test_splitpath42 (); + retval |= do_test_memchr (); + if (retval) { printf ("%sSomething failed%s\n", ANSI_COLOR_RED, ANSI_COLOR_RESET); diff --git a/stuff/compat.h b/stuff/compat.h index 23d0150d..82a13b01 100644 --- a/stuff/compat.h +++ b/stuff/compat.h @@ -10,6 +10,21 @@ void getext_malloc (const char *src, char **ext); extern int splitpath4_malloc(const char *src, char **drive, char **path, char **file, char **ext); /* returns non-zero on errors */ extern int splitpath_malloc(const char *src, char **drive, char **path, char **filename); /* returns non-zero on errors */ +#ifndef HAVE_MEMRCHR +static inline void *memrchr(const void *s, int c, size_t n) +{ + char c2 = c; + char *s2 = (char *)s + n - 1; + while (n--) + { + if (*s2 == c2) return s2; + s2--; + } + + return 0; +} +#endif + #ifndef HAVE_STRUPR #include static inline char *strupr(char *src) diff --git a/stuff/file.c b/stuff/file.c index f634edf7..00ae498c 100644 --- a/stuff/file.c +++ b/stuff/file.c @@ -20,6 +20,7 @@ #include "types.h" #include "boot/psetting.h" +#include "stuff/compat.h" #include "stuff/file.h" struct osfile_cacheline_t