path.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #pragma once
  2. #include <nall/string.hpp>
  3. namespace nall::Path {
  4. inline auto active() -> string {
  5. char path[PATH_MAX] = "";
  6. (void)getcwd(path, PATH_MAX);
  7. string result = path;
  8. if(!result) result = ".";
  9. result.transform("\\", "/");
  10. if(!result.endsWith("/")) result.append("/");
  11. return result;
  12. }
  13. inline auto real(string_view name) -> string {
  14. string result;
  15. char path[PATH_MAX] = "";
  16. if(::realpath(name, path)) result = Location::path(string{path}.transform("\\", "/"));
  17. if(!result) return active();
  18. result.transform("\\", "/");
  19. if(!result.endsWith("/")) result.append("/");
  20. return result;
  21. }
  22. inline auto program() -> string {
  23. #if defined(PLATFORM_WINDOWS)
  24. wchar_t path[PATH_MAX] = L"";
  25. GetModuleFileName(nullptr, path, PATH_MAX);
  26. string result = (const char*)utf8_t(path);
  27. result.transform("\\", "/");
  28. return Path::real(result);
  29. #else
  30. Dl_info info;
  31. dladdr((void*)&program, &info);
  32. return Path::real(info.dli_fname);
  33. #endif
  34. }
  35. // /
  36. // c:/
  37. inline auto root() -> string {
  38. #if defined(PLATFORM_WINDOWS)
  39. wchar_t path[PATH_MAX] = L"";
  40. SHGetFolderPathW(nullptr, CSIDL_WINDOWS | CSIDL_FLAG_CREATE, nullptr, 0, path);
  41. string result = (const char*)utf8_t(path);
  42. result.transform("\\", "/");
  43. return slice(result, 0, 3);
  44. #else
  45. return "/";
  46. #endif
  47. }
  48. // /home/username/
  49. // c:/users/username/
  50. inline auto user() -> string {
  51. #if defined(PLATFORM_WINDOWS)
  52. wchar_t path[PATH_MAX] = L"";
  53. SHGetFolderPathW(nullptr, CSIDL_PROFILE | CSIDL_FLAG_CREATE, nullptr, 0, path);
  54. string result = (const char*)utf8_t(path);
  55. result.transform("\\", "/");
  56. #else
  57. struct passwd* userinfo = getpwuid(getuid());
  58. string result = userinfo->pw_dir;
  59. #endif
  60. if(!result) result = ".";
  61. if(!result.endsWith("/")) result.append("/");
  62. return result;
  63. }
  64. // /home/username/Desktop/
  65. // c:/users/username/Desktop/
  66. inline auto desktop(string_view name = {}) -> string {
  67. return {user(), "Desktop/", name};
  68. }
  69. //todo: MacOS uses the same location for userData() and userSettings()
  70. //... is there a better option here?
  71. // /home/username/.config/
  72. // ~/Library/Application Support/
  73. // c:/users/username/appdata/roaming/
  74. inline auto userSettings() -> string {
  75. #if defined(PLATFORM_WINDOWS)
  76. wchar_t path[PATH_MAX] = L"";
  77. SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
  78. string result = (const char*)utf8_t(path);
  79. result.transform("\\", "/");
  80. #elif defined(PLATFORM_MACOS)
  81. string result = {Path::user(), "Library/Application Support/"};
  82. #else
  83. string result;
  84. if(const char *env = getenv("XDG_CONFIG_HOME")) {
  85. result = string(env);
  86. } else {
  87. result = {Path::user(), ".config/"};
  88. }
  89. #endif
  90. if(!result) result = ".";
  91. if(!result.endsWith("/")) result.append("/");
  92. return result;
  93. }
  94. // /home/username/.local/share/
  95. // ~/Library/Application Support/
  96. // c:/users/username/appdata/local/
  97. inline auto userData() -> string {
  98. #if defined(PLATFORM_WINDOWS)
  99. wchar_t path[PATH_MAX] = L"";
  100. SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
  101. string result = (const char*)utf8_t(path);
  102. result.transform("\\", "/");
  103. #elif defined(PLATFORM_MACOS)
  104. string result = {Path::user(), "Library/Application Support/"};
  105. #else
  106. string result;
  107. if(const char *env = getenv("XDG_DATA_HOME")) {
  108. result = string(env);
  109. } else {
  110. result = {Path::user(), ".local/share/"};
  111. }
  112. #endif
  113. if(!result) result = ".";
  114. if(!result.endsWith("/")) result.append("/");
  115. return result;
  116. }
  117. // /usr/share
  118. // /Library/Application Support/
  119. // c:/ProgramData/
  120. inline auto sharedData() -> string {
  121. #if defined(PLATFORM_WINDOWS)
  122. wchar_t path[PATH_MAX] = L"";
  123. SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
  124. string result = (const char*)utf8_t(path);
  125. result.transform("\\", "/");
  126. #elif defined(PLATFORM_MACOS)
  127. string result = "/Library/Application Support/";
  128. #else
  129. string result = "/usr/share/";
  130. #endif
  131. if(!result) result = ".";
  132. if(!result.endsWith("/")) result.append("/");
  133. return result;
  134. }
  135. // /tmp
  136. // c:/users/username/AppData/Local/Temp/
  137. inline auto temporary() -> string {
  138. #if defined(PLATFORM_WINDOWS)
  139. wchar_t path[PATH_MAX] = L"";
  140. GetTempPathW(PATH_MAX, path);
  141. string result = (const char*)utf8_t(path);
  142. result.transform("\\", "/");
  143. #elif defined(P_tmpdir)
  144. string result = P_tmpdir;
  145. #else
  146. string result = "/tmp/";
  147. #endif
  148. if(!result.endsWith("/")) result.append("/");
  149. return result;
  150. }
  151. }