- 重构模块使用新的代码风格 - 老代码 (src 目录下的代码) 继续使用之前的代码风格 通过在需要不同代码风格的目录下放对应 .clang-format 配置文件实现
101 lines
2.4 KiB
C
101 lines
2.4 KiB
C
#include "config/loader.h"
|
|
|
|
#include <dlfcn.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include "base/log.h"
|
|
#include "base/memory.h"
|
|
|
|
static char *config_loader_join_path(const char *base, const char *suffix) {
|
|
if (!base || !suffix) return nullptr;
|
|
|
|
size_t base_len = strlen(base);
|
|
size_t suffix_len = strlen(suffix);
|
|
char *path = p_new(char, base_len + suffix_len + 1);
|
|
memcpy(path, base, base_len);
|
|
memcpy(path + base_len, suffix, suffix_len + 1);
|
|
return path;
|
|
}
|
|
|
|
static bool config_loader_resolve_path(
|
|
char **out_path,
|
|
bool *out_is_explicit,
|
|
const char *override_path
|
|
) {
|
|
const char *path = override_path;
|
|
if (path && *path) {
|
|
*out_path = p_strdup(path);
|
|
*out_is_explicit = true;
|
|
return true;
|
|
}
|
|
|
|
path = getenv("ZDWM_CONFIG_LIB");
|
|
if (path && *path) {
|
|
*out_path = p_strdup(path);
|
|
*out_is_explicit = true;
|
|
return true;
|
|
}
|
|
|
|
path = getenv("XDG_CONFIG_HOME");
|
|
if (path && *path) {
|
|
*out_path = config_loader_join_path(path, "/zdwm/config.so");
|
|
*out_is_explicit = false;
|
|
return *out_path != nullptr;
|
|
}
|
|
|
|
path = getenv("HOME");
|
|
if (path && *path) {
|
|
*out_path = config_loader_join_path(path, "/.config/zdwm/config.so");
|
|
*out_is_explicit = false;
|
|
return *out_path != nullptr;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool config_loader_load(config_loader_t *loader, const char *override_path) {
|
|
if (!loader) return false;
|
|
config_loader_cleanup(loader);
|
|
|
|
bool is_explicit = false;
|
|
if (!config_loader_resolve_path(&loader->path, &is_explicit, override_path)) {
|
|
return false;
|
|
}
|
|
|
|
if (access(loader->path, F_OK) != 0) {
|
|
if (!is_explicit) return true;
|
|
|
|
warn("config library not found: %s", loader->path);
|
|
config_loader_cleanup(loader);
|
|
return false;
|
|
}
|
|
|
|
loader->handle = dlopen(loader->path, RTLD_NOW | RTLD_LOCAL);
|
|
if (!loader->handle) {
|
|
warn("failed to load config library %s: %s", loader->path, dlerror());
|
|
config_loader_cleanup(loader);
|
|
return false;
|
|
}
|
|
|
|
dlerror();
|
|
loader->setup = (zdwm_config_setup_fn *)dlsym(loader->handle, "setup");
|
|
const char *error = dlerror();
|
|
if (!error) return true;
|
|
|
|
warn("failed to resolve setup from %s: %s", loader->path, error);
|
|
config_loader_cleanup(loader);
|
|
return false;
|
|
}
|
|
|
|
void config_loader_cleanup(config_loader_t *loader) {
|
|
if (!loader) return;
|
|
|
|
loader->setup = nullptr;
|
|
|
|
if (loader->handle) dlclose(loader->handle);
|
|
loader->handle = nullptr;
|
|
|
|
p_delete(&loader->path);
|
|
}
|