From ae2709a72b748e1656b7067951e0532dfe45ae2d Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 10 Oct 2015 17:15:49 +0200 Subject: add strstarts strends strcasestarts strcaseends wcsstarts wcsends wcscasestarts wcscaseends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- TODO | 3 -- include/string.h | 56 +++++++++++++++++++++++++++++++++++ include/wchar.h | 56 +++++++++++++++++++++++++++++++++++ src/string/strstr.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/wchar/wcsstr.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 4f893ff..c376ec1 100644 --- a/TODO +++ b/TODO @@ -16,6 +16,3 @@ input/output overview (15 p429) debugging support (16 p435) input/output on streams (17 p439) -add strstarts, strends, wcsstarts, wcsends as - faster specialised alternatives to strstr. - diff --git a/include/string.h b/include/string.h index b851a76..08777be 100644 --- a/include/string.h +++ b/include/string.h @@ -969,6 +969,62 @@ char* rawstrcasestr(const char*, const char*) */ void* memcasemem(const void*, size_t, const void*, size_t) __GCC_ONLY(__attribute__((warn_unused_result, pure))); + +/** + * Check whether a string starts with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +char* strstarts(const char*, const char*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); + +/** + * Check whether a string ends with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +char* strends(const char*, const char*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); + +/** + * Check whether a string starts with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +char* strcasestarts(const char*, const char*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); + +/** + * Check whether a string ends with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +char* strcaseends(const char*, const char*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #endif #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) diff --git a/include/wchar.h b/include/wchar.h index 9b57a7e..e9d2daa 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -942,6 +942,62 @@ wchar_t* rawwcscasestr(const wchar_t*, const wchar_t*) */ wchar_t* wmemcasemem(const wchar_t*, size_t, const wchar_t*, size_t) __GCC_ONLY(__attribute__((warn_unused_result, pure))); + +/** + * Check whether a string starts with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +wchar_t* wcsstarts(const wchar_t*, const wchar_t*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); + +/** + * Check whether a string ends with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +wchar_t* wcsends(const wchar_t*, const wchar_t*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); + +/** + * Check whether a string starts with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +wchar_t* wcscasestarts(const wchar_t*, const wchar_t*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); + +/** + * Check whether a string ends with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +wchar_t* wcscaseends(const wchar_t*, const wchar_t*) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #endif #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) diff --git a/src/string/strstr.c b/src/string/strstr.c index d63628a..34b3120 100644 --- a/src/string/strstr.c +++ b/src/string/strstr.c @@ -182,3 +182,87 @@ void* memcasemem(const void* __haystack, size_t haystack_length, #undef CASE } + +/** + * Check whether a string starts with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +char* strstarts(const char* string, const char* desired) +{ + size_t n = strlen(string); + size_t m = strlen(desired); + if (n < m) + return NULL; + return memcmp(string, desired, m) ? NULL : string; +} + + +/** + * Check whether a string ends with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +char* strends(const char* string, const char* desired) +{ + size_t n = strlen(string); + size_t m = strlen(desired); + if (n < m) + return NULL; + return memcmp(string + (n - m), desired, m) ? NULL : (string + n); +} + + +/** + * Check whether a string starts with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +char* strcasestarts(const char* string, const char* desired) +{ + size_t n = strlen(string); + size_t m = strlen(desired); + if (n < m) + return NULL; + return memcasecmp(string, desired, m) ? NULL : string; +} + + +/** + * Check whether a string ends with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +char* strcaseends(const char* string, const char* desired) +{ + size_t n = strlen(string); + size_t m = strlen(desired); + if (n < m) + return NULL; + return memcasecmp(string + (n - m), desired, m) ? NULL : (string + n); +} + diff --git a/src/wchar/wcsstr.c b/src/wchar/wcsstr.c index f54ff6e..bc2bbec 100644 --- a/src/wchar/wcsstr.c +++ b/src/wchar/wcsstr.c @@ -192,3 +192,87 @@ wchar_t* wmemcasemem(const wchar_t* haystack, size_t haystack_length, #undef CASE } + +/** + * Check whether a string starts with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +wchar_t* wcsstarts(const wchar_t* string, const wchar_t* desired) +{ + size_t n = wcslen(string); + size_t m = wcslen(desired); + if (n < m) + return NULL; + return wmemcmp(string, desired, m) ? NULL : string; +} + + +/** + * Check whether a string ends with a specific string. + * This check is case sensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +wchar_t* wcsends(const wchar_t* string, const wchar_t* desired) +{ + size_t n = wcslen(string); + size_t m = wcslen(desired); + if (n < m) + return NULL; + return wmemcmp(string + (n - m), desired, m) ? NULL : (string + n); +} + + +/** + * Check whether a string starts with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired beginning of the string. + * @return `string` if `string` begins with + * `desired`, `NULL` otherwise. + */ +wchar_t* wcscasestarts(const wchar_t* string, const wchar_t* desired) +{ + size_t n = wcslen(string); + size_t m = wcslen(desired); + if (n < m) + return NULL; + return wmemcasecmp(string, desired, m) ? NULL : string; +} + + +/** + * Check whether a string ends with a specific string. + * This check is case insensitive. + * + * This is a slibc extension. + * + * @param string The string to inspect. + * @param desired The desired ending of the string. + * @return The `string`, where `desired` beings if + * `string` ends with `desired`, `NULL` otherwise. + */ +wchar_t* wcscaseends(const wchar_t* string, const wchar_t* desired) +{ + size_t n = wcslen(string); + size_t m = wcslen(desired); + if (n < m) + return NULL; + return wmemcasecmp(string + (n - m), desired, m) ? NULL : (string + n); +} + -- cgit v1.2.3-70-g09d2