|
CX Framework
Cross-platform C utility framework
|
Macros | |
| #define | strNConcat(o, ...) _strNConcat(o, count_macro_args(__VA_ARGS__), (strref[]) { __VA_ARGS__ }) |
| #define | strNConcatC(o, ...) _strNConcatC(o, count_macro_args(__VA_ARGS__), (string*[]) { __VA_ARGS__ }) |
Functions | |
| bool | strAppend (strhandle io, strref s) |
| bool | strAppendBytes (strhandle io, _In_reads_bytes_opt_(sz) const void *buf, uint32 sz) |
| void | strAppendChar (strhandle io, uint8 ch) |
| bool | strPrepend (strref s, strhandle io) |
| bool | strRepeat (strhandle o, strref s, uint32 n) |
| bool | strFillChar (strhandle o, uint8 ch, uint32 n) |
| bool | strConcat (strhandle o, strref s1, strref s2) |
| bool | strConcatC (strhandle o, strhandle sc1, strhandle sc2) |
| bool | strSubStr (strhandle o, strref s, int32 b, int32 e) |
| bool | strSubStrC (strhandle o, strhandle sc, int32 b, int32 e) |
| bool | strSubStrI (strhandle io, int32 b, int32 e) |
| bool | strTrim (strhandle o, strref s, strref chars) |
| bool | strLTrim (strhandle o, strref s, strref chars) |
| bool | strRTrim (strhandle o, strref s, strref chars) |
| bool | strReplaceChar (strhandle o, strref s, char from, char to) |
| bool | strReplaceChari (strhandle o, strref s, char from, char to) |
| bool | strReplace (strhandle o, strref s, strref find, strref repl, int32 max) |
| bool | strReplacei (strhandle o, strref s, strref find, strref repl, int32 max) |
| bool | strInsert (strhandle o, strref s, int32 off, strref ins) |
| bool | strErase (strhandle o, strref s, int32 b, int32 e) |
| void | strUpper (strhandle io) |
| void | strLower (strhandle io) |
| int32 | strSplit (sa_string *out, strref s, strref sep, bool empty) |
| int32 | strSplitAny (sa_string *out, strref s, strref chars, bool empty) |
| int32 | strSplitMax (sa_string *out, strref s, strref sep, bool empty, int32 maxparts) |
| int32 | strSplitAnyMax (sa_string *out, strref s, strref chars, bool empty, int32 maxparts) |
| bool | strSplitNext (strref s, int32 *pos, strref sep, strhandle out) |
| bool | strSplitNextAny (strref s, int32 *pos, strref chars, strhandle out) |
| bool | strJoin (strhandle out, sa_string arr, strref sep) |
| uint8 | strGetChar (strref str, int32 i) |
| void | strSetChar (strhandle str, int32 i, uint8 ch) |
String manipulation operations for modifying, combining, and extracting portions of strings. Many operations have multiple variants optimized for different use cases.
o - Output string; existing content is destroyed and replacedio - Input+output string; modified in-place when possibles* - Input string; read-only, not modifiedsc* - Input string that is consumed; destroyed/reused efficiently, handle set to NULLFunctions ending in 'C' (like strConcatC, strSubStrC) take ownership of their input strings and destroy them after use. This allows for more efficient memory reuse when you no longer need the source strings:
Functions ending in 'I' modify the string in-place, efficiently reusing the existing buffer when possible:
Most functions accept negative indices to count from the end of the string: -1 refers to the last byte, -2 to second-to-last, etc.
For large string operations, the library may use rope data structures internally to avoid copying. This is transparent to the caller but affects performance characteristics - very large concatenations and substrings are much faster.
| #define strNConcat | ( | o, | |
| ... | |||
| ) | _strNConcat(o, count_macro_args(__VA_ARGS__), (strref[]) { __VA_ARGS__ }) |
bool strNConcat(string *o, ...)
Concatenates multiple strings into an output string
Combines any number of strings into a single result. This is more efficient than calling strConcat() repeatedly. For very large results, may create a rope structure.
The macro accepts a variable number of string arguments and automatically counts them.
| o | Output string (existing content destroyed) |
| ... | Variable number of string arguments to concatenate |
Example:
Definition at line 250 of file strmanip.h.
| #define strNConcatC | ( | o, | |
| ... | |||
| ) | _strNConcatC(o, count_macro_args(__VA_ARGS__), (string*[]) { __VA_ARGS__ }) |
bool strNConcatC(string *o, string *s1, string *s2, ...)
Concatenates multiple strings, consuming all inputs
Like strNConcat(), but takes ownership of all input strings and destroys them after use. All input string handles will be NULL after this call. This is the most efficient way to combine many temporary strings.
The macro accepts a variable number of string handle pointers.
| o | Output string (existing content destroyed) |
| ... | Variable number of string handle pointers (destroyed after use) |
Example:
Definition at line 277 of file strmanip.h.
| bool strAppend | ( | strhandle | io, |
| strref | s | ||
| ) |
Appends a string to another string in-place
Adds the content of string s to the end of string io. The operation is performed in-place when possible for efficiency. For large strings, may create a rope structure instead of copying.
If io is NULL or empty, this is equivalent to strDup().
| io | String to append to (modified in-place) |
| s | String to append (not modified) |
Example:
| bool strAppendBytes | ( | strhandle | io, |
| _In_reads_bytes_opt_(sz) const void * | buf, | ||
| uint32 | sz | ||
| ) |
Appends a raw byte buffer to a string in-place
Adds sz bytes from buf to the end of string io. This is binary safe: embedded NUL bytes are preserved and the length comes from sz rather than from strlen(). The result is still NUL terminated.
Because the appended bytes are arbitrary, the cached encoding flags are cleared.
If io is NULL or empty, this is equivalent to strFromBytes().
| io | String to append to (modified in-place) |
| buf | Byte buffer to append (NULL or sz of 0 appends nothing) |
| sz | Number of bytes to append |
Example:
| void strAppendChar | ( | strhandle | io, |
| uint8 | ch | ||
| ) |
Appends a single byte to a string in-place
Adds one byte to the end of the string. This replaces the strSetChar(&s, strEnd, ch) idiom and is somewhat cheaper, since it does not have to resolve the append position.
Note: this operates on bytes, not UTF-8 code points. Appending a byte >= 0x80 clears the cached encoding flags, since a single byte cannot complete a valid UTF-8 sequence on its own.
| io | String to append to (modified in-place) |
| ch | Byte value to append |
Example:
| bool strConcat | ( | strhandle | o, |
| strref | s1, | ||
| strref | s2 | ||
| ) |
Concatenates two strings into an output string
Combines s1 and s2 into a new string stored in o. Any existing content in o is destroyed. For large strings, may create a rope structure for efficiency.
If o points to the same string as s1, this is optimized to behave like strAppend().
| o | Output string (existing content destroyed) |
| s1 | First string (not modified) |
| s2 | Second string (not modified) |
Example:
Concatenates two strings, consuming the inputs
Like strConcat(), but takes ownership of sc1 and sc2, destroying them after use. This allows for more efficient memory reuse when the source strings are no longer needed. Both sc1 and sc2 will be NULL after this call.
| o | Output string (existing content destroyed) |
| sc1 | First string (destroyed after use) |
| sc2 | Second string (destroyed after use) |
Example:
| bool strErase | ( | strhandle | o, |
| strref | s, | ||
| int32 | b, | ||
| int32 | e | ||
| ) |
Removes a range of bytes from a string
Writes s to o with bytes from position b (inclusive) to position e (exclusive) removed. Negative indices count from the end and strEnd means the end of the string, matching strSubStr() — strErase() removes exactly the range that strSubStr() would have kept.
The output handle may be the same as the source, which erases in place.
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| b | Starting position of the range to remove (negative = from end) |
| e | Ending position of the range to remove (negative = from end, strEnd = end) |
Example:
| bool strFillChar | ( | strhandle | o, |
| uint8 | ch, | ||
| uint32 | n | ||
| ) |
Creates a string consisting of a single byte repeated a number of times
Writes n copies of the byte ch to o. A count of 0 produces an empty string. This is the efficient way to build padding or fill runs.
| o | Output string (existing content destroyed) |
| ch | Byte value to fill with |
| n | Number of bytes |
Example:
| uint8 strGetChar | ( | strref | str, |
| int32 | i | ||
| ) |
Retrieves a single byte from a string
Gets the byte at position i in the string. Negative indices count from the end, stopping at the start of the string rather than wrapping around. Returns 0 if the index is out of bounds.
Indices resolve exactly as they do for strSetChar(), so the two are safe to pair up on the same index.
Note: This operates on bytes, not UTF-8 characters. For multi-byte encodings, use a string iterator instead.
| str | String to read from |
| i | Index of byte to retrieve (negative = from end) |
Example:
| bool strInsert | ( | strhandle | o, |
| strref | s, | ||
| int32 | off, | ||
| strref | ins | ||
| ) |
Inserts a string at a byte offset
Writes s to o with 'ins' spliced in at byte offset 'off'. Negative offsets count from the end of the string and strEnd appends, matching strSubStr(). Offsets beyond the end of the string are clamped.
The output handle may be the same as the source, which inserts in place.
Note: this operates on bytes, not UTF-8 code points. Inserting in the middle of a multi-byte sequence produces invalid UTF-8; use strU8Offset() to find a safe offset.
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| off | Byte offset to insert at (negative = from end, strEnd = append) |
| ins | String to insert (NULL or empty leaves the source unchanged) |
Example:
| bool strJoin | ( | strhandle | out, |
| sa_string | arr, | ||
| strref | sep | ||
| ) |
Joins an array of strings into a single string with a separator
Combines all strings in the array into one string, inserting the separator between each element. The separator is not added before the first element or after the last element.
| out | Output string (existing content destroyed) |
| arr | Array of strings to join |
| sep | Separator to insert between elements |
Example:
| void strLower | ( | strhandle | io | ) |
Converts a string to lowercase (ASCII only)
Modifies the string in-place, converting all uppercase ASCII letters (A-Z) to lowercase (a-z). This is ASCII-only and does not properly handle multi-byte UTF-8 characters or locale-specific case rules.
The string is flattened and made unique before modification.
| io | String to convert in-place |
Example:
| bool strLTrim | ( | strhandle | o, |
| strref | s, | ||
| strref | chars | ||
| ) |
Removes leading bytes that are members of a set
Like strTrim(), but only removes bytes from the beginning of the string.
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| chars | Set of bytes to remove (NULL = whitespace) |
Example:
| bool strPrepend | ( | strref | s, |
| strhandle | io | ||
| ) |
Prepends a string to another string in-place
Adds the content of string s to the beginning of string io. This is less efficient than strAppend() because the entire string must be reconstructed.
| s | String to prepend (not modified) |
| io | String to prepend to (modified in-place) |
Example:
| bool strRepeat | ( | strhandle | o, |
| strref | s, | ||
| uint32 | n | ||
| ) |
Creates a string by repeating another string a number of times
Writes n concatenated copies of s to o. A count of 0, or an empty source string, produces an empty string.
The output handle may be the same as the source, in which case the string is replaced by the repeated version:
| o | Output string (existing content destroyed) |
| s | String to repeat (not modified) |
| n | Number of copies |
Example:
| bool strReplace | ( | strhandle | o, |
| strref | s, | ||
| strref | find, | ||
| strref | repl, | ||
| int32 | max | ||
| ) |
Replaces occurrences of a substring with another string
Writes s to o with occurrences of 'find' replaced by 'repl'. The search is non-overlapping and proceeds left to right; the replacement text is never rescanned. An empty or NULL 'find' matches nothing and the source is copied unchanged.
The output handle may be the same as the source, which replaces in place:
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| find | Substring to search for |
| repl | Replacement string (NULL or empty deletes the match) |
| max | Maximum number of replacements, or 0 (or negative) for all |
Example:
| bool strReplaceChar | ( | strhandle | o, |
| strref | s, | ||
| char | from, | ||
| char | to | ||
| ) |
Replaces every occurrence of a byte with another byte
Writes s to o with every occurrence of 'from' replaced by 'to'. Since the length does not change, this is a single pass over the buffer with no searching.
The output handle may be the same as the source, which causes the replacement to be performed in-place.
Note: this operates on bytes, not UTF-8 code points. Replacing a byte >= 0x80 can corrupt a multi-byte sequence, so the cached encoding flags are cleared unless both bytes are ASCII.
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| from | Byte to search for |
| to | Byte to replace it with |
Example:
| bool strReplaceChari | ( | strhandle | o, |
| strref | s, | ||
| char | from, | ||
| char | to | ||
| ) |
Replaces every occurrence of a byte with another byte, ignoring case
Like strReplaceChar(), but matches 'from' case-insensitively (ASCII only). The replacement byte is written exactly as given, so the case of the result comes from 'to' and not from what was matched.
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| from | Byte to search for (matched in either case) |
| to | Byte to replace it with |
Example:
| bool strReplacei | ( | strhandle | o, |
| strref | s, | ||
| strref | find, | ||
| strref | repl, | ||
| int32 | max | ||
| ) |
Replaces occurrences of a substring with another string, ignoring case
Like strReplace(), but matches 'find' case-insensitively (ASCII only).
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| find | Substring to search for (matched without regard to case) |
| repl | Replacement string (NULL or empty deletes the match) |
| max | Maximum number of replacements, or 0 (or negative) for all |
Example:
| bool strRTrim | ( | strhandle | o, |
| strref | s, | ||
| strref | chars | ||
| ) |
Removes trailing bytes that are members of a set
Like strTrim(), but only removes bytes from the end of the string.
| o | Output string (existing content destroyed, may be the same handle as s) |
| s | Source string (not modified) |
| chars | Set of bytes to remove (NULL = whitespace) |
Example:
| void strSetChar | ( | strhandle | str, |
| int32 | i, | ||
| uint8 | ch | ||
| ) |
Sets a single byte in a string
Modifies the byte at position i in the string. Negative indices count from the end, stopping at the start of the string rather than wrapping around. Use strEnd for i to append a byte to the end of the string.
If a positive index is beyond the current length, the string is grown and zero-padded.
Note: This operates on bytes, not UTF-8 characters. Be careful when modifying multi-byte UTF-8 sequences as you can create invalid encodings.
| str | String to modify |
| i | Index of byte to set (negative = from end, strEnd = append) |
| ch | Byte value to set |
Example:
| int32 strSplit | ( | sa_string * | out, |
| strref | s, | ||
| strref | sep, | ||
| bool | empty | ||
| ) |
Splits a string into pieces separated by a delimiter
Divides the string s into segments at each occurrence of the separator string, storing the results in a dynamic array. The output array is cleared first.
| out | Pointer to string array to store results (cleared first) |
| s | String to split |
| sep | Separator string to split on |
| empty | If true, empty segments are preserved; if false, they are skipped |
Example:
| int32 strSplitAny | ( | sa_string * | out, |
| strref | s, | ||
| strref | chars, | ||
| bool | empty | ||
| ) |
Splits a string at any of a set of delimiter bytes
Like strSplit(), but the string is divided at every byte that appears anywhere in 'chars' rather than at occurrences of a multi-byte separator. An empty or NULL character set never matches, so the whole string comes back as one segment.
Note: this operates on bytes, not UTF-8 code points.
| out | Pointer to string array to store results (cleared first) |
| s | String to split |
| chars | Set of delimiter bytes to split on |
| empty | If true, empty segments are preserved; if false, they are skipped |
Example:
| int32 strSplitAnyMax | ( | sa_string * | out, |
| strref | s, | ||
| strref | chars, | ||
| bool | empty, | ||
| int32 | maxparts | ||
| ) |
Splits a string at any of a set of delimiter bytes, up to a limit
Combines strSplitAny() and strSplitMax(): the string is divided at every byte in 'chars', and the final element holds the unsplit remainder once maxparts segments have been produced.
| out | Pointer to string array to store results (cleared first) |
| s | String to split |
| chars | Set of delimiter bytes to split on |
| empty | If true, empty segments are preserved; if false, they are skipped |
| maxparts | Maximum number of segments, or 0 for unlimited |
Example:
| int32 strSplitMax | ( | sa_string * | out, |
| strref | s, | ||
| strref | sep, | ||
| bool | empty, | ||
| int32 | maxparts | ||
| ) |
Splits a string into at most a given number of pieces
Like strSplit(), but stops splitting once maxparts segments have been produced. The final element holds the entire unsplit remainder of the string, separators included. A maxparts of 0 (or negative) means no limit, making this identical to strSplit().
| out | Pointer to string array to store results (cleared first) |
| s | String to split |
| sep | Separator string to split on |
| empty | If true, empty segments are preserved; if false, they are skipped |
| maxparts | Maximum number of segments, or 0 for unlimited |
Example:
| bool strSplitNext | ( | strref | s, |
| int32 * | pos, | ||
| strref | sep, | ||
| strhandle | out | ||
| ) |
Retrieves the next piece of a string being split, without building an array
Cursor-style alternative to strSplit() for callers that only need one segment at a time. Initialize the cursor to 0 and call repeatedly until it returns false. Empty segments are always produced, matching strSplit() with empty set to true.
The segment is still allocated (as a rope reference for large ones), but the sa_string is never materialized.
| s | String to split (not modified) |
| pos | Cursor; initialize to 0 before the first call, then leave it alone |
| sep | Separator string to split on |
| out | Output string receiving the segment (existing content destroyed) |
Example:
| bool strSplitNextAny | ( | strref | s, |
| int32 * | pos, | ||
| strref | chars, | ||
| strhandle | out | ||
| ) |
Retrieves the next piece of a string being split at any of a set of bytes
Like strSplitNext(), but divides the string at every byte that appears anywhere in 'chars' rather than at occurrences of a multi-byte separator.
| s | String to split (not modified) |
| pos | Cursor; initialize to 0 before the first call, then leave it alone |
| chars | Set of delimiter bytes to split on |
| out | Output string receiving the segment (existing content destroyed) |
Example:
| bool strSubStr | ( | strhandle | o, |
| strref | s, | ||
| int32 | b, | ||
| int32 | e | ||
| ) |
Extracts a substring from a string
Creates a new string containing bytes from position b (inclusive) to position e (exclusive). Negative indices count from the end. Use strEnd for e to extract to the end of the string.
For large substrings, may create a rope reference instead of copying the data.
| o | Output string (existing content destroyed) |
| s | Source string (not modified) |
| b | Starting position (negative = from end) |
| e | Ending position (negative = from end, strEnd = end of string) |
Example:
Extracts a substring, consuming the source string
Like strSubStr(), but takes ownership of sc and destroys it after use. The sc handle will be NULL after this call. More efficient when the source is no longer needed.
| o | Output string (existing content destroyed) |
| sc | Source string (destroyed after use) |
| b | Starting position (negative = from end) |
| e | Ending position (negative = from end, strEnd = end of string) |
Example:
| bool strSubStrI | ( | strhandle | io, |
| int32 | b, | ||
| int32 | e | ||
| ) |
Extracts a substring in-place
Modifies the string to contain only the specified range. This is the most efficient way to truncate or extract from a string when you don't need the original.
| io | String to modify in-place |
| b | Starting position (negative = from end) |
| e | Ending position (negative = from end, strEnd = end of string) |
Example:
| bool strTrim | ( | strhandle | o, |
| strref | s, | ||
| strref | chars | ||
| ) |
Removes leading and trailing bytes that are members of a set
Writes the portion of s between the first and last byte that is not in 'chars' to o. A NULL character set means the default whitespace set: space, tab, carriage return, linefeed, vertical tab, and formfeed. If every byte is in the set, the result is empty.
The output handle may be the same as the source, which is how a string is trimmed in place:
For large results this produces a rope reference instead of copying, exactly like strSubStr().
| o | Output string (existing content destroyed) |
| s | Source string (not modified) |
| chars | Set of bytes to remove (NULL = whitespace) |
Example:
| void strUpper | ( | strhandle | io | ) |
Converts a string to uppercase (ASCII only)
Modifies the string in-place, converting all lowercase ASCII letters (a-z) to uppercase (A-Z). This is ASCII-only and does not properly handle multi-byte UTF-8 characters or locale-specific case rules.
The string is flattened and made unique before modification.
| io | String to convert in-place |
Example: