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