src/cx/string.h

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

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

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

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

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

mercurial