Skip to content

Commit f88c23f

Browse files
committed
Updates
1 parent e146c7a commit f88c23f

File tree

5 files changed

+200
-5
lines changed

5 files changed

+200
-5
lines changed

cdrom/cdrom.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,9 +1494,7 @@ bool cdrom_is_media_inserted(libretro_vfs_implementation_file *stream)
14941494
bool cdrom_drive_has_media(const char drive)
14951495
{
14961496
RFILE *file;
1497-
char cdrom_path_bin[256];
1498-
1499-
cdrom_path_bin[0] = '\0';
1497+
char cdrom_path_bin[256] = {0};
15001498

15011499
cdrom_device_fillpath(cdrom_path_bin, sizeof(cdrom_path_bin), drive, 1, false);
15021500

@@ -1690,8 +1688,11 @@ void cdrom_device_fillpath(char *path, size_t len, char drive, unsigned char tra
16901688
#ifdef __linux__
16911689
pos = strlcpy(path, "cdrom://drive", len);
16921690

1693-
if (len > pos)
1691+
if (len > pos + 1)
1692+
{
16941693
path[pos++] = drive;
1694+
path[pos] = '\0';
1695+
}
16951696

16961697
pos = strlcat(path, ".cue", len);
16971698
#endif
@@ -1702,8 +1703,11 @@ void cdrom_device_fillpath(char *path, size_t len, char drive, unsigned char tra
17021703
#ifdef _WIN32
17031704
pos = strlcpy(path, "cdrom://", len);
17041705

1705-
if (len > pos)
1706+
if (len > pos + 1)
1707+
{
17061708
path[pos++] = drive;
1709+
path[pos] = '\0';
1710+
}
17071711

17081712
pos += snprintf(path + pos, len - pos, ":/drive-track%02d.bin", track);
17091713
#else

include/lists/string_list.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ bool string_list_find_elem_prefix(const struct string_list *list,
8888
*/
8989
struct string_list *string_split(const char *str, const char *delim);
9090

91+
/**
92+
* string_separate:
93+
* @str : string to turn into a string list
94+
* @delim : delimiter character to use for separating the string.
95+
*
96+
* Creates a new string list based on string @str, delimited by @delim.
97+
* Includes empty strings - i.e. two adjacent delimiters will resolve
98+
* to a string list element of "".
99+
*
100+
* Returns: new string list if successful, otherwise NULL.
101+
*/
102+
struct string_list *string_separate(char *str, const char *delim);
103+
91104
/**
92105
* string_list_new:
93106
*

include/string/stdstring.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,32 @@ char *string_trim_whitespace(char *const s);
129129
char *word_wrap(char *buffer, const char *string,
130130
int line_width, bool unicode, unsigned max_lines);
131131

132+
/* Splits string into tokens seperated by 'delim'
133+
* > Returned token string must be free()'d
134+
* > Returns NULL if token is not found
135+
* > After each call, 'str' is set to the position after the
136+
* last found token
137+
* > Tokens *include* empty strings
138+
* Usage example:
139+
* char *str = "1,2,3,4,5,6,7,,,10,";
140+
* char **str_ptr = &str;
141+
* char *token = NULL;
142+
* while((token = string_tokenize(str_ptr, ",")))
143+
* {
144+
* printf("%s\n", token);
145+
* free(token);
146+
* token = NULL;
147+
* }
148+
*/
149+
char* string_tokenize(char **str, const char *delim);
150+
151+
/* Removes every instance of character 'c' from 'str' */
152+
void string_remove_all_chars(char *str, char c);
153+
154+
/* Converts string to unsigned integer.
155+
* Returns 0 if string is invalid */
156+
unsigned string_to_unsigned(char *str);
157+
132158
RETRO_END_DECLS
133159

134160
#endif

lists/string_list.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,59 @@ struct string_list *string_split(const char *str, const char *delim)
259259
return NULL;
260260
}
261261

262+
/**
263+
* string_separate:
264+
* @str : string to turn into a string list
265+
* @delim : delimiter character to use for separating the string.
266+
*
267+
* Creates a new string list based on string @str, delimited by @delim.
268+
* Includes empty strings - i.e. two adjacent delimiters will resolve
269+
* to a string list element of "".
270+
*
271+
* Returns: new string list if successful, otherwise NULL.
272+
*/
273+
struct string_list *string_separate(char *str, const char *delim)
274+
{
275+
char *token = NULL;
276+
char **str_ptr = NULL;
277+
struct string_list *list = NULL;
278+
279+
/* Sanity check */
280+
if (!str || string_is_empty(delim))
281+
goto error;
282+
283+
str_ptr = &str;
284+
list = string_list_new();
285+
286+
if (!list)
287+
goto error;
288+
289+
token = string_tokenize(str_ptr, delim);
290+
while (token)
291+
{
292+
union string_list_elem_attr attr;
293+
294+
attr.i = 0;
295+
296+
if (!string_list_append(list, token, attr))
297+
goto error;
298+
299+
free(token);
300+
token = NULL;
301+
302+
token = string_tokenize(str_ptr, delim);
303+
}
304+
305+
return list;
306+
307+
error:
308+
if (token)
309+
free(token);
310+
if (list)
311+
string_list_free(list);
312+
return NULL;
313+
}
314+
262315
/**
263316
* string_list_find_elem:
264317
* @list : pointer to string list

string/stdstring.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)