src/cx/string.h

Mon, 18 Dec 2023 14:14:47 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 18 Dec 2023 14:14:47 +0100
changeset 759
475335643af4
parent 700
72dccb560084
child 806
e06249e09f99
permissions
-rw-r--r--

increase version number to 3.1

remove per-file version information
from Doxygen output

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

mercurial