On Windows getenv (and putenv) uses ANSI codepage so it needs to be encoded
to internally used encoding (eg. UTF-8). Here we use _wgetenv (and _wputenv)
instead and encode that.
Also add SystemTools::HasEnv function.
---
Source/kwsys/SystemTools.cxx| 80 +++--
Source/kwsys/SystemTools.hxx.in | 4 +++
2 files changed, 74 insertions(+), 10 deletions(-)
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index c6e668d..5bcf0d0 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -406,6 +406,9 @@ struct SystemToolsPathCaseCmp
class SystemToolsPathCaseMap:
public std::map {};
+
+class SystemToolsEnvMap :
+public std::map {};
#endif
// adds the elements of the env variable path to the arg passed in
@@ -458,7 +461,23 @@ void SystemTools::GetPath(std::vector& path,
const char* env)
const char* SystemTools::GetEnv(const char* key)
{
- return getenv(key);
+ const char *v = 0;
+#if defined(_WIN32)
+ std::string env;
+ if (SystemTools::GetEnv(key, env)) {
+const std::string skey = key;
+SystemToolsEnvMap::iterator i = EnvMap->find(skey);
+if (i != EnvMap->end()) {
+ i->second = env;
+} else {
+ i = EnvMap->insert(SystemToolsEnvMap::value_type(skey, env)).first;
+}
+v = i->second.c_str();
+ }
+#else
+ v = getenv(key);
+#endif
+ return v;
}
const char* SystemTools::GetEnv(const std::string& key)
@@ -468,16 +487,21 @@ const char* SystemTools::GetEnv(const std::string& key)
bool SystemTools::GetEnv(const char* key, std::string& result)
{
+#if defined(_WIN32)
+ const std::wstring wkey = Encoding::ToWide(key);
+ const wchar_t* wv = _wgetenv(wkey.c_str());
+ if (wv) {
+result = Encoding::ToNarrow(wv);
+return true;
+ }
+#else
const char* v = getenv(key);
- if(v)
-{
+ if (v) {
result = v;
return true;
-}
- else
-{
-return false;
-}
+ }
+#endif
+ return false;
}
bool SystemTools::GetEnv(const std::string& key, std::string& result)
@@ -485,6 +509,22 @@ bool SystemTools::GetEnv(const std::string& key,
std::string& result)
return SystemTools::GetEnv(key.c_str(), result);
}
+bool SystemTools::HasEnv(const char* key)
+{
+#if defined(_WIN32)
+ const std::wstring wkey = Encoding::ToWide(key);
+ const wchar_t* v = _wgetenv(wkey.c_str());
+#else
+ const char* v = getenv(key);
+#endif
+ return v != 0;
+}
+
+bool SystemTools::HasEnv(const std::string& key)
+{
+ return SystemTools::HasEnv(key.c_str());
+}
+
//
#if defined(__CYGWIN__) || defined(__GLIBC__)
@@ -533,13 +573,25 @@ static int kwsysUnPutEnv(const std::string& env)
# ifdef KWSYS_PUTENV_EMPTY
buf[len] = '=';
buf[len+1] = 0;
- if(putenv(buf) < 0)
+#if defined(_WIN32)
+ const std::wstring wbuf = Encoding::ToWide(buf);
+ const int r = _wputenv(wbuf.c_str());
+#else
+ const int r = putenv(buf);
+#endif
+ if(r < 0)
{
err = errno;
}
# else
buf[len] = 0;
- if(putenv(buf) < 0 && errno != EINVAL)
+#if defined(_WIN32)
+ const std::wstring wbuf = Encoding::ToWide(buf);
+ const int r = _wputenv(wbuf.c_str());
+#else
+ const int r = putenv(buf);
+#endif
+ if(r < 0 && errno != EINVAL)
{
err = errno;
}
@@ -679,7 +731,12 @@ public:
static_cast(oldEnv);
char* newEnv = strdup(env);
this->insert(newEnv);
+#if defined(_WIN32)
+const std::wstring wEnv = Encoding::ToWide(newEnv);
+return _wputenv(wEnv.c_str()) == 0;
+#else
return putenv(newEnv) == 0;
+#endif
}
bool UnPut(const char* env)
{
@@ -5371,6 +5428,7 @@ static unsigned int SystemToolsManagerCount;
SystemToolsTranslationMap *SystemTools::TranslationMap;
#ifdef _WIN32
SystemToolsPathCaseMap *SystemTools::PathCaseMap;
+SystemToolsEnvMap *SystemTools::EnvMap;
#endif
#ifdef __CYGWIN__
SystemToolsTranslationMap *SystemTools::Cyg2Win32Map;
@@ -5421,6 +5479,7 @@ void SystemTools::ClassInitialize()
SystemTools::TranslationMap = new SystemToolsTranslationMap;
#ifdef _WIN32
SystemTools::PathCaseMap = new SystemToolsPathCaseMap;
+ SystemTools::EnvMap = new SystemToolsEnvMap;
#endif
#ifdef __CYGWIN__
SystemTools::Cyg2Win32Map = new SystemToolsTranslationMap;
@@ -5480,6 +5539,7 @@ void SystemTools::ClassFinalize()
delete SystemTools::TranslationMap;
#ifdef _WIN32
delete SystemTools::PathCaseMap;
+ delete SystemTools::EnvMap;
#endif
#ifdef __CYGWIN__
delete SystemTools::Cyg2Win32Map;
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index bba5a5c..8f01e75 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -53,6 +53,7 @@ namespace @KWSYS_NAMESPACE@
class SystemToolsTranslationMap;
class SystemToolsPathCaseMap;
+class SystemToolsEnvMap;
/** \class SystemToolsManager
* \brief Use to make sure SystemTools is initialized before it is used
@@ -843,6 +844,8 @@ public:
st