CSTR v1.0.0-build
Simple yet powerful string manipulation in C
Loading...
Searching...
No Matches
cstr.h
Go to the documentation of this file.
1// cstr.h
2
3#pragma once
4
5#include "CSTRpredefines.h"
6
7#ifdef __CSTR_OK
8# undef __CSTR_OK
9#endif // defined(__CSTR_OK)
10
11#if __STDC_VERSION__ >= CSTR_DEFAULT_C_STD
12
13#include <stdbool.h>
14#include <stdlib.h>
15
16#define CSTR_NPOS -1
17#define CSTR_SUCCESS 0
18#define CSTR_FAIL 1
19#define CSTR_FORCECAP_LIMIT 2
20
21// NOTE: Dear developer, check all the available macros here
22#ifdef CSTR_RECOMMENDED
23# define CSTR_DYNAMIC_CAPACITY
24# define CSTR_ENABLE_GET_RETURN
25# define CSTR_ENABLE_GET_CONST_RETURN
26#endif // CSTR_RECOMMENDED
27
28// NOTE:
29// Other macros that are not recommended but available for flexibility are:
30// CSTR_DEFINE_INTERNAL : Define the internal files inside of the header file (cstr.h)
31// Check the definitions below the definition of the CSTR struct
32// CSTR_RECOMMENDED : Enable recommended macros, such as CSTR_DYNAMIC_CAPACITY, CSTR_ENABLE_GET_RETURN, ...
33
34/**
35 * @brief Custom dynamic string type
36 *
37 * The fields should typically be managed only through the cstr_* API
38 * Directly modifying them can lead to undefined behavior unless explicitly intended
39 */
40typedef struct
41{
42 /**
43 * @brief Tracks whether this CSTR has been initialized
44 * @note Should only be set by internal or initialization functions
45 */
47
48 /**
49 * @brief Pointer to the character buffer
50 * Always NULL terminated if properly managed through the API
51 */
52 char *data;
53
54 /**
55 * @brief If true, capacity is fixed and operations that exceed
56 * it return an error instead of reallocating the size
57 */
59
60 /**
61 * @brief Current string length (not counting the NULL terminator)
62 */
63 size_t len;
64
65 /**
66 * @brief Total allocated capacity (including NULL terminator)
67 */
68 size_t cap;
69} CSTR;
70
71#ifdef CSTR_DEFINE_INTERNAL
72/**
73 * @brief Update the capacity automatically
74 * IMPORTANT:
75 * This function won't do anything if macro `CSTR_DYNAMIC_CAPACITY` is NOT defined
76 *
77 * @return Return if fail or success
78 * @note Typically used in the other defined functions for CSTR inner API
79 */
81
82/**
83 * @brief Internal helper to format and set the string content.
84 *
85 * Uses a printf-style format string and variadic arguments to
86 * overwrite the content of a CSTR. The function computes the
87 * required buffer size, reallocates if needed (unless forceCap
88 * is active), formats the string, and updates length/capacity.
89 *
90 * @param _str Pointer to the CSTR to modify.
91 * @param _fmt printf-style format string.
92 * @param ... Variadic arguments corresponding to the format.
93 *
94 * @return
95 * - CSTR_SUCCESS on success
96 * - CSTR_FAIL if parameters are invalid, allocation fails,
97 * or vsnprintf reports an error
98 * - CSTR_FORCECAP_LIMIT if forceCap is enabled and the
99 * required size exceeds current capacity
100 *
101 * @note Typically used in the other defined functions for CSTR inner API
102 */
103static int __cstr_setFormat(CSTR *_str, const char *_fmt, ...);
104#endif // defined(CSTR_DEFINE_INTERNAL)
105
106/**
107 * @brief Initialize a new empty CSTR
108 *
109 * @return A new CSTR instance. Check `.initialized` or if CSTR is not NULL to confirm success
110 */
112
113/**
114 * @brief Initialize a CSTR with a copy of an original C-string
115 *
116 * @param _dest Pointer to the destination CSTR
117 * @param _src NULL terminated string to copy from
118 * @return CSTR_SUCCESS on success, otherwise CSTR_FAIL
119 */
120int cstr_initCopy(CSTR *_dest, const char *_src);
121
122/**
123 * @brief Destroy and clean up a CSTR and its allocated objects
124 *
125 * @param _str Pointer to the CSTR to destroy
126 * @return CSTR_SUCCESS on success, otherwise CSTR_FAIL
127 */
129
130/**
131 * @brief Set the content of a CSTR to a new C-string in `.data`
132 *
133 * @param _str Pointer to the CSTR to modify
134 * @param _data Null terminated string to set
135 * @return CSTR_SUCCESS, CSTR_FAIL, or CSTR_FORCECAP_LIMIT
136 */
137int cstr_set(CSTR *_str, const char *_data);
138
139/**
140 * @brief Append a suffix to the end of a CSTR
141 *
142 * @param _str Pointer to the CSTR to modify
143 * @param _suffix NULL terminated string to append
144 * @return CSTR_SUCCESS, CSTR_FAIL, or CSTR_FORCECAP_LIMIT
145 */
146int cstr_add(CSTR *_str, const char *_suffix);
147
148/**
149 * @brief Extract a substring in place from a CSTR
150 *
151 * @param _str Pointer to the CSTR to modify
152 * @param _start Starting index of the substring
153 * @param _len Length of the substring
154 * @return CSTR_SUCCESS or CSTR_FAIL
155 */
156int cstr_substr(CSTR *_str, size_t _start, size_t _len);
157
158/**
159 * @brief Clear a CSTR to an empty string without freeing memory
160 *
161 * @param _str Pointer to the CSTR to clear
162 * @return CSTR_SUCCESS or CSTR_FAIL
163 */
164int cstr_clear(CSTR *_str);
165
166/**
167 * @brief Convert all characters in a CSTR to uppercase
168 *
169 * @param _str Pointer to the CSTR to modify
170 * @return CSTR_SUCCESS or CSTR_FAIL
171 */
172int cstr_upper(CSTR *_str);
173
174/**
175 * @brief Convert all characters in a CSTR to lowercase
176 *
177 * @param _str Pointer to the CSTR to modify
178 * @return CSTR_SUCCESS or CSTR_FAIL
179 */
180int cstr_lower(CSTR *_str);
181
182/**
183 * @brief Insert a string at a specific position in a CSTR
184 *
185 * @param _str Pointer to the CSTR to modify
186 * @param _data NULL terminated string to insert
187 * @param _pos Position at which to insert, 0-based
188 * @return CSTR_SUCCESS, CSTR_FAIL, or CSTR_FORCECAP_LIMIT
189 */
190int cstr_insert(CSTR *_str, const char *_data, size_t _pos);
191
192/**
193 * @brief Reverse the content of a CSTR in place
194 *
195 * @param _str Pointer to the CSTR to modify
196 * @return CSTR_SUCCESS or CSTR_FAIL
197 */
199
200/**
201 * @brief Clear the content of a CSTR and optionally shrink capacity
202 *
203 * @param _str Pointer to the CSTR to shrink
204 * @param _len New length (characters to keep)
205 * @return CSTR_SUCCESS or CSTR_FAIL
206 */
207int cstr_shrink(CSTR *_str, const size_t _len);
208
209/**
210 * @brief Create a numeric string from an integer
211 */
212int cstr_fromInt(CSTR *_str, int _val);
213
214/**
215 * @brief Create a numeric string from a long
216 */
217int cstr_fromLong(CSTR *_str, long _val);
218
219/**
220 * @brief Create a numeric string from a float
221 */
222int cstr_fromFloat(CSTR *_str, float _val);
223
224/**
225 * @brief Create a numeric string from a double
226 */
227int cstr_fromDouble(CSTR *_str, double _val);
228
229/**
230 * @brief Create a hexadecimal string from an unsigned integer
231 */
232int cstr_fromHex(CSTR *_str, unsigned int _val);
233
234/**
235 * @brief Replace only the first occurrence of a substring
236 *
237 * @param _str Pointer to the CSTR
238 * @param _old Substring to locate
239 * @param _new Replacement string
240 * @return CSTR_SUCCESS or an error code (CSTR_FAIL, ...)
241 */
242int cstr_replace(CSTR *_str, const char *_old, const char *_new);
243
244/**
245 * @brief Replace all occurrences of a substring
246 *
247 * @param _str Pointer to the CSTR
248 * @param _old Substring to locate
249 * @param _new Replacement string
250 * @return CSTR_SUCCESS or CSTR_FAIL
251 */
252int cstr_replaceAll(CSTR *_str, const char *_old, const char *_new);
253
254/**
255 * @brief Erase a portion of the string
256 *
257 * @param _str Pointer to the CSTR
258 * @param _pos Starting position
259 * @param _len Number of characters to remove
260 * @return CSTR_SUCCESS or CSTR_FAIL
261 */
262int cstr_erase(CSTR *_str, int _pos, size_t _len);
263
264/**
265 * @brief Find the first occurrence of a substring
266 *
267 * @param _str Pointer to the CSTR to search
268 * @param _find Substring to locate
269 * @return Index of first match, or CSTR_NPOS if not found
270 */
271size_t cstr_find(const CSTR *_str, const char *_find);
272
273/**
274 * @brief Find a substring starting from a specific index
275 *
276 * @param _str Pointer to the CSTR to search
277 * @param _find Substring to locate
278 * @param pos Starting index
279 * @return Index of match, or CSTR_NPOS if not found
280 */
281size_t cstr_findFrom(const CSTR *_str, const char *_find, size_t pos);
282
283/**
284 * @brief Check if a CSTR begins with the given prefix
285 *
286 * @param _str The CSTR to check by value
287 * @param _prefix The prefix string
288 * @return true if it starts with prefix, else return false
289 */
290bool cstr_startsWith(CSTR _str, const char *_prefix);
291
292/**
293 * @brief Check if a CSTR ends with the given suffix
294 *
295 * @param _str The CSTR to check (by value)
296 * @param _suffix The suffix string
297 * @return true if it ends with suffix, false otherwise
298 */
299bool cstr_endsWith(const CSTR _str, const char *_suffix);
300
301/**
302 * @brief Compare two CSTR instances for equality
303 *
304 * @param _s1 First CSTR (by value)
305 * @param _s2 Second CSTR (by value)
306 * @return true if equal, false otherwise
307 */
308bool cstr_comp(const CSTR _s1, const CSTR _s2);
309
310/**
311 * @brief Return "true" or "false" based on a boolean value
312 *
313 * @param _bool Boolean value
314 * @return "true" if _bool is true, otherwise "false".
315 */
316const char *cstr_bool(const bool _bool);
317
318/**
319 * @brief Get if the string is empty
320 * Return true if:
321 * `.len` smaller or equal to 0
322 * `.data` is empty ("")
323 * `.initialized` is false
324 * `_str` is NULL
325 * If none of the requirements are met, means that it's not empty, hence, return false
326 *
327 * @return Is the string empty? Yes (true), No (false)
328 */
329bool cstr_empty(const CSTR *_str);
330
331#define __CSTR_OK
332
333#ifdef __CSTR_OK
334# ifdef CSTR_ENABLE_GET_RETURN
335# define CSTR_GET_RETURN(_cstr, _call, ...) ((_call(&_cstr, __VA_ARGS__)), _cstr)
336# else
337# define CSTR_GET_RETURN(_cstr, _call, ...)
338# endif // defined(CSTR_ENABLE_GET_RETURN)
339
340# ifdef CSTR_CONST_RETURN_USE_PTR_METHOD
341# define CSTR_CONST_RETURN_PTR_METHOD ->
342# else
343# define CSTR_CONST_RETURN_PTR_METHOD .
344# endif
345
346# ifdef CSTR_ENABLE_GET_CONST_RETURN
347# define CSTR_GET_CONST_RETURN(_str, _call, ...) \
348 ({ \
349 CSTR tmpS; \
350 cstr_initCopy(&tmpS, _str CSTR_CONST_RETURN_PTR_METHOD data); \
351 _call(&tmpS, __VA_ARGS__); \
352 tmpS; \
353 })
354# else
355# define CSTR_GET_CONST_RETURN(_str, _call, ...)
356# endif // defined(CSTR_ENABLE_GET_CONST_RETURN)
357#endif // __CSTR_OK
358
359#else
360# error "Must use C11 as the minimum standard"
361#endif // __STDC_VERSION__
362
int cstr_insert(CSTR *_str, const char *_data, size_t _pos)
Insert a string at a specific position in a CSTR.
int cstr_reverse(CSTR *_str)
Reverse the content of a CSTR in place.
bool cstr_comp(const CSTR _s1, const CSTR _s2)
Compare two CSTR instances for equality.
int cstr_lower(CSTR *_str)
Convert all characters in a CSTR to lowercase.
int cstr_replaceAll(CSTR *_str, const char *_old, const char *_new)
Replace all occurrences of a substring.
int cstr_fromFloat(CSTR *_str, float _val)
Create a numeric string from a float.
int cstr_fromHex(CSTR *_str, unsigned int _val)
Create a hexadecimal string from an unsigned integer.
int cstr_shrink(CSTR *_str, const size_t _len)
Clear the content of a CSTR and optionally shrink capacity.
int cstr_destroy(CSTR *_str)
Destroy and clean up a CSTR and its allocated objects.
int cstr_substr(CSTR *_str, size_t _start, size_t _len)
Extract a substring in place from a CSTR.
int cstr_fromInt(CSTR *_str, int _val)
Create a numeric string from an integer.
int cstr_set(CSTR *_str, const char *_data)
Set the content of a CSTR to a new C-string in .data
bool cstr_startsWith(CSTR _str, const char *_prefix)
Check if a CSTR begins with the given prefix.
int cstr_fromDouble(CSTR *_str, double _val)
Create a numeric string from a double.
int cstr_erase(CSTR *_str, int _pos, size_t _len)
Erase a portion of the string.
int cstr_add(CSTR *_str, const char *_suffix)
Append a suffix to the end of a CSTR.
int cstr_initCopy(CSTR *_dest, const char *_src)
Initialize a CSTR with a copy of an original C-string.
int cstr_upper(CSTR *_str)
Convert all characters in a CSTR to uppercase.
static int __cstr_setFormat(CSTR *_str, const char *_fmt,...)
Internal helper to format and set the string content.
int __cstr_updateCap(CSTR *_str)
Update the capacity automatically IMPORTANT: This function won't do anything if macro CSTR_DYNAMIC_CA...
bool cstr_empty(const CSTR *_str)
Get if the string is empty Return true if: .len smaller or equal to 0 .data is empty ("") ....
int cstr_fromLong(CSTR *_str, long _val)
Create a numeric string from a long.
size_t cstr_find(const CSTR *_str, const char *_find)
Find the first occurrence of a substring.
CSTR cstr_init(void)
Initialize a new empty CSTR.
const char * cstr_bool(const bool _bool)
Return "true" or "false" based on a boolean value.
int cstr_replace(CSTR *_str, const char *_old, const char *_new)
Replace only the first occurrence of a substring.
size_t cstr_findFrom(const CSTR *_str, const char *_find, size_t pos)
Find a substring starting from a specific index.
int cstr_clear(CSTR *_str)
Clear a CSTR to an empty string without freeing memory.
bool cstr_endsWith(const CSTR _str, const char *_suffix)
Check if a CSTR ends with the given suffix.
Custom dynamic string type.
Definition cstr.h:41
bool initialized
Tracks whether this CSTR has been initialized.
Definition cstr.h:46
size_t len
Current string length (not counting the NULL terminator)
Definition cstr.h:63
size_t cap
Total allocated capacity (including NULL terminator)
Definition cstr.h:68
char * data
Pointer to the character buffer Always NULL terminated if properly managed through the API.
Definition cstr.h:52
bool forceCap
If true, capacity is fixed and operations that exceed it return an error instead of reallocating the ...
Definition cstr.h:58