iostream.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. #include <memory>
  20. #include <istream>
  21. #include <fstream>
  22. #if defined (_STLP_MSVC) || defined (__MWERKS__) || defined (__ICL) || defined (__ISCPP__)
  23. # define _STLP_USE_NOT_INIT_SEGMENT
  24. # include <iostream>
  25. #endif
  26. #include "stdio_streambuf.h"
  27. #include "aligned_buffer.h"
  28. #include "_stdio_file.h"
  29. #include "c_locale.h"
  30. // boris : note this is repeated in <iostream>
  31. #ifndef _STLP_USE_NAMESPACES
  32. // in case of SGI iostreams, we have to rename our streams not to clash with those
  33. // provided in native lib
  34. # define cin _STLP_cin
  35. # define cout _STLP_cout
  36. # define cerr _STLP_cerr
  37. # define clog _STLP_clog
  38. #endif
  39. _STLP_BEGIN_NAMESPACE
  40. // This file handles iostream initialization. It is inherently
  41. // nonportable, since the C++ language definition provides no mechanism
  42. // for controlling order of initialization of nonlocal objects.
  43. // Initialization has three parts, which must be performed in the following
  44. // order:
  45. // (1) Initialize the locale system
  46. // (2) Call the constructors for the eight global stream objects.
  47. // (3) Create streambufs for the global stream objects, and initialize
  48. // the stream objects by calling the init() member function.
  49. #if defined (_STLP_USE_NOT_INIT_SEGMENT)
  50. // Definitions of the eight global I/O objects that are declared in
  51. // <iostream>. For some compilers we use pragmas to put the global I/O
  52. // objects into an initialization segment that will not
  53. // be executed. We then explicitly invoke the constructors
  54. // with placement new in ios_base::_S_initialize()
  55. # if defined (__MWERKS__)
  56. # pragma suppress_init_code on
  57. # else
  58. # pragma init_seg("STLPORT_NO_INIT")
  59. # endif
  60. _STLP_DECLSPEC istream cin(0);
  61. _STLP_DECLSPEC ostream cout(0);
  62. _STLP_DECLSPEC ostream cerr(0);
  63. _STLP_DECLSPEC ostream clog(0);
  64. # ifndef _STLP_NO_WCHAR_T
  65. _STLP_DECLSPEC wistream wcin(0);
  66. _STLP_DECLSPEC wostream wcout(0);
  67. _STLP_DECLSPEC wostream wcerr(0);
  68. _STLP_DECLSPEC wostream wclog(0);
  69. # endif
  70. # if defined (__MWERKS__)
  71. # pragma suppress_init_code off
  72. # endif
  73. #else
  74. // Definitions of the eight global I/O objects that are declared in
  75. // <iostream>. Disgusting hack: we deliberately define them with the
  76. // wrong types so that the constructors don't get run automatically.
  77. // We need special tricks to make sure that these objects are struct-
  78. // aligned rather than byte-aligned.
  79. // This is not portable. Declaring a variable with different types in
  80. // two translations units is "undefined", according to the C++ standard.
  81. // Most compilers, however, silently accept this instead of diagnosing
  82. // it as an error.
  83. # ifndef __DMC__
  84. _STLP_DECLSPEC _Stl_aligned_buffer<istream> cin;
  85. _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cout;
  86. _STLP_DECLSPEC _Stl_aligned_buffer<ostream> cerr;
  87. _STLP_DECLSPEC _Stl_aligned_buffer<ostream> clog;
  88. # else
  89. _Stl_aligned_buffer<istream> cin;
  90. _Stl_aligned_buffer<ostream> cout;
  91. _Stl_aligned_buffer<ostream> cerr;
  92. _Stl_aligned_buffer<ostream> clog;
  93. # pragma alias("?cin@std@@3V?$basic_istream@std@DV?$char_traits@std@D@1@@1@A", "?cin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@DV?$char_traits@std@D@1@@1@@1@A")
  94. # pragma alias("?cout@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
  95. # pragma alias("?cerr@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?cerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
  96. # pragma alias("?clog@std@@3V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@A", "?clog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@DV?$char_traits@std@D@1@@1@@1@A")
  97. # endif
  98. # ifndef _STLP_NO_WCHAR_T
  99. # ifndef __DMC__
  100. _STLP_DECLSPEC _Stl_aligned_buffer<wistream> wcin;
  101. _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcout;
  102. _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wcerr;
  103. _STLP_DECLSPEC _Stl_aligned_buffer<wostream> wclog;
  104. # else
  105. _Stl_aligned_buffer<wistream> wcin;
  106. _Stl_aligned_buffer<wostream> wcout;
  107. _Stl_aligned_buffer<wostream> wcerr;
  108. _Stl_aligned_buffer<wostream> wclog;
  109. # pragma alias("?wcin@std@@3V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcin@std@@3T?$_Stl_aligned_buffer@std@V?$basic_istream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
  110. # pragma alias("?wcout@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcout@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
  111. # pragma alias("?wcerr@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wcerr@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
  112. # pragma alias("?wclog@std@@3V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@A", "?wclog@std@@3T?$_Stl_aligned_buffer@std@V?$basic_ostream@std@_YV?$char_traits@std@_Y@1@@1@@1@A")
  113. # endif
  114. # endif
  115. #endif /* STL_MSVC || __MWERKS__ */
  116. // Member functions from class ios_base and ios_base::Init
  117. long ios_base::Init::_S_count = 0;
  118. // by default, those are synced
  119. bool ios_base::_S_is_synced = true;
  120. ios_base::Init::Init() {
  121. if (_S_count++ == 0) {
  122. _Locale_init();
  123. ios_base::_S_initialize();
  124. _Filebuf_base::_S_initialize();
  125. }
  126. }
  127. ios_base::Init::~Init() {
  128. if (--_S_count == 0) {
  129. ios_base::_S_uninitialize();
  130. _Locale_final();
  131. }
  132. }
  133. static int _Stl_extract_open_param(FILE* f)
  134. { return _FILE_fd(f); }
  135. #ifdef _STLP_REDIRECT_STDSTREAMS
  136. static const char* _Stl_extract_open_param(const char* name)
  137. { return name; }
  138. #endif
  139. template <class _Tp>
  140. static filebuf*
  141. _Stl_create_filebuf(_Tp x, ios_base::openmode mode ) {
  142. auto_ptr<filebuf> result(new basic_filebuf<char, char_traits<char> >());
  143. result->open(_Stl_extract_open_param(x), mode);
  144. if (result->is_open())
  145. return result.release();
  146. return 0;
  147. }
  148. #if !defined (_STLP_NO_WCHAR_T)
  149. static wfilebuf*
  150. _Stl_create_wfilebuf(FILE* f, ios_base::openmode mode) {
  151. auto_ptr<wfilebuf> result(new basic_filebuf<wchar_t, char_traits<wchar_t> >());
  152. result->_M_open(_FILE_fd(f), mode);
  153. if (result->is_open())
  154. return result.release();
  155. return 0;
  156. }
  157. #endif
  158. void _STLP_CALL ios_base::_S_initialize() {
  159. #if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
  160. using _STLP_PRIV stdio_istreambuf;
  161. using _STLP_PRIV stdio_ostreambuf;
  162. #endif
  163. auto_ptr<streambuf> cin_buf;
  164. auto_ptr<streambuf> cout_buf;
  165. auto_ptr<streambuf> cerr_buf;
  166. auto_ptr<streambuf> clog_buf;
  167. if (_S_is_synced)
  168. cin_buf.reset(new stdio_istreambuf(stdin));
  169. else
  170. cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in));
  171. if (_S_is_synced) {
  172. #ifdef _STLP_REDIRECT_STDSTREAMS
  173. cout_buf.reset(_Stl_create_filebuf("/stdout.txt", ios::out));
  174. cerr_buf.reset(_Stl_create_filebuf("/stderr.txt", ios::out));
  175. clog_buf.reset(_Stl_create_filebuf("/stdlog.txt", ios::out));
  176. #else
  177. cout_buf.reset(new stdio_ostreambuf(stdout));
  178. cerr_buf.reset(new stdio_ostreambuf(stderr));
  179. clog_buf.reset(new stdio_ostreambuf(stderr));
  180. #endif
  181. }
  182. else {
  183. cout_buf.reset(_Stl_create_filebuf(stdout, ios_base::out));
  184. cerr_buf.reset(_Stl_create_filebuf(stderr, ios_base::out));
  185. clog_buf.reset(_Stl_create_filebuf(stderr, ios_base::out));
  186. }
  187. istream* ptr_cin = new(&cin) istream(cin_buf.get()); cin_buf.release();
  188. ostream* ptr_cout = new(&cout) ostream(cout_buf.get()); cout_buf.release();
  189. ostream* ptr_cerr = new(&cerr) ostream(cerr_buf.get()); cerr_buf.release();
  190. /*ostream* ptr_clog = */ new(&clog) ostream(clog_buf.get()); clog_buf.release();
  191. ptr_cin->tie(ptr_cout);
  192. ptr_cerr->setf(ios_base::unitbuf);
  193. #ifndef _STLP_NO_WCHAR_T
  194. auto_ptr<wfilebuf> win(_Stl_create_wfilebuf(stdin, ios_base::in));
  195. auto_ptr<wfilebuf> wout(_Stl_create_wfilebuf(stdout, ios_base::out));
  196. auto_ptr<wfilebuf> werr(_Stl_create_wfilebuf(stderr, ios_base::out));
  197. auto_ptr<wfilebuf> wlog(_Stl_create_wfilebuf(stderr, ios_base::out));
  198. // Run constructors for the four wide stream objects.
  199. wistream* ptr_wcin = new(&wcin) wistream(win.get()); win.release();
  200. wostream* ptr_wcout = new(&wcout) wostream(wout.get()); wout.release();
  201. wostream* ptr_wcerr = new(&wcerr) wostream(werr.get()); werr.release();
  202. /*wostream* ptr_wclog = */ new(&wclog) wostream(wlog.get()); wlog.release();
  203. ptr_wcin->tie(ptr_wcout);
  204. ptr_wcerr->setf(ios_base::unitbuf);
  205. #endif
  206. }
  207. void _STLP_CALL ios_base::_S_uninitialize() {
  208. // Note that destroying output streambufs flushes the buffers.
  209. istream* ptr_cin = &cin;
  210. ostream* ptr_cout = &cout;
  211. ostream* ptr_cerr = &cerr;
  212. ostream* ptr_clog = &clog;
  213. // We don't want any exceptions being thrown here
  214. ptr_cin->exceptions(0);
  215. ptr_cout->exceptions(0);
  216. ptr_cerr->exceptions(0);
  217. ptr_clog->exceptions(0);
  218. delete ptr_cin->rdbuf(0);
  219. delete ptr_cout->rdbuf(0);
  220. delete ptr_cerr->rdbuf(0);
  221. delete ptr_clog->rdbuf(0);
  222. _Destroy(ptr_cin);
  223. _Destroy(ptr_cout);
  224. _Destroy(ptr_cerr);
  225. _Destroy(ptr_clog);
  226. #ifndef _STLP_NO_WCHAR_T
  227. wistream* ptr_wcin = &wcin;
  228. wostream* ptr_wcout = &wcout;
  229. wostream* ptr_wcerr = &wcerr;
  230. wostream* ptr_wclog = &wclog;
  231. // We don't want any exceptions being thrown here
  232. ptr_wcin->exceptions(0);
  233. ptr_wcout->exceptions(0);
  234. ptr_wcerr->exceptions(0);
  235. ptr_wclog->exceptions(0);
  236. delete ptr_wcin->rdbuf(0);
  237. delete ptr_wcout->rdbuf(0);
  238. delete ptr_wcerr->rdbuf(0);
  239. delete ptr_wclog->rdbuf(0);
  240. _Destroy(ptr_wcin);
  241. _Destroy(ptr_wcout);
  242. _Destroy(ptr_wcerr);
  243. _Destroy(ptr_wclog);
  244. #endif
  245. }
  246. bool _STLP_CALL ios_base::sync_with_stdio(bool sync) {
  247. # if !defined (_STLP_HAS_NO_NAMESPACES) && !defined (_STLP_DONT_USE_PRIV_NAMESPACE)
  248. using _STLP_PRIV stdio_istreambuf;
  249. using _STLP_PRIV stdio_ostreambuf;
  250. # endif
  251. if (sync == _S_is_synced) return sync;
  252. // if by any chance we got there before std streams initialization,
  253. // just set the sync flag and exit
  254. if (Init::_S_count == 0) {
  255. _S_is_synced = sync;
  256. return sync;
  257. }
  258. auto_ptr<streambuf> cin_buf;
  259. auto_ptr<streambuf> cout_buf;
  260. auto_ptr<streambuf> cerr_buf;
  261. auto_ptr<streambuf> clog_buf;
  262. if (sync)
  263. cin_buf.reset(new stdio_istreambuf(stdin));
  264. else
  265. cin_buf.reset(_Stl_create_filebuf(stdin, ios_base::in));
  266. if (sync) {
  267. #ifdef _STLP_REDIRECT_STDSTREAMS
  268. cout_buf.reset(_Stl_create_filebuf("/stdout.txt", ios::out));
  269. cerr_buf.reset(_Stl_create_filebuf("/stderr.txt", ios::out));
  270. clog_buf.reset(_Stl_create_filebuf("/stdlog.txt", ios::out));
  271. #else
  272. cout_buf.reset(new stdio_ostreambuf(stdout));
  273. cerr_buf.reset(new stdio_ostreambuf(stderr));
  274. clog_buf.reset(new stdio_ostreambuf(stderr));
  275. #endif
  276. }
  277. else {
  278. cout_buf.reset(_Stl_create_filebuf(stdout, ios_base::out));
  279. cerr_buf.reset(_Stl_create_filebuf(stderr, ios_base::out));
  280. clog_buf.reset(_Stl_create_filebuf(stderr, ios_base::out));
  281. }
  282. if (cin_buf.get() != 0 && cout_buf.get() != 0 && cerr_buf.get() != 0 && clog_buf.get() != 0) {
  283. // When streambuf passed to rdbuf is not null, rdbuf is exception safe:
  284. delete (&cin)->rdbuf(cin_buf.release());
  285. delete (&cout)->rdbuf(cout_buf.release());
  286. delete (&cerr)->rdbuf(cerr_buf.release());
  287. delete (&clog)->rdbuf(clog_buf.release());
  288. _S_is_synced = sync;
  289. }
  290. return _S_is_synced;
  291. }
  292. _STLP_END_NAMESPACE
  293. // Local Variables:
  294. // mode:C++
  295. // End: