diff -r 62f1a55535e7 -r 0b33b9396851 ucx/ucx/string.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/string.h Mon Feb 04 17:49:50 2019 +0100 @@ -0,0 +1,934 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/** + * Bounded string implementation. + * + * The UCX strings (sstr_t) provide an alternative to C strings. + * The main difference to C strings is, that sstr_t does not + * need to be NULL-terminated. Instead the length is stored + * within the structure. + * + * When using sstr_t, developers must be full aware of what type + * of string (NULL-terminated) or not) they are using, when + * accessing the char* ptr directly. + * + * The UCX string module provides some common string functions, known from + * standard libc, working with sstr_t. + * + * @file string.h + * @author Mike Becker + * @author Olaf Wintermann + */ + +#ifndef UCX_STRING_H +#define UCX_STRING_H + +#include "ucx.h" +#include "allocator.h" +#include + +/* + * Use this macro to disable the shortcuts if you experience macro collision. + */ +#ifndef UCX_NO_SSTR_SHORTCUTS +/** + * Shortcut for a sstr_t struct + * or scstr_t struct literal. + */ +#define ST(s) { s, sizeof(s)-1 } + +/** Shortcut for the conversion of a C string to a sstr_t. */ +#define S(s) sstrn(s, sizeof(s)-1) + +/** Shortcut for the conversion of a C string to a scstr_t. */ +#define SC(s) scstrn(s, sizeof(s)-1) +#endif /* UCX_NO_SSTR_SHORTCUTS */ + +/* + * Use this macro to disable the format macros. + */ +#ifndef UCX_NO_SSTR_FORMAT_MACROS +/** Expands a sstr_t or scstr_t to printf arguments. */ +#define SFMT(s) (int) (s).length, (s).ptr + +/** Format specifier for a sstr_t or scstr_t. */ +#define PRIsstr ".*s" +#endif /* UCX_NO_SSTR_FORMAT_MACROS */ + +#ifdef __cplusplus +extern "C" { +#endif +/** + * The UCX string structure. + */ +typedef struct { + /** A pointer to the string + * (not necessarily NULL-terminated) */ + char *ptr; + /** The length of the string */ + size_t length; +} sstr_t; + +/** + * The UCX string structure for immutable (constant) strings. + */ +typedef struct { + /** A constant pointer to the immutable string + * (not necessarily NULL-terminated) */ + const char *ptr; + /** The length of the string */ + size_t length; +} scstr_t; + +#ifdef __cplusplus +} +#endif + + +#ifdef __cplusplus +/** + * One of two type adjustment functions that return a scstr_t. + * + * Used internally to convert a UCX string to an immutable UCX string. + * + * Do not use this function manually. + * + * @param str some sstr_t + * @return an immutable (scstr_t) version of the provided string. + */ +inline scstr_t s2scstr(sstr_t s) { + scstr_t c; + c.ptr = s.ptr; + c.length = s.length; + return c; +} + +/** + * One of two type adjustment functions that return a scstr_t. + * + * Used internally to convert a UCX string to an immutable UCX string. + * This variant is used, when the string is already immutable and no operation + * needs to be performed. + * + * Do not use this function manually. + * + * @param str some scstr_t + * @return the argument itself + */ +inline scstr_t s2scstr(scstr_t str) { + return str; +} + +/** + * Converts a UCX string to an immutable UCX string (scstr_t). + * @param str some UCX string + * @return the an immutable version of the provided string + */ +#define SCSTR(s) s2scstr(s) +#else + +/** + * One of two type adjustment functions that return a scstr_t. + * + * Used internally to convert a UCX string to an immutable UCX string. + * This variant is used, when the string is already immutable and no operation + * needs to be performed. + * + * Do not use this function manually. + * + * @param str some scstr_t + * @return the argument itself + */ +scstr_t ucx_sc2sc(scstr_t str); + +/** + * One of two type adjustment functions that return a scstr_t. + * + * Used internally to convert a UCX string to an immutable UCX string. + * + * Do not use this function manually. + * + * @param str some sstr_t + * @return an immutable (scstr_t) version of the provided string. + */ +scstr_t ucx_ss2sc(sstr_t str); + +#if __STDC_VERSION__ >= 201112L +/** + * Converts a UCX string to an immutable UCX string (scstr_t). + * @param str some UCX string + * @return the an immutable version of the provided string + */ +#define SCSTR(str) _Generic(str, sstr_t: ucx_ss2sc, scstr_t: ucx_sc2sc)(str) + +#elif defined(__GNUC__) || defined(__clang__) + +/** + * Converts a UCX string to an immutable UCX string (scstr_t). + * @param str some UCX string + * @return the an immutable version of the provided string + */ +#define SCSTR(str) __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(str), sstr_t), \ + ucx_ss2sc, \ + ucx_sc2sc)(str) + +#elif defined(__sun) + +/** + * Converts a UCX string to an immutable UCX string (scstr_t). + * @param str some UCX string + * @return the an immutable version of the provided string + */ +#define SCSTR(str) ({typeof(str) ucx_tmp_var_str = str; \ + scstr_t ucx_tmp_var_c; \ + ucx_tmp_var_c.ptr = ucx_tmp_var_str.ptr;\ + ucx_tmp_var_c.length = ucx_tmp_var_str.length;\ + ucx_tmp_var_c; }) +#else /* no generics and no builtins */ + +/** + * Converts a UCX string to an immutable UCX string (scstr_t). + * + * This internal function (ab)uses the C standard an expects one single + * argument which is then implicitly converted to scstr_t without a warning. + * + * Do not use this function manually. + * + * @return the an immutable version of the provided string + */ +scstr_t ucx_ss2c_s(); + +/** + * Converts a UCX string to an immutable UCX string (scstr_t). + * @param str some UCX string + * @return the an immutable version of the provided string + */ +#define SCSTR(str) ucx_ss2c_s(str) +#endif /* C11 feature test */ + +#endif /* C++ */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Creates a new sstr_t based on a C string. + * + * The length is implicitly inferred by using a call to strlen(). + * + * Note: the sstr_t will hold a reference to the C string. If you + * do want a copy, use sstrdup() on the return value of this function. + * + * If you need to wrap a constant string, use scstr(). + * + * @param cstring the C string to wrap + * @return a new sstr_t containing the C string + * + * @see sstrn() + */ +sstr_t sstr(char *cstring); + +/** + * Creates a new sstr_t of the specified length based on a C string. + * + * Note: the sstr_t will hold a reference to the C string. If you + * do want a copy, use sstrdup() on the return value of this function. + * + * If you need to wrap a constant string, use scstrn(). + * + * @param cstring the C string to wrap + * @param length the length of the string + * @return a new sstr_t containing the C string + * + * @see sstr() + * @see S() + */ +sstr_t sstrn(char *cstring, size_t length); + +/** + * Creates a new scstr_t based on a constant C string. + * + * The length is implicitly inferred by using a call to strlen(). + * + * Note: the scstr_t will hold a reference to the C string. If you + * do want a copy, use scstrdup() on the return value of this function. + * + * @param cstring the C string to wrap + * @return a new scstr_t containing the C string + * + * @see scstrn() + */ +scstr_t scstr(const char *cstring); + + +/** + * Creates a new scstr_t of the specified length based on a constant C string. + * + * Note: the scstr_t will hold a reference to the C string. If you + * do want a copy, use scstrdup() on the return value of this function. + * + * + * @param cstring the C string to wrap + * @param length the length of the string + * @return a new scstr_t containing the C string + * + * @see scstr() + */ +scstr_t scstrn(const char *cstring, size_t length); + +/** + * Returns the cumulated length of all specified strings. + * + * Attention: if the count argument does not match the count of the + * specified strings, the behavior is undefined. + * + * @param count the total number of specified strings (so at least 1) + * @param ... all strings + * @return the cumulated length of all strings + */ +size_t scstrnlen(size_t count, ...); + +/** + * Alias for scstrnlen() which automatically converts the arguments. + * + * @param count the total number of specified strings (so at least 1) + * @param ... all strings + * @return the cumulated length of all strings + */ +#define sstrnlen(count, ...) scstrnlen(count, __VA_ARGS__) + +/** + * Concatenates two or more strings. + * + * The resulting string will be allocated by standard malloc(). + * So developers MUST pass the sstr_t.ptr to free(). + * + * The sstr_t.ptr of the return value will always be NULL- + * terminated. + * + * @param count the total number of strings to concatenate + * @param s1 first string + * @param ... all remaining strings + * @return the concatenated string + */ +sstr_t scstrcat(size_t count, scstr_t s1, ...); + +/** + * Alias for scstrcat() which automatically converts the arguments. + * + * @param count the total number of strings to concatenate + * @param s1 first string + * @param ... all remaining strings + * @return the concatenated string + */ +#define sstrcat(count, s1, ...) scstrcat(count, SCSTR(s1), __VA_ARGS__) + +/** + * Concatenates two or more strings using a UcxAllocator. + * + * See scstrcat() for details. + * + * @param a the allocator to use + * @param count the total number of strings to concatenate + * @param s1 first string + * @param ... all remaining strings + * @return the concatenated string + */ +sstr_t scstrcat_a(UcxAllocator *a, size_t count, scstr_t s1, ...); + +/** + * Alias for scstrcat_a() which automatically converts the arguments. + * + * See sstrcat() for details. + * + * @param a the allocator to use + * @param count the total number of strings to concatenate + * @param s1 first string + * @param ... all remaining strings + * @return the concatenated string + */ +#define sstrcat_a(a, count, s1, ...) \ + scstrcat_a(a, count, SCSTR(s1), __VA_ARGS__) + +/** + * Returns a substring starting at the specified location. + * + * Attention: the new string references the same memory area as the + * input string and will NOT be NULL-terminated. + * Use sstrdup() to get a copy. + * + * @param string input string + * @param start start location of the substring + * @return a substring of string starting at start + * + * @see sstrsubsl() + * @see sstrchr() + */ +sstr_t sstrsubs(sstr_t string, size_t start); + +/** + * Returns a substring with a maximum length starting at the specified location. + * + * Attention: the new string references the same memory area as the + * input string and will NOT be NULL-terminated. + * Use sstrdup() to get a copy. + * + * @param string input string + * @param start start location of the substring + * @param length the maximum length of the substring + * @return a substring of string starting at start + * with a maximum length of length + * + * @see sstrsubs() + * @see sstrchr() + */ +sstr_t sstrsubsl(sstr_t string, size_t start, size_t length); + +/** + * Returns a substring of an immutable string starting at the specified + * location. + * + * Attention: the new string references the same memory area as the + * input string and will NOT be NULL-terminated. + * Use scstrdup() to get a copy. + * + * @param string input string + * @param start start location of the substring + * @return a substring of string starting at start + * + * @see scstrsubsl() + * @see scstrchr() + */ +scstr_t scstrsubs(scstr_t string, size_t start); + +/** + * Returns a substring of an immutable string with a maximum length starting + * at the specified location. + * + * Attention: the new string references the same memory area as the + * input string and will NOT be NULL-terminated. + * Use scstrdup() to get a copy. + * + * @param string input string + * @param start start location of the substring + * @param length the maximum length of the substring + * @return a substring of string starting at start + * with a maximum length of length + * + * @see scstrsubs() + * @see scstrchr() + */ +scstr_t scstrsubsl(scstr_t string, size_t start, size_t length); + +/** + * Returns a substring starting at the location of the first occurrence of the + * specified character. + * + * If the string does not contain the character, an empty string is returned. + * + * @param string the string where to locate the character + * @param chr the character to locate + * @return a substring starting at the first location of chr + * + * @see sstrsubs() + */ +sstr_t sstrchr(sstr_t string, int chr); + +/** + * Returns a substring starting at the location of the last occurrence of the + * specified character. + * + * If the string does not contain the character, an empty string is returned. + * + * @param string the string where to locate the character + * @param chr the character to locate + * @return a substring starting at the last location of chr + * + * @see sstrsubs() + */ +sstr_t sstrrchr(sstr_t string, int chr); + +/** + * Returns an immutable substring starting at the location of the first + * occurrence of the specified character. + * + * If the string does not contain the character, an empty string is returned. + * + * @param string the string where to locate the character + * @param chr the character to locate + * @return a substring starting at the first location of chr + * + * @see scstrsubs() + */ +scstr_t scstrchr(scstr_t string, int chr); + +/** + * Returns an immutable substring starting at the location of the last + * occurrence of the specified character. + * + * If the string does not contain the character, an empty string is returned. + * + * @param string the string where to locate the character + * @param chr the character to locate + * @return a substring starting at the last location of chr + * + * @see scstrsubs() + */ +scstr_t scstrrchr(scstr_t string, int chr); + +/** + * Returns a substring starting at the location of the first occurrence of the + * specified string. + * + * If the string does not contain the other string, an empty string is returned. + * + * If match is an empty string, the complete string is + * returned. + * + * @param string the string to be scanned + * @param match string containing the sequence of characters to match + * @return a substring starting at the first occurrence of + * match, or an empty string, if the sequence is not + * present in string + */ +sstr_t scstrsstr(sstr_t string, scstr_t match); + +/** + * Alias for scstrsstr() which automatically converts the match string. + * + * @param string the string to be scanned + * @param match string containing the sequence of characters to match + * @return a substring starting at the first occurrence of + * match, or an empty string, if the sequence is not + * present in string + */ +#define sstrstr(string, match) scstrsstr(string, SCSTR(match)) + +/** + * Returns an immutable substring starting at the location of the + * first occurrence of the specified immutable string. + * + * If the string does not contain the other string, an empty string is returned. + * + * If match is an empty string, the complete string is + * returned. + * + * @param string the string to be scanned + * @param match string containing the sequence of characters to match + * @return a substring starting at the first occurrence of + * match, or an empty string, if the sequence is not + * present in string + */ +scstr_t scstrscstr(scstr_t string, scstr_t match); + +/** + * Alias for scstrscstr() which automatically converts the match string. + * + * @param string the string to be scanned + * @param match string containing the sequence of characters to match + * @return a substring starting at the first occurrence of + * match, or an empty string, if the sequence is not + * present in string + */ +#define sstrscstr(string, match) scstrscstr(string, SCSTR(match)) + +/** + * Splits a string into parts by using a delimiter string. + * + * This function will return NULL, if one of the following happens: + * + * + * The integer referenced by count is used as input and determines + * the maximum size of the resulting array, i.e. the maximum count of splits to + * perform + 1. + * + * The integer referenced by count is also used as output and is + * set to + * + * + * If the string starts with the delimiter, the first item of the resulting + * array will be an empty string. + * + * If the string ends with the delimiter and the maximum list size is not + * exceeded, the last array item will be an empty string. + * In case the list size would be exceeded, the last array item will be the + * remaining string after the last split, including the terminating + * delimiter. + * + * Attention: The array pointer AND all sstr_t.ptr of the array + * items must be manually passed to free(). Use sstrsplit_a() with + * an allocator to managed memory, to avoid this. + * + * @param string the string to split + * @param delim the delimiter string + * @param count IN: the maximum size of the resulting array (0 = no limit), + * OUT: the actual size of the array + * @return a sstr_t array containing the split strings or + * NULL on error + * + * @see scstrsplit_a() + */ +sstr_t* scstrsplit(scstr_t string, scstr_t delim, ssize_t *count); + +/** + * Alias for scstrsplit() which automatically converts the arguments. + * + * @param string the string to split + * @param delim the delimiter string + * @param count IN: the maximum size of the resulting array (0 = no limit), + * OUT: the actual size of the array + * @return a sstr_t array containing the split strings or + * NULL on error + * + * @see sstrsplit_a() + */ +#define sstrsplit(string, delim, count) \ + scstrsplit(SCSTR(string), SCSTR(delim), count) + +/** + * Performing scstrsplit() using a UcxAllocator. + * + * Read the description of scstrsplit() for details. + * + * The memory for the sstr_t.ptr pointers of the array items and the memory for + * the sstr_t array itself are allocated by using the UcxAllocator.malloc() + * function. + * + * Note: the allocator is not used for memory that is freed within the + * same call of this function (locally scoped variables). + * + * @param allocator the UcxAllocator used for allocating memory + * @param string the string to split + * @param delim the delimiter string + * @param count IN: the maximum size of the resulting array (0 = no limit), + * OUT: the actual size of the array + * @return a sstr_t array containing the split strings or + * NULL on error + * + * @see scstrsplit() + */ +sstr_t* scstrsplit_a(UcxAllocator *allocator, scstr_t string, scstr_t delim, + ssize_t *count); + +/** + * Alias for scstrsplit_a() which automatically converts the arguments. + * + * @param allocator the UcxAllocator used for allocating memory + * @param string the string to split + * @param delim the delimiter string + * @param count IN: the maximum size of the resulting array (0 = no limit), + * OUT: the actual size of the array + * @return a sstr_t array containing the split strings or + * NULL on error + * + * @see sstrsplit() + */ +#define sstrsplit_a(allocator, string, delim, count) \ + scstrsplit_a(allocator, SCSTR(string), SCSTR(delim), count) + +/** + * Compares two UCX strings with standard memcmp(). + * + * At first it compares the scstr_t.length attribute of the two strings. The + * memcmp() function is called, if and only if the lengths match. + * + * @param s1 the first string + * @param s2 the second string + * @return -1, if the length of s1 is less than the length of s2 or 1, if the + * length of s1 is greater than the length of s2 or the result of + * memcmp() otherwise (i.e. 0 if the strings match) + */ +int scstrcmp(scstr_t s1, scstr_t s2); + +/** + * Alias for scstrcmp() which automatically converts its arguments. + * + * @param s1 the first string + * @param s2 the second string + * @return -1, if the length of s1 is less than the length of s2 or 1, if the + * length of s1 is greater than the length of s2 or the result of + * memcmp() otherwise (i.e. 0 if the strings match) + */ +#define sstrcmp(s1, s2) scstrcmp(SCSTR(s1), SCSTR(s2)) + +/** + * Compares two UCX strings ignoring the case. + * + * At first it compares the scstr_t.length attribute of the two strings. If and + * only if the lengths match, both strings are compared char by char ignoring + * the case. + * + * @param s1 the first string + * @param s2 the second string + * @return -1, if the length of s1 is less than the length of s2 or 1, if the + * length of s1 is greater than the length of s2 or the result of the platform + * specific string comparison function ignoring the case. + */ +int scstrcasecmp(scstr_t s1, scstr_t s2); + +/** + * Alias for scstrcasecmp() which automatically converts the arguments. + * + * @param s1 the first string + * @param s2 the second string + * @return -1, if the length of s1 is less than the length of s2 or 1, if the + * length of s1 is greater than the length of s2 or the result of the platform + * specific string comparison function ignoring the case. + */ +#define sstrcasecmp(s1, s2) scstrcasecmp(SCSTR(s1), SCSTR(s2)) + +/** + * Creates a duplicate of the specified string. + * + * The new sstr_t will contain a copy allocated by standard + * malloc(). So developers MUST pass the sstr_t.ptr to + * free(). + * + * The sstr_t.ptr of the return value will always be NULL- + * terminated and mutable, regardless of the argument. + * + * @param string the string to duplicate + * @return a duplicate of the string + * @see scstrdup_a() + */ +sstr_t scstrdup(scstr_t string); + +/** + * Alias for scstrdup() which automatically converts the argument. + * + * @param string the string to duplicate + * @return a duplicate of the string + * @see sstrdup_a() + */ +#define sstrdup(string) scstrdup(SCSTR(string)) + +/** + * Creates a duplicate of the specified string using a UcxAllocator. + * + * The new sstr_t will contain a copy allocated by the allocators + * UcxAllocator.malloc() function. So it is implementation depended, whether the + * returned sstr_t.ptr pointer must be passed to the allocators + * UcxAllocator.free() function manually. + * + * The sstr_t.ptr of the return value will always be NULL- + * terminated and mutable, regardless of the argument. + * + * @param allocator a valid instance of a UcxAllocator + * @param string the string to duplicate + * @return a duplicate of the string + * @see scstrdup() + */ +sstr_t scstrdup_a(UcxAllocator *allocator, scstr_t string); + +/** + * Alias for scstrdup_a() which automatically converts the argument. + * + * @param allocator a valid instance of a UcxAllocator + * @param string the string to duplicate + * @return a duplicate of the string + * @see scstrdup() + */ +#define sstrdup_a(allocator, string) scstrdup_a(allocator, SCSTR(string)) + + +/** + * Omits leading and trailing spaces. + * + * This function returns a new sstr_t containing a trimmed version of the + * specified string. + * + * Note: the new sstr_t references the same memory, thus you + * MUST NOT pass the sstr_t.ptr of the return value to + * free(). It is also highly recommended to avoid assignments like + * mystr = sstrtrim(mystr); as you lose the reference to the + * source string. Assignments of this type are only permitted, if the + * sstr_t.ptr of the source string does not need to be freed or if another + * reference to the source string exists. + * + * @param string the string that shall be trimmed + * @return a new sstr_t containing the trimmed string + */ +sstr_t sstrtrim(sstr_t string); + +/** + * Omits leading and trailing spaces. + * + * This function returns a new scstr_t containing a trimmed version of the + * specified string. + * + * Note: the new scstr_t references the same memory, thus you + * MUST NOT pass the scstr_t.ptr of the return value to + * free(). It is also highly recommended to avoid assignments like + * mystr = scstrtrim(mystr); as you lose the reference to the + * source string. Assignments of this type are only permitted, if the + * scstr_t.ptr of the source string does not need to be freed or if another + * reference to the source string exists. + * + * @param string the string that shall be trimmed + * @return a new scstr_t containing the trimmed string + */ +scstr_t scstrtrim(scstr_t string); + +/** + * Checks, if a string has a specific prefix. + * @param string the string to check + * @param prefix the prefix the string should have + * @return 1, if and only if the string has the specified prefix, 0 otherwise + */ +int scstrprefix(scstr_t string, scstr_t prefix); + +/** + * Alias for scstrprefix() which automatically converts the arguments. + * + * @param string the string to check + * @param prefix the prefix the string should have + * @return 1, if and only if the string has the specified prefix, 0 otherwise + */ +#define sstrprefix(string, prefix) scstrprefix(SCSTR(string), SCSTR(prefix)) + +/** + * Checks, if a string has a specific suffix. + * @param string the string to check + * @param suffix the suffix the string should have + * @return 1, if and only if the string has the specified suffix, 0 otherwise + */ +int scstrsuffix(scstr_t string, scstr_t suffix); + +/** + * Alias for scstrsuffix() which automatically converts the arguments. + * + * @param string the string to check + * @param suffix the suffix the string should have + * @return 1, if and only if the string has the specified suffix, 0 otherwise + */ +#define sstrsuffix(string, suffix) scstrsuffix(SCSTR(string), SCSTR(suffix)) + +/** + * Returns a lower case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of scstrdup() for the implications. + * + * @param string the input string + * @return the resulting lower case string + * @see scstrdup() + */ +sstr_t scstrlower(scstr_t string); + +/** + * Alias for scstrlower() which automatically converts the argument. + * + * @param string the input string + * @return the resulting lower case string + */ +#define sstrlower(string) scstrlower(SCSTR(string)) + +/** + * Returns a lower case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of scstrdup_a() for the implications. + * + * @param allocator the allocator used for duplicating the string + * @param string the input string + * @return the resulting lower case string + * @see scstrdup_a() + */ +sstr_t scstrlower_a(UcxAllocator *allocator, scstr_t string); + + +/** + * Alias for scstrlower_a() which automatically converts the argument. + * + * @param allocator the allocator used for duplicating the string + * @param string the input string + * @return the resulting lower case string + */ +#define sstrlower_a(allocator, string) scstrlower_a(allocator, SCSTR(string)) + +/** + * Returns a upper case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of scstrdup() for the implications. + * + * @param string the input string + * @return the resulting upper case string + * @see scstrdup() + */ +sstr_t scstrupper(scstr_t string); + +/** + * Alias for scstrupper() which automatically converts the argument. + * + * @param string the input string + * @return the resulting upper case string + */ +#define sstrupper(string) scstrupper(SCSTR(string)) + +/** + * Returns a upper case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of scstrdup_a() for the implications. + * + * @param allocator the allocator used for duplicating the string + * @param string the input string + * @return the resulting upper case string + * @see scstrdup_a() + */ +sstr_t scstrupper_a(UcxAllocator *allocator, scstr_t string); + +/** + * Alias for scstrupper_a() which automatically converts the argument. + * + * @param allocator the allocator used for duplicating the string + * @param string the input string + * @return the resulting upper case string + */ +#define sstrupper_a(allocator, string) scstrupper_a(allocator, string) + +#ifdef __cplusplus +} +#endif + +#endif /* UCX_STRING_H */