mirror of
https://github.com/boostorg/nowide.git
synced 2026-02-22 15:32:35 +00:00
Many updates
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
include_directories(.)
|
||||
include_directories(/home/artik/Packages/boost/boost_1_49_0)
|
||||
if(NOT BOOST_PATH)
|
||||
set(BOOST_PATH ${CMAKE_CURRENT_SOURCE_PATH})
|
||||
endif()
|
||||
include_directories(${BOOST_PATH})
|
||||
|
||||
enable_testing()
|
||||
|
||||
@@ -20,15 +23,11 @@ foreach(TEST ${BOOST_NOWIDE_TESTS})
|
||||
add_test(${TEST} ${TEST})
|
||||
endforeach()
|
||||
|
||||
if(WIN32)
|
||||
add_library(boost_nowide SHARED libs/nowide/src/iostream.cpp)
|
||||
set_target_properties(boost_nowide PROPERTIES COMPILE_DEFINITIONS BOOST_NOWIDE_DYN_LINK)
|
||||
set_target_properties(test_iostream PROPERTIES COMPILE_DEFINITIONS BOOST_NOWIDE_DYN_LINK)
|
||||
target_link_libraries(test_iostream boost_nowide)
|
||||
endif()
|
||||
add_library(boost_nowide SHARED libs/nowide/src/iostream.cpp)
|
||||
set_target_properties(boost_nowide PROPERTIES COMPILE_DEFINITIONS BOOST_NOWIDE_DYN_LINK)
|
||||
set_target_properties(test_iostream PROPERTIES COMPILE_DEFINITIONS BOOST_NOWIDE_DYN_LINK)
|
||||
target_link_libraries(test_iostream boost_nowide)
|
||||
|
||||
add_executable(test_system libs/nowide/test/test_system.cpp)
|
||||
add_test(test_system_1 test_system "-1")
|
||||
add_test(test_system_2 test_system "-2")
|
||||
add_test(test_system_3 test_system "-3")
|
||||
add_test(test_system_w test_system "-2")
|
||||
add_test(test_system_n test_system "-n")
|
||||
add_test(test_system_w test_system "-w")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#ifndef BOOST_WINDOWS
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
class args {
|
||||
public:
|
||||
args(int &,char **&) {}
|
||||
@@ -26,12 +26,25 @@ namespace boost {
|
||||
|
||||
#else
|
||||
|
||||
///
|
||||
/// \brief args is a class that fixes standard main() function arguments and changes them to UTF-8 under
|
||||
/// Microsoft Windows.
|
||||
///
|
||||
/// \note the class owns the memory of the newly allocated strings
|
||||
///
|
||||
class args {
|
||||
public:
|
||||
|
||||
///
|
||||
/// Fix command line agruments
|
||||
///
|
||||
args(int &argc,char **&argv)
|
||||
{
|
||||
fix_args(argc,argv);
|
||||
}
|
||||
///
|
||||
/// Fix command line agruments and environment
|
||||
///
|
||||
args(int &argc,char **&argv,char **&en)
|
||||
{
|
||||
fix_args(argc,argv);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
#include <windows.h>
|
||||
@@ -20,12 +21,17 @@
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#ifndef BOOST_WINDOWS
|
||||
#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;
|
||||
@@ -53,6 +59,12 @@ namespace boost {
|
||||
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;
|
||||
@@ -70,6 +82,9 @@ namespace boost {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
///
|
||||
/// \brief Remove enviroment variable \a key
|
||||
///
|
||||
inline int unsetenv(char const *key)
|
||||
{
|
||||
wshort_stackstring name;
|
||||
@@ -79,6 +94,9 @@ namespace boost {
|
||||
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;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
///
|
||||
/// Template function that converts a buffer of UTF sequence in range [source_begin,source_end)
|
||||
/// \brief Template function that converts a buffer of UTF sequence in range [source_begin,source_end)
|
||||
/// to the output \a buffer of size \a buffer_size.
|
||||
///
|
||||
/// In case of success a NUL terminated string returned (buffer), otherwise 0 is returned.
|
||||
@@ -61,7 +61,7 @@ namespace boost {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/// \end
|
||||
/// \endcond
|
||||
|
||||
///
|
||||
/// Convert NUL terminated UTF source string to NUL terminated \a output string of size at
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
//
|
||||
// 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_CPPENV_H_INCLUDED
|
||||
#define BOOST_NOWIDE_CPPENV_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <map>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <boost/locale/encoding_errors.hpp>
|
||||
#include <vector>
|
||||
#ifdef BOOST_WINDOWS
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#ifndef BOOST_WINDOWS
|
||||
inline bool has_enironment(char const *key)
|
||||
{
|
||||
return ::getenv(key)!=0;
|
||||
}
|
||||
inline bool has_enironment(std::string const &key)
|
||||
{
|
||||
return ::getenv(key.c_str())!=0;
|
||||
}
|
||||
inline std::string get_environment(char const *key,char const *def="")
|
||||
{
|
||||
char const *v=::getenv(key);
|
||||
if(!v)
|
||||
return def;
|
||||
return v;
|
||||
}
|
||||
inline std::string get_environment(std::string const &key,std::string const &def=std::string())
|
||||
{
|
||||
char const *v=::getenv(key.c_str());
|
||||
if(!v)
|
||||
return def;
|
||||
return v;
|
||||
}
|
||||
inline int set_environment(char const *key,char const *value,bool override=true)
|
||||
{
|
||||
return ::setenv(key,value,int(override));
|
||||
}
|
||||
inline int set_environment(std::string const &key,std::string const &value,bool override=true)
|
||||
{
|
||||
return ::setenv(key.c_str(),value.c_str(),int(override));
|
||||
}
|
||||
inline int unset_environment(char const *key)
|
||||
{
|
||||
return ::unsetenv(key);
|
||||
}
|
||||
inline int unset_environment(std::string const &key)
|
||||
{
|
||||
return ::unsetenv(key.c_str());
|
||||
}
|
||||
inline std::map<std::string,std::string> get_environment_strings()
|
||||
{
|
||||
std::map<std::string,std::string> result;
|
||||
char **e = environ;
|
||||
if(!e)
|
||||
return result;
|
||||
for(;*e;e++) {
|
||||
char *key = *e;
|
||||
char *key_end = strchr(key,'=');
|
||||
if(key_end == 0)
|
||||
continue;
|
||||
std::string skey = std::string(key,key_end);
|
||||
std::string svalue(key_end + 1);
|
||||
result[skey]=svalue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
inline bool has_enironment(char const *key)
|
||||
{
|
||||
wshort_stackstring name;
|
||||
if(!name.convert(key)) {
|
||||
throw boost::locale::conv::conversion_error();
|
||||
}
|
||||
wchar_t unused;
|
||||
if(GetEnvironmentVariableW(name.c_str(),&unused,1)==0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline bool has_enironment(std::string const &key)
|
||||
{
|
||||
return has_enironment(key.c_str());
|
||||
}
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace details {
|
||||
inline bool get_environment_value(char const *key,std::string &result)
|
||||
{
|
||||
wshort_stackstring name;
|
||||
if(!name.convert(key)) {
|
||||
throw boost::locale::conv::conversion_error();
|
||||
}
|
||||
for(;;) {
|
||||
static const size_t buf_size = 64;
|
||||
wchar_t buf[buf_size];
|
||||
size_t n = GetEnvironmentVariableW(name.c_str(),buf,buf_size);
|
||||
if(n == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
||||
return false;
|
||||
if(n >= buf_size) {
|
||||
std::vector<wchar_t> tmp(n);
|
||||
n = GetEnvironmentVariableW(name.c_str(),&tmp[0],tmp.size());
|
||||
// The size may have changed
|
||||
if(n == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
||||
return false;
|
||||
if(n >= tmp.size())
|
||||
continue;
|
||||
std::string v = convert(&tmp[0]);
|
||||
v.swap(result);
|
||||
return true;
|
||||
}
|
||||
std::string v = convert(buf);
|
||||
v.swap(result);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
|
||||
inline std::string get_environment(std::string const &key,std::string const &def=std::string())
|
||||
{
|
||||
std::string result;
|
||||
if(details::get_environment_value(key.c_str(),result))
|
||||
return result;
|
||||
return def;
|
||||
}
|
||||
inline std::string get_environment(char const *key,char const *def="")
|
||||
{
|
||||
std::string result;
|
||||
if(details::get_environment_value(key,result))
|
||||
return result;
|
||||
return def;
|
||||
}
|
||||
inline int set_environment(char const *key,char const *value,bool override=true)
|
||||
{
|
||||
wshort_stackstring name;
|
||||
if(!name.convert(key)) {
|
||||
throw boost::locale::conv::conversion_error();
|
||||
}
|
||||
if(!override) {
|
||||
wchar_t unused;
|
||||
if(!(GetEnvironmentVariableW(name.c_str(),&unused,1)==0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND))
|
||||
return 0;
|
||||
}
|
||||
wstackstring wval;
|
||||
if(!wval.convert(value))
|
||||
throw boost::locale::conv::conversion_error();
|
||||
if(SetEnvironmentVariableW(name.c_str(),wval.c_str()))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
inline int set_environment(std::string const &key,std::string const &value,bool override=true)
|
||||
{
|
||||
return set_environment(key.c_str(),value.c_str(),override);
|
||||
}
|
||||
inline int unset_environment(char const *key)
|
||||
{
|
||||
wshort_stackstring name;
|
||||
if(!name.convert(key)) {
|
||||
throw boost::locale::conv::conversion_error();
|
||||
}
|
||||
if(SetEnvironmentVariableW(name.c_str(),0))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
inline int unset_environment(std::string const &key)
|
||||
{
|
||||
return unset_environment(key.c_str());
|
||||
}
|
||||
inline std::map<std::string,std::string> get_environment_strings()
|
||||
{
|
||||
std::map<std::string,std::string> result;
|
||||
wchar_t *wstrings = 0;
|
||||
try {
|
||||
wstrings = GetEnvironmentStringsW();
|
||||
if(!wstrings)
|
||||
return result;
|
||||
for(;*wstrings!=0;wstrings += wcslen(wstrings) + 1) {
|
||||
wchar_t *key_end = wcschr(wstrings,L'=');
|
||||
if(key_end == 0)
|
||||
continue;
|
||||
short_stackstring key;
|
||||
if(!key.convert(wstrings,key_end))
|
||||
continue;
|
||||
stackstring val;
|
||||
if(!val.convert(key_end+1))
|
||||
continue;
|
||||
result[key.c_str()] = val.c_str();
|
||||
}
|
||||
|
||||
}
|
||||
catch(...) {
|
||||
if(wstrings) {
|
||||
FreeEnvironmentStringsW(wstrings);
|
||||
wstrings = 0;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
if(wstrings) {
|
||||
FreeEnvironmentStringsW(wstrings);
|
||||
wstrings = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
} // nowide
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
///
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
@@ -22,41 +23,69 @@
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#ifndef BOOST_WINDOWS
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::fopen;
|
||||
using std::freopen;
|
||||
using std::remove;
|
||||
using std::rename;
|
||||
#else
|
||||
|
||||
///
|
||||
/// \brief Same as freopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
/// In invalid UTF-8 given, NULL is returned and errno is set to EINVAL
|
||||
///
|
||||
inline FILE *freopen(char const *file_name,char const *mode,FILE *stream)
|
||||
{
|
||||
wstackstring wname;
|
||||
wshort_stackstring wmode;
|
||||
if(!wname.convert(file_name) || !wmode.convert(mode))
|
||||
if(!wname.convert(file_name) || !wmode.convert(mode)) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
return _wfreopen(wname.c_str(),wmode.c_str(),stream);
|
||||
}
|
||||
///
|
||||
/// \brief Same as fopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
/// In invalid UTF-8 given, NULL is returned and errno is set to EINVAL
|
||||
///
|
||||
inline FILE *fopen(char const *file_name,char const *mode)
|
||||
{
|
||||
wstackstring wname;
|
||||
wshort_stackstring wmode;
|
||||
if(!wname.convert(file_name) || !wmode.convert(mode))
|
||||
if(!wname.convert(file_name) || !wmode.convert(mode)) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
return _wfopen(wname.c_str(),wmode.c_str());
|
||||
}
|
||||
///
|
||||
/// \brief Same as rename but old_name and new_name are UTF-8 strings
|
||||
///
|
||||
/// In invalid UTF-8 given, -1 is returned and errno is set to EINVAL
|
||||
///
|
||||
inline int rename(char const *old_name,char const *new_name)
|
||||
{
|
||||
wstackstring wold,wnew;
|
||||
if(!wold.convert(old_name) || !wnew.convert(new_name))
|
||||
if(!wold.convert(old_name) || !wnew.convert(new_name)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return _wrename(wold.c_str(),wnew.c_str());
|
||||
}
|
||||
///
|
||||
/// \brief Same as rename but name is UTF-8 string
|
||||
///
|
||||
/// In invalid UTF-8 given, -1 is returned and errno is set to EINVAL
|
||||
///
|
||||
inline int remove(char const *name)
|
||||
{
|
||||
wstackstring wname;
|
||||
if(!wname.convert(name))
|
||||
if(!wname.convert(name)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return _wremove(wname.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,17 +17,32 @@
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_FSTREAM_TESTS)
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_FSTREAM_TESTS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::basic_filebuf;
|
||||
using std::filebuf;
|
||||
#else // Windows
|
||||
|
||||
///
|
||||
/// \brief This forward declaration defined the basic_filebuf type.
|
||||
///
|
||||
/// it is implemented and specialized for CharType = char, it behaves
|
||||
/// implements std::filebuf over standard C I/O
|
||||
///
|
||||
template<typename CharType,typename Traits = std::char_traits<CharType> >
|
||||
class basic_filebuf;
|
||||
|
||||
///
|
||||
/// \brief This is implementation of std::filebuf
|
||||
///
|
||||
/// it is implemented and specialized for CharType = char, it behaves
|
||||
/// implements std::filebuf over standard C I/O
|
||||
///
|
||||
template<>
|
||||
class basic_filebuf<char> : public std::basic_streambuf<char> {
|
||||
public:
|
||||
///
|
||||
/// Creates new filebuf
|
||||
///
|
||||
basic_filebuf() :
|
||||
buffer_size_(4),
|
||||
buffer_(0),
|
||||
@@ -49,10 +64,16 @@ namespace nowide {
|
||||
delete [] buffer_;
|
||||
}
|
||||
|
||||
///
|
||||
/// Same as std::filebuf::open but s is UTF-8 string
|
||||
///
|
||||
basic_filebuf *open(std::string const &s,std::ios_base::openmode mode)
|
||||
{
|
||||
return open(s.c_str(),mode);
|
||||
}
|
||||
///
|
||||
/// Same as std::filebuf::open but s is UTF-8 string
|
||||
///
|
||||
basic_filebuf *open(char const *s,std::ios_base::openmode mode)
|
||||
{
|
||||
if(file_) {
|
||||
@@ -76,6 +97,9 @@ namespace nowide {
|
||||
file_ = f;
|
||||
return this;
|
||||
}
|
||||
///
|
||||
/// Same as std::filebuf::close()
|
||||
///
|
||||
basic_filebuf *close()
|
||||
{
|
||||
bool res = sync() == 0;
|
||||
@@ -86,6 +110,9 @@ namespace nowide {
|
||||
}
|
||||
return res ? this : 0;
|
||||
}
|
||||
///
|
||||
/// Same as std::filebuf::is_open()
|
||||
///
|
||||
bool is_open() const
|
||||
{
|
||||
return file_ != 0;
|
||||
@@ -166,28 +193,6 @@ namespace nowide {
|
||||
#else
|
||||
#endif
|
||||
|
||||
int fixg()
|
||||
{
|
||||
if(gptr()!=egptr()) {
|
||||
std::streamsize off = gptr() - egptr();
|
||||
setg(0,0,0);
|
||||
if(fseek(file_,off,SEEK_CUR) != 0)
|
||||
return -1;
|
||||
}
|
||||
setg(0,0,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fixp()
|
||||
{
|
||||
if(pptr()!=0) {
|
||||
int r = sync();
|
||||
setp(0,0);
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overflow(int c)
|
||||
{
|
||||
#ifdef BOOST_NOWIDE_DEBUG_FILEBUF
|
||||
@@ -257,16 +262,6 @@ namespace nowide {
|
||||
return pubseekoff(-1,std::ios::cur);
|
||||
}
|
||||
|
||||
void reset(FILE *f = 0)
|
||||
{
|
||||
sync();
|
||||
if(file_) {
|
||||
fclose(file_);
|
||||
file_ = 0;
|
||||
}
|
||||
file_ = f;
|
||||
}
|
||||
|
||||
std::streampos seekoff(std::streamoff off,
|
||||
std::ios_base::seekdir seekdir,
|
||||
std::ios_base::openmode /*m*/)
|
||||
@@ -299,6 +294,39 @@ namespace nowide {
|
||||
return seekoff(std::streamoff(off),std::ios_base::beg,m);
|
||||
}
|
||||
private:
|
||||
int fixg()
|
||||
{
|
||||
if(gptr()!=egptr()) {
|
||||
std::streamsize off = gptr() - egptr();
|
||||
setg(0,0,0);
|
||||
if(fseek(file_,off,SEEK_CUR) != 0)
|
||||
return -1;
|
||||
}
|
||||
setg(0,0,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fixp()
|
||||
{
|
||||
if(pptr()!=0) {
|
||||
int r = sync();
|
||||
setp(0,0);
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset(FILE *f = 0)
|
||||
{
|
||||
sync();
|
||||
if(file_) {
|
||||
fclose(file_);
|
||||
file_ = 0;
|
||||
}
|
||||
file_ = f;
|
||||
}
|
||||
|
||||
|
||||
static wchar_t const *get_mode(std::ios_base::openmode mode)
|
||||
{
|
||||
//
|
||||
@@ -354,6 +382,9 @@ namespace nowide {
|
||||
std::ios::openmode mode_;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Convinience typedef
|
||||
///
|
||||
typedef basic_filebuf<char> filebuf;
|
||||
|
||||
#endif // windows
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace boost {
|
||||
/// of std namespace (i.e. not on Windows)
|
||||
///
|
||||
namespace nowide {
|
||||
#if !defined BOOST_WINDOWS && !defined BOOST_NOWIDE_FSTREAM_TESTS
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_FSTREAM_TESTS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
|
||||
using std::basic_ifstream;
|
||||
using std::basic_ofstream;
|
||||
@@ -32,11 +32,9 @@ namespace nowide {
|
||||
using std::ofstream;
|
||||
using std::fstream;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_WINDOWS) || defined(BOOST_DOXYGEN_DOCS) || defined(BOOST_NOWIDE_FSTREAM_TESTS)
|
||||
#else
|
||||
///
|
||||
/// Same as std::basic_ifstream<char> but accepts UTF-8 strings under Windows
|
||||
/// \brief Same as std::basic_ifstream<char> but accepts UTF-8 strings under Windows
|
||||
///
|
||||
template<typename CharType,typename Traits = std::char_traits<CharType> >
|
||||
class basic_ifstream : public std::basic_istream<CharType,Traits>
|
||||
@@ -99,7 +97,7 @@ namespace nowide {
|
||||
};
|
||||
|
||||
///
|
||||
/// Same as std::basic_ofstream<char> but accepts UTF-8 strings under Windows
|
||||
/// \brief Same as std::basic_ofstream<char> but accepts UTF-8 strings under Windows
|
||||
///
|
||||
|
||||
template<typename CharType,typename Traits = std::char_traits<CharType> >
|
||||
@@ -161,7 +159,7 @@ namespace nowide {
|
||||
};
|
||||
|
||||
///
|
||||
/// Same as std::basic_fstream<char> but accepts UTF-8 strings under Windows
|
||||
/// \brief Same as std::basic_fstream<char> but accepts UTF-8 strings under Windows
|
||||
///
|
||||
|
||||
template<typename CharType,typename Traits = std::char_traits<CharType> >
|
||||
@@ -224,7 +222,7 @@ namespace nowide {
|
||||
|
||||
|
||||
///
|
||||
/// Same as std::filebuf but accepts UTF-8 strings under Windows
|
||||
/// \brief Same as std::filebuf but accepts UTF-8 strings under Windows
|
||||
///
|
||||
typedef basic_filebuf<char> filebuf;
|
||||
///
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#ifndef BOOST_WINDOWS
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::cin;
|
||||
@@ -53,10 +53,29 @@ namespace boost {
|
||||
|
||||
/// \endcond
|
||||
|
||||
|
||||
///
|
||||
/// \brief Same as std::cin, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL details::winconsole_istream cin;
|
||||
///
|
||||
/// \brief Same as std::cout, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL details::winconsole_ostream cout;
|
||||
///
|
||||
/// \brief Same as std::cerr, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL details::winconsole_ostream cerr;
|
||||
///
|
||||
/// \brief Same as std::clog, but uses UTF-8
|
||||
///
|
||||
/// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
|
||||
///
|
||||
extern BOOST_NOWIDE_DECL details::winconsole_ostream clog;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -128,9 +128,21 @@ private:
|
||||
output_char *mem_buffer_;
|
||||
}; //basic_stackstring
|
||||
|
||||
///
|
||||
/// Convinience typedef
|
||||
///
|
||||
typedef basic_stackstring<wchar_t,char,256> wstackstring;
|
||||
///
|
||||
/// Convinience typedef
|
||||
///
|
||||
typedef basic_stackstring<char,wchar_t,256> stackstring;
|
||||
///
|
||||
/// Convinience typedef
|
||||
///
|
||||
typedef basic_stackstring<wchar_t,char,16> wshort_stackstring;
|
||||
///
|
||||
/// Convinience typedef
|
||||
///
|
||||
typedef basic_stackstring<char,wchar_t,16> short_stackstring;
|
||||
|
||||
|
||||
|
||||
@@ -13,12 +13,18 @@
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#ifndef BOOST_WINDOWS
|
||||
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
|
||||
using ::system;
|
||||
|
||||
#else // Windows
|
||||
|
||||
///
|
||||
/// Same as std::system but cmd is UTF-8.
|
||||
///
|
||||
/// If the input is not valid UTF-8, -1 returned and errno set to EINVAL
|
||||
///
|
||||
inline int system(char const *cmd)
|
||||
{
|
||||
if(!cmd)
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
#define _UNICODE
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <boost/locale/encoding_utf.hpp>
|
||||
#include <string>
|
||||
|
||||
|
||||
void write(wchar_t const *s)
|
||||
{
|
||||
HANDLE h=GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD written = 0;
|
||||
DWORD dummy;
|
||||
if(GetConsoleMode(h,&dummy)) {
|
||||
WriteConsoleW(h,s,wcslen(s),&written,0);
|
||||
}
|
||||
else {
|
||||
std::string tmp = boost::locale::conv::utf_to_utf<char>(s);
|
||||
WriteFile(h,tmp.c_str(),tmp.size(),&written,0);
|
||||
}
|
||||
}
|
||||
|
||||
int read(wchar_t *buf,size_t n)
|
||||
{
|
||||
HANDLE h=GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD read = 0;
|
||||
DWORD dummy;
|
||||
if(GetConsoleMode(h,&dummy)) {
|
||||
ReadConsoleW(h,buf,n-1,&read,0);
|
||||
buf[read] = 0;
|
||||
}
|
||||
else {
|
||||
char tmp[256];
|
||||
ReadFile(h,tmp,sizeof(tmp),&read,0);
|
||||
tmp[read] = 0;
|
||||
std::wstring wtmp = boost::locale::conv::utf_to_utf<wchar_t>(tmp);
|
||||
buf[n-1]=0;
|
||||
wcsncpy(buf,wtmp.c_str(),n-1);
|
||||
read = wcslen(buf);
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
write(L"שלום ασφγσφγ мир\n");
|
||||
wchar_t buf[256];
|
||||
read(buf,256);
|
||||
write(buf);
|
||||
return 0;
|
||||
}
|
||||
26
libs/nowide/build/Jamfile.v2
Normal file
26
libs/nowide/build/Jamfile.v2
Normal file
@@ -0,0 +1,26 @@
|
||||
# Boost System Library Build Jamfile
|
||||
|
||||
# (C) Copyright Beman Dawes 2002, 2006, Artyom Beilis 2012
|
||||
#
|
||||
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# See library home page at http://www.boost.org/libs/nowide
|
||||
|
||||
project boost/nowide
|
||||
: source-location ../src
|
||||
: usage-requirements # pass these requirement to dependents (i.e. users)
|
||||
<link>shared:<define>BOOST_NOWIDE_DYN_LINK=1
|
||||
<link>static:<define>BOOST_NOWIDE_STATIC_LINK=1
|
||||
;
|
||||
|
||||
SOURCES = iostream ;
|
||||
|
||||
lib boost_nowide
|
||||
: $(SOURCES).cpp
|
||||
: <link>shared:<define>BOOST_SYSTEM_DYN_LINK=1
|
||||
<link>static:<define>BOOST_SYSTEM_STATIC_LINK=1
|
||||
;
|
||||
|
||||
boost-install boost_system ;
|
||||
1632
libs/nowide/doc/Doxyfile
Normal file
1632
libs/nowide/doc/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
11
libs/nowide/doc/gendoc.sh
Executable file
11
libs/nowide/doc/gendoc.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2009-2011 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)
|
||||
#
|
||||
|
||||
|
||||
rm -f html/* && doxygen
|
||||
212
libs/nowide/doc/main.txt
Normal file
212
libs/nowide/doc/main.txt
Normal file
@@ -0,0 +1,212 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 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)
|
||||
//
|
||||
|
||||
|
||||
/*!
|
||||
|
||||
\mainpage Boost.Nowide
|
||||
|
||||
Table of Contents:
|
||||
|
||||
- \ref main
|
||||
- \ref main_rationale
|
||||
- \ref main_the_problem
|
||||
- \ref main_the_solution
|
||||
- \ref main_wide
|
||||
- \ref main_reading
|
||||
- \ref using
|
||||
- \ref technical
|
||||
- \ref technical_imple
|
||||
- \ref technical_cio
|
||||
|
||||
|
||||
\section main What is Boost.Nowide
|
||||
|
||||
Boost.Nowide is a library implemented by Artyom Beilis
|
||||
that make cross platform Unicode aware programming
|
||||
ieasier.
|
||||
|
||||
|
||||
|
||||
\subsection main_rationale Rationale
|
||||
\subsubsection main_the_problem The Problem
|
||||
|
||||
Consider a simple application that splits a big file into chunks, such that
|
||||
they can be sent by e-mail. It requires doing few very simple taks:
|
||||
|
||||
- Access command line arguments: <code>int main(int argc,char **argv)</code>
|
||||
- Open a input file, open several output files: <code>std::fstream::open(char const *,std::ios::openmode m)</code>
|
||||
- Remove the files in case of fault: <code>std::remove(char const *file)</code>
|
||||
- Print a progress report into console: <code>std::cout << file_name </code>
|
||||
|
||||
Unfortunately it is impossible to implement this simple task in a plain C++
|
||||
if the file names contain non-ASCII characters
|
||||
|
||||
The simple program that uses the API would work on the systems that use UTF-8
|
||||
internally -- the vast majority of Unix-Line operating systems: Linux, Mac OS X,
|
||||
Solaris, BSD. But it would fail on files like <code>War and Peace - Война и мир - מלחמה ושלום.zip</code>
|
||||
under Microsoft Windows because the native Windows Unicode aware API is Wide-API - UTF-16.
|
||||
|
||||
This, even a trivial task is very hard to implement in cross platform manner.
|
||||
|
||||
\subsubsection main_the_solution The Solution
|
||||
|
||||
Boost.Nowide provides a set of standard library functions that are UTF-8 aware and
|
||||
makes Unicode aware programming easier.
|
||||
|
||||
The library provides:
|
||||
|
||||
- Easy to use functions for converting UTF-8 to/from UTF-16
|
||||
- A class to fixing \c argc, \c argc and \c env \c main parameters to use UTF-8
|
||||
- UTF-8 aware functions
|
||||
- \c stdio.h functions:
|
||||
- \c fopen
|
||||
- \c freopen
|
||||
- \c remove
|
||||
- \c rename
|
||||
- \c stdlib.h functions
|
||||
- \c system
|
||||
- \c getenv
|
||||
- \c setenv
|
||||
- \c unsetenv
|
||||
- \c putenv
|
||||
- \c fstream
|
||||
- \c filebuf
|
||||
- \c fstream/ofstream/ifstream
|
||||
- \c iostream
|
||||
- \c cout
|
||||
- \c cerr
|
||||
- \c clog
|
||||
- \c cin
|
||||
|
||||
|
||||
\subsubsection main_wide Why Not Narrow and Wide?
|
||||
|
||||
Why not to provide both Wide and Narrow implementations so the
|
||||
developer can choose to use Wide characters on Unix-Like platforms
|
||||
|
||||
Several reasons:
|
||||
|
||||
- \c wchar_t is not really portable, it can be 2 bytes, 4 bytes or even 1 byte making Unicode aware programming harder
|
||||
- Standard C and C++ library uses narrow strings for OS interactions. This library follows this general rule. There is
|
||||
no such thing as <code>fopen(wchar_t const *,wchar_t const *)</code> in the standard library, so it is better
|
||||
to stick to the standards rather than re-implement Wide API in "Microsoft Windows Style"
|
||||
|
||||
|
||||
\subsubsection main_reading Further Reading
|
||||
|
||||
- <a href="http://www.utf8everywhere.org/">www.utf8everywhere.org</a>
|
||||
- <a href="http://alfps.wordpress.com/2011/11/22/unicode-part-1-windows-console-io-approaches/">Windows console i/o approaches</a>
|
||||
|
||||
\section using Using The Library
|
||||
|
||||
The library is mostly header only library, only console I/O requires separate compilation under Windows.
|
||||
|
||||
As a developer you are expected to to \c boost::nowide functions instead of the function avalible in the
|
||||
\c std namespace.
|
||||
|
||||
For example, Unicode unaware implementation of line counter:
|
||||
\code
|
||||
<fstream>
|
||||
<iostream>
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
if(argc!=2) {
|
||||
std::cerr << "Usage: file_name" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::ifstream f(argv[2]);
|
||||
if(!f) {
|
||||
std::cerr << "Can't open a file " << argv[2] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
int total_lines = 0
|
||||
while(f) {
|
||||
if(f.get() == '\n)
|
||||
total_lines++;
|
||||
}
|
||||
f.close();
|
||||
std::cout << "File " << argv[2] << " has " << total_lines << " lines" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
To make this program handle Unicode properly we do the following changes:
|
||||
|
||||
|
||||
\code
|
||||
<boost/nowide/args.hpp>
|
||||
<boost/nowide/fstream.hpp>
|
||||
<boost/nowide/iostream.hpp>
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
boost::nowide::args a(argc,argv); // Fix arguments - make them UTF-8
|
||||
if(argc!=2) {
|
||||
boost::nowide::cerr << "Usage: file_name" << std::endl; // Unicode aware console
|
||||
return 1;
|
||||
}
|
||||
|
||||
boost::nowide::ifstream f(argv[2]); // argv[2] - is UTF-8
|
||||
if(!f) {
|
||||
// the console can display UTF-8
|
||||
boost::nowide::cerr << "Can't open a file " << argv[2] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
int total_lines = 0
|
||||
while(f) {
|
||||
if(f.get() == '\n)
|
||||
total_lines++;
|
||||
}
|
||||
f.close();
|
||||
// the console can display UTF-8
|
||||
boost::nowide::cout << "File " << argv[2] << " has " << total_lines << " lines" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
This is very simple and straight forward approach helps writing Unicode aware programs.
|
||||
|
||||
\section technical Technical Details
|
||||
\subsection technical_imple Windows vs POSIX
|
||||
|
||||
The library provide UTF-8 aware functions for Microsoft Windows in \c boost::nowide namespace that usually lay in \c std:: namespace,
|
||||
for example \c std::fopen goes to \c boost::nowide::fopen.
|
||||
|
||||
Under POSIX platforms the boost::nowide::fopen and all other functions are aliases to standard library functions:
|
||||
|
||||
\code
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#ifdef BOOST_WINDOWS
|
||||
inline FILE *fopen(char const *name,char const *mode)
|
||||
{
|
||||
...
|
||||
}
|
||||
#else
|
||||
using std::fopen
|
||||
#endif
|
||||
} // nowide
|
||||
} // boost
|
||||
\endcode
|
||||
|
||||
\subsection technical_cio Console I/O
|
||||
|
||||
Console I/O implemented as wrapper over ReadConsoleW/WriteConsoleW unless
|
||||
the stream is not "atty" like a pipe than ReadFile/WriteFile is used.
|
||||
|
||||
This approach eliminates a need of manual code page handling. If TrueType
|
||||
fonts are used the Unicode aware input and output would work.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 filetype=cpp.doxygen
|
||||
|
||||
16
libs/nowide/index.html
Normal file
16
libs/nowide/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Boost.Locale Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
|
||||
<meta http-equiv="refresh" content="0; URL=doc/html/index.html" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
Automatic redirection failed, please go to <a href=
|
||||
"doc/html/index.html">doc/html/index.html</a>
|
||||
</body>
|
||||
</html>
|
||||
<!-- Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) Distributed under the Boost Software License, Version 1.0 -->
|
||||
@@ -9,12 +9,10 @@
|
||||
#include <boost/nowide/iostream.hpp>
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <stdio.h>
|
||||
#ifndef BOOST_WINDOWS
|
||||
# error "This code shold be used only under Windows platforms"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
@@ -75,14 +73,16 @@ namespace details {
|
||||
return -1;
|
||||
wchar_t *out = wbuffer_;
|
||||
uf::code_point c;
|
||||
size_t decoded = 0;
|
||||
while(p < e && (c = uf::utf_traits<char>::decode(p,e))!=uf::illegal && c!=uf::incomplete) {
|
||||
out = uf::utf_traits<wchar_t>::encode(c,out);
|
||||
decoded = p-b;
|
||||
}
|
||||
if(c==uf::illegal)
|
||||
return -1;
|
||||
if(!WriteConsoleW(handle_,wbuffer_,out - wbuffer_,0,0))
|
||||
return -1;
|
||||
return p - b;
|
||||
return decoded;
|
||||
}
|
||||
|
||||
static const int buffer_size = 1024;
|
||||
@@ -175,17 +175,18 @@ namespace details {
|
||||
wchar_t *e = b + wsize_;
|
||||
wchar_t *p = b;
|
||||
uf::code_point c;
|
||||
wsize_ = e-p;
|
||||
while(p < e && (c = uf::utf_traits<wchar_t>::decode(p,e))!=uf::illegal && c!=uf::incomplete) {
|
||||
out = uf::utf_traits<char>::encode(c,out);
|
||||
wsize_ = e-p;
|
||||
}
|
||||
|
||||
if(c==uf::illegal)
|
||||
return -1;
|
||||
|
||||
wsize_ = (e-p);
|
||||
|
||||
if(c==uf::incomplete) {
|
||||
memmove(b,p,sizeof(wchar_t)*wsize_);
|
||||
memmove(b,e-wsize_,sizeof(wchar_t)*wsize_);
|
||||
}
|
||||
|
||||
return out - buffer_;
|
||||
@@ -254,5 +255,6 @@ namespace {
|
||||
} // nowide
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
///
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
21
libs/nowide/test/Jamfile.v2
Normal file
21
libs/nowide/test/Jamfile.v2
Normal file
@@ -0,0 +1,21 @@
|
||||
# Boost System Library test Jamfile
|
||||
|
||||
# Copyright Beman Dawes 2003, 2006, Artyom Beilis 2012
|
||||
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
# See library home page at http://www.boost.org/libs/system
|
||||
|
||||
project
|
||||
;
|
||||
|
||||
test-suite "nowide"
|
||||
: [ run test_convert.cpp ]
|
||||
[ run test_env.cpp ]
|
||||
[ run test_fstream.cpp ]
|
||||
[ run test_iostream.cpp : : : <library>/boost/nowide//boost_nowide ]
|
||||
[ run test_stdio.cpp ]
|
||||
[ run test_system.cpp : "-w" : : : test_system_w ]
|
||||
[ run test_system.cpp : "-n" : : : test_system_n ]
|
||||
;
|
||||
@@ -6,7 +6,6 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/nowide/cppenv.hpp>
|
||||
#include <boost/nowide/cenv.hpp>
|
||||
#include <iostream>
|
||||
#include "test.hpp"
|
||||
@@ -18,8 +17,6 @@ int main()
|
||||
char penv[256] = {0};
|
||||
strncpy(penv,("BOOST_TEST2=" + example + "x").c_str(),sizeof(penv)-1);
|
||||
|
||||
std::cout << "C API" << std::endl;
|
||||
|
||||
TEST(boost::nowide::setenv("BOOST_TEST1",example.c_str(),1)==0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1")==example);
|
||||
@@ -29,28 +26,6 @@ int main()
|
||||
TEST(boost::nowide::getenv("BOOST_TEST2"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST_INVALID")==0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST2")==example + "x");
|
||||
|
||||
std::cout << "C++ API C Strings" << std::endl;
|
||||
|
||||
TEST(boost::nowide::set_environment("BOOST_TEST3",example.c_str(),true)==0);
|
||||
TEST(boost::nowide::has_enironment("BOOST_TEST3"));
|
||||
TEST(boost::nowide::get_environment("BOOST_TEST3")==example);
|
||||
TEST(boost::nowide::set_environment("BOOST_TEST3","xx",false)==0);
|
||||
TEST(boost::nowide::get_environment("BOOST_TEST3")==example);
|
||||
TEST(boost::nowide::get_environment("BOOST_TEST_INVALID","inv")==std::string("inv"));
|
||||
|
||||
TEST(boost::nowide::get_environment("BOOST_TEST2")==example + "x");
|
||||
|
||||
std::cout << "C++ API C++ Strings" << std::endl;
|
||||
|
||||
TEST(boost::nowide::set_environment(std::string("BOOST_TEST4"),example,true)==0);
|
||||
TEST(boost::nowide::has_enironment(std::string("BOOST_TEST4")));
|
||||
TEST(boost::nowide::get_environment(std::string("BOOST_TEST4"))==example);
|
||||
TEST(boost::nowide::set_environment(std::string("BOOST_TEST4"),std::string("xx"),false)==0);
|
||||
TEST(boost::nowide::get_environment(std::string("BOOST_TEST4"))==example);
|
||||
|
||||
TEST(boost::nowide::get_environment(std::string("BOOST_TEST2"))==example + "x");
|
||||
TEST(boost::nowide::get_environment(std::string("BOOST_TEST_INVALID"),std::string("inv"))==std::string("inv"));
|
||||
|
||||
std::cout << "Ok" << std::endl;
|
||||
return 0;
|
||||
|
||||
@@ -21,9 +21,17 @@ int main(int argc,char **argv)
|
||||
TEST(boost::nowide::cin.get() == c);
|
||||
}
|
||||
std::string v1,v2;
|
||||
boost::nowide::cout << "Normal I/O:" << std::endl;
|
||||
boost::nowide::cout << example << std::endl;
|
||||
boost::nowide::cerr << example << std::endl;
|
||||
|
||||
boost::nowide::cout << "Flushing each character:" << std::endl;
|
||||
|
||||
for(char const *s=example;*s;s++) {
|
||||
boost::nowide::cout << *s << std::flush;
|
||||
TEST(boost::nowide::cout);
|
||||
}
|
||||
|
||||
TEST(boost::nowide::cout);
|
||||
TEST(boost::nowide::cerr);
|
||||
if(argc==2 && argv[1]==std::string("-i")) {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <boost/nowide/system.hpp>
|
||||
#include <boost/nowide/args.hpp>
|
||||
#include <boost/nowide/cenv.hpp>
|
||||
#include <boost/nowide/cppenv.hpp>
|
||||
#include <iostream>
|
||||
#include "test.hpp"
|
||||
|
||||
@@ -23,30 +22,21 @@ int main(int argc,char **argv,char **env)
|
||||
TEST(argv[1]==example);
|
||||
TEST(argv[2] == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST"));
|
||||
TEST(boost::nowide::has_enironment("BOOST_NOWIDE_TEST"));
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST_NONE") == 0);
|
||||
TEST(!boost::nowide::has_enironment("BOOST_NOWIDE_TEST_NONE"));
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST")==example);
|
||||
TEST(boost::nowide::get_environment("BOOST_NOWIDE_TEST")==example);
|
||||
TEST(boost::nowide::get_environment("BOOST_NOWIDE_TEST","default")==example);
|
||||
TEST(boost::nowide::get_environment("BOOST_NOWIDE_TEST_NONE","default")=="default");
|
||||
std::string sample = "BOOST_NOWIDE_TEST=" + example;
|
||||
bool found = false;
|
||||
std::map<std::string,std::string> strs = boost::nowide::get_environment_strings();
|
||||
size_t total = 0;
|
||||
for(char **e=env;*e!=0;e++) {
|
||||
char *key_end = strchr(*e,'=');
|
||||
TEST(key_end);
|
||||
std::string key = std::string(*e,key_end);
|
||||
std::string value = key_end + 1;
|
||||
TEST(strs.count(key) == 1);
|
||||
TEST(strs[key]==value);
|
||||
TEST(getenv(key.c_str()));
|
||||
TEST(boost::nowide::getenv(key.c_str()) == value);
|
||||
if(*e == sample)
|
||||
found = true;
|
||||
total ++;
|
||||
}
|
||||
TEST(found);
|
||||
TEST(strs.size() == total);
|
||||
std::cout << "Subprocess ok" << std::endl;
|
||||
}
|
||||
else if(argc==2 && argv[1][0]=='-') {
|
||||
@@ -66,27 +56,18 @@ int main(int argc,char **argv,char **env)
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
case '1':
|
||||
TEST(boost::nowide::set_environment(std::string("BOOST_NOWIDE_TEST"),example) == 0);
|
||||
TEST(boost::nowide::set_environment(std::string("BOOST_NOWIDE_TEST_NONE"),example) == 0);
|
||||
TEST(boost::nowide::unset_environment(std::string("BOOST_NOWIDE_TEST_NONE")) == 0);
|
||||
break;
|
||||
case '2':
|
||||
TEST(boost::nowide::set_environment("BOOST_NOWIDE_TEST",example.c_str()) == 0);
|
||||
TEST(boost::nowide::set_environment("BOOST_NOWIDE_TEST_NONE",example.c_str()) == 0);
|
||||
TEST(boost::nowide::unset_environment("BOOST_NOWIDE_TEST_NONE") == 0);
|
||||
break;
|
||||
case '3':
|
||||
case 'n':
|
||||
TEST(boost::nowide::setenv("BOOST_NOWIDE_TEST",example.c_str(),1) == 0);
|
||||
TEST(boost::nowide::setenv("BOOST_NOWIDE_TEST_NONE",example.c_str(),1) == 0);
|
||||
TEST(boost::nowide::unsetenv("BOOST_NOWIDE_TEST_NONE") == 0);
|
||||
break;
|
||||
default:
|
||||
std::cout << "Invalid parameters expected '-1/-2/-3/-w'" << std::endl;
|
||||
std::cout << "Invalid parameters expected '-n/-w'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::string command = argv[0];
|
||||
command += " ";
|
||||
std::string command = "\"";
|
||||
command += argv[0];
|
||||
command += "\" ";
|
||||
command += example;
|
||||
TEST(boost::nowide::system(command.c_str()) == 0);
|
||||
std::cout << "Parent ok" << std::endl;
|
||||
|
||||
Reference in New Issue
Block a user