-
Notifications
You must be signed in to change notification settings - Fork 2.1k
support unicode in paths #998
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #998 +/- ##
==========================================
+ Coverage 64.14% 64.32% +0.18%
==========================================
Files 17 17
Lines 3327 3330 +3
Branches 1125 1126 +1
==========================================
+ Hits 2134 2142 +8
+ Misses 766 760 -6
- Partials 427 428 +1 ☔ View full report in Codecov by Sentry. |
Thanks for the PR. I need some time to look through the changes. In the meantime, could you please rebase onto current head and resolve the conflicts? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I had a careful look at the implementation, I see two major issues:
- Switching to
std::wstring
underUNICODE
definition will break existing user code. This is something we definitely want to avoid. Support for wide strings should be transparent. - Many of the functions are duplicated with respect to wide strings. For maintenance purposes, the
std::basic_string
code should be unified using templates to encapsulate the logic into a single function or method.
Now I have modified the template<class CharT>
static const std::basic_string<typename std::enable_if_t<std::is_same_v<CharT, wchar_t>, CharT>> DefaultLogDir() {
std::wstring env = getenvw((wchar_t*)TEXT("GOOGLE_LOG_DIR"));
if (!env.empty()) {
return env;
}
env = getenvw((wchar_t*)TEXT("TEST_TMPDIR"));
return env;
}
template<class CharT>
static const std::basic_string<typename std::enable_if_t<std::is_same_v<CharT, char>, CharT>> DefaultLogDir()
{
const char* env;
env = getenv("GOOGLE_LOG_DIR");
if (env != nullptr && env[0] != '\0') {
return env;
}
env = getenv("TEST_TMPDIR");
if (env != nullptr && env[0] != '\0') {
return env;
}
return "";
}
template<class CharT>
static const std::basic_string<typename std::enable_if_t<!std::is_same_v<CharT, char> && !std::is_same_v<CharT, wchar_t>, CharT>> DefaultLogDir()
{
return {};
} |
In the code above, Something like this should do the job: namespace details {
using std::getenv; // char variant
const wchar_t* getenv(const wchar_t* name) {
return _wgetenv(name);
}
} // namespace internal
template<class Ch, std::size_t N>
std::basic_string<Ch> DefaultLogDir(const std::array<const Ch*, N>& names) {
for (const Ch* name : names) {
if ((const Ch* var = details::getenv(name)) != nullptr) {
return var;
}
}
return {};
} Now you only need to specialize the literals: template<class Ch>
struct LogDirEnvVar;
template<>
struct LogDirEnvVar<char> {
constexpr static std::array<const char*, 2> names() noexcept {
return {"GOOGLE_LOG_DIR", "TEST_TMPDIR"};
}
};
template<>
struct LogDirEnvVar<wchar_t> {
constexpr static std::array<const wchar_t*, 2> names() noexcept {
return {L"GOOGLE_LOG_DIR", L"TEST_TMPDIR"};
}
}; Eventually, you can define template<class Ch>
decltype(auto) DefaultLogDir() {
return DefaultLogDir(LogDirEnvVar<Ch>::names());
} and use it as follows: auto dir1 = DefaultLogDir<char>();
auto dir2 = DefaultLogDir<wchar_t>(); However, I'm not sure this is really necessary here. Can't you just always use the wide string variant here? |
Thanks for your suggestions; it's a very nice thing for me. Regarding your question, I don't have much experience with platforms other than Windows, but I will try to do it. |
@xfc1939 Please do not close the PRs to create a new one. Simply update your branch and push the changes. Thank you. |
…re/support_unicode_paths
0932ea5
to
7102881
Compare
all right, I have updated my branch and sumited here. |
Fixes #984