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