mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-29 16:26:39 +01:00
Detect data dirs at runtime
* Respecting the current platform * Using them where appropiate
This commit is contained in:
+127
-106
@@ -18,140 +18,160 @@
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
static void initConfigDirs(FFstate* state)
|
||||
#define FF_ENSURE_ONLY_ONCE_IN_LIST(list, element) \
|
||||
if(ffListFirstIndexComp(list, element, (bool(*)(const void*, const void*))ffStrbufEqual) < list->length - 1) \
|
||||
{ \
|
||||
ffStrbufDestroy(ffListGet(list, list->length - 1)); \
|
||||
--list->length; \
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void pathsAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId)
|
||||
{
|
||||
ffListInit(&state->configDirs, sizeof(FFstrbuf));
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
PWSTR pPath;
|
||||
if(SUCCEEDED(SHGetKnownFolderPath(folderId, 0, NULL, &pPath)))
|
||||
{
|
||||
PWSTR pPath;
|
||||
if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &pPath)))
|
||||
{
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
|
||||
ffStrbufInit(buffer);
|
||||
ffStrbufSetWS(buffer, pPath);
|
||||
ffStrbufReplaceAllC(buffer, '\\', '/');
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
}
|
||||
CoTaskMemFree(pPath);
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
{
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
|
||||
ffStrbufInitS(buffer, state->passwd->pw_dir);
|
||||
ffStrbufAppendS(buffer, "/Library/Preferences/");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
|
||||
if(ffStrSet(xdgConfigHome))
|
||||
{
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(buffer, 64);
|
||||
ffStrbufAppendS(buffer, xdgConfigHome);
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs);
|
||||
ffStrbufInit(buffer);
|
||||
ffStrbufSetWS(buffer, pPath);
|
||||
ffStrbufReplaceAllC(buffer, '\\', '/');
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer);
|
||||
}
|
||||
CoTaskMemFree(pPath);
|
||||
}
|
||||
|
||||
#endif
|
||||
void pathsAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix)
|
||||
{
|
||||
const char* value = getenv(env);
|
||||
if(!ffStrSet(value))
|
||||
return;
|
||||
|
||||
#define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \
|
||||
if(ffListFirstIndexComp(&state->configDirs, element, (bool(*)(const void*, const void*))ffStrbufEqual) < state->configDirs.length - 1) \
|
||||
{ \
|
||||
ffStrbufDestroy(ffListGet(&state->configDirs, state->configDirs.length - 1)); \
|
||||
--state->configDirs.length; \
|
||||
}
|
||||
FFstrbuf* buffer = ffListAdd(dirs);
|
||||
ffStrbufInitA(buffer, 64);
|
||||
ffStrbufAppendS(buffer, value);
|
||||
ffStrbufReplaceAllC(buffer, '\\', '/');
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
ffStrbufAppendS(buffer, suffix);
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
FFstrbuf* userConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(userConfigHome, 64);
|
||||
ffStrbufAppendS(userConfigHome, state->passwd->pw_dir);
|
||||
ffStrbufAppendS(userConfigHome, "/.config/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(userConfigHome)
|
||||
void pathsAddHome(FFlist* dirs, FFstate* state, const char* suffix)
|
||||
{
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs);
|
||||
ffStrbufInitA(buffer, 64);
|
||||
ffStrbufAppendS(buffer, state->passwd->pw_dir);
|
||||
ffStrbufAppendS(buffer, suffix);
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer);
|
||||
}
|
||||
|
||||
FFstrbuf* userHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(userHome, 64);
|
||||
ffStrbufAppendS(userHome, state->passwd->pw_dir);
|
||||
ffStrbufEnsureEndsWithC(userHome, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(userHome)
|
||||
void pathsAddAbsolute(FFlist* dirs, const char* path)
|
||||
{
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs);
|
||||
ffStrbufInitA(buffer, 64);
|
||||
ffStrbufAppendS(buffer, path);
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
if(getenv("MSYSTEM") && getenv("HOME"))
|
||||
{
|
||||
// We are in MSYS2 / Git Bash
|
||||
|
||||
FFstrbuf* msysConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(msysConfigHome, 64);
|
||||
ffStrbufAppendS(msysConfigHome, getenv("HOME"));
|
||||
ffStrbufReplaceAllC(msysConfigHome, '\\', '/');
|
||||
ffStrbufEnsureEndsWithC(msysConfigHome, '/');
|
||||
ffStrbufAppendS(msysConfigHome, ".config/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(msysConfigHome)
|
||||
|
||||
FFstrbuf* msysHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(msysHome, 64);
|
||||
ffStrbufAppendS(msysHome, getenv("HOME"));
|
||||
ffStrbufReplaceAllC(msysHome, '\\', '/');
|
||||
ffStrbufEnsureEndsWithC(msysHome, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(msysHome)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
|
||||
FFstrbuf xdgConfigDirs;
|
||||
ffStrbufInitA(&xdgConfigDirs, 64);
|
||||
ffStrbufAppendS(&xdgConfigDirs, getenv("XDG_CONFIG_DIRS"));
|
||||
void pathsAddEnv(FFlist* dirs, const char* env)
|
||||
{
|
||||
FFstrbuf value;
|
||||
ffStrbufInitA(&value, 64);
|
||||
ffStrbufAppendS(&value, getenv(env));
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < xdgConfigDirs.length)
|
||||
while (startIndex < value.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&xdgConfigDirs, startIndex, ':');
|
||||
xdgConfigDirs.chars[colonIndex] = '\0';
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, ':');
|
||||
value.chars[colonIndex] = '\0';
|
||||
|
||||
if(!ffStrSet(xdgConfigDirs.chars + startIndex))
|
||||
if(!ffStrSet(value.chars + startIndex))
|
||||
{
|
||||
startIndex = colonIndex + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(buffer, 64);
|
||||
ffStrbufAppendS(buffer, xdgConfigDirs.chars + startIndex);
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(buffer);
|
||||
pathsAddAbsolute(dirs, value.chars + startIndex);
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
ffStrbufDestroy(&xdgConfigDirs);
|
||||
|
||||
FFstrbuf* systemConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfigHome, 64);
|
||||
ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ETC"/xdg/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigHome)
|
||||
ffStrbufDestroy(&value);
|
||||
}
|
||||
|
||||
static void initConfigDirs(FFstate* state)
|
||||
{
|
||||
ffListInit(&state->configDirs, sizeof(FFstrbuf));
|
||||
|
||||
#ifdef _WIN32
|
||||
pathsAddKnownFolder(&state->configDirs, &FOLDERID_RoamingAppData);
|
||||
pathsAddKnownFolder(&state->configDirs, &FOLDERID_LocalAppData);
|
||||
#elif defined(__APPLE__)
|
||||
pathsAddHome(&state->configDirs, state, "/Library/Preferences/");
|
||||
#else
|
||||
pathsAddEnv(&state->configDirs, "XDG_CONFIG_HOME");
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
FFstrbuf* systemConfig = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfig, 64);
|
||||
ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ETC"/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfig)
|
||||
|
||||
FFstrbuf* systemConfigInstall = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfigInstall, 64);
|
||||
ffStrbufAppendS(systemConfigInstall, FASTFETCH_TARGET_DIR_INSTALL_SYSCONF"/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigInstall)
|
||||
|
||||
pathsAddHome(&state->configDirs, state, "/.config/");
|
||||
pathsAddHome(&state->configDirs, state, "");
|
||||
|
||||
#ifdef _WIN32
|
||||
if(getenv("MSYSTEM") && getenv("HOME"))
|
||||
{
|
||||
// We are in MSYS2 / Git Bash
|
||||
pathsAddEnvSuffix(&state->configDirs, "HOME", ".config/");
|
||||
pathsAddEnvSuffix(&state->configDirs, "HOME", "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef FF_ENSURE_ONLY_ONCE_IN_LIST
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
pathsAddEnv(&state->configDirs, "XDG_CONFIG_DIRS");
|
||||
pathsAddAbsolute(&state->configDirs, FASTFETCH_TARGET_DIR_ETC"/xdg/");
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
pathsAddAbsolute(&state->configDirs, FASTFETCH_TARGET_DIR_ETC"/");
|
||||
pathsAddAbsolute(&state->configDirs, FASTFETCH_TARGET_DIR_INSTALL_SYSCONF"/");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void initDataDirs(FFstate* state)
|
||||
{
|
||||
ffListInit(&state->dataDirs, sizeof(FFstrbuf));
|
||||
|
||||
#ifdef _WIN32
|
||||
pathsAddKnownFolder(&state->dataDirs, &FOLDERID_RoamingAppData);
|
||||
pathsAddKnownFolder(&state->dataDirs, &FOLDERID_LocalAppData);
|
||||
#elif defined(__APPLE__)
|
||||
pathsAddHome(&state->dataDirs, state, "/Library/Application Support/");
|
||||
#else
|
||||
pathsAddEnv(&state->dataDirs, "XDG_DATA_HOME");
|
||||
#endif
|
||||
|
||||
pathsAddHome(&state->dataDirs, state, "/.local/share/");
|
||||
pathsAddHome(&state->dataDirs, state, "");
|
||||
|
||||
#ifdef _WIN32
|
||||
if(getenv("MSYSTEM") && getenv("HOME"))
|
||||
{
|
||||
// We are in MSYS2 / Git Bash
|
||||
pathsAddEnvSuffix(&state->dataDirs, "HOME", ".local/share/");
|
||||
pathsAddEnvSuffix(&state->dataDirs, "HOME", "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
pathsAddEnv(&state->dataDirs, "XDG_DATA_DIRS");
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
pathsAddAbsolute(&state->dataDirs, FASTFETCH_TARGET_DIR_USR"/local/share/");
|
||||
pathsAddAbsolute(&state->dataDirs, FASTFETCH_TARGET_DIR_USR"/share/");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void initState(FFstate* state)
|
||||
@@ -172,6 +192,7 @@ static void initState(FFstate* state)
|
||||
uname(&state->utsname);
|
||||
|
||||
initConfigDirs(state);
|
||||
initDataDirs(state);
|
||||
}
|
||||
|
||||
static void initModuleArg(FFModuleArgs* args)
|
||||
|
||||
+4
-19
@@ -144,11 +144,6 @@ done:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
FFstrbuf absolutePath;
|
||||
@@ -164,22 +159,17 @@ bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeF
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileHomeValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
bool foundAFile = false;
|
||||
|
||||
FFstrbuf baseDir;
|
||||
ffStrbufInitA(&baseDir, 64);
|
||||
|
||||
for(uint32_t i = 0; i < instance->state.configDirs.length; i++)
|
||||
for(uint32_t i = 0; i < list->length; i++)
|
||||
{
|
||||
//We need to copy the config dir each time, because it used by multiple threads, so we can't directly write to it.
|
||||
ffStrbufSet(&baseDir, ffListGet(&instance->state.configDirs, i));
|
||||
//We need to copy the dir each time, because it used by multiple threads, so we can't directly write to it.
|
||||
ffStrbufSet(&baseDir, ffListGet(list, i));
|
||||
ffStrbufAppendS(&baseDir, relativeFile);
|
||||
|
||||
if(ffParsePropFileValues(baseDir.chars, numQueries, queries))
|
||||
@@ -203,8 +193,3 @@ bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativ
|
||||
|
||||
return foundAFile;
|
||||
}
|
||||
|
||||
bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileConfigValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
+36
-4
@@ -14,10 +14,42 @@ typedef struct FFpropquery
|
||||
bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
|
||||
static inline bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileHomeValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileList(const FFlist* list, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileListValues(list, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
return ffParsePropFileListValues(&instance->state.configDirs, relativeFile, numQueries, queries);
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileConfigValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileDataValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
return ffParsePropFileListValues(&instance->state.dataDirs, relativeFile, numQueries, queries);
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileData(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileDataValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user