mirror of
https://github.com/boostorg/nowide.git
synced 2026-02-21 15:12:30 +00:00
@@ -34,10 +34,9 @@ pr:
|
||||
- develop
|
||||
|
||||
variables:
|
||||
- name: B2_VARIANT
|
||||
value: release,debug
|
||||
- name: B2_LINK
|
||||
value: shared,static
|
||||
B2_CI_VERSION: 1
|
||||
B2_VARIANT: release,debug
|
||||
B2_LINK: shared,static
|
||||
|
||||
stages:
|
||||
|
||||
@@ -126,7 +125,6 @@ stages:
|
||||
B2_TOOLSET: clang
|
||||
B2_CXXSTD: 03,11,14,17,2a
|
||||
XCODE_APP: /Applications/Xcode_11.3.1.app
|
||||
B2_LINK: static
|
||||
B2_JOBS: 3 # Workaround for https://github.com/boostorg/boost-ci/issues/50
|
||||
steps:
|
||||
- bash: |
|
||||
|
||||
48
.travis.yml
48
.travis.yml
@@ -25,48 +25,51 @@ env:
|
||||
|
||||
anchors:
|
||||
libcpp: &libcpp { apt: { packages: [libc++-dev, libc++-helpers] } }
|
||||
ubuntu-toolchain-r-test:
|
||||
- &ubuntu-toolchain-r-test
|
||||
sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
clang-33: &clang-33 { apt: { packages: [ "clang-3.3"] } }
|
||||
clang-34: &clang-34 { apt: { packages: [ "clang-3.4"] } }
|
||||
clang-35: &clang-35 { apt: { packages: [ "clang-3.5"], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
clang-36: &clang-36 { apt: { packages: [ "clang-3.6"], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
clang-37: &clang-37 { apt: { packages: [ "clang-3.7"], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
clang-38: &clang-38 { apt: { packages: [ "clang-3.8"], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
clang-39: &clang-39 { apt: { packages: [ "clang-3.9"], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
clang-35: &clang-35 { apt: { packages: [ "clang-3.5"], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
clang-36: &clang-36 { apt: { packages: [ "clang-3.6"], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
clang-37: &clang-37 { apt: { packages: [ "clang-3.7"], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
clang-38: &clang-38 { apt: { packages: [ "clang-3.8"], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
clang-39: &clang-39 { apt: { packages: [ "clang-3.9"], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
clang-4: &clang-4 { apt: { packages: [ "clang-4.0",
|
||||
"libstdc++-6-dev" ], sources: [ "llvm-toolchain-xenial-4.0",
|
||||
"ubuntu-toolchain-r-test" ] } }
|
||||
*ubuntu-toolchain-r-test ] } }
|
||||
clang-5: &clang-5 { apt: { packages: [ "clang-5.0",
|
||||
"libstdc++-7-dev" ], sources: [ "llvm-toolchain-xenial-5.0",
|
||||
"ubuntu-toolchain-r-test" ] } }
|
||||
*ubuntu-toolchain-r-test ] } }
|
||||
clang-6: &clang-6 { apt: { packages: [ "clang-6.0",
|
||||
"libc6-dbg",
|
||||
"libc++-dev",
|
||||
"libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-6.0",
|
||||
"ubuntu-toolchain-r-test" ] } }
|
||||
*ubuntu-toolchain-r-test ] } }
|
||||
clang-7: &clang-7 { apt: { packages: [ "clang-7",
|
||||
"libc6-dbg",
|
||||
"libc++-dev",
|
||||
"libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-7",
|
||||
"ubuntu-toolchain-r-test" ] } }
|
||||
*ubuntu-toolchain-r-test ] } }
|
||||
clang-8: &clang-8 { apt: { packages: [ "clang-8",
|
||||
"libc6-dbg",
|
||||
"libc++-dev",
|
||||
"libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-8",
|
||||
"ubuntu-toolchain-r-test" ] } }
|
||||
clang-9: &clang-9 { apt: { packages: [ "clang-9" ], sources: [ "ubuntu-toolchain-r-test",
|
||||
*ubuntu-toolchain-r-test ] } }
|
||||
clang-9: &clang-9 { apt: { packages: [ "clang-9" ], sources: [ *ubuntu-toolchain-r-test,
|
||||
{ sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main',
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'} ] } }
|
||||
|
||||
gcc-44: &gcc-44 { apt: { packages: [ "g++-4.4" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-46: &gcc-46 { apt: { packages: [ "g++-4.6" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-47: &gcc-47 { apt: { packages: [ "g++-4.7" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-48: &gcc-48 { apt: { packages: [ "g++-4.8" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-49: &gcc-49 { apt: { packages: [ "g++-4.9" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-5: &gcc-5 { apt: { packages: [ "g++-5" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-6: &gcc-6 { apt: { packages: [ "g++-6" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-7: &gcc-7 { apt: { packages: [ "g++-7" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-8: &gcc-8 { apt: { packages: [ "g++-8" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-9: &gcc-9 { apt: { packages: [ "g++-9" ], sources: [ "ubuntu-toolchain-r-test" ] } }
|
||||
gcc-44: &gcc-44 { apt: { packages: [ "g++-4.4" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-46: &gcc-46 { apt: { packages: [ "g++-4.6" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-47: &gcc-47 { apt: { packages: [ "g++-4.7" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-48: &gcc-48 { apt: { packages: [ "g++-4.8" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-49: &gcc-49 { apt: { packages: [ "g++-4.9" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-5: &gcc-5 { apt: { packages: [ "g++-5" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-6: &gcc-6 { apt: { packages: [ "g++-6" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-7: &gcc-7 { apt: { packages: [ "g++-7" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-8: &gcc-8 { apt: { packages: [ "g++-8" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
gcc-9: &gcc-9 { apt: { packages: [ "g++-9" ], sources: [ *ubuntu-toolchain-r-test ] } }
|
||||
|
||||
jobs:
|
||||
include:
|
||||
@@ -77,8 +80,7 @@ jobs:
|
||||
- { compiler: clang++-libc++, env: 'SANITIZERS=1 B2_CXXSTD=03,11,14', addons: *libcpp, dist: trusty }
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
# DYLD_LIBRARY_PATH causes problems on system() spawned processes -> static build only
|
||||
env: SANITIZERS=1 B2_CXXSTD=03,11,14,1z B2_LINK=link=static
|
||||
env: SANITIZERS=1 B2_CXXSTD=03,11,14,1z
|
||||
# Codecov
|
||||
- compiler: g++-8
|
||||
env: COMMENT=codecov.io B2_CXXSTD=03,11 GCOV=gcov-8
|
||||
|
||||
@@ -6,3 +6,5 @@ codecov:
|
||||
wait_for_ci: yes
|
||||
comment:
|
||||
layout: "diff, files"
|
||||
ignore:
|
||||
- "test/test.hpp"
|
||||
|
||||
@@ -33,7 +33,7 @@ run test_fstream_cxx11.cpp : : : <define>BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT=1
|
||||
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=1 <target-os>windows:<library>shell32 <target-os>darwin,<link>shared:<build>no : 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 ;
|
||||
|
||||
compile benchmark_fstream.cpp : <define>BOOST_NOWIDE_USE_WIN_FSTREAM=1 <library>/boost/chrono//boost_chrono/ ;
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test.hpp"
|
||||
#define BOOST_NOWIDE_TEST_NO_MAIN
|
||||
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
@@ -22,6 +23,8 @@
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
template<typename Key, typename Value, typename Key2>
|
||||
Value get(const std::map<Key, Value>& map, const Key2& key)
|
||||
{
|
||||
|
||||
@@ -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,6 +10,7 @@
|
||||
#define BOOST_NOWIDE_LIB_TEST_H_INCLUDED
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -51,6 +52,16 @@ inline void test_failed(const char* expr, const char* file, const int line, cons
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline void test_equal_impl(const T& lhs, const U& rhs, const char* file, const int line, const char* function)
|
||||
{
|
||||
if(lhs == rhs)
|
||||
return;
|
||||
std::ostringstream ss;
|
||||
ss << "[" << lhs << "!=" << rhs << "]";
|
||||
test_failed(ss.str().c_str(), file, line, function);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define DISABLE_CONST_EXPR_DETECTED __pragma(warning(push)) __pragma(warning(disable : 4127))
|
||||
#define DISABLE_CONST_EXPR_DETECTED_POP __pragma(warning(pop))
|
||||
@@ -68,5 +79,31 @@ inline void test_failed(const char* expr, const char* file, const int line, cons
|
||||
test_failed(#x, __FILE__, __LINE__, __FUNCTION__); \
|
||||
DISABLE_CONST_EXPR_DETECTED \
|
||||
} while(0) DISABLE_CONST_EXPR_DETECTED_POP
|
||||
#define TEST_EQ(lhs, rhs) \
|
||||
do \
|
||||
{ \
|
||||
test_mon(); \
|
||||
test_equal_impl((lhs), (rhs), __FILE__, __LINE__, __FUNCTION__); \
|
||||
break; \
|
||||
DISABLE_CONST_EXPR_DETECTED \
|
||||
} while(0) DISABLE_CONST_EXPR_DETECTED_POP
|
||||
|
||||
#endif // #ifndef BOOST_NOWIDE_LIB_TEST_H_INCLUDED
|
||||
|
||||
#ifndef BOOST_NOWIDE_TEST_NO_MAIN
|
||||
// Tests should implement this
|
||||
void test_main(int argc, char** argv, char** env);
|
||||
|
||||
int main(int argc, char** argv, char** env)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_main(argc, argv, env);
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Failed " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,16 +6,18 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test.hpp"
|
||||
#include "test_sets.hpp"
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/nowide/utf8_codecvt.hpp>
|
||||
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <vector>
|
||||
|
||||
#include "test.hpp"
|
||||
#include "test_sets.hpp"
|
||||
|
||||
static const char* utf8_name =
|
||||
"\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt";
|
||||
static const std::wstring wide_name_str = boost::nowide::widen(utf8_name);
|
||||
@@ -318,19 +320,9 @@ void test_codecvt_subst()
|
||||
run_all(codecvt_to_wide, codecvt_to_narrow);
|
||||
}
|
||||
|
||||
int main()
|
||||
void test_main(int, char**, char**)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_codecvt_conv();
|
||||
test_codecvt_err();
|
||||
test_codecvt_subst();
|
||||
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Failed : " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
test_codecvt_conv();
|
||||
test_codecvt_err();
|
||||
test_codecvt_subst();
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test.hpp"
|
||||
#include "test_sets.hpp"
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "test.hpp"
|
||||
#include "test_sets.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC < 1700
|
||||
#pragma warning(disable : 4428) // universal-character-name encountered in source
|
||||
#endif
|
||||
@@ -67,60 +68,51 @@ std::string narrow_raw_string_and_size(const std::wstring& s)
|
||||
return boost::nowide::narrow(s2.c_str(), s.size());
|
||||
}
|
||||
|
||||
int main()
|
||||
void test_main(int, char**, char**)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string hello = "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d";
|
||||
std::wstring whello = L"\u05e9\u05dc\u05d5\u05dd";
|
||||
std::wstring whello_3e = L"\u05e9\u05dc\u05d5\ufffd";
|
||||
std::wstring whello_3 = L"\u05e9\u05dc\u05d5";
|
||||
std::string hello = "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d";
|
||||
std::wstring whello = L"\u05e9\u05dc\u05d5\u05dd";
|
||||
std::wstring whello_3e = L"\u05e9\u05dc\u05d5\ufffd";
|
||||
std::wstring whello_3 = L"\u05e9\u05dc\u05d5";
|
||||
|
||||
std::cout << "- boost::nowide::widen" << std::endl;
|
||||
{
|
||||
const char* b = hello.c_str();
|
||||
const char* e = b + hello.size();
|
||||
wchar_t buf[6] = {0, 0, 0, 0, 0, 1};
|
||||
TEST(boost::nowide::widen(buf, 5, b, e) == buf);
|
||||
TEST(buf == whello);
|
||||
TEST(buf[5] == 1);
|
||||
TEST(boost::nowide::widen(buf, 4, b, e) == 0);
|
||||
TEST(boost::nowide::widen(buf, 5, b, e - 1) == buf);
|
||||
TEST(buf == whello_3e);
|
||||
TEST(boost::nowide::widen(buf, 5, b, e - 2) == buf);
|
||||
TEST(buf == whello_3);
|
||||
TEST(boost::nowide::widen(buf, 5, b, b) == buf && buf[0] == 0);
|
||||
TEST(boost::nowide::widen(buf, 5, b, b + 2) == buf && buf[1] == 0 && buf[0] == whello[0]);
|
||||
}
|
||||
std::cout << "- boost::nowide::narrow" << std::endl;
|
||||
{
|
||||
const wchar_t* b = whello.c_str();
|
||||
const wchar_t* e = b + whello.size(); //-V594
|
||||
char buf[10] = {0};
|
||||
buf[9] = 1;
|
||||
TEST(boost::nowide::narrow(buf, 9, b, e) == buf);
|
||||
TEST(buf == hello);
|
||||
TEST(buf[9] == 1);
|
||||
TEST(boost::nowide::narrow(buf, 8, b, e) == 0);
|
||||
TEST(boost::nowide::narrow(buf, 7, b, e - 1) == buf);
|
||||
TEST(buf == hello.substr(0, 6));
|
||||
}
|
||||
|
||||
std::cout << "- (output_buffer, buffer_size, input_raw_string)" << std::endl;
|
||||
run_all(widen_buf_ptr, narrow_buf_ptr);
|
||||
std::cout << "- (output_buffer, buffer_size, input_raw_string, string_len)" << std::endl;
|
||||
run_all(widen_buf_range, narrow_buf_range);
|
||||
std::cout << "- (input_raw_string)" << std::endl;
|
||||
run_all(widen_raw_string, narrow_raw_string);
|
||||
std::cout << "- (input_raw_string, size)" << std::endl;
|
||||
run_all(widen_raw_string_and_size, narrow_raw_string_and_size);
|
||||
std::cout << "- (const std::string&)" << std::endl;
|
||||
run_all(boost::nowide::widen, boost::nowide::narrow);
|
||||
} catch(const std::exception& e)
|
||||
std::cout << "- boost::nowide::widen" << std::endl;
|
||||
{
|
||||
std::cerr << "Failed :" << e.what() << std::endl;
|
||||
return 1;
|
||||
const char* b = hello.c_str();
|
||||
const char* e = b + hello.size();
|
||||
wchar_t buf[6] = {0, 0, 0, 0, 0, 1};
|
||||
TEST(boost::nowide::widen(buf, 5, b, e) == buf);
|
||||
TEST(buf == whello);
|
||||
TEST(buf[5] == 1);
|
||||
TEST(boost::nowide::widen(buf, 4, b, e) == 0);
|
||||
TEST(boost::nowide::widen(buf, 5, b, e - 1) == buf);
|
||||
TEST(buf == whello_3e);
|
||||
TEST(boost::nowide::widen(buf, 5, b, e - 2) == buf);
|
||||
TEST(buf == whello_3);
|
||||
TEST(boost::nowide::widen(buf, 5, b, b) == buf && buf[0] == 0);
|
||||
TEST(boost::nowide::widen(buf, 5, b, b + 2) == buf && buf[1] == 0 && buf[0] == whello[0]);
|
||||
}
|
||||
std::cout << "- boost::nowide::narrow" << std::endl;
|
||||
{
|
||||
const wchar_t* b = whello.c_str();
|
||||
const wchar_t* e = b + whello.size(); //-V594
|
||||
char buf[10] = {0};
|
||||
buf[9] = 1;
|
||||
TEST(boost::nowide::narrow(buf, 9, b, e) == buf);
|
||||
TEST(buf == hello);
|
||||
TEST(buf[9] == 1);
|
||||
TEST(boost::nowide::narrow(buf, 8, b, e) == 0);
|
||||
TEST(boost::nowide::narrow(buf, 7, b, e - 1) == buf);
|
||||
TEST(buf == hello.substr(0, 6));
|
||||
}
|
||||
|
||||
return 0;
|
||||
std::cout << "- (output_buffer, buffer_size, input_raw_string)" << std::endl;
|
||||
run_all(widen_buf_ptr, narrow_buf_ptr);
|
||||
std::cout << "- (output_buffer, buffer_size, input_raw_string, string_len)" << std::endl;
|
||||
run_all(widen_buf_range, narrow_buf_range);
|
||||
std::cout << "- (input_raw_string)" << std::endl;
|
||||
run_all(widen_raw_string, narrow_raw_string);
|
||||
std::cout << "- (input_raw_string, size)" << std::endl;
|
||||
run_all(widen_raw_string_and_size, narrow_raw_string_and_size);
|
||||
std::cout << "- (const std::string&)" << std::endl;
|
||||
run_all(boost::nowide::widen, boost::nowide::narrow);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <boost/nowide/cstdlib.hpp>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_NOWIDE_TEST_INCLUDE_WINDOWS) && defined(BOOST_WINDOWS)
|
||||
#include <windows.h>
|
||||
@@ -28,40 +27,31 @@ void strcpy_safe(char (&dest)[size], const char* src)
|
||||
dest[len] = 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
void test_main(int, char**, char**)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string example = "\xd7\xa9-\xd0\xbc-\xce\xbd";
|
||||
char penv[256] = {0};
|
||||
strcpy_safe(penv, ("BOOST_TEST2=" + example + "x").c_str());
|
||||
std::string example = "\xd7\xa9-\xd0\xbc-\xce\xbd";
|
||||
char penv[256] = {0};
|
||||
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"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1") == example);
|
||||
TEST(boost::nowide::setenv("BOOST_TEST1", "xx", 0) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1") == example);
|
||||
TEST(boost::nowide::putenv(penv) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST2"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST_INVALID") == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST2") == example + "x");
|
||||
TEST(boost::nowide::setenv("BOOST_TEST1", example.c_str(), 1) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1") == example);
|
||||
TEST(boost::nowide::setenv("BOOST_TEST1", "xx", 0) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1") == example);
|
||||
TEST(boost::nowide::putenv(penv) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST2"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST_INVALID") == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST2") == example + "x");
|
||||
#ifdef BOOST_WINDOWS
|
||||
// Passing a variable without an equals sign (before \0) is an error
|
||||
// But GLIBC has an extension that unsets the env var instead
|
||||
char penv2[256] = {0};
|
||||
const char* sPenv2 = "BOOST_TEST1SOMEGARBAGE=";
|
||||
strcpy_safe(penv2, sPenv2);
|
||||
// End the string before the equals sign -> Expect fail
|
||||
penv2[strlen("BOOST_TEST1")] = '\0';
|
||||
TEST(boost::nowide::putenv(penv2) == -1);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1") == example);
|
||||
// Passing a variable without an equals sign (before \0) is an error
|
||||
// But GLIBC has an extension that unsets the env var instead
|
||||
char penv2[256] = {0};
|
||||
const char* sPenv2 = "BOOST_TEST1SOMEGARBAGE=";
|
||||
strcpy_safe(penv2, sPenv2);
|
||||
// End the string before the equals sign -> Expect fail
|
||||
penv2[strlen("BOOST_TEST1")] = '\0';
|
||||
TEST(boost::nowide::putenv(penv2) == -1);
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1"));
|
||||
TEST(boost::nowide::getenv("BOOST_TEST1") == example);
|
||||
#endif
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Failed " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,66 +6,56 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/nowide/filesystem.hpp>
|
||||
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/nowide/filesystem.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
int main()
|
||||
void test_main(int, char**, char**)
|
||||
{
|
||||
try
|
||||
boost::nowide::nowide_filesystem();
|
||||
const std::string prefix = boost::filesystem::unique_path("nowide-%%%%-%%%%-").string();
|
||||
const std::string utf8_name =
|
||||
prefix + "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt";
|
||||
|
||||
{
|
||||
boost::nowide::nowide_filesystem();
|
||||
const std::string prefix = boost::filesystem::unique_path("nowide-%%%%-%%%%-").string();
|
||||
const std::string utf8_name =
|
||||
prefix + "\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt";
|
||||
|
||||
{
|
||||
boost::nowide::ofstream f(utf8_name.c_str());
|
||||
TEST(f);
|
||||
f << "Test" << std::endl;
|
||||
}
|
||||
|
||||
TEST(boost::filesystem::is_regular_file(boost::nowide::widen(utf8_name)));
|
||||
TEST(boost::filesystem::is_regular_file(utf8_name));
|
||||
|
||||
TEST(boost::nowide::remove(utf8_name.c_str()) == 0);
|
||||
|
||||
TEST(!boost::filesystem::is_regular_file(boost::nowide::widen(utf8_name)));
|
||||
TEST(!boost::filesystem::is_regular_file(utf8_name));
|
||||
|
||||
const boost::filesystem::path path = utf8_name;
|
||||
{
|
||||
boost::nowide::ofstream f(path);
|
||||
TEST(f);
|
||||
f << "Test" << std::endl;
|
||||
TEST(is_regular_file(path));
|
||||
}
|
||||
{
|
||||
boost::nowide::ifstream f(path);
|
||||
TEST(f);
|
||||
std::string test;
|
||||
f >> test;
|
||||
TEST(test == "Test");
|
||||
}
|
||||
{
|
||||
boost::nowide::fstream f(path);
|
||||
TEST(f);
|
||||
std::string test;
|
||||
f >> test;
|
||||
TEST(test == "Test");
|
||||
}
|
||||
boost::filesystem::remove(path);
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Failed : " << e.what() << std::endl;
|
||||
return 1;
|
||||
boost::nowide::ofstream f(utf8_name.c_str());
|
||||
TEST(f);
|
||||
f << "Test" << std::endl;
|
||||
}
|
||||
std::cout << "Ok" << std::endl;
|
||||
|
||||
return 0;
|
||||
TEST(boost::filesystem::is_regular_file(boost::nowide::widen(utf8_name)));
|
||||
TEST(boost::filesystem::is_regular_file(utf8_name));
|
||||
|
||||
TEST(boost::nowide::remove(utf8_name.c_str()) == 0);
|
||||
|
||||
TEST(!boost::filesystem::is_regular_file(boost::nowide::widen(utf8_name)));
|
||||
TEST(!boost::filesystem::is_regular_file(utf8_name));
|
||||
|
||||
const boost::filesystem::path path = utf8_name;
|
||||
{
|
||||
boost::nowide::ofstream f(path);
|
||||
TEST(f);
|
||||
f << "Test" << std::endl;
|
||||
TEST(is_regular_file(path));
|
||||
}
|
||||
{
|
||||
boost::nowide::ifstream f(path);
|
||||
TEST(f);
|
||||
std::string test;
|
||||
f >> test;
|
||||
TEST(test == "Test");
|
||||
}
|
||||
{
|
||||
boost::nowide::fstream f(path);
|
||||
TEST(f);
|
||||
std::string test;
|
||||
f >> test;
|
||||
TEST(test == "Test");
|
||||
}
|
||||
boost::filesystem::remove(path);
|
||||
}
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test.hpp"
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
|
||||
#include <boost/nowide/convert.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
namespace nw = boost::nowide;
|
||||
|
||||
void make_empty_file(const char* filepath)
|
||||
@@ -488,33 +490,24 @@ void test_is_open(const char* filename)
|
||||
TEST(nw::remove(filename) == 0);
|
||||
}
|
||||
|
||||
int main(int, char** argv)
|
||||
void test_main(int, char** argv, char**)
|
||||
{
|
||||
const std::string exampleFilename = std::string(argv[0]) + "-\xd7\xa9-\xd0\xbc-\xce\xbd.txt";
|
||||
try
|
||||
{
|
||||
std::cout << "Testing fstream" << std::endl;
|
||||
test_ofstream_creates_file(exampleFilename.c_str());
|
||||
test_ofstream_write(exampleFilename.c_str());
|
||||
test_ifstream_open_read(exampleFilename.c_str());
|
||||
test_fstream(exampleFilename.c_str());
|
||||
test_is_open(exampleFilename.c_str());
|
||||
std::cout << "Testing fstream" << std::endl;
|
||||
test_ofstream_creates_file(exampleFilename.c_str());
|
||||
test_ofstream_write(exampleFilename.c_str());
|
||||
test_ifstream_open_read(exampleFilename.c_str());
|
||||
test_fstream(exampleFilename.c_str());
|
||||
test_is_open(exampleFilename.c_str());
|
||||
|
||||
std::cout << "Complex IO" << std::endl;
|
||||
test_with_different_buffer_sizes(exampleFilename.c_str());
|
||||
std::cout << "Complex IO" << std::endl;
|
||||
test_with_different_buffer_sizes(exampleFilename.c_str());
|
||||
|
||||
std::cout << "filebuf::close" << std::endl;
|
||||
test_close(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());
|
||||
std::cout << "Flush - Test" << std::endl;
|
||||
test_flush<nw::ifstream, nw::ofstream>(exampleFilename.c_str());
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Ok" << std::endl;
|
||||
return 0;
|
||||
std::cout << "Flush - Sanity Check" << std::endl;
|
||||
test_flush<std::ifstream, std::ofstream>(exampleFilename.c_str());
|
||||
std::cout << "Flush - Test" << std::endl;
|
||||
test_flush<nw::ifstream, nw::ofstream>(exampleFilename.c_str());
|
||||
}
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
|
||||
#if BOOST_NOWIDE_CXX11
|
||||
|
||||
#include "test.hpp"
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
namespace nw = boost::nowide;
|
||||
|
||||
void create_file(const std::string& filename, const std::string& contents)
|
||||
@@ -180,21 +181,12 @@ void test_fstream(const std::string& filename)
|
||||
TEST(nw::remove(filename.c_str()) == 0);
|
||||
}
|
||||
|
||||
int main(int, char** argv)
|
||||
void test_main(int, char** argv, char**)
|
||||
{
|
||||
const std::string exampleFilename = std::string(argv[0]) + "-\xd7\xa9-\xd0\xbc-\xce\xbd.txt";
|
||||
try
|
||||
{
|
||||
test_ifstream(exampleFilename);
|
||||
test_ofstream(exampleFilename);
|
||||
test_fstream(exampleFilename);
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Ok" << std::endl;
|
||||
return 0;
|
||||
test_ifstream(exampleFilename);
|
||||
test_ofstream(exampleFilename);
|
||||
test_fstream(exampleFilename);
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -204,7 +196,6 @@ int main(int, char** argv)
|
||||
int main()
|
||||
{
|
||||
std::cout << "Test skipped as there is no C++11 support by the compiler" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/nowide/detail/utf.hpp>
|
||||
#include <boost/nowide/iostream.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/nowide/detail/utf.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "test.hpp"
|
||||
@@ -25,7 +25,7 @@ bool isValidUTF8(const std::string& s)
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
void test_main(int argc, char** argv, char**)
|
||||
{
|
||||
const char* example = "Basic letters: \xd7\xa9-\xd0\xbc-\xce\xbd\n"
|
||||
"East Asian Letters: \xe5\x92\x8c\xe5\xb9\xb3\n"
|
||||
@@ -33,64 +33,55 @@ int main(int argc, char** argv)
|
||||
"Invalid UTF-8: `\xFF' `\xd7\xFF' `\xe5\xFF\x8c' `\xf0\x9d\x84\xFF' \n"
|
||||
"\n";
|
||||
|
||||
try
|
||||
// If we are using the standard rdbuf we can only put back 1 char
|
||||
if(boost::nowide::cin.rdbuf() == std::cin.rdbuf())
|
||||
{
|
||||
// If we are using the standard rdbuf we can only put back 1 char
|
||||
if(boost::nowide::cin.rdbuf() == std::cin.rdbuf())
|
||||
std::cout << "Using std::cin" << std::endl;
|
||||
int maxval = 15000;
|
||||
for(int i = 0; i < maxval; i++)
|
||||
{
|
||||
std::cout << "Using std::cin" << std::endl;
|
||||
int maxval = 15000;
|
||||
for(int i = 0; i < maxval; i++)
|
||||
{
|
||||
char c = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.putback(c));
|
||||
int ci = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.get() == ci);
|
||||
}
|
||||
} else
|
||||
{
|
||||
int maxval = 15000;
|
||||
for(int i = 0; i < maxval; i++)
|
||||
{
|
||||
char c = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.putback(c));
|
||||
}
|
||||
for(int i = maxval - 1; i >= 0; i--)
|
||||
{
|
||||
int c = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.get() == c);
|
||||
}
|
||||
char c = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.putback(c));
|
||||
int ci = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.get() == ci);
|
||||
}
|
||||
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(const char* s = example; *s; s++)
|
||||
} else
|
||||
{
|
||||
int maxval = 15000;
|
||||
for(int i = 0; i < maxval; i++)
|
||||
{
|
||||
boost::nowide::cout << *s << std::flush;
|
||||
TEST(boost::nowide::cout);
|
||||
char c = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.putback(c));
|
||||
}
|
||||
for(int i = maxval - 1; i >= 0; i--)
|
||||
{
|
||||
int c = i % 96 + ' ';
|
||||
TEST(boost::nowide::cin.get() == c);
|
||||
}
|
||||
}
|
||||
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(const char* s = example; *s; s++)
|
||||
{
|
||||
boost::nowide::cout << *s << std::flush;
|
||||
TEST(boost::nowide::cout);
|
||||
TEST(boost::nowide::cerr);
|
||||
if(argc == 2 && argv[1] == std::string("-i"))
|
||||
{
|
||||
std::string v1, v2;
|
||||
boost::nowide::cin >> v1 >> v2;
|
||||
TEST(boost::nowide::cin);
|
||||
TEST(isValidUTF8(v1));
|
||||
TEST(isValidUTF8(v2));
|
||||
boost::nowide::cout << "First: " << v1 << std::endl;
|
||||
boost::nowide::cout << "Second: " << v2 << std::endl;
|
||||
TEST(boost::nowide::cout);
|
||||
}
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Fail: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
TEST(boost::nowide::cout);
|
||||
TEST(boost::nowide::cerr);
|
||||
if(argc == 2 && argv[1] == std::string("-i"))
|
||||
{
|
||||
std::string v1, v2;
|
||||
boost::nowide::cin >> v1 >> v2;
|
||||
TEST(boost::nowide::cin);
|
||||
TEST(isValidUTF8(v1));
|
||||
TEST(isValidUTF8(v2));
|
||||
boost::nowide::cout << "First: " << v1 << std::endl;
|
||||
boost::nowide::cout << "Second: " << v2 << std::endl;
|
||||
TEST(boost::nowide::cout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test.hpp"
|
||||
#include "test_sets.hpp"
|
||||
#include <boost/nowide/stackstring.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "test.hpp"
|
||||
#include "test_sets.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC < 1700
|
||||
#pragma warning(disable : 4428) // universal-character-name encountered in source
|
||||
#endif
|
||||
@@ -71,194 +72,185 @@ std::string heap_stackstring_to_narrow(const std::wstring& s)
|
||||
return ss.get();
|
||||
}
|
||||
|
||||
int main()
|
||||
void test_main(int, char**, char**)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string hello = "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d";
|
||||
std::wstring whello = boost::nowide::widen(hello);
|
||||
const wchar_t* wempty = L"";
|
||||
std::string hello = "\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d";
|
||||
std::wstring whello = boost::nowide::widen(hello);
|
||||
const wchar_t* wempty = L"";
|
||||
|
||||
{
|
||||
std::cout << "-- Default constructed string is NULL" << std::endl;
|
||||
const boost::nowide::short_stackstring s;
|
||||
TEST(s.get() == 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);
|
||||
}
|
||||
{
|
||||
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);
|
||||
TEST(s.get() == NULL);
|
||||
boost::nowide::short_stackstring s2(L"foo");
|
||||
TEST(s2.get() == std::string("foo"));
|
||||
s2.convert(NULL, NULL);
|
||||
TEST(s2.get() == NULL);
|
||||
}
|
||||
{
|
||||
std::cout << "-- An empty string is accepted" << std::endl;
|
||||
const boost::nowide::short_stackstring s(wempty);
|
||||
TEST(s.get());
|
||||
TEST(s.get() == std::string());
|
||||
const boost::nowide::short_stackstring s2(wempty, wempty);
|
||||
TEST(s2.get());
|
||||
TEST(s2.get() == std::string());
|
||||
}
|
||||
{
|
||||
std::cout << "-- An empty string is accepted" << std::endl;
|
||||
boost::nowide::short_stackstring s, s2;
|
||||
TEST(s.convert(wempty));
|
||||
TEST(s.get() == std::string());
|
||||
TEST(s2.convert(wempty, wempty));
|
||||
TEST(s2.get() == std::string());
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on heap" << std::endl;
|
||||
test_basic_stackstring<wchar_t, char, 3> sw;
|
||||
TEST(sw.convert(hello.c_str()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == whello);
|
||||
TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == whello);
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on stack" << std::endl;
|
||||
test_basic_stackstring<wchar_t, char, 40> sw;
|
||||
TEST(sw.convert(hello.c_str()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == whello);
|
||||
TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == whello);
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on heap" << std::endl;
|
||||
test_basic_stackstring<char, wchar_t, 3> sw;
|
||||
TEST(sw.convert(whello.c_str()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == hello);
|
||||
TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == hello);
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on stack" << std::endl;
|
||||
test_basic_stackstring<char, wchar_t, 40> sw;
|
||||
TEST(sw.convert(whello.c_str()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == hello);
|
||||
TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == hello);
|
||||
}
|
||||
{
|
||||
typedef test_basic_stackstring<wchar_t, char, 6> stackstring;
|
||||
const std::wstring heapVal = L"heapValue";
|
||||
const std::wstring stackVal = L"stack";
|
||||
const stackstring heap(boost::nowide::narrow(heapVal).c_str());
|
||||
const stackstring stack(boost::nowide::narrow(stackVal).c_str());
|
||||
TEST(heap.uses_heap_memory());
|
||||
TEST(stack.uses_stack_memory());
|
||||
|
||||
{
|
||||
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); //-V570
|
||||
TEST(sw3.get() == heapVal);
|
||||
// Assign empty
|
||||
sw3 = sEmpty; //-V820
|
||||
TEST(sw3.get() == NULL);
|
||||
}
|
||||
{
|
||||
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); //-V570
|
||||
TEST(sw3.get() == stackVal);
|
||||
// Assign empty
|
||||
sw3 = sEmpty; //-V820
|
||||
TEST(sw3.get() == NULL);
|
||||
}
|
||||
{
|
||||
stackstring sw2(stack);
|
||||
sw2 = heap;
|
||||
TEST(sw2.get() == heapVal);
|
||||
}
|
||||
{
|
||||
stackstring sw2(heap);
|
||||
sw2 = stack;
|
||||
TEST(sw2.get() == stackVal);
|
||||
}
|
||||
{
|
||||
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::wstring val2 = sw3.get();
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == val2);
|
||||
TEST(sw3.get() == heapVal);
|
||||
}
|
||||
{
|
||||
stackstring sw2(stack), sw3(stack);
|
||||
sw3.get()[0] = 'z';
|
||||
const std::wstring val2 = sw3.get();
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == val2);
|
||||
TEST(sw3.get() == stackVal);
|
||||
}
|
||||
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;
|
||||
run_all(heap_stackstring_to_wide, heap_stackstring_to_narrow);
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Failed :" << e.what() << std::endl;
|
||||
return 1;
|
||||
std::cout << "-- Default constructed string is NULL" << std::endl;
|
||||
const boost::nowide::short_stackstring s;
|
||||
TEST(s.get() == 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);
|
||||
}
|
||||
{
|
||||
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);
|
||||
TEST(s.get() == NULL);
|
||||
boost::nowide::short_stackstring s2(L"foo");
|
||||
TEST(s2.get() == std::string("foo"));
|
||||
s2.convert(NULL, NULL);
|
||||
TEST(s2.get() == NULL);
|
||||
}
|
||||
{
|
||||
std::cout << "-- An empty string is accepted" << std::endl;
|
||||
const boost::nowide::short_stackstring s(wempty);
|
||||
TEST(s.get());
|
||||
TEST(s.get() == std::string());
|
||||
const boost::nowide::short_stackstring s2(wempty, wempty);
|
||||
TEST(s2.get());
|
||||
TEST(s2.get() == std::string());
|
||||
}
|
||||
{
|
||||
std::cout << "-- An empty string is accepted" << std::endl;
|
||||
boost::nowide::short_stackstring s, s2;
|
||||
TEST(s.convert(wempty));
|
||||
TEST(s.get() == std::string());
|
||||
TEST(s2.convert(wempty, wempty));
|
||||
TEST(s2.get() == std::string());
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on heap" << std::endl;
|
||||
test_basic_stackstring<wchar_t, char, 3> sw;
|
||||
TEST(sw.convert(hello.c_str()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == whello);
|
||||
TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == whello);
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on stack" << std::endl;
|
||||
test_basic_stackstring<wchar_t, char, 40> sw;
|
||||
TEST(sw.convert(hello.c_str()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == whello);
|
||||
TEST(sw.convert(hello.c_str(), hello.c_str() + hello.size()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == whello);
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on heap" << std::endl;
|
||||
test_basic_stackstring<char, wchar_t, 3> sw;
|
||||
TEST(sw.convert(whello.c_str()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == hello);
|
||||
TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
|
||||
TEST(sw.uses_heap_memory());
|
||||
TEST(sw.get() == hello);
|
||||
}
|
||||
{
|
||||
std::cout << "-- Will be put on stack" << std::endl;
|
||||
test_basic_stackstring<char, wchar_t, 40> sw;
|
||||
TEST(sw.convert(whello.c_str()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == hello);
|
||||
TEST(sw.convert(whello.c_str(), whello.c_str() + whello.size()));
|
||||
TEST(sw.uses_stack_memory());
|
||||
TEST(sw.get() == hello);
|
||||
}
|
||||
{
|
||||
typedef test_basic_stackstring<wchar_t, char, 6> stackstring;
|
||||
const std::wstring heapVal = L"heapValue";
|
||||
const std::wstring stackVal = L"stack";
|
||||
const stackstring heap(boost::nowide::narrow(heapVal).c_str());
|
||||
const stackstring stack(boost::nowide::narrow(stackVal).c_str());
|
||||
TEST(heap.uses_heap_memory());
|
||||
TEST(stack.uses_stack_memory());
|
||||
|
||||
return 0;
|
||||
{
|
||||
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); //-V570
|
||||
TEST(sw3.get() == heapVal);
|
||||
// Assign empty
|
||||
sw3 = sEmpty; //-V820
|
||||
TEST(sw3.get() == NULL);
|
||||
}
|
||||
{
|
||||
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); //-V570
|
||||
TEST(sw3.get() == stackVal);
|
||||
// Assign empty
|
||||
sw3 = sEmpty; //-V820
|
||||
TEST(sw3.get() == NULL);
|
||||
}
|
||||
{
|
||||
stackstring sw2(stack);
|
||||
sw2 = heap;
|
||||
TEST(sw2.get() == heapVal);
|
||||
}
|
||||
{
|
||||
stackstring sw2(heap);
|
||||
sw2 = stack;
|
||||
TEST(sw2.get() == stackVal);
|
||||
}
|
||||
{
|
||||
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::wstring val2 = sw3.get();
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == val2);
|
||||
TEST(sw3.get() == heapVal);
|
||||
}
|
||||
{
|
||||
stackstring sw2(stack), sw3(stack);
|
||||
sw3.get()[0] = 'z';
|
||||
const std::wstring val2 = sw3.get();
|
||||
swap(sw2, sw3);
|
||||
TEST(sw2.get() == val2);
|
||||
TEST(sw3.get() == stackVal);
|
||||
}
|
||||
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;
|
||||
run_all(heap_stackstring_to_wide, heap_stackstring_to_narrow);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ void noop_invalid_param_handler(const wchar_t*, const wchar_t*, const wchar_t*,
|
||||
{}
|
||||
#endif
|
||||
|
||||
int main(int, char** argv)
|
||||
void test_main(int, char** argv, char**)
|
||||
{
|
||||
const std::string prefix = argv[0];
|
||||
const std::string filename = prefix + "\xd7\xa9-\xd0\xbc-\xce\xbd.txt";
|
||||
@@ -59,95 +59,86 @@ int main(int, char** argv)
|
||||
_set_invalid_parameter_handler(noop_invalid_param_handler);
|
||||
#endif
|
||||
|
||||
try
|
||||
std::cout << " -- fopen - existing file" << std::endl;
|
||||
{
|
||||
std::cout << " -- fopen - existing file" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
FILE* f = boost::nowide::fopen(filename.c_str(), "r");
|
||||
TEST(f);
|
||||
char buf[16];
|
||||
TEST(std::fgets(buf, 16, f) != 0);
|
||||
TEST(strcmp(buf, "test\n") == 0);
|
||||
std::fclose(f);
|
||||
}
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
std::cout << " -- freopen" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
FILE* f = boost::nowide::fopen(filename.c_str(), "r+");
|
||||
TEST(f);
|
||||
std::cout << " -- Can read & write" << std::endl;
|
||||
{
|
||||
char buf[32];
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "test\n") == 0);
|
||||
TEST(std::fseek(f, 0, SEEK_END) == 0);
|
||||
TEST(std::fputs("foobar\n", f) >= 0);
|
||||
}
|
||||
// Reopen in read mode
|
||||
// Note that changing the mode is not possibly on all implementations
|
||||
// E.g. MSVC disallows NULL completely as the file parameter
|
||||
FILE* f2 = boost::nowide::freopen(NULL, "r", f);
|
||||
if(!f2)
|
||||
f2 = boost::nowide::freopen(filename.c_str(), "r", f);
|
||||
std::cout << " -- no write possible" << std::endl;
|
||||
{
|
||||
TEST(f2 == f);
|
||||
TEST(std::fputs("not-written\n", f) < 0);
|
||||
TEST(std::fseek(f, 0, SEEK_SET) == 0);
|
||||
char buf[32];
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "test\n") == 0);
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "foobar\n") == 0);
|
||||
}
|
||||
std::cout << " -- Reopen different file" << std::endl;
|
||||
const std::string filename2 = filename + ".1.txt";
|
||||
TEST(boost::nowide::freopen(filename2.c_str(), "w", f) == f);
|
||||
{
|
||||
char buf[32];
|
||||
TEST(std::fputs("baz\n", f) >= 0);
|
||||
std::fclose(f);
|
||||
f = boost::nowide::fopen(filename2.c_str(), "r");
|
||||
TEST(f);
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "baz\n") == 0);
|
||||
}
|
||||
std::fclose(f);
|
||||
boost::nowide::remove(filename2.c_str());
|
||||
}
|
||||
std::cout << " -- rename" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
const std::string filename2 = filename + ".1.txt";
|
||||
boost::nowide::remove(filename2.c_str());
|
||||
TEST(file_exists(filename));
|
||||
TEST(!file_exists(filename2));
|
||||
TEST(boost::nowide::rename(filename.c_str(), filename2.c_str()) == 0);
|
||||
TEST(!file_exists(filename));
|
||||
TEST(file_exists(filename2));
|
||||
TEST(boost::nowide::remove(filename.c_str()) < 0);
|
||||
TEST(boost::nowide::remove(filename2.c_str()) == 0);
|
||||
}
|
||||
} catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Failed " << e.what() << std::endl;
|
||||
return 1;
|
||||
create_test_file(filename);
|
||||
FILE* f = boost::nowide::fopen(filename.c_str(), "r");
|
||||
TEST(f);
|
||||
char buf[16];
|
||||
TEST(std::fgets(buf, 16, f) != 0);
|
||||
TEST(strcmp(buf, "test\n") == 0);
|
||||
std::fclose(f);
|
||||
}
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
std::cout << " -- freopen" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
FILE* f = boost::nowide::fopen(filename.c_str(), "r+");
|
||||
TEST(f);
|
||||
std::cout << " -- Can read & write" << std::endl;
|
||||
{
|
||||
char buf[32];
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "test\n") == 0);
|
||||
TEST(std::fseek(f, 0, SEEK_END) == 0);
|
||||
TEST(std::fputs("foobar\n", f) >= 0);
|
||||
}
|
||||
// Reopen in read mode
|
||||
// Note that changing the mode is not possibly on all implementations
|
||||
// E.g. MSVC disallows NULL completely as the file parameter
|
||||
FILE* f2 = boost::nowide::freopen(NULL, "r", f);
|
||||
if(!f2)
|
||||
f2 = boost::nowide::freopen(filename.c_str(), "r", f);
|
||||
std::cout << " -- no write possible" << std::endl;
|
||||
{
|
||||
TEST(f2 == f);
|
||||
TEST(std::fputs("not-written\n", f) < 0);
|
||||
TEST(std::fseek(f, 0, SEEK_SET) == 0);
|
||||
char buf[32];
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "test\n") == 0);
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "foobar\n") == 0);
|
||||
}
|
||||
std::cout << " -- Reopen different file" << std::endl;
|
||||
const std::string filename2 = filename + ".1.txt";
|
||||
TEST(boost::nowide::freopen(filename2.c_str(), "w", f) == f);
|
||||
{
|
||||
char buf[32];
|
||||
TEST(std::fputs("baz\n", f) >= 0);
|
||||
std::fclose(f);
|
||||
f = boost::nowide::fopen(filename2.c_str(), "r");
|
||||
TEST(f);
|
||||
TEST(std::fgets(buf, 32, f) != 0);
|
||||
TEST(strcmp(buf, "baz\n") == 0);
|
||||
}
|
||||
std::fclose(f);
|
||||
boost::nowide::remove(filename2.c_str());
|
||||
}
|
||||
std::cout << " -- rename" << std::endl;
|
||||
{
|
||||
create_test_file(filename);
|
||||
const std::string filename2 = filename + ".1.txt";
|
||||
boost::nowide::remove(filename2.c_str());
|
||||
TEST(file_exists(filename));
|
||||
TEST(!file_exists(filename2));
|
||||
TEST(boost::nowide::rename(filename.c_str(), filename2.c_str()) == 0);
|
||||
TEST(!file_exists(filename));
|
||||
TEST(file_exists(filename2));
|
||||
TEST(boost::nowide::remove(filename.c_str()) < 0);
|
||||
TEST(boost::nowide::remove(filename2.c_str()) == 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5,81 +5,174 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "test.hpp"
|
||||
#include <boost/nowide/args.hpp>
|
||||
#include <boost/nowide/cstdlib.hpp>
|
||||
|
||||
#include <boost/nowide/args.hpp>
|
||||
#include <boost/nowide/detail/convert.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
int main(int argc, char** argv, char** env)
|
||||
#include "test.hpp"
|
||||
|
||||
bool is_ascii(const std::string& s)
|
||||
{
|
||||
try
|
||||
for(std::string::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
{
|
||||
std::string example = "\xd7\xa9-\xd0\xbc-\xce\xbd";
|
||||
boost::nowide::args a(argc, argv, env);
|
||||
if(argc == 2 && argv[1][0] != '-')
|
||||
if(static_cast<unsigned char>(*it) > 0x7F)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string replace_non_ascii(const std::string& s)
|
||||
{
|
||||
std::string::const_iterator it = s.begin();
|
||||
namespace utf = boost::nowide::detail::utf;
|
||||
typedef utf::utf_traits<char> utf8;
|
||||
std::string result;
|
||||
result.reserve(s.size());
|
||||
while(it != s.end())
|
||||
{
|
||||
utf::code_point c = utf8::decode(it, s.end());
|
||||
TEST(c != utf::illegal && c != utf::incomplete);
|
||||
if(c > 0x7F)
|
||||
c = '?'; // WinAPI seems to do this
|
||||
result.push_back(static_cast<char>(c));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void compare_string_arrays(char** main_val, char** utf8_val, bool sort)
|
||||
{
|
||||
std::vector<std::string> vec_main, vec_utf8;
|
||||
for(; *main_val; ++main_val)
|
||||
vec_main.push_back(std::string(*main_val));
|
||||
for(; *utf8_val; ++utf8_val)
|
||||
vec_utf8.push_back(std::string(*utf8_val));
|
||||
// Same number of strings
|
||||
TEST_EQ(vec_main.size(), vec_utf8.size());
|
||||
if(sort)
|
||||
{
|
||||
// Order doesn't matter
|
||||
std::sort(vec_main.begin(), vec_main.end());
|
||||
std::sort(vec_utf8.begin(), vec_utf8.end());
|
||||
}
|
||||
for(size_t i = 0; i < vec_main.size(); ++i)
|
||||
{
|
||||
// Skip strings with non-ascii chars
|
||||
if(is_ascii(vec_main[i]) && vec_main[i] != vec_utf8[i])
|
||||
TEST_EQ(vec_main[i], replace_non_ascii(vec_utf8[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void compare_getenv(char** env)
|
||||
{
|
||||
// For all all variables in env check against getenv
|
||||
for(char** e = env; *e != 0; e++)
|
||||
{
|
||||
const char* key_begin = *e;
|
||||
const char* key_end = strchr(key_begin, '=');
|
||||
TEST(key_end);
|
||||
std::string key = std::string(key_begin, key_end);
|
||||
const char* std_value = std::getenv(key.c_str());
|
||||
const char* bnw_value = boost::nowide::getenv(key.c_str());
|
||||
// If std_value is set, bnw value must be too and be equal, else bnw value must be unset too
|
||||
if(std_value)
|
||||
{
|
||||
TEST(argv[1] == example);
|
||||
TEST(argv[2] == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST"));
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST_NONE") == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST") == example);
|
||||
// Empty variables are unreliable on windows, hence skip. E.g. using "set FOO=" unsets FOO
|
||||
TEST(bnw_value);
|
||||
// Compare only if ascii
|
||||
if(is_ascii(std_value) && std::string(std_value) != std::string(bnw_value))
|
||||
TEST_EQ(std_value, replace_non_ascii(bnw_value));
|
||||
} else
|
||||
TEST(!bnw_value);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string example = "\xd7\xa9-\xd0\xbc-\xce\xbd";
|
||||
|
||||
void run_child(int argc, char** argv, char** env)
|
||||
{
|
||||
// Test arguments
|
||||
TEST(argc == 2);
|
||||
TEST_EQ(argv[1], example);
|
||||
TEST(argv[2] == 0);
|
||||
|
||||
// Test getenv
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST"));
|
||||
TEST_EQ(boost::nowide::getenv("BOOST_NOWIDE_TEST"), example);
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST_NONE") == 0);
|
||||
// Empty variables are unreliable on windows, hence skip. E.g. using "set FOO=" unsets FOO
|
||||
#ifndef BOOST_WINDOWS
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"));
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_EMPTY") == std::string());
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"));
|
||||
TEST_EQ(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"), std::string());
|
||||
#endif // !_WIN32
|
||||
|
||||
std::string sample = "BOOST_NOWIDE_TEST=" + example;
|
||||
bool found = false;
|
||||
for(char** e = env; *e != 0; e++)
|
||||
{
|
||||
char* eptr = *e;
|
||||
std::cout << "Checking " << eptr << std::endl;
|
||||
char* key_end = strchr(eptr, '=');
|
||||
TEST(key_end);
|
||||
std::string key = std::string(eptr, key_end);
|
||||
std::string value = key_end + 1;
|
||||
#ifdef BOOST_WINDOWS
|
||||
if(value.empty())
|
||||
continue;
|
||||
#endif
|
||||
std::cout << "Key: " << key << " Value: " << value << std::endl;
|
||||
TEST(boost::nowide::getenv(key.c_str()));
|
||||
TEST(boost::nowide::getenv(key.c_str()) == value);
|
||||
if(*e == sample)
|
||||
found = true;
|
||||
}
|
||||
TEST(found);
|
||||
std::cout << "Subprocess ok" << std::endl;
|
||||
} else if(argc == 1)
|
||||
{
|
||||
#if BOOST_NOWIDE_TEST_USE_NARROW
|
||||
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);
|
||||
TEST(boost::nowide::setenv("BOOST_NOWIDE_EMPTY", "", 1) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"));
|
||||
std::string command = "\"";
|
||||
command += argv[0];
|
||||
command += "\" ";
|
||||
command += example;
|
||||
TEST(boost::nowide::system(command.c_str()) == 0);
|
||||
std::cout << "Parent ok" << std::endl;
|
||||
#else
|
||||
std::wstring envVar = L"BOOST_NOWIDE_TEST=" + boost::nowide::widen(example);
|
||||
TEST(_wputenv(envVar.c_str()) == 0);
|
||||
std::wstring wcommand = boost::nowide::widen(argv[0]) + L" " + boost::nowide::widen(example);
|
||||
TEST(_wsystem(wcommand.c_str()) == 0);
|
||||
std::cout << "Wide Parent ok" << std::endl;
|
||||
#endif
|
||||
}
|
||||
} catch(const std::exception& e)
|
||||
// This must be contained in env
|
||||
std::string sample = "BOOST_NOWIDE_TEST=" + example;
|
||||
bool found = false;
|
||||
for(char** e = env; *e != 0; e++)
|
||||
{
|
||||
std::cerr << "Failed " << e.what() << std::endl;
|
||||
return 1;
|
||||
if(*e == sample)
|
||||
found = true;
|
||||
}
|
||||
TEST(found);
|
||||
|
||||
return 0;
|
||||
std::cout << "Subprocess ok" << std::endl;
|
||||
}
|
||||
|
||||
void run_parent(const char* exe_path)
|
||||
{
|
||||
#if BOOST_NOWIDE_TEST_USE_NARROW
|
||||
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);
|
||||
TEST(boost::nowide::setenv("BOOST_NOWIDE_EMPTY", "", 1) == 0);
|
||||
TEST(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"));
|
||||
std::string command = "\"";
|
||||
command += exe_path;
|
||||
command += "\" ";
|
||||
command += example;
|
||||
TEST(boost::nowide::system(command.c_str()) == 0);
|
||||
std::cout << "Parent ok" << std::endl;
|
||||
#else
|
||||
std::wstring envVar = L"BOOST_NOWIDE_TEST=" + boost::nowide::widen(example);
|
||||
TEST(_wputenv(envVar.c_str()) == 0);
|
||||
std::wstring wcommand = boost::nowide::widen(exe_path) + L" " + boost::nowide::widen(example);
|
||||
TEST(_wsystem(wcommand.c_str()) == 0);
|
||||
std::cout << "Wide Parent ok" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_main(int argc, char** argv, char** env)
|
||||
{
|
||||
const int old_argc = argc;
|
||||
char** old_argv = argv;
|
||||
char** old_env = env;
|
||||
{
|
||||
boost::nowide::args _(argc, argv, env);
|
||||
TEST(argc == old_argc);
|
||||
std::cout << "Checking arguments" << std::endl;
|
||||
compare_string_arrays(old_argv, argv, false);
|
||||
std::cout << "Checking env" << std::endl;
|
||||
compare_string_arrays(old_env, env, true);
|
||||
compare_getenv(env);
|
||||
}
|
||||
// When `args` is destructed the old values must be restored
|
||||
TEST(argc == old_argc);
|
||||
TEST(argv == old_argv);
|
||||
TEST(env == old_env);
|
||||
|
||||
boost::nowide::args a(argc, argv, env);
|
||||
if(argc == 1)
|
||||
run_parent(argv[0]);
|
||||
else
|
||||
run_child(argc, argv, env);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user