💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
3.6 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <engine/utility/paths.hpp>
  20. #include <cstddef>
  21. #include <limits.h>
  22. #include <stdexcept>
  23. #if defined(_WIN32)
  24. #include <Shlobj.h>
  25. #include <windows.h>
  26. #else
  27. #include <pwd.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <unistd.h>
  31. #endif
  32. std::filesystem::path get_executable_path()
  33. {
  34. std::filesystem::path executable_path;
  35. #if defined(_WIN32)
  36. // Get executable path on Windows
  37. std::wstring path(MAX_PATH, L'\0');
  38. GetModuleFileNameW(GetModuleHandleW(nullptr), path.data(), MAX_PATH);
  39. path.erase(std::find(path.begin(), path.end(), L'\0'), path.end());
  40. executable_path = path;
  41. #else
  42. // Get executable path on Linux
  43. char path[PATH_MAX];
  44. ssize_t length = ::readlink("/proc/self/exe", path, sizeof(path) - 1);
  45. if (length != -1)
  46. {
  47. path[length] = '\0';
  48. executable_path = path;
  49. }
  50. #endif
  51. return executable_path;
  52. }
  53. std::filesystem::path get_executable_data_path()
  54. {
  55. #if defined(_WIN32)
  56. return get_executable_path().parent_path();
  57. #else
  58. return get_executable_path().parent_path().parent_path() / "share";
  59. #endif
  60. }
  61. std::filesystem::path get_local_config_path()
  62. {
  63. std::filesystem::path local_config_path;
  64. #if defined(_WIN32)
  65. std::wstring path(MAX_PATH, L'\0');
  66. if (SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, path.data()) == S_OK)
  67. {
  68. path.erase(std::find(path.begin(), path.end(), L'\0'), path.end());
  69. local_config_path = path;
  70. }
  71. // Windows Vista+
  72. // wchar_t* path_buffer = nullptr;
  73. // if (SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, nullptr, &path_buffer) == S_OK)
  74. // {
  75. // local_config_path = std::filesystem::path(path_buffer);
  76. // CoTaskMemFree(static_cast<void*>(path_buffer));
  77. // }
  78. #else
  79. // Determine home path
  80. std::filesystem::path home_path = getpwuid(getuid())->pw_dir;
  81. // Determine config path
  82. char* xdg_config_home = std::getenv("XDG_CONFIG_HOME");
  83. if (!xdg_config_home)
  84. {
  85. // Default to $HOME/.config/ as per:
  86. // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables
  87. local_config_path = home_path / ".config/";
  88. }
  89. else
  90. {
  91. local_config_path = xdg_config_home;
  92. }
  93. #endif
  94. return local_config_path;
  95. }
  96. std::filesystem::path get_shared_config_path()
  97. {
  98. #if defined(_WIN32)
  99. std::filesystem::path shared_config_path;
  100. std::wstring path(MAX_PATH, L'\0');
  101. if (SHGetFolderPathW(nullptr, CSIDL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, path.data()) == S_OK)
  102. {
  103. path.erase(std::find(path.begin(), path.end(), L'\0'), path.end());
  104. shared_config_path = path;
  105. }
  106. // Windows Vista+
  107. // wchar_t* path_buffer = nullptr;
  108. // if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, nullptr, &path_buffer) == S_OK)
  109. // {
  110. // shared_config_path = path_buffer;
  111. // CoTaskMemFree(static_cast<void*>(path_buffer));
  112. // }
  113. return shared_config_path;
  114. #else
  115. return get_local_config_path();
  116. #endif
  117. }