1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11
10 // UNSUPPORTED: no-localization
11 // UNSUPPORTED: !stdlib=libc++ && c++14
12
13 // <iomanip>
14
15 // quoted
16
17 #include <iomanip>
18 #include <sstream>
19 #include <string_view>
20 #include <cassert>
21
22 #include "test_macros.h"
23
is_skipws(const std::istream * is)24 bool is_skipws ( const std::istream *is ) {
25 return ( is->flags() & std::ios_base::skipws ) != 0;
26 }
27
28 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
is_skipws(const std::wistream * is)29 bool is_skipws ( const std::wistream *is ) {
30 return ( is->flags() & std::ios_base::skipws ) != 0;
31 }
32 #endif
33
round_trip(const char * p)34 void round_trip ( const char *p ) {
35 std::stringstream ss;
36 bool skippingws = is_skipws ( &ss );
37 std::string_view sv {p};
38
39 ss << std::quoted(sv);
40 std::string s;
41 ss >> std::quoted(s);
42 assert ( s == sv );
43 assert ( skippingws == is_skipws ( &ss ));
44 }
45
round_trip_ws(const char * p)46 void round_trip_ws ( const char *p ) {
47 std::stringstream ss;
48 std::noskipws ( ss );
49 bool skippingws = is_skipws ( &ss );
50 std::string_view sv {p};
51
52 ss << std::quoted(sv);
53 std::string s;
54 ss >> std::quoted(s);
55 assert ( s == sv );
56 assert ( skippingws == is_skipws ( &ss ));
57 }
58
round_trip_d(const char * p,char delim)59 void round_trip_d ( const char *p, char delim ) {
60 std::stringstream ss;
61 std::string_view sv {p};
62
63 ss << std::quoted(sv, delim);
64 std::string s;
65 ss >> std::quoted(s, delim);
66 assert ( s == sv );
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 std::string_view sv {p};
72
73 ss << std::quoted(sv, '"', escape );
74 std::string s;
75 ss >> std::quoted(s, '"', escape );
76 assert ( s == sv );
77 }
78
79
80
quote(const char * p,char delim='"',char escape='\\\\')81 std::string quote ( const char *p, char delim='"', char escape='\\' ) {
82 std::stringstream ss;
83 ss << std::quoted(p, delim, escape);
84 std::string s;
85 ss >> s; // no quote
86 return s;
87 }
88
unquote(const char * p,char delim='"',char escape='\\\\')89 std::string unquote ( const char *p, char delim='"', char escape='\\' ) {
90 std::stringstream ss;
91 ss << p;
92 std::string s;
93 ss >> std::quoted(s, delim, escape);
94 return s;
95 }
96
97 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
round_trip(const wchar_t * p)98 void round_trip ( const wchar_t *p ) {
99 std::wstringstream ss;
100 bool skippingws = is_skipws ( &ss );
101 std::wstring_view sv {p};
102
103 ss << std::quoted(sv);
104 std::wstring s;
105 ss >> std::quoted(s);
106 assert ( s == sv );
107 assert ( skippingws == is_skipws ( &ss ));
108 }
109
110
round_trip_ws(const wchar_t * p)111 void round_trip_ws ( const wchar_t *p ) {
112 std::wstringstream ss;
113 std::noskipws ( ss );
114 bool skippingws = is_skipws ( &ss );
115 std::wstring_view sv {p};
116
117 ss << std::quoted(sv);
118 std::wstring s;
119 ss >> std::quoted(s);
120 assert ( s == sv );
121 assert ( skippingws == is_skipws ( &ss ));
122 }
123
round_trip_d(const wchar_t * p,wchar_t delim)124 void round_trip_d ( const wchar_t *p, wchar_t delim ) {
125 std::wstringstream ss;
126 std::wstring_view sv {p};
127
128 ss << std::quoted(sv, delim);
129 std::wstring s;
130 ss >> std::quoted(s, delim);
131 assert ( s == sv );
132 }
133
round_trip_e(const wchar_t * p,wchar_t escape)134 void round_trip_e ( const wchar_t *p, wchar_t escape ) {
135 std::wstringstream ss;
136 std::wstring_view sv {p};
137
138 ss << std::quoted(sv, wchar_t('"'), escape );
139 std::wstring s;
140 ss >> std::quoted(s, wchar_t('"'), escape );
141 assert ( s == sv );
142 }
143
144
quote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')145 std::wstring quote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
146 std::wstringstream ss;
147 std::wstring_view sv {p};
148
149 ss << std::quoted(sv, delim, escape);
150 std::wstring s;
151 ss >> s; // no quote
152 return s;
153 }
154
unquote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')155 std::wstring unquote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
156 std::wstringstream ss;
157 std::wstring_view sv {p};
158
159 ss << sv;
160 std::wstring s;
161 ss >> std::quoted(s, delim, escape);
162 return s;
163 }
164 #endif // TEST_HAS_NO_WIDE_CHARACTERS
165
main(int,char **)166 int main(int, char**)
167 {
168 round_trip ( "" );
169 round_trip_ws ( "" );
170 round_trip_d ( "", 'q' );
171 round_trip_e ( "", 'q' );
172
173 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
174 round_trip ( L"" );
175 round_trip_ws ( L"" );
176 round_trip_d ( L"", 'q' );
177 round_trip_e ( L"", 'q' );
178 #endif
179
180 round_trip ( "Hi" );
181 round_trip_ws ( "Hi" );
182 round_trip_d ( "Hi", '!' );
183 round_trip_e ( "Hi", '!' );
184 assert ( quote ( "Hi", '!' ) == "!Hi!" );
185 assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
186
187 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
188 round_trip ( L"Hi" );
189 round_trip_ws ( L"Hi" );
190 round_trip_d ( L"Hi", '!' );
191 round_trip_e ( L"Hi", '!' );
192 assert ( quote ( L"Hi", '!' ) == L"!Hi!" );
193 assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
194 #endif
195
196 round_trip ( "Hi Mom" );
197 round_trip_ws ( "Hi Mom" );
198
199 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
200 round_trip ( L"Hi Mom" );
201 round_trip_ws ( L"Hi Mom" );
202 #endif
203
204 assert ( quote ( "" ) == "\"\"" );
205 assert ( quote ( "a" ) == "\"a\"" );
206 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
207 assert ( quote ( L"" ) == L"\"\"" );
208 assert ( quote ( L"a" ) == L"\"a\"" );
209 #endif
210
211 // missing end quote - must not hang
212 assert ( unquote ( "\"abc" ) == "abc" );
213 assert ( unquote ( "abc" ) == "abc" ); // no delimiter
214 assert ( unquote ( "abc def" ) == "abc" ); // no delimiter
215 assert ( unquote ( "" ) == "" ); // nothing there
216
217 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
218 assert ( unquote ( L"\"abc" ) == L"abc" );
219 assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
220 assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
221 assert ( unquote ( L"" ) == L"" ); // nothing there
222 #endif
223
224 return 0;
225 }
226