home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / src / iostream.cpp < prev    next >
C/C++ Source or Header  |  2002-02-02  |  10KB  |  365 lines

  1. /*
  2.  * Copyright (c) 1999
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Copyright (c) 1999 
  6.  * Boris Fomitchev
  7.  *
  8.  * This material is provided "as is", with absolutely no warranty expressed
  9.  * or implied. Any use is at your own risk.
  10.  *
  11.  * Permission to use or copy this software for any purpose is hereby granted 
  12.  * without fee, provided the above notices are retained on all copies.
  13.  * Permission to modify the code and to distribute modified code is granted,
  14.  * provided the above notices are retained, and a notice that the code was
  15.  * modified is included with the above copyright notice.
  16.  *
  17.  */ 
  18. # include "stlport_prefix.h"
  19.  
  20. #include <istream>
  21. // #include <stl/_istream.h>
  22.  
  23. #include <stl/_fstream.h>
  24. #include <stdio_streambuf>
  25. #include "aligned_buffer.h"
  26.  
  27. // boris : note this is repeated in <iostream>
  28. #ifndef _STLP_USE_NAMESPACES
  29. // in case of SGI iostreams, we have to rename our streams not to clash with those
  30. // provided in native lib
  31. # define cin _STLP_cin
  32. # define cout _STLP_cout
  33. # define cerr _STLP_cerr
  34. # define clog _STLP_clog
  35. #endif
  36.  
  37. _STLP_BEGIN_NAMESPACE
  38.  
  39. #if defined (__BORLANDC__) && ! defined (_STLP_USE_GLIBC)
  40. using _STLP_VENDOR_CSTD::_streams;
  41. #endif
  42.  
  43. // This file handles iostream initialization.  It is inherently
  44. // nonportable, since the C++ language definition provides no mechanism
  45. // for controlling order of initialization of nonlocal objects.  
  46. // Initialization has three parts, which must be performed in the following
  47. // order:
  48. //  (1) Initialize the locale system
  49. //  (2) Call the constructors for the eight global stream objects.
  50. //  (3) Create streambufs for the global stream objects, and initialize
  51. //      the stream objects by calling the init() member function.
  52.  
  53.  
  54. #if defined (_STLP_MSVC) || defined(__MWERKS__) || defined (__ICL) || defined (__ISCPP__)
  55.  
  56. // Definitions of the eight global I/O objects that are declared in 
  57. // <iostream>. For VC++ we use the init_seg pragma to put the global I/O
  58. // objects into an intitialization segement that will not
  59. // be executed. We then explicitly invoke the constructors
  60. // with placement new in ios_base::_S_initialize() 
  61.  
  62. #if defined(__MWERKS__)
  63. # pragma suppress_init_code on
  64. #else
  65. # pragma init_seg("STLPORT_NO_INIT")
  66. #endif
  67.  
  68. _STLP_DECLSPEC istream cin(0);
  69. _STLP_DECLSPEC ostream cout(0);
  70. _STLP_DECLSPEC ostream cerr(0);
  71. _STLP_DECLSPEC ostream clog(0);
  72.  
  73. _STLP_DECLSPEC wistream wcin(0);
  74. _STLP_DECLSPEC wostream wcout(0);
  75. _STLP_DECLSPEC wostream wcerr(0);
  76. _STLP_DECLSPEC wostream wclog(0);
  77.  
  78. #if defined(__MWERKS__)
  79. # pragma suppress_init_code off
  80. #endif
  81.  
  82. #else
  83.  
  84.  
  85. // Definitions of the eight global I/O objects that are declared in 
  86. // <iostream>.  Disgusting hack: we deliberately define them with the
  87. // wrong types so that the constructors don't get run automatically.
  88. // We need special tricks to make sure that these objects are struct-
  89. // aligned rather than byte-aligned.
  90.  
  91. // This is not portable.  Declaring a variable with different types in
  92. // two translations units is "undefined", according to the C++ standard.
  93. // Most compilers, however, silently accept this instead of diagnosing
  94. // it as an error.
  95.  
  96. _STLP_DECLSPEC _Stl_aligned_buffer<istream> cin;
  97. _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cout;
  98. _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cerr;
  99. _STLP_DECLSPEC _Stl_aligned_buffer<ostream> clog;
  100.  
  101. # ifndef _STLP_NO_WCHAR_T
  102.  
  103. _STLP_DECLSPEC _Stl_aligned_buffer<wistream> wcin;
  104. _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcout;
  105. _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcerr;
  106. _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wclog;
  107.  
  108. # endif
  109.  
  110. #endif /* STL_MSVC || __MWERKS__ */
  111.  
  112. // Member functions from class ios_base and ios_base::Init
  113.  
  114. long ios_base::Init::_S_count = 0;
  115. // by default, those are synced
  116. bool ios_base::_S_was_synced = true;
  117.  
  118. ios_base::Init::Init() {
  119.     if (_S_count++ == 0)
  120.       ios_base::_S_initialize();
  121. }
  122.  
  123. ios_base::Init::~Init() {
  124.     if (--_S_count == 0)
  125.       ios_base::_S_uninitialize();
  126. }
  127.  
  128.  
  129. filebuf*
  130. _Stl_create_filebuf(FILE* f, ios_base::openmode mode )
  131. {
  132.   basic_filebuf<char, char_traits<char> >* result;
  133.   
  134.   result = new basic_filebuf<char, char_traits<char> >();
  135.  
  136.   _STLP_TRY {
  137.     result->_M_open(_FILE_fd(f), mode);
  138.   }
  139.   _STLP_CATCH_ALL {}
  140.  
  141.   if (!result->is_open()) {
  142.     delete result;
  143.     result = 0;
  144.   }
  145.   return result;
  146. }
  147.  
  148. # ifndef _STLP_NO_WCHAR_T
  149.  
  150. wfilebuf*
  151. _Stl_create_wfilebuf(FILE* f, ios_base::openmode mode )
  152. {
  153.   basic_filebuf<wchar_t, char_traits<wchar_t> >* result;
  154.   
  155.   result = new basic_filebuf<wchar_t, char_traits<wchar_t> >();
  156.  
  157.   _STLP_TRY {
  158.     result->_M_open(_FILE_fd(f), mode);
  159.   }
  160.   _STLP_CATCH_ALL {}
  161.  
  162.   if (!result->is_open()) {
  163.     delete result;
  164.     result = 0;
  165.   }
  166.   return result;
  167. }
  168.  
  169. # endif
  170.  
  171. void  _STLP_CALL ios_base::_S_initialize()
  172. {
  173. # if !defined(_STLP_HAS_NO_NAMESPACES) && !defined(_STLP_WINCE)
  174.   using _SgI::stdio_istreambuf;
  175.   using _SgI::stdio_ostreambuf;
  176. # endif
  177.   _STLP_TRY {
  178.     // Run constructors for the four narrow stream objects.
  179.     // check with locale system
  180.     if (_Loc_init::_S_count++ == 0) {
  181.       locale::_S_initialize();
  182.     }
  183. #if !defined(_STLP_WINCE)
  184.     istream* ptr_cin  = new((void*)&cin)  istream(0);
  185.     ostream* ptr_cout = new((void*)&cout) ostream(0);
  186.     ostream* ptr_cerr = new((void*)&cerr) ostream(0);
  187.     ostream* ptr_clog = new((void*)&clog) ostream(0);
  188.  
  189.     // Initialize the four narrow stream objects.
  190.     if (_S_was_synced) {
  191.       ptr_cin->init(new stdio_istreambuf(stdin));
  192.       ptr_cout->init(new stdio_ostreambuf(stdout));
  193.       ptr_cerr->init(new stdio_ostreambuf(stderr));
  194.       ptr_clog->init(new stdio_ostreambuf(stderr));
  195.     } else {
  196.       ptr_cin->init(_Stl_create_filebuf(stdin, ios_base::in));
  197.       ptr_cin->init(_Stl_create_filebuf(stdout, ios_base::out));
  198.       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out));
  199.       ptr_cin->init(_Stl_create_filebuf(stderr, ios_base::out)); 
  200.     }
  201.     ptr_cin->tie(ptr_cout);
  202.     ptr_cerr->setf(ios_base::unitbuf);
  203.  
  204. # ifndef _STLP_NO_WCHAR_T
  205.  
  206.     // Run constructors for the four wide stream objects.
  207.     wistream* ptr_wcin  = new(&wcin)  wistream(0);
  208.     wostream* ptr_wcout = new(&wcout) wostream(0);
  209.     wostream* ptr_wcerr = new(&wcerr) wostream(0);
  210.     wostream* ptr_wclog = new(&wclog) wostream(0);
  211.     
  212.     wfilebuf* win  = _Stl_create_wfilebuf(stdin, ios_base::in);
  213.     wfilebuf* wout = _Stl_create_wfilebuf(stdout, ios_base::out);;
  214.     wfilebuf* werr = _Stl_create_wfilebuf(stderr, ios_base::out);
  215.     wfilebuf* wlog = _Stl_create_wfilebuf(stderr, ios_base::out);
  216.     
  217.     ptr_wcin->init(win);
  218.     ptr_wcout->init(wout);
  219.     ptr_wcerr->init(werr);
  220.     ptr_wclog->init(wlog);
  221.  
  222.     ptr_wcin->tie(ptr_wcout);
  223.     ptr_wcerr->setf(ios_base::unitbuf);
  224.     
  225. # endif /*  _STLP_NO_WCHAR_T */
  226. #endif /* _STLP_WINCE */
  227.  
  228.   }
  229.  
  230.   _STLP_CATCH_ALL {}
  231. }
  232.  
  233. void _STLP_CALL ios_base::_S_uninitialize()
  234. {
  235.   // Note that destroying output streambufs flushes the buffers.
  236.  
  237.   istream* ptr_cin  = __REINTERPRET_CAST(istream*,&cin);
  238.   ostream* ptr_cout = __REINTERPRET_CAST(ostream*,&cout);
  239.   ostream* ptr_cerr = __REINTERPRET_CAST(ostream*,&cerr);
  240.   ostream* ptr_clog = __REINTERPRET_CAST(ostream*,&clog);
  241.  
  242. # ifndef _STLP_NO_WCHAR_T
  243.   wistream* ptr_wcin  = __REINTERPRET_CAST(wistream*,&wcin);
  244.   wostream* ptr_wcout = __REINTERPRET_CAST(wostream*,&wcout);
  245.   wostream* ptr_wcerr = __REINTERPRET_CAST(wostream*,&wcerr);
  246.   wostream* ptr_wclog = __REINTERPRET_CAST(wostream*,&wclog);
  247. # endif
  248.  
  249.   // we don't want any exceptions being thrown here
  250.   ptr_cin->exceptions(0);
  251.   ptr_cout->exceptions(0);
  252.   ptr_cerr->exceptions(0);
  253.   ptr_clog->exceptions(0);
  254.  
  255.   delete ptr_cin->rdbuf(0);
  256.   delete ptr_cout->rdbuf(0);
  257.   delete ptr_cerr->rdbuf(0);
  258.   delete ptr_clog->rdbuf(0);
  259.  
  260.   _Destroy(ptr_cin);
  261.   _Destroy(ptr_cout);
  262.   _Destroy(ptr_cerr);
  263.   _Destroy(ptr_clog);
  264.  
  265. # ifndef _STLP_NO_WCHAR_T
  266.   // we don't want any exceptions being thrown here
  267.   ptr_wcin->exceptions(0);
  268.   ptr_wcout->exceptions(0);
  269.   ptr_wcerr->exceptions(0);
  270.   ptr_wclog->exceptions(0);
  271.  
  272.   delete ptr_wcin->rdbuf(0);
  273.   delete ptr_wcout->rdbuf(0);
  274.   delete ptr_wcerr->rdbuf(0);
  275.   delete ptr_wclog->rdbuf(0);
  276.  
  277.   _Destroy(ptr_wcin);
  278.   _Destroy(ptr_wcout);
  279.   _Destroy(ptr_wcerr);
  280.   _Destroy(ptr_wclog);
  281.  
  282. # endif
  283.     if (--_Loc_init::_S_count == 0) {
  284.       locale::_S_uninitialize();
  285.     }
  286. }
  287.  
  288.  
  289. bool _STLP_CALL ios_base::sync_with_stdio(bool sync) {
  290. #if !defined(STLP_WINCE)
  291. # ifndef _STLP_HAS_NO_NAMESPACES
  292.   using _SgI::stdio_istreambuf;
  293.   using _SgI::stdio_ostreambuf;
  294. # endif
  295.   
  296.   bool was_synced =  _S_was_synced;
  297.  
  298.   // if by any chance we got there before std streams initialization,
  299.   // just set the sync flag and exit
  300.   if (Init::_S_count == 0) {
  301.     _S_was_synced = sync;
  302.     return was_synced;
  303.   }
  304.  
  305.   istream* ptr_cin  = __REINTERPRET_CAST(istream*,&cin);
  306.   ostream* ptr_cout = __REINTERPRET_CAST(ostream*,&cout);
  307.   ostream* ptr_cerr = __REINTERPRET_CAST(ostream*,&cerr);
  308.   ostream* ptr_clog = __REINTERPRET_CAST(ostream*,&clog);
  309.  
  310.   streambuf* old_cin  = ptr_cin->rdbuf();
  311.   streambuf* old_cout = ptr_cout->rdbuf();
  312.   streambuf* old_cerr = ptr_cerr->rdbuf();
  313.   streambuf* old_clog = ptr_clog->rdbuf();
  314.  
  315.   streambuf* new_cin  = 0;
  316.   streambuf* new_cout = 0;
  317.   streambuf* new_cerr = 0;
  318.   streambuf* new_clog = 0;
  319.  
  320.   _STLP_TRY {
  321.     if (sync && !was_synced) {
  322.       new_cin  = new stdio_istreambuf(stdin);
  323.       new_cout = new stdio_ostreambuf(stdout);
  324.       new_cerr = new stdio_ostreambuf(stderr);
  325.       new_clog = new stdio_ostreambuf(stderr);
  326.     }
  327.     else if (!sync && was_synced) {
  328.       new_cin  = _Stl_create_filebuf(stdin, ios_base::in);
  329.       new_cout = _Stl_create_filebuf(stdout, ios_base::out);
  330.       new_cerr = _Stl_create_filebuf(stderr, ios_base::out);
  331.       new_clog = _Stl_create_filebuf(stderr, ios_base::out);
  332.     }
  333.   }
  334.   _STLP_CATCH_ALL {}
  335.  
  336.   if (new_cin && new_cout && new_cerr && new_clog) {
  337.     ptr_cin->rdbuf(new_cin);
  338.     ptr_cout->rdbuf(new_cout);
  339.     ptr_cerr->rdbuf(new_cerr);
  340.     ptr_clog->rdbuf(new_clog);
  341.  
  342.     delete old_cin;
  343.     delete old_cout;
  344.     delete old_cerr;
  345.     delete old_clog;
  346.   }
  347.   else {
  348.     delete new_cin;
  349.     delete new_cout;
  350.     delete new_cerr;
  351.     delete new_clog;
  352.   }
  353.  
  354.   return was_synced;
  355. #else
  356.   return false;
  357. #endif /* _STLP_WINCE */
  358. }
  359.  
  360. _STLP_END_NAMESPACE
  361.  
  362. // Local Variables:
  363. // mode:C++
  364. // End:
  365.