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