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