Thu, 02 Oct 2025 17:58:43 +0200
use memrchr() to implement cx_strrchr() when it is available
src/string.c | file | annotate | diff | comparison | revisions | |
tests/test_string.c | file | annotate | diff | comparison | revisions |
--- a/src/string.c Wed Oct 01 22:45:48 2025 +0200 +++ b/src/string.c Thu Oct 02 17:58:43 2025 +0200 @@ -25,9 +25,14 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#define _GNU_SOURCE +#include <string.h> +#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >=2 +#define FEATURE_MEMRCHR_AVAILABLE +#endif + #include "cx/string.h" -#include <string.h> #include <stdarg.h> #include <assert.h> #include <errno.h> @@ -231,9 +236,14 @@ } cxstring cx_strrchr( - cxstring string, - int chr + cxstring string, + int chr ) { +#ifdef FEATURE_MEMRCHR_AVAILABLE + char *ret = memrchr(string.ptr, 0xFF & chr, string.length); + if (ret == NULL) return (cxstring) {NULL, 0}; + return (cxstring) {ret, string.length - (ret - string.ptr)}; +#else chr = 0xFF & chr; size_t i = string.length; while (i > 0) { @@ -244,6 +254,7 @@ } } return (cxstring) {NULL, 0}; +#endif } cxmutstr cx_strrchr_m(
--- a/tests/test_string.c Wed Oct 01 22:45:48 2025 +0200 +++ b/tests/test_string.c Thu Oct 02 17:58:43 2025 +0200 @@ -200,7 +200,7 @@ } CX_TEST(test_strrchr) { - cxstring str = CX_STR("I will find you - and I will kill you"); + cxstring str = CX_STR("X will find you - and I will kill you"); CX_TEST_DO { cxstring notfound = cx_strrchr(str, 'x'); @@ -210,6 +210,13 @@ CX_TEST_ASSERT(result.length == 13); CX_TEST_ASSERT(0 == strcmp(result.ptr, "will kill you")); + result = cx_strrchr(str, 'u'); + CX_TEST_ASSERT(result.length == 1); + CX_TEST_ASSERT(0 == strcmp(result.ptr, "u")); + + result = cx_strrchr(str, 'X'); + CX_TEST_ASSERT(0 == cx_strcmp(result, str)); + // just for coverage, call the _m variant cxmutstr m = cx_strrchr_m(cx_mutstrn(NULL, 0), 'a'); CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), cx_str("")));