Skip to content

Commit

Permalink
filesystem: SDL_GetBasePath() now follows the SDL_GetStringRule.
Browse files Browse the repository at this point in the history
It also now caches at the higher level, so the platform-specific bits don't
change their interface much.

A little code hygiene work was applied to some of the platform bits on top of
this.

Reference Issue libsdl-org#10229.
  • Loading branch information
icculus committed Jul 13, 2024
1 parent 9379e2e commit 0b8c3b6
Show file tree
Hide file tree
Showing 25 changed files with 141 additions and 73 deletions.
8 changes: 4 additions & 4 deletions docs/README-macos.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ Some things that may be of interest about how it all works...
## Working directory

In SDL 1.2, the working directory of your SDL app is by default set to its
parent, but this is no longer the case in SDL 2.0. SDL2 does change the
working directory, which means it'll be whatever the command line prompt
that launched the program was using, or if launched by double-clicking in
the finger, it will be "/", the _root of the filesystem_. Plan accordingly!
parent, but this is no longer the case in SDL 2.0 and later. SDL2 does not
change the working directory, which means it'll be whatever the command line
prompt that launched the program was using, or if launched by double-clicking
in the Finder, it will be "/", the _root of the filesystem_. Plan accordingly!
You can use SDL_GetBasePath() to find where the program is running from and
chdir() there directly.

Expand Down
3 changes: 1 addition & 2 deletions docs/README-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,10 +802,9 @@ On Haiku OS, SDL no longer sets the current working directory to the executable'

