1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11 10 // UNSUPPORTED: no-localization 11 // UNSUPPORTED: !stdlib=libc++ && c++14 12 13 // <iomanip> 14 15 // quoted 16 17 #include <iomanip> 18 #include <sstream> 19 #include <string_view> 20 #include <cassert> 21 22 #include "test_macros.h" 23 24 bool is_skipws ( const std::istream *is ) { 25 return ( is->flags() & std::ios_base::skipws ) != 0; 26 } 27 28 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 29 bool is_skipws ( const std::wistream *is ) { 30 return ( is->flags() & std::ios_base::skipws ) != 0; 31 } 32 #endif 33 34 void round_trip ( const char *p ) { 35 std::stringstream ss; 36 bool skippingws = is_skipws ( &ss ); 37 std::string_view sv {p}; 38 39 ss << std::quoted(sv); 40 std::string s; 41 ss >> std::quoted(s); 42 assert ( s == sv ); 43 assert ( skippingws == is_skipws ( &ss )); 44 } 45 46 void round_trip_ws ( const char *p ) { 47 std::stringstream ss; 48 std::noskipws ( ss ); 49 bool skippingws = is_skipws ( &ss ); 50 std::string_view sv {p}; 51 52 ss << std::quoted(sv); 53 std::string s; 54 ss >> std::quoted(s); 55 assert ( s == sv ); 56 assert ( skippingws == is_skipws ( &ss )); 57 } 58 59 void round_trip_d ( const char *p, char delim ) { 60 std::stringstream ss; 61 std::string_view sv {p}; 62 63 ss << std::quoted(sv, delim); 64 std::string s; 65 ss >> std::quoted(s, delim); 66 assert ( s == sv ); 67 } 68 69 void round_trip_e ( const char *p, char escape ) { 70 std::stringstream ss; 71 std::string_view sv {p}; 72 73 ss << std::quoted(sv, '"', escape ); 74 std::string s; 75 ss >> std::quoted(s, '"', escape ); 76 assert ( s == sv ); 77 } 78 79 80 81 std::string quote ( const char *p, char delim='"', char escape='\\' ) { 82 std::stringstream ss; 83 ss << std::quoted(p, delim, escape); 84 std::string s; 85 ss >> s; // no quote 86 return s; 87 } 88 89 std::string unquote ( const char *p, char delim='"', char escape='\\' ) { 90 std::stringstream ss; 91 ss << p; 92 std::string s; 93 ss >> std::quoted(s, delim, escape); 94 return s; 95 } 96 97 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 98 void round_trip ( const wchar_t *p ) { 99 std::wstringstream ss; 100 bool skippingws = is_skipws ( &ss ); 101 std::wstring_view sv {p}; 102 103 ss << std::quoted(sv); 104 std::wstring s; 105 ss >> std::quoted(s); 106 assert ( s == sv ); 107 assert ( skippingws == is_skipws ( &ss )); 108 } 109 110 111 void round_trip_ws ( const wchar_t *p ) { 112 std::wstringstream ss; 113 std::noskipws ( ss ); 114 bool skippingws = is_skipws ( &ss ); 115 std::wstring_view sv {p}; 116 117 ss << std::quoted(sv); 118 std::wstring s; 119 ss >> std::quoted(s); 120 assert ( s == sv ); 121 assert ( skippingws == is_skipws ( &ss )); 122 } 123 124 void round_trip_d ( const wchar_t *p, wchar_t delim ) { 125 std::wstringstream ss; 126 std::wstring_view sv {p}; 127 128 ss << std::quoted(sv, delim); 129 std::wstring s; 130 ss >> std::quoted(s, delim); 131 assert ( s == sv ); 132 } 133 134 void round_trip_e ( const wchar_t *p, wchar_t escape ) { 135 std::wstringstream ss; 136 std::wstring_view sv {p}; 137 138 ss << std::quoted(sv, wchar_t('"'), escape ); 139 std::wstring s; 140 ss >> std::quoted(s, wchar_t('"'), escape ); 141 assert ( s == sv ); 142 } 143 144 145 std::wstring quote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) { 146 std::wstringstream ss; 147 std::wstring_view sv {p}; 148 149 ss << std::quoted(sv, delim, escape); 150 std::wstring s; 151 ss >> s; // no quote 152 return s; 153 } 154 155 std::wstring unquote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) { 156 std::wstringstream ss; 157 std::wstring_view sv {p}; 158 159 ss << sv; 160 std::wstring s; 161 ss >> std::quoted(s, delim, escape); 162 return s; 163 } 164 #endif // TEST_HAS_NO_WIDE_CHARACTERS 165 166 int main(int, char**) 167 { 168 round_trip ( "" ); 169 round_trip_ws ( "" ); 170 round_trip_d ( "", 'q' ); 171 round_trip_e ( "", 'q' ); 172 173 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 174 round_trip ( L"" ); 175 round_trip_ws ( L"" ); 176 round_trip_d ( L"", 'q' ); 177 round_trip_e ( L"", 'q' ); 178 #endif 179 180 round_trip ( "Hi" ); 181 round_trip_ws ( "Hi" ); 182 round_trip_d ( "Hi", '!' ); 183 round_trip_e ( "Hi", '!' ); 184 assert ( quote ( "Hi", '!' ) == "!Hi!" ); 185 assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" ); 186 187 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 188 round_trip ( L"Hi" ); 189 round_trip_ws ( L"Hi" ); 190 round_trip_d ( L"Hi", '!' ); 191 round_trip_e ( L"Hi", '!' ); 192 assert ( quote ( L"Hi", '!' ) == L"!Hi!" ); 193 assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" ); 194 #endif 195 196 round_trip ( "Hi Mom" ); 197 round_trip_ws ( "Hi Mom" ); 198 199 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 200 round_trip ( L"Hi Mom" ); 201 round_trip_ws ( L"Hi Mom" ); 202 #endif 203 204 assert ( quote ( "" ) == "\"\"" ); 205 assert ( quote ( "a" ) == "\"a\"" ); 206 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 207 assert ( quote ( L"" ) == L"\"\"" ); 208 assert ( quote ( L"a" ) == L"\"a\"" ); 209 #endif 210 211 // missing end quote - must not hang 212 assert ( unquote ( "\"abc" ) == "abc" ); 213 assert ( unquote ( "abc" ) == "abc" ); // no delimiter 214 assert ( unquote ( "abc def" ) == "abc" ); // no delimiter 215 assert ( unquote ( "" ) == "" ); // nothing there 216 217 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 218 assert ( unquote ( L"\"abc" ) == L"abc" ); 219 assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter 220 assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter 221 assert ( unquote ( L"" ) == L"" ); // nothing there 222 #endif 223 224 return 0; 225 } 226