1053d81ceSMarshall Clow //===----------------------------------------------------------------------===//
2053d81ceSMarshall Clow //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6053d81ceSMarshall Clow //
7053d81ceSMarshall Clow //===----------------------------------------------------------------------===//
8053d81ceSMarshall Clow
913410fa7SLouis Dionne // UNSUPPORTED: c++03, c++11
10a7f9895cSLouis Dionne // UNSUPPORTED: no-localization
11*4fc50236SJoe Loser // UNSUPPORTED: !stdlib=libc++ && c++14
1213410fa7SLouis Dionne
13053d81ceSMarshall Clow // <iomanip>
14053d81ceSMarshall Clow
15053d81ceSMarshall Clow // quoted
16053d81ceSMarshall Clow
17053d81ceSMarshall Clow #include <iomanip>
18053d81ceSMarshall Clow #include <sstream>
19053d81ceSMarshall Clow #include <string_view>
20053d81ceSMarshall Clow #include <cassert>
21053d81ceSMarshall Clow
220f901c7eSStephan T. Lavavej #include "test_macros.h"
230f901c7eSStephan T. Lavavej
is_skipws(const std::istream * is)24053d81ceSMarshall Clow bool is_skipws ( const std::istream *is ) {
25053d81ceSMarshall Clow return ( is->flags() & std::ios_base::skipws ) != 0;
26053d81ceSMarshall Clow }
27053d81ceSMarshall Clow
28f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
is_skipws(const std::wistream * is)29053d81ceSMarshall Clow bool is_skipws ( const std::wistream *is ) {
30053d81ceSMarshall Clow return ( is->flags() & std::ios_base::skipws ) != 0;
31053d81ceSMarshall Clow }
32f4c1258dSLouis Dionne #endif
33053d81ceSMarshall Clow
round_trip(const char * p)34053d81ceSMarshall Clow void round_trip ( const char *p ) {
35053d81ceSMarshall Clow std::stringstream ss;
36053d81ceSMarshall Clow bool skippingws = is_skipws ( &ss );
37053d81ceSMarshall Clow std::string_view sv {p};
38053d81ceSMarshall Clow
39053d81ceSMarshall Clow ss << std::quoted(sv);
40053d81ceSMarshall Clow std::string s;
41053d81ceSMarshall Clow ss >> std::quoted(s);
42053d81ceSMarshall Clow assert ( s == sv );
43053d81ceSMarshall Clow assert ( skippingws == is_skipws ( &ss ));
44053d81ceSMarshall Clow }
45053d81ceSMarshall Clow
round_trip_ws(const char * p)46053d81ceSMarshall Clow void round_trip_ws ( const char *p ) {
47053d81ceSMarshall Clow std::stringstream ss;
48053d81ceSMarshall Clow std::noskipws ( ss );
49053d81ceSMarshall Clow bool skippingws = is_skipws ( &ss );
50053d81ceSMarshall Clow std::string_view sv {p};
51053d81ceSMarshall Clow
52053d81ceSMarshall Clow ss << std::quoted(sv);
53053d81ceSMarshall Clow std::string s;
54053d81ceSMarshall Clow ss >> std::quoted(s);
55053d81ceSMarshall Clow assert ( s == sv );
56053d81ceSMarshall Clow assert ( skippingws == is_skipws ( &ss ));
57053d81ceSMarshall Clow }
58053d81ceSMarshall Clow
round_trip_d(const char * p,char delim)59053d81ceSMarshall Clow void round_trip_d ( const char *p, char delim ) {
60053d81ceSMarshall Clow std::stringstream ss;
61053d81ceSMarshall Clow std::string_view sv {p};
62053d81ceSMarshall Clow
63053d81ceSMarshall Clow ss << std::quoted(sv, delim);
64053d81ceSMarshall Clow std::string s;
65053d81ceSMarshall Clow ss >> std::quoted(s, delim);
66053d81ceSMarshall Clow assert ( s == sv );
67053d81ceSMarshall Clow }
68053d81ceSMarshall Clow
round_trip_e(const char * p,char escape)69053d81ceSMarshall Clow void round_trip_e ( const char *p, char escape ) {
70053d81ceSMarshall Clow std::stringstream ss;
71053d81ceSMarshall Clow std::string_view sv {p};
72053d81ceSMarshall Clow
73053d81ceSMarshall Clow ss << std::quoted(sv, '"', escape );
74053d81ceSMarshall Clow std::string s;
75053d81ceSMarshall Clow ss >> std::quoted(s, '"', escape );
76053d81ceSMarshall Clow assert ( s == sv );
77053d81ceSMarshall Clow }
78053d81ceSMarshall Clow
79053d81ceSMarshall Clow
80053d81ceSMarshall Clow
quote(const char * p,char delim='"',char escape='\\\\')81053d81ceSMarshall Clow std::string quote ( const char *p, char delim='"', char escape='\\' ) {
82053d81ceSMarshall Clow std::stringstream ss;
83053d81ceSMarshall Clow ss << std::quoted(p, delim, escape);
84053d81ceSMarshall Clow std::string s;
85053d81ceSMarshall Clow ss >> s; // no quote
86053d81ceSMarshall Clow return s;
87053d81ceSMarshall Clow }
88053d81ceSMarshall Clow
unquote(const char * p,char delim='"',char escape='\\\\')89053d81ceSMarshall Clow std::string unquote ( const char *p, char delim='"', char escape='\\' ) {
90053d81ceSMarshall Clow std::stringstream ss;
91053d81ceSMarshall Clow ss << p;
92053d81ceSMarshall Clow std::string s;
93053d81ceSMarshall Clow ss >> std::quoted(s, delim, escape);
94053d81ceSMarshall Clow return s;
95053d81ceSMarshall Clow }
96053d81ceSMarshall Clow
97f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
round_trip(const wchar_t * p)98053d81ceSMarshall Clow void round_trip ( const wchar_t *p ) {
99053d81ceSMarshall Clow std::wstringstream ss;
100053d81ceSMarshall Clow bool skippingws = is_skipws ( &ss );
101053d81ceSMarshall Clow std::wstring_view sv {p};
102053d81ceSMarshall Clow
103053d81ceSMarshall Clow ss << std::quoted(sv);
104053d81ceSMarshall Clow std::wstring s;
105053d81ceSMarshall Clow ss >> std::quoted(s);
106053d81ceSMarshall Clow assert ( s == sv );
107053d81ceSMarshall Clow assert ( skippingws == is_skipws ( &ss ));
108053d81ceSMarshall Clow }
109053d81ceSMarshall Clow
110053d81ceSMarshall Clow
round_trip_ws(const wchar_t * p)111053d81ceSMarshall Clow void round_trip_ws ( const wchar_t *p ) {
112053d81ceSMarshall Clow std::wstringstream ss;
113053d81ceSMarshall Clow std::noskipws ( ss );
114053d81ceSMarshall Clow bool skippingws = is_skipws ( &ss );
115053d81ceSMarshall Clow std::wstring_view sv {p};
116053d81ceSMarshall Clow
117053d81ceSMarshall Clow ss << std::quoted(sv);
118053d81ceSMarshall Clow std::wstring s;
119053d81ceSMarshall Clow ss >> std::quoted(s);
120053d81ceSMarshall Clow assert ( s == sv );
121053d81ceSMarshall Clow assert ( skippingws == is_skipws ( &ss ));
122053d81ceSMarshall Clow }
123053d81ceSMarshall Clow
round_trip_d(const wchar_t * p,wchar_t delim)124053d81ceSMarshall Clow void round_trip_d ( const wchar_t *p, wchar_t delim ) {
125053d81ceSMarshall Clow std::wstringstream ss;
126053d81ceSMarshall Clow std::wstring_view sv {p};
127053d81ceSMarshall Clow
128053d81ceSMarshall Clow ss << std::quoted(sv, delim);
129053d81ceSMarshall Clow std::wstring s;
130053d81ceSMarshall Clow ss >> std::quoted(s, delim);
131053d81ceSMarshall Clow assert ( s == sv );
132053d81ceSMarshall Clow }
133053d81ceSMarshall Clow
round_trip_e(const wchar_t * p,wchar_t escape)134053d81ceSMarshall Clow void round_trip_e ( const wchar_t *p, wchar_t escape ) {
135053d81ceSMarshall Clow std::wstringstream ss;
136053d81ceSMarshall Clow std::wstring_view sv {p};
137053d81ceSMarshall Clow
138053d81ceSMarshall Clow ss << std::quoted(sv, wchar_t('"'), escape );
139053d81ceSMarshall Clow std::wstring s;
140053d81ceSMarshall Clow ss >> std::quoted(s, wchar_t('"'), escape );
141053d81ceSMarshall Clow assert ( s == sv );
142053d81ceSMarshall Clow }
143053d81ceSMarshall Clow
144053d81ceSMarshall Clow
quote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')145053d81ceSMarshall Clow std::wstring quote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
146053d81ceSMarshall Clow std::wstringstream ss;
147053d81ceSMarshall Clow std::wstring_view sv {p};
148053d81ceSMarshall Clow
149053d81ceSMarshall Clow ss << std::quoted(sv, delim, escape);
150053d81ceSMarshall Clow std::wstring s;
151053d81ceSMarshall Clow ss >> s; // no quote
152053d81ceSMarshall Clow return s;
153053d81ceSMarshall Clow }
154053d81ceSMarshall Clow
unquote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')155053d81ceSMarshall Clow std::wstring unquote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
156053d81ceSMarshall Clow std::wstringstream ss;
157053d81ceSMarshall Clow std::wstring_view sv {p};
158053d81ceSMarshall Clow
159053d81ceSMarshall Clow ss << sv;
160053d81ceSMarshall Clow std::wstring s;
161053d81ceSMarshall Clow ss >> std::quoted(s, delim, escape);
162053d81ceSMarshall Clow return s;
163053d81ceSMarshall Clow }
164f4c1258dSLouis Dionne #endif // TEST_HAS_NO_WIDE_CHARACTERS
165053d81ceSMarshall Clow
main(int,char **)1662df59c50SJF Bastien int main(int, char**)
167053d81ceSMarshall Clow {
168053d81ceSMarshall Clow round_trip ( "" );
169053d81ceSMarshall Clow round_trip_ws ( "" );
170053d81ceSMarshall Clow round_trip_d ( "", 'q' );
171053d81ceSMarshall Clow round_trip_e ( "", 'q' );
172053d81ceSMarshall Clow
173f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
174053d81ceSMarshall Clow round_trip ( L"" );
175053d81ceSMarshall Clow round_trip_ws ( L"" );
176053d81ceSMarshall Clow round_trip_d ( L"", 'q' );
177053d81ceSMarshall Clow round_trip_e ( L"", 'q' );
178f4c1258dSLouis Dionne #endif
179053d81ceSMarshall Clow
180053d81ceSMarshall Clow round_trip ( "Hi" );
181053d81ceSMarshall Clow round_trip_ws ( "Hi" );
182053d81ceSMarshall Clow round_trip_d ( "Hi", '!' );
183053d81ceSMarshall Clow round_trip_e ( "Hi", '!' );
184053d81ceSMarshall Clow assert ( quote ( "Hi", '!' ) == "!Hi!" );
185053d81ceSMarshall Clow assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
186053d81ceSMarshall Clow
187f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
188053d81ceSMarshall Clow round_trip ( L"Hi" );
189053d81ceSMarshall Clow round_trip_ws ( L"Hi" );
190053d81ceSMarshall Clow round_trip_d ( L"Hi", '!' );
191053d81ceSMarshall Clow round_trip_e ( L"Hi", '!' );
192053d81ceSMarshall Clow assert ( quote ( L"Hi", '!' ) == L"!Hi!" );
193053d81ceSMarshall Clow assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
194f4c1258dSLouis Dionne #endif
195053d81ceSMarshall Clow
196053d81ceSMarshall Clow round_trip ( "Hi Mom" );
197053d81ceSMarshall Clow round_trip_ws ( "Hi Mom" );
198f4c1258dSLouis Dionne
199f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
200053d81ceSMarshall Clow round_trip ( L"Hi Mom" );
201053d81ceSMarshall Clow round_trip_ws ( L"Hi Mom" );
202f4c1258dSLouis Dionne #endif
203053d81ceSMarshall Clow
204053d81ceSMarshall Clow assert ( quote ( "" ) == "\"\"" );
205053d81ceSMarshall Clow assert ( quote ( "a" ) == "\"a\"" );
206f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
207f4c1258dSLouis Dionne assert ( quote ( L"" ) == L"\"\"" );
208053d81ceSMarshall Clow assert ( quote ( L"a" ) == L"\"a\"" );
209f4c1258dSLouis Dionne #endif
210053d81ceSMarshall Clow
211053d81ceSMarshall Clow // missing end quote - must not hang
212053d81ceSMarshall Clow assert ( unquote ( "\"abc" ) == "abc" );
213053d81ceSMarshall Clow assert ( unquote ( "abc" ) == "abc" ); // no delimiter
214053d81ceSMarshall Clow assert ( unquote ( "abc def" ) == "abc" ); // no delimiter
215053d81ceSMarshall Clow assert ( unquote ( "" ) == "" ); // nothing there
216f4c1258dSLouis Dionne
217f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
218f4c1258dSLouis Dionne assert ( unquote ( L"\"abc" ) == L"abc" );
219f4c1258dSLouis Dionne assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
220f4c1258dSLouis Dionne assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
221053d81ceSMarshall Clow assert ( unquote ( L"" ) == L"" ); // nothing there
222f4c1258dSLouis Dionne #endif
2232df59c50SJF Bastien
2242df59c50SJF Bastien return 0;
225053d81ceSMarshall Clow }
226