@@ -237,3 +237,102 @@ char *word_wrap(char* buffer, const char *string, int line_width, bool unicode,
237237
238238 return buffer ;
239239}
240+
241+ /* Splits string into tokens seperated by 'delim'
242+ * > Returned token string must be free()'d
243+ * > Returns NULL if token is not found
244+ * > After each call, 'str' is set to the position after the
245+ * last found token
246+ * > Tokens *include* empty strings
247+ * Usage example:
248+ * char *str = "1,2,3,4,5,6,7,,,10,";
249+ * char **str_ptr = &str;
250+ * char *token = NULL;
251+ * while((token = string_tokenize(str_ptr, ",")))
252+ * {
253+ * printf("%s\n", token);
254+ * free(token);
255+ * token = NULL;
256+ * }
257+ */
258+ char * string_tokenize (char * * str , const char * delim )
259+ {
260+ /* Taken from https://codereview.stackexchange.com/questions/216956/strtok-function-thread-safe-supports-empty-tokens-doesnt-change-string# */
261+ char * str_ptr = NULL ;
262+ char * delim_ptr = NULL ;
263+ char * token = NULL ;
264+ size_t token_len = 0 ;
265+
266+ /* Sanity checks */
267+ if (!str || string_is_empty (delim ))
268+ return NULL ;
269+
270+ str_ptr = * str ;
271+
272+ /* Note: we don't check string_is_empty() here,
273+ * empty strings are valid */
274+ if (!str_ptr )
275+ return NULL ;
276+
277+ /* Search for delimiter */
278+ delim_ptr = strstr (str_ptr , delim );
279+
280+ if (delim_ptr )
281+ token_len = delim_ptr - str_ptr ;
282+ else
283+ token_len = strlen (str_ptr );
284+
285+ /* Allocate token string */
286+ token = (char * )malloc ((token_len + 1 ) * sizeof (char ));
287+
288+ if (!token )
289+ return NULL ;
290+
291+ /* Copy token */
292+ strlcpy (token , str_ptr , (token_len + 1 ) * sizeof (char ));
293+ token [token_len ] = '\0' ;
294+
295+ /* Update input string pointer */
296+ * str = delim_ptr ? delim_ptr + strlen (delim ) : NULL ;
297+
298+ return token ;
299+ }
300+
301+ /* Removes every instance of character 'c' from 'str' */
302+ void string_remove_all_chars (char * str , char c )
303+ {
304+ char * read_ptr = NULL ;
305+ char * write_ptr = NULL ;
306+
307+ if (string_is_empty (str ))
308+ return ;
309+
310+ read_ptr = str ;
311+ write_ptr = str ;
312+
313+ while (* read_ptr != '\0' )
314+ {
315+ * write_ptr = * read_ptr ++ ;
316+ write_ptr += (* write_ptr != c ) ? 1 : 0 ;
317+ }
318+
319+ * write_ptr = '\0' ;
320+ }
321+
322+ /* Converts string to unsigned integer.
323+ * Returns 0 if string is invalid */
324+ unsigned string_to_unsigned (char * str )
325+ {
326+ char * ptr = NULL ;
327+
328+ if (string_is_empty (str ))
329+ return 0 ;
330+
331+ for (ptr = str ; * ptr != '\0' ; ptr ++ )
332+ {
333+ if (!isdigit (* ptr ))
334+ return 0 ;
335+ }
336+
337+ return (unsigned )strtoul (str , NULL , 10 );
338+ }
0 commit comments