Skip to content

Instantly share code, notes, and snippets.

@flibitijibibo
Last active November 21, 2017 23:31
Show Gist options
  • Save flibitijibibo/5139524 to your computer and use it in GitHub Desktop.
Save flibitijibibo/5139524 to your computer and use it in GitHub Desktop.
flibit's XDG/OSX Save and Config Folder Thing
/* XDG/OSX Save and Config Folder Thing
* Written by Ethan "flibitijibibo" Lee
* http://www.flibitijibibo.com/
*
* Released under public domain.
* No warranty implied; use at your own risk.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
static const char *gameName = "GameName";
/* Gets the ideal save directory for the target platform.
* @param output A character array, ideally PATH_MAX characters long.
*
* Typical Usage:
* char savePath[PATH_MAX];
* getUserSaveDir(savePath);
* strcat(savePath, "/save.sav");
* FILE *saveFile = fopen(savePath, "rwb");
*/
static void getUserSaveDir(char* output)
{
#if defined(__APPLE__)
char *homeDir = getenv("HOME");
if (homeDir == NULL)
{
strcpy(output, "."); /* Oh well. */
}
else
{
strcpy(output, homeDir);
strcat(output, "/Library/Application Support/");
strcat(output, gameName);
mkdir(output, 0777);
}
#elif defined(__linux__)
static int warnFail = 1;
char *homeDir = getenv("XDG_DATA_HOME");
if (homeDir == NULL)
{
homeDir = getenv("HOME");
if (homeDir == NULL)
{
if (warnFail)
{
warnFail = 0;
fprintf(stderr, "Couldn't find XDG_DATA_HOME or HOME.\n");
fprintf(stderr, "Fall back to '.'\n");
}
strcpy(output, "."); /* Oh well. */
}
else
{
if (warnFail)
{
warnFail = 0;
fprintf(stderr, "Couldn't find XDG_DATA_HOME.\n");
fprintf(stderr, "Fall back to hardcoded ~/.local/share/.\n");
}
strcpy(output, homeDir);
strcat(output, "/.local/share/");
strcat(output, gameName);
mkdir(output, 0777);
}
}
else
{
strcpy(output, homeDir);
strcat(output, "/");
strcat(output, gameName);
mkdir(output, 0777);
}
#else
#error I need a getUserSaveDir implementation for this platform!
#endif
}
/* Gets the ideal config directory for the target platform.
* @param output A character array, ideally PATH_MAX characters long.
*
* Typical Usage:
* char configPath[PATH_MAX];
* getUserConfigDir(configPath);
* strcat(configPath, "/config.cfg");
* FILE *configFile = fopen(configPath, "rw");
*/
static void getUserConfigDir(char* output)
{
#if defined(__APPLE__)
char *homeDir = getenv("HOME");
if (homeDir == NULL)
{
strcpy(output, "."); /* Oh well. */
}
else
{
strcpy(output, homeDir);
strcat(output, "/Library/Application Support/");
strcat(output, gameName);
mkdir(output, 0777);
}
#elif defined(__linux__)
static int warnFail = 1;
char *homeDir = getenv("XDG_CONFIG_HOME");
if (homeDir == NULL)
{
homeDir = getenv("HOME");
if (homeDir == NULL)
{
if (warnFail)
{
warnFail = 0;
fprintf(stderr, "Couldn't find XDG_CONFIG_HOME or HOME.\n");
fprintf(stderr, "Fall back to '.'\n");
}
strcpy(output, "."); /* Oh well. */
}
else
{
if (warnFail)
{
warnFail = 0;
fprintf(stderr, "Couldn't find XDG_CONFIG_HOME.\n");
fprintf(stderr, "Fall back to hardcoded ~/.config/.\n");
}
strcpy(output, homeDir);
strcat(output, "/.config/");
strcat(output, gameName);
mkdir(output, 0777);
}
}
else
{
strcpy(output, homeDir);
strcat(output, "/");
strcat(output, gameName);
mkdir(output, 0777);
}
#else
#error I need a getUserConfigDir implementation for this platform!
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment