]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/nowide/test/test_system.cpp
2 // Copyright (c) 2012 Artyom Beilis (Tonkikh)
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
9 #define _CRT_SECURE_NO_WARNINGS
12 #include <boost/nowide/args.hpp>
13 #include <boost/nowide/cstdlib.hpp>
14 #include <boost/nowide/utf/convert.hpp>
15 #include <boost/nowide/utf/utf.hpp>
25 bool is_ascii(const std::string
& s
)
27 return std::find_if(s
.begin(), s
.end(), [](const char c
) { return static_cast<unsigned char>(c
) > 0x7F; })
31 std::string
replace_non_ascii(const std::string
& s
) // LCOV_EXCL_LINE
33 std::string::const_iterator it
= s
.begin();
34 namespace utf
= boost::nowide::utf
;
35 using utf8
= utf::utf_traits
<char>;
37 result
.reserve(s
.size());
40 utf::code_point c
= utf8::decode(it
, s
.end());
41 TEST(c
!= utf::illegal
&& c
!= utf::incomplete
);
43 c
= '?'; // WinAPI seems to do this
44 result
.push_back(static_cast<char>(c
));
49 void compare_string_arrays(char** main_val
, char** utf8_val
, bool sort
)
51 std::vector
<std::string
> vec_main
, vec_utf8
;
52 for(; *main_val
; ++main_val
)
53 vec_main
.push_back(std::string(*main_val
));
54 for(; *utf8_val
; ++utf8_val
)
55 vec_utf8
.push_back(std::string(*utf8_val
));
56 // Same number of strings
57 TEST_EQ(vec_main
.size(), vec_utf8
.size());
60 // Order doesn't matter
61 std::sort(vec_main
.begin(), vec_main
.end());
62 std::sort(vec_utf8
.begin(), vec_utf8
.end());
64 for(size_t i
= 0; i
< vec_main
.size(); ++i
)
66 // Skip strings with non-ascii chars
67 if(is_ascii(vec_main
[i
]) && vec_main
[i
] != vec_utf8
[i
])
68 TEST_EQ(vec_main
[i
], replace_non_ascii(vec_utf8
[i
]));
72 void compare_getenv(char** env
)
74 // For all all variables in env check against getenv
75 for(char** e
= env
; *e
!= 0; e
++)
77 const char* key_begin
= *e
;
78 const char* key_end
= strchr(key_begin
, '=');
80 std::string key
= std::string(key_begin
, key_end
);
81 const char* std_value
= std::getenv(key
.c_str());
82 const char* bnw_value
= boost::nowide::getenv(key
.c_str());
85 // Compare only if ascii
86 if(is_ascii(std_value
) && std::string(std_value
) != std::string(bnw_value
))
87 TEST_EQ(std_value
, replace_non_ascii(bnw_value
));
91 const std::string example
= "\xd7\xa9-\xd0\xbc-\xce\xbd";
93 void run_child(int argc
, char** argv
, char** env
)
97 TEST_EQ(argv
[1], example
);
98 TEST(argv
[2] == NULL
);
101 TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST"));
102 TEST_EQ(boost::nowide::getenv("BOOST_NOWIDE_TEST"), example
);
103 TEST(boost::nowide::getenv("BOOST_NOWIDE_TEST_NONE") == NULL
);
104 // Empty variables are unreliable on windows, hence skip. E.g. using "set FOO=" unsets FOO
105 #ifndef BOOST_WINDOWS
106 TEST(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"));
107 TEST_EQ(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"), std::string());
110 // This must be contained in env
111 std::string sample
= "BOOST_NOWIDE_TEST=" + example
;
113 for(char** e
= env
; *e
!= 0; e
++)
120 std::cout
<< "Subprocess ok" << std::endl
;
123 void run_parent(const char* exe_path
)
125 TEST(boost::nowide::system(nullptr) != 0);
126 const std::string command
= "\"" + std::string(exe_path
) + "\" " + example
;
127 #if BOOST_NOWIDE_TEST_USE_NARROW
128 TEST_EQ(boost::nowide::setenv("BOOST_NOWIDE_TEST", example
.c_str(), 1), 0);
129 TEST_EQ(boost::nowide::setenv("BOOST_NOWIDE_TEST_NONE", example
.c_str(), 1), 0);
130 TEST_EQ(boost::nowide::unsetenv("BOOST_NOWIDE_TEST_NONE"), 0);
131 TEST_EQ(boost::nowide::setenv("BOOST_NOWIDE_EMPTY", "", 1), 0);
132 TEST(boost::nowide::getenv("BOOST_NOWIDE_EMPTY"));
133 TEST_EQ(boost::nowide::system(command
.c_str()), 0);
134 std::cout
<< "Parent ok" << std::endl
;
136 const std::wstring envVar
= L
"BOOST_NOWIDE_TEST=" + boost::nowide::widen(example
);
137 TEST_EQ(_wputenv(envVar
.c_str()), 0);
138 const std::wstring wcommand
= boost::nowide::widen(command
);
139 TEST_EQ(_wsystem(wcommand
.c_str()), 0);
140 std::cout
<< "Wide Parent ok" << std::endl
;
144 // coverity [root_function]
145 void test_main(int argc
, char** argv
, char** env
)
147 const int old_argc
= argc
;
148 char** old_argv
= argv
;
149 char** old_env
= env
;
151 boost::nowide::args
_(argc
, argv
, env
);
152 TEST_EQ(argc
, old_argc
);
153 std::cout
<< "Checking arguments" << std::endl
;
154 compare_string_arrays(old_argv
, argv
, false);
155 std::cout
<< "Checking env" << std::endl
;
156 compare_string_arrays(old_env
, env
, true);
159 // When `args` is destructed the old values must be restored
160 TEST_EQ(argc
, old_argc
);
161 TEST(argv
== old_argv
);
162 TEST(env
== old_env
);
164 boost::nowide::args
a(argc
, argv
, env
);
168 run_child(argc
, argv
, env
);