diff options
author | 3gg <3gg@shellblade.net> | 2025-08-30 16:53:58 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2025-08-30 16:53:58 -0700 |
commit | 6aaedb813fa11ba0679c3051bc2eb28646b9506c (patch) | |
tree | 34acbfc9840e02cb4753e6306ea7ce978bf8b58e /src/contrib/SDL-3.2.20/test/testfilesystem.c | |
parent | 8f228ade99dd3d4c8da9b78ade1815c9adf85c8f (diff) |
Update to SDL3
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/testfilesystem.c')
-rw-r--r-- | src/contrib/SDL-3.2.20/test/testfilesystem.c | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/testfilesystem.c b/src/contrib/SDL-3.2.20/test/testfilesystem.c new file mode 100644 index 0000000..11235eb --- /dev/null +++ b/src/contrib/SDL-3.2.20/test/testfilesystem.c | |||
@@ -0,0 +1,315 @@ | |||
1 | /* | ||
2 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
3 | |||
4 | This software is provided 'as-is', without any express or implied | ||
5 | warranty. In no event will the authors be held liable for any damages | ||
6 | arising from the use of this software. | ||
7 | |||
8 | Permission is granted to anyone to use this software for any purpose, | ||
9 | including commercial applications, and to alter it and redistribute it | ||
10 | freely. | ||
11 | */ | ||
12 | /* Simple test of filesystem functions. */ | ||
13 | |||
14 | #include <SDL3/SDL.h> | ||
15 | #include <SDL3/SDL_main.h> | ||
16 | #include <SDL3/SDL_test.h> | ||
17 | |||
18 | static SDL_EnumerationResult SDLCALL enum_callback(void *userdata, const char *origdir, const char *fname) | ||
19 | { | ||
20 | SDL_PathInfo info; | ||
21 | char *fullpath = NULL; | ||
22 | |||
23 | if (SDL_asprintf(&fullpath, "%s%s", origdir, fname) < 0) { | ||
24 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); | ||
25 | return SDL_ENUM_FAILURE; | ||
26 | } | ||
27 | |||
28 | if (!SDL_GetPathInfo(fullpath, &info)) { | ||
29 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't stat '%s': %s", fullpath, SDL_GetError()); | ||
30 | } else { | ||
31 | const char *type; | ||
32 | if (info.type == SDL_PATHTYPE_FILE) { | ||
33 | type = "FILE"; | ||
34 | } else if (info.type == SDL_PATHTYPE_DIRECTORY) { | ||
35 | type = "DIRECTORY"; | ||
36 | } else { | ||
37 | type = "OTHER"; | ||
38 | } | ||
39 | SDL_Log("DIRECTORY %s (type=%s, size=%" SDL_PRIu64 ", create=%" SDL_PRIu64 ", mod=%" SDL_PRIu64 ", access=%" SDL_PRIu64 ")", | ||
40 | fullpath, type, info.size, info.modify_time, info.create_time, info.access_time); | ||
41 | |||
42 | if (info.type == SDL_PATHTYPE_DIRECTORY) { | ||
43 | if (!SDL_EnumerateDirectory(fullpath, enum_callback, userdata)) { | ||
44 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Enumeration failed!"); | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | SDL_free(fullpath); | ||
50 | return SDL_ENUM_CONTINUE; /* keep going */ | ||
51 | } | ||
52 | |||
53 | |||
54 | static SDL_EnumerationResult SDLCALL enum_storage_callback(void *userdata, const char *origdir, const char *fname) | ||
55 | { | ||
56 | SDL_Storage *storage = (SDL_Storage *) userdata; | ||
57 | SDL_PathInfo info; | ||
58 | char *fullpath = NULL; | ||
59 | |||
60 | if (SDL_asprintf(&fullpath, "%s%s", origdir, fname) < 0) { | ||
61 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); | ||
62 | return SDL_ENUM_FAILURE; | ||
63 | } | ||
64 | |||
65 | if (!SDL_GetStoragePathInfo(storage, fullpath, &info)) { | ||
66 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't stat '%s': %s", fullpath, SDL_GetError()); | ||
67 | } else { | ||
68 | const char *type; | ||
69 | if (info.type == SDL_PATHTYPE_FILE) { | ||
70 | type = "FILE"; | ||
71 | } else if (info.type == SDL_PATHTYPE_DIRECTORY) { | ||
72 | type = "DIRECTORY"; | ||
73 | } else { | ||
74 | type = "OTHER"; | ||
75 | } | ||
76 | SDL_Log("STORAGE %s (type=%s, size=%" SDL_PRIu64 ", create=%" SDL_PRIu64 ", mod=%" SDL_PRIu64 ", access=%" SDL_PRIu64 ")", | ||
77 | fullpath, type, info.size, info.modify_time, info.create_time, info.access_time); | ||
78 | |||
79 | if (info.type == SDL_PATHTYPE_DIRECTORY) { | ||
80 | if (!SDL_EnumerateStorageDirectory(storage, fullpath, enum_storage_callback, userdata)) { | ||
81 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Enumeration failed!"); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | SDL_free(fullpath); | ||
87 | return SDL_ENUM_CONTINUE; /* keep going */ | ||
88 | } | ||
89 | |||
90 | int main(int argc, char *argv[]) | ||
91 | { | ||
92 | SDLTest_CommonState *state; | ||
93 | char *pref_path; | ||
94 | char *curdir; | ||
95 | const char *base_path; | ||
96 | |||
97 | /* Initialize test framework */ | ||
98 | state = SDLTest_CommonCreateState(argv, 0); | ||
99 | if (!state) { | ||
100 | return 1; | ||
101 | } | ||
102 | |||
103 | /* Parse commandline */ | ||
104 | if (!SDLTest_CommonDefaultArgs(state, argc, argv)) { | ||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | if (!SDL_Init(0)) { | ||
109 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init() failed: %s", SDL_GetError()); | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | base_path = SDL_GetBasePath(); | ||
114 | if (!base_path) { | ||
115 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find base path: %s", | ||
116 | SDL_GetError()); | ||
117 | } else { | ||
118 | SDL_Log("base path: '%s'", base_path); | ||
119 | } | ||
120 | |||
121 | pref_path = SDL_GetPrefPath("libsdl", "test_filesystem"); | ||
122 | if (!pref_path) { | ||
123 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find pref path: %s", | ||
124 | SDL_GetError()); | ||
125 | } else { | ||
126 | SDL_Log("pref path: '%s'", pref_path); | ||
127 | } | ||
128 | SDL_free(pref_path); | ||
129 | |||
130 | pref_path = SDL_GetPrefPath(NULL, "test_filesystem"); | ||
131 | if (!pref_path) { | ||
132 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find pref path without organization: %s", | ||
133 | SDL_GetError()); | ||
134 | } else { | ||
135 | SDL_Log("pref path: '%s'", pref_path); | ||
136 | } | ||
137 | SDL_free(pref_path); | ||
138 | |||
139 | curdir = SDL_GetCurrentDirectory(); | ||
140 | if (!curdir) { | ||
141 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find current directory: %s", | ||
142 | SDL_GetError()); | ||
143 | } else { | ||
144 | SDL_Log("current directory: '%s'", curdir); | ||
145 | } | ||
146 | SDL_free(curdir); | ||
147 | |||
148 | if (base_path) { | ||
149 | char **globlist; | ||
150 | SDL_Storage *storage = NULL; | ||
151 | SDL_IOStream *stream; | ||
152 | const char *text = "foo\n"; | ||
153 | SDL_PathInfo pathinfo; | ||
154 | |||
155 | if (!SDL_EnumerateDirectory(base_path, enum_callback, NULL)) { | ||
156 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Base path enumeration failed!"); | ||
157 | } | ||
158 | |||
159 | globlist = SDL_GlobDirectory(base_path, "*/test*/T?st*", SDL_GLOB_CASEINSENSITIVE, NULL); | ||
160 | if (!globlist) { | ||
161 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Base path globbing failed!"); | ||
162 | } else { | ||
163 | int i; | ||
164 | for (i = 0; globlist[i]; i++) { | ||
165 | SDL_Log("DIRECTORY GLOB[%d]: '%s'", i, globlist[i]); | ||
166 | } | ||
167 | SDL_free(globlist); | ||
168 | } | ||
169 | |||
170 | /* !!! FIXME: put this in a subroutine and make it test more thoroughly (and put it in testautomation). */ | ||
171 | if (!SDL_CreateDirectory("testfilesystem-test")) { | ||
172 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateDirectory('testfilesystem-test') failed: %s", SDL_GetError()); | ||
173 | } else if (!SDL_CreateDirectory("testfilesystem-test/1")) { | ||
174 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateDirectory('testfilesystem-test/1') failed: %s", SDL_GetError()); | ||
175 | } else if (!SDL_CreateDirectory("testfilesystem-test/1")) { /* THIS SHOULD NOT FAIL! Making a directory that already exists should succeed here. */ | ||
176 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateDirectory('testfilesystem-test/1') failed: %s", SDL_GetError()); | ||
177 | } else if (!SDL_CreateDirectory("testfilesystem-test/3/4/5/6")) { /* THIS SHOULD NOT FAIL! Making a directory with missing parents succeed here. */ | ||
178 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateDirectory('testfilesystem-test/3/4/5/6') failed: %s", SDL_GetError()); | ||
179 | } else if (!SDL_RemovePath("testfilesystem-test/3/4/5/6")) { /* THIS SHOULD NOT FAIL! Making a directory with missing parents succeed here. */ | ||
180 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-test/3/4/5/6') failed: %s", SDL_GetError()); | ||
181 | } else if (!SDL_RemovePath("testfilesystem-test/3/4/5")) { /* THIS SHOULD NOT FAIL! Making a directory with missing parents succeed here. */ | ||
182 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-test/3/4/5') failed: %s", SDL_GetError()); | ||
183 | } else if (!SDL_RemovePath("testfilesystem-test/3/4")) { /* THIS SHOULD NOT FAIL! Making a directory with missing parents succeed here. */ | ||
184 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-test/3/4') failed: %s", SDL_GetError()); | ||
185 | } else if (!SDL_RemovePath("testfilesystem-test/3")) { /* THIS SHOULD NOT FAIL! Making a directory with missing parents succeed here. */ | ||
186 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-test/3') failed: %s", SDL_GetError()); | ||
187 | } else if (!SDL_RenamePath("testfilesystem-test/1", "testfilesystem-test/2")) { | ||
188 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RenamePath('testfilesystem-test/1', 'testfilesystem-test/2') failed: %s", SDL_GetError()); | ||
189 | } else if (!SDL_RemovePath("testfilesystem-test/2")) { | ||
190 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-test/2') failed: %s", SDL_GetError()); | ||
191 | } else if (!SDL_RemovePath("testfilesystem-test")) { | ||
192 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-test') failed: %s", SDL_GetError()); | ||
193 | } else if (!SDL_RemovePath("testfilesystem-test")) { /* THIS SHOULD NOT FAIL! Removing a directory that is already gone should succeed here. */ | ||
194 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-test') failed: %s", SDL_GetError()); | ||
195 | } | ||
196 | |||
197 | stream = SDL_IOFromFile("testfilesystem-A", "wb"); | ||
198 | if (stream) { | ||
199 | SDL_WriteIO(stream, text, SDL_strlen(text)); | ||
200 | SDL_CloseIO(stream); | ||
201 | |||
202 | if (!SDL_RenamePath("testfilesystem-A", "testfilesystem-B")) { | ||
203 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RenamePath('testfilesystem-A', 'testfilesystem-B') failed: %s", SDL_GetError()); | ||
204 | } else if (!SDL_CopyFile("testfilesystem-B", "testfilesystem-A")) { | ||
205 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CopyFile('testfilesystem-B', 'testfilesystem-A') failed: %s", SDL_GetError()); | ||
206 | } else { | ||
207 | size_t sizeA, sizeB; | ||
208 | char *textA, *textB; | ||
209 | |||
210 | textA = (char *)SDL_LoadFile("testfilesystem-A", &sizeA); | ||
211 | if (!textA || sizeA != SDL_strlen(text) || SDL_strcmp(textA, text) != 0) { | ||
212 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Contents of testfilesystem-A didn't match, expected %s, got %s", text, textA); | ||
213 | } | ||
214 | SDL_free(textA); | ||
215 | |||
216 | textB = (char *)SDL_LoadFile("testfilesystem-B", &sizeB); | ||
217 | if (!textB || sizeB != SDL_strlen(text) || SDL_strcmp(textB, text) != 0) { | ||
218 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Contents of testfilesystem-B didn't match, expected %s, got %s", text, textB); | ||
219 | } | ||
220 | SDL_free(textB); | ||
221 | } | ||
222 | |||
223 | if (!SDL_RemovePath("testfilesystem-A")) { | ||
224 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-A') failed: %s", SDL_GetError()); | ||
225 | } | ||
226 | if (!SDL_RemovePath("testfilesystem-B")) { | ||
227 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_RemovePath('testfilesystem-B') failed: %s", SDL_GetError()); | ||
228 | } | ||
229 | } else { | ||
230 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_IOFromFile('testfilesystem-A', 'w') failed: %s", SDL_GetError()); | ||
231 | } | ||
232 | |||
233 | storage = SDL_OpenFileStorage(base_path); | ||
234 | if (!storage) { | ||
235 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open base path storage object: %s", SDL_GetError()); | ||
236 | } else { | ||
237 | if (!SDL_EnumerateStorageDirectory(storage, "CMakeFiles", enum_storage_callback, storage)) { | ||
238 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Storage Base path enumeration failed!"); | ||
239 | } | ||
240 | |||
241 | globlist = SDL_GlobStorageDirectory(storage, "", "C*/test*/T?st*", SDL_GLOB_CASEINSENSITIVE, NULL); | ||
242 | if (!globlist) { | ||
243 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Base path globbing failed!"); | ||
244 | } else { | ||
245 | int i; | ||
246 | for (i = 0; globlist[i]; i++) { | ||
247 | SDL_Log("STORAGE GLOB[%d]: '%s'", i, globlist[i]); | ||
248 | } | ||
249 | SDL_free(globlist); | ||
250 | } | ||
251 | |||
252 | /* these should fail: */ | ||
253 | if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/../testsprite.c", &pathinfo)) { | ||
254 | SDL_Log("Storage access on path with internal '..' refused correctly."); | ||
255 | } else { | ||
256 | SDL_Log("Storage access on path with internal '..' accepted INCORRECTLY."); | ||
257 | } | ||
258 | |||
259 | if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/./TargetDirectories.txt", &pathinfo)) { | ||
260 | SDL_Log("Storage access on path with internal '.' refused correctly."); | ||
261 | } else { | ||
262 | SDL_Log("Storage access on path with internal '.' accepted INCORRECTLY."); | ||
263 | } | ||
264 | |||
265 | if (!SDL_GetStoragePathInfo(storage, "../test", &pathinfo)) { | ||
266 | SDL_Log("Storage access on path with leading '..' refused correctly."); | ||
267 | } else { | ||
268 | SDL_Log("Storage access on path with leading '..' accepted INCORRECTLY."); | ||
269 | } | ||
270 | |||
271 | if (!SDL_GetStoragePathInfo(storage, "./CMakeFiles", &pathinfo)) { | ||
272 | SDL_Log("Storage access on path with leading '.' refused correctly."); | ||
273 | } else { | ||
274 | SDL_Log("Storage access on path with leading '.' accepted INCORRECTLY."); | ||
275 | } | ||
276 | |||
277 | if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/..", &pathinfo)) { | ||
278 | SDL_Log("Storage access on path with trailing '..' refused correctly."); | ||
279 | } else { | ||
280 | SDL_Log("Storage access on path with trailing '..' accepted INCORRECTLY."); | ||
281 | } | ||
282 | |||
283 | if (!SDL_GetStoragePathInfo(storage, "CMakeFiles/.", &pathinfo)) { | ||
284 | SDL_Log("Storage access on path with trailing '.' refused correctly."); | ||
285 | } else { | ||
286 | SDL_Log("Storage access on path with trailing '.' accepted INCORRECTLY."); | ||
287 | } | ||
288 | |||
289 | if (!SDL_GetStoragePathInfo(storage, "..", &pathinfo)) { | ||
290 | SDL_Log("Storage access on path '..' refused correctly."); | ||
291 | } else { | ||
292 | SDL_Log("Storage access on path '..' accepted INCORRECTLY."); | ||
293 | } | ||
294 | |||
295 | if (!SDL_GetStoragePathInfo(storage, ".", &pathinfo)) { | ||
296 | SDL_Log("Storage access on path '.' refused correctly."); | ||
297 | } else { | ||
298 | SDL_Log("Storage access on path '.' accepted INCORRECTLY."); | ||
299 | } | ||
300 | |||
301 | if (!SDL_GetStoragePathInfo(storage, "CMakeFiles\\TargetDirectories.txt", &pathinfo)) { | ||
302 | SDL_Log("Storage access on path with Windows separator refused correctly."); | ||
303 | } else { | ||
304 | SDL_Log("Storage access on path with Windows separator accepted INCORRECTLY."); | ||
305 | } | ||
306 | |||
307 | SDL_CloseStorage(storage); | ||
308 | } | ||
309 | |||
310 | } | ||
311 | |||
312 | SDL_Quit(); | ||
313 | SDLTest_CommonDestroyState(state); | ||
314 | return 0; | ||
315 | } | ||