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