15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier
931cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11
10bb6d61c7SLouis Dionne
115a83710eSEric Fiselier // <iomanip>
125a83710eSEric Fiselier
135a83710eSEric Fiselier // quoted
145a83710eSEric Fiselier
155a83710eSEric Fiselier #include <iomanip>
165a83710eSEric Fiselier #include <sstream>
175a83710eSEric Fiselier #include <string>
185a83710eSEric Fiselier #include <cassert>
195a83710eSEric Fiselier
207fc6a556SMarshall Clow #include "test_macros.h"
217fc6a556SMarshall Clow
22d77ed5a1SMarshall Clow template <class CharT, class Traits>
is_skipws(const std::basic_istream<CharT,Traits> & is)23d77ed5a1SMarshall Clow bool is_skipws ( const std::basic_istream<CharT, Traits>& is ) {
24d77ed5a1SMarshall Clow return ( is.flags() & std::ios_base::skipws ) != 0;
255a83710eSEric Fiselier }
265a83710eSEric Fiselier
27d77ed5a1SMarshall Clow template <class CharT, class Traits = std::char_traits<CharT>>
both_ways(const CharT * p)28d77ed5a1SMarshall Clow void both_ways ( const CharT *p ) {
29d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> str(p);
305a83710eSEric Fiselier auto q = std::quoted(str);
315a83710eSEric Fiselier
32d77ed5a1SMarshall Clow std::basic_stringstream<CharT, Traits> ss;
33d77ed5a1SMarshall Clow bool skippingws = is_skipws ( ss );
344dc0ed83SStephan T. Lavavej ((void)skippingws); // Prevent unused warning
355a83710eSEric Fiselier ss << q;
365a83710eSEric Fiselier ss >> q;
375a83710eSEric Fiselier }
385a83710eSEric Fiselier
39d77ed5a1SMarshall Clow template <class CharT, class Traits = std::char_traits<CharT>>
round_trip(const CharT * p)40d77ed5a1SMarshall Clow void round_trip ( const CharT *p ) {
41d77ed5a1SMarshall Clow std::basic_stringstream<CharT, Traits> ss;
42d77ed5a1SMarshall Clow bool skippingws = is_skipws ( ss );
43d77ed5a1SMarshall Clow
445a83710eSEric Fiselier ss << std::quoted(p);
45d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> s;
465a83710eSEric Fiselier ss >> std::quoted(s);
475a83710eSEric Fiselier assert ( s == p );
48d77ed5a1SMarshall Clow assert ( skippingws == is_skipws ( ss ));
495a83710eSEric Fiselier }
505a83710eSEric Fiselier
51d77ed5a1SMarshall Clow
52d77ed5a1SMarshall Clow template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_ws(const CharT * p)53d77ed5a1SMarshall Clow void round_trip_ws ( const CharT *p ) {
54d77ed5a1SMarshall Clow std::basic_stringstream<CharT, Traits> ss;
555a83710eSEric Fiselier std::noskipws ( ss );
56d77ed5a1SMarshall Clow bool skippingws = is_skipws ( ss );
57d77ed5a1SMarshall Clow
585a83710eSEric Fiselier ss << std::quoted(p);
59d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> s;
605a83710eSEric Fiselier ss >> std::quoted(s);
615a83710eSEric Fiselier assert ( s == p );
62d77ed5a1SMarshall Clow assert ( skippingws == is_skipws ( ss ));
635a83710eSEric Fiselier }
645a83710eSEric Fiselier
65d77ed5a1SMarshall Clow template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_d(const CharT * p,char delim)66d77ed5a1SMarshall Clow void round_trip_d ( const CharT *p, char delim ) {
67d77ed5a1SMarshall Clow std::basic_stringstream<CharT, Traits> ss;
6895b5ac7dSEric Fiselier CharT d(delim);
69d77ed5a1SMarshall Clow
70d77ed5a1SMarshall Clow ss << std::quoted(p, d);
71d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> s;
72d77ed5a1SMarshall Clow ss >> std::quoted(s, d);
735a83710eSEric Fiselier assert ( s == p );
745a83710eSEric Fiselier }
755a83710eSEric Fiselier
76d77ed5a1SMarshall Clow template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_e(const CharT * p,char escape)77d77ed5a1SMarshall Clow void round_trip_e ( const CharT *p, char escape ) {
78d77ed5a1SMarshall Clow std::basic_stringstream<CharT, Traits> ss;
7995b5ac7dSEric Fiselier CharT e(escape);
80d77ed5a1SMarshall Clow
81d77ed5a1SMarshall Clow ss << std::quoted(p, CharT('"'), e );
82d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> s;
83d77ed5a1SMarshall Clow ss >> std::quoted(s, CharT('"'), e );
845a83710eSEric Fiselier assert ( s == p );
855a83710eSEric Fiselier }
865a83710eSEric Fiselier
875a83710eSEric Fiselier
88d77ed5a1SMarshall Clow template <class CharT, class Traits = std::char_traits<CharT>>
quote(const CharT * p,char delim='"',char escape='\\\\')89d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> quote ( const CharT *p, char delim='"', char escape='\\' ) {
90d77ed5a1SMarshall Clow std::basic_stringstream<CharT, Traits> ss;
9195b5ac7dSEric Fiselier CharT d(delim);
9295b5ac7dSEric Fiselier CharT e(escape);
93d77ed5a1SMarshall Clow ss << std::quoted(p, d, e);
94d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> s;
955a83710eSEric Fiselier ss >> s; // no quote
965a83710eSEric Fiselier return s;
975a83710eSEric Fiselier }
985a83710eSEric Fiselier
99d77ed5a1SMarshall Clow template <class CharT, class Traits = std::char_traits<CharT>>
unquote(const CharT * p,char delim='"',char escape='\\\\')100d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> unquote ( const CharT *p, char delim='"', char escape='\\' ) {
101d77ed5a1SMarshall Clow std::basic_stringstream<CharT, Traits> ss;
1025a83710eSEric Fiselier ss << p;
103d77ed5a1SMarshall Clow
10495b5ac7dSEric Fiselier CharT d(delim);
10595b5ac7dSEric Fiselier CharT e(escape);
106d77ed5a1SMarshall Clow std::basic_string<CharT, Traits> s;
107d77ed5a1SMarshall Clow ss >> std::quoted(s, d, e);
1085a83710eSEric Fiselier return s;
1095a83710eSEric Fiselier }
1105a83710eSEric Fiselier
test_padding()1115a83710eSEric Fiselier void test_padding () {
1125a83710eSEric Fiselier {
1135a83710eSEric Fiselier std::stringstream ss;
1145a83710eSEric Fiselier ss << std::left << std::setw(10) << std::setfill('!') << std::quoted("abc", '`');
1155a83710eSEric Fiselier assert ( ss.str() == "`abc`!!!!!" );
1165a83710eSEric Fiselier }
1175a83710eSEric Fiselier
1185a83710eSEric Fiselier {
1195a83710eSEric Fiselier std::stringstream ss;
1205a83710eSEric Fiselier ss << std::right << std::setw(10) << std::setfill('!') << std::quoted("abc", '`');
1215a83710eSEric Fiselier assert ( ss.str() == "!!!!!`abc`" );
1225a83710eSEric Fiselier }
1235a83710eSEric Fiselier }
1245a83710eSEric Fiselier
1255a83710eSEric Fiselier
main(int,char **)1262df59c50SJF Bastien int main(int, char**)
1275a83710eSEric Fiselier {
1285a83710eSEric Fiselier both_ways ( "" ); // This is a compilation check
1295a83710eSEric Fiselier
1305a83710eSEric Fiselier round_trip ( "" );
1315a83710eSEric Fiselier round_trip_ws ( "" );
1325a83710eSEric Fiselier round_trip_d ( "", 'q' );
1335a83710eSEric Fiselier round_trip_e ( "", 'q' );
1345a83710eSEric Fiselier
135*f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1365a83710eSEric Fiselier round_trip ( L"" );
1375a83710eSEric Fiselier round_trip_ws ( L"" );
1385a83710eSEric Fiselier round_trip_d ( L"", 'q' );
1395a83710eSEric Fiselier round_trip_e ( L"", 'q' );
140*f4c1258dSLouis Dionne #endif
1415a83710eSEric Fiselier
1425a83710eSEric Fiselier round_trip ( "Hi" );
1435a83710eSEric Fiselier round_trip_ws ( "Hi" );
1445a83710eSEric Fiselier round_trip_d ( "Hi", '!' );
1455a83710eSEric Fiselier round_trip_e ( "Hi", '!' );
1465a83710eSEric Fiselier assert ( quote ( "Hi", '!' ) == "!Hi!" );
1475a83710eSEric Fiselier assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
1485a83710eSEric Fiselier
149*f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1505a83710eSEric Fiselier round_trip ( L"Hi" );
1515a83710eSEric Fiselier round_trip_ws ( L"Hi" );
1525a83710eSEric Fiselier round_trip_d ( L"Hi", '!' );
1535a83710eSEric Fiselier round_trip_e ( L"Hi", '!' );
1545a83710eSEric Fiselier assert ( quote ( L"Hi", '!' ) == L"!Hi!" );
1555a83710eSEric Fiselier assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
156*f4c1258dSLouis Dionne #endif
1575a83710eSEric Fiselier
1585a83710eSEric Fiselier round_trip ( "Hi Mom" );
1595a83710eSEric Fiselier round_trip_ws ( "Hi Mom" );
160*f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1615a83710eSEric Fiselier round_trip ( L"Hi Mom" );
1625a83710eSEric Fiselier round_trip_ws ( L"Hi Mom" );
163*f4c1258dSLouis Dionne #endif
1645a83710eSEric Fiselier
1655a83710eSEric Fiselier assert ( quote ( "" ) == "\"\"" );
1665a83710eSEric Fiselier assert ( quote ( "a" ) == "\"a\"" );
167*f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
168*f4c1258dSLouis Dionne assert ( quote ( L"" ) == L"\"\"" );
1695a83710eSEric Fiselier assert ( quote ( L"a" ) == L"\"a\"" );
170*f4c1258dSLouis Dionne #endif
1715a83710eSEric Fiselier
1725a83710eSEric Fiselier // missing end quote - must not hang
1735a83710eSEric Fiselier assert ( unquote ( "\"abc" ) == "abc" );
174*f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1755a83710eSEric Fiselier assert ( unquote ( L"\"abc" ) == L"abc" );
176*f4c1258dSLouis Dionne #endif
1775a83710eSEric Fiselier
1785a83710eSEric Fiselier assert ( unquote ( "abc" ) == "abc" ); // no delimiter
1795a83710eSEric Fiselier assert ( unquote ( "abc def" ) == "abc" ); // no delimiter
180*f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
181*f4c1258dSLouis Dionne assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
1825a83710eSEric Fiselier assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
183*f4c1258dSLouis Dionne #endif
1845a83710eSEric Fiselier
1855a83710eSEric Fiselier assert ( unquote ( "" ) == "" ); // nothing there
186*f4c1258dSLouis Dionne #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1875a83710eSEric Fiselier assert ( unquote ( L"" ) == L"" ); // nothing there
188*f4c1258dSLouis Dionne #endif
189*f4c1258dSLouis Dionne
1905a83710eSEric Fiselier test_padding ();
1912df59c50SJF Bastien
1922df59c50SJF Bastien return 0;
1935a83710eSEric Fiselier }
194