# HG changeset patch # User Mike Becker # Date 1759432905 -7200 # Node ID c5a225d7228ccd55989b782719a4720e7c797f2b # Parent a6f357c18ac63cd9701caec9bb7f06cb4934c36d improve feature test for memrchr() making it also available on BSD diff -r a6f357c18ac6 -r c5a225d7228c configure --- a/configure Thu Oct 02 17:58:43 2025 +0200 +++ b/configure Thu Oct 02 21:21:45 2025 +0200 @@ -115,6 +115,7 @@ --enable-api-docs run Doxygen during build --enable-coverage test coverage with gcov --enable-asan address sanitizer + --disable-memrchr --disable-cxx-tests the check-cxx makefile target --disable-szmul-builtin use custom implementation, instead @@ -161,6 +162,7 @@ fi # features +FEATURE_MEMRCHR=auto FEATURE_CXX_TESTS=auto FEATURE_SZMUL_BUILTIN=auto @@ -195,6 +197,8 @@ "--disable-coverage") unset FEATURE_COVERAGE ;; "--enable-asan") FEATURE_ASAN=on ;; "--disable-asan") unset FEATURE_ASAN ;; + "--enable-memrchr") FEATURE_MEMRCHR=on ;; + "--disable-memrchr") unset FEATURE_MEMRCHR ;; "--enable-cxx-tests") FEATURE_CXX_TESTS=on ;; "--disable-cxx-tests") unset FEATURE_CXX_TESTS ;; "--enable-szmul-builtin") FEATURE_SZMUL_BUILTIN=on ;; @@ -349,7 +353,7 @@ if notistoolchain "gcc"; then break fi - if command -v gcovr > /dev/null ; then + if command -v gcovr > /dev/null 2>&1 ; then : else break @@ -497,13 +501,48 @@ dep_checked_file_tools=1 return 0 } +dependency_error_memrchr() +{ + print_check_msg "$dep_checked_memrchr" "checking for memrchr... " + # dependency memrchr + while true + do + if $TOOLCHAIN_CC -o /dev/null make/test_memrchr.c > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_CFLAGS="$TEMP_CFLAGS -DWITH_MEMRCHR" + print_check_msg "$dep_checked_memrchr" "yes\n" + dep_checked_memrchr=1 + return 1 + done + + # dependency memrchr + while true + do + if $TOOLCHAIN_CC -o /dev/null -D_GNU_SOURCE make/test_memrchr.c > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_CFLAGS="$TEMP_CFLAGS -DWITH_MEMRCHR -DMEMRCHR_NEED_GNU" + print_check_msg "$dep_checked_memrchr" "yes\n" + dep_checked_memrchr=1 + return 1 + done + + print_check_msg "$dep_checked_memrchr" "no\n" + dep_checked_memrchr=1 + return 0 +} dependency_error_doxygen() { print_check_msg "$dep_checked_doxygen" "checking for doxygen... " # dependency doxygen while true do - if test -n "$DOXYGEN" > /dev/null ; then + if test -n "$DOXYGEN" > /dev/null 2>&1 ; then : else break @@ -527,7 +566,7 @@ # dependency no_coverage while true do - if test -z "$FEATURE_COVERAGE" > /dev/null ; then + if test -z "$FEATURE_COVERAGE" > /dev/null 2>&1 ; then : else break @@ -697,6 +736,26 @@ else : fi +if [ -n "$FEATURE_MEMRCHR" ]; then + # check dependency + if dependency_error_memrchr ; then + # "auto" features can fail and are just disabled in this case + if [ "$FEATURE_MEMRCHR" = "auto" ]; then + DISABLE_FEATURE_MEMRCHR=1 + else + DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED memrchr " + ERROR=1 + fi + fi + if [ -n "$DISABLE_FEATURE_MEMRCHR" ]; then + unset FEATURE_MEMRCHR + fi +fi +if [ -n "$FEATURE_MEMRCHR" ]; then + : +else + : +fi if [ -n "$FEATURE_CXX_TESTS" ]; then # check dependency if dependency_error_cxx ; then @@ -843,6 +902,11 @@ else echo " asan: off" fi +if [ -n "$FEATURE_MEMRCHR" ]; then +echo " memrchr: on" +else +echo " memrchr: off" +fi if [ -n "$FEATURE_CXX_TESTS" ]; then echo " cxx-tests: on" else diff -r a6f357c18ac6 -r c5a225d7228c make/configure.vm --- a/make/configure.vm Thu Oct 02 17:58:43 2025 +0200 +++ b/make/configure.vm Thu Oct 02 21:21:45 2025 +0200 @@ -400,7 +400,7 @@ fi #end #foreach( $test in $sub.tests ) - if $test > /dev/null ; then + if $test > /dev/null 2>&1 ; then : else break @@ -502,7 +502,6 @@ #foreach( $flags in $dependency.flags ) #if( $flags.exec ) - $flags.value > /dev/null if tmp_flags=`$flags.value` ; then TEMP_$flags.varName="$TEMP_$flags.varName $tmp_flags" else diff -r a6f357c18ac6 -r c5a225d7228c make/project.xml --- a/make/project.xml Thu Oct 02 17:58:43 2025 +0200 +++ b/make/project.xml Thu Oct 02 21:21:45 2025 +0200 @@ -89,6 +89,16 @@ test -z "$FEATURE_COVERAGE" + + $TOOLCHAIN_CC -o /dev/null make/test_memrchr.c + -DWITH_MEMRCHR + + + + $TOOLCHAIN_CC -o /dev/null -D_GNU_SOURCE make/test_memrchr.c + -DWITH_MEMRCHR -DMEMRCHR_NEED_GNU + + doxygen @@ -106,6 +116,9 @@ address sanitizer asan + + memrchr + cxx the check-cxx makefile target diff -r a6f357c18ac6 -r c5a225d7228c make/test_memrchr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/test_memrchr.c Thu Oct 02 21:21:45 2025 +0200 @@ -0,0 +1,6 @@ +#include + +int main() { + const char *r = memrchr("tester", 'e', 6); + return !(r != NULL); +} diff -r a6f357c18ac6 -r c5a225d7228c src/string.c --- a/src/string.c Thu Oct 02 17:58:43 2025 +0200 +++ b/src/string.c Thu Oct 02 21:21:45 2025 +0200 @@ -25,14 +25,13 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#ifdef MEMRCHR_NEED_GNU #define _GNU_SOURCE -#include -#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >=2 -#define FEATURE_MEMRCHR_AVAILABLE #endif #include "cx/string.h" +#include #include #include #include @@ -239,7 +238,7 @@ cxstring string, int chr ) { -#ifdef FEATURE_MEMRCHR_AVAILABLE +#ifdef WITH_MEMRCHR char *ret = memrchr(string.ptr, 0xFF & chr, string.length); if (ret == NULL) return (cxstring) {NULL, 0}; return (cxstring) {ret, string.length - (ret - string.ptr)}; @@ -248,7 +247,6 @@ size_t i = string.length; while (i > 0) { i--; - // TODO: improve by comparing multiple bytes at once if (string.ptr[i] == chr) { return cx_strsubs(string, i); }