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: libcpp-has-no-localization
11 
12 // <iomanip>
13 
14 // quoted
15 
16 #include <iomanip>
17 #include <sstream>
18 #include <string_view>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 
is_skipws(const std::istream * is)23 bool is_skipws ( const std::istream *is ) {
24     return ( is->flags() & std::ios_base::skipws ) != 0;
25     }
26 
27 
is_skipws(const std::wistream * is)28 bool is_skipws ( const std::wistream *is ) {
29     return ( is->flags() & std::ios_base::skipws ) != 0;
30     }
31 
round_trip(const char * p)32 void round_trip ( const char *p ) {
33     std::stringstream ss;
34     bool skippingws = is_skipws ( &ss );
35     std::string_view sv {p};
36 
37     ss << std::quoted(sv);
38     std::string s;
39     ss >> std::quoted(s);
40     assert ( s == sv );
41     assert ( skippingws == is_skipws ( &ss ));
42     }
43 
round_trip_ws(const char * p)44 void round_trip_ws ( const char *p ) {
45     std::stringstream ss;
46     std::noskipws ( ss );
47     bool skippingws = is_skipws ( &ss );
48     std::string_view sv {p};
49 
50     ss << std::quoted(sv);
51     std::string s;
52     ss >> std::quoted(s);
53     assert ( s == sv );
54     assert ( skippingws == is_skipws ( &ss ));
55     }
56 
round_trip_d(const char * p,char delim)57 void round_trip_d ( const char *p, char delim ) {
58     std::stringstream ss;
59     std::string_view sv {p};
60 
61     ss << std::quoted(sv, delim);
62     std::string s;
63     ss >> std::quoted(s, delim);
64     assert ( s == sv );
65     }
66 
round_trip_e(const char * p,char escape)67 void round_trip_e ( const char *p, char escape ) {
68     std::stringstream ss;
69     std::string_view sv {p};
70 
71     ss << std::quoted(sv, '"', escape );
72     std::string s;
73     ss >> std::quoted(s, '"', escape );
74     assert ( s == sv );
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 
95 
round_trip(const wchar_t * p)96 void round_trip ( const wchar_t *p ) {
97     std::wstringstream ss;
98     bool skippingws = is_skipws ( &ss );
99     std::wstring_view sv {p};
100 
101     ss << std::quoted(sv);
102     std::wstring s;
103     ss >> std::quoted(s);
104     assert ( s == sv );
105     assert ( skippingws == is_skipws ( &ss ));
106     }
107 
108 
round_trip_ws(const wchar_t * p)109 void round_trip_ws ( const wchar_t *p ) {
110     std::wstringstream ss;
111     std::noskipws ( ss );
112     bool skippingws = is_skipws ( &ss );
113     std::wstring_view sv {p};
114 
115     ss << std::quoted(sv);
116     std::wstring s;
117     ss >> std::quoted(s);
118     assert ( s == sv );
119     assert ( skippingws == is_skipws ( &ss ));
120     }
121 
round_trip_d(const wchar_t * p,wchar_t delim)122 void round_trip_d ( const wchar_t *p, wchar_t delim ) {
123     std::wstringstream ss;
124     std::wstring_view sv {p};
125 
126     ss << std::quoted(sv, delim);
127     std::wstring s;
128     ss >> std::quoted(s, delim);
129     assert ( s == sv );
130     }
131 
round_trip_e(const wchar_t * p,wchar_t escape)132 void round_trip_e ( const wchar_t *p, wchar_t escape ) {
133     std::wstringstream ss;
134     std::wstring_view sv {p};
135 
136     ss << std::quoted(sv, wchar_t('"'), escape );
137     std::wstring s;
138     ss >> std::quoted(s, wchar_t('"'), escape );
139     assert ( s == sv );
140     }
141 
142 
quote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')143 std::wstring quote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
144     std::wstringstream ss;
145     std::wstring_view sv {p};
146 
147     ss << std::quoted(sv, delim, escape);
148     std::wstring s;
149     ss >> s;    // no quote
150     return s;
151 }
152 
unquote(const wchar_t * p,wchar_t delim='"',wchar_t escape='\\\\')153 std::wstring unquote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
154     std::wstringstream ss;
155     std::wstring_view sv {p};
156 
157     ss << sv;
158     std::wstring s;
159     ss >> std::quoted(s, delim, escape);
160     return s;
161 }
162 
main(int,char **)163 int main(int, char**)
164 {
165     round_trip    (  "" );
166     round_trip_ws (  "" );
167     round_trip_d  (  "", 'q' );
168     round_trip_e  (  "", 'q' );
169 
170     round_trip    ( L"" );
171     round_trip_ws ( L"" );
172     round_trip_d  ( L"", 'q' );
173     round_trip_e  ( L"", 'q' );
174 
175     round_trip    (  "Hi" );
176     round_trip_ws (  "Hi" );
177     round_trip_d  (  "Hi", '!' );
178     round_trip_e  (  "Hi", '!' );
179     assert ( quote ( "Hi", '!' ) == "!Hi!" );
180     assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
181 
182     round_trip    ( L"Hi" );
183     round_trip_ws ( L"Hi" );
184     round_trip_d  ( L"Hi", '!' );
185     round_trip_e  ( L"Hi", '!' );
186     assert ( quote ( L"Hi", '!' )  == L"!Hi!" );
187     assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
188 
189     round_trip    (  "Hi Mom" );
190     round_trip_ws (  "Hi Mom" );
191     round_trip    ( L"Hi Mom" );
192     round_trip_ws ( L"Hi Mom" );
193 
194     assert ( quote (  "" )  ==  "\"\"" );
195     assert ( quote ( L"" )  == L"\"\"" );
196     assert ( quote (  "a" ) ==  "\"a\"" );
197     assert ( quote ( L"a" ) == L"\"a\"" );
198 
199 //  missing end quote - must not hang
200     assert ( unquote (  "\"abc" ) ==  "abc" );
201     assert ( unquote ( L"\"abc" ) == L"abc" );
202 
203     assert ( unquote (  "abc" ) == "abc" ); // no delimiter
204     assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
205     assert ( unquote (  "abc def" ) ==  "abc" ); // no delimiter
206     assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
207 
208     assert ( unquote (  "" ) ==  "" ); // nothing there
209     assert ( unquote ( L"" ) == L"" ); // nothing there
210 
211     return 0;
212 }
213