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// In macosx10.9 to macosx10.14, streams are provided in the dylib AND they
10// have a bug in how they handle null-termination in case of errors (see D40677).
11// Requires 396145d in the built library.
12// XFAIL: using-built-library-before-llvm-9
13
14// <istream>
15
16// basic_istream<charT,traits>& getline(char_type* s, streamsize n, char_type delim);
17
18#include <istream>
19#include <cassert>
20#include <streambuf>
21
22#include "test_macros.h"
23
24template <class CharT>
25struct testbuf
26 : public std::basic_streambuf<CharT>
27{
28 typedef std::basic_string<CharT> string_type;
29 typedef std::basic_streambuf<CharT> base;
30private:
31 string_type str_;
32public:
33
34 testbuf() {}
35 testbuf(const string_type& str)
36 : str_(str)
37 {
38 base::setg(const_cast<CharT*>(str_.data()),
39 const_cast<CharT*>(str_.data()),
40 const_cast<CharT*>(str_.data()) + str_.size());
41 }
42
43 CharT* eback() const {return base::eback();}
44 CharT* gptr() const {return base::gptr();}
45 CharT* egptr() const {return base::egptr();}
46};
47
48int main(int, char**)
49{
50 {
51 testbuf<char> sb(" * * ");
52 std::istream is(&sb);
53 char s[5];
54 is.getline(s: s, n: 5, delim: '*');
55 assert(!is.eof());
56 assert(!is.fail());
57 assert(std::string(s) == " ");
58 assert(is.gcount() == 3);
59 is.getline(s: s, n: 5, delim: '*');
60 assert(!is.eof());
61 assert(!is.fail());
62 assert(std::string(s) == " ");
63 assert(is.gcount() == 5);
64 is.getline(s: s, n: 5, delim: '*');
65 assert( is.eof());
66 assert(!is.fail());
67 assert(std::string(s) == " ");
68 assert(is.gcount() == 1);
69 // Check that even in error case the buffer is properly 0-terminated.
70 is.getline(s: s, n: 5, delim: '*');
71 assert( is.eof());
72 assert( is.fail());
73 assert(std::string(s) == "");
74 assert(is.gcount() == 0);
75 }
76#ifndef TEST_HAS_NO_WIDE_CHARACTERS
77 {
78 testbuf<wchar_t> sb(L" * * ");
79 std::wistream is(&sb);
80 wchar_t s[5];
81 is.getline(s: s, n: 5, delim: L'*');
82 assert(!is.eof());
83 assert(!is.fail());
84 assert(std::wstring(s) == L" ");
85 assert(is.gcount() == 3);
86 is.getline(s: s, n: 5, delim: L'*');
87 assert(!is.eof());
88 assert(!is.fail());
89 assert(std::wstring(s) == L" ");
90 assert(is.gcount() == 5);
91 is.getline(s: s, n: 5, delim: L'*');
92 assert( is.eof());
93 assert(!is.fail());
94 assert(std::wstring(s) == L" ");
95 assert(is.gcount() == 1);
96 // Check that even in error case the buffer is properly 0-terminated.
97 is.getline(s: s, n: 5, delim: L'*');
98 assert( is.eof());
99 assert( is.fail());
100 assert(std::wstring(s) == L"");
101 assert(is.gcount() == 0);
102 }
103#endif
104#ifndef TEST_HAS_NO_EXCEPTIONS
105 {
106 testbuf<char> sb(" ");
107 std::basic_istream<char> is(&sb);
108 char s[5] = "test";
109 is.exceptions(std::ios_base::eofbit);
110 bool threw = false;
111 try {
112 is.getline(s, 5, '*');
113 } catch (std::ios_base::failure&) {
114 threw = true;
115 }
116 assert(!is.bad());
117 assert( is.eof());
118 assert(!is.fail());
119 assert(threw);
120 assert(std::basic_string<char>(s) == " ");
121 assert(is.gcount() == 1);
122 }
123#ifndef TEST_HAS_NO_WIDE_CHARACTERS
124 {
125 testbuf<wchar_t> sb(L" ");
126 std::basic_istream<wchar_t> is(&sb);
127 wchar_t s[5] = L"test";
128 is.exceptions(std::ios_base::eofbit);
129 bool threw = false;
130 try {
131 is.getline(s, 5, L'*');
132 } catch (std::ios_base::failure&) {
133 threw = true;
134 }
135 assert(!is.bad());
136 assert( is.eof());
137 assert(!is.fail());
138 assert(threw);
139 assert(std::basic_string<wchar_t>(s) == L" ");
140 assert(is.gcount() == 1);
141 }
142#endif
143
144 {
145 testbuf<char> sb;
146 std::basic_istream<char> is(&sb);
147 char s[5] = "test";
148 is.exceptions(std::ios_base::eofbit);
149 bool threw = false;
150 try {
151 is.getline(s, 5, '*');
152 } catch (std::ios_base::failure&) {
153 threw = true;
154 }
155 assert(!is.bad());
156 assert( is.eof());
157 assert( is.fail());
158 assert(threw);
159 assert(std::basic_string<char>(s) == "");
160 assert(is.gcount() == 0);
161 }
162#ifndef TEST_HAS_NO_WIDE_CHARACTERS
163 {
164 testbuf<wchar_t> sb;
165 std::basic_istream<wchar_t> is(&sb);
166 wchar_t s[5] = L"test";
167 is.exceptions(std::ios_base::eofbit);
168 bool threw = false;
169 try {
170 is.getline(s, 5, L'*');
171 } catch (std::ios_base::failure&) {
172 threw = true;
173 }
174 assert(!is.bad());
175 assert( is.eof());
176 assert( is.fail());
177 assert(threw);
178 assert(std::basic_string<wchar_t>(s) == L"");
179 assert(is.gcount() == 0);
180 }
181#endif
182#endif // TEST_HAS_NO_EXCEPTIONS
183
184 return 0;
185}
186

source code of libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp