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