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
22 template <class CharT, class Traits>
is_skipws(const std::basic_istream<CharT,Traits> & is)23 bool is_skipws ( const std::basic_istream<CharT, Traits>& is ) {
24 return ( is.flags() & std::ios_base::skipws ) != 0;
25 }
26
27 template <class CharT, class Traits = std::char_traits<CharT>>
both_ways(const CharT * p)28 void 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
39 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip(const CharT * p)40 void 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
52 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_ws(const CharT * p)53 void round_trip_ws ( const CharT *p ) {
54 std::basic_stringstream<CharT, Traits> ss;
55 std::noskipws ( 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
65 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_d(const CharT * p,char delim)66 void 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
76 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_e(const CharT * p,char escape)77 void 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
88 template <class CharT, class Traits = std::char_traits<CharT>>
quote(const CharT * p,char delim='"',char escape='\\\\')89 std::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
99 template <class CharT, class Traits = std::char_traits<CharT>>
unquote(const CharT * p,char delim='"',char escape='\\\\')100 std::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
test_padding()111 void test_padding () {
112 {
113 std::stringstream ss;
114 ss << std::left << std::setw(10) << std::setfill('!') << std::quoted("abc", '`');
115 assert ( ss.str() == "`abc`!!!!!" );
116 }
117
118 {
119 std::stringstream ss;
120 ss << std::right << std::setw(10) << std::setfill('!') << std::quoted("abc", '`');
121 assert ( ss.str() == "!!!!!`abc`" );
122 }
123 }
124
125
main(int,char **)126 int main(int, char**)
127 {
128 both_ways ( "" ); // This is a compilation check
129
130 round_trip ( "" );
131 round_trip_ws ( "" );
132 round_trip_d ( "", 'q' );
133 round_trip_e ( "", 'q' );
134
135 round_trip ( L"" );
136 round_trip_ws ( L"" );
137 round_trip_d ( L"", 'q' );
138 round_trip_e ( L"", 'q' );
139
140 round_trip ( "Hi" );
141 round_trip_ws ( "Hi" );
142 round_trip_d ( "Hi", '!' );
143 round_trip_e ( "Hi", '!' );
144 assert ( quote ( "Hi", '!' ) == "!Hi!" );
145 assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
146
147 round_trip ( L"Hi" );
148 round_trip_ws ( L"Hi" );
149 round_trip_d ( L"Hi", '!' );
150 round_trip_e ( L"Hi", '!' );
151 assert ( quote ( L"Hi", '!' ) == L"!Hi!" );
152 assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
153
154 round_trip ( "Hi Mom" );
155 round_trip_ws ( "Hi Mom" );
156 round_trip ( L"Hi Mom" );
157 round_trip_ws ( L"Hi Mom" );
158
159 assert ( quote ( "" ) == "\"\"" );
160 assert ( quote ( L"" ) == L"\"\"" );
161 assert ( quote ( "a" ) == "\"a\"" );
162 assert ( quote ( L"a" ) == L"\"a\"" );
163
164 // missing end quote - must not hang
165 assert ( unquote ( "\"abc" ) == "abc" );
166 assert ( unquote ( L"\"abc" ) == L"abc" );
167
168 assert ( unquote ( "abc" ) == "abc" ); // no delimiter
169 assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
170 assert ( unquote ( "abc def" ) == "abc" ); // no delimiter
171 assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
172
173 assert ( unquote ( "" ) == "" ); // nothing there
174 assert ( unquote ( L"" ) == L"" ); // nothing there
175 test_padding ();
176
177 return 0;
178 }
179