mirror of
https://github.com/boostorg/nowide.git
synced 2026-02-21 15:12:30 +00:00
Merge pull request #71 from Flamefire/fix_CI_and_bugs
Fix CI and bugs detected
This commit is contained in:
@@ -262,8 +262,14 @@ script:
|
||||
else
|
||||
false
|
||||
fi
|
||||
# DYLD_LIBRARY_PATH causes problems on system() spawned processes
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
LINK=static
|
||||
else
|
||||
LINK=static,shared
|
||||
fi
|
||||
- which $TRAVIS_COMPILER
|
||||
- $TRAVIS_COMPILER --version
|
||||
- |
|
||||
echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam
|
||||
- ./b2 -j3 libs/nowide/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} ${VISIBILITY:+visibility=$VISIBILITY}
|
||||
- ./b2 -j3 libs/nowide/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release link=$LINK ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} ${VISIBILITY:+visibility=$VISIBILITY}
|
||||
|
||||
@@ -44,7 +44,7 @@ endif()
|
||||
|
||||
# Using glob here is ok as it is only for headers
|
||||
file(GLOB_RECURSE headers include/*.hpp)
|
||||
add_library(boost_nowide src/iostream.cpp ${headers})
|
||||
add_library(boost_nowide src/cstdio.cpp src/cstdlib.cpp src/iostream.cpp ${headers})
|
||||
add_library(Boost::nowide ALIAS boost_nowide)
|
||||
set_target_properties(boost_nowide PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
|
||||
@@ -13,7 +13,7 @@ branches:
|
||||
- /feature\/.*/
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
fast_finish: false
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
@@ -81,7 +81,7 @@ test_script:
|
||||
- PATH=%ADDPATH%%PATH%
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- b2 -j3 libs/nowide/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release
|
||||
- b2 -j3 libs/nowide/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release link=shared,static
|
||||
- ps: |
|
||||
If ("$env:BOOST_CMAKE" -eq "1") {
|
||||
./b2 --clean
|
||||
|
||||
@@ -14,7 +14,7 @@ project boost/nowide
|
||||
<link>shared:<define>BOOST_NOWIDE_DYN_LINK=1
|
||||
;
|
||||
|
||||
SOURCES = iostream ;
|
||||
SOURCES = cstdio cstdlib iostream ;
|
||||
|
||||
lib boost_nowide
|
||||
: $(SOURCES).cpp
|
||||
|
||||
@@ -46,22 +46,31 @@
|
||||
#include <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
/// @def BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS
|
||||
/// @brief Define to 1 to use internal classes from fstream.hpp
|
||||
/// @def BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
/// @brief Whether to use the wchar_t* overloads in fstream/filebuf
|
||||
/// Enabled on Windows and Cygwin as the latter may use wchar_t in filesystem::path
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#define BOOST_NOWIDE_USE_WCHAR_OVERLOADS 1
|
||||
#else
|
||||
#define BOOST_NOWIDE_USE_WCHAR_OVERLOADS 0
|
||||
#endif
|
||||
|
||||
/// @def BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
/// @brief Define to 1 to use internal class from filebuf.hpp
|
||||
///
|
||||
/// - On Non-Windows platforms: Define to 1 to use the same classes from header <fstream.hpp>
|
||||
/// that are used on Windows.
|
||||
/// - On Non-Windows platforms: Define to 1 to use the same class from header <filebuf.hpp>
|
||||
/// that is used on Windows.
|
||||
/// - On Windows: No effect, always overwritten to 1
|
||||
///
|
||||
/// Affects boost::nowide::basic_filebuf,
|
||||
/// boost::nowide::basic_ofstream, boost::nowide::basic_ifstream, boost::nowide::basic_fstream
|
||||
#if defined(BOOST_WINDOWS)
|
||||
#ifdef BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS
|
||||
#undef BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS
|
||||
#if defined(BOOST_WINDOWS) || BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
#ifdef BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#undef BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#endif
|
||||
#define BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS 1
|
||||
#elif !defined(BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS)
|
||||
#define BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS 0
|
||||
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT 1
|
||||
#elif !defined(BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT)
|
||||
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT 0
|
||||
#endif
|
||||
|
||||
#if BOOST_VERSION < 106500 && defined(BOOST_GCC) && __GNUC__ >= 7
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -8,18 +9,9 @@
|
||||
#ifndef BOOST_NOWIDE_CSTDIO_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_CSTDIO_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#endif
|
||||
#include <boost/nowide/config.hpp>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
@@ -32,43 +24,24 @@ namespace nowide {
|
||||
///
|
||||
/// \brief Same as freopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
inline FILE* freopen(const char* file_name, const char* mode, FILE* stream)
|
||||
{
|
||||
const wstackstring wname(file_name);
|
||||
const wshort_stackstring wmode(mode);
|
||||
return _wfreopen(wname.get(), wmode.get(), stream);
|
||||
}
|
||||
BOOST_NOWIDE_DECL FILE* freopen(const char* file_name, const char* mode, FILE* stream);
|
||||
///
|
||||
/// \brief Same as fopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
inline FILE* fopen(const char* file_name, const char* mode)
|
||||
{
|
||||
const wstackstring wname(file_name);
|
||||
const wshort_stackstring wmode(mode);
|
||||
return _wfopen(wname.get(), wmode.get());
|
||||
}
|
||||
BOOST_NOWIDE_DECL FILE* fopen(const char* file_name, const char* mode);
|
||||
///
|
||||
/// \brief Same as rename but old_name and new_name are UTF-8 strings
|
||||
///
|
||||
inline int rename(const char* old_name, const char* new_name)
|
||||
{
|
||||
const wstackstring wold(old_name), wnew(new_name);
|
||||
return _wrename(wold.get(), wnew.get());
|
||||
}
|
||||
BOOST_NOWIDE_DECL int rename(const char* old_name, const char* new_name);
|
||||
///
|
||||
/// \brief Same as rename but name is UTF-8 string
|
||||
///
|
||||
inline int remove(const char* name)
|
||||
{
|
||||
const wstackstring wname(name);
|
||||
return _wremove(wname.get());
|
||||
}
|
||||
BOOST_NOWIDE_DECL int remove(const char* name);
|
||||
#endif
|
||||
namespace detail {
|
||||
BOOST_NOWIDE_DECL FILE* wfopen(const wchar_t* filename, const wchar_t* mode);
|
||||
}
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,12 +8,8 @@
|
||||
#ifndef BOOST_NOWIDE_CSTDLIB_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_CSTDLIB_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_WINDOWS
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <boost/nowide/windows.hpp>
|
||||
#include <vector>
|
||||
#else
|
||||
#include <boost/nowide/config.hpp>
|
||||
#if !BOOST_WINDOWS
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
@@ -21,9 +17,6 @@ namespace boost {
|
||||
namespace nowide {
|
||||
#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::getenv;
|
||||
using ::setenv;
|
||||
using ::unsetenv;
|
||||
using ::putenv;
|
||||
using std::system;
|
||||
#else
|
||||
///
|
||||
@@ -31,91 +24,43 @@ namespace nowide {
|
||||
///
|
||||
/// This function is not thread safe or reenterable as defined by the standard library
|
||||
///
|
||||
inline char* getenv(const char* key)
|
||||
{
|
||||
static stackstring value;
|
||||
|
||||
const wshort_stackstring name(key);
|
||||
|
||||
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.get(), 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.get(), &tmp[0], static_cast<unsigned>(tmp.size() - 1));
|
||||
// The size may have changed
|
||||
if(n >= tmp.size() - 1)
|
||||
return 0;
|
||||
ptr = &tmp[0];
|
||||
}
|
||||
value.convert(ptr);
|
||||
return value.get();
|
||||
}
|
||||
///
|
||||
/// \brief UTF-8 aware setenv, \a key - the variable name, \a value is a new UTF-8 value,
|
||||
///
|
||||
/// if overwrite is not 0, that the old value is always overwritten, otherwise,
|
||||
/// if the variable exists it remains unchanged
|
||||
///
|
||||
inline int setenv(const char* key, const char* value, int overwrite)
|
||||
{
|
||||
const wshort_stackstring name(key);
|
||||
if(!overwrite)
|
||||
{
|
||||
wchar_t unused[2];
|
||||
if(GetEnvironmentVariableW(name.get(), unused, 2) != 0 || GetLastError() != 203) // ERROR_ENVVAR_NOT_FOUND
|
||||
return 0;
|
||||
}
|
||||
const wstackstring wval(value);
|
||||
if(SetEnvironmentVariableW(name.get(), wval.get()))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
///
|
||||
/// \brief Remove environment variable \a key
|
||||
///
|
||||
inline int unsetenv(const char* key)
|
||||
{
|
||||
const wshort_stackstring name(key);
|
||||
if(SetEnvironmentVariableW(name.get(), 0))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
///
|
||||
/// \brief UTF-8 aware putenv implementation, expects string in format KEY=VALUE
|
||||
///
|
||||
inline int putenv(char* string)
|
||||
{
|
||||
const char* key = string;
|
||||
const char* key_end = string;
|
||||
while(*key_end != '=' && *key_end != '\0')
|
||||
key_end++;
|
||||
if(*key_end == '\0')
|
||||
return -1;
|
||||
const wshort_stackstring wkey(key, key_end);
|
||||
const wstackstring wvalue(key_end + 1);
|
||||
|
||||
if(SetEnvironmentVariableW(wkey.get(), wvalue.get()))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
BOOST_NOWIDE_DECL char* getenv(const char* key);
|
||||
|
||||
///
|
||||
/// Same as std::system but cmd is UTF-8.
|
||||
///
|
||||
inline int system(const char* cmd)
|
||||
{
|
||||
if(!cmd)
|
||||
return _wsystem(0);
|
||||
const wstackstring wcmd(cmd);
|
||||
return _wsystem(wcmd.get());
|
||||
}
|
||||
BOOST_NOWIDE_DECL int system(const char* cmd);
|
||||
|
||||
#endif
|
||||
///
|
||||
/// \brief Set environment variable \a key to \a value
|
||||
///
|
||||
/// if overwrite is not 0, that the old value is always overwritten, otherwise,
|
||||
/// if the variable exists it remains unchanged
|
||||
///
|
||||
/// \a key and \a value are UTF-8 on Windows
|
||||
/// \return zero on success, else nonzero
|
||||
///
|
||||
BOOST_NOWIDE_DECL int setenv(const char* key, const char* value, int overwrite);
|
||||
|
||||
///
|
||||
/// \brief Remove environment variable \a key
|
||||
///
|
||||
/// \a key is UTF-8 on Windows
|
||||
/// \return zero on success, else nonzero
|
||||
///
|
||||
BOOST_NOWIDE_DECL int unsetenv(const char* key);
|
||||
|
||||
///
|
||||
/// \brief Adds or changes an environment variable, \a string must be in format KEY=VALUE
|
||||
///
|
||||
/// \a string MAY become part of the environment, hence changes to the value MAY change
|
||||
/// the environment. For portability it is hence recommended NOT to change it.
|
||||
/// \a string is UTF-8 on Windows
|
||||
/// \return zero on success, else nonzero
|
||||
///
|
||||
BOOST_NOWIDE_DECL int putenv(char* string);
|
||||
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2019 Alexander Grund
|
||||
// Copyright (c) 2019-2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -10,7 +10,8 @@
|
||||
#define BOOST_NOWIDE_FILEBUF_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/config.hpp>
|
||||
#if BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS
|
||||
#if BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
@@ -23,18 +24,12 @@
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996 4244 4800)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
#if !BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
#if !BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT && !defined(BOOST_NOWIDE_DOXYGEN)
|
||||
using std::basic_filebuf;
|
||||
using std::filebuf;
|
||||
#else // Windows
|
||||
|
||||
///
|
||||
/// \brief This forward declaration defines the basic_filebuf type.
|
||||
///
|
||||
@@ -97,20 +92,13 @@ namespace nowide {
|
||||
if(is_open())
|
||||
return NULL;
|
||||
validate_cvt(this->getloc());
|
||||
const bool ate = bool(mode & std::ios_base::ate);
|
||||
const bool ate = (mode & std::ios_base::ate) != 0;
|
||||
if(ate)
|
||||
mode = mode ^ std::ios_base::ate;
|
||||
mode &= ~std::ios_base::ate;
|
||||
const wchar_t* smode = get_mode(mode);
|
||||
if(!smode)
|
||||
return 0;
|
||||
#ifdef BOOST_WINDOWS
|
||||
file_ = ::_wfopen(s, smode);
|
||||
#else
|
||||
const stackstring name(s);
|
||||
const short_stackstring smode2(smode);
|
||||
file_ = std::fopen(name.get(), smode2.get());
|
||||
#endif
|
||||
|
||||
file_ = detail::wfopen(s, smode);
|
||||
if(!file_)
|
||||
return 0;
|
||||
if(ate && std::fseek(file_, 0, SEEK_END) != 0)
|
||||
@@ -177,7 +165,7 @@ namespace nowide {
|
||||
if(owns_buffer_)
|
||||
delete[] buffer_;
|
||||
buffer_ = s;
|
||||
buffer_size_ = (n >= 0) ? n : 0;
|
||||
buffer_size_ = (n >= 0) ? static_cast<size_t>(n) : 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -197,7 +185,7 @@ namespace nowide {
|
||||
setp(buffer_, buffer_ + buffer_size_);
|
||||
if(c != EOF)
|
||||
{
|
||||
*buffer_ = c;
|
||||
*buffer_ = Traits::to_char_type(c);
|
||||
pbump(1);
|
||||
}
|
||||
} else if(c != EOF)
|
||||
@@ -206,7 +194,7 @@ namespace nowide {
|
||||
{
|
||||
make_buffer();
|
||||
setp(buffer_, buffer_ + buffer_size_);
|
||||
*buffer_ = c;
|
||||
*buffer_ = Traits::to_char_type(c);
|
||||
pbump(1);
|
||||
} else if(std::fputc(c, file_) == EOF)
|
||||
{
|
||||
@@ -247,7 +235,7 @@ namespace nowide {
|
||||
const int c = std::fgetc(file_);
|
||||
if(c == EOF)
|
||||
return EOF;
|
||||
last_char_ = c;
|
||||
last_char_ = Traits::to_char_type(c);
|
||||
setg(&last_char_, &last_char_, &last_char_ + 1);
|
||||
} else
|
||||
{
|
||||
@@ -305,7 +293,8 @@ namespace nowide {
|
||||
case std::ios_base::end: whence = SEEK_END; break;
|
||||
default: assert(false); return EOF;
|
||||
}
|
||||
if(std::fseek(file_, off, whence) != 0)
|
||||
assert(off <= std::numeric_limits<long>::max());
|
||||
if(std::fseek(file_, static_cast<long>(off), whence) != 0)
|
||||
return EOF;
|
||||
return std::ftell(file_);
|
||||
}
|
||||
@@ -330,7 +319,7 @@ namespace nowide {
|
||||
const std::streamsize off = gptr() - egptr();
|
||||
setg(0, 0, 0);
|
||||
assert(off <= std::numeric_limits<long>::max());
|
||||
if(off && std::fseek(file_, off, SEEK_CUR) != 0)
|
||||
if(off && std::fseek(file_, static_cast<long>(off), SEEK_CUR) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -427,8 +416,4 @@ namespace nowide {
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace nowide {
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#ifdef BOOST_WINDOWS
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
explicit basic_ifstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::in)
|
||||
{
|
||||
open(file_name, mode);
|
||||
@@ -118,7 +118,7 @@ namespace nowide {
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#ifdef BOOST_WINDOWS
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
explicit basic_ofstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::out)
|
||||
{
|
||||
open(file_name, mode);
|
||||
@@ -162,7 +162,7 @@ namespace nowide {
|
||||
{
|
||||
open(file_name, mode);
|
||||
}
|
||||
#ifdef BOOST_WINDOWS
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
explicit basic_fstream(const wchar_t* file_name,
|
||||
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
|
||||
{
|
||||
@@ -187,9 +187,6 @@ namespace nowide {
|
||||
using fstream_impl::close;
|
||||
using fstream_impl::rdbuf;
|
||||
};
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Same as std::filebuf but accepts UTF-8 strings under Windows
|
||||
@@ -225,6 +222,7 @@ namespace nowide {
|
||||
public T_StreamType::template stream_base<CharType, Traits>::type
|
||||
{
|
||||
typedef basic_filebuf<CharType, Traits> internal_buffer_type;
|
||||
typedef buf_holder<internal_buffer_type> base_buf_holder;
|
||||
typedef typename T_StreamType::template stream_base<CharType, Traits>::type stream_base;
|
||||
|
||||
public:
|
||||
@@ -232,7 +230,9 @@ namespace nowide {
|
||||
using stream_base::clear;
|
||||
|
||||
protected:
|
||||
fstream_impl() : stream_base(rdbuf())
|
||||
using base_buf_holder::buf_;
|
||||
|
||||
fstream_impl() : stream_base(&buf_)
|
||||
{}
|
||||
|
||||
void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
|
||||
@@ -243,7 +243,7 @@ namespace nowide {
|
||||
typename detail::enable_if_path<Path, void>::type open(const Path& file_name,
|
||||
std::ios_base::openmode mode = T_StreamType::mode())
|
||||
{
|
||||
return open(file_name.c_str(), mode);
|
||||
open(file_name.c_str(), mode);
|
||||
}
|
||||
void open(const char* file_name, std::ios_base::openmode mode = T_StreamType::mode())
|
||||
{
|
||||
@@ -252,7 +252,7 @@ namespace nowide {
|
||||
else
|
||||
clear();
|
||||
}
|
||||
#ifdef BOOST_WINDOWS
|
||||
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
|
||||
void open(const wchar_t* file_name, std::ios_base::openmode mode = T_StreamType::mode())
|
||||
{
|
||||
if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
|
||||
@@ -277,10 +277,12 @@ namespace nowide {
|
||||
|
||||
internal_buffer_type* rdbuf() const
|
||||
{
|
||||
return const_cast<internal_buffer_type*>(&this->buf_);
|
||||
return const_cast<internal_buffer_type*>(&buf_);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
/// Trait to heuristically check for a *::filesystem::path
|
||||
/// Done by checking for make_preferred and filename member functions with correct signature
|
||||
template<typename T>
|
||||
|
||||
@@ -34,50 +34,6 @@ namespace nowide {
|
||||
typedef CharOut output_char;
|
||||
typedef CharIn input_char;
|
||||
|
||||
basic_stackstring(const basic_stackstring& other) : data_(NULL)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
friend void swap(basic_stackstring& lhs, basic_stackstring& rhs)
|
||||
{
|
||||
if(lhs.uses_stack_memory())
|
||||
{
|
||||
if(rhs.uses_stack_memory())
|
||||
{
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
std::swap(lhs.buffer_[i], rhs.buffer_[i]);
|
||||
} else
|
||||
{
|
||||
lhs.data_ = rhs.data_;
|
||||
rhs.data_ = rhs.buffer_;
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
rhs.buffer_[i] = lhs.buffer_[i];
|
||||
}
|
||||
} else if(rhs.uses_stack_memory())
|
||||
{
|
||||
rhs.data_ = lhs.data_;
|
||||
lhs.data_ = lhs.buffer_;
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
lhs.buffer_[i] = rhs.buffer_[i];
|
||||
} else
|
||||
std::swap(lhs.data_, rhs.data_);
|
||||
}
|
||||
basic_stackstring& operator=(const basic_stackstring& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
clear();
|
||||
const size_t len = other.length();
|
||||
if(other.uses_stack_memory())
|
||||
data_ = buffer_;
|
||||
else
|
||||
data_ = new output_char[len + 1];
|
||||
std::memcpy(data_, other.data_, sizeof(output_char) * (len + 1));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_stackstring() : data_(NULL)
|
||||
{
|
||||
buffer_[0] = 0;
|
||||
@@ -90,6 +46,36 @@ namespace nowide {
|
||||
{
|
||||
convert(begin, end);
|
||||
}
|
||||
|
||||
basic_stackstring(const basic_stackstring& other) : data_(NULL)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
basic_stackstring& operator=(const basic_stackstring& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
clear();
|
||||
const size_t len = other.length();
|
||||
if(other.uses_stack_memory())
|
||||
data_ = buffer_;
|
||||
else if(other.data_)
|
||||
data_ = new output_char[len + 1];
|
||||
else
|
||||
{
|
||||
data_ = NULL;
|
||||
return *this;
|
||||
}
|
||||
std::memcpy(data_, other.data_, sizeof(output_char) * (len + 1));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~basic_stackstring()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
output_char* convert(const input_char* input)
|
||||
{
|
||||
if(input)
|
||||
@@ -132,9 +118,30 @@ namespace nowide {
|
||||
delete[] data_;
|
||||
data_ = NULL;
|
||||
}
|
||||
~basic_stackstring()
|
||||
|
||||
friend void swap(basic_stackstring& lhs, basic_stackstring& rhs)
|
||||
{
|
||||
clear();
|
||||
if(lhs.uses_stack_memory())
|
||||
{
|
||||
if(rhs.uses_stack_memory())
|
||||
{
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
std::swap(lhs.buffer_[i], rhs.buffer_[i]);
|
||||
} else
|
||||
{
|
||||
lhs.data_ = rhs.data_;
|
||||
rhs.data_ = rhs.buffer_;
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
rhs.buffer_[i] = lhs.buffer_[i];
|
||||
}
|
||||
} else if(rhs.uses_stack_memory())
|
||||
{
|
||||
rhs.data_ = lhs.data_;
|
||||
lhs.data_ = lhs.buffer_;
|
||||
for(size_t i = 0; i < buffer_size; i++)
|
||||
lhs.buffer_[i] = rhs.buffer_[i];
|
||||
} else
|
||||
std::swap(lhs.data_, rhs.data_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
74
src/cstdio.cpp
Normal file
74
src/cstdio.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#define BOOST_NOWIDE_SOURCE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#elif(defined(__MINGW32__) || defined(__CYGWIN__)) && defined(__STRICT_ANSI__)
|
||||
// Need the _w* functions which are extensions on MinGW/Cygwin
|
||||
#undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
namespace detail {
|
||||
FILE* wfopen(const wchar_t* filename, const wchar_t* mode)
|
||||
{
|
||||
#ifdef BOOST_WINDOWS
|
||||
return ::_wfopen(filename, mode);
|
||||
#else
|
||||
const stackstring name(filename);
|
||||
const short_stackstring smode2(mode);
|
||||
return std::fopen(name.get(), smode2.get());
|
||||
#endif
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
///
|
||||
/// \brief Same as freopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
FILE* freopen(const char* file_name, const char* mode, FILE* stream)
|
||||
{
|
||||
const wstackstring wname(file_name);
|
||||
const wshort_stackstring wmode(mode);
|
||||
return _wfreopen(wname.get(), wmode.get(), stream);
|
||||
}
|
||||
///
|
||||
/// \brief Same as fopen but file_name and mode are UTF-8 strings
|
||||
///
|
||||
FILE* fopen(const char* file_name, const char* mode)
|
||||
{
|
||||
const wstackstring wname(file_name);
|
||||
const wshort_stackstring wmode(mode);
|
||||
return _wfopen(wname.get(), wmode.get());
|
||||
}
|
||||
///
|
||||
/// \brief Same as rename but old_name and new_name are UTF-8 strings
|
||||
///
|
||||
int rename(const char* old_name, const char* new_name)
|
||||
{
|
||||
const wstackstring wold(old_name), wnew(new_name);
|
||||
return _wrename(wold.get(), wnew.get());
|
||||
}
|
||||
///
|
||||
/// \brief Same as rename but name is UTF-8 string
|
||||
///
|
||||
int remove(const char* name)
|
||||
{
|
||||
const wstackstring wname(name);
|
||||
return _wremove(wname.get());
|
||||
}
|
||||
#endif
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
121
src/cstdlib.cpp
Normal file
121
src/cstdlib.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2020 Alexander Grund
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#define BOOST_NOWIDE_SOURCE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#elif(defined(__MINGW32__) || defined(__CYGWIN__)) && defined(__STRICT_ANSI__)
|
||||
// Need the _w* functions which are extensions on MinGW/Cygwin
|
||||
#undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
#include <boost/nowide/cstdlib.hpp>
|
||||
|
||||
#if !BOOST_WINDOWS
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
int setenv(const char* key, const char* value, int overwrite)
|
||||
{
|
||||
return ::setenv(key, value, overwrite);
|
||||
}
|
||||
|
||||
int unsetenv(const char* key)
|
||||
{
|
||||
return ::unsetenv(key);
|
||||
}
|
||||
|
||||
int putenv(char* string)
|
||||
{
|
||||
return ::putenv(string);
|
||||
}
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
#else
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
char* getenv(const char* key)
|
||||
{
|
||||
static stackstring value;
|
||||
|
||||
const wshort_stackstring name(key);
|
||||
|
||||
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.get(), 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.get(), &tmp[0], static_cast<unsigned>(tmp.size() - 1));
|
||||
// The size may have changed
|
||||
if(n >= tmp.size() - 1)
|
||||
return 0;
|
||||
ptr = &tmp[0];
|
||||
}
|
||||
value.convert(ptr);
|
||||
return value.get();
|
||||
}
|
||||
|
||||
int setenv(const char* key, const char* value, int overwrite)
|
||||
{
|
||||
const wshort_stackstring name(key);
|
||||
if(!overwrite)
|
||||
{
|
||||
wchar_t unused[2];
|
||||
if(GetEnvironmentVariableW(name.get(), unused, 2) != 0 || GetLastError() != 203) // ERROR_ENVVAR_NOT_FOUND
|
||||
return 0;
|
||||
}
|
||||
const wstackstring wval(value);
|
||||
if(SetEnvironmentVariableW(name.get(), wval.get()))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unsetenv(const char* key)
|
||||
{
|
||||
const wshort_stackstring name(key);
|
||||
if(SetEnvironmentVariableW(name.get(), 0))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int putenv(char* string)
|
||||
{
|
||||
const char* key = string;
|
||||
const char* key_end = string;
|
||||
while(*key_end != '=' && *key_end != '\0')
|
||||
key_end++;
|
||||
if(*key_end == '\0')
|
||||
return -1;
|
||||
const wshort_stackstring wkey(key, key_end);
|
||||
const wstackstring wvalue(key_end + 1);
|
||||
|
||||
if(SetEnvironmentVariableW(wkey.get(), wvalue.get()))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int system(const char* cmd)
|
||||
{
|
||||
if(!cmd)
|
||||
return _wsystem(0);
|
||||
const wstackstring wcmd(cmd);
|
||||
return _wsystem(wcmd.get());
|
||||
}
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
#endif
|
||||
@@ -31,12 +31,12 @@
|
||||
#endif
|
||||
|
||||
#if defined(NOWIDE_WINDOWS)
|
||||
#ifdef BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS
|
||||
#undef BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS
|
||||
#ifdef BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#undef BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
#endif
|
||||
#define BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS 1
|
||||
#elif !defined(BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS)
|
||||
#define BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS 0
|
||||
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT 1
|
||||
#elif !defined(BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT)
|
||||
#define BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@ boost_nowide_add_test(test_system_n SRC test_system.cpp DEFINITIONS BOOST_NOWIDE
|
||||
if(WIN32)
|
||||
boost_nowide_add_test(test_system_w SRC test_system.cpp DEFINITIONS BOOST_NOWIDE_TEST_USE_NARROW=0)
|
||||
else()
|
||||
boost_nowide_add_test(test_internal_fstream SRC test_fstream.cpp DEFINITIONS BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS=1)
|
||||
boost_nowide_add_test(test_internal_fstream SRC test_fstream.cpp DEFINITIONS BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT=1)
|
||||
endif()
|
||||
|
||||
if(NOT BOOST_NOWIDE_STANDALONE)
|
||||
@@ -40,4 +40,4 @@ endif()
|
||||
if(NOT BOOST_SUPERPROJECT_SOURCE_DIR)
|
||||
find_package(Boost 1.56 REQUIRED COMPONENTS chrono)
|
||||
endif()
|
||||
boost_nowide_add_test(benchmark_fstream COMPILE_ONLY DEFINITIONS BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS=1 LIBRARIES Boost::chrono)
|
||||
boost_nowide_add_test(benchmark_fstream COMPILE_ONLY DEFINITIONS BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT=1 LIBRARIES Boost::chrono)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import testing ;
|
||||
|
||||
project : requirements
|
||||
<library>/boost/nowide//boost_nowide
|
||||
<warnings>pedantic
|
||||
<warnings-as-errors>on
|
||||
<toolset>gcc:<cxxflags>-Wno-long-long
|
||||
@@ -26,12 +27,11 @@ run test_env.cpp ;
|
||||
run test_env.cpp : : : <define>BOOST_NOWIDE_TEST_INCLUDE_WINDOWS=1 : test_env_win ;
|
||||
run test_fs.cpp : : : <library>/boost/filesystem//boost_filesystem/<warnings-as-errors>off : ;
|
||||
run test_fstream.cpp ;
|
||||
run test_fstream.cpp : : : <define>BOOST_NOWIDE_USE_FSTREAM_REPLACEMENTS=1 <target-os>windows:<build>no : test_internal_fstream;
|
||||
run test_iostream.cpp : : : <library>/boost/nowide//boost_nowide <link>static : test_iostream_static ;
|
||||
run test_iostream.cpp : : : <library>/boost/nowide//boost_nowide <link>shared : test_iostream_shared ;
|
||||
run test_fstream.cpp : : : <define>BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT=1 <target-os>windows:<build>no : test_internal_fstream ;
|
||||
run test_iostream.cpp ;
|
||||
run test_stackstring.cpp ;
|
||||
run test_stdio.cpp ;
|
||||
run test_system.cpp : : : <define>BOOST_NOWIDE_TEST_USE_NARROW=1 <target-os>windows:<library>shell32 : test_system_n ;
|
||||
run test_system.cpp : : : <define>BOOST_NOWIDE_TEST_USE_NARROW=0 <target-os>windows:<library>shell32 <build>no <target-os>windows:<build>yes: test_system_w ;
|
||||
run test_system.cpp : : : <define>BOOST_NOWIDE_TEST_USE_NARROW=0 <target-os>windows:<library>shell32 <build>no <target-os>windows:<build>yes : test_system_w ;
|
||||
|
||||
compile benchmark_fstream.cpp : <define>BOOST_NOWIDE_USE_WIN_FSTREAM=1 <library>/boost/chrono//boost_chrono/;
|
||||
compile benchmark_fstream.cpp : <define>BOOST_NOWIDE_USE_WIN_FSTREAM=1 <library>/boost/chrono//boost_chrono/ ;
|
||||
|
||||
@@ -19,11 +19,17 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable : 4996) // function unsafe/deprecated
|
||||
#endif
|
||||
template<typename Key, typename Value, typename Key2>
|
||||
Value get(const std::map<Key, Value>& map, const Key2& key)
|
||||
{
|
||||
typename std::map<Key, Value>::const_iterator it = map.find(key);
|
||||
if(it == map.end())
|
||||
throw std::runtime_error("Key not found");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
namespace nw = boost::nowide;
|
||||
template<typename FStream>
|
||||
@@ -66,7 +72,7 @@ class io_stdio
|
||||
public:
|
||||
io_stdio(const char* file, bool read)
|
||||
{
|
||||
f_ = std::fopen(file, read ? "r" : "w+");
|
||||
f_ = nw::fopen(file, read ? "r" : "w+");
|
||||
TEST(f_);
|
||||
}
|
||||
~io_stdio()
|
||||
@@ -201,8 +207,8 @@ perf_data test_io_driver(const char* file, const char* type)
|
||||
double read_speed = 0, write_speed = 0;
|
||||
for(int i = 0; i < repeats; i++)
|
||||
{
|
||||
read_speed += results[i].read.at(block_size);
|
||||
write_speed += results[i].write.at(block_size);
|
||||
read_speed += get(results[i].read, block_size);
|
||||
write_speed += get(results[i].write, block_size);
|
||||
}
|
||||
results[0].read[block_size] = read_speed / repeats;
|
||||
results[0].write[block_size] = write_speed / repeats;
|
||||
@@ -221,9 +227,9 @@ void print_perf_data(const std::map<size_t, double>& stdio_data,
|
||||
for(int block_size = MIN_BLOCK_SIZE; block_size <= MAX_BLOCK_SIZE; block_size *= 2)
|
||||
{
|
||||
std::cout << std::setw(8) << block_size << " ";
|
||||
std::cout << std::fixed << std::setprecision(3) << std::setw(8) << stdio_data.at(block_size) << " MB/s ";
|
||||
std::cout << std::fixed << std::setprecision(3) << std::setw(8) << std_data.at(block_size) << " MB/s ";
|
||||
std::cout << std::fixed << std::setprecision(3) << std::setw(8) << nowide_data.at(block_size) << " MB/s ";
|
||||
std::cout << std::fixed << std::setprecision(3) << std::setw(8) << get(stdio_data, block_size) << " MB/s ";
|
||||
std::cout << std::fixed << std::setprecision(3) << std::setw(8) << get(std_data, block_size) << " MB/s ";
|
||||
std::cout << std::fixed << std::setprecision(3) << std::setw(8) << get(nowide_data, block_size) << " MB/s ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,23 +9,64 @@
|
||||
#ifndef BOOST_NOWIDE_LIB_TEST_H_INCLUDED
|
||||
#define BOOST_NOWIDE_LIB_TEST_H_INCLUDED
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
struct test_monitor
|
||||
{
|
||||
test_monitor()
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER > 1310)
|
||||
// disable message boxes on assert(), abort()
|
||||
::_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
||||
#endif
|
||||
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
|
||||
// disable message boxes on iterator debugging violations
|
||||
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
inline boost::nowide::test_monitor& test_mon()
|
||||
{
|
||||
static boost::nowide::test_monitor instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// Function called when a test failed to be able set a breakpoint for debugging
|
||||
inline void test_failed(const std::string& msg)
|
||||
{
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define DISABLE_CONST_EXPR_DETECTED __pragma(warning(push)) __pragma(warning(disable : 4127))
|
||||
#define DISABLE_CONST_EXPR_DETECTED_POP __pragma(warning(pop))
|
||||
#else
|
||||
#define DISABLE_CONST_EXPR_DETECTED
|
||||
#define DISABLE_CONST_EXPR_DETECTED_POP
|
||||
#endif
|
||||
|
||||
#define TEST(x) \
|
||||
do \
|
||||
{ \
|
||||
test_mon(); \
|
||||
if(x) \
|
||||
break; \
|
||||
std::ostringstream ss; \
|
||||
ss << "Error " #x " in " << __FILE__ << ':' << __LINE__ << " " << __FUNCTION__; \
|
||||
test_failed(ss.str()); \
|
||||
} while(0)
|
||||
DISABLE_CONST_EXPR_DETECTED \
|
||||
} while(0) DISABLE_CONST_EXPR_DETECTED_POP
|
||||
|
||||
#endif // #ifndef BOOST_NOWIDE_LIB_TEST_H_INCLUDED
|
||||
|
||||
@@ -16,9 +16,17 @@
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable : 4996) // function unsafe/deprecated
|
||||
#endif
|
||||
// "Safe" strcpy version with NULL termination to make MSVC runtime happy
|
||||
// which warns when using strncpy
|
||||
template<size_t size>
|
||||
void strcpy_safe(char (&dest)[size], const char* src)
|
||||
{
|
||||
size_t len = std::strlen(src);
|
||||
if(len >= size)
|
||||
len = size - 1u;
|
||||
std::memcpy(dest, src, len);
|
||||
dest[len] = 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -26,7 +34,7 @@ int main()
|
||||
{
|
||||
std::string example = "\xd7\xa9-\xd0\xbc-\xce\xbd";
|
||||
char penv[256] = {0};
|
||||
strncpy(penv, ("BOOST_TEST2=" + example + "x").c_str(), sizeof(penv) - 1);
|
||||
strcpy_safe(penv, ("BOOST_TEST2=" + example + "x").c_str());
|
||||
|
||||
TEST(boost::nowide::setenv("BOOST_TEST1", example.c_str(), 1) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1"));
|
||||
@@ -42,7 +50,7 @@ int main()
|
||||
// But GLIBC has an extension that unsets the env var instead
|
||||
char penv2[256] = {0};
|
||||
const char* sPenv2 = "BOOST_TEST1SOMEGARBAGE=";
|
||||
strncpy(penv2, sPenv2, sizeof(penv2) - 1);
|
||||
strcpy_safe(penv2, sPenv2);
|
||||
// End the string before the equals sign -> Expect fail
|
||||
penv2[strlen("BOOST_TEST1")] = '\0';
|
||||
TEST(boost::nowide::putenv(penv2) == -1);
|
||||
|
||||
@@ -50,7 +50,6 @@ bool file_contents_equal(const char* filepath, const char (&contents)[N], bool b
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename FStream>
|
||||
void test_with_different_buffer_sizes(const char* filepath)
|
||||
{
|
||||
/* Important part of the standard for mixing input with output:
|
||||
@@ -63,13 +62,13 @@ void test_with_different_buffer_sizes(const char* filepath)
|
||||
{
|
||||
std::cout << "Buffer size = " << i << std::endl;
|
||||
char buf[16];
|
||||
FStream f;
|
||||
nw::fstream f;
|
||||
// Different conditions when setbuf might be called: Usually before opening a file is OK
|
||||
if(i >= 0)
|
||||
f.rdbuf()->pubsetbuf((i == 0) ? NULL : buf, i);
|
||||
f.open(filepath, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
TEST(f);
|
||||
|
||||
// Add 'abcdefg'
|
||||
TEST(f.put('a'));
|
||||
TEST(f.put('b'));
|
||||
TEST(f.put('c'));
|
||||
@@ -77,67 +76,84 @@ void test_with_different_buffer_sizes(const char* filepath)
|
||||
TEST(f.put('e'));
|
||||
TEST(f.put('f'));
|
||||
TEST(f.put('g'));
|
||||
// Read first char
|
||||
TEST(f.seekg(0));
|
||||
TEST(f.get() == 'a');
|
||||
TEST(f.gcount() == 1u);
|
||||
// Skip next char
|
||||
TEST(f.seekg(1, std::ios::cur));
|
||||
TEST(f.get() == 'c');
|
||||
TEST(f.gcount() == 1u);
|
||||
// Go back 1 char
|
||||
TEST(f.seekg(-1, std::ios::cur));
|
||||
TEST(f.get() == 'c');
|
||||
TEST(f.gcount() == 1u);
|
||||
|
||||
// Test switching between read->write->read
|
||||
// case 1) overwrite, flush, read
|
||||
TEST(f.seekg(1));
|
||||
TEST(f.put('B'));
|
||||
TEST(f.flush()); // Flush when changing out->in
|
||||
TEST(f.get() == 'c');
|
||||
TEST(f.gcount() == 1u);
|
||||
TEST(f.seekg(1));
|
||||
TEST(f.get() == 'B');
|
||||
TEST(f.gcount() == 1u);
|
||||
// case 2) overwrite, seek, read
|
||||
TEST(f.seekg(2));
|
||||
TEST(f.put('C'));
|
||||
TEST(f.seekg(3)); // Seek when changing out->in
|
||||
TEST(f.get() == 'd');
|
||||
TEST(f.gcount() == 1u);
|
||||
|
||||
// Check that sequence from start equals expected
|
||||
TEST(f.seekg(0));
|
||||
TEST(f.get() == 'a');
|
||||
TEST(f.get() == 'B');
|
||||
TEST(f.get() == 'C');
|
||||
TEST(f.get() == 'd');
|
||||
TEST(f.get() == 'e');
|
||||
// Putback after flush
|
||||
|
||||
// Putback after flush is implementation defined
|
||||
// Boost.Nowide: Works
|
||||
#if BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
TEST(f << std::flush);
|
||||
TEST(f.putback('e'));
|
||||
TEST(f.putback('d'));
|
||||
TEST(f.get() == 'd');
|
||||
TEST(f.get() == 'e');
|
||||
#endif
|
||||
// Rest of sequence
|
||||
TEST(f.get() == 'f');
|
||||
TEST(f.get() == 'g');
|
||||
TEST(f.get() == EOF);
|
||||
|
||||
// Put back until front of file is reached
|
||||
f.clear();
|
||||
TEST(f.seekg(1));
|
||||
TEST(f.get() == 'B');
|
||||
TEST(f.putback('B'));
|
||||
// Putting back multiple chars is not possible on all implementations after a seek/flush
|
||||
if(f.putback('a'))
|
||||
{
|
||||
TEST(!f.putback('x')); // At beginning of file -> No putback possible
|
||||
// Get characters that were putback to avoid MSVC bug https://github.com/microsoft/STL/issues/342
|
||||
f.clear();
|
||||
TEST(f.get() == 'a');
|
||||
TEST(f.get() == 'B');
|
||||
} else
|
||||
{
|
||||
f.clear();
|
||||
TEST(f.get() == 'B');
|
||||
}
|
||||
#if BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT
|
||||
TEST(f.putback('a'));
|
||||
TEST(!f.putback('x')); // At beginning of file -> No putback possible
|
||||
// Get characters that were putback to avoid MSVC bug https://github.com/microsoft/STL/issues/342
|
||||
f.clear();
|
||||
TEST(f.get() == 'a');
|
||||
#endif
|
||||
TEST(f.get() == 'B');
|
||||
f.close();
|
||||
TEST(nw::remove(filepath) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FileBuf>
|
||||
void test_close(const char* filepath)
|
||||
{
|
||||
const std::string filepath2 = std::string(filepath) + ".2";
|
||||
// Make sure file does not exist yet
|
||||
nw::remove(filepath2.c_str());
|
||||
TEST(!file_exists(filepath2.c_str()));
|
||||
FileBuf buf;
|
||||
nw::filebuf buf;
|
||||
TEST(buf.open(filepath, std::ios_base::out) == &buf);
|
||||
TEST(buf.is_open());
|
||||
// Opening when already open fails
|
||||
@@ -487,17 +503,11 @@ int main(int, char** argv)
|
||||
test_fstream(exampleFilename.c_str());
|
||||
test_is_open(exampleFilename.c_str());
|
||||
|
||||
std::cout << "Complex IO - Sanity Check" << std::endl;
|
||||
// Don't use chars the std stream can't properly handle
|
||||
test_with_different_buffer_sizes<std::fstream>((std::string(argv[0]) + "-bufferSize.txt").c_str());
|
||||
std::cout << "Complex IO - Test" << std::endl;
|
||||
test_with_different_buffer_sizes<nw::fstream>(exampleFilename.c_str());
|
||||
std::cout << "Complex IO" << std::endl;
|
||||
test_with_different_buffer_sizes(exampleFilename.c_str());
|
||||
|
||||
std::cout << "filebuf::close - Sanity Check" << std::endl;
|
||||
// Don't use chars the std stream can't properly handle
|
||||
test_close<std::filebuf>((std::string(argv[0]) + "-bufferSize.txt").c_str());
|
||||
std::cout << "filebuf::close - Test" << std::endl;
|
||||
test_close<nw::filebuf>(exampleFilename.c_str());
|
||||
std::cout << "filebuf::close" << std::endl;
|
||||
test_close(exampleFilename.c_str());
|
||||
|
||||
std::cout << "Flush - Sanity Check" << std::endl;
|
||||
test_flush<std::ifstream, std::ofstream>(exampleFilename.c_str());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2019-2020 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -10,6 +11,7 @@
|
||||
#include "test_sets.hpp"
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC < 1700
|
||||
#pragma warning(disable : 4428) // universal-character-name encountered in source
|
||||
@@ -48,19 +50,19 @@ int main()
|
||||
const wchar_t* wempty = L"";
|
||||
|
||||
{
|
||||
// Default constructed string is NULL
|
||||
std::cout << "-- Default constructed string is NULL" << std::endl;
|
||||
const boost::nowide::short_stackstring s;
|
||||
TEST(s.get() == NULL);
|
||||
}
|
||||
{
|
||||
// NULL ptr passed to ctor results in NULL
|
||||
std::cout << "-- NULL ptr passed to ctor results in NULL" << std::endl;
|
||||
const boost::nowide::short_stackstring s(NULL);
|
||||
TEST(s.get() == NULL);
|
||||
const boost::nowide::short_stackstring s2(NULL, NULL);
|
||||
TEST(s2.get() == NULL);
|
||||
}
|
||||
{
|
||||
// NULL ptr passed to convert results in NULL
|
||||
std::cout << "-- NULL ptr passed to convert results in NULL" << std::endl;
|
||||
boost::nowide::short_stackstring s(L"foo");
|
||||
TEST(s.get() == std::string("foo"));
|
||||
s.convert(NULL);
|
||||
@@ -71,7 +73,7 @@ int main()
|
||||
TEST(s2.get() == NULL);
|
||||
}
|
||||
{
|
||||
// An empty string is accepted
|
||||
std::cout << "-- An empty string is accepted" << std::endl;
|
||||
const boost::nowide::short_stackstring s(wempty);
|
||||
TEST(s.get());
|
||||
TEST(s.get() == std::string());
|
||||
@@ -80,7 +82,7 @@ int main()
|
||||
TEST(s2.get() == std::string());
|
||||
}
|
||||
{
|
||||
// An empty string is accepted
|
||||
std::cout << "-- An empty string is accepted" << std::endl;
|
||||
boost::nowide::short_stackstring s, s2;
|
||||
TEST(s.convert(wempty));
|
||||
TEST(s.get() == std::string());
|
||||
@@ -88,8 +90,7 @@ int main()
|
||||
TEST(s2.get() == std::string());
|
||||
}
|
||||
{
|
||||
// Will be put on heap
|
||||
TEST(whello.size() >= 3);
|
||||
std::cout << "-- Will be put on heap" << std::endl;
|
||||
boost::nowide::basic_stackstring<wchar_t, char, 3> sw;
|
||||
TEST(sw.convert(hello.c_str()));
|
||||
TEST(sw.get() == whello);
|
||||
@@ -97,53 +98,61 @@ int main()
|
||||
TEST(sw.get() == whello);
|
||||
}
|
||||
{
|
||||
// Will be put on stack
|
||||
TEST(whello.size() < 5);
|
||||
boost::nowide::basic_stackstring<wchar_t, char, 5> sw;
|
||||
std::cout << "-- Will be put on stack" << std::endl;
|
||||
boost::nowide::basic_stackstring<wchar_t, char, 40> sw;
|
||||
TEST(sw.convert(hello.c_str()));
|
||||
TEST(sw.get() == whello);
|
||||
TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
|
||||
TEST(sw.get() == whello);
|
||||
}
|
||||
{
|
||||
// Will be put on heap
|
||||
TEST(hello.size() >= 5);
|
||||
boost::nowide::basic_stackstring<char, wchar_t, 5> sw;
|
||||
std::cout << "-- Will be put on heap" << std::endl;
|
||||
boost::nowide::basic_stackstring<char, wchar_t, 3> sw;
|
||||
TEST(sw.convert(whello.c_str()));
|
||||
TEST(sw.get() == hello);
|
||||
TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
|
||||
TEST(sw.get() == hello);
|
||||
}
|
||||
{
|
||||
// Will be put on stack
|
||||
TEST(hello.size() < 10);
|
||||
boost::nowide::basic_stackstring<char, wchar_t, 10> sw;
|
||||
std::cout << "-- Will be put on stack" << std::endl;
|
||||
boost::nowide::basic_stackstring<char, wchar_t, 40> sw;
|
||||
TEST(sw.convert(whello.c_str()));
|
||||
TEST(sw.get() == hello);
|
||||
TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
|
||||
TEST(sw.get() == hello);
|
||||
}
|
||||
{
|
||||
typedef boost::nowide::basic_stackstring<char, wchar_t, 5> stackstring;
|
||||
const std::string heapVal = hello;
|
||||
TEST(heapVal.size() >= 5); // Will be put on heap
|
||||
const std::wstring wtest = L"test";
|
||||
const std::string stackVal = "test";
|
||||
TEST(stackVal.size() < 5); // Will be put on stack
|
||||
const stackstring heap(whello.c_str());
|
||||
const stackstring stack(wtest.c_str());
|
||||
typedef boost::nowide::basic_stackstring<wchar_t, char, 6> stackstring;
|
||||
const std::wstring heapVal = L"heapValue";
|
||||
TEST(heapVal.size() >= 6); // Will be put on heap
|
||||
const std::wstring stackVal = L"stack";
|
||||
TEST(stackVal.size() < 6); // Will be put on stack
|
||||
const stackstring heap(boost::nowide::narrow(heapVal).c_str());
|
||||
const stackstring stack(boost::nowide::narrow(stackVal).c_str());
|
||||
|
||||
{
|
||||
stackstring sw2(heap), sw3;
|
||||
stackstring sw2(heap), sw3, sEmpty;
|
||||
sw3 = heap;
|
||||
TEST(sw2.get() == heapVal);
|
||||
TEST(sw3.get() == heapVal);
|
||||
// Self assign avoiding clang self-assign-overloaded warning
|
||||
sw3 = static_cast<const stackstring&>(sw3);
|
||||
TEST(sw3.get() == heapVal);
|
||||
// Assign empty
|
||||
sw3 = sEmpty;
|
||||
TEST(sw3.get() == NULL);
|
||||
}
|
||||
{
|
||||
stackstring sw2(stack), sw3;
|
||||
stackstring sw2(stack), sw3, sEmpty;
|
||||
sw3 = stack;
|
||||
TEST(sw2.get() == stackVal);
|
||||
TEST(sw3.get() == stackVal);
|
||||
// Self assign avoiding clang self-assign-overloaded warning
|
||||
sw3 = static_cast<const stackstring&>(sw3);
|
||||
TEST(sw3.get() == stackVal);
|
||||
// Assign empty
|
||||
sw3 = sEmpty;
|
||||
TEST(sw3.get() == NULL);
|
||||
}
|
||||
{
|
||||
stackstring sw2(stack);
|
||||
@@ -156,18 +165,24 @@ int main()
|
||||
TEST(sw2.get() == stackVal);
|
||||
}
|
||||
{
|
||||
stackstring sw2(heap), sw3(stack);
|
||||
stackstring sw2(heap), sw3(stack), sEmpty1, sEmpty2;
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == stackVal);
|
||||
TEST(sw3.get() == heapVal);
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == heapVal);
|
||||
TEST(sw3.get() == stackVal);
|
||||
swap(sw2, sEmpty1);
|
||||
TEST(sEmpty1.get() == heapVal);
|
||||
TEST(sw2.get() == NULL);
|
||||
swap(sw3, sEmpty2);
|
||||
TEST(sEmpty2.get() == stackVal);
|
||||
TEST(sw3.get() == NULL);
|
||||
}
|
||||
{
|
||||
stackstring sw2(heap), sw3(heap);
|
||||
sw3.get()[0] = 'z';
|
||||
const std::string val2 = sw3.get();
|
||||
const std::wstring val2 = sw3.get();
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == val2);
|
||||
TEST(sw3.get() == heapVal);
|
||||
@@ -175,15 +190,28 @@ int main()
|
||||
{
|
||||
stackstring sw2(stack), sw3(stack);
|
||||
sw3.get()[0] = 'z';
|
||||
const std::string val2 = sw3.get();
|
||||
const std::wstring val2 = sw3.get();
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == val2);
|
||||
TEST(sw3.get() == stackVal);
|
||||
}
|
||||
// Sanity check
|
||||
std::cout << "-- Sanity check" << std::endl;
|
||||
TEST(stack.get() == stackVal);
|
||||
TEST(heap.get() == heapVal);
|
||||
}
|
||||
{
|
||||
std::cout << "-- Test putting stackstrings into vector (done by args) class" << std::endl;
|
||||
// Use a smallish buffer, to have stack and heap values
|
||||
typedef boost::nowide::basic_stackstring<wchar_t, char, 5> stackstring;
|
||||
std::vector<stackstring> strings;
|
||||
strings.resize(2);
|
||||
TEST(strings[0].convert("1234") == std::wstring(L"1234"));
|
||||
TEST(strings[1].convert("Hello World") == std::wstring(L"Hello World"));
|
||||
strings.push_back(stackstring("FooBar"));
|
||||
TEST(strings[0].get() == std::wstring(L"1234"));
|
||||
TEST(strings[1].get() == std::wstring(L"Hello World"));
|
||||
TEST(strings[2].get() == std::wstring(L"FooBar"));
|
||||
}
|
||||
std::cout << "- Stackstring" << std::endl;
|
||||
run_all(stackstring_to_wide, stackstring_to_narrow);
|
||||
std::cout << "- Heap Stackstring" << std::endl;
|
||||
|
||||
@@ -8,19 +8,18 @@
|
||||
//
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable : 4996) // function unsafe/deprecated
|
||||
#endif
|
||||
|
||||
bool file_exists(const std::string& filename)
|
||||
{
|
||||
#ifdef BOOST_WINDOWS
|
||||
FILE* f = _wfopen(boost::nowide::widen(filename).c_str(), L"r");
|
||||
FILE* f = boost::nowide::detail::wfopen(boost::nowide::widen(filename).c_str(), L"r");
|
||||
#else
|
||||
FILE* f = std::fopen(filename.c_str(), "r");
|
||||
#endif
|
||||
@@ -36,7 +35,7 @@ bool file_exists(const std::string& filename)
|
||||
void create_test_file(const std::string& filename)
|
||||
{
|
||||
#ifdef BOOST_WINDOWS
|
||||
FILE* f = _wfopen(boost::nowide::widen(filename).c_str(), L"w");
|
||||
FILE* f = boost::nowide::detail::wfopen(boost::nowide::widen(filename).c_str(), L"w");
|
||||
#else
|
||||
FILE* f = std::fopen(filename.c_str(), "w");
|
||||
#endif
|
||||
@@ -45,14 +44,24 @@ void create_test_file(const std::string& filename)
|
||||
std::fclose(f);
|
||||
}
|
||||
|
||||
#if BOOST_MSVC
|
||||
#include <crtdbg.h> // For _CrtSetReportMode
|
||||
void noop_invalid_param_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned, uintptr_t)
|
||||
{}
|
||||
#endif
|
||||
|
||||
int main(int, char** argv)
|
||||
{
|
||||
const std::string prefix = argv[0];
|
||||
const std::string filename = prefix + "\xd7\xa9-\xd0\xbc-\xce\xbd.txt";
|
||||
#if BOOST_MSVC
|
||||
// Prevent abort on freopen(NULL, ...)
|
||||
_set_invalid_parameter_handler(noop_invalid_param_handler);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
// fopen - existing file
|
||||
std::cout << " -- fopen - existing file" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
FILE* f = boost::nowide::fopen(filename.c_str(), "r");
|
||||
@@ -62,26 +71,26 @@ int main(int, char** argv)
|
||||
TEST(strcmp(buf, "test\n") == 0);
|
||||
std::fclose(f);
|
||||
}
|
||||
// remove
|
||||
std::cout << " -- remove" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
TEST(file_exists(filename));
|
||||
TEST(boost::nowide::remove(filename.c_str()) == 0);
|
||||
TEST(!file_exists(filename));
|
||||
}
|
||||
// fopen non-existing file
|
||||
std::cout << " -- fopen non-existing file" << std::endl;
|
||||
{
|
||||
boost::nowide::remove(filename.c_str());
|
||||
TEST(!file_exists(filename));
|
||||
TEST(boost::nowide::fopen(filename.c_str(), "r") == NULL);
|
||||
TEST(!file_exists(filename));
|
||||
}
|
||||
// freopen
|
||||
std::cout << " -- freopen" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
FILE* f = boost::nowide::fopen(filename.c_str(), "r+");
|
||||
TEST(f);
|
||||
// Can read & write
|
||||
std::cout << " -- Can read & write" << std::endl;
|
||||
{
|
||||
char buf[32];
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
@@ -95,7 +104,7 @@ int main(int, char** argv)
|
||||
FILE* f2 = boost::nowide::freopen(NULL, "r", f);
|
||||
if(!f2)
|
||||
f2 = boost::nowide::freopen(filename.c_str(), "r", f);
|
||||
// no write possible
|
||||
std::cout << " -- no write possible" << std::endl;
|
||||
{
|
||||
TEST(f2 == f);
|
||||
TEST(std::fputs("not-written\n", f) < 0);
|
||||
@@ -106,7 +115,7 @@ int main(int, char** argv)
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "foobar\n") == 0);
|
||||
}
|
||||
// Reopen different file
|
||||
std::cout << " -- Reopen different file" << std::endl;
|
||||
const std::string filename2 = filename + ".1.txt";
|
||||
TEST(boost::nowide::freopen(filename2.c_str(), "w", f) == f);
|
||||
{
|
||||
@@ -121,7 +130,7 @@ int main(int, char** argv)
|
||||
std::fclose(f);
|
||||
boost::nowide::remove(filename2.c_str());
|
||||
}
|
||||
// rename
|
||||
std::cout << " -- rename" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
const std::string filename2 = filename + ".1.txt";
|
||||
|
||||
Reference in New Issue
Block a user