Atlas - testfilesystem.c
Home / ext / SDL / test Lines: 2 | Size: 14397 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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 18static 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 54static 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 90int 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} 316[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.