# HG changeset patch # User Mike Becker # Date 1662209767 -7200 # Node ID c067394737cac4a3c0cd66e860271dccb9872e1c # Parent aac47db8da0b98dc076eeb91e91f168dcc1e5e42 implement more string functions diff -r aac47db8da0b -r c067394737ca src/cx/string.h --- a/src/cx/string.h Wed Aug 31 23:12:05 2022 +0200 +++ b/src/cx/string.h Sat Sep 03 14:56:07 2022 +0200 @@ -658,7 +658,7 @@ * \c false otherwise */ __attribute__((__warn_unused_result__)) -int cx_strsuffix( +bool cx_strsuffix( cxstring string, cxstring suffix ); @@ -672,7 +672,7 @@ * \c false otherwise */ __attribute__((__warn_unused_result__)) -int cx_strcaseprefix( +bool cx_strcaseprefix( cxstring string, cxstring prefix ); @@ -686,7 +686,7 @@ * \c false otherwise */ __attribute__((__warn_unused_result__)) -int cx_strcasesuffix( +bool cx_strcasesuffix( cxstring string, cxstring suffix ); diff -r aac47db8da0b -r c067394737ca src/string.c --- a/src/string.c Wed Aug 31 23:12:05 2022 +0200 +++ b/src/string.c Sat Sep 03 14:56:07 2022 +0200 @@ -32,6 +32,13 @@ #include #include #include +#include + +#ifndef _WIN32 + +#include /* for strncasecmp() */ + +#endif /* _WIN32 */ cxmutstr cx_mutstr(char *cstring) { return (cxmutstr) {cstring, strlen(cstring)}; @@ -336,3 +343,90 @@ return cx_strsplit_a(allocator, cx_strcast(string), delim, limit, (cxstring **) output); } + +int cx_strcmp(cxstring s1, cxstring s2) { + if (s1.length == s2.length) { + return memcmp(s1.ptr, s2.ptr, s1.length); + } else if (s1.length > s2.length) { + return 1; + } else { + return -1; + } +} + +int cx_strcasecmp(cxstring s1, cxstring s2) { + if (s1.length == s2.length) { +#ifdef _WIN32 + return _strnicmp(s1.ptr, s2.ptr, s1.length); +#else + return strncasecmp(s1.ptr, s2.ptr, s1.length); +#endif + } else if (s1.length > s2.length) { + return 1; + } else { + return -1; + } +} + +cxmutstr cx_strdup_a(CxAllocator *allocator, cxstring string) { + cxmutstr result = { + cxMalloc(allocator, string.length + 1), + string.length + }; + if (result.ptr == NULL) { + result.length = 0; + return result; + } + memcpy(result.ptr, string.ptr, string.length); + result.ptr[string.length] = '\0'; + return result; +} + +cxstring cx_strtrim(cxstring string) { + cxstring result = string; + // TODO: optimize by comparing multiple bytes at once + while (result.length > 0 && isspace(*result.ptr)) { + result.ptr++; + result.length--; + } + while (result.length > 0 && isspace(result.ptr[result.length - 1])) { + result.length--; + } + return result; +} + +cxmutstr cx_strtrim_m(cxmutstr string) { + cxstring result = cx_strtrim(cx_strcast(string)); + return (cxmutstr) {(char *) result.ptr, result.length}; +} + +bool cx_strprefix(cxstring string, cxstring prefix) { + if (string.length < prefix.length) return false; + return memcmp(string.ptr, prefix.ptr, prefix.length) == 0; +} + +bool cx_strsuffix(cxstring string, cxstring suffix) { + if (string.length < suffix.length) return false; + return memcmp(string.ptr + string.length - suffix.length, + suffix.ptr, suffix.length) == 0; +} + +bool cx_casestrprefix(cxstring string, cxstring prefix) { + if (string.length < prefix.length) return false; +#ifdef _WIN32 + return _strnicmp(string.ptr, prefix.ptr, prefix.length) == 0; +#else + return strncasecmp(string.ptr, prefix.ptr, prefix.length) == 0; +#endif +} + +bool cx_casestrsuffix(cxstring string, cxstring suffix) { + if (string.length < suffix.length) return false; +#ifdef _WIN32 + return _strnicmp(string.ptr+string.length-suffix.length, + suffix.ptr, suffix.length) == 0; +#else + return strncasecmp(string.ptr + string.length - suffix.length, + suffix.ptr, suffix.length) == 0; +#endif +}