mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-28 18:50:59 +01:00
118 lines
5.5 KiB
C
118 lines
5.5 KiB
C
#pragma once
|
|
|
|
#include "fastfetch.h" // IWYU pragma: keep
|
|
|
|
#ifndef FF_DISABLE_DLOPEN
|
|
|
|
#if defined(_WIN32)
|
|
#define FF_DLOPEN_FLAGS 0
|
|
[[nodiscard]] void* dlopen(const char* path, int mode);
|
|
[[nodiscard]] void* dlsym(void* handle, const char* symbol);
|
|
int dlclose(void* handle);
|
|
#else
|
|
#include <dlfcn.h>
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#define FF_LIBRARY_EXTENSION ".dll"
|
|
#elif defined(__APPLE__)
|
|
#define FF_LIBRARY_EXTENSION ".dylib"
|
|
#else
|
|
#define FF_LIBRARY_EXTENSION ".so"
|
|
#endif
|
|
|
|
[[gnu::nonnull(1)]] static inline void ffLibraryUnload(void** handle) {
|
|
if (*handle) {
|
|
dlclose(*handle);
|
|
}
|
|
}
|
|
|
|
#define FF_LIBRARY_SYMBOL(symbolName) \
|
|
typeof(&symbolName) ff##symbolName;
|
|
|
|
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, libraryFileName, maxVersion, ...) \
|
|
[[gnu::cleanup(ffLibraryUnload)]] void* libraryObjectName = ffLibraryLoadSingle(libraryFileName, maxVersion); \
|
|
__VA_OPT__(if (__builtin_expect(libraryObjectName == nullptr, false)) libraryObjectName = ffLibraryLoadMulti(__VA_ARGS__, nullptr);) \
|
|
if (__builtin_expect(libraryObjectName == nullptr, false)) \
|
|
return returnValue;
|
|
|
|
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
|
|
FF_LIBRARY_LOAD(libraryObjectName, "dlopen(" libraryFileName ") failed", libraryFileName, maxVersion, ##__VA_ARGS__)
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
|
symbolMapping = (typeof(&symbolName)) dlsym(library, #symbolName); \
|
|
if (__builtin_expect(symbolMapping == nullptr, false)) \
|
|
return returnValue;
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
|
|
auto FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, returnValue);
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
|
|
auto ff##symbolName = (typeof(&symbolName)) dlsym(library, #symbolName);
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
|
|
auto FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, "dlsym " #symbolName " failed");
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
|
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, returnValue);
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_VAR_LAZY(library, varName, symbolName) \
|
|
(varName).ff##symbolName = (typeof(&symbolName)) dlsym(library, #symbolName);
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
|
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, "dlsym " #symbolName " failed");
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
|
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff##symbolName, symbolName, returnValue);
|
|
|
|
[[gnu::nonnull(1), nodiscard]] void* ffLibraryLoadSingle(const char* path, int maxVersion);
|
|
[[gnu::nonnull(1), nodiscard]] void* ffLibraryLoadMulti(const char* path, int maxVersion, ...);
|
|
|
|
#else
|
|
|
|
#define FF_LIBRARY_EXTENSION ""
|
|
|
|
#define FF_LIBRARY_SYMBOL(symbolName) \
|
|
typeof(&symbolName) ff##symbolName;
|
|
|
|
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
|
|
[[maybe_unused]] void* libraryObjectName = nullptr; // Placeholder
|
|
|
|
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
|
|
FF_LIBRARY_LOAD(libraryObjectName, , libraryFileName, maxVersion, ##__VA_ARGS__)
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
|
symbolMapping = (typeof(&symbolName)) &symbolName;
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
|
|
[[maybe_unused]] auto FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, returnValue);
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
|
|
[[maybe_unused]] auto ff##symbolName = (typeof(&symbolName)) &symbolName;
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
|
|
[[maybe_unused]] auto FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, "dlsym " #symbolName " failed");
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
|
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, returnValue);
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_VAR_LAZY(library, varName, symbolName) \
|
|
(varName).ff##symbolName = (typeof(&symbolName)) &symbolName;
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
|
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, "dlsym " #symbolName " failed");
|
|
|
|
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
|
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff##symbolName, symbolName, returnValue);
|
|
|
|
#endif
|
|
|
|
#if _WIN32
|
|
[[gnu::nonnull(1), nodiscard]] void* ffLibraryGetModule(const wchar_t* libraryFileName);
|
|
#endif
|
|
|
|
// Return false to stop iterating, true to continue
|
|
typedef bool (*FFLibraryIterateCallback)(const char* name, void* userData);
|
|
// Iterate over all loaded dynamic libraries. Returns true on success, false on failure.
|
|
[[nodiscard]] bool ffLibraryIterateDynamicLibs(FFLibraryIterateCallback callback, void* userData);
|