blob: 2625838c4001994067dfca126abf31cd7f54537b [file] [log] [blame]
Austin Schuh3333ec72022-12-29 16:21:06 -08001/* 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
42typedef struct string_buffer string_buffer_t;
43
44typedef struct string_feeder string_feeder_t;
45struct string_feeder
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 responsibilty 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
101void str_split_destroy(zarray_t *s);
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, long 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 */
265string_buffer_t *string_buffer_create();
266
267/**
268 * Frees the resources associated with a string buffer object, including space
269 * allocated for any appended characters / strings.
270 */
271void string_buffer_destroy(string_buffer_t *sb);
272
273/**
274 * Appends a single character to the end of the supplied string buffer.
275 */
276void string_buffer_append(string_buffer_t *sb, char c);
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 */
282char string_buffer_pop_back(string_buffer_t *sb);
283
284/**
285 * Appends the supplied string to the end of the supplied string buffer.
286 */
287void string_buffer_append_string(string_buffer_t *sb, const char *str);
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 */
311size_t string_buffer_size(string_buffer_t *sb);
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 */
317char *string_buffer_to_string(string_buffer_t *sb);
318
319/**
320 * Clears the contents of the string buffer, setting its length to zero.
321 */
322void string_buffer_reset(string_buffer_t *sb);
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 */
336string_feeder_t *string_feeder_create(const char *str);
337
338/**
339 * Frees resources associated with the supplied string feeder object, after
340 * which it will no longer be valid for use.
341 */
342void string_feeder_destroy(string_feeder_t *sf);
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 */
352bool string_feeder_has_next(string_feeder_t *sf);
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 */
361char string_feeder_next(string_feeder_t *sf);
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 */
374char *string_feeder_next_length(string_feeder_t *sf, size_t length);
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 */
384char string_feeder_peek(string_feeder_t *sf);
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 */
397char *string_feeder_peek_length(string_feeder_t *sf, size_t length);
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 */
411int string_feeder_get_line(string_feeder_t *sf);
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 */
427int string_feeder_get_column(string_feeder_t *sf);
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 */
436bool string_feeder_starts_with(string_feeder_t *sf, const char *str);
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