diff options
Diffstat (limited to 'src/boost/nowide/cenv.hpp')
-rw-r--r-- | src/boost/nowide/cenv.hpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/boost/nowide/cenv.hpp b/src/boost/nowide/cenv.hpp new file mode 100644 index 000000000..a38a24b97 --- /dev/null +++ b/src/boost/nowide/cenv.hpp @@ -0,0 +1,124 @@ +// +// Copyright (c) 2012 Artyom Beilis (Tonkikh) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +#ifndef BOOST_NOWIDE_CENV_H_INCLUDED +#define BOOST_NOWIDE_CENV_H_INCLUDED + +#include <string> +#include <stdexcept> +#include <stdlib.h> +#include <boost/config.hpp> +#include <boost/nowide/stackstring.hpp> +#include <vector> + +#ifdef BOOST_WINDOWS +#include <boost/nowide/windows.hpp> +#endif + +namespace boost { +namespace nowide { + #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) + using ::getenv; + using ::setenv; + using ::unsetenv; + using ::putenv; + #else + /// + /// \brief UTF-8 aware getenv. Returns 0 if the variable is not set. + /// + /// This function is not thread safe or reenterable as defined by the standard library + /// + inline char *getenv(char const *key) + { + static stackstring value; + + wshort_stackstring name; + if(!name.convert(key)) + return 0; + + static const size_t buf_size = 64; + wchar_t buf[buf_size]; + std::vector<wchar_t> tmp; + wchar_t *ptr = buf; + size_t n = GetEnvironmentVariableW(name.c_str(),buf,buf_size); + if(n == 0 && GetLastError() == 203) // ERROR_ENVVAR_NOT_FOUND + return 0; + if(n >= buf_size) { + tmp.resize(n+1,L'\0'); + n = GetEnvironmentVariableW(name.c_str(),&tmp[0],static_cast<unsigned>(tmp.size() - 1)); + // The size may have changed + if(n >= tmp.size() - 1) + return 0; + ptr = &tmp[0]; + } + if(!value.convert(ptr)) + return 0; + return value.c_str(); + } + /// + /// \brief UTF-8 aware setenv, \a key - the variable name, \a value is a new UTF-8 value, + /// + /// if override is not 0, that the old value is always overridded, otherwise, + /// if the variable exists it remains unchanged + /// + inline int setenv(char const *key,char const *value,int override) + { + wshort_stackstring name; + if(!name.convert(key)) + return -1; + if(!override) { + wchar_t unused[2]; + if(!(GetEnvironmentVariableW(name.c_str(),unused,2)==0 && GetLastError() == 203)) // ERROR_ENVVAR_NOT_FOUND + return 0; + } + wstackstring wval; + if(!wval.convert(value)) + return -1; + if(SetEnvironmentVariableW(name.c_str(),wval.c_str())) + return 0; + return -1; + } + /// + /// \brief Remove enviroment variable \a key + /// + inline int unsetenv(char const *key) + { + wshort_stackstring name; + if(!name.convert(key)) + return -1; + if(SetEnvironmentVariableW(name.c_str(),0)) + return 0; + return -1; + } + /// + /// \brief UTF-8 aware putenv implementation, expects string in format KEY=VALUE + /// + inline int putenv(char *string) + { + char const *key = string; + char const *key_end = string; + while(*key_end != '=' && *key_end != 0) + ++ key_end; + if(*key_end == 0) + return -1; + wshort_stackstring wkey; + if(!wkey.convert(key,key_end)) + return -1; + wstackstring wvalue; + if(!wvalue.convert(key_end+1)) + return -1; + if(SetEnvironmentVariableW(wkey.c_str(),wvalue.c_str())) + return 0; + return -1; + } + #endif +} // nowide +} // namespace boost + +#endif +/// +// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 |