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

source code of libcxx/test/std/strings/string.view/string.view.nonmem/quoted.pass.cpp