summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2018-12-14 12:01:51 -0500
committerNat Goodspeed <nat@lindenlab.com>2018-12-14 12:01:51 -0500
commit132e708fec50fd756b822925313456c70a4ff27f (patch)
treebc5ac17d8e0cfe8e5c550615789da8a4eabab541 /indra
parent9ffcafb64b4483c315d00e88ffc1438bce1f7915 (diff)
SL-10153: Fix previous commit for non-Windows systems.
Move Windows-flavored llstring_getoptenv() to Windows-specific section of llstring.cpp. boost::optional type must be stated explicitly to initialize with a value. On platforms where llwchar is the same as wchar_t, LLWString is the same as std::wstring, so ll_convert specializations for std::wstring would duplicate those for LLWString. Defend against that. The compilers we use don't like 'return condition? { expr } : {}', in which we hope to construct and return an instance of the declared return type without having to restate the type. It works to use an explicit 'if' statement.
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llstring.cpp70
-rw-r--r--indra/llcommon/llstring.h30
2 files changed, 57 insertions, 43 deletions
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f931103ba6..0174c411b4 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -53,40 +53,6 @@ std::string ll_safe_string(const char* in, S32 maxlen)
return std::string();
}
-boost::optional<std::wstring> llstring_getoptenv(const std::string& key)
-{
- auto wkey = ll_convert_string_to_wide(key);
- // Take a wild guess as to how big the buffer should be.
- std::vector<wchar_t> buffer(1024);
- auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
- // If our initial guess was too short, n will indicate the size (in
- // wchar_t's) that buffer should have been, including the terminating nul.
- if (n > (buffer.size() - 1))
- {
- // make it big enough
- buffer.resize(n);
- // and try again
- n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
- }
- // did that (ultimately) succeed?
- if (n)
- {
- // great, return populated boost::optional
- return { &buffer[0] };
- }
-
- // not successful
- auto last_error = GetLastError();
- // Don't bother warning for NOT_FOUND; that's an expected case
- if (last_error != ERROR_ENVVAR_NOT_FOUND)
- {
- LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: "
- << windows_message<std::string>(last_error) << LL_ENDL;
- }
- // return empty boost::optional
- return {};
-}
-
bool is_char_hex(char hex)
{
if((hex >= '0') && (hex <= '9'))
@@ -854,6 +820,40 @@ std::wstring windows_message<std::wstring>(DWORD error)
return out.str();
}
+boost::optional<std::wstring> llstring_getoptenv(const std::string& key)
+{
+ auto wkey = ll_convert_string_to_wide(key);
+ // Take a wild guess as to how big the buffer should be.
+ std::vector<wchar_t> buffer(1024);
+ auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+ // If our initial guess was too short, n will indicate the size (in
+ // wchar_t's) that buffer should have been, including the terminating nul.
+ if (n > (buffer.size() - 1))
+ {
+ // make it big enough
+ buffer.resize(n);
+ // and try again
+ n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+ }
+ // did that (ultimately) succeed?
+ if (n)
+ {
+ // great, return populated boost::optional
+ return boost::optional<std::wstring>(&buffer[0]);
+ }
+
+ // not successful
+ auto last_error = GetLastError();
+ // Don't bother warning for NOT_FOUND; that's an expected case
+ if (last_error != ERROR_ENVVAR_NOT_FOUND)
+ {
+ LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: "
+ << windows_message<std::string>(last_error) << LL_ENDL;
+ }
+ // return empty boost::optional
+ return {};
+}
+
#else // ! LL_WINDOWS
boost::optional<std::string> llstring_getoptenv(const std::string& key)
@@ -862,7 +862,7 @@ boost::optional<std::string> llstring_getoptenv(const std::string& key)
if (found)
{
// return populated boost::optional
- return { found };
+ return boost::optional<std::string>(found);
}
else
{
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 2dccc7cbdf..87cb35c59c 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -583,19 +583,24 @@ typedef std::basic_string<U16> llutf16string;
// comparable preferred alias involving std::wstring. (In this scenario, if
// you pass llutf16string, it will engage the std::wstring specialization.)
#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing
-#else
+#else // defined(LL_WCHAR_T_NATIVE)
// wchar_t is a distinct native type, so llutf16string is also a distinct
// type, and there IS a point to converting separately to/from llutf16string.
// (But why? Windows APIs are still defined in terms of wchar_t, and
// in this scenario llutf16string won't work for them!)
#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
-// converting between std::wstring and llutf16string involves copying chars
-// enclose the brace-initialization expression in parens to protect the comma
-// from macro-argument parsing
-ll_convert_alias(llutf16string, std::wstring, ({ in.begin(), in.end() }));
-ll_convert_alias(std::wstring, llutf16string, ({ in.begin(), in.end() }));
-#endif
+#if LL_WINDOWS
+// LL_WCHAR_T_NATIVE is defined on non-Windows systems because, in fact,
+// wchar_t is native. Everywhere but Windows, we use it for llwchar (see
+// stdtypes.h). That makes LLWString identical to std::wstring, so these
+// aliases for std::wstring would collide with those for LLWString. Only
+// define on Windows, where converting between std::wstring and llutf16string
+// means copying chars.
+ll_convert_alias(llutf16string, std::wstring, llutf16string(in.begin(), in.end()));
+ll_convert_alias(std::wstring, llutf16string, std::wstring(in.begin(), in.end()));
+#endif // LL_WINDOWS
+#endif // defined(LL_WCHAR_T_NATIVE)
LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
@@ -1751,7 +1756,16 @@ template<class T>
auto LLStringUtilBase<T>::getoptenv(const std::string& key) -> boost::optional<string_type>
{
auto found{llstring_getoptenv(key)};
- return found? { ll_convert<string_type>(*found) } : {};
+ if (found)
+ {
+ // return populated boost::optional
+ return { ll_convert<string_type>(*found) };
+ }
+ else
+ {
+ // empty boost::optional
+ return {};
+ }
}
// static