1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2021 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 | #if defined(__clang_analyzer__) |
22 | #define SDL_DISABLE_ANALYZE_MACROS 1 |
23 | #endif |
24 | |
25 | #include "../SDL_internal.h" |
26 | |
27 | #include "SDL_stdinc.h" |
28 | |
29 | char *SDL_strtokr(char *s1, const char *s2, char **ptr) |
30 | { |
31 | #ifdef HAVE_STRTOK_R |
32 | return strtok_r(s1, s2, ptr); |
33 | |
34 | #else /* SDL implementation */ |
35 | /* |
36 | * Adapted from _PDCLIB_strtok() of PDClib library at |
37 | * https://github.com/DevSolar/pdclib.git |
38 | * |
39 | * The code was under CC0 license: |
40 | * https://creativecommons.org/publicdomain/zero/1.0/legalcode : |
41 | * |
42 | * No Copyright |
43 | * |
44 | * The person who associated a work with this deed has dedicated the |
45 | * work to the public domain by waiving all of his or her rights to |
46 | * the work worldwide under copyright law, including all related and |
47 | * neighboring rights, to the extent allowed by law. |
48 | * |
49 | * You can copy, modify, distribute and perform the work, even for |
50 | * commercial purposes, all without asking permission. See Other |
51 | * Information below. |
52 | */ |
53 | const char *p = s2; |
54 | |
55 | if (!s2 || !ptr || (!s1 && !*ptr)) return NULL; |
56 | |
57 | if (s1 != NULL) { /* new string */ |
58 | *ptr = s1; |
59 | } else { /* old string continued */ |
60 | if (*ptr == NULL) { |
61 | /* No old string, no new string, nothing to do */ |
62 | return NULL; |
63 | } |
64 | s1 = *ptr; |
65 | } |
66 | |
67 | /* skip leading s2 characters */ |
68 | while (*p && *s1) { |
69 | if (*s1 == *p) { |
70 | /* found separator; skip and start over */ |
71 | ++s1; |
72 | p = s2; |
73 | continue; |
74 | } |
75 | ++p; |
76 | } |
77 | |
78 | if (! *s1) { /* no more to parse */ |
79 | *ptr = s1; |
80 | return NULL; |
81 | } |
82 | |
83 | /* skipping non-s2 characters */ |
84 | *ptr = s1; |
85 | while (**ptr) { |
86 | p = s2; |
87 | while (*p) { |
88 | if (**ptr == *p++) { |
89 | /* found separator; overwrite with '\0', position *ptr, return */ |
90 | *((*ptr)++) = '\0'; |
91 | return s1; |
92 | } |
93 | } |
94 | ++(*ptr); |
95 | } |
96 | |
97 | /* parsed to end of string */ |
98 | return s1; |
99 | #endif |
100 | } |
101 | |