```c
{
char *path = SDL_GetBasePath();
const char *path = SDL_GetBasePath();
if (path) {
chdir(path);
SDL_free(path);
}
}
```
Expand Down
9 changes: 4 additions & 5 deletions include/SDL3/SDL_filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ extern "C" {
/**
* Get the directory where the application was run from.
*
* This is not necessarily a fast call, so you should call this once near
* startup and save the string if you need it.
* SDL caches the result of this call internally, but the first call to this
* function is not necessarily fast, so plan accordingly.
*
* **macOS and iOS Specific Functionality**: If the application is in a ".app"
* bundle, this function returns the Resource directory (e.g.
Expand All @@ -68,8 +68,7 @@ extern "C" {
* The returned path is guaranteed to end with a path separator ('\\' on
* Windows, '/' on most other platforms).
*
* The pointer returned is owned by the caller. Please call SDL_free() on the
* pointer when done with it.
* The returned string follows the SDL_GetStringRule.
*
* \returns an absolute path in UTF-8 encoding to the application data
* directory. NULL will be returned on error or when the platform
Expand All @@ -80,7 +79,7 @@ extern "C" {
*
* \sa SDL_GetPrefPath
*/
extern SDL_DECLSPEC char *SDLCALL SDL_GetBasePath(void);
extern SDL_DECLSPEC const char *SDLCALL SDL_GetBasePath(void);

/**
* Get the user-and-app-specific path where files can be written.
Expand Down
3 changes: 3 additions & 0 deletions src/SDL.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "thread/SDL_thread_c.h"
#include "video/SDL_pixels_c.h"
#include "video/SDL_video_c.h"
#include "filesystem/SDL_filesystem_c.h"

#define SDL_INIT_EVERYTHING ~0U

Expand Down Expand Up @@ -192,6 +193,7 @@ void SDL_InitMainThread(void)

SDL_InitTLSData();
SDL_InitTicks();
SDL_InitFilesystem();
SDL_InitLog();
SDL_InitProperties();
SDL_GetGlobalProperties();
Expand All @@ -207,6 +209,7 @@ static void SDL_QuitMainThread(void)

SDL_QuitProperties();
SDL_QuitLog();
SDL_QuitFilesystem();
SDL_QuitTicks();
SDL_QuitTLSData();

Expand Down
2 changes: 1 addition & 1 deletion src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ SDL_DYNAPI_PROC(const int*,SDL_GetAudioStreamInputChannelMap,(SDL_AudioStream *a
SDL_DYNAPI_PROC(const int*,SDL_GetAudioStreamOutputChannelMap,(SDL_AudioStream *a, int *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetAudioStreamProperties,(SDL_AudioStream *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetAudioStreamQueued,(SDL_AudioStream *a),(a),return)
SDL_DYNAPI_PROC(char*,SDL_GetBasePath,(void),(),return)
SDL_DYNAPI_PROC(const char*,SDL_GetBasePath,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_GetBooleanProperty,(SDL_PropertiesID a, const char *b, SDL_bool c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_GetCPUCacheLineSize,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_GetCPUCount,(void),(),return)
Expand Down
22 changes: 22 additions & 0 deletions src/filesystem/SDL_filesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,3 +400,25 @@ char **SDL_GlobDirectory(const char *path, const char *pattern, SDL_GlobFlags fl
return SDL_InternalGlobDirectory(path, pattern, flags, count, GlobDirectoryEnumerator, GlobDirectoryGetPathInfo, NULL);
}


static char *CachedBasePath = NULL;

const char *SDL_GetBasePath(void)
{
if (!CachedBasePath) {
CachedBasePath = SDL_SYS_GetBasePath();
}
return CachedBasePath;
}

void SDL_InitFilesystem(void)
{
CachedBasePath = NULL; // just in case.
}

void SDL_QuitFilesystem(void)
{
SDL_free(CachedBasePath);
CachedBasePath = NULL;
}

29 changes: 29 additions & 0 deletions src/filesystem/SDL_filesystem_c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <[email protected]>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

#ifndef SDL_filesystem_c_h_
#define SDL_filesystem_c_h_

extern void SDL_InitFilesystem(void);
extern void SDL_QuitFilesystem(void);

#endif

3 changes: 3 additions & 0 deletions src/filesystem/SDL_sysfilesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#ifndef SDL_sysfilesystem_h_
#define SDL_sysfilesystem_h_

// return a string that we can SDL_free(). It will be cached at the higher level.
extern char *SDL_SYS_GetBasePath(void);

int SDL_SYS_EnumerateDirectory(const char *path, const char *dirname, SDL_EnumerateDirectoryCallback cb, void *userdata);
int SDL_SYS_RemovePath(const char *path);
int SDL_SYS_RenamePath(const char *oldpath, const char *newpath);
Expand Down
2 changes: 1 addition & 1 deletion src/filesystem/android/SDL_sysfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

#include <unistd.h>

char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
/* The current working directory is / on Android */
SDL_Unsupported();
Expand Down
2 changes: 1 addition & 1 deletion src/filesystem/cocoa/SDL_sysfilesystem.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include <sys/stat.h>
#include <sys/types.h>

char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
@autoreleasepool {
NSBundle *bundle = [NSBundle mainBundle];
Expand Down
2 changes: 1 addition & 1 deletion src/filesystem/dummy/SDL_sysfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */

char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
SDL_Unsupported();
return NULL;
Expand Down
5 changes: 2 additions & 3 deletions src/filesystem/emscripten/SDL_sysfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@

#include <emscripten/emscripten.h>

char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
char *retval = "/";
return SDL_strdup(retval);
return SDL_strdup("/");
}

char *SDL_GetPrefPath(const char *org, const char *app)
Expand Down
2 changes: 1 addition & 1 deletion src/filesystem/gdk/SDL_sysfilesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include <XGameSaveFiles.h>

char *
SDL_GetBasePath(void)
SDL_SYS_GetBasePath(void)
{
/* NOTE: This function is a UTF8 version of the Win32 SDL_GetBasePath()!
* The GDK actually _recommends_ the 'A' functions over the 'W' functions :o
Expand Down
15 changes: 9 additions & 6 deletions src/filesystem/haiku/SDL_sysfilesystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,18 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */

extern "C" {
#include "../SDL_sysfilesystem.h"
}

#include <kernel/image.h>
#include <storage/Directory.h>
#include <storage/Entry.h>
#include <storage/FindDirectory.h>
#include <storage/Path.h>


char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
char name[MAXPATHLEN];

Expand All @@ -51,13 +55,12 @@ char *SDL_GetBasePath(void)

const size_t len = SDL_strlen(str);
char *retval = (char *) SDL_malloc(len + 2);
if (!retval) {
return NULL;
if (retval) {
SDL_memcpy(retval, str, len);
retval[len] = '/';
retval[len+1] = '\0';
}

SDL_memcpy(retval, str, len);
retval[len] = '/';
retval[len+1] = '\0';
return retval;
}

Expand Down
2 changes: 1 addition & 1 deletion src/filesystem/n3ds/SDL_sysfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
static char *MakePrefPath(const char *app);
static int CreatePrefPathDir(const char *pref);

char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
char *base_path = SDL_strdup("romfs:/");
return base_path;
Expand Down
33 changes: 20 additions & 13 deletions src/filesystem/ps2/SDL_sysfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */

char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
char *retval = NULL;
size_t len;
Expand All @@ -37,7 +37,9 @@ char *SDL_GetBasePath(void)
getcwd(cwd, sizeof(cwd));
len = SDL_strlen(cwd) + 2;
retval = (char *)SDL_malloc(len);
SDL_snprintf(retval, len, "%s/", cwd);
if (retval) {
SDL_snprintf(retval, len, "%s/", cwd);
}

return retval;
}
Expand All @@ -46,7 +48,7 @@ char *SDL_GetBasePath(void)
static void recursive_mkdir(const char *dir)
{
char tmp[FILENAME_MAX];
char *base = SDL_GetBasePath();
const char *base = SDL_GetBasePath();
char *p = NULL;
size_t len;

Expand All @@ -60,42 +62,47 @@ static void recursive_mkdir(const char *dir)
if (*p == '/') {
*p = 0;
// Just creating subfolders from current path
if (SDL_strstr(tmp, base) != NULL) {
if (base && SDL_strstr(tmp, base) != NULL) {
mkdir(tmp, S_IRWXU);
}

*p = '/';
}
}

SDL_free(base);
mkdir(tmp, S_IRWXU);
}

char *SDL_GetPrefPath(const char *org, const char *app)
{
char *retval = NULL;
size_t len;
char *base = SDL_GetBasePath();

if (!app) {
SDL_InvalidParamError("app");
return NULL;
}

if (!org) {
org = "";
}

const char *base = SDL_GetBasePath();
if (!base) {
return NULL;
}

len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
retval = (char *)SDL_malloc(len);
if (retval) {
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
}

if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
recursive_mkdir(retval);
}
SDL_free(base);

recursive_mkdir(retval);

return retval;
}
Expand Down
26 changes: 17 additions & 9 deletions src/filesystem/psp/SDL_sysfilesystem.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */

char *SDL_GetBasePath(void)
char *SDL_SYS_GetBasePath(void)
{
char *retval = NULL;
size_t len;
Expand All @@ -37,7 +37,9 @@ char *SDL_GetBasePath(void)
getcwd(cwd, sizeof(cwd));
len = SDL_strlen(cwd) + 2;
retval = (char *)SDL_malloc(len);
SDL_snprintf(retval, len, "%s/", cwd);
if (retval) {
SDL_snprintf(retval, len, "%s/", cwd);
}

return retval;
}
Expand All @@ -46,26 +48,32 @@ char *SDL_GetPrefPath(const char *org, const char *app)
{
char *retval = NULL;
size_t len;
char *base = SDL_GetBasePath();
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}

const char *base = SDL_GetBasePath();
if (!base) {
return NULL;
}

if (!org) {
org = "";
}

len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
retval = (char *)SDL_malloc(len);
if (retval) {
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
}

if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
mkdir(retval, 0755);
}
SDL_free(base);

mkdir(retval, 0755);
return retval;
}

Expand Down
Loading

0 comments on commit 0b8c3b6

Please sign in to comment.