src/cx/string.h

Sun, 14 Jan 2024 13:50:17 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 14 Jan 2024 13:50:17 +0100
changeset 806
e06249e09f99
parent 759
475335643af4
permissions
-rw-r--r--

add constant for reading out strstr sbo size - relates to #343

also fixes the related test which was working with the old SBO size of 256 and was broken after increasing it to 512

universe@576 1 /*
universe@576 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@576 3 *
universe@576 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@576 5 *
universe@576 6 * Redistribution and use in source and binary forms, with or without
universe@576 7 * modification, are permitted provided that the following conditions are met:
universe@576 8 *
universe@576 9 * 1. Redistributions of source code must retain the above copyright
universe@576 10 * notice, this list of conditions and the following disclaimer.
universe@576 11 *
universe@576 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@576 13 * notice, this list of conditions and the following disclaimer in the
universe@576 14 * documentation and/or other materials provided with the distribution.
universe@576 15 *
universe@576 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@576 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@576 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@576 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@576 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@576 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@576 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@576 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@576 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@576 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@576 26 * POSSIBILITY OF SUCH DAMAGE.
universe@576 27 */
universe@576 28 /**
universe@576 29 * \file string.h
universe@576 30 * \brief Strings that know their length.
universe@576 31 * \author Mike Becker
universe@576 32 * \author Olaf Wintermann
universe@576 33 * \copyright 2-Clause BSD License
universe@576 34 */
universe@576 35
universe@576 36 #ifndef UCX_STRING_H
universe@576 37 #define UCX_STRING_H
universe@576 38
universe@576 39 #include "common.h"
universe@576 40 #include "allocator.h"
universe@576 41
universe@576 42 /**
universe@806 43 * The maximum length of the "needle" in cx_strstr() that can use SBO.
universe@806 44 */
universe@806 45 extern unsigned const cx_strstr_sbo_size;
universe@806 46
universe@806 47 /**
universe@576 48 * The UCX string structure.
universe@576 49 */
universe@577 50 struct cx_mutstr_s {
universe@576 51 /**
universe@576 52 * A pointer to the string.
universe@576 53 * \note The string is not necessarily \c NULL terminated.
universe@576 54 * Always use the length.
universe@576 55 */
universe@576 56 char *ptr;
universe@576 57 /** The length of the string */
universe@576 58 size_t length;
universe@577 59 };
universe@576 60
universe@576 61 /**
universe@576 62 * A mutable string.
universe@576 63 */
universe@576 64 typedef struct cx_mutstr_s cxmutstr;
universe@576 65
universe@576 66 /**
universe@576 67 * The UCX string structure for immutable (constant) strings.
universe@576 68 */
universe@577 69 struct cx_string_s {
universe@576 70 /**
universe@576 71 * A pointer to the immutable string.
universe@576 72 * \note The string is not necessarily \c NULL terminated.
universe@576 73 * Always use the length.
universe@576 74 */
universe@576 75 char const *ptr;
universe@576 76 /** The length of the string */
universe@576 77 size_t length;
universe@577 78 };
universe@576 79
universe@576 80 /**
universe@576 81 * An immutable string.
universe@576 82 */
universe@576 83 typedef struct cx_string_s cxstring;
universe@576 84
universe@583 85 /**
universe@645 86 * Context for string tokenizing.
universe@645 87 */
universe@645 88 struct cx_strtok_ctx_s {
universe@645 89 /**
universe@645 90 * The string to tokenize.
universe@645 91 */
universe@645 92 cxstring str;
universe@645 93 /**
universe@645 94 * The primary delimiter.
universe@645 95 */
universe@645 96 cxstring delim;
universe@645 97 /**
universe@645 98 * Optional array of more delimiters.
universe@645 99 */
universe@645 100 cxstring const *delim_more;
universe@645 101 /**
universe@645 102 * Length of the array containing more delimiters.
universe@645 103 */
universe@645 104 size_t delim_more_count;
universe@645 105 /**
universe@645 106 * Position of the currently active token in the source string.
universe@645 107 */
universe@645 108 size_t pos;
universe@645 109 /**
universe@645 110 * Position of next delimiter in the source string.
universe@645 111 *
universe@645 112 * If the tokenizer has not yet returned a token, the content of this field
universe@645 113 * is undefined. If the tokenizer reached the end of the string, this field
universe@645 114 * contains the length of the source string.
universe@645 115 */
universe@645 116 size_t delim_pos;
universe@645 117 /**
universe@645 118 * The position of the next token in the source string.
universe@645 119 */
universe@645 120 size_t next_pos;
universe@645 121 /**
universe@645 122 * The number of already found tokens.
universe@645 123 */
universe@645 124 size_t found;
universe@645 125 /**
universe@645 126 * The maximum number of tokens that shall be returned.
universe@645 127 */
universe@645 128 size_t limit;
universe@645 129 };
universe@645 130
universe@645 131 /**
universe@645 132 * A string tokenizing context.
universe@645 133 */
universe@645 134 typedef struct cx_strtok_ctx_s CxStrtokCtx;
universe@645 135
universe@684 136 #ifdef __cplusplus
universe@684 137 extern "C" {
universe@684 138
universe@684 139 /**
universe@684 140 * A literal initializer for an UCX string structure.
universe@684 141 *
universe@684 142 * @param literal the string literal
universe@684 143 */
universe@684 144 #define CX_STR(literal) cxstring{literal, sizeof(literal) - 1}
universe@684 145
universe@684 146 #else // __cplusplus
universe@684 147
universe@645 148 /**
universe@583 149 * A literal initializer for an UCX string structure.
universe@583 150 *
universe@583 151 * The argument MUST be a string (const char*) \em literal.
universe@583 152 *
universe@583 153 * @param literal the string literal
universe@583 154 */
universe@684 155 #define CX_STR(literal) (cxstring){literal, sizeof(literal) - 1}
universe@583 156
universe@576 157 #endif
universe@576 158
universe@576 159
universe@576 160 /**
universe@576 161 * Wraps a mutable string that must be zero-terminated.
universe@576 162 *
universe@576 163 * The length is implicitly inferred by using a call to \c strlen().
universe@576 164 *
universe@576 165 * \note the wrapped string will share the specified pointer to the string.
universe@576 166 * If you do want a copy, use cx_strdup() on the return value of this function.
universe@576 167 *
universe@576 168 * If you need to wrap a constant string, use cx_str().
universe@576 169 *
universe@584 170 * @param cstring the string to wrap, must be zero-terminated
universe@576 171 * @return the wrapped string
universe@576 172 *
universe@576 173 * @see cx_mutstrn()
universe@576 174 */
universe@584 175 __attribute__((__warn_unused_result__, __nonnull__))
universe@576 176 cxmutstr cx_mutstr(char *cstring);
universe@576 177
universe@576 178 /**
universe@576 179 * Wraps a string that does not need to be zero-terminated.
universe@576 180 *
universe@576 181 * The argument may be \c NULL if the length is zero.
universe@576 182 *
universe@576 183 * \note the wrapped string will share the specified pointer to the string.
universe@576 184 * If you do want a copy, use cx_strdup() on the return value of this function.
universe@576 185 *
universe@576 186 * If you need to wrap a constant string, use cx_strn().
universe@576 187 *
universe@584 188 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
universe@576 189 * @param length the length of the string
universe@576 190 * @return the wrapped string
universe@576 191 *
universe@576 192 * @see cx_mutstr()
universe@576 193 */
universe@576 194 __attribute__((__warn_unused_result__))
universe@576 195 cxmutstr cx_mutstrn(
universe@576 196 char *cstring,
universe@576 197 size_t length
universe@576 198 );
universe@576 199
universe@576 200 /**
universe@576 201 * Wraps a string that must be zero-terminated.
universe@576 202 *
universe@576 203 * The length is implicitly inferred by using a call to \c strlen().
universe@576 204 *
universe@576 205 * \note the wrapped string will share the specified pointer to the string.
universe@576 206 * If you do want a copy, use cx_strdup() on the return value of this function.
universe@576 207 *
universe@576 208 * If you need to wrap a non-constant string, use cx_mutstr().
universe@576 209 *
universe@584 210 * @param cstring the string to wrap, must be zero-terminated
universe@576 211 * @return the wrapped string
universe@576 212 *
universe@576 213 * @see cx_strn()
universe@576 214 */
universe@584 215 __attribute__((__warn_unused_result__, __nonnull__))
universe@576 216 cxstring cx_str(char const *cstring);
universe@576 217
universe@576 218
universe@576 219 /**
universe@576 220 * Wraps a string that does not need to be zero-terminated.
universe@576 221 *
universe@576 222 * The argument may be \c NULL if the length is zero.
universe@576 223 *
universe@576 224 * \note the wrapped string will share the specified pointer to the string.
universe@576 225 * If you do want a copy, use cx_strdup() on the return value of this function.
universe@576 226 *
universe@576 227 * If you need to wrap a non-constant string, use cx_mutstrn().
universe@576 228 *
universe@584 229 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
universe@576 230 * @param length the length of the string
universe@576 231 * @return the wrapped string
universe@576 232 *
universe@576 233 * @see cx_str()
universe@576 234 */
universe@576 235 __attribute__((__warn_unused_result__))
universe@576 236 cxstring cx_strn(
universe@576 237 char const *cstring,
universe@576 238 size_t length
universe@576 239 );
universe@576 240
universe@576 241 /**
universe@576 242 * Casts a mutable string to an immutable string.
universe@576 243 *
universe@576 244 * \note This is not seriously a cast. Instead you get a copy
universe@576 245 * of the struct with the desired pointer type. Both structs still
universe@576 246 * point to the same location, though!
universe@576 247 *
universe@576 248 * @param str the mutable string to cast
universe@576 249 * @return an immutable copy of the string pointer
universe@576 250 */
universe@576 251 __attribute__((__warn_unused_result__))
universe@576 252 cxstring cx_strcast(cxmutstr str);
universe@576 253
universe@576 254 /**
universe@576 255 * Passes the pointer in this string to \c free().
universe@576 256 *
universe@576 257 * The pointer in the struct is set to \c NULL and the length is set to zero.
universe@576 258 *
universe@576 259 * \note There is no implementation for cxstring, because it is unlikely that
universe@576 260 * you ever have a \c char \c const* you are really supposed to free. If you
universe@576 261 * encounter such situation, you should double-check your code.
universe@576 262 *
universe@576 263 * @param str the string to free
universe@576 264 */
universe@583 265 __attribute__((__nonnull__))
universe@576 266 void cx_strfree(cxmutstr *str);
universe@576 267
universe@576 268 /**
universe@583 269 * Passes the pointer in this string to the allocators free function.
universe@583 270 *
universe@583 271 * The pointer in the struct is set to \c NULL and the length is set to zero.
universe@583 272 *
universe@583 273 * \note There is no implementation for cxstring, because it is unlikely that
universe@583 274 * you ever have a \c char \c const* you are really supposed to free. If you
universe@583 275 * encounter such situation, you should double-check your code.
universe@583 276 *
universe@583 277 * @param alloc the allocator
universe@583 278 * @param str the string to free
universe@583 279 */
universe@583 280 __attribute__((__nonnull__))
universe@583 281 void cx_strfree_a(
universe@693 282 CxAllocator const *alloc,
universe@583 283 cxmutstr *str
universe@583 284 );
universe@583 285
universe@583 286 /**
universe@576 287 * Returns the accumulated length of all specified strings.
universe@576 288 *
universe@576 289 * \attention if the count argument is larger than the number of the
universe@576 290 * specified strings, the behavior is undefined.
universe@576 291 *
universe@576 292 * @param count the total number of specified strings
universe@576 293 * @param ... all strings
universe@576 294 * @return the accumulated length of all strings
universe@576 295 */
universe@576 296 __attribute__((__warn_unused_result__))
universe@576 297 size_t cx_strlen(
universe@576 298 size_t count,
universe@576 299 ...
universe@576 300 );
universe@576 301
universe@576 302 /**
universe@697 303 * Concatenates strings.
universe@576 304 *
universe@576 305 * The resulting string will be allocated by the specified allocator.
universe@697 306 * So developers \em must pass the return value to cx_strfree_a() eventually.
universe@697 307 *
universe@697 308 * If \p str already contains a string, the memory will be reallocated and
universe@697 309 * the other strings are appended. Otherwise, new memory is allocated.
universe@697 310 *
universe@697 311 * \note It is guaranteed that there is only one allocation.
universe@697 312 * It is also guaranteed that the returned string is zero-terminated.
universe@576 313 *
universe@576 314 * @param alloc the allocator to use
universe@697 315 * @param str the string the other strings shall be concatenated to
universe@697 316 * @param count the number of the other following strings to concatenate
universe@697 317 * @param ... all other strings
universe@576 318 * @return the concatenated string
universe@576 319 */
universe@576 320 __attribute__((__warn_unused_result__, __nonnull__))
universe@697 321 cxmutstr cx_strcat_ma(
universe@693 322 CxAllocator const *alloc,
universe@697 323 cxmutstr str,
universe@576 324 size_t count,
universe@576 325 ...
universe@576 326 );
universe@576 327
universe@576 328 /**
universe@697 329 * Concatenates strings and returns a new string.
universe@697 330 *
universe@697 331 * The resulting string will be allocated by the specified allocator.
universe@697 332 * So developers \em must pass the return value to cx_strfree_a() eventually.
universe@697 333 *
universe@697 334 * \note It is guaranteed that there is only one allocation.
universe@697 335 * It is also guaranteed that the returned string is zero-terminated.
universe@697 336 *
universe@697 337 * @param alloc the allocator to use
universe@697 338 * @param count the number of the other following strings to concatenate
universe@697 339 * @param ... all other strings
universe@697 340 * @return the concatenated string
universe@697 341 */
universe@697 342 #define cx_strcat_a(alloc, count, ...) \
universe@697 343 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
universe@697 344
universe@697 345 /**
universe@697 346 * Concatenates strings and returns a new string.
universe@576 347 *
universe@576 348 * The resulting string will be allocated by standard \c malloc().
universe@576 349 * So developers \em must pass the return value to cx_strfree() eventually.
universe@576 350 *
universe@589 351 * \note It is guaranteed that there is only one allocation.
universe@589 352 * It is also guaranteed that the returned string is zero-terminated.
universe@589 353 *
universe@697 354 * @param count the number of the other following strings to concatenate
universe@697 355 * @param ... all other strings
universe@576 356 * @return the concatenated string
universe@576 357 */
universe@576 358 #define cx_strcat(count, ...) \
universe@697 359 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
universe@697 360
universe@697 361 /**
universe@697 362 * Concatenates strings.
universe@697 363 *
universe@697 364 * The resulting string will be allocated by standard \c malloc().
universe@697 365 * So developers \em must pass the return value to cx_strfree() eventually.
universe@697 366 *
universe@697 367 * If \p str already contains a string, the memory will be reallocated and
universe@697 368 * the other strings are appended. Otherwise, new memory is allocated.
universe@697 369 *
universe@697 370 * \note It is guaranteed that there is only one allocation.
universe@697 371 * It is also guaranteed that the returned string is zero-terminated.
universe@697 372 *
universe@697 373 * @param str the string the other strings shall be concatenated to
universe@697 374 * @param count the number of the other following strings to concatenate
universe@697 375 * @param ... all other strings
universe@697 376 * @return the concatenated string
universe@697 377 */
universe@697 378 #define cx_strcat_m(str, count, ...) \
universe@697 379 cx_strcat_ma(cxDefaultAllocator, str, count, __VA_ARGS__)
universe@576 380
universe@576 381 /**
universe@576 382 * Returns a substring starting at the specified location.
universe@576 383 *
universe@576 384 * \attention the new string references the same memory area as the
universe@576 385 * input string and is usually \em not zero-terminated.
universe@576 386 * Use cx_strdup() to get a copy.
universe@576 387 *
universe@576 388 * @param string input string
universe@576 389 * @param start start location of the substring
universe@576 390 * @return a substring of \p string starting at \p start
universe@576 391 *
universe@576 392 * @see cx_strsubsl()
universe@576 393 * @see cx_strsubs_m()
universe@576 394 * @see cx_strsubsl_m()
universe@576 395 */
universe@576 396 __attribute__((__warn_unused_result__))
universe@576 397 cxstring cx_strsubs(
universe@576 398 cxstring string,
universe@576 399 size_t start
universe@576 400 );
universe@576 401
universe@576 402 /**
universe@576 403 * Returns a substring starting at the specified location.
universe@576 404 *
universe@576 405 * The returned string will be limited to \p length bytes or the number
universe@576 406 * of bytes available in \p string, whichever is smaller.
universe@576 407 *
universe@576 408 * \attention the new string references the same memory area as the
universe@576 409 * input string and is usually \em not zero-terminated.
universe@576 410 * Use cx_strdup() to get a copy.
universe@576 411 *
universe@576 412 * @param string input string
universe@576 413 * @param start start location of the substring
universe@576 414 * @param length the maximum length of the returned string
universe@576 415 * @return a substring of \p string starting at \p start
universe@576 416 *
universe@576 417 * @see cx_strsubs()
universe@576 418 * @see cx_strsubs_m()
universe@576 419 * @see cx_strsubsl_m()
universe@576 420 */
universe@576 421 __attribute__((__warn_unused_result__))
universe@576 422 cxstring cx_strsubsl(
universe@576 423 cxstring string,
universe@576 424 size_t start,
universe@576 425 size_t length
universe@576 426 );
universe@576 427
universe@576 428 /**
universe@576 429 * Returns a substring starting at the specified location.
universe@576 430 *
universe@576 431 * \attention the new string references the same memory area as the
universe@576 432 * input string and is usually \em not zero-terminated.
universe@576 433 * Use cx_strdup() to get a copy.
universe@576 434 *
universe@576 435 * @param string input string
universe@576 436 * @param start start location of the substring
universe@576 437 * @return a substring of \p string starting at \p start
universe@576 438 *
universe@576 439 * @see cx_strsubsl_m()
universe@576 440 * @see cx_strsubs()
universe@576 441 * @see cx_strsubsl()
universe@576 442 */
universe@576 443 __attribute__((__warn_unused_result__))
universe@576 444 cxmutstr cx_strsubs_m(
universe@576 445 cxmutstr string,
universe@576 446 size_t start
universe@576 447 );
universe@576 448
universe@576 449 /**
universe@576 450 * Returns a substring starting at the specified location.
universe@576 451 *
universe@576 452 * The returned string will be limited to \p length bytes or the number
universe@576 453 * of bytes available in \p string, whichever is smaller.
universe@576 454 *
universe@576 455 * \attention the new string references the same memory area as the
universe@576 456 * input string and is usually \em not zero-terminated.
universe@576 457 * Use cx_strdup() to get a copy.
universe@576 458 *
universe@576 459 * @param string input string
universe@576 460 * @param start start location of the substring
universe@576 461 * @param length the maximum length of the returned string
universe@576 462 * @return a substring of \p string starting at \p start
universe@576 463 *
universe@576 464 * @see cx_strsubs_m()
universe@576 465 * @see cx_strsubs()
universe@576 466 * @see cx_strsubsl()
universe@576 467 */
universe@576 468 __attribute__((__warn_unused_result__))
universe@576 469 cxmutstr cx_strsubsl_m(
universe@576 470 cxmutstr string,
universe@576 471 size_t start,
universe@576 472 size_t length
universe@576 473 );
universe@576 474
universe@576 475 /**
universe@576 476 * Returns a substring starting at the location of the first occurrence of the
universe@576 477 * specified character.
universe@576 478 *
universe@576 479 * If the string does not contain the character, an empty string is returned.
universe@576 480 *
universe@576 481 * @param string the string where to locate the character
universe@576 482 * @param chr the character to locate
universe@576 483 * @return a substring starting at the first location of \p chr
universe@576 484 *
universe@576 485 * @see cx_strchr_m()
universe@576 486 */
universe@576 487 __attribute__((__warn_unused_result__))
universe@576 488 cxstring cx_strchr(
universe@576 489 cxstring string,
universe@576 490 int chr
universe@576 491 );
universe@576 492
universe@576 493 /**
universe@576 494 * Returns a substring starting at the location of the first occurrence of the
universe@576 495 * specified character.
universe@576 496 *
universe@576 497 * If the string does not contain the character, an empty string is returned.
universe@576 498 *
universe@576 499 * @param string the string where to locate the character
universe@576 500 * @param chr the character to locate
universe@576 501 * @return a substring starting at the first location of \p chr
universe@576 502 *
universe@576 503 * @see cx_strchr()
universe@576 504 */
universe@576 505 __attribute__((__warn_unused_result__))
universe@576 506 cxmutstr cx_strchr_m(
universe@576 507 cxmutstr string,
universe@576 508 int chr
universe@576 509 );
universe@576 510
universe@576 511 /**
universe@576 512 * Returns a substring starting at the location of the last occurrence of the
universe@576 513 * specified character.
universe@576 514 *
universe@576 515 * If the string does not contain the character, an empty string is returned.
universe@576 516 *
universe@576 517 * @param string the string where to locate the character
universe@576 518 * @param chr the character to locate
universe@576 519 * @return a substring starting at the last location of \p chr
universe@576 520 *
universe@576 521 * @see cx_strrchr_m()
universe@576 522 */
universe@576 523 __attribute__((__warn_unused_result__))
universe@576 524 cxstring cx_strrchr(
universe@576 525 cxstring string,
universe@576 526 int chr
universe@576 527 );
universe@576 528
universe@576 529 /**
universe@576 530 * Returns a substring starting at the location of the last occurrence of the
universe@576 531 * specified character.
universe@576 532 *
universe@576 533 * If the string does not contain the character, an empty string is returned.
universe@576 534 *
universe@576 535 * @param string the string where to locate the character
universe@576 536 * @param chr the character to locate
universe@576 537 * @return a substring starting at the last location of \p chr
universe@576 538 *
universe@576 539 * @see cx_strrchr()
universe@576 540 */
universe@576 541 __attribute__((__warn_unused_result__))
universe@576 542 cxmutstr cx_strrchr_m(
universe@576 543 cxmutstr string,
universe@576 544 int chr
universe@576 545 );
universe@576 546
universe@576 547 /**
universe@576 548 * Returns a substring starting at the location of the first occurrence of the
universe@576 549 * specified string.
universe@576 550 *
universe@576 551 * If \p haystack does not contain \p needle, an empty string is returned.
universe@576 552 *
universe@576 553 * If \p needle is an empty string, the complete \p haystack is
universe@576 554 * returned.
universe@576 555 *
universe@576 556 * @param haystack the string to be scanned
universe@576 557 * @param needle string containing the sequence of characters to match
universe@576 558 * @return a substring starting at the first occurrence of
universe@576 559 * \p needle, or an empty string, if the sequence is not
universe@576 560 * contained
universe@576 561 * @see cx_strstr_m()
universe@576 562 */
universe@576 563 __attribute__((__warn_unused_result__))
universe@576 564 cxstring cx_strstr(
universe@576 565 cxstring haystack,
universe@576 566 cxstring needle
universe@576 567 );
universe@576 568
universe@576 569 /**
universe@576 570 * Returns a substring starting at the location of the first occurrence of the
universe@576 571 * specified string.
universe@576 572 *
universe@576 573 * If \p haystack does not contain \p needle, an empty string is returned.
universe@576 574 *
universe@576 575 * If \p needle is an empty string, the complete \p haystack is
universe@576 576 * returned.
universe@576 577 *
universe@576 578 * @param haystack the string to be scanned
universe@576 579 * @param needle string containing the sequence of characters to match
universe@576 580 * @return a substring starting at the first occurrence of
universe@576 581 * \p needle, or an empty string, if the sequence is not
universe@576 582 * contained
universe@576 583 * @see cx_strstr()
universe@576 584 */
universe@576 585 __attribute__((__warn_unused_result__))
universe@576 586 cxmutstr cx_strstr_m(
universe@576 587 cxmutstr haystack,
universe@576 588 cxstring needle
universe@576 589 );
universe@576 590
universe@576 591 /**
universe@576 592 * Splits a given string using a delimiter string.
universe@576 593 *
universe@576 594 * \note The resulting array contains strings that point to the source
universe@576 595 * \p string. Use cx_strdup() to get copies.
universe@576 596 *
universe@576 597 * @param string the string to split
universe@576 598 * @param delim the delimiter
universe@576 599 * @param limit the maximum number of split items
universe@576 600 * @param output a pre-allocated array of at least \p limit length
universe@576 601 * @return the actual number of split items
universe@576 602 */
universe@576 603 __attribute__((__warn_unused_result__, __nonnull__))
universe@576 604 size_t cx_strsplit(
universe@576 605 cxstring string,
universe@576 606 cxstring delim,
universe@576 607 size_t limit,
universe@576 608 cxstring *output
universe@576 609 );
universe@576 610
universe@576 611 /**
universe@576 612 * Splits a given string using a delimiter string.
universe@576 613 *
universe@576 614 * The array pointed to by \p output will be allocated by \p allocator.
universe@576 615 *
universe@576 616 * \note The resulting array contains strings that point to the source
universe@576 617 * \p string. Use cx_strdup() to get copies.
universe@576 618 *
universe@576 619 * \attention If allocation fails, the \c NULL pointer will be written to
universe@576 620 * \p output and the number returned will be zero.
universe@576 621 *
universe@576 622 * @param allocator the allocator to use for allocating the resulting array
universe@576 623 * @param string the string to split
universe@576 624 * @param delim the delimiter
universe@576 625 * @param limit the maximum number of split items
universe@576 626 * @param output a pointer where the address of the allocated array shall be
universe@576 627 * written to
universe@576 628 * @return the actual number of split items
universe@576 629 */
universe@576 630 __attribute__((__warn_unused_result__, __nonnull__))
universe@576 631 size_t cx_strsplit_a(
universe@693 632 CxAllocator const *allocator,
universe@576 633 cxstring string,
universe@576 634 cxstring delim,
universe@576 635 size_t limit,
universe@576 636 cxstring **output
universe@576 637 );
universe@576 638
universe@576 639
universe@576 640 /**
universe@576 641 * Splits a given string using a delimiter string.
universe@576 642 *
universe@576 643 * \note The resulting array contains strings that point to the source
universe@576 644 * \p string. Use cx_strdup() to get copies.
universe@576 645 *
universe@576 646 * @param string the string to split
universe@576 647 * @param delim the delimiter
universe@576 648 * @param limit the maximum number of split items
universe@576 649 * @param output a pre-allocated array of at least \p limit length
universe@576 650 * @return the actual number of split items
universe@576 651 */
universe@576 652 __attribute__((__warn_unused_result__, __nonnull__))
universe@576 653 size_t cx_strsplit_m(
universe@576 654 cxmutstr string,
universe@576 655 cxstring delim,
universe@576 656 size_t limit,
universe@576 657 cxmutstr *output
universe@576 658 );
universe@576 659
universe@576 660 /**
universe@576 661 * Splits a given string using a delimiter string.
universe@576 662 *
universe@576 663 * The array pointed to by \p output will be allocated by \p allocator.
universe@576 664 *
universe@576 665 * \note The resulting array contains strings that point to the source
universe@576 666 * \p string. Use cx_strdup() to get copies.
universe@576 667 *
universe@576 668 * \attention If allocation fails, the \c NULL pointer will be written to
universe@576 669 * \p output and the number returned will be zero.
universe@576 670 *
universe@576 671 * @param allocator the allocator to use for allocating the resulting array
universe@576 672 * @param string the string to split
universe@576 673 * @param delim the delimiter
universe@576 674 * @param limit the maximum number of split items
universe@576 675 * @param output a pointer where the address of the allocated array shall be
universe@576 676 * written to
universe@576 677 * @return the actual number of split items
universe@576 678 */
universe@576 679 __attribute__((__warn_unused_result__, __nonnull__))
universe@576 680 size_t cx_strsplit_ma(
universe@693 681 CxAllocator const *allocator,
universe@576 682 cxmutstr string,
universe@576 683 cxstring delim,
universe@576 684 size_t limit,
universe@576 685 cxmutstr **output
universe@576 686 );
universe@576 687
universe@576 688 /**
universe@576 689 * Compares two strings.
universe@576 690 *
universe@576 691 * @param s1 the first string
universe@576 692 * @param s2 the second string
universe@576 693 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
universe@576 694 * than \p s2, zero if both strings equal
universe@576 695 */
universe@576 696 __attribute__((__warn_unused_result__))
universe@576 697 int cx_strcmp(
universe@576 698 cxstring s1,
universe@576 699 cxstring s2
universe@576 700 );
universe@576 701
universe@576 702 /**
universe@576 703 * Compares two strings ignoring case.
universe@576 704 *
universe@576 705 * @param s1 the first string
universe@576 706 * @param s2 the second string
universe@576 707 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
universe@576 708 * than \p s2, zero if both strings equal ignoring case
universe@576 709 */
universe@576 710 __attribute__((__warn_unused_result__))
universe@576 711 int cx_strcasecmp(
universe@576 712 cxstring s1,
universe@576 713 cxstring s2
universe@576 714 );
universe@576 715
universe@657 716 /**
universe@657 717 * Compares two strings.
universe@657 718 *
universe@677 719 * This function has a compatible signature for the use as a cx_compare_func.
universe@657 720 *
universe@657 721 * @param s1 the first string
universe@657 722 * @param s2 the second string
universe@657 723 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
universe@657 724 * than \p s2, zero if both strings equal
universe@657 725 */
universe@657 726 __attribute__((__warn_unused_result__, __nonnull__))
universe@657 727 int cx_strcmp_p(
universe@657 728 void const *s1,
universe@657 729 void const *s2
universe@657 730 );
universe@657 731
universe@657 732 /**
universe@657 733 * Compares two strings ignoring case.
universe@657 734 *
universe@677 735 * This function has a compatible signature for the use as a cx_compare_func.
universe@657 736 *
universe@657 737 * @param s1 the first string
universe@657 738 * @param s2 the second string
universe@657 739 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
universe@657 740 * than \p s2, zero if both strings equal ignoring case
universe@657 741 */
universe@657 742 __attribute__((__warn_unused_result__, __nonnull__))
universe@657 743 int cx_strcasecmp_p(
universe@657 744 void const *s1,
universe@657 745 void const *s2
universe@657 746 );
universe@657 747
universe@576 748
universe@576 749 /**
universe@576 750 * Creates a duplicate of the specified string.
universe@576 751 *
universe@576 752 * The new string will contain a copy allocated by \p allocator.
universe@576 753 *
universe@589 754 * \note The returned string is guaranteed to be zero-terminated.
universe@576 755 *
universe@576 756 * @param allocator the allocator to use
universe@576 757 * @param string the string to duplicate
universe@576 758 * @return a duplicate of the string
universe@576 759 * @see cx_strdup()
universe@576 760 */
universe@576 761 __attribute__((__warn_unused_result__, __nonnull__))
universe@576 762 cxmutstr cx_strdup_a(
universe@693 763 CxAllocator const *allocator,
universe@576 764 cxstring string
universe@576 765 );
universe@576 766
universe@576 767 /**
universe@578 768 * Creates a duplicate of the specified string.
universe@578 769 *
universe@578 770 * The new string will contain a copy allocated by standard
universe@578 771 * \c malloc(). So developers \em must pass the return value to cx_strfree().
universe@578 772 *
universe@589 773 * \note The returned string is guaranteed to be zero-terminated.
universe@578 774 *
universe@578 775 * @param string the string to duplicate
universe@578 776 * @return a duplicate of the string
universe@578 777 * @see cx_strdup_a()
universe@578 778 */
universe@578 779 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
universe@578 780
universe@700 781
universe@700 782 /**
universe@700 783 * Creates a duplicate of the specified string.
universe@700 784 *
universe@700 785 * The new string will contain a copy allocated by \p allocator.
universe@700 786 *
universe@700 787 * \note The returned string is guaranteed to be zero-terminated.
universe@700 788 *
universe@700 789 * @param allocator the allocator to use
universe@700 790 * @param string the string to duplicate
universe@700 791 * @return a duplicate of the string
universe@700 792 * @see cx_strdup_m()
universe@700 793 */
universe@700 794 #define cx_strdup_ma(allocator, string) cx_strdup_a(allocator, cx_strcast(string))
universe@700 795
universe@700 796 /**
universe@700 797 * Creates a duplicate of the specified string.
universe@700 798 *
universe@700 799 * The new string will contain a copy allocated by standard
universe@700 800 * \c malloc(). So developers \em must pass the return value to cx_strfree().
universe@700 801 *
universe@700 802 * \note The returned string is guaranteed to be zero-terminated.
universe@700 803 *
universe@700 804 * @param string the string to duplicate
universe@700 805 * @return a duplicate of the string
universe@700 806 * @see cx_strdup_ma()
universe@700 807 */
universe@700 808 #define cx_strdup_m(string) cx_strdup_a(cxDefaultAllocator, cx_strcast(string))
universe@700 809
universe@578 810 /**
universe@576 811 * Omits leading and trailing spaces.
universe@576 812 *
universe@576 813 * \note the returned string references the same memory, thus you
universe@576 814 * must \em not free the returned memory.
universe@576 815 *
universe@576 816 * @param string the string that shall be trimmed
universe@576 817 * @return the trimmed string
universe@576 818 */
universe@576 819 __attribute__((__warn_unused_result__))
universe@576 820 cxstring cx_strtrim(cxstring string);
universe@576 821
universe@576 822 /**
universe@576 823 * Omits leading and trailing spaces.
universe@576 824 *
universe@576 825 * \note the returned string references the same memory, thus you
universe@576 826 * must \em not free the returned memory.
universe@576 827 *
universe@576 828 * @param string the string that shall be trimmed
universe@576 829 * @return the trimmed string
universe@576 830 */
universe@576 831 __attribute__((__warn_unused_result__))
universe@576 832 cxmutstr cx_strtrim_m(cxmutstr string);
universe@576 833
universe@576 834 /**
universe@576 835 * Checks, if a string has a specific prefix.
universe@576 836 *
universe@576 837 * @param string the string to check
universe@576 838 * @param prefix the prefix the string should have
universe@576 839 * @return \c true, if and only if the string has the specified prefix,
universe@576 840 * \c false otherwise
universe@576 841 */
universe@576 842 __attribute__((__warn_unused_result__))
universe@576 843 bool cx_strprefix(
universe@576 844 cxstring string,
universe@576 845 cxstring prefix
universe@576 846 );
universe@576 847
universe@576 848 /**
universe@576 849 * Checks, if a string has a specific suffix.
universe@576 850 *
universe@576 851 * @param string the string to check
universe@576 852 * @param suffix the suffix the string should have
universe@576 853 * @return \c true, if and only if the string has the specified suffix,
universe@576 854 * \c false otherwise
universe@576 855 */
universe@576 856 __attribute__((__warn_unused_result__))
universe@581 857 bool cx_strsuffix(
universe@576 858 cxstring string,
universe@576 859 cxstring suffix
universe@576 860 );
universe@576 861
universe@576 862 /**
universe@576 863 * Checks, if a string has a specific prefix, ignoring the case.
universe@576 864 *
universe@576 865 * @param string the string to check
universe@576 866 * @param prefix the prefix the string should have
universe@576 867 * @return \c true, if and only if the string has the specified prefix,
universe@576 868 * \c false otherwise
universe@576 869 */
universe@576 870 __attribute__((__warn_unused_result__))
universe@581 871 bool cx_strcaseprefix(
universe@576 872 cxstring string,
universe@576 873 cxstring prefix
universe@576 874 );
universe@576 875
universe@576 876 /**
universe@576 877 * Checks, if a string has a specific suffix, ignoring the case.
universe@576 878 *
universe@576 879 * @param string the string to check
universe@576 880 * @param suffix the suffix the string should have
universe@576 881 * @return \c true, if and only if the string has the specified suffix,
universe@576 882 * \c false otherwise
universe@576 883 */
universe@576 884 __attribute__((__warn_unused_result__))
universe@581 885 bool cx_strcasesuffix(
universe@576 886 cxstring string,
universe@576 887 cxstring suffix
universe@576 888 );
universe@576 889
universe@576 890 /**
universe@576 891 * Converts the string to lower case.
universe@576 892 *
universe@576 893 * The change is made in-place. If you want a copy, use cx_strdup(), first.
universe@576 894 *
universe@576 895 * @param string the string to modify
universe@576 896 * @see cx_strdup()
universe@576 897 */
universe@576 898 void cx_strlower(cxmutstr string);
universe@576 899
universe@576 900 /**
universe@576 901 * Converts the string to upper case.
universe@576 902 *
universe@576 903 * The change is made in-place. If you want a copy, use cx_strdup(), first.
universe@576 904 *
universe@576 905 * @param string the string to modify
universe@576 906 * @see cx_strdup()
universe@576 907 */
universe@576 908 void cx_strupper(cxmutstr string);
universe@576 909
universe@576 910 /**
universe@576 911 * Replaces a pattern in a string with another string.
universe@576 912 *
universe@576 913 * The pattern is taken literally and is no regular expression.
universe@576 914 * Replaces at most \p replmax occurrences.
universe@576 915 *
universe@589 916 * The returned string will be allocated by \p allocator and is guaranteed
universe@589 917 * to be zero-terminated.
universe@576 918 *
universe@576 919 * If allocation fails, or the input string is empty,
universe@583 920 * the returned string will be empty.
universe@576 921 *
universe@576 922 * @param allocator the allocator to use
universe@576 923 * @param str the string where replacements should be applied
universe@576 924 * @param pattern the pattern to search for
universe@576 925 * @param replacement the replacement string
universe@576 926 * @param replmax maximum number of replacements
universe@576 927 * @return the resulting string after applying the replacements
universe@576 928 */
universe@576 929 __attribute__((__warn_unused_result__, __nonnull__))
universe@583 930 cxmutstr cx_strreplacen_a(
universe@693 931 CxAllocator const *allocator,
universe@576 932 cxstring str,
universe@576 933 cxstring pattern,
universe@576 934 cxstring replacement,
universe@576 935 size_t replmax
universe@576 936 );
universe@576 937
universe@578 938 /**
universe@578 939 * Replaces a pattern in a string with another string.
universe@578 940 *
universe@578 941 * The pattern is taken literally and is no regular expression.
universe@578 942 * Replaces at most \p replmax occurrences.
universe@578 943 *
universe@589 944 * The returned string will be allocated by \c malloc() and is guaranteed
universe@589 945 * to be zero-terminated.
universe@578 946 *
universe@578 947 * If allocation fails, or the input string is empty,
universe@583 948 * the returned string will be empty.
universe@578 949 *
universe@578 950 * @param str the string where replacements should be applied
universe@578 951 * @param pattern the pattern to search for
universe@578 952 * @param replacement the replacement string
universe@578 953 * @param replmax maximum number of replacements
universe@578 954 * @return the resulting string after applying the replacements
universe@578 955 */
universe@583 956 #define cx_strreplacen(str, pattern, replacement, replmax) \
universe@583 957 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
universe@583 958
universe@583 959 /**
universe@583 960 * Replaces a pattern in a string with another string.
universe@583 961 *
universe@583 962 * The pattern is taken literally and is no regular expression.
universe@583 963 *
universe@589 964 * The returned string will be allocated by \p allocator and is guaranteed
universe@589 965 * to be zero-terminated.
universe@583 966 *
universe@583 967 * If allocation fails, or the input string is empty,
universe@583 968 * the returned string will be empty.
universe@583 969 *
universe@583 970 * @param allocator the allocator to use
universe@583 971 * @param str the string where replacements should be applied
universe@583 972 * @param pattern the pattern to search for
universe@583 973 * @param replacement the replacement string
universe@583 974 * @return the resulting string after applying the replacements
universe@583 975 */
universe@583 976 #define cx_strreplace_a(allocator, str, pattern, replacement) \
universe@583 977 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
universe@583 978
universe@583 979 /**
universe@583 980 * Replaces a pattern in a string with another string.
universe@583 981 *
universe@583 982 * The pattern is taken literally and is no regular expression.
universe@583 983 * Replaces at most \p replmax occurrences.
universe@583 984 *
universe@589 985 * The returned string will be allocated by \c malloc() and is guaranteed
universe@589 986 * to be zero-terminated.
universe@583 987 *
universe@583 988 * If allocation fails, or the input string is empty,
universe@583 989 * the returned string will be empty.
universe@583 990 *
universe@583 991 * @param str the string where replacements should be applied
universe@583 992 * @param pattern the pattern to search for
universe@583 993 * @param replacement the replacement string
universe@583 994 * @return the resulting string after applying the replacements
universe@583 995 */
universe@583 996 #define cx_strreplace(str, pattern, replacement) \
universe@583 997 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
universe@578 998
universe@645 999 /**
universe@645 1000 * Creates a string tokenization context.
universe@645 1001 *
universe@645 1002 * @param str the string to tokenize
universe@645 1003 * @param delim the delimiter (must not be empty)
universe@645 1004 * @param limit the maximum number of tokens that shall be returned
universe@645 1005 * @return a new string tokenization context
universe@645 1006 */
universe@645 1007 __attribute__((__warn_unused_result__))
universe@645 1008 CxStrtokCtx cx_strtok(
universe@645 1009 cxstring str,
universe@645 1010 cxstring delim,
universe@645 1011 size_t limit
universe@645 1012 );
universe@645 1013
universe@645 1014 /**
universe@645 1015 * Creates a string tokenization context for a mutable string.
universe@645 1016 *
universe@645 1017 * @param str the string to tokenize
universe@645 1018 * @param delim the delimiter (must not be empty)
universe@645 1019 * @param limit the maximum number of tokens that shall be returned
universe@645 1020 * @return a new string tokenization context
universe@645 1021 */
universe@645 1022 __attribute__((__warn_unused_result__))
universe@645 1023 CxStrtokCtx cx_strtok_m(
universe@645 1024 cxmutstr str,
universe@645 1025 cxstring delim,
universe@645 1026 size_t limit
universe@645 1027 );
universe@645 1028
universe@645 1029 /**
universe@645 1030 * Returns the next token.
universe@645 1031 *
universe@645 1032 * The token will point to the source string.
universe@645 1033 *
universe@645 1034 * @param ctx the tokenization context
universe@645 1035 * @param token a pointer to memory where the next token shall be stored
universe@645 1036 * @return true if successful, false if the limit or the end of the string
universe@645 1037 * has been reached
universe@645 1038 */
universe@645 1039 __attribute__((__warn_unused_result__, __nonnull__))
universe@645 1040 bool cx_strtok_next(
universe@645 1041 CxStrtokCtx *ctx,
universe@645 1042 cxstring *token
universe@645 1043 );
universe@645 1044
universe@645 1045 /**
universe@645 1046 * Returns the next token of a mutable string.
universe@645 1047 *
universe@645 1048 * The token will point to the source string.
universe@645 1049 * If the context was not initialized over a mutable string, modifying
universe@645 1050 * the data of the returned token is undefined behavior.
universe@645 1051 *
universe@645 1052 * @param ctx the tokenization context
universe@645 1053 * @param token a pointer to memory where the next token shall be stored
universe@645 1054 * @return true if successful, false if the limit or the end of the string
universe@645 1055 * has been reached
universe@645 1056 */
universe@645 1057 __attribute__((__warn_unused_result__, __nonnull__))
universe@645 1058 bool cx_strtok_next_m(
universe@645 1059 CxStrtokCtx *ctx,
universe@645 1060 cxmutstr *token
universe@645 1061 );
universe@645 1062
universe@645 1063 /**
universe@645 1064 * Defines an array of more delimiters for the specified tokenization context.
universe@645 1065 *
universe@645 1066 * @param ctx the tokenization context
universe@645 1067 * @param delim array of more delimiters
universe@645 1068 * @param count number of elements in the array
universe@645 1069 */
universe@645 1070 __attribute__((__nonnull__))
universe@645 1071 void cx_strtok_delim(
universe@645 1072 CxStrtokCtx *ctx,
universe@645 1073 cxstring const *delim,
universe@645 1074 size_t count
universe@645 1075 );
universe@645 1076
universe@645 1077
universe@576 1078 #ifdef __cplusplus
universe@576 1079 } // extern "C"
universe@576 1080 #endif
universe@576 1081
universe@576 1082 #endif //UCX_STRING_H

mercurial