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 #include "test_macros.h" 20 21 #if TEST_STD_VER > 11 22 23 template <class CharT, class Traits> 24 bool is_skipws ( const std::basic_istream<CharT, Traits>& is ) { 25 return ( is.flags() & std::ios_base::skipws ) != 0; 26 } 27 28 template <class CharT, class Traits = std::char_traits<CharT>> 29 void both_ways ( const CharT *p ) { 30 std::basic_string<CharT, Traits> str(p); 31 auto q = std::quoted(str); 32 33 std::basic_stringstream<CharT, Traits> ss; 34 bool skippingws = is_skipws ( ss ); 35 ((void)skippingws); // Prevent unused warning 36 ss << q; 37 ss >> q; 38 } 39 40 template <class CharT, class Traits = std::char_traits<CharT>> 41 void round_trip ( const CharT *p ) { 42 std::basic_stringstream<CharT, Traits> ss; 43 bool skippingws = is_skipws ( ss ); 44 45 ss << std::quoted(p); 46 std::basic_string<CharT, Traits> s; 47 ss >> std::quoted(s); 48 assert ( s == p ); 49 assert ( skippingws == is_skipws ( ss )); 50 } 51 52 53 template <class CharT, class Traits = std::char_traits<CharT>> 54 void round_trip_ws ( const CharT *p ) { 55 std::basic_stringstream<CharT, Traits> ss; 56 std::noskipws ( ss ); 57 bool skippingws = is_skipws ( ss ); 58 59 ss << std::quoted(p); 60 std::basic_string<CharT, Traits> s; 61 ss >> std::quoted(s); 62 assert ( s == p ); 63 assert ( skippingws == is_skipws ( ss )); 64 } 65 66 template <class CharT, class Traits = std::char_traits<CharT>> 67 void round_trip_d ( const CharT *p, char delim ) { 68 std::basic_stringstream<CharT, Traits> ss; 69 CharT d(delim); 70 71 ss << std::quoted(p, d); 72 std::basic_string<CharT, Traits> s; 73 ss >> std::quoted(s, d); 74 assert ( s == p ); 75 } 76 77 template <class CharT, class Traits = std::char_traits<CharT>> 78 void round_trip_e ( const CharT *p, char escape ) { 79 std::basic_stringstream<CharT, Traits> ss; 80 CharT e(escape); 81 82 ss << std::quoted(p, CharT('"'), e ); 83 std::basic_string<CharT, Traits> s; 84 ss >> std::quoted(s, CharT('"'), e ); 85 assert ( s == p ); 86 } 87 88 89 template <class CharT, class Traits = std::char_traits<CharT>> 90 std::basic_string<CharT, Traits> quote ( const CharT *p, char delim='"', char escape='\\' ) { 91 std::basic_stringstream<CharT, Traits> ss; 92 CharT d(delim); 93 CharT e(escape); 94 ss << std::quoted(p, d, e); 95 std::basic_string<CharT, Traits> s; 96 ss >> s; // no quote 97 return s; 98 } 99 100 template <class CharT, class Traits = std::char_traits<CharT>> 101 std::basic_string<CharT, Traits> unquote ( const CharT *p, char delim='"', char escape='\\' ) { 102 std::basic_stringstream<CharT, Traits> ss; 103 ss << p; 104 105 CharT d(delim); 106 CharT e(escape); 107 std::basic_string<CharT, Traits> s; 108 ss >> std::quoted(s, d, e); 109 return s; 110 } 111 112 void test_padding () { 113 { 114 std::stringstream ss; 115 ss << std::left << std::setw(10) << std::setfill('!') << std::quoted("abc", '`'); 116 assert ( ss.str() == "`abc`!!!!!" ); 117 } 118 119 { 120 std::stringstream ss; 121 ss << std::right << std::setw(10) << std::setfill('!') << std::quoted("abc", '`'); 122 assert ( ss.str() == "!!!!!`abc`" ); 123 } 124 } 125 126 127 int main() 128 { 129 both_ways ( "" ); // This is a compilation check 130 131 round_trip ( "" ); 132 round_trip_ws ( "" ); 133 round_trip_d ( "", 'q' ); 134 round_trip_e ( "", 'q' ); 135 136 round_trip ( L"" ); 137 round_trip_ws ( L"" ); 138 round_trip_d ( L"", 'q' ); 139 round_trip_e ( L"", 'q' ); 140 141 round_trip ( "Hi" ); 142 round_trip_ws ( "Hi" ); 143 round_trip_d ( "Hi", '!' ); 144 round_trip_e ( "Hi", '!' ); 145 assert ( quote ( "Hi", '!' ) == "!Hi!" ); 146 assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" ); 147 148 round_trip ( L"Hi" ); 149 round_trip_ws ( L"Hi" ); 150 round_trip_d ( L"Hi", '!' ); 151 round_trip_e ( L"Hi", '!' ); 152 assert ( quote ( L"Hi", '!' ) == L"!Hi!" ); 153 assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" ); 154 155 round_trip ( "Hi Mom" ); 156 round_trip_ws ( "Hi Mom" ); 157 round_trip ( L"Hi Mom" ); 158 round_trip_ws ( L"Hi Mom" ); 159 160 assert ( quote ( "" ) == "\"\"" ); 161 assert ( quote ( L"" ) == L"\"\"" ); 162 assert ( quote ( "a" ) == "\"a\"" ); 163 assert ( quote ( L"a" ) == L"\"a\"" ); 164 165 // missing end quote - must not hang 166 assert ( unquote ( "\"abc" ) == "abc" ); 167 assert ( unquote ( L"\"abc" ) == L"abc" ); 168 169 assert ( unquote ( "abc" ) == "abc" ); // no delimiter 170 assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter 171 assert ( unquote ( "abc def" ) == "abc" ); // no delimiter 172 assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter 173 174 assert ( unquote ( "" ) == "" ); // nothing there 175 assert ( unquote ( L"" ) == L"" ); // nothing there 176 test_padding (); 177 } 178 179 #else 180 int main() {} 181 #endif 182