More spring-cleaning.
[dragonfly.git] / contrib / libio / tests / tiomisc.cc
1 /* Random regression tests etc. */
2
3 #include <fstream.h>
4 #include <stdio.h>
5 #include <strstream.h>
6 #include <string.h>
7 #include <fcntl.h>
8 #include <stdlib.h>
9 #include <assert.h>
10
11 #define BUF_SIZE 4096
12
13 void
14 test1 ()
15 {
16    fstream f;
17    char    buf[BUF_SIZE];
18
19    f.setbuf( buf, BUF_SIZE );
20 }
21
22 void
23 test2 ( )
24 {
25    char string[BUF_SIZE];
26    ostrstream s( string, BUF_SIZE );
27
28    s << "Bla bla bla " << 55 << ' ' << 3.23 << '\0' << endl;
29    cout << "Test2: " << string << endl;
30 }
31
32 \f
33 /* Test case from Joe Buck <jbuck@Synopsys.COM>. */
34
35 class special_ofstream : public ofstream {
36 public:
37         special_ofstream() : ofstream() {}
38         special_ofstream(int fd) : ofstream(fd) {}
39         special_ofstream(const char *name, int mode=ios::out, int prot=0664) {
40                 open(name,mode,prot);
41         }
42         void open(const char *name, int mode=ios::out, int prot=0664);
43 };
44
45 void special_ofstream::open(const char* name, int mode, int prot) {
46         if (strcmp(name, "<cout>") == 0) {
47                 rdbuf()->attach(1);
48         }
49         else if (strcmp(name, "<cerr>") == 0) {
50                 rdbuf()->attach(2);
51                 setf(unitbuf);
52         }
53         else ofstream::open(name,mode,prot);
54 }
55
56 void
57 test3 ()
58 {
59         {
60                 special_ofstream o("<cout>");
61                 o << "Hello\n";
62                 // o is destructed now.  This should not close cout
63         }
64         {
65                 special_ofstream o("<cout>");
66                 o << "Line 2\n";
67         }
68 }
69
70 void
71 getline_test1 ()
72 {
73   char buf[1000];
74   char data[] = "#include <iostream.h>\n#include <fstream.h>\n";
75   istrstream infile(data, strlen(data));
76   infile.getline(buf,1000);
77   infile.getline(buf,1000);
78
79   cout << buf << '\n';
80 }
81
82 // test istream::getline on readng overlong lines.
83 void
84 getline_test2 ()
85 {
86   char data[] = "Line one.\nline 2.\n";
87   char line[100];
88   istrstream strin(data, strlen(data));
89   strin.getline(line, 10);
90   cout << "line: " << line << ", count: " << strin.gcount () << "\n";
91 }
92
93 void
94 getline_test3 ()
95 {
96   char data[] = "123456789\nabcdefghijkl.\n";
97   char line[10];
98   istrstream strin(data, strlen(data));
99   strin.getline(line, 10);
100   cout << "line: " << line << ", count: " << strin.gcount () << "\n";
101   strin.getline(line, 10);
102   cout << "line: " << line << ", count: " << strin.gcount () << "\n";
103   assert (!strin.good());
104   strin.clear ();
105   strin.getline(line, 10);
106   cout << "line: " << line << ", count: " << strin.gcount () << "\n";
107 }
108
109 class A : private ostream
110 {
111 public:
112   A(streambuf* s);
113   ostream::flush;
114 };
115 A::A(streambuf* s)
116 : ostream(s)
117 {
118 }
119
120 void
121 flush1_test()
122 {
123   A os(cout.rdbuf());
124   os.flush();
125 }
126
127 void
128 reread_test ()
129 {  // This is PR 5486.
130    int tag_char;
131    char *fname = "Makefile";
132    int mode = O_RDONLY;
133    filebuf file_p; 
134
135    int fd = ::open(fname, mode, 0666);
136    file_p.attach(fd); 
137
138    istream d_istream(&file_p);
139
140    // Read a character from the stream, save it and put it back.
141    tag_char = d_istream.get();
142    int save_char = tag_char;
143    d_istream.putback((char) tag_char);
144
145    // Uncomment then next statement and the next get will be EOF.
146    streampos pos = d_istream.tellg();  
147
148    // Re-read the first character
149    tag_char = d_istream.get();
150
151    cout << "reread_test: " << (char)save_char << " " << (char)tag_char << "\n";
152    cout.flush();
153
154 }
155 \f
156 void *danger_pointer;
157 void operator delete (void *p) throw()
158 {
159   if (p)
160     {
161       if (p == danger_pointer)
162         fprintf (stderr, "maybe deleted\n");
163
164       free (p);
165     }
166 }
167
168 struct my_ostream: virtual public ios, public ostream
169 {
170   my_ostream (ostream &s): ios (s.rdbuf()) { }
171 };
172
173 void
174 test_destroy ()
175 {
176   ofstream fstr ("foo.dat");
177   my_ostream wa (fstr);
178
179   /* Check that sure wa.rdbuf() is only freed once. */
180   danger_pointer = wa.rdbuf ();
181
182   wa << "Hi there" << endl;
183 #ifdef _IO_NEW_STREAMS
184   fprintf (stderr, "maybe deleted\n");
185 #endif
186 }
187 \f
188 /* Submitted by Luke Blanshard <luke@cs.wisc.edu>.
189
190    In certain circumstances, the library will write past the end of the
191    buffer it has allocated for a file:  You must read from the file,
192    exactly enough bytes that the read pointer is at the end of the
193    buffer.  Then you must write to the file, at the same place you just
194    finished reading from.
195
196    "Your patch looks great, and you're welcome to use the test code for any  
197    purpose whatever.  I hereby renounce my implicit copyright on it."  */
198
199 void
200 test_read_write_flush ()
201 {
202     fstream f;
203     char buf[8192];
204
205     for ( int index=0; index < sizeof buf; ++index )
206         buf[index] = (index+1)&63? 'x' : '\n';
207
208     f.open( "foo.dat", ios::in|ios::out|ios::trunc );
209     f.write( buf, sizeof buf );
210
211     f.seekg( 0, ios::beg );
212     f.read( buf, sizeof buf );
213
214 //    f.seekp( sizeof buf, ios::beg );  // Present or absent, bug still happens.
215     f.write( "a", 1 );
216
217     if ( f.rdbuf()->_IO_write_ptr > f.rdbuf()->_IO_buf_end )
218         cerr << "test_read_write_flush: it's broken.\n";
219     else
220         cout << "test_read_write_flush: the problem isn't showing itself.\n";
221 }
222 \f
223 int main( )
224 {
225   test1 ();
226   test2 ();
227   test3 ();
228   getline_test1 ();
229   getline_test2 ();
230   getline_test3 ();
231   flush1_test ();
232   reread_test ();
233   test_destroy ();
234   test_read_write_flush ();
235   return 0;
236 }