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
11// <iomanip>
12
13// quoted
14
15#include <iomanip>
16#include <sstream>
17#include <string>
18#include <cassert>
19
20#include "test_macros.h"
21
22template <class CharT, class Traits>
23bool is_skipws ( const std::basic_istream<CharT, Traits>& is ) {
24 return ( is.flags() & std::ios_base::skipws ) != 0;
25}
26
27template <class CharT, class Traits = std::char_traits<CharT>>
28void both_ways ( const CharT *p ) {
29 std::basic_string<CharT, Traits> str(p);
30 auto q = std::quoted(str);
31
32 std::basic_stringstream<CharT, Traits> ss;
33 bool skippingws = is_skipws ( ss );
34 ((void)skippingws); // Prevent unused warning
35 ss << q;
36 ss >> q;
37}
38
39template <class CharT, class Traits = std::char_traits<CharT>>
40void round_trip ( const CharT *p ) {
41 std::basic_stringstream<CharT, Traits> ss;
42 bool skippingws = is_skipws ( ss );
43
44 ss << std::quoted(p);
45 std::basic_string<CharT, Traits> s;
46 ss >> std::quoted(s);
47 assert ( s == p );
48 assert ( skippingws == is_skipws ( ss ));
49}
50
51
52template <class CharT, class Traits = std::char_traits<CharT>>
53void round_trip_ws ( const CharT *p ) {
54 std::basic_stringstream<CharT, Traits> ss;
55 std::noskipws ( base&: ss );
56 bool skippingws = is_skipws ( ss );
57
58 ss << std::quoted(p);
59 std::basic_string<CharT, Traits> s;
60 ss >> std::quoted(s);
61 assert ( s == p );
62 assert ( skippingws == is_skipws ( ss ));
63}
64
65template <class CharT, class Traits = std::char_traits<CharT>>
66void round_trip_d ( const CharT *p, char delim ) {
67 std::basic_stringstream<CharT, Traits> ss;
68 CharT d(delim);
69
70 ss << std::quoted(p, d);
71 std::basic_string<CharT, Traits> s;
72 ss >> std::quoted(s, d);
73 assert ( s == p );
74}
75
76template <class CharT, class Traits = std::char_traits<CharT>>
77void round_trip_e ( const CharT *p, char escape ) {
78 std::basic_stringstream<CharT, Traits> ss;
79 CharT e(escape);
80
81 ss << std::quoted(p, CharT('"'), e );
82 std::basic_string<CharT, Traits> s;
83 ss >> std::quoted(s, CharT('"'), e );
84 assert ( s == p );
85}
86
87
88template <class CharT, class Traits = std::char_traits<CharT>>
89std::basic_string<CharT, Traits> quote ( const CharT *p, char delim='"', char escape='\\' ) {
90 std::basic_stringstream<CharT, Traits> ss;
91 CharT d(delim);
92 CharT e(escape);
93 ss << std::quoted(p, d, e);
94 std::basic_string<CharT, Traits> s;
95 ss >> s; // no quote
96 return s;
97}
98
99template <class CharT, class Traits = std::char_traits<CharT>>
100std::basic_string<CharT, Traits> unquote ( const CharT *p, char delim='"', char escape='\\' ) {
101 std::basic_stringstream<CharT, Traits> ss;
102 ss << p;
103
104 CharT d(delim);
105 CharT e(escape);
106 std::basic_string<CharT, Traits> s;
107 ss >> std::quoted(s, d, e);
108 return s;
109}
110
111void test_padding () {
112 {
113 std::stringstream ss;
114 ss << std::left << std::setw(10) << std::setfill('!') << std::quoted(string: "abc", delim: '`');
115 assert ( ss.str() == "`abc`!!!!!" );
116 }
117
118 {
119 std::stringstream ss;
120 ss << std::right << std::setw(10) << std::setfill('!') << std::quoted(string: "abc", delim: '`');
121 assert ( ss.str() == "!!!!!`abc`" );
122 }
123}
124
125
126int main(int, char**)
127{
128 both_ways ( p: "" ); // This is a compilation check
129
130 round_trip ( p: "" );
131 round_trip_ws ( p: "" );
132 round_trip_d ( p: "", delim: 'q' );
133 round_trip_e ( p: "", escape: 'q' );
134
135#ifndef TEST_HAS_NO_WIDE_CHARACTERS
136 round_trip ( p: L"" );
137 round_trip_ws ( p: L"" );
138 round_trip_d ( p: L"", delim: 'q' );
139 round_trip_e ( p: L"", escape: 'q' );
140#endif
141
142 round_trip ( p: "Hi" );
143 round_trip_ws ( p: "Hi" );
144 round_trip_d ( p: "Hi", delim: '!' );
145 round_trip_e ( p: "Hi", escape: '!' );
146 assert ( quote ( "Hi", '!' ) == "!Hi!" );
147 assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
148
149#ifndef TEST_HAS_NO_WIDE_CHARACTERS
150 round_trip ( p: L"Hi" );
151 round_trip_ws ( p: L"Hi" );
152 round_trip_d ( p: L"Hi", delim: '!' );
153 round_trip_e ( p: L"Hi", escape: '!' );
154 assert ( quote ( L"Hi", '!' ) == L"!Hi!" );
155 assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
156#endif
157
158 round_trip ( p: "Hi Mom" );
159 round_trip_ws ( p: "Hi Mom" );
160#ifndef TEST_HAS_NO_WIDE_CHARACTERS
161 round_trip ( p: L"Hi Mom" );
162 round_trip_ws ( p: L"Hi Mom" );
163#endif
164
165 assert ( quote ( "" ) == "\"\"" );
166 assert ( quote ( "a" ) == "\"a\"" );
167#ifndef TEST_HAS_NO_WIDE_CHARACTERS
168 assert ( quote ( L"" ) == L"\"\"" );
169 assert ( quote ( L"a" ) == L"\"a\"" );
170#endif
171
172 // missing end quote - must not hang
173 assert ( unquote ( "\"abc" ) == "abc" );
174#ifndef TEST_HAS_NO_WIDE_CHARACTERS
175 assert ( unquote ( L"\"abc" ) == L"abc" );
176#endif
177
178 assert ( unquote ( "abc" ) == "abc" ); // no delimiter
179 assert ( unquote ( "abc def" ) == "abc" ); // no delimiter
180#ifndef TEST_HAS_NO_WIDE_CHARACTERS
181 assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
182 assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
183#endif
184
185 assert ( unquote ( "" ) == "" ); // nothing there
186#ifndef TEST_HAS_NO_WIDE_CHARACTERS
187 assert ( unquote ( L"" ) == L"" ); // nothing there
188#endif
189
190 test_padding ();
191
192 return 0;
193}
194

source code of libcxx/test/std/input.output/iostream.format/quoted.manip/quoted.pass.cpp