WPILibC++ 2025.1.1
Loading...
Searching...
No Matches
string_util.h
Go to the documentation of this file.
1/* Copyright (C) 2013-2016, The Regents of The University of Michigan.
2All rights reserved.
3This software was developed in the APRIL Robotics Lab under the
4direction of Edwin Olson, ebolson@umich.edu. This software may be
5available under alternative licensing terms; contact the address above.
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
81. Redistributions of source code must retain the above copyright notice, this
9 list of conditions and the following disclaimer.
102. Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23The views and conclusions contained in the software and documentation are those
24of the authors and should not be interpreted as representing official policies,
25either expressed or implied, of the Regents of The University of Michigan.
26*/
27
28#pragma once
29
30#include <stdio.h>
31#include <stdarg.h>
32#include <stdbool.h>
33#include <ctype.h>
34
35#include "zarray.h"
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41
43
46{
47 char *s;
48 size_t len;
49 size_t pos;
50
51 int line, col;
52};
53
54/**
55 * Similar to sprintf(), except that it will malloc() enough space for the
56 * formatted string which it returns. It is the caller's responsibility to call
57 * free() on the returned string when it is no longer needed.
58 */
59char *sprintf_alloc(const char *fmt, ...)
60#ifndef _MSC_VER
61__attribute__ ((format (printf, 1, 2)))
62#endif
63;
64
65/**
66 * Similar to vsprintf(), except that it will malloc() enough space for the
67 * formatted string which it returns. It is the caller's responsibility to call
68 * free() on the returned string when it is no longer needed.
69 */
70char *vsprintf_alloc(const char *fmt, va_list args);
71
72/**
73 * Concatenates 1 or more strings together and returns the result, which will be a
74 * newly allocated string which it is the caller's responsibility to free.
75 */
76#define str_concat(...) _str_concat_private(__VA_ARGS__, NULL)
77char *_str_concat_private(const char *first, ...);
78
79
80// Returns the index of the first character that differs:
81int str_diff_idx(const char * a, const char * b);
82
83/**
84 * Splits the supplied string into an array of strings by subdividing it at
85 * each occurrence of the supplied delimiter string. The split strings will not
86 * contain the delimiter. The original string will remain unchanged.
87 * If str is composed of all delimiters, an empty array will be returned.
88 *
89 * It is the caller's responsibility to free the returned zarray, as well as
90 * the strings contained within it, e.g.:
91 *
92 * zarray_t *za = str_split("this is a haystack", " ");
93 * => ["this", "is", "a", "haystack"]
94 * zarray_vmap(za, free);
95 * zarray_destroy(za);
96 */
97zarray_t *str_split(const char *str, const char *delim);
98
99zarray_t *str_split_spaces(const char *str);
100
102
103/*
104 * Determines if str1 exactly matches str2 (more efficient than strcmp(...) == 0)
105 */
106static inline bool streq(const char *str1, const char* str2)
107{
108 int i;
109 for (i = 0 ; str1[i] != '\0' ; i++) {
110 if (str1[i] != str2[i])
111 return false;
112 }
113
114 return str2[i] == '\0';
115}
116
117/**
118 * Determines if str1 exactly matches str2, ignoring case (more efficient than
119 * strcasecmp(...) == 0)
120 */
121static inline bool strcaseeq(const char *str1, const char* str2)
122{
123 int i;
124 for (i = 0 ; str1[i] != '\0' ; i++) {
125 if (str1[i] == str2[i])
126 continue;
127 else if (islower(str1[i]) && (str1[i] - 32) == str2[i])
128 continue;
129 else if (isupper(str1[i]) && (str1[i] + 32) == str2[i])
130 continue;
131
132 return false;
133 }
134
135 return str2[i] == '\0';
136}
137
138/**
139 * Trims whitespace characters (i.e. matching isspace()) from the beginning and/or
140 * end of the supplied string. This change affects the supplied string in-place.
141 * The supplied/edited string is returned to enable chained reference.
142 *
143 * Note: do not pass a string literal to this function
144 */
145char *str_trim(char *str);
146
147/**
148 * Trims whitespace characters (i.e. matching isspace()) from the beginning
149 * of the supplied string. This change affects the supplied string in-place.
150 * The supplied/edited string is returned to enable chained reference.
151 *
152 * Note: do not pass a string literal to this function
153 */
154char *str_lstrip(char *str);
155
156/**
157 * Trims whitespace characters (i.e. matching isspace()) from the end of the
158 * supplied string. This change affects the supplied string in-place.
159 * The supplied/edited string is returned to enable chained reference.
160 *
161 * Note: do not pass a string literal to this function
162 */
163char *str_rstrip(char *str);
164
165/**
166 * Returns true if the end of string 'haystack' matches 'needle', else false.
167 *
168 * Note: An empty needle ("") will match any source.
169 */
170bool str_ends_with(const char *haystack, const char *needle);
171
172/**
173 * Returns true if the start of string 'haystack' matches 'needle', else false.
174 *
175 * Note: An empty needle ("") will match any source.
176 */
177bool str_starts_with(const char *haystack, const char *needle);
178
179/**
180 * Returns true if the start of string 'haystack' matches any needle, else false.
181 *
182 * Note: An empty needle ("") will match any source.
183 */
184bool str_starts_with_any(const char *haystack, const char **needles, int num_needles);
185
186/**
187 * Returns true if the string 'haystack' matches any needle, else false.
188 */
189bool str_matches_any(const char *haystack, const char **needles, int num_needles);
190
191/**
192 * Retrieves a (newly-allocated) substring of the given string, 'str', starting
193 * from character index 'startidx' through index 'endidx' - 1 (inclusive).
194 * An 'endidx' value -1 is equivalent to strlen(str).
195 *
196 * It is the caller's responsibility to free the returned string.
197 *
198 * Examples:
199 * str_substring("string", 1, 3) = "tr"
200 * str_substring("string", 2, -1) = "ring"
201 * str_substring("string", 3, 3) = ""
202 *
203 * Note: startidx must be >= endidx
204 */
205char *str_substring(const char *str, size_t startidx, size_t endidx);
206
207/**
208 * Retrieves the zero-based index of the beginning of the supplied substring
209 * (needle) within the search string (haystack) if it exists.
210 *
211 * Returns -1 if the supplied needle is not found within the haystack.
212 */
213int str_indexof(const char *haystack, const char *needle);
214
215 static inline int str_contains(const char *haystack, const char *needle) {
216 return str_indexof(haystack, needle) >= 0;
217 }
218
219// same as above, but returns last match
220int str_last_indexof(const char *haystack, const char *needle);
221
222/**
223 * Replaces all upper-case characters within the supplied string with their
224 * lower-case counterparts, modifying the original string's contents.
225 *
226 * Returns the supplied / modified string.
227 */
228char *str_tolowercase(char *s);
229
230/**
231 * Replaces all lower-case characters within the supplied string with their
232 * upper-case counterparts, modifying the original string's contents.
233 *
234 * Returns the supplied / modified string.
235 */
236char *str_touppercase(char *s);
237
238/**
239 * Replaces all occurrences of 'needle' in the string 'haystack', substituting
240 * for them the value of 'replacement', and returns the result as a newly-allocated
241 * string. The original strings remain unchanged.
242 *
243 * It is the caller's responsibility to free the returned string.
244 *
245 * Examples:
246 * str_replace("string", "ri", "u") = "stung"
247 * str_replace("singing", "ing", "") = "s"
248 * str_replace("string", "foo", "bar") = "string"
249 *
250 * Note: An empty needle will match only an empty haystack
251 */
252char *str_replace(const char *haystack, const char *needle, const char *replacement);
253
254 char *str_replace_many(const char *_haystack, ...);
255//////////////////////////////////////////////////////
256// String Buffer
257
258/**
259 * Creates and initializes a string buffer object which can be used with any of
260 * the string_buffer_*() functions.
261 *
262 * It is the caller's responsibility to free the string buffer resources with
263 * a call to string_buffer_destroy() when it is no longer needed.
264 */
266
267/**
268 * Frees the resources associated with a string buffer object, including space
269 * allocated for any appended characters / strings.
270 */
272
273/**
274 * Appends a single character to the end of the supplied string buffer.
275 */
277
278/**
279 * Removes a single character from the end of the string and
280 * returns it. Does nothing if string is empty and returns NULL
281 */
283
284/**
285 * Appends the supplied string to the end of the supplied string buffer.
286 */
288
289/**
290 * Formats the supplied string and arguments in a manner akin to printf(), and
291 * appends the resulting string to the end of the supplied string buffer.
292 */
293void string_buffer_appendf(string_buffer_t *sb, const char *fmt, ...)
294#ifndef _MSC_VER
295__attribute__ ((format (printf, 2, 3)))
296#endif
297;
298
299/**
300 * Determines whether the character contents held by the supplied string buffer
301 * ends with the supplied string.
302 *
303 * Returns true if the string buffer's contents ends with 'str', else false.
304 */
305bool string_buffer_ends_with(string_buffer_t *sb, const char *str);
306
307/**
308 * Returns the string-length of the contents of the string buffer (not counting \0).
309 * Equivalent to calling strlen() on the string returned by string_buffer_to_string(sb).
310 */
312
313/**
314 * Returns the contents of the string buffer in a newly-allocated string, which
315 * it is the caller's responsibility to free once it is no longer needed.
316 */
318
319/**
320 * Clears the contents of the string buffer, setting its length to zero.
321 */
323
324//////////////////////////////////////////////////////
325// String Feeder
326
327/**
328 * Creates a string feeder object which can be used to traverse the supplied
329 * string using the string_feeder_*() functions. A local copy of the string's
330 * contents will be stored so that future changes to 'str' will not be
331 * reflected by the string feeder object.
332 *
333 * It is the caller's responsibility to call string_feeder_destroy() on the
334 * returned object when it is no longer needed.
335 */
337
338/**
339 * Frees resources associated with the supplied string feeder object, after
340 * which it will no longer be valid for use.
341 */
343
344/**
345 * Determines whether any characters remain to be retrieved from the string
346 * feeder's string (not including the terminating '\0').
347 *
348 * Returns true if at least one more character can be retrieved with calls to
349 * string_feeder_next(), string_feeder_peek(), string_feeder_peek(), or
350 * string_feeder_consume(), else false.
351 */
353
354/**
355 * Retrieves the next available character from the supplied string feeder
356 * (which may be the terminating '\0' character) and advances the feeder's
357 * position to the next character in the string.
358 *
359 * Note: Attempts to read past the end of the string will throw an assertion.
360 */
362
363/**
364 * Retrieves a series of characters from the supplied string feeder. The number
365 * of characters returned will be 'length' or the number of characters
366 * remaining in the string, whichever is shorter. The string feeder's position
367 * will be advanced by the number of characters returned.
368 *
369 * It is the caller's responsibility to free the returned string when it is no
370 * longer needed.
371 *
372 * Note: Calling once the end of the string has already been read will throw an assertion.
373 */
375
376/**
377 * Retrieves the next available character from the supplied string feeder
378 * (which may be the terminating '\0' character), but does not advance
379 * the feeder's position so that subsequent calls to _next() or _peek() will
380 * retrieve the same character.
381 *
382 * Note: Attempts to peek past the end of the string will throw an assertion.
383 */
385
386/**
387 * Retrieves a series of characters from the supplied string feeder. The number
388 * of characters returned will be 'length' or the number of characters
389 * remaining in the string, whichever is shorter. The string feeder's position
390 * will not be advanced.
391 *
392 * It is the caller's responsibility to free the returned string when it is no
393 * longer needed.
394 *
395 * Note: Calling once the end of the string has already been read will throw an assertion.
396 */
398
399/**
400 * Retrieves the line number of the current position in the supplied
401 * string feeder, which will be incremented whenever a newline is consumed.
402 *
403 * Examples:
404 * prior to reading 1st character: line = 1, column = 0
405 * after reading 1st non-newline character: line = 1, column = 1
406 * after reading 2nd non-newline character: line = 1, column = 2
407 * after reading 1st newline character: line = 2, column = 0
408 * after reading 1st character after 1st newline: line = 2, column = 1
409 * after reading 2nd newline character: line = 3, column = 0
410 */
412
413/**
414 * Retrieves the column index in the current line for the current position
415 * in the supplied string feeder, which will be incremented with each
416 * non-newline character consumed, and reset to 0 whenever a newline (\n) is
417 * consumed.
418 *
419 * Examples:
420 * prior to reading 1st character: line = 1, column = 0
421 * after reading 1st non-newline character: line = 1, column = 1
422 * after reading 2nd non-newline character: line = 1, column = 2
423 * after reading 1st newline character: line = 2, column = 0
424 * after reading 1st character after 1st newline: line = 2, column = 1
425 * after reading 2nd newline character: line = 3, column = 0
426 */
428
429/**
430 * Determines whether the supplied string feeder's remaining contents starts
431 * with the given string.
432 *
433 * Returns true if the beginning of the string feeder's remaining contents matches
434 * the supplied string exactly, else false.
435 */
437
438/**
439 * Consumes from the string feeder the number of characters contained in the
440 * given string (not including the terminating '\0').
441 *
442 * Throws an assertion if the consumed characters do not exactly match the
443 * contents of the supplied string.
444 */
445void string_feeder_require(string_feeder_t *sf, const char *str);
446
447/*#ifndef strdup
448 static inline char *strdup(const char *s) {
449 int len = strlen(s);
450 char *out = malloc(len+1);
451 memcpy(out, s, len + 1);
452 return out;
453 }
454#endif
455*/
456
457
458// find everything that looks like an env variable and expand it
459// using getenv. Caller should free the result.
460// e.g. "$HOME/abc" ==> "/home/ebolson/abc"
461char *str_expand_envs(const char *in);
462
463#ifdef __cplusplus
464}
465#endif
Definition format.h:924
FMT_INLINE auto format(detail::locale_ref loc, format_string< T... > fmt, T &&... args) -> std::string
Definition format.h:4146
auto printf(string_view fmt, const T &... args) -> int
Formats args according to specifications in fmt and writes the output to stdout.
Definition printf.h:621
static bool streq(const char *str1, const char *str2)
Definition string_util.h:106
void string_buffer_destroy(string_buffer_t *sb)
Frees the resources associated with a string buffer object, including space allocated for any appende...
char string_buffer_pop_back(string_buffer_t *sb)
Removes a single character from the end of the string and returns it.
char string_feeder_next(string_feeder_t *sf)
Retrieves the next available character from the supplied string feeder (which may be the terminating ...
char * string_feeder_peek_length(string_feeder_t *sf, size_t length)
Retrieves a series of characters from the supplied string feeder.
char * str_tolowercase(char *s)
Replaces all upper-case characters within the supplied string with their lower-case counterparts,...
void string_buffer_append(string_buffer_t *sb, char c)
Appends a single character to the end of the supplied string buffer.
char * str_lstrip(char *str)
Trims whitespace characters (i.e.
char * str_substring(const char *str, size_t startidx, size_t endidx)
Retrieves a (newly-allocated) substring of the given string, 'str', starting from character index 'st...
void string_buffer_reset(string_buffer_t *sb)
Clears the contents of the string buffer, setting its length to zero.
char * _str_concat_private(const char *first,...)
bool string_feeder_starts_with(string_feeder_t *sf, const char *str)
Determines whether the supplied string feeder's remaining contents starts with the given string.
void string_feeder_destroy(string_feeder_t *sf)
Frees resources associated with the supplied string feeder object, after which it will no longer be v...
string_buffer_t * string_buffer_create(void)
Creates and initializes a string buffer object which can be used with any of the string_buffer_*() fu...
char * str_trim(char *str)
Trims whitespace characters (i.e.
int str_diff_idx(const char *a, const char *b)
int string_feeder_get_column(string_feeder_t *sf)
Retrieves the column index in the current line for the current position in the supplied string feeder...
void str_split_destroy(zarray_t *s)
static int str_contains(const char *haystack, const char *needle)
Definition string_util.h:215
char char * vsprintf_alloc(const char *fmt, va_list args)
Similar to vsprintf(), except that it will malloc() enough space for the formatted string which it re...
bool string_feeder_has_next(string_feeder_t *sf)
Determines whether any characters remain to be retrieved from the string feeder's string (not includi...
zarray_t * str_split(const char *str, const char *delim)
Splits the supplied string into an array of strings by subdividing it at each occurrence of the suppl...
int str_last_indexof(const char *haystack, const char *needle)
bool str_matches_any(const char *haystack, const char **needles, int num_needles)
Returns true if the string 'haystack' matches any needle, else false.
char * str_replace_many(const char *_haystack,...)
int str_indexof(const char *haystack, const char *needle)
Retrieves the zero-based index of the beginning of the supplied substring (needle) within the search ...
char * str_replace(const char *haystack, const char *needle, const char *replacement)
Replaces all occurrences of 'needle' in the string 'haystack', substituting for them the value of 're...
char * str_expand_envs(const char *in)
string_feeder_t * string_feeder_create(const char *str)
Creates a string feeder object which can be used to traverse the supplied string using the string_fee...
char * str_touppercase(char *s)
Replaces all lower-case characters within the supplied string with their upper-case counterparts,...
void string_feeder_require(string_feeder_t *sf, const char *str)
Consumes from the string feeder the number of characters contained in the given string (not including...
char * sprintf_alloc(const char *fmt,...) __attribute__((format(printf
Similar to sprintf(), except that it will malloc() enough space for the formatted string which it ret...
void string_buffer_append_string(string_buffer_t *sb, const char *str)
Appends the supplied string to the end of the supplied string buffer.
void bool string_buffer_ends_with(string_buffer_t *sb, const char *str)
Determines whether the character contents held by the supplied string buffer ends with the supplied s...
char * str_rstrip(char *str)
Trims whitespace characters (i.e.
void string_buffer_appendf(string_buffer_t *sb, const char *fmt,...) __attribute__((format(printf
Formats the supplied string and arguments in a manner akin to printf(), and appends the resulting str...
char string_feeder_peek(string_feeder_t *sf)
Retrieves the next available character from the supplied string feeder (which may be the terminating ...
char * string_feeder_next_length(string_feeder_t *sf, size_t length)
Retrieves a series of characters from the supplied string feeder.
bool str_ends_with(const char *haystack, const char *needle)
Returns true if the end of string 'haystack' matches 'needle', else false.
bool str_starts_with(const char *haystack, const char *needle)
Returns true if the start of string 'haystack' matches 'needle', else false.
size_t string_buffer_size(string_buffer_t *sb)
Returns the string-length of the contents of the string buffer (not counting \0).
bool str_starts_with_any(const char *haystack, const char **needles, int num_needles)
Returns true if the start of string 'haystack' matches any needle, else false.
zarray_t * str_split_spaces(const char *str)
static bool strcaseeq(const char *str1, const char *str2)
Determines if str1 exactly matches str2, ignoring case (more efficient than strcasecmp(....
Definition string_util.h:121
int string_feeder_get_line(string_feeder_t *sf)
Retrieves the line number of the current position in the supplied string feeder, which will be increm...
char * string_buffer_to_string(string_buffer_t *sb)
Returns the contents of the string buffer in a newly-allocated string, which it is the caller's respo...
Definition string_util.h:46
int line
Definition string_util.h:51
char * s
Definition string_util.h:47
int col
Definition string_util.h:51
size_t pos
Definition string_util.h:49
size_t len
Definition string_util.h:48
Definition zarray.h:44