Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / libio / tests / tFile.cc
1 /* 
2 Copyright (C) 1993 Free Software Foundation
3
4 This file is part of the GNU IO Library.  This library is free
5 software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING.  If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does not cause
21 the resulting executable to be covered by the GNU General Public License.
22 This exception does not however invalidate any other reasons why
23 the executable file might be covered by the GNU General Public License. */
24
25 // This may look like C code, but it is really -*- C++ -*-
26
27 /*
28  * a few tests for streams
29  *
30  */
31
32 #include <stream.h>
33 #include <fstream.h>
34 #ifndef _OLD_STREAMS
35 #include <strstream.h>
36 #include "unistd.h"
37 #endif
38 #include <SFile.h>
39 #include <PlotFile.h>
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <assert.h>
45
46 const char *tempfile;
47
48 class record
49 {
50 public:
51   char c; int i; double d;
52 };
53
54 ostream& operator<<(ostream& s, record& r)
55 {
56   return(s << "(i = " << r.i << " c = " << r.c << " d = " << r.d << ")");
57 }
58
59 void t1()
60 {
61   char ch;
62
63   assert(cout.good());
64   assert(cout.writable());
65   assert(cout.is_open());
66   cout << "Hello, world via cout\n";
67   assert(cerr.good());
68   assert(cerr.writable());
69   assert(cerr.is_open());
70   cerr << "Hello, world via cerr\n";
71
72   assert(cin.good());
73   assert(cin.readable());
74   assert(cin.is_open());
75
76   cout << "enter a char:";  cin >> ch;
77   cout.put('c');  cout.put(' ');  cout.put('=');  cout.put(' ');
78   cout.put('"');  cout.put(ch);    cout << '"';  cout << char('\n');
79   assert(cin.good());
80   assert(cout.good());
81 }
82
83 void t2()
84 {
85   int i;
86   short h;
87   long l;
88   float f;
89   double d;
90   char s[100];
91
92   cout << "enter three integers (short, int, long):";  
93   cin >> h; cin >> i;   
94   // cin.scan("%ld", &l);
95   cin >> l;
96   cout << "first  = " << h << " via dec = " << dec(h, 8) << "\n";
97   cout << "second = " << i << form(" via form = %d = 0%o", i, i);
98   cout.form(" via cout.form = %d = 0x%x\n", i, i);
99   cout << "third  = " << l  << " via hex = " << hex(l) << "\n";
100   assert(cin.good());
101   assert(cout.good());
102
103   cout << "enter a float then a double:";  cin >> f; cin >> d;
104   cout << "first  = " << f << "\n";
105   cout << "second = " << d << "\n";
106   assert(cin.good());
107   assert(cout.good());
108
109   cout << "enter 5 characters separated with spaces:";  cin >> s;
110   cout << "first  = " << s << "\n";
111   cin.get(s, 100);
112   cout << "rest   = " << s << "\n";
113
114   assert(cin.good());
115
116   cin.width(10);
117   cin >> s;
118   cin.clear();
119   cout << "A 10-character buffer: " << s << endl;
120
121   assert(cout.good());
122
123 }
124
125 void t3()
126 {
127   char ch;
128   cout << "\nMaking streams sout and sin...";
129 #ifdef _OLD_STREAMS
130   ostream sout("streamfile", io_writeonly, a_create);
131 #else
132   ofstream sout("streamfile");
133 #endif
134   assert(sout.good());
135   assert(sout.is_open());
136   assert(sout.writable());
137   assert(!sout.readable());
138   sout << "This file has one line testing output streams.\n";
139   sout.close();
140   assert(!sout.is_open());
141 #ifdef _OLD_STREAMS
142   istream sin("streamfile", io_readonly, a_useonly);
143 #else
144   ifstream sin("streamfile");
145 #endif
146   assert(sin.good());
147   assert(sin.is_open());
148   assert(!sin.writable());
149   assert(sin.readable());
150   cout << "contents of file:\n";
151   while(sin >> ch) cout << ch;
152   sin.close();
153   assert(!sin.is_open());
154 }
155
156
157 void t4()
158 {
159   char s[100];
160   char ch;
161   int i;
162
163   cout << "\nMaking File tf ... "; 
164 #ifdef _OLD_STREAMS
165   File tf(tempfile, io_readwrite, a_create);
166 #else
167   fstream tf(tempfile, ios::in|ios::out|ios::trunc);
168 #endif
169   assert(tf.good());
170   assert(tf.is_open());
171   assert(tf.writable());
172   assert(tf.readable());
173   strcpy(s, "This is the first and only line of this file.\n");
174 #ifdef _OLD_STREAMS
175   tf.put(s);
176   tf.seek(0);
177 #else
178   tf << s;
179   tf.rdbuf()->seekoff(0, ios::beg);
180 #endif
181   tf.get(s, 100);
182   assert(tf.good());
183   cout << "first line of file:\n" << s << "\n";
184   cout << "next char = ";
185   tf.get(ch);
186   cout << (int)ch;
187   cout.put('\n');
188   assert(ch == 10);
189   strcpy(s, "Now there is a second line.\n");
190   cout << "reopening tempfile, appending: " << s;
191 #ifdef _OLD_STREAMS
192   tf.open(tf.name(), io_appendonly, a_use);
193 #else
194   tf.close();
195   tf.open(tempfile, ios::app);
196 #endif
197   assert(tf.good());
198   assert(tf.is_open());
199   assert(tf.writable());
200   assert(!tf.readable());
201 #ifdef _OLD_STREAMS
202   tf.put(s);
203   assert(tf.good());
204   tf.open(tf.name(), io_readonly, a_use);
205 #else
206   tf << s;
207   assert(tf.good());
208   tf.close();
209   tf.open(tempfile, ios::in);
210 #endif
211   tf.raw();
212   assert(tf.good());
213   assert(tf.is_open());
214   assert(!tf.writable());
215   assert(tf.readable());
216   cout << "First 10 chars via raw system read after reopen for input:\n";
217   read(tf.filedesc(), s, 10);
218   assert(tf.good());
219   for (i = 0; i < 10; ++ i)
220     cout.put(s[i]);
221   lseek(tf.filedesc(), 5, 0);
222   cout << "\nContents after raw lseek to pos 5:\n";
223   while ( (tf.get(ch)) && (cout.put(ch)) );
224 #ifdef _OLD_STREAMS
225   tf.remove();
226 #else
227   tf.close();
228   unlink((char*)tempfile);
229 #endif
230   assert(!tf.is_open());
231 }
232
233 void t5()
234 {
235   record r;
236   int i;
237   cout << "\nMaking SFile rf...";
238 #ifdef _OLD_STREAMS
239   SFile rf("recfile", sizeof(record), io_readwrite, a_create);
240 #else
241   SFile rf("recfile", sizeof(record), ios::in|ios::out|ios::trunc);
242 #endif
243   assert(rf.good());
244   assert(rf.is_open());
245   assert(rf.writable());
246   assert(rf.readable());
247   for (i = 0; i < 10; ++i)
248   {
249     r.c = i + 'a';
250     r.i = i;
251     r.d = (double)(i) / 1000.0;
252     rf.put(&r);
253   }
254   assert(rf.good());
255   cout << "odd elements of file in reverse order:\n";
256   for (i = 9; i >= 0; i -= 2)
257   {
258     rf[i].get(&r);
259     assert(r.c == i + 'a');
260     assert(r.i == i);
261     cout << r << "\n";
262   }
263   assert(rf.good());
264 #ifdef _OLD_STREAMS
265   rf.remove();
266 #else
267   rf.close();
268   unlink("recfile");
269 #endif
270   assert(!rf.is_open());
271 }
272
273 void t6()
274 {
275   cout << "\nMaking PlotFile pf ...";
276   static const char plot_name[] = "plot.out";
277   PlotFile pf(plot_name);
278   assert(pf.good());
279   assert(pf.is_open());
280   assert(pf.writable());
281   assert(!pf.readable());
282   pf.move(10,10);
283   pf.label("Test");
284   pf.circle(300,300,200);
285   pf.line(100, 100, 500, 500);
286   assert(pf.good());
287 #ifdef _OLD_STREAMS
288   cout << "(You may delete or attempt to plot " << pf.name() << ")\n";
289 #else
290   cout << "(You may delete or attempt to plot " << plot_name << ")\n";
291 #endif
292 }
293
294 void t7()
295 {
296   char ch;
297   static char t7_line1[] = "This is a string-based stream.\n";
298   static char t7_line2[] = "With two lines.\n";
299   char mybuf[60];
300   char *bufp;
301 #ifdef _OLD_STREAMS
302   cout << "creating string-based ostream...\n";
303   ostream strout(60, mybuf);
304 #else
305   cout << "creating ostrstream...\n";
306   ostrstream strout(mybuf, 60);
307 #endif
308   assert(strout.good());
309   assert(strout.writable());
310   strout << t7_line1 << t7_line2 << ends;
311   assert(strout.good());
312   cout << "with contents:\n";
313   bufp = strout.str();
314   assert(bufp == mybuf);
315   strout.rdbuf()->freeze(0); /* Should be a no-op */
316   cout << mybuf;
317 #ifdef _OLD_STREAMS
318   cout << "using it to create string-based istream...\n";
319   istream strin(strlen(mybuf), mybuf);
320 #else
321   cout << "using it to create istrstream...\n";
322   istrstream strin(mybuf, strlen(mybuf));
323 #endif
324   assert(strin.good());
325   assert(strin.readable());
326   cout << "with contents:\n";
327 #ifndef _OLD_STREAMS
328   char line[100];
329   strin.getline(line, 100);
330   int line1_len = strlen(t7_line1);
331   assert(strin.tellg() == line1_len);
332   int line_len = strin.gcount();
333   assert(line_len == line1_len);
334   cout.write(line, line1_len - 1);
335   cout << endl;
336 #endif
337   while (strin.get(ch)) cout.put(ch);
338
339   strstream str1;
340   strstream str2;
341   str1 << "Testing string-based stream using strstream.\n";
342   str1.seekg(0);
343   for (;;) {
344       int i = str1.get();
345       if (i == EOF)
346           break;
347       str2 << (char)i;
348   }
349   str2 << ends;
350   cout << str2.str();
351
352   // This should make it overflow.
353   strout << t7_line1;
354   assert (strout.bad());
355 }
356
357 void t8()
358 {
359 #ifdef _OLD_STREAMS
360   cout << "\nThe following file open should generate error message:";
361   cout.flush();
362   File ef("shouldnotexist", io_readonly, a_useonly);
363 #else
364   ifstream ef("shouldnotexist");
365 #endif
366   assert(!ef.good());
367   assert(!ef.is_open());
368 }
369
370 void t9()
371 {
372   char ch;
373   static char ffile_name[] = "ftmp";
374   {
375       cout << "\nMaking filebuf streams fout and fin...";
376       filebuf foutbuf;
377 #ifdef _OLD_STREAMS
378       foutbuf.open(ffile_name, output);
379 #else
380       foutbuf.open(ffile_name, ios::out);
381 #endif
382       ostream fout(&foutbuf);
383       assert(fout.good());
384       assert(fout.is_open());
385       assert(fout.writable());
386       assert(!fout.readable());
387       fout << "This file has one line testing output streams.\n";
388 #ifdef _OLD_STREAMS
389       fout.close();
390       assert(!fout.is_open());
391 #endif
392   }
393   filebuf finbuf;
394 #ifdef _OLD_STREAMS
395   finbuf.open(ffile_name, input);
396 #else
397   finbuf.open(ffile_name, ios::in);
398 #endif
399   istream fin(&finbuf);
400   assert(fin.good());
401   assert(fin.is_open());
402   assert(!fin.writable());
403   assert(fin.readable());
404   cout << "contents of file:\n";
405   while(fin >> ch) cout << ch;
406 #ifndef _OLD_STREAMS
407   cout << '\n';
408 #endif
409   fin.close();
410   assert(!fin.is_open());
411 }
412
413 void t10()
414 {
415     int fileCnt = 3;
416     char *file_name_pattern = "ftmp%d";
417     char current_file_name[50];
418     ifstream inFile;
419     ofstream outFile;
420     char c;
421     int i;
422     
423     cout << '\n';
424
425     // Write some files.
426     for (i=0; i < fileCnt; i++)   {
427         sprintf(current_file_name, file_name_pattern, i);
428         outFile.open(current_file_name, ios::out);
429                 
430         if ( outFile.fail() )
431             cerr << "File " << current_file_name
432                 << " can't be opened for output" << endl;
433         else {
434             outFile << "This is line 1 of " << current_file_name << '\n';
435             outFile << "This is line 2 of " << current_file_name << endl;
436             outFile.close();
437         }
438     }
439
440     // Now read the files back in, and write then out to cout.
441     for (i=0; i < fileCnt; i++)   {
442         sprintf(current_file_name, file_name_pattern, i);
443         inFile.open(current_file_name, ios::in);
444                 
445
446         if ( inFile.fail() )
447             cerr << "File " << current_file_name 
448                 << " can't be opened for input" << endl;
449         else {
450             while ( inFile.get (c))
451                 cout << c;
452             cout << endl;
453             inFile.close();
454         }
455     }
456 }
457
458 // Test form
459
460 void t11()
461 {
462     int count1, count2;
463     cout.form("%.2f+%.2f = %4.3e\n%n", 5.5, 6.25, 5.5+6.25, &count1);
464     char *text = "Previous line has12345";
465     char text_length_to_use = strlen(text) - 5;
466     count2 = cout.rdbuf()->form("%-*.*s%3g characters\n",
467                                 text_length_to_use + 1, 
468                                 text_length_to_use,
469                                 text,
470                                 (double)(count1-1));
471     cout.form("%-*.*s%+d characters\n%n",
472               text_length_to_use + 1, text_length_to_use, text,
473               count2-1, &count1);
474     assert(count1 == 33);
475 }
476
477 static void
478 show_int (long val)
479 {
480   cout.setf(ios::showbase);
481   cout << dec; cout.width (8); cout << val << "(dec) = ";
482   cout << hex; cout.width (8); cout << (0xFFFF & val) << "(hex) = ";
483   cout << oct; cout.width (8);
484   cout << (0xFFFF & val) << "(oct) [showbase on]\n";
485   cout.unsetf(ios::showbase);
486   cout << dec; cout.width (8); cout << val << "(dec) = ";
487   cout << hex; cout.width (8); cout << (0xFFFF & val) << "(hex) = ";
488   cout << oct; cout.width (8);
489   cout << (0xFFFF & val) << "(oct) [showbase off]\n";
490 }
491
492 void
493 t12 ()
494 {
495   ios::fmtflags old_flags = cout.setf(ios::showpos);
496   int fill = cout.fill('_');
497   cout.unsetf(ios::uppercase);
498   cout.setf(ios::internal, ios::adjustfield);
499   show_int(34567);
500   show_int(-34567);
501   cout.setf(ios::right, ios::adjustfield);
502   show_int(0);
503   cout.setf(ios::uppercase);
504   cout.unsetf(ios::showpos);
505   show_int(34567);
506   cout.setf(ios::left, ios::adjustfield);
507   show_int(-34567);
508   cout.fill(fill);
509   show_int(0);
510   cout.setf(old_flags,
511             ios::adjustfield|ios::basefield
512             |ios::showbase|ios::showpos|ios::uppercase);
513 }
514
515 main(int argc, char **argv)
516 {
517  char temp [1024] = "tempfile";
518
519  if (argc > 1 && strncmp(argv[1], "-b", 2) == 0) {
520      streambuf *sb = cout.rdbuf();
521      streambuf *ret;
522      int buffer_size = atoi(&argv[1][2]);
523      if (buffer_size == 0)
524          ret = sb->setbuf(NULL, 0);
525      else
526          ret = sb->setbuf(new char[buffer_size], buffer_size);
527      if (ret != sb)
528          cerr << "Warning: cout.rdbuf()->setbuf failed!\n";
529
530      strncpy (&temp [8], &argv[1][2], 1000);
531      temp [1008] = '\0';
532   }
533   tempfile = temp;
534   t1();
535   t2();
536   t3();
537   t4();
538   t5();
539   t6();
540   t7();
541   t9();
542   t8();
543   t10();
544   t11();
545   t12();
546
547   cout << "Final names & states:\n";
548 #ifdef _OLD_STREAMS
549   cout << "cin:      " << cin.name()  << "\t" << cin.rdstate() << "\n";
550   cout << "cout:     " << cout.name() << "\t" << cout.rdstate() << "\n";
551   cout << "cerr:     " << cerr.name() << "\t" << cerr.rdstate() << "\n";
552 #else
553   cout << "cin:      " << "(stdin)"  << "\t" << cin.rdstate() << "\n";
554   cout << "cout:     " << "(stdout)" << "\t" << cout.rdstate() << "\n";
555   cout << "cerr:     " << "(stderr)" << "\t" << cerr.rdstate() << "\n";
556 #endif
557   cout << "\nend of test.\n";
558 }