src/cx/string.h

Fri, 09 Sep 2022 20:19:08 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 09 Sep 2022 20:19:08 +0200
changeset 583
0f3c9662f9b5
parent 581
c067394737ca
child 584
184e9ebfc3cc
permissions
-rw-r--r--

add tests and missing implementations for strings

     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  * A literal initializer for an UCX string structure.
    83  *
    84  * The argument MUST be a string (const char*) \em literal.
    85  *
    86  * @param literal the string literal
    87  */
    88 #define CX_STR(literal) {literal, sizeof(literal) - 1}
    90 #ifdef __cplusplus
    91 extern "C" {
    92 #endif
    95 /**
    96  * Wraps a mutable string that must be zero-terminated.
    97  *
    98  * The length is implicitly inferred by using a call to \c strlen().
    99  * As a special case, a \c NULL argument is treated like an empty string.
   100  *
   101  * \note the wrapped string will share the specified pointer to the string.
   102  * If you do want a copy, use cx_strdup() on the return value of this function.
   103  *
   104  * If you need to wrap a constant string, use cx_str().
   105  *
   106  * @param cstring the string to wrap, must be zero-terminated (or \c NULL)
   107  * @return the wrapped string
   108  *
   109  * @see cx_mutstrn()
   110  */
   111 __attribute__((__warn_unused_result__))
   112 cxmutstr cx_mutstr(char *cstring);
   114 /**
   115  * Wraps a string that does not need to be zero-terminated.
   116  *
   117  * The argument may be \c NULL if the length is zero.
   118  *
   119  * \note the wrapped string will share the specified pointer to the string.
   120  * If you do want a copy, use cx_strdup() on the return value of this function.
   121  *
   122  * If you need to wrap a constant string, use cx_strn().
   123  *
   124  * @param cstring  the string to wrap (or \c NULL, if the length is zero)
   125  * @param length   the length of the string
   126  * @return the wrapped string
   127  *
   128  * @see cx_mutstr()
   129  */
   130 __attribute__((__warn_unused_result__))
   131 cxmutstr cx_mutstrn(
   132         char *cstring,
   133         size_t length
   134 );
   136 /**
   137  * Wraps a string that must be zero-terminated.
   138  *
   139  * The length is implicitly inferred by using a call to \c strlen().
   140  * As a special case, a \c NULL argument is treated like an empty string.
   141  *
   142  * \note the wrapped string will share the specified pointer to the string.
   143  * If you do want a copy, use cx_strdup() on the return value of this function.
   144  *
   145  * If you need to wrap a non-constant string, use cx_mutstr().
   146  *
   147  * @param cstring the string to wrap, must be zero-terminated (or \c NULL)
   148  * @return the wrapped string
   149  *
   150  * @see cx_strn()
   151  */
   152 __attribute__((__warn_unused_result__))
   153 cxstring cx_str(char const *cstring);
   156 /**
   157  * Wraps a string that does not need to be zero-terminated.
   158  *
   159  * The argument may be \c NULL if the length is zero.
   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 non-constant string, use cx_mutstrn().
   165  *
   166  * @param cstring  the string to wrap (or \c NULL, if the length is zero)
   167  * @param length   the length of the string
   168  * @return the wrapped string
   169  *
   170  * @see cx_str()
   171  */
   172 __attribute__((__warn_unused_result__))
   173 cxstring cx_strn(
   174         char const *cstring,
   175         size_t length
   176 );
   178 /**
   179 * Casts a mutable string to an immutable string.
   180 *
   181 * \note This is not seriously a cast. Instead you get a copy
   182 * of the struct with the desired pointer type. Both structs still
   183 * point to the same location, though!
   184 *
   185 * @param str the mutable string to cast
   186 * @return an immutable copy of the string pointer
   187 */
   188 __attribute__((__warn_unused_result__))
   189 cxstring cx_strcast(cxmutstr str);
   191 /**
   192  * Passes the pointer in this string to \c free().
   193  *
   194  * The pointer in the struct is set to \c NULL and the length is set to zero.
   195  *
   196  * \note There is no implementation for cxstring, because it is unlikely that
   197  * you ever have a \c char \c const* you are really supposed to free. If you
   198  * encounter such situation, you should double-check your code.
   199  *
   200  * @param str the string to free
   201  */
   202 __attribute__((__nonnull__))
   203 void cx_strfree(cxmutstr *str);
   205 /**
   206  * Passes the pointer in this string to the allocators free function.
   207  *
   208  * The pointer in the struct is set to \c NULL and the length is set to zero.
   209  *
   210  * \note There is no implementation for cxstring, because it is unlikely that
   211  * you ever have a \c char \c const* you are really supposed to free. If you
   212  * encounter such situation, you should double-check your code.
   213  *
   214  * @param alloc the allocator
   215  * @param str the string to free
   216  */
   217 __attribute__((__nonnull__))
   218 void cx_strfree_a(
   219         CxAllocator *alloc,
   220         cxmutstr *str
   221 );
   223 /**
   224  * Returns the accumulated length of all specified strings.
   225  *
   226  * \attention if the count argument is larger than the number of the
   227  * specified strings, the behavior is undefined.
   228  *
   229  * @param count    the total number of specified strings
   230  * @param ...      all strings
   231  * @return the accumulated length of all strings
   232  */
   233 __attribute__((__warn_unused_result__))
   234 size_t cx_strlen(
   235         size_t count,
   236         ...
   237 );
   239 /**
   240  * Concatenates two or more strings.
   241  *
   242  * The resulting string will be allocated by the specified allocator.
   243   * So developers \em must pass the return value to cx_strfree() eventually.
   244   *
   245   * \note It is guaranteed that there is only one allocation.
   246  *
   247  * @param alloc the allocator to use
   248  * @param count   the total number of strings to concatenate
   249  * @param ...     all strings
   250  * @return the concatenated string
   251  */
   252 __attribute__((__warn_unused_result__, __nonnull__))
   253 cxmutstr cx_strcat_a(
   254         CxAllocator *alloc,
   255         size_t count,
   256         ...
   257 );
   259 /**
   260  * Concatenates two or more strings.
   261  *
   262  * The resulting string will be allocated by standard \c malloc().
   263  * So developers \em must pass the return value to cx_strfree() eventually.
   264  *
   265  * @param count   the total number of strings to concatenate
   266  * @param ...     all strings
   267  * @return the concatenated string
   268  */
   269 #define cx_strcat(count, ...) \
   270 cx_strcat_a(cxDefaultAllocator, count, __VA_ARGS__)
   272 /**
   273  * Returns a substring starting at the specified location.
   274  *
   275  * \attention the new string references the same memory area as the
   276  * input string and is usually \em not zero-terminated.
   277  * Use cx_strdup() to get a copy.
   278  *
   279  * @param string input string
   280  * @param start  start location of the substring
   281  * @return a substring of \p string starting at \p start
   282  *
   283  * @see cx_strsubsl()
   284  * @see cx_strsubs_m()
   285  * @see cx_strsubsl_m()
   286  */
   287 __attribute__((__warn_unused_result__))
   288 cxstring cx_strsubs(
   289         cxstring string,
   290         size_t start
   291 );
   293 /**
   294  * Returns a substring starting at the specified location.
   295  *
   296  * The returned string will be limited to \p length bytes or the number
   297  * of bytes available in \p string, whichever is smaller.
   298  *
   299  * \attention the new string references the same memory area as the
   300  * input string and is usually \em not zero-terminated.
   301  * Use cx_strdup() to get a copy.
   302  *
   303  * @param string input string
   304  * @param start  start location of the substring
   305  * @param length the maximum length of the returned string
   306  * @return a substring of \p string starting at \p start
   307  *
   308  * @see cx_strsubs()
   309  * @see cx_strsubs_m()
   310  * @see cx_strsubsl_m()
   311  */
   312 __attribute__((__warn_unused_result__))
   313 cxstring cx_strsubsl(
   314         cxstring string,
   315         size_t start,
   316         size_t length
   317 );
   319 /**
   320  * Returns a substring starting at the specified location.
   321  *
   322  * \attention the new string references the same memory area as the
   323  * input string and is usually \em not zero-terminated.
   324  * Use cx_strdup() to get a copy.
   325  *
   326  * @param string input string
   327  * @param start  start location of the substring
   328  * @return a substring of \p string starting at \p start
   329  *
   330  * @see cx_strsubsl_m()
   331  * @see cx_strsubs()
   332  * @see cx_strsubsl()
   333  */
   334 __attribute__((__warn_unused_result__))
   335 cxmutstr cx_strsubs_m(
   336         cxmutstr string,
   337         size_t start
   338 );
   340 /**
   341  * Returns a substring starting at the specified location.
   342  *
   343  * The returned string will be limited to \p length bytes or the number
   344  * of bytes available in \p string, whichever is smaller.
   345  *
   346  * \attention the new string references the same memory area as the
   347  * input string and is usually \em not zero-terminated.
   348  * Use cx_strdup() to get a copy.
   349  *
   350  * @param string input string
   351  * @param start  start location of the substring
   352  * @param length the maximum length of the returned string
   353  * @return a substring of \p string starting at \p start
   354  *
   355  * @see cx_strsubs_m()
   356  * @see cx_strsubs()
   357  * @see cx_strsubsl()
   358  */
   359 __attribute__((__warn_unused_result__))
   360 cxmutstr cx_strsubsl_m(
   361         cxmutstr string,
   362         size_t start,
   363         size_t length
   364 );
   366 /**
   367  * Returns a substring starting at the location of the first occurrence of the
   368  * specified character.
   369  *
   370  * If the string does not contain the character, an empty string is returned.
   371  *
   372  * @param string the string where to locate the character
   373  * @param chr    the character to locate
   374  * @return       a substring starting at the first location of \p chr
   375  *
   376  * @see cx_strchr_m()
   377  */
   378 __attribute__((__warn_unused_result__))
   379 cxstring cx_strchr(
   380         cxstring string,
   381         int chr
   382 );
   384 /**
   385  * Returns a substring starting at the location of the first occurrence of the
   386  * specified character.
   387  *
   388  * If the string does not contain the character, an empty string is returned.
   389  *
   390  * @param string the string where to locate the character
   391  * @param chr    the character to locate
   392  * @return       a substring starting at the first location of \p chr
   393  *
   394  * @see cx_strchr()
   395  */
   396 __attribute__((__warn_unused_result__))
   397 cxmutstr cx_strchr_m(
   398         cxmutstr string,
   399         int chr
   400 );
   402 /**
   403  * Returns a substring starting at the location of the last occurrence of the
   404  * specified character.
   405  *
   406  * If the string does not contain the character, an empty string is returned.
   407  *
   408  * @param string the string where to locate the character
   409  * @param chr    the character to locate
   410  * @return       a substring starting at the last location of \p chr
   411  *
   412  * @see cx_strrchr_m()
   413  */
   414 __attribute__((__warn_unused_result__))
   415 cxstring cx_strrchr(
   416         cxstring string,
   417         int chr
   418 );
   420 /**
   421  * Returns a substring starting at the location of the last occurrence of the
   422  * specified character.
   423  *
   424  * If the string does not contain the character, an empty string is returned.
   425  *
   426  * @param string the string where to locate the character
   427  * @param chr    the character to locate
   428  * @return       a substring starting at the last location of \p chr
   429  *
   430  * @see cx_strrchr()
   431  */
   432 __attribute__((__warn_unused_result__))
   433 cxmutstr cx_strrchr_m(
   434         cxmutstr string,
   435         int chr
   436 );
   438 /**
   439  * Returns a substring starting at the location of the first occurrence of the
   440  * specified string.
   441  *
   442  * If \p haystack does not contain \p needle, an empty string is returned.
   443  *
   444  * If \p needle is an empty string, the complete \p haystack is
   445  * returned.
   446  *
   447  * @param haystack the string to be scanned
   448  * @param needle  string containing the sequence of characters to match
   449  * @return       a substring starting at the first occurrence of
   450  *               \p needle, or an empty string, if the sequence is not
   451  *               contained
   452  * @see cx_strstr_m()
   453  */
   454 __attribute__((__warn_unused_result__))
   455 cxstring cx_strstr(
   456         cxstring haystack,
   457         cxstring needle
   458 );
   460 /**
   461  * Returns a substring starting at the location of the first occurrence of the
   462  * specified string.
   463  *
   464  * If \p haystack does not contain \p needle, an empty string is returned.
   465  *
   466  * If \p needle is an empty string, the complete \p haystack is
   467  * returned.
   468  *
   469  * @param haystack the string to be scanned
   470  * @param needle  string containing the sequence of characters to match
   471  * @return       a substring starting at the first occurrence of
   472  *               \p needle, or an empty string, if the sequence is not
   473  *               contained
   474  * @see cx_strstr()
   475  */
   476 __attribute__((__warn_unused_result__))
   477 cxmutstr cx_strstr_m(
   478         cxmutstr haystack,
   479         cxstring needle
   480 );
   482 /**
   483  * Splits a given string using a delimiter string.
   484  *
   485  * \note The resulting array contains strings that point to the source
   486  * \p string. Use cx_strdup() to get copies.
   487  *
   488  * @param string the string to split
   489  * @param delim  the delimiter
   490  * @param limit the maximum number of split items
   491  * @param output a pre-allocated array of at least \p limit length
   492  * @return the actual number of split items
   493  */
   494 __attribute__((__warn_unused_result__, __nonnull__))
   495 size_t cx_strsplit(
   496         cxstring string,
   497         cxstring delim,
   498         size_t limit,
   499         cxstring *output
   500 );
   502 /**
   503  * Splits a given string using a delimiter string.
   504  *
   505  * The array pointed to by \p output will be allocated by \p allocator.
   506  *
   507  * \note The resulting array contains strings that point to the source
   508  * \p string. Use cx_strdup() to get copies.
   509  *
   510  * \attention If allocation fails, the \c NULL pointer will be written to
   511  * \p output and the number returned will be zero.
   512  *
   513  * @param allocator the allocator to use for allocating the resulting array
   514  * @param string the string to split
   515  * @param delim  the delimiter
   516  * @param limit the maximum number of split items
   517  * @param output a pointer where the address of the allocated array shall be
   518  * written to
   519  * @return the actual number of split items
   520  */
   521 __attribute__((__warn_unused_result__, __nonnull__))
   522 size_t cx_strsplit_a(
   523         CxAllocator *allocator,
   524         cxstring string,
   525         cxstring delim,
   526         size_t limit,
   527         cxstring **output
   528 );
   531 /**
   532  * Splits a given string using a delimiter string.
   533  *
   534  * \note The resulting array contains strings that point to the source
   535  * \p string. Use cx_strdup() to get copies.
   536  *
   537  * @param string the string to split
   538  * @param delim  the delimiter
   539  * @param limit the maximum number of split items
   540  * @param output a pre-allocated array of at least \p limit length
   541  * @return the actual number of split items
   542  */
   543 __attribute__((__warn_unused_result__, __nonnull__))
   544 size_t cx_strsplit_m(
   545         cxmutstr string,
   546         cxstring delim,
   547         size_t limit,
   548         cxmutstr *output
   549 );
   551 /**
   552  * Splits a given string using a delimiter string.
   553  *
   554  * The array pointed to by \p output will be allocated by \p allocator.
   555  *
   556  * \note The resulting array contains strings that point to the source
   557  * \p string. Use cx_strdup() to get copies.
   558  *
   559  * \attention If allocation fails, the \c NULL pointer will be written to
   560  * \p output and the number returned will be zero.
   561  *
   562  * @param allocator the allocator to use for allocating the resulting array
   563  * @param string the string to split
   564  * @param delim  the delimiter
   565  * @param limit the maximum number of split items
   566  * @param output a pointer where the address of the allocated array shall be
   567  * written to
   568  * @return the actual number of split items
   569  */
   570 __attribute__((__warn_unused_result__, __nonnull__))
   571 size_t cx_strsplit_ma(
   572         CxAllocator *allocator,
   573         cxmutstr string,
   574         cxstring delim,
   575         size_t limit,
   576         cxmutstr **output
   577 );
   579 /**
   580  * Compares two strings.
   581  *
   582  * @param s1 the first string
   583  * @param s2 the second string
   584  * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
   585  * than \p s2, zero if both strings equal
   586  */
   587 __attribute__((__warn_unused_result__))
   588 int cx_strcmp(
   589         cxstring s1,
   590         cxstring s2
   591 );
   593 /**
   594  * Compares two strings ignoring case.
   595  *
   596  * @param s1 the first string
   597  * @param s2 the second string
   598  * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
   599  * than \p s2, zero if both strings equal ignoring case
   600  */
   601 __attribute__((__warn_unused_result__))
   602 int cx_strcasecmp(
   603         cxstring s1,
   604         cxstring s2
   605 );
   608 /**
   609  * Creates a duplicate of the specified string.
   610  *
   611  * The new string will contain a copy allocated by \p allocator.
   612  *
   613  * \note The returned string is guaranteed to be zero-terminated and can safely
   614  * be passed to other APIs.
   615  *
   616  * @param allocator the allocator to use
   617  * @param string the string to duplicate
   618  * @return a duplicate of the string
   619  * @see cx_strdup()
   620  */
   621 __attribute__((__warn_unused_result__, __nonnull__))
   622 cxmutstr cx_strdup_a(
   623         CxAllocator *allocator,
   624         cxstring string
   625 );
   627 /**
   628  * Creates a duplicate of the specified string.
   629  *
   630  * The new string will contain a copy allocated by standard
   631  * \c malloc(). So developers \em must pass the return value to cx_strfree().
   632  *
   633  * \note The returned string is guaranteed to be zero-terminated and can safely
   634  * be passed to other APIs.
   635  *
   636  * @param string the string to duplicate
   637  * @return a duplicate of the string
   638  * @see cx_strdup_a()
   639  */
   640 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
   642 /**
   643  * Omits leading and trailing spaces.
   644  *
   645  * \note the returned string references the same memory, thus you
   646  * must \em not free the returned memory.
   647  *
   648  * @param string the string that shall be trimmed
   649  * @return the trimmed string
   650  */
   651 __attribute__((__warn_unused_result__))
   652 cxstring cx_strtrim(cxstring string);
   654 /**
   655  * Omits leading and trailing spaces.
   656  *
   657  * \note the returned string references the same memory, thus you
   658  * must \em not free the returned memory.
   659  *
   660  * @param string the string that shall be trimmed
   661  * @return the trimmed string
   662  */
   663 __attribute__((__warn_unused_result__))
   664 cxmutstr cx_strtrim_m(cxmutstr string);
   666 /**
   667  * Checks, if a string has a specific prefix.
   668  *
   669  * @param string the string to check
   670  * @param prefix the prefix the string should have
   671  * @return \c true, if and only if the string has the specified prefix,
   672  * \c false otherwise
   673  */
   674 __attribute__((__warn_unused_result__))
   675 bool cx_strprefix(
   676         cxstring string,
   677         cxstring prefix
   678 );
   680 /**
   681  * Checks, if a string has a specific suffix.
   682  *
   683  * @param string the string to check
   684  * @param suffix the suffix the string should have
   685  * @return \c true, if and only if the string has the specified suffix,
   686  * \c false otherwise
   687  */
   688 __attribute__((__warn_unused_result__))
   689 bool cx_strsuffix(
   690         cxstring string,
   691         cxstring suffix
   692 );
   694 /**
   695  * Checks, if a string has a specific prefix, ignoring the case.
   696  *
   697  * @param string the string to check
   698  * @param prefix the prefix the string should have
   699  * @return \c true, if and only if the string has the specified prefix,
   700  * \c false otherwise
   701  */
   702 __attribute__((__warn_unused_result__))
   703 bool cx_strcaseprefix(
   704         cxstring string,
   705         cxstring prefix
   706 );
   708 /**
   709  * Checks, if a string has a specific suffix, ignoring the case.
   710  *
   711  * @param string the string to check
   712  * @param suffix the suffix the string should have
   713  * @return \c true, if and only if the string has the specified suffix,
   714  * \c false otherwise
   715  */
   716 __attribute__((__warn_unused_result__))
   717 bool cx_strcasesuffix(
   718         cxstring string,
   719         cxstring suffix
   720 );
   722 /**
   723  * Converts the string to lower case.
   724  *
   725  * The change is made in-place. If you want a copy, use cx_strdup(), first.
   726  *
   727  * @param string the string to modify
   728  * @see cx_strdup()
   729  */
   730 void cx_strlower(cxmutstr string);
   732 /**
   733  * Converts the string to upper case.
   734  *
   735  * The change is made in-place. If you want a copy, use cx_strdup(), first.
   736  *
   737  * @param string the string to modify
   738  * @see cx_strdup()
   739  */
   740 void cx_strupper(cxmutstr string);
   742 /**
   743  * Replaces a pattern in a string with another string.
   744  *
   745  * The pattern is taken literally and is no regular expression.
   746  * Replaces at most \p replmax occurrences.
   747  *
   748  * The returned string will be allocated by \p allocator.
   749  *
   750  * If allocation fails, or the input string is empty,
   751  * the returned string will be empty.
   752  *
   753  * @param allocator the allocator to use
   754  * @param str the string where replacements should be applied
   755  * @param pattern the pattern to search for
   756  * @param replacement the replacement string
   757  * @param replmax maximum number of replacements
   758  * @return the resulting string after applying the replacements
   759  */
   760 __attribute__((__warn_unused_result__, __nonnull__))
   761 cxmutstr cx_strreplacen_a(
   762         CxAllocator *allocator,
   763         cxstring str,
   764         cxstring pattern,
   765         cxstring replacement,
   766         size_t replmax
   767 );
   769 /**
   770  * Replaces a pattern in a string with another string.
   771  *
   772  * The pattern is taken literally and is no regular expression.
   773  * Replaces at most \p replmax occurrences.
   774  *
   775  * The returned string will be allocated by \c malloc() and \em must be passed
   776  * to cx_strfree() eventually.
   777  *
   778  * If allocation fails, or the input string is empty,
   779  * the returned string will be empty.
   780  *
   781  * @param str the string where replacements should be applied
   782  * @param pattern the pattern to search for
   783  * @param replacement the replacement string
   784  * @param replmax maximum number of replacements
   785  * @return the resulting string after applying the replacements
   786  */
   787 #define cx_strreplacen(str, pattern, replacement, replmax) \
   788 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
   790 /**
   791  * Replaces a pattern in a string with another string.
   792  *
   793  * The pattern is taken literally and is no regular expression.
   794  *
   795  * The returned string will be allocated by \p allocator.
   796  *
   797  * If allocation fails, or the input string is empty,
   798  * the returned string will be empty.
   799  *
   800  * @param allocator the allocator to use
   801  * @param str the string where replacements should be applied
   802  * @param pattern the pattern to search for
   803  * @param replacement the replacement string
   804  * @return the resulting string after applying the replacements
   805  */
   806 #define cx_strreplace_a(allocator, str, pattern, replacement) \
   807 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
   809 /**
   810  * Replaces a pattern in a string with another string.
   811  *
   812  * The pattern is taken literally and is no regular expression.
   813  * Replaces at most \p replmax occurrences.
   814  *
   815  * The returned string will be allocated by \c malloc() and \em must be passed
   816  * to cx_strfree() eventually.
   817  *
   818  * If allocation fails, or the input string is empty,
   819  * the returned string will be empty.
   820  *
   821  * @param str the string where replacements should be applied
   822  * @param pattern the pattern to search for
   823  * @param replacement the replacement string
   824  * @return the resulting string after applying the replacements
   825  */
   826 #define cx_strreplace(str, pattern, replacement) \
   827 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
   829 #ifdef __cplusplus
   830 } // extern "C"
   831 #endif
   833 #endif //UCX_STRING_H

mercurial