|
29 | 29 |
|
30 | 30 | #include <filesystem> |
31 | 31 |
|
| 32 | +#ifdef __CYGWIN__ |
| 33 | +#include <algorithm> |
| 34 | +#endif |
| 35 | + |
32 | 36 | #include "paths.hh" |
33 | 37 |
|
34 | 38 | #include <unistd.h> |
|
37 | 41 | #include "fmt/format.h" |
38 | 42 | #include "opt_util.hh" |
39 | 43 |
|
40 | | -#ifdef _WIN32 |
41 | | -// Make sure we don't bring in all the extra junk with windows.h |
42 | | -# ifndef WIN32_LEAN_AND_MEAN |
43 | | -# define WIN32_LEAN_AND_MEAN |
44 | | -# endif |
45 | | -// stringapiset.h depends on this |
46 | | -# include <windows.h> |
47 | | -// For SUCCEEDED macro |
48 | | -# include <winerror.h> |
49 | | -// For WideCharToMultiByte |
50 | | -# include <stringapiset.h> |
51 | | -// For SHGetFolderPathW and various CSIDL "magic numbers" |
52 | | -# include <shlobj.h> |
53 | | - |
54 | | -namespace sago { |
55 | | -namespace internal { |
56 | | - |
57 | | -std::string |
58 | | -win32_utf16_to_utf8(const wchar_t* wstr) |
59 | | -{ |
60 | | - std::string res; |
61 | | - // If the 6th parameter is 0 then WideCharToMultiByte returns the number of |
62 | | - // bytes needed to store the result. |
63 | | - int actualSize = WideCharToMultiByte( |
64 | | - CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr); |
65 | | - if (actualSize > 0) { |
66 | | - // If the converted UTF-8 string could not be in the initial buffer. |
67 | | - // Allocate one that can hold it. |
68 | | - std::vector<char> buffer(actualSize); |
69 | | - actualSize = WideCharToMultiByte(CP_UTF8, |
70 | | - 0, |
71 | | - wstr, |
72 | | - -1, |
73 | | - &buffer[0], |
74 | | - static_cast<int>(buffer.size()), |
75 | | - nullptr, |
76 | | - nullptr); |
77 | | - res = buffer.data(); |
78 | | - } |
79 | | - if (actualSize == 0) { |
80 | | - // WideCharToMultiByte return 0 for errors. |
81 | | - throw std::runtime_error("UTF16 to UTF8 failed with error code: " |
82 | | - + std::to_string(GetLastError())); |
83 | | - } |
84 | | - return res; |
85 | | -} |
86 | | - |
87 | | -} // namespace internal |
88 | | -} // namespace sago |
89 | | - |
90 | | -class FreeCoTaskMemory { |
91 | | - LPWSTR pointer = NULL; |
92 | | - |
93 | | -public: |
94 | | - explicit FreeCoTaskMemory(LPWSTR pointer) : pointer(pointer) {}; |
95 | | - ~FreeCoTaskMemory() { CoTaskMemFree(pointer); } |
96 | | -}; |
97 | | - |
98 | | -static std::string |
99 | | -GetKnownWindowsFolder(REFKNOWNFOLDERID folderId, const char* errorMsg) |
100 | | -{ |
101 | | - LPWSTR wszPath = NULL; |
102 | | - HRESULT hr; |
103 | | - hr = SHGetKnownFolderPath(folderId, KF_FLAG_CREATE, NULL, &wszPath); |
104 | | - FreeCoTaskMemory scopeBoundMemory(wszPath); |
105 | | - |
106 | | - if (!SUCCEEDED(hr)) { |
107 | | - throw std::runtime_error(errorMsg); |
108 | | - } |
109 | | - return sago::internal::win32_utf16_to_utf8(wszPath); |
110 | | -} |
111 | | - |
112 | | -static std::string |
113 | | -GetAppData() |
114 | | -{ |
115 | | - return GetKnownWindowsFolder(FOLDERID_RoamingAppData, |
116 | | - "RoamingAppData could not be found"); |
117 | | -} |
118 | | - |
119 | | -static std::string |
120 | | -GetAppDataCommon() |
121 | | -{ |
122 | | - return GetKnownWindowsFolder(FOLDERID_ProgramData, |
123 | | - "ProgramData could not be found"); |
124 | | -} |
125 | | - |
126 | | -static std::string |
127 | | -GetAppDataLocal() |
128 | | -{ |
129 | | - return GetKnownWindowsFolder(FOLDERID_LocalAppData, |
130 | | - "LocalAppData could not be found"); |
131 | | -} |
132 | | -#endif |
133 | | - |
134 | 44 | namespace lnav::paths { |
135 | 45 |
|
136 | | -#ifdef _WIN32 |
| 46 | +#ifdef __CYGWIN__ |
137 | 47 | std::string |
138 | 48 | windows_to_unix_file_path(const std::string& input) |
139 | 49 | { |
@@ -167,13 +77,20 @@ windows_to_unix_file_path(const std::string& input) |
167 | 77 | std::filesystem::path |
168 | 78 | dotlnav() |
169 | 79 | { |
170 | | -#ifdef _WIN32 |
171 | | - auto home_env = windows_to_unix_file_path(GetAppDataLocal()); |
172 | | -#else |
173 | 80 | auto home_env = std::string(getenv_opt("HOME").value_or("")); |
174 | | -#endif |
175 | 81 | const auto* xdg_config_home = getenv("XDG_CONFIG_HOME"); |
176 | 82 |
|
| 83 | +#ifdef __CYGWIN__ |
| 84 | + const auto* app_data = getenv("APPDATA"); |
| 85 | + if (app_data != nullptr) { |
| 86 | + auto app_data_path = std::filesystem::path(windows_to_unix_file_path(app_data)); |
| 87 | + |
| 88 | + if (std::filesystem::is_directory(app_data_path)) { |
| 89 | + return app_data_path / "lnav"; |
| 90 | + } |
| 91 | + } |
| 92 | +#endif |
| 93 | + |
177 | 94 | if (!home_env.empty()) { |
178 | 95 | auto home_path = std::filesystem::path(home_env); |
179 | 96 |
|
|
0 commit comments