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