Mon, 29 Aug 2022 20:54:42 +0200
first proposal for the string header
src/CMakeLists.txt | file | annotate | diff | comparison | revisions | |
src/cx/string.h | file | annotate | diff | comparison | revisions | |
src/string.c | file | annotate | diff | comparison | revisions |
1.1 --- a/src/CMakeLists.txt Fri Aug 12 16:56:41 2022 +0200 1.2 +++ b/src/CMakeLists.txt Mon Aug 29 20:54:42 2022 +0200 1.3 @@ -1,6 +1,7 @@ 1.4 set(sources 1.5 utils.c 1.6 allocator.c 1.7 + string.c 1.8 list.c 1.9 linked_list.c 1.10 tree.c 1.11 @@ -12,6 +13,7 @@ 1.12 set(headers 1.13 cx/common.h 1.14 cx/utils.h 1.15 + cx/string.h 1.16 cx/allocator.h 1.17 cx/iterator.h 1.18 cx/list.h
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/cx/string.h Mon Aug 29 20:54:42 2022 +0200 2.3 @@ -0,0 +1,771 @@ 2.4 +/* 2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2.6 + * 2.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 2.8 + * 2.9 + * Redistribution and use in source and binary forms, with or without 2.10 + * modification, are permitted provided that the following conditions are met: 2.11 + * 2.12 + * 1. Redistributions of source code must retain the above copyright 2.13 + * notice, this list of conditions and the following disclaimer. 2.14 + * 2.15 + * 2. Redistributions in binary form must reproduce the above copyright 2.16 + * notice, this list of conditions and the following disclaimer in the 2.17 + * documentation and/or other materials provided with the distribution. 2.18 + * 2.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2.29 + * POSSIBILITY OF SUCH DAMAGE. 2.30 + */ 2.31 +/** 2.32 + * \file string.h 2.33 + * \brief Strings that know their length. 2.34 + * \author Mike Becker 2.35 + * \author Olaf Wintermann 2.36 + * \version 3.0 2.37 + * \copyright 2-Clause BSD License 2.38 + */ 2.39 + 2.40 +#ifndef UCX_STRING_H 2.41 +#define UCX_STRING_H 2.42 + 2.43 +#include "common.h" 2.44 +#include "allocator.h" 2.45 + 2.46 +/** 2.47 + * The UCX string structure. 2.48 + */ 2.49 +struct { 2.50 + /** 2.51 + * A pointer to the string. 2.52 + * \note The string is not necessarily \c NULL terminated. 2.53 + * Always use the length. 2.54 + */ 2.55 + char *ptr; 2.56 + /** The length of the string */ 2.57 + size_t length; 2.58 +} cx_mutstr_s; 2.59 + 2.60 +/** 2.61 + * A mutable string. 2.62 + */ 2.63 +typedef struct cx_mutstr_s cxmutstr; 2.64 + 2.65 +/** 2.66 + * The UCX string structure for immutable (constant) strings. 2.67 + */ 2.68 +struct { 2.69 + /** 2.70 + * A pointer to the immutable string. 2.71 + * \note The string is not necessarily \c NULL terminated. 2.72 + * Always use the length. 2.73 + */ 2.74 + char const *ptr; 2.75 + /** The length of the string */ 2.76 + size_t length; 2.77 +} cx_string_s; 2.78 + 2.79 +/** 2.80 + * An immutable string. 2.81 + */ 2.82 +typedef struct cx_string_s cxstring; 2.83 + 2.84 +#ifdef __cplusplus 2.85 +extern "C" { 2.86 +#endif 2.87 + 2.88 + 2.89 +/** 2.90 + * Wraps a mutable string that must be zero-terminated. 2.91 + * 2.92 + * The length is implicitly inferred by using a call to \c strlen(). 2.93 + * As a special case, a \c NULL argument is treated like an empty string. 2.94 + * 2.95 + * \note the wrapped string will share the specified pointer to the string. 2.96 + * If you do want a copy, use cx_strdup() on the return value of this function. 2.97 + * 2.98 + * If you need to wrap a constant string, use cx_str(). 2.99 + * 2.100 + * @param cstring the string to wrap, must be zero-terminated (or \c NULL) 2.101 + * @return the wrapped string 2.102 + * 2.103 + * @see cx_mutstrn() 2.104 + */ 2.105 +__attribute__((__warn_unused_result__)) 2.106 +cxmutstr cx_mutstr(char *cstring); 2.107 + 2.108 +/** 2.109 + * Wraps a string that does not need to be zero-terminated. 2.110 + * 2.111 + * The argument may be \c NULL if the length is zero. 2.112 + * 2.113 + * \note the wrapped string will share the specified pointer to the string. 2.114 + * If you do want a copy, use cx_strdup() on the return value of this function. 2.115 + * 2.116 + * If you need to wrap a constant string, use cx_strn(). 2.117 + * 2.118 + * @param cstring the string to wrap (or \c NULL, if the length is zero) 2.119 + * @param length the length of the string 2.120 + * @return the wrapped string 2.121 + * 2.122 + * @see cx_mutstr() 2.123 + */ 2.124 +__attribute__((__warn_unused_result__)) 2.125 +cxmutstr cx_mutstrn( 2.126 + char *cstring, 2.127 + size_t length 2.128 +); 2.129 + 2.130 +/** 2.131 + * Wraps a string that must be zero-terminated. 2.132 + * 2.133 + * The length is implicitly inferred by using a call to \c strlen(). 2.134 + * As a special case, a \c NULL argument is treated like an empty string. 2.135 + * 2.136 + * \note the wrapped string will share the specified pointer to the string. 2.137 + * If you do want a copy, use cx_strdup() on the return value of this function. 2.138 + * 2.139 + * If you need to wrap a non-constant string, use cx_mutstr(). 2.140 + * 2.141 + * @param cstring the string to wrap, must be zero-terminated (or \c NULL) 2.142 + * @return the wrapped string 2.143 + * 2.144 + * @see cx_strn() 2.145 + */ 2.146 +__attribute__((__warn_unused_result__)) 2.147 +cxstring cx_str(char const *cstring); 2.148 + 2.149 + 2.150 +/** 2.151 + * Wraps a string that does not need to be zero-terminated. 2.152 + * 2.153 + * The argument may be \c NULL if the length is zero. 2.154 + * 2.155 + * \note the wrapped string will share the specified pointer to the string. 2.156 + * If you do want a copy, use cx_strdup() on the return value of this function. 2.157 + * 2.158 + * If you need to wrap a non-constant string, use cx_mutstrn(). 2.159 + * 2.160 + * @param cstring the string to wrap (or \c NULL, if the length is zero) 2.161 + * @param length the length of the string 2.162 + * @return the wrapped string 2.163 + * 2.164 + * @see cx_str() 2.165 + */ 2.166 +__attribute__((__warn_unused_result__)) 2.167 +cxstring cx_strn( 2.168 + char const *cstring, 2.169 + size_t length 2.170 +); 2.171 + 2.172 +/** 2.173 +* Casts a mutable string to an immutable string. 2.174 +* 2.175 +* \note This is not seriously a cast. Instead you get a copy 2.176 +* of the struct with the desired pointer type. Both structs still 2.177 +* point to the same location, though! 2.178 +* 2.179 +* @param str the mutable string to cast 2.180 +* @return an immutable copy of the string pointer 2.181 +*/ 2.182 +__attribute__((__warn_unused_result__)) 2.183 +cxstring cx_strcast(cxmutstr str); 2.184 + 2.185 +/** 2.186 + * Passes the pointer in this string to \c free(). 2.187 + * 2.188 + * The pointer in the struct is set to \c NULL and the length is set to zero. 2.189 + * 2.190 + * \note There is no implementation for cxstring, because it is unlikely that 2.191 + * you ever have a \c char \c const* you are really supposed to free. If you 2.192 + * encounter such situation, you should double-check your code. 2.193 + * 2.194 + * @param str the string to free 2.195 + */ 2.196 +void cx_strfree(cxmutstr *str); 2.197 + 2.198 +/** 2.199 + * Returns the accumulated length of all specified strings. 2.200 + * 2.201 + * \attention if the count argument is larger than the number of the 2.202 + * specified strings, the behavior is undefined. 2.203 + * 2.204 + * @param count the total number of specified strings 2.205 + * @param ... all strings 2.206 + * @return the accumulated length of all strings 2.207 + */ 2.208 +__attribute__((__warn_unused_result__)) 2.209 +size_t cx_strlen( 2.210 + size_t count, 2.211 + ... 2.212 +); 2.213 + 2.214 +/** 2.215 + * Concatenates two or more strings. 2.216 + * 2.217 + * The resulting string will be allocated by the specified allocator. 2.218 + * So developers \em must pass the return value to cx_strfree() eventually. 2.219 + * 2.220 + * \note It is guaranteed that there is only one allocation. 2.221 + * 2.222 + * @param alloc the allocator to use 2.223 + * @param count the total number of strings to concatenate 2.224 + * @param ... all strings 2.225 + * @return the concatenated string 2.226 + */ 2.227 +__attribute__((__warn_unused_result__, __nonnull__)) 2.228 +cxmutstr cx_strcat_a( 2.229 + CxAllocator *alloc, 2.230 + size_t count, 2.231 + ... 2.232 +); 2.233 + 2.234 +/** 2.235 + * Concatenates two or more strings. 2.236 + * 2.237 + * The resulting string will be allocated by standard \c malloc(). 2.238 + * So developers \em must pass the return value to cx_strfree() eventually. 2.239 + * 2.240 + * @param count the total number of strings to concatenate 2.241 + * @param ... all strings 2.242 + * @return the concatenated string 2.243 + */ 2.244 +#define cx_strcat(count, ...) \ 2.245 +cx_strcat_a(cxDefaultAllocator, count, __VA_ARGS__) 2.246 + 2.247 +/** 2.248 + * Returns a substring starting at the specified location. 2.249 + * 2.250 + * \attention the new string references the same memory area as the 2.251 + * input string and is usually \em not zero-terminated. 2.252 + * Use cx_strdup() to get a copy. 2.253 + * 2.254 + * @param string input string 2.255 + * @param start start location of the substring 2.256 + * @return a substring of \p string starting at \p start 2.257 + * 2.258 + * @see cx_strsubsl() 2.259 + * @see cx_strsubs_m() 2.260 + * @see cx_strsubsl_m() 2.261 + */ 2.262 +__attribute__((__warn_unused_result__)) 2.263 +cxstring cx_strsubs( 2.264 + cxstring string, 2.265 + size_t start 2.266 +); 2.267 + 2.268 +/** 2.269 + * Returns a substring starting at the specified location. 2.270 + * 2.271 + * The returned string will be limited to \p length bytes or the number 2.272 + * of bytes available in \p string, whichever is smaller. 2.273 + * 2.274 + * \attention the new string references the same memory area as the 2.275 + * input string and is usually \em not zero-terminated. 2.276 + * Use cx_strdup() to get a copy. 2.277 + * 2.278 + * @param string input string 2.279 + * @param start start location of the substring 2.280 + * @param length the maximum length of the returned string 2.281 + * @return a substring of \p string starting at \p start 2.282 + * 2.283 + * @see cx_strsubs() 2.284 + * @see cx_strsubs_m() 2.285 + * @see cx_strsubsl_m() 2.286 + */ 2.287 +__attribute__((__warn_unused_result__)) 2.288 +cxstring cx_strsubsl( 2.289 + cxstring string, 2.290 + size_t start, 2.291 + size_t length 2.292 +); 2.293 + 2.294 +/** 2.295 + * Returns a substring starting at the specified location. 2.296 + * 2.297 + * \attention the new string references the same memory area as the 2.298 + * input string and is usually \em not zero-terminated. 2.299 + * Use cx_strdup() to get a copy. 2.300 + * 2.301 + * @param string input string 2.302 + * @param start start location of the substring 2.303 + * @return a substring of \p string starting at \p start 2.304 + * 2.305 + * @see cx_strsubsl_m() 2.306 + * @see cx_strsubs() 2.307 + * @see cx_strsubsl() 2.308 + */ 2.309 +__attribute__((__warn_unused_result__)) 2.310 +cxmutstr cx_strsubs_m( 2.311 + cxmutstr string, 2.312 + size_t start 2.313 +); 2.314 + 2.315 +/** 2.316 + * Returns a substring starting at the specified location. 2.317 + * 2.318 + * The returned string will be limited to \p length bytes or the number 2.319 + * of bytes available in \p string, whichever is smaller. 2.320 + * 2.321 + * \attention the new string references the same memory area as the 2.322 + * input string and is usually \em not zero-terminated. 2.323 + * Use cx_strdup() to get a copy. 2.324 + * 2.325 + * @param string input string 2.326 + * @param start start location of the substring 2.327 + * @param length the maximum length of the returned string 2.328 + * @return a substring of \p string starting at \p start 2.329 + * 2.330 + * @see cx_strsubs_m() 2.331 + * @see cx_strsubs() 2.332 + * @see cx_strsubsl() 2.333 + */ 2.334 +__attribute__((__warn_unused_result__)) 2.335 +cxmutstr cx_strsubsl_m( 2.336 + cxmutstr string, 2.337 + size_t start, 2.338 + size_t length 2.339 +); 2.340 + 2.341 +/** 2.342 + * Returns a substring starting at the location of the first occurrence of the 2.343 + * specified character. 2.344 + * 2.345 + * If the string does not contain the character, an empty string is returned. 2.346 + * 2.347 + * @param string the string where to locate the character 2.348 + * @param chr the character to locate 2.349 + * @return a substring starting at the first location of \p chr 2.350 + * 2.351 + * @see cx_strchr_m() 2.352 + */ 2.353 +__attribute__((__warn_unused_result__)) 2.354 +cxstring cx_strchr( 2.355 + cxstring string, 2.356 + int chr 2.357 +); 2.358 + 2.359 +/** 2.360 + * Returns a substring starting at the location of the first occurrence of the 2.361 + * specified character. 2.362 + * 2.363 + * If the string does not contain the character, an empty string is returned. 2.364 + * 2.365 + * @param string the string where to locate the character 2.366 + * @param chr the character to locate 2.367 + * @return a substring starting at the first location of \p chr 2.368 + * 2.369 + * @see cx_strchr() 2.370 + */ 2.371 +__attribute__((__warn_unused_result__)) 2.372 +cxmutstr cx_strchr_m( 2.373 + cxmutstr string, 2.374 + int chr 2.375 +); 2.376 + 2.377 +/** 2.378 + * Returns a substring starting at the location of the last occurrence of the 2.379 + * specified character. 2.380 + * 2.381 + * If the string does not contain the character, an empty string is returned. 2.382 + * 2.383 + * @param string the string where to locate the character 2.384 + * @param chr the character to locate 2.385 + * @return a substring starting at the last location of \p chr 2.386 + * 2.387 + * @see cx_strrchr_m() 2.388 + */ 2.389 +__attribute__((__warn_unused_result__)) 2.390 +cxstring cx_strrchr( 2.391 + cxstring string, 2.392 + int chr 2.393 +); 2.394 + 2.395 +/** 2.396 + * Returns a substring starting at the location of the last occurrence of the 2.397 + * specified character. 2.398 + * 2.399 + * If the string does not contain the character, an empty string is returned. 2.400 + * 2.401 + * @param string the string where to locate the character 2.402 + * @param chr the character to locate 2.403 + * @return a substring starting at the last location of \p chr 2.404 + * 2.405 + * @see cx_strrchr() 2.406 + */ 2.407 +__attribute__((__warn_unused_result__)) 2.408 +cxmutstr cx_strrchr_m( 2.409 + cxmutstr string, 2.410 + int chr 2.411 +); 2.412 + 2.413 +/** 2.414 + * Returns a substring starting at the location of the first occurrence of the 2.415 + * specified string. 2.416 + * 2.417 + * If \p haystack does not contain \p needle, an empty string is returned. 2.418 + * 2.419 + * If \p needle is an empty string, the complete \p haystack is 2.420 + * returned. 2.421 + * 2.422 + * @param haystack the string to be scanned 2.423 + * @param needle string containing the sequence of characters to match 2.424 + * @return a substring starting at the first occurrence of 2.425 + * \p needle, or an empty string, if the sequence is not 2.426 + * contained 2.427 + * @see cx_strstr_m() 2.428 + */ 2.429 +__attribute__((__warn_unused_result__)) 2.430 +cxstring cx_strstr( 2.431 + cxstring haystack, 2.432 + cxstring needle 2.433 +); 2.434 + 2.435 +/** 2.436 + * Returns a substring starting at the location of the first occurrence of the 2.437 + * specified string. 2.438 + * 2.439 + * If \p haystack does not contain \p needle, an empty string is returned. 2.440 + * 2.441 + * If \p needle is an empty string, the complete \p haystack is 2.442 + * returned. 2.443 + * 2.444 + * @param haystack the string to be scanned 2.445 + * @param needle string containing the sequence of characters to match 2.446 + * @return a substring starting at the first occurrence of 2.447 + * \p needle, or an empty string, if the sequence is not 2.448 + * contained 2.449 + * @see cx_strstr() 2.450 + */ 2.451 +__attribute__((__warn_unused_result__)) 2.452 +cxmutstr cx_strstr_m( 2.453 + cxmutstr haystack, 2.454 + cxstring needle 2.455 +); 2.456 + 2.457 +/** 2.458 + * Splits a given string using a delimiter string. 2.459 + * 2.460 + * \note The resulting array contains strings that point to the source 2.461 + * \p string. Use cx_strdup() to get copies. 2.462 + * 2.463 + * @param string the string to split 2.464 + * @param delim the delimiter 2.465 + * @param limit the maximum number of split items 2.466 + * @param output a pre-allocated array of at least \p limit length 2.467 + * @return the actual number of split items 2.468 + */ 2.469 +__attribute__((__warn_unused_result__, __nonnull__)) 2.470 +size_t cx_strsplit( 2.471 + cxstring string, 2.472 + cxstring delim, 2.473 + size_t limit, 2.474 + cxstring *output 2.475 +); 2.476 + 2.477 +/** 2.478 + * Splits a given string using a delimiter string. 2.479 + * 2.480 + * The array pointed to by \p output will be allocated by \p allocator. 2.481 + * 2.482 + * \note The resulting array contains strings that point to the source 2.483 + * \p string. Use cx_strdup() to get copies. 2.484 + * 2.485 + * \attention If allocation fails, the \c NULL pointer will be written to 2.486 + * \p output and the number returned will be zero. 2.487 + * 2.488 + * @param allocator the allocator to use for allocating the resulting array 2.489 + * @param string the string to split 2.490 + * @param delim the delimiter 2.491 + * @param limit the maximum number of split items 2.492 + * @param output a pointer where the address of the allocated array shall be 2.493 + * written to 2.494 + * @return the actual number of split items 2.495 + */ 2.496 +__attribute__((__warn_unused_result__, __nonnull__)) 2.497 +size_t cx_strsplit_a( 2.498 + CxAllocator *allocator, 2.499 + cxstring string, 2.500 + cxstring delim, 2.501 + size_t limit, 2.502 + cxstring **output 2.503 +); 2.504 + 2.505 + 2.506 +/** 2.507 + * Splits a given string using a delimiter string. 2.508 + * 2.509 + * \note The resulting array contains strings that point to the source 2.510 + * \p string. Use cx_strdup() to get copies. 2.511 + * 2.512 + * @param string the string to split 2.513 + * @param delim the delimiter 2.514 + * @param limit the maximum number of split items 2.515 + * @param output a pre-allocated array of at least \p limit length 2.516 + * @return the actual number of split items 2.517 + */ 2.518 +__attribute__((__warn_unused_result__, __nonnull__)) 2.519 +size_t cx_strsplit_m( 2.520 + cxmutstr string, 2.521 + cxstring delim, 2.522 + size_t limit, 2.523 + cxmutstr *output 2.524 +); 2.525 + 2.526 +/** 2.527 + * Splits a given string using a delimiter string. 2.528 + * 2.529 + * The array pointed to by \p output will be allocated by \p allocator. 2.530 + * 2.531 + * \note The resulting array contains strings that point to the source 2.532 + * \p string. Use cx_strdup() to get copies. 2.533 + * 2.534 + * \attention If allocation fails, the \c NULL pointer will be written to 2.535 + * \p output and the number returned will be zero. 2.536 + * 2.537 + * @param allocator the allocator to use for allocating the resulting array 2.538 + * @param string the string to split 2.539 + * @param delim the delimiter 2.540 + * @param limit the maximum number of split items 2.541 + * @param output a pointer where the address of the allocated array shall be 2.542 + * written to 2.543 + * @return the actual number of split items 2.544 + */ 2.545 +__attribute__((__warn_unused_result__, __nonnull__)) 2.546 +size_t cx_strsplit_ma( 2.547 + CxAllocator *allocator, 2.548 + cxmutstr string, 2.549 + cxstring delim, 2.550 + size_t limit, 2.551 + cxmutstr **output 2.552 +); 2.553 + 2.554 +/** 2.555 + * Compares two strings. 2.556 + * 2.557 + * @param s1 the first string 2.558 + * @param s2 the second string 2.559 + * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger 2.560 + * than \p s2, zero if both strings equal 2.561 + */ 2.562 +__attribute__((__warn_unused_result__)) 2.563 +int cx_strcmp( 2.564 + cxstring s1, 2.565 + cxstring s2 2.566 +); 2.567 + 2.568 +/** 2.569 + * Compares two strings ignoring case. 2.570 + * 2.571 + * @param s1 the first string 2.572 + * @param s2 the second string 2.573 + * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger 2.574 + * than \p s2, zero if both strings equal ignoring case 2.575 + */ 2.576 +__attribute__((__warn_unused_result__)) 2.577 +int cx_strcasecmp( 2.578 + cxstring s1, 2.579 + cxstring s2 2.580 +); 2.581 + 2.582 +/** 2.583 + * Creates a duplicate of the specified string. 2.584 + * 2.585 + * The new string will contain a copy allocated by standard 2.586 + * \c malloc(). So developers \em must pass the return value to cx_strfree(). 2.587 + * 2.588 + * \note The returned string is guaranteed to be zero-terminated and can safely 2.589 + * be passed to other APIs. 2.590 + * 2.591 + * @param string the string to duplicate 2.592 + * @return a duplicate of the string 2.593 + * @see cx_strdup_a() 2.594 + */ 2.595 +__attribute__((__warn_unused_result__)) 2.596 +cxmutstr cx_strdup(cxstring string); 2.597 + 2.598 +/** 2.599 + * Creates a duplicate of the specified string. 2.600 + * 2.601 + * The new string will contain a copy allocated by \p allocator. 2.602 + * 2.603 + * \note The returned string is guaranteed to be zero-terminated and can safely 2.604 + * be passed to other APIs. 2.605 + * 2.606 + * @param allocator the allocator to use 2.607 + * @param string the string to duplicate 2.608 + * @return a duplicate of the string 2.609 + * @see cx_strdup() 2.610 + */ 2.611 +__attribute__((__warn_unused_result__, __nonnull__)) 2.612 +cxmutstr cx_strdup_a( 2.613 + CxAllocator *allocator, 2.614 + cxstring string 2.615 +); 2.616 + 2.617 +/** 2.618 + * Omits leading and trailing spaces. 2.619 + * 2.620 + * \note the returned string references the same memory, thus you 2.621 + * must \em not free the returned memory. 2.622 + * 2.623 + * @param string the string that shall be trimmed 2.624 + * @return the trimmed string 2.625 + */ 2.626 +__attribute__((__warn_unused_result__)) 2.627 +cxstring cx_strtrim(cxstring string); 2.628 + 2.629 +/** 2.630 + * Omits leading and trailing spaces. 2.631 + * 2.632 + * \note the returned string references the same memory, thus you 2.633 + * must \em not free the returned memory. 2.634 + * 2.635 + * @param string the string that shall be trimmed 2.636 + * @return the trimmed string 2.637 + */ 2.638 +__attribute__((__warn_unused_result__)) 2.639 +cxmutstr cx_strtrim_m(cxmutstr string); 2.640 + 2.641 +/** 2.642 + * Checks, if a string has a specific prefix. 2.643 + * 2.644 + * @param string the string to check 2.645 + * @param prefix the prefix the string should have 2.646 + * @return \c true, if and only if the string has the specified prefix, 2.647 + * \c false otherwise 2.648 + */ 2.649 +__attribute__((__warn_unused_result__)) 2.650 +bool cx_strprefix( 2.651 + cxstring string, 2.652 + cxstring prefix 2.653 +); 2.654 + 2.655 +/** 2.656 + * Checks, if a string has a specific suffix. 2.657 + * 2.658 + * @param string the string to check 2.659 + * @param suffix the suffix the string should have 2.660 + * @return \c true, if and only if the string has the specified suffix, 2.661 + * \c false otherwise 2.662 + */ 2.663 +__attribute__((__warn_unused_result__)) 2.664 +int cx_strsuffix( 2.665 + cxstring string, 2.666 + cxstring suffix 2.667 +); 2.668 + 2.669 +/** 2.670 + * Checks, if a string has a specific prefix, ignoring the case. 2.671 + * 2.672 + * @param string the string to check 2.673 + * @param prefix the prefix the string should have 2.674 + * @return \c true, if and only if the string has the specified prefix, 2.675 + * \c false otherwise 2.676 + */ 2.677 +__attribute__((__warn_unused_result__)) 2.678 +int cx_strcaseprefix( 2.679 + cxstring string, 2.680 + cxstring prefix 2.681 +); 2.682 + 2.683 +/** 2.684 + * Checks, if a string has a specific suffix, ignoring the case. 2.685 + * 2.686 + * @param string the string to check 2.687 + * @param suffix the suffix the string should have 2.688 + * @return \c true, if and only if the string has the specified suffix, 2.689 + * \c false otherwise 2.690 + */ 2.691 +__attribute__((__warn_unused_result__)) 2.692 +int cx_strcasesuffix( 2.693 + cxstring string, 2.694 + cxstring suffix 2.695 +); 2.696 + 2.697 +/** 2.698 + * Converts the string to lower case. 2.699 + * 2.700 + * The change is made in-place. If you want a copy, use cx_strdup(), first. 2.701 + * 2.702 + * @param string the string to modify 2.703 + * @see cx_strdup() 2.704 + */ 2.705 +void cx_strlower(cxmutstr string); 2.706 + 2.707 +/** 2.708 + * Converts the string to upper case. 2.709 + * 2.710 + * The change is made in-place. If you want a copy, use cx_strdup(), first. 2.711 + * 2.712 + * @param string the string to modify 2.713 + * @see cx_strdup() 2.714 + */ 2.715 +void cx_strupper(cxmutstr string); 2.716 + 2.717 +/** 2.718 + * Replaces a pattern in a string with another string. 2.719 + * 2.720 + * The pattern is taken literally and is no regular expression. 2.721 + * Replaces at most \p replmax occurrences. 2.722 + * 2.723 + * The returned string will be allocated by \c malloc() and \em must be passed 2.724 + * to cx_strfree() eventually. 2.725 + * 2.726 + * If allocation fails, or the input string is empty, 2.727 + * the returned string will point to \c NULL. 2.728 + * 2.729 + * @param str the string where replacements should be applied 2.730 + * @param pattern the pattern to search for 2.731 + * @param replacement the replacement string 2.732 + * @param replmax maximum number of replacements 2.733 + * @return the resulting string after applying the replacements 2.734 + */ 2.735 +__attribute__((__warn_unused_result__)) 2.736 +cxmutstr cx_strreplace( 2.737 + cxstring str, 2.738 + cxstring pattern, 2.739 + cxstring replacement, 2.740 + size_t replmax 2.741 +); 2.742 + 2.743 +/** 2.744 + * Replaces a pattern in a string with another string. 2.745 + * 2.746 + * The pattern is taken literally and is no regular expression. 2.747 + * Replaces at most \p replmax occurrences. 2.748 + * 2.749 + * The returned string will be allocated by \p allocator. 2.750 + * 2.751 + * If allocation fails, or the input string is empty, 2.752 + * the returned string will point to \c NULL. 2.753 + * 2.754 + * @param allocator the allocator to use 2.755 + * @param str the string where replacements should be applied 2.756 + * @param pattern the pattern to search for 2.757 + * @param replacement the replacement string 2.758 + * @param replmax maximum number of replacements 2.759 + * @return the resulting string after applying the replacements 2.760 + */ 2.761 +__attribute__((__warn_unused_result__, __nonnull__)) 2.762 +cxmutstr cx_strreplace_a( 2.763 + CxAllocator *allocator, 2.764 + cxstring str, 2.765 + cxstring pattern, 2.766 + cxstring replacement, 2.767 + size_t replmax 2.768 +); 2.769 + 2.770 +#ifdef __cplusplus 2.771 +} // extern "C" 2.772 +#endif 2.773 + 2.774 +#endif //UCX_STRING_H
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/string.c Mon Aug 29 20:54:42 2022 +0200 3.3 @@ -0,0 +1,29 @@ 3.4 +/* 3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3.6 + * 3.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 3.8 + * 3.9 + * Redistribution and use in source and binary forms, with or without 3.10 + * modification, are permitted provided that the following conditions are met: 3.11 + * 3.12 + * 1. Redistributions of source code must retain the above copyright 3.13 + * notice, this list of conditions and the following disclaimer. 3.14 + * 3.15 + * 2. Redistributions in binary form must reproduce the above copyright 3.16 + * notice, this list of conditions and the following disclaimer in the 3.17 + * documentation and/or other materials provided with the distribution. 3.18 + * 3.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 3.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 3.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3.29 + * POSSIBILITY OF SUCH DAMAGE. 3.30 + */ 3.31 + 3.32 +#include "cx/string.h"