1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | #include "SDL_internal.h" |
22 | |
23 | |
24 | char *SDL_strtok_r(char *s1, const char *s2, char **ptr) |
25 | { |
26 | #ifdef HAVE_STRTOK_R |
27 | return strtok_r(s1, s2, ptr); |
28 | |
29 | #else /* SDL implementation */ |
30 | /* |
31 | * Adapted from _PDCLIB_strtok() of PDClib library at |
32 | * https://github.com/DevSolar/pdclib.git |
33 | * |
34 | * The code was under CC0 license: |
35 | * https://creativecommons.org/publicdomain/zero/1.0/legalcode : |
36 | * |
37 | * No Copyright |
38 | * |
39 | * The person who associated a work with this deed has dedicated the |
40 | * work to the public domain by waiving all of his or her rights to |
41 | * the work worldwide under copyright law, including all related and |
42 | * neighboring rights, to the extent allowed by law. |
43 | * |
44 | * You can copy, modify, distribute and perform the work, even for |
45 | * commercial purposes, all without asking permission. See Other |
46 | * Information below. |
47 | */ |
48 | const char *p = s2; |
49 | |
50 | if (!s2 || !ptr || (!s1 && !*ptr)) return NULL; |
51 | |
52 | if (s1 != NULL) { /* new string */ |
53 | *ptr = s1; |
54 | } else { /* old string continued */ |
55 | if (*ptr == NULL) { |
56 | /* No old string, no new string, nothing to do */ |
57 | return NULL; |
58 | } |
59 | s1 = *ptr; |
60 | } |
61 | |
62 | /* skip leading s2 characters */ |
63 | while (*p && *s1) { |
64 | if (*s1 == *p) { |
65 | /* found separator; skip and start over */ |
66 | ++s1; |
67 | p = s2; |
68 | continue; |
69 | } |
70 | ++p; |
71 | } |
72 | |
73 | if (! *s1) { /* no more to parse */ |
74 | *ptr = s1; |
75 | return NULL; |
76 | } |
77 | |
78 | /* skipping non-s2 characters */ |
79 | *ptr = s1; |
80 | while (**ptr) { |
81 | p = s2; |
82 | while (*p) { |
83 | if (**ptr == *p++) { |
84 | /* found separator; overwrite with '\0', position *ptr, return */ |
85 | *((*ptr)++) = '\0'; |
86 | return s1; |
87 | } |
88 | } |
89 | ++(*ptr); |
90 | } |
91 | |
92 | /* parsed to end of string */ |
93 | return s1; |
94 | #endif |
95 | } |
96 | |