-
Notifications
You must be signed in to change notification settings - Fork 216
volk: prefer XDG config dir for volk_config, add tests & docs (#792) #810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
8719f2c
d1b742c
f4e66d5
b1d56d1
3ef4774
2850ec0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,10 +12,13 @@ | |
| #include <stdlib.h> | ||
| #include <string.h> | ||
| #if defined(_MSC_VER) | ||
| #include <direct.h> | ||
| #include <io.h> | ||
| #define access _access | ||
| #define F_OK 0 | ||
| #else | ||
| #include <sys/stat.h> | ||
| #include <sys/types.h> | ||
| #include <unistd.h> | ||
| #endif | ||
| #include <volk/volk_prefs.h> | ||
|
|
@@ -24,51 +27,128 @@ void volk_get_config_path(char* path, bool read) | |
| { | ||
| if (!path) | ||
| return; | ||
| const char* suffix = "/.volk/volk_config"; | ||
| const char* suffix2 = "/volk/volk_config"; // non-hidden | ||
| char* home = NULL; | ||
| const char* legacy_suffix = "/.volk/volk_config"; | ||
| const char* nonhidden_suffix = "/volk/volk_config"; // non-hidden | ||
| char tmp[512] = { 0 }; | ||
|
|
||
| // allows config redirection via env variable | ||
| home = getenv("VOLK_CONFIGPATH"); | ||
| if (home != NULL) { | ||
| strncpy(path, home, 512); | ||
| strcat(path, suffix2); | ||
| if (!read || access(path, F_OK) != -1) { | ||
| /* helper to ensure directory exists for write-mode */ | ||
| { | ||
| #if defined(_MSC_VER) | ||
| /* use _mkdir on MSVC */ | ||
| #else | ||
| /* ensure sys/stat available */ | ||
| #endif | ||
|
||
| } | ||
|
|
||
| /* 1) explicit override via VOLK_CONFIGPATH */ | ||
| const char* env_override = getenv("VOLK_CONFIGPATH"); | ||
| if (env_override) { | ||
| snprintf(tmp, sizeof(tmp), "%s%s", env_override, nonhidden_suffix); | ||
| if (!read || access(tmp, F_OK) == 0) { | ||
| strncpy(path, tmp, 512); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| /* 2) XDG_CONFIG_HOME/volk if XDG set */ | ||
| const char* xdg = getenv("XDG_CONFIG_HOME"); | ||
| if (xdg) { | ||
| snprintf(tmp, sizeof(tmp), "%s/volk/volk_config", xdg); | ||
| if (!read) { | ||
| char parent[512]; | ||
| char dir[512]; | ||
| /* ensure XDG_CONFIG_HOME exists, then create XDG/volk */ | ||
| snprintf(parent, sizeof(parent), "%s", xdg); | ||
| snprintf(dir, sizeof(dir), "%s/volk", xdg); | ||
| #if defined(_MSC_VER) | ||
| _mkdir(parent); | ||
| _mkdir(dir); | ||
| #else | ||
| struct stat st = { 0 }; | ||
| if (stat(parent, &st) == -1) { | ||
| mkdir(parent, 0755); | ||
| } | ||
| if (stat(dir, &st) == -1) { | ||
| mkdir(dir, 0755); | ||
| } | ||
| #endif | ||
|
Comment on lines
+54
to
+65
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The old function behavior was to just check for possible folders and return the path. Why is it necessary to create folders now?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original function returned a path string, but didn't guarantee that path could actually be used for writing. If a user called volk_get_config_path(path, false) (write-mode) and tried to write the config file, it would fail with a file I/O error if the parent directories didn't exist. I agree this might be outside the function's scope. Would you prefer:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Go with option B. This function should just discover where to look for files =D |
||
| } | ||
| if (!read || access(tmp, F_OK) == 0) { | ||
| strncpy(path, tmp, 512); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // check for user-local config file | ||
| home = getenv("HOME"); | ||
| if (home != NULL) { | ||
| strncpy(path, home, 512); | ||
| strcat(path, suffix); | ||
| if (!read || (access(path, F_OK) != -1)) { | ||
| /* 3) $HOME/.config/volk */ | ||
| const char* home = getenv("HOME"); | ||
| if (home) { | ||
| snprintf(tmp, sizeof(tmp), "%s/.config/volk/volk_config", home); | ||
| if (!read) { | ||
| char parent[512]; | ||
| char dir[512]; | ||
| /* ensure HOME/.config exists, then create HOME/.config/volk */ | ||
| snprintf(parent, sizeof(parent), "%s/.config", home); | ||
| snprintf(dir, sizeof(dir), "%s/.config/volk", home); | ||
| #if defined(_MSC_VER) | ||
| _mkdir(parent); | ||
| _mkdir(dir); | ||
| #else | ||
| struct stat st = { 0 }; | ||
| if (stat(parent, &st) == -1) { | ||
| mkdir(parent, 0755); | ||
| } | ||
| if (stat(dir, &st) == -1) { | ||
| mkdir(dir, 0755); | ||
| } | ||
| #endif | ||
| } | ||
| if (!read || access(tmp, F_OK) == 0) { | ||
| strncpy(path, tmp, 512); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // check for config file in APPDATA (Windows) | ||
| home = getenv("APPDATA"); | ||
| if (home != NULL) { | ||
| strncpy(path, home, 512); | ||
| strcat(path, suffix); | ||
| if (!read || (access(path, F_OK) != -1)) { | ||
| /* 4) legacy $HOME/.volk */ | ||
| if (home) { | ||
| snprintf(tmp, sizeof(tmp), "%s%s", home, legacy_suffix); | ||
| if (!read || access(tmp, F_OK) == 0) { | ||
| strncpy(path, tmp, 512); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // check for system-wide config file | ||
| if (access("/etc/volk/volk_config", F_OK) != -1) { | ||
| strncpy(path, "/etc", 512); | ||
| strcat(path, suffix2); | ||
| if (!read || (access(path, F_OK) != -1)) { | ||
| /* 5) Windows APPDATA fallback */ | ||
| const char* appdata = getenv("APPDATA"); | ||
| if (appdata) { | ||
| snprintf(tmp, sizeof(tmp), "%s%s", appdata, legacy_suffix); | ||
| if (!read || access(tmp, F_OK) == 0) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The old behavior was |
||
| strncpy(path, tmp, 512); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // If still no path was found set path[0] to '0' and fall through | ||
| path[0] = 0; | ||
| /* System-wide */ | ||
| if (access("/etc/volk/volk_config", F_OK) == 0) { | ||
| strncpy(path, "/etc/volk/volk_config", 512); | ||
| return; | ||
| } | ||
| /* If nothing found, follow the XDG-first fallback behavior: | ||
| - if XDG_CONFIG_HOME is set, return XDG_CONFIG_HOME/volk/volk_config | ||
| - else if HOME is set, return HOME/.config/volk/volk_config | ||
| - otherwise return empty string | ||
| This ensures read-mode returns the new XDG location as fallback. */ | ||
| if (xdg) { | ||
| snprintf(tmp, sizeof(tmp), "%s/volk/volk_config", xdg); | ||
| strncpy(path, tmp, 512); | ||
| return; | ||
| } | ||
| if (home) { | ||
| snprintf(tmp, sizeof(tmp), "%s/.config/volk/volk_config", home); | ||
| strncpy(path, tmp, 512); | ||
| return; | ||
| } | ||
|
||
|
|
||
| path[0] = '\0'; | ||
| return; | ||
| } | ||
|
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does anything in this file need to change? The intended behavior before was to skip over these tests of the required dependencies are missing.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's OK to go with fetchContent after the check. One more thing though: We have similar stuff in other parts of our CMake structure. That'd need to be combined. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,13 +10,39 @@ if(NOT ENABLE_TESTING) | |
| return() | ||
| endif(NOT ENABLE_TESTING) | ||
|
|
||
| find_package(fmt) | ||
| find_package(GTest) | ||
| include(FetchContent) | ||
|
|
||
| if(NOT fmt_FOUND OR NOT GTest_FOUND) | ||
| message(warning "Missing fmtlib and/or googletest for this test suite") | ||
| return() | ||
| endif(NOT fmt_FOUND OR NOT GTest_FOUND) | ||
| # Prefer system fmt if available, otherwise fetch a pinned version. | ||
| find_package(fmt QUIET) | ||
| if(NOT fmt_FOUND) | ||
| message(STATUS "fmt not found: fetching fmt via FetchContent") | ||
| FetchContent_Declare( | ||
| fmt | ||
| GIT_REPOSITORY https://github.com/fmtlib/fmt.git | ||
| GIT_TAG 10.2.1 | ||
| GIT_SHALLOW TRUE | ||
| ) | ||
| FetchContent_MakeAvailable(fmt) | ||
| endif() | ||
|
||
|
|
||
| # Prefer system GTest if available, otherwise fetch googletest. | ||
| find_package(GTest QUIET) | ||
| if(NOT GTest_FOUND) | ||
| message(STATUS "GTest not found: fetching googletest via FetchContent") | ||
| set(BUILD_GMOCK OFF CACHE BOOL "Disable gmock" FORCE) | ||
| set(INSTALL_GTEST OFF CACHE BOOL "Disable gtest install" FORCE) | ||
| FetchContent_Declare( | ||
| googletest | ||
| GIT_REPOSITORY https://github.com/google/googletest.git | ||
| GIT_TAG release-1.12.1 | ||
|
||
| GIT_SHALLOW TRUE | ||
| ) | ||
| FetchContent_GetProperties(googletest) | ||
| if(NOT googletest_POPULATED) | ||
| FetchContent_Populate(googletest) | ||
| add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) | ||
| endif() | ||
| endif() | ||
|
|
||
| file(GLOB volk_test_files "test_*.cc") | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.