src/cx/string.h

Sat, 22 Apr 2023 12:29:00 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 22 Apr 2023 12:29:00 +0200
changeset 696
1ba4ec2e7a89
parent 693
494d9b20b99e
child 697
ebdce4bf262b
permissions
-rw-r--r--

add cxHashMapCreateSimple()

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

mercurial