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 
is_skipws(const std::istream * is)21 bool is_skipws ( const std::istream *is ) {
22     return ( is->flags() & std::ios_base::skipws ) != 0;
23     }
24 
25 
is_skipws(const std::wistream * is)26 bool is_skipws ( const std::wistream *is ) {
27     return ( is->flags() & std::ios_base::skipws ) != 0;
28     }
29 
both_ways(const char * p)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 
round_trip(const char * p)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 
round_trip_ws(const char * p)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 
round_trip_d(const char * p,char delim)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 
round_trip_e(const char * p,char escape)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 
quote(const char * p,char delim='"',char escape='\\\\')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 
unquote(const char * p,char delim='"',char escape='\\\\')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 
test_padding()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 
round_trip(const wchar_t * p)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 
round_trip_ws(const wchar_t * p)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 
round_trip_d(const wchar_t * p,wchar_t delim)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 
round_trip_e(const wchar_t * p,wchar_t escape)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 
quote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')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 
unquote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')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 
main()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
main()218 int main() {}
219 #endif
220