src/cx/string.h

Mon, 24 Apr 2023 19:08:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 24 Apr 2023 19:08:56 +0200
changeset 701
72a440c437e9
parent 700
72dccb560084
child 759
475335643af4
permissions
-rw-r--r--

explicitly set cmake policy CMP0077

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

mercurial