this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

libstdc++darwin with ABI fixes

+2030 -13
+1 -2
CMakeLists.txt
··· 103 103 add_subdirectory(src/IOKit) 104 104 add_subdirectory(src/libcrashhandler) 105 105 add_subdirectory(src/thin) 106 - # Not ready yet 107 - # add_subdirectory(src/cxx) 106 + add_subdirectory(src/libstdc++darwin) 108 107 109 108 add_dependencies(dyld${SUFFIX} mach-o) 110 109 add_dependencies(Cocoa crashhandler)
+2 -1
etc/dylib.conf
··· 3 3 /usr/lib/libobjc.A.dylib=libobjc.A.dylib.so 4 4 /usr/lib/libintl.8.dylib=libc.so.6 5 5 /usr/lib/libz.1.dylib=libz.so.1 6 - /usr/lib/libstdc++.6.dylib=/dev/null 6 + /usr/lib/libstdc++.6.dylib=libstdc++darwin.so 7 7 /usr/lib/libc++.1.dylib=/dev/null 8 8 /usr/lib/libc++abi.dylib=/dev/null 9 9 /usr/lib/libcrypto.0.9.8.dylib=libcrypto.so ··· 13 13 /usr/lib/libiconv.2.dylib=libc.so.6 14 14 /usr/lib/libauto.dylib=/dev/null 15 15 /usr/lib/libsqlite3.dylib=libsqlite3.so 16 + /usr/lib/libncurses.5.4.dylib=libncurses.5.4.dylib.so 16 17 17 18 @rpath/libclang.dylib=libclang.so 18 19 @rpath/libobjc.A.dylib=libobjc.A.dylib.so
+32 -10
src/dyld/ld.cpp
··· 61 61 __attribute__((constructor)) static void initLD(); 62 62 static std::list<Darling::DlsymHookFunc> g_dlsymHooks; 63 63 64 + static void* g_libStdCxxDarwin = nullptr; 65 + 64 66 extern MachOLoader* g_loader; 65 67 extern char g_darwin_executable_path[PATH_MAX]; 66 68 extern char g_sysroot[PATH_MAX]; ··· 94 96 } 95 97 else 96 98 { 99 + size_t pos = line.find('#'); 100 + if (pos != std::string::npos) 101 + line.resize(pos); 102 + // TODO: trim 97 103 g_searchPath.push_back(line); 98 104 } 99 105 } ··· 237 243 // @rpath - https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath 238 244 for (std::string rpathSearch : rpaths) 239 245 { 240 - { 241 - bool recNotFoundError; 242 - path = replacePathPrefix("@rpath", filename, rpathSearch.c_str()); 243 - 244 - RET_IF( DlopenWithContext(path.c_str(), flag, rpaths, &recNotFoundError) ); 246 + bool recNotFoundError; 247 + path = replacePathPrefix("@rpath", filename, rpathSearch.c_str()); 248 + 249 + RET_IF( DlopenWithContext(path.c_str(), flag, rpaths, &recNotFoundError) ); 245 250 246 - // Stop if there was an error, vs just not found 247 - if (!recNotFoundError) 248 - return nullptr; 249 - } 251 + // Stop if there was an error, vs just not found 252 + if (!recNotFoundError) 253 + return nullptr; 250 254 } 251 255 } 252 256 else ··· 374 378 LOG << "Loading a native library " << name << std::endl; 375 379 // We're loading a native library 376 380 // TODO: flags 377 - void* d = ::dlopen(name, RTLD_NOW|RTLD_GLOBAL); 381 + int flags = RTLD_NOW | RTLD_GLOBAL; 382 + void* d; 383 + 384 + // TODO: another hack location for libstdc++darwin.so 385 + if (strcmp(name, "libstdc++darwin.so") == 0) 386 + flags |= RTLD_DEEPBIND; 387 + 388 + d = ::dlopen(name, flags); 389 + 378 390 if (d != 0) 379 391 { 380 392 LOG << "Native library loaded\n"; ··· 385 397 lib->type = LoadedLibraryNative; 386 398 lib->nativeRef = d; 387 399 //lib->slide = lib->base = 0; 400 + 401 + if (strstr(name, "libstdc++darwin") != nullptr) 402 + g_libStdCxxDarwin = d; 388 403 389 404 g_ldLibraries[name] = lib; 390 405 return lib; ··· 682 697 } 683 698 } 684 699 #endif 700 + 701 + // FIXME: this is very crude, but simple and effective... 702 + // "St" == namespace std 703 + if (g_libStdCxxDarwin && strstr(translated, "St") != nullptr) 704 + { 705 + RET_IF(::dlsym(g_libStdCxxDarwin, translated)); 706 + } 685 707 686 708 RET_IF(::dlsym(RTLD_DEFAULT, translated)); 687 709
+20
src/libstdc++darwin/CMakeLists.txt
··· 1 + project(libstdc++darwin) 2 + 3 + # clang doesn't support linker scripts (-T) 4 + SET(CMAKE_CXX_COMPILER "/usr/bin/g++") 5 + set(CMAKE_CXX_FLAGS "") 6 + 7 + cmake_minimum_required(VERSION 2.4.0) 8 + 9 + add_definitions(-Bsymbolic -fno-weak) 10 + add_library(stdc++darwin SHARED filebuf_abi_fix.cpp) 11 + 12 + #add_custom_target(stdc++_darwinx ALL COMMAND echo objcopy 13 + # --redefine-syms=${CMAKE_CURRENT_SOURCE_DIR}/renames.list 14 + # ${CMAKE_CURRENT_BINARY_DIR}/libstdc++_darwin.so) 15 + 16 + #add_dependencies(stdc++_darwinx stdc++_darwin) 17 + #target_link_libraries(stdc++-darwin -T${CMAKE_CURRENT_SOURCE_DIR}/renames.cmd) 18 + 19 + install(TARGETS stdc++darwin DESTINATION "lib${SUFFIX}/darling") 20 +
+11
src/libstdc++darwin/filebuf_abi_fix.cpp
··· 1 + // http://stackoverflow.com/a/452955 2 + #define _GLIBCXX_VISIBILITY(x) __attribute((visibility(#x))) 3 + #define _GLIBCXX_BEGIN_NAMESPACE_VERSION 4 + #define _GLIBCXX_END_NAMESPACE_VERSION 5 + #include "fstream" 6 + 7 + template class std::basic_filebuf<char, std::char_traits<char> >; 8 + template class std::basic_streambuf<char, std::char_traits<char> >; 9 + template class std::basic_ios<char, std::char_traits<char> >; 10 + template class std::basic_ostream<char, std::char_traits<char> >; 11 +
+951
src/libstdc++darwin/fstream
··· 1 + // File based streams -*- C++ -*- 2 + 3 + // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 + // 2006, 2007, 2008, 2009, 2010, 2011 5 + // Free Software Foundation, Inc. 6 + // 7 + // This file is part of the GNU ISO C++ Library. This library is free 8 + // software; you can redistribute it and/or modify it under the 9 + // terms of the GNU General Public License as published by the 10 + // Free Software Foundation; either version 3, or (at your option) 11 + // any later version. 12 + 13 + // This library is distributed in the hope that it will be useful, 14 + // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + // GNU General Public License for more details. 17 + 18 + // Under Section 7 of GPL version 3, you are granted additional 19 + // permissions described in the GCC Runtime Library Exception, version 20 + // 3.1, as published by the Free Software Foundation. 21 + 22 + // You should have received a copy of the GNU General Public License and 23 + // a copy of the GCC Runtime Library Exception along with this program; 24 + // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 + // <http://www.gnu.org/licenses/>. 26 + 27 + /** @file include/fstream 28 + * This is a Standard C++ Library header. 29 + */ 30 + 31 + // 32 + // ISO C++ 14882: 27.8 File-based streams 33 + // 34 + 35 + #ifndef _GLIBCXX_FSTREAM 36 + #define _GLIBCXX_FSTREAM 1 37 + 38 + #pragma GCC system_header 39 + 40 + #include <istream> 41 + #include <ostream> 42 + #include <bits/codecvt.h> 43 + #include <cstdio> // For BUFSIZ 44 + #include <bits/basic_file.h> // For __basic_file, __c_lock 45 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 46 + #include <string> // For std::string overloads. 47 + #endif 48 + 49 + namespace std _GLIBCXX_VISIBILITY(default) 50 + { 51 + _GLIBCXX_BEGIN_NAMESPACE_VERSION 52 + 53 + // [27.8.1.1] template class basic_filebuf 54 + /** 55 + * @brief The actual work of input and output (for files). 56 + * @ingroup io 57 + * 58 + * This class associates both its input and output sequence with an 59 + * external disk file, and maintains a joint file position for both 60 + * sequences. Many of its semantics are described in terms of similar 61 + * behavior in the Standard C Library's @c FILE streams. 62 + */ 63 + // Requirements on traits_type, specific to this class: 64 + // traits_type::pos_type must be fpos<traits_type::state_type> 65 + // traits_type::off_type must be streamoff 66 + // traits_type::state_type must be Assignable and DefaultConstructible, 67 + // and traits_type::state_type() must be the initial state for codecvt. 68 + template<typename _CharT, typename _Traits> 69 + class basic_filebuf : public basic_streambuf<_CharT, _Traits> 70 + { 71 + public: 72 + // Types: 73 + typedef _CharT char_type; 74 + typedef _Traits traits_type; 75 + typedef typename traits_type::int_type int_type; 76 + typedef typename traits_type::pos_type pos_type; 77 + typedef typename traits_type::off_type off_type; 78 + 79 + typedef basic_streambuf<char_type, traits_type> __streambuf_type; 80 + typedef basic_filebuf<char_type, traits_type> __filebuf_type; 81 + typedef __basic_file<char> __file_type; 82 + typedef typename traits_type::state_type __state_type; 83 + typedef codecvt<char_type, char, __state_type> __codecvt_type; 84 + 85 + friend class ios_base; // For sync_with_stdio. 86 + 87 + protected: 88 + // Data Members: 89 + // MT lock inherited from libio or other low-level io library. 90 + 91 + // Darling MODIFICATION 92 + union 93 + { 94 + __c_lock _M_lock; 95 + // 64 on 64-bit 96 + // 44 on 32-bit 97 + struct 98 + { 99 + char __align0[24]; 100 + long __align0x[5]; 101 + }; 102 + }; 103 + 104 + // External buffer. 105 + __file_type _M_file; 106 + 107 + /// Place to stash in || out || in | out settings for current filebuf. 108 + ios_base::openmode _M_mode; 109 + 110 + // Beginning state type for codecvt. 111 + // Darling MODIFICATION 112 + union 113 + { 114 + __state_type _M_state_beg; 115 + char __align1[128]; 116 + }; 117 + 118 + // During output, the state that corresponds to pptr(), 119 + // during input, the state that corresponds to egptr() and 120 + // _M_ext_next. 121 + // Darling MODIFICATION 122 + union 123 + { 124 + __state_type _M_state_cur; 125 + char __align2[128]; 126 + }; 127 + 128 + // Not used for output. During input, the state that corresponds 129 + // to eback() and _M_ext_buf. 130 + // Darling MODIFICATION 131 + union 132 + { 133 + __state_type _M_state_last; 134 + char __align3[128]; 135 + }; 136 + 137 + /// Pointer to the beginning of internal buffer. 138 + char_type* _M_buf; 139 + 140 + /** 141 + * Actual size of internal buffer. This number is equal to the size 142 + * of the put area + 1 position, reserved for the overflow char of 143 + * a full area. 144 + */ 145 + size_t _M_buf_size; 146 + 147 + // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. 148 + bool _M_buf_allocated; 149 + 150 + /** 151 + * _M_reading == false && _M_writing == false for @b uncommitted mode; 152 + * _M_reading == true for @b read mode; 153 + * _M_writing == true for @b write mode; 154 + * 155 + * NB: _M_reading == true && _M_writing == true is unused. 156 + */ 157 + bool _M_reading; 158 + bool _M_writing; 159 + 160 + //@{ 161 + /** 162 + * Necessary bits for putback buffer management. 163 + * 164 + * @note pbacks of over one character are not currently supported. 165 + */ 166 + char_type _M_pback; 167 + char_type* _M_pback_cur_save; 168 + char_type* _M_pback_end_save; 169 + bool _M_pback_init; 170 + //@} 171 + 172 + // Cached codecvt facet. 173 + const __codecvt_type* _M_codecvt; 174 + 175 + /** 176 + * Buffer for external characters. Used for input when 177 + * codecvt::always_noconv() == false. When valid, this corresponds 178 + * to eback(). 179 + */ 180 + char* _M_ext_buf; 181 + 182 + /** 183 + * Size of buffer held by _M_ext_buf. 184 + */ 185 + streamsize _M_ext_buf_size; 186 + 187 + /** 188 + * Pointers into the buffer held by _M_ext_buf that delimit a 189 + * subsequence of bytes that have been read but not yet converted. 190 + * When valid, _M_ext_next corresponds to egptr(). 191 + */ 192 + const char* _M_ext_next; 193 + char* _M_ext_end; 194 + 195 + /** 196 + * Initializes pback buffers, and moves normal buffers to safety. 197 + * Assumptions: 198 + * _M_in_cur has already been moved back 199 + */ 200 + void 201 + _M_create_pback() 202 + { 203 + if (!_M_pback_init) 204 + { 205 + _M_pback_cur_save = this->gptr(); 206 + _M_pback_end_save = this->egptr(); 207 + this->setg(&_M_pback, &_M_pback, &_M_pback + 1); 208 + _M_pback_init = true; 209 + } 210 + } 211 + 212 + /** 213 + * Deactivates pback buffer contents, and restores normal buffer. 214 + * Assumptions: 215 + * The pback buffer has only moved forward. 216 + */ 217 + void 218 + _M_destroy_pback() throw() 219 + { 220 + if (_M_pback_init) 221 + { 222 + // Length _M_in_cur moved in the pback buffer. 223 + _M_pback_cur_save += this->gptr() != this->eback(); 224 + this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); 225 + _M_pback_init = false; 226 + } 227 + } 228 + 229 + public: 230 + // Constructors/destructor: 231 + /** 232 + * @brief Does not open any files. 233 + * 234 + * The default constructor initializes the parent class using its 235 + * own default ctor. 236 + */ 237 + basic_filebuf(); 238 + 239 + /** 240 + * @brief The destructor closes the file first. 241 + */ 242 + virtual 243 + ~basic_filebuf() 244 + { this->close(); } 245 + 246 + // Members: 247 + /** 248 + * @brief Returns true if the external file is open. 249 + */ 250 + bool 251 + is_open() const throw() 252 + { return _M_file.is_open(); } 253 + 254 + /** 255 + * @brief Opens an external file. 256 + * @param s The name of the file. 257 + * @param mode The open mode flags. 258 + * @return @c this on success, NULL on failure 259 + * 260 + * If a file is already open, this function immediately fails. 261 + * Otherwise it tries to open the file named @a s using the flags 262 + * given in @a mode. 263 + * 264 + * Table 92, adapted here, gives the relation between openmode 265 + * combinations and the equivalent fopen() flags. 266 + * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, 267 + * and binary|in|app per DR 596) 268 + * +---------------------------------------------------------+ 269 + * | ios_base Flag combination stdio equivalent | 270 + * |binary in out trunc app | 271 + * +---------------------------------------------------------+ 272 + * | + w | 273 + * | + + a | 274 + * | + a | 275 + * | + + w | 276 + * | + r | 277 + * | + + r+ | 278 + * | + + + w+ | 279 + * | + + + a+ | 280 + * | + + a+ | 281 + * +---------------------------------------------------------+ 282 + * | + + wb | 283 + * | + + + ab | 284 + * | + + ab | 285 + * | + + + wb | 286 + * | + + rb | 287 + * | + + + r+b | 288 + * | + + + + w+b | 289 + * | + + + + a+b | 290 + * | + + + a+b | 291 + * +---------------------------------------------------------+ 292 + */ 293 + __filebuf_type* 294 + open(const char* __s, ios_base::openmode __mode); 295 + 296 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 297 + /** 298 + * @brief Opens an external file. 299 + * @param s The name of the file. 300 + * @param mode The open mode flags. 301 + * @return @c this on success, NULL on failure 302 + */ 303 + __filebuf_type* 304 + open(const std::string& __s, ios_base::openmode __mode) 305 + { return open(__s.c_str(), __mode); } 306 + #endif 307 + 308 + /** 309 + * @brief Closes the currently associated file. 310 + * @return @c this on success, NULL on failure 311 + * 312 + * If no file is currently open, this function immediately fails. 313 + * 314 + * If a <em>put buffer area</em> exists, @c overflow(eof) is 315 + * called to flush all the characters. The file is then 316 + * closed. 317 + * 318 + * If any operations fail, this function also fails. 319 + */ 320 + __filebuf_type* 321 + close(); 322 + 323 + protected: 324 + void 325 + _M_allocate_internal_buffer(); 326 + 327 + void 328 + _M_destroy_internal_buffer() throw(); 329 + 330 + // [27.8.1.4] overridden virtual functions 331 + virtual streamsize 332 + showmanyc(); 333 + 334 + // Stroustrup, 1998, p. 628 335 + // underflow() and uflow() functions are called to get the next 336 + // character from the real input source when the buffer is empty. 337 + // Buffered input uses underflow() 338 + 339 + virtual int_type 340 + underflow(); 341 + 342 + virtual int_type 343 + pbackfail(int_type __c = _Traits::eof()); 344 + 345 + // Stroustrup, 1998, p 648 346 + // The overflow() function is called to transfer characters to the 347 + // real output destination when the buffer is full. A call to 348 + // overflow(c) outputs the contents of the buffer plus the 349 + // character c. 350 + // 27.5.2.4.5 351 + // Consume some sequence of the characters in the pending sequence. 352 + virtual int_type 353 + overflow(int_type __c = _Traits::eof()); 354 + 355 + // Convert internal byte sequence to external, char-based 356 + // sequence via codecvt. 357 + bool 358 + _M_convert_to_external(char_type*, streamsize); 359 + 360 + /** 361 + * @brief Manipulates the buffer. 362 + * @param s Pointer to a buffer area. 363 + * @param n Size of @a s. 364 + * @return @c this 365 + * 366 + * If no file has been opened, and both @a s and @a n are zero, then 367 + * the stream becomes unbuffered. Otherwise, @c s is used as a 368 + * buffer; see 369 + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html 370 + * for more. 371 + */ 372 + virtual __streambuf_type* 373 + setbuf(char_type* __s, streamsize __n); 374 + 375 + virtual pos_type 376 + seekoff(off_type __off, ios_base::seekdir __way, 377 + ios_base::openmode __mode = ios_base::in | ios_base::out); 378 + 379 + virtual pos_type 380 + seekpos(pos_type __pos, 381 + ios_base::openmode __mode = ios_base::in | ios_base::out); 382 + 383 + // Common code for seekoff, seekpos, and overflow 384 + pos_type 385 + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); 386 + 387 + int 388 + _M_get_ext_pos(__state_type &__state); 389 + 390 + virtual int 391 + sync(); 392 + 393 + virtual void 394 + imbue(const locale& __loc); 395 + 396 + virtual streamsize 397 + xsgetn(char_type* __s, streamsize __n); 398 + 399 + virtual streamsize 400 + xsputn(const char_type* __s, streamsize __n); 401 + 402 + // Flushes output buffer, then writes unshift sequence. 403 + bool 404 + _M_terminate_output(); 405 + 406 + /** 407 + * This function sets the pointers of the internal buffer, both get 408 + * and put areas. Typically: 409 + * 410 + * __off == egptr() - eback() upon underflow/uflow (@b read mode); 411 + * __off == 0 upon overflow (@b write mode); 412 + * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). 413 + * 414 + * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size 415 + * reflects the actual allocated memory and the last cell is reserved 416 + * for the overflow char of a full put area. 417 + */ 418 + void 419 + _M_set_buffer(streamsize __off) 420 + { 421 + const bool __testin = _M_mode & ios_base::in; 422 + const bool __testout = _M_mode & ios_base::out; 423 + 424 + if (__testin && __off > 0) 425 + this->setg(_M_buf, _M_buf, _M_buf + __off); 426 + else 427 + this->setg(_M_buf, _M_buf, _M_buf); 428 + 429 + if (__testout && __off == 0 && _M_buf_size > 1 ) 430 + this->setp(_M_buf, _M_buf + _M_buf_size - 1); 431 + else 432 + this->setp(0, 0); 433 + } 434 + }; 435 + 436 + // [27.8.1.5] Template class basic_ifstream 437 + /** 438 + * @brief Controlling input for files. 439 + * @ingroup io 440 + * 441 + * This class supports reading from named files, using the inherited 442 + * functions from std::basic_istream. To control the associated 443 + * sequence, an instance of std::basic_filebuf is used, which this page 444 + * refers to as @c sb. 445 + */ 446 + template<typename _CharT, typename _Traits> 447 + class basic_ifstream : public basic_istream<_CharT, _Traits> 448 + { 449 + public: 450 + // Types: 451 + typedef _CharT char_type; 452 + typedef _Traits traits_type; 453 + typedef typename traits_type::int_type int_type; 454 + typedef typename traits_type::pos_type pos_type; 455 + typedef typename traits_type::off_type off_type; 456 + 457 + // Non-standard types: 458 + typedef basic_filebuf<char_type, traits_type> __filebuf_type; 459 + typedef basic_istream<char_type, traits_type> __istream_type; 460 + 461 + private: 462 + __filebuf_type _M_filebuf; 463 + 464 + public: 465 + // Constructors/Destructors: 466 + /** 467 + * @brief Default constructor. 468 + * 469 + * Initializes @c sb using its default constructor, and passes 470 + * @c &sb to the base class initializer. Does not open any files 471 + * (you haven't given it a filename to open). 472 + */ 473 + basic_ifstream() : __istream_type(), _M_filebuf() 474 + { this->init(&_M_filebuf); } 475 + 476 + /** 477 + * @brief Create an input file stream. 478 + * @param s Null terminated string specifying the filename. 479 + * @param mode Open file in specified mode (see std::ios_base). 480 + * 481 + * @c ios_base::in is automatically included in @a mode. 482 + * 483 + * Tip: When using std::string to hold the filename, you must use 484 + * .c_str() before passing it to this constructor. 485 + */ 486 + explicit 487 + basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) 488 + : __istream_type(), _M_filebuf() 489 + { 490 + this->init(&_M_filebuf); 491 + this->open(__s, __mode); 492 + } 493 + 494 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 495 + /** 496 + * @brief Create an input file stream. 497 + * @param s std::string specifying the filename. 498 + * @param mode Open file in specified mode (see std::ios_base). 499 + * 500 + * @c ios_base::in is automatically included in @a mode. 501 + */ 502 + explicit 503 + basic_ifstream(const std::string& __s, 504 + ios_base::openmode __mode = ios_base::in) 505 + : __istream_type(), _M_filebuf() 506 + { 507 + this->init(&_M_filebuf); 508 + this->open(__s, __mode); 509 + } 510 + #endif 511 + 512 + /** 513 + * @brief The destructor does nothing. 514 + * 515 + * The file is closed by the filebuf object, not the formatting 516 + * stream. 517 + */ 518 + ~basic_ifstream() 519 + { } 520 + 521 + // Members: 522 + /** 523 + * @brief Accessing the underlying buffer. 524 + * @return The current basic_filebuf buffer. 525 + * 526 + * This hides both signatures of std::basic_ios::rdbuf(). 527 + */ 528 + __filebuf_type* 529 + rdbuf() const 530 + { return const_cast<__filebuf_type*>(&_M_filebuf); } 531 + 532 + /** 533 + * @brief Wrapper to test for an open file. 534 + * @return @c rdbuf()->is_open() 535 + */ 536 + bool 537 + is_open() 538 + { return _M_filebuf.is_open(); } 539 + 540 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 541 + // 365. Lack of const-qualification in clause 27 542 + bool 543 + is_open() const 544 + { return _M_filebuf.is_open(); } 545 + 546 + /** 547 + * @brief Opens an external file. 548 + * @param s The name of the file. 549 + * @param mode The open mode flags. 550 + * 551 + * Calls @c std::basic_filebuf::open(s,mode|in). If that function 552 + * fails, @c failbit is set in the stream's error state. 553 + * 554 + * Tip: When using std::string to hold the filename, you must use 555 + * .c_str() before passing it to this constructor. 556 + */ 557 + void 558 + open(const char* __s, ios_base::openmode __mode = ios_base::in) 559 + { 560 + if (!_M_filebuf.open(__s, __mode | ios_base::in)) 561 + this->setstate(ios_base::failbit); 562 + else 563 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 564 + // 409. Closing an fstream should clear error state 565 + this->clear(); 566 + } 567 + 568 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 569 + /** 570 + * @brief Opens an external file. 571 + * @param s The name of the file. 572 + * @param mode The open mode flags. 573 + * 574 + * Calls @c std::basic_filebuf::open(s,mode|in). If that function 575 + * fails, @c failbit is set in the stream's error state. 576 + */ 577 + void 578 + open(const std::string& __s, ios_base::openmode __mode = ios_base::in) 579 + { 580 + if (!_M_filebuf.open(__s, __mode | ios_base::in)) 581 + this->setstate(ios_base::failbit); 582 + else 583 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 584 + // 409. Closing an fstream should clear error state 585 + this->clear(); 586 + } 587 + #endif 588 + 589 + /** 590 + * @brief Close the file. 591 + * 592 + * Calls @c std::basic_filebuf::close(). If that function 593 + * fails, @c failbit is set in the stream's error state. 594 + */ 595 + void 596 + close() 597 + { 598 + if (!_M_filebuf.close()) 599 + this->setstate(ios_base::failbit); 600 + } 601 + }; 602 + 603 + 604 + // [27.8.1.8] Template class basic_ofstream 605 + /** 606 + * @brief Controlling output for files. 607 + * @ingroup io 608 + * 609 + * This class supports reading from named files, using the inherited 610 + * functions from std::basic_ostream. To control the associated 611 + * sequence, an instance of std::basic_filebuf is used, which this page 612 + * refers to as @c sb. 613 + */ 614 + template<typename _CharT, typename _Traits> 615 + class basic_ofstream : public basic_ostream<_CharT,_Traits> 616 + { 617 + public: 618 + // Types: 619 + typedef _CharT char_type; 620 + typedef _Traits traits_type; 621 + typedef typename traits_type::int_type int_type; 622 + typedef typename traits_type::pos_type pos_type; 623 + typedef typename traits_type::off_type off_type; 624 + 625 + // Non-standard types: 626 + typedef basic_filebuf<char_type, traits_type> __filebuf_type; 627 + typedef basic_ostream<char_type, traits_type> __ostream_type; 628 + 629 + private: 630 + __filebuf_type _M_filebuf; 631 + 632 + public: 633 + // Constructors: 634 + /** 635 + * @brief Default constructor. 636 + * 637 + * Initializes @c sb using its default constructor, and passes 638 + * @c &sb to the base class initializer. Does not open any files 639 + * (you haven't given it a filename to open). 640 + */ 641 + basic_ofstream(): __ostream_type(), _M_filebuf() 642 + { this->init(&_M_filebuf); } 643 + 644 + /** 645 + * @brief Create an output file stream. 646 + * @param s Null terminated string specifying the filename. 647 + * @param mode Open file in specified mode (see std::ios_base). 648 + * 649 + * @c ios_base::out|ios_base::trunc is automatically included in 650 + * @a mode. 651 + * 652 + * Tip: When using std::string to hold the filename, you must use 653 + * .c_str() before passing it to this constructor. 654 + */ 655 + explicit 656 + basic_ofstream(const char* __s, 657 + ios_base::openmode __mode = ios_base::out|ios_base::trunc) 658 + : __ostream_type(), _M_filebuf() 659 + { 660 + this->init(&_M_filebuf); 661 + this->open(__s, __mode); 662 + } 663 + 664 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 665 + /** 666 + * @brief Create an output file stream. 667 + * @param s std::string specifying the filename. 668 + * @param mode Open file in specified mode (see std::ios_base). 669 + * 670 + * @c ios_base::out|ios_base::trunc is automatically included in 671 + * @a mode. 672 + */ 673 + explicit 674 + basic_ofstream(const std::string& __s, 675 + ios_base::openmode __mode = ios_base::out|ios_base::trunc) 676 + : __ostream_type(), _M_filebuf() 677 + { 678 + this->init(&_M_filebuf); 679 + this->open(__s, __mode); 680 + } 681 + #endif 682 + 683 + /** 684 + * @brief The destructor does nothing. 685 + * 686 + * The file is closed by the filebuf object, not the formatting 687 + * stream. 688 + */ 689 + ~basic_ofstream() 690 + { } 691 + 692 + // Members: 693 + /** 694 + * @brief Accessing the underlying buffer. 695 + * @return The current basic_filebuf buffer. 696 + * 697 + * This hides both signatures of std::basic_ios::rdbuf(). 698 + */ 699 + __filebuf_type* 700 + rdbuf() const 701 + { return const_cast<__filebuf_type*>(&_M_filebuf); } 702 + 703 + /** 704 + * @brief Wrapper to test for an open file. 705 + * @return @c rdbuf()->is_open() 706 + */ 707 + bool 708 + is_open() 709 + { return _M_filebuf.is_open(); } 710 + 711 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 712 + // 365. Lack of const-qualification in clause 27 713 + bool 714 + is_open() const 715 + { return _M_filebuf.is_open(); } 716 + 717 + /** 718 + * @brief Opens an external file. 719 + * @param s The name of the file. 720 + * @param mode The open mode flags. 721 + * 722 + * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that 723 + * function fails, @c failbit is set in the stream's error state. 724 + * 725 + * Tip: When using std::string to hold the filename, you must use 726 + * .c_str() before passing it to this constructor. 727 + */ 728 + void 729 + open(const char* __s, 730 + ios_base::openmode __mode = ios_base::out | ios_base::trunc) 731 + { 732 + if (!_M_filebuf.open(__s, __mode | ios_base::out)) 733 + this->setstate(ios_base::failbit); 734 + else 735 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 736 + // 409. Closing an fstream should clear error state 737 + this->clear(); 738 + } 739 + 740 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 741 + /** 742 + * @brief Opens an external file. 743 + * @param s The name of the file. 744 + * @param mode The open mode flags. 745 + * 746 + * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that 747 + * function fails, @c failbit is set in the stream's error state. 748 + */ 749 + void 750 + open(const std::string& __s, 751 + ios_base::openmode __mode = ios_base::out | ios_base::trunc) 752 + { 753 + if (!_M_filebuf.open(__s, __mode | ios_base::out)) 754 + this->setstate(ios_base::failbit); 755 + else 756 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 757 + // 409. Closing an fstream should clear error state 758 + this->clear(); 759 + } 760 + #endif 761 + 762 + /** 763 + * @brief Close the file. 764 + * 765 + * Calls @c std::basic_filebuf::close(). If that function 766 + * fails, @c failbit is set in the stream's error state. 767 + */ 768 + void 769 + close() 770 + { 771 + if (!_M_filebuf.close()) 772 + this->setstate(ios_base::failbit); 773 + } 774 + }; 775 + 776 + 777 + // [27.8.1.11] Template class basic_fstream 778 + /** 779 + * @brief Controlling input and output for files. 780 + * @ingroup io 781 + * 782 + * This class supports reading from and writing to named files, using 783 + * the inherited functions from std::basic_iostream. To control the 784 + * associated sequence, an instance of std::basic_filebuf is used, which 785 + * this page refers to as @c sb. 786 + */ 787 + template<typename _CharT, typename _Traits> 788 + class basic_fstream : public basic_iostream<_CharT, _Traits> 789 + { 790 + public: 791 + // Types: 792 + typedef _CharT char_type; 793 + typedef _Traits traits_type; 794 + typedef typename traits_type::int_type int_type; 795 + typedef typename traits_type::pos_type pos_type; 796 + typedef typename traits_type::off_type off_type; 797 + 798 + // Non-standard types: 799 + typedef basic_filebuf<char_type, traits_type> __filebuf_type; 800 + typedef basic_ios<char_type, traits_type> __ios_type; 801 + typedef basic_iostream<char_type, traits_type> __iostream_type; 802 + 803 + private: 804 + __filebuf_type _M_filebuf; 805 + 806 + public: 807 + // Constructors/destructor: 808 + /** 809 + * @brief Default constructor. 810 + * 811 + * Initializes @c sb using its default constructor, and passes 812 + * @c &sb to the base class initializer. Does not open any files 813 + * (you haven't given it a filename to open). 814 + */ 815 + basic_fstream() 816 + : __iostream_type(), _M_filebuf() 817 + { this->init(&_M_filebuf); } 818 + 819 + /** 820 + * @brief Create an input/output file stream. 821 + * @param s Null terminated string specifying the filename. 822 + * @param mode Open file in specified mode (see std::ios_base). 823 + * 824 + * Tip: When using std::string to hold the filename, you must use 825 + * .c_str() before passing it to this constructor. 826 + */ 827 + explicit 828 + basic_fstream(const char* __s, 829 + ios_base::openmode __mode = ios_base::in | ios_base::out) 830 + : __iostream_type(0), _M_filebuf() 831 + { 832 + this->init(&_M_filebuf); 833 + this->open(__s, __mode); 834 + } 835 + 836 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 837 + /** 838 + * @brief Create an input/output file stream. 839 + * @param s Null terminated string specifying the filename. 840 + * @param mode Open file in specified mode (see std::ios_base). 841 + */ 842 + explicit 843 + basic_fstream(const std::string& __s, 844 + ios_base::openmode __mode = ios_base::in | ios_base::out) 845 + : __iostream_type(0), _M_filebuf() 846 + { 847 + this->init(&_M_filebuf); 848 + this->open(__s, __mode); 849 + } 850 + #endif 851 + 852 + /** 853 + * @brief The destructor does nothing. 854 + * 855 + * The file is closed by the filebuf object, not the formatting 856 + * stream. 857 + */ 858 + ~basic_fstream() 859 + { } 860 + 861 + // Members: 862 + /** 863 + * @brief Accessing the underlying buffer. 864 + * @return The current basic_filebuf buffer. 865 + * 866 + * This hides both signatures of std::basic_ios::rdbuf(). 867 + */ 868 + __filebuf_type* 869 + rdbuf() const 870 + { return const_cast<__filebuf_type*>(&_M_filebuf); } 871 + 872 + /** 873 + * @brief Wrapper to test for an open file. 874 + * @return @c rdbuf()->is_open() 875 + */ 876 + bool 877 + is_open() 878 + { return _M_filebuf.is_open(); } 879 + 880 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 881 + // 365. Lack of const-qualification in clause 27 882 + bool 883 + is_open() const 884 + { return _M_filebuf.is_open(); } 885 + 886 + /** 887 + * @brief Opens an external file. 888 + * @param s The name of the file. 889 + * @param mode The open mode flags. 890 + * 891 + * Calls @c std::basic_filebuf::open(s,mode). If that 892 + * function fails, @c failbit is set in the stream's error state. 893 + * 894 + * Tip: When using std::string to hold the filename, you must use 895 + * .c_str() before passing it to this constructor. 896 + */ 897 + void 898 + open(const char* __s, 899 + ios_base::openmode __mode = ios_base::in | ios_base::out) 900 + { 901 + if (!_M_filebuf.open(__s, __mode)) 902 + this->setstate(ios_base::failbit); 903 + else 904 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 905 + // 409. Closing an fstream should clear error state 906 + this->clear(); 907 + } 908 + 909 + #ifdef __GXX_EXPERIMENTAL_CXX0X__ 910 + /** 911 + * @brief Opens an external file. 912 + * @param s The name of the file. 913 + * @param mode The open mode flags. 914 + * 915 + * Calls @c std::basic_filebuf::open(s,mode). If that 916 + * function fails, @c failbit is set in the stream's error state. 917 + */ 918 + void 919 + open(const std::string& __s, 920 + ios_base::openmode __mode = ios_base::in | ios_base::out) 921 + { 922 + if (!_M_filebuf.open(__s, __mode)) 923 + this->setstate(ios_base::failbit); 924 + else 925 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 926 + // 409. Closing an fstream should clear error state 927 + this->clear(); 928 + } 929 + #endif 930 + 931 + /** 932 + * @brief Close the file. 933 + * 934 + * Calls @c std::basic_filebuf::close(). If that function 935 + * fails, @c failbit is set in the stream's error state. 936 + */ 937 + void 938 + close() 939 + { 940 + if (!_M_filebuf.close()) 941 + this->setstate(ios_base::failbit); 942 + } 943 + }; 944 + 945 + _GLIBCXX_END_NAMESPACE_VERSION 946 + } // namespace 947 + 948 + // Darling MODIFICATION 949 + #include "fstream.tcc" 950 + 951 + #endif /* _GLIBCXX_FSTREAM */
+984
src/libstdc++darwin/fstream.tcc
··· 1 + // File based streams -*- C++ -*- 2 + 3 + // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 4 + // 2007, 2008, 2009, 2010, 2011 5 + // Free Software Foundation, Inc. 6 + // 7 + // This file is part of the GNU ISO C++ Library. This library is free 8 + // software; you can redistribute it and/or modify it under the 9 + // terms of the GNU General Public License as published by the 10 + // Free Software Foundation; either version 3, or (at your option) 11 + // any later version. 12 + 13 + // This library is distributed in the hope that it will be useful, 14 + // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + // GNU General Public License for more details. 17 + 18 + // Under Section 7 of GPL version 3, you are granted additional 19 + // permissions described in the GCC Runtime Library Exception, version 20 + // 3.1, as published by the Free Software Foundation. 21 + 22 + // You should have received a copy of the GNU General Public License and 23 + // a copy of the GCC Runtime Library Exception along with this program; 24 + // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 + // <http://www.gnu.org/licenses/>. 26 + 27 + /** @file bits/fstream.tcc 28 + * This is an internal header file, included by other library headers. 29 + * Do not attempt to use it directly. @headername{fstream} 30 + */ 31 + 32 + // 33 + // ISO C++ 14882: 27.8 File-based streams 34 + // 35 + 36 + #ifndef _FSTREAM_TCC 37 + #define _FSTREAM_TCC 1 38 + 39 + #pragma GCC system_header 40 + 41 + #include <bits/cxxabi_forced.h> 42 + 43 + namespace std _GLIBCXX_VISIBILITY(default) 44 + { 45 + _GLIBCXX_BEGIN_NAMESPACE_VERSION 46 + 47 + template<typename _CharT, typename _Traits> 48 + void 49 + basic_filebuf<_CharT, _Traits>:: 50 + _M_allocate_internal_buffer() 51 + { 52 + // Allocate internal buffer only if one doesn't already exist 53 + // (either allocated or provided by the user via setbuf). 54 + if (!_M_buf_allocated && !_M_buf) 55 + { 56 + _M_buf = new char_type[_M_buf_size]; 57 + _M_buf_allocated = true; 58 + } 59 + } 60 + 61 + template<typename _CharT, typename _Traits> 62 + void 63 + basic_filebuf<_CharT, _Traits>:: 64 + _M_destroy_internal_buffer() throw() 65 + { 66 + if (_M_buf_allocated) 67 + { 68 + delete [] _M_buf; 69 + _M_buf = 0; 70 + _M_buf_allocated = false; 71 + } 72 + delete [] _M_ext_buf; 73 + _M_ext_buf = 0; 74 + _M_ext_buf_size = 0; 75 + _M_ext_next = 0; 76 + _M_ext_end = 0; 77 + } 78 + 79 + template<typename _CharT, typename _Traits> 80 + basic_filebuf<_CharT, _Traits>:: 81 + basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock), 82 + _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(), 83 + _M_state_last(), _M_buf(0), _M_buf_size(BUFSIZ), 84 + _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(), 85 + _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false), 86 + _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0), 87 + _M_ext_end(0) 88 + { 89 + if (has_facet<__codecvt_type>(this->_M_buf_locale)) 90 + _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale); 91 + } 92 + 93 + template<typename _CharT, typename _Traits> 94 + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* 95 + basic_filebuf<_CharT, _Traits>:: 96 + open(const char* __s, ios_base::openmode __mode) 97 + { 98 + __filebuf_type *__ret = 0; 99 + if (!this->is_open()) 100 + { 101 + _M_file.open(__s, __mode); 102 + if (this->is_open()) 103 + { 104 + _M_allocate_internal_buffer(); 105 + _M_mode = __mode; 106 + 107 + // Setup initial buffer to 'uncommitted' mode. 108 + _M_reading = false; 109 + _M_writing = false; 110 + _M_set_buffer(-1); 111 + 112 + // Reset to initial state. 113 + _M_state_last = _M_state_cur = _M_state_beg; 114 + 115 + // 27.8.1.3,4 116 + if ((__mode & ios_base::ate) 117 + && this->seekoff(0, ios_base::end, __mode) 118 + == pos_type(off_type(-1))) 119 + this->close(); 120 + else 121 + __ret = this; 122 + } 123 + } 124 + return __ret; 125 + } 126 + 127 + template<typename _CharT, typename _Traits> 128 + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* 129 + basic_filebuf<_CharT, _Traits>:: 130 + close() 131 + { 132 + if (!this->is_open()) 133 + return 0; 134 + 135 + bool __testfail = false; 136 + { 137 + // NB: Do this here so that re-opened filebufs will be cool... 138 + struct __close_sentry 139 + { 140 + basic_filebuf *__fb; 141 + __close_sentry (basic_filebuf *__fbi): __fb(__fbi) { } 142 + ~__close_sentry () 143 + { 144 + __fb->_M_mode = ios_base::openmode(0); 145 + __fb->_M_pback_init = false; 146 + __fb->_M_destroy_internal_buffer(); 147 + __fb->_M_reading = false; 148 + __fb->_M_writing = false; 149 + __fb->_M_set_buffer(-1); 150 + __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg; 151 + } 152 + } __cs (this); 153 + 154 + __try 155 + { 156 + if (!_M_terminate_output()) 157 + __testfail = true; 158 + } 159 + __catch(__cxxabiv1::__forced_unwind&) 160 + { 161 + _M_file.close(); 162 + __throw_exception_again; 163 + } 164 + __catch(...) 165 + { __testfail = true; } 166 + } 167 + 168 + if (!_M_file.close()) 169 + __testfail = true; 170 + 171 + if (__testfail) 172 + return 0; 173 + else 174 + return this; 175 + } 176 + 177 + template<typename _CharT, typename _Traits> 178 + streamsize 179 + basic_filebuf<_CharT, _Traits>:: 180 + showmanyc() 181 + { 182 + streamsize __ret = -1; 183 + const bool __testin = _M_mode & ios_base::in; 184 + if (__testin && this->is_open()) 185 + { 186 + // For a stateful encoding (-1) the pending sequence might be just 187 + // shift and unshift prefixes with no actual character. 188 + __ret = this->egptr() - this->gptr(); 189 + 190 + #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM 191 + // About this workaround, see libstdc++/20806. 192 + const bool __testbinary = _M_mode & ios_base::binary; 193 + if (__check_facet(_M_codecvt).encoding() >= 0 194 + && __testbinary) 195 + #else 196 + if (__check_facet(_M_codecvt).encoding() >= 0) 197 + #endif 198 + __ret += _M_file.showmanyc() / _M_codecvt->max_length(); 199 + } 200 + return __ret; 201 + } 202 + 203 + template<typename _CharT, typename _Traits> 204 + typename basic_filebuf<_CharT, _Traits>::int_type 205 + basic_filebuf<_CharT, _Traits>:: 206 + underflow() 207 + { 208 + int_type __ret = traits_type::eof(); 209 + const bool __testin = _M_mode & ios_base::in; 210 + if (__testin) 211 + { 212 + if (_M_writing) 213 + { 214 + if (overflow() == traits_type::eof()) 215 + return __ret; 216 + _M_set_buffer(-1); 217 + _M_writing = false; 218 + } 219 + // Check for pback madness, and if so switch back to the 220 + // normal buffers and jet outta here before expensive 221 + // fileops happen... 222 + _M_destroy_pback(); 223 + 224 + if (this->gptr() < this->egptr()) 225 + return traits_type::to_int_type(*this->gptr()); 226 + 227 + // Get and convert input sequence. 228 + const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; 229 + 230 + // Will be set to true if ::read() returns 0 indicating EOF. 231 + bool __got_eof = false; 232 + // Number of internal characters produced. 233 + streamsize __ilen = 0; 234 + codecvt_base::result __r = codecvt_base::ok; 235 + if (__check_facet(_M_codecvt).always_noconv()) 236 + { 237 + __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()), 238 + __buflen); 239 + if (__ilen == 0) 240 + __got_eof = true; 241 + } 242 + else 243 + { 244 + // Worst-case number of external bytes. 245 + // XXX Not done encoding() == -1. 246 + const int __enc = _M_codecvt->encoding(); 247 + streamsize __blen; // Minimum buffer size. 248 + streamsize __rlen; // Number of chars to read. 249 + if (__enc > 0) 250 + __blen = __rlen = __buflen * __enc; 251 + else 252 + { 253 + __blen = __buflen + _M_codecvt->max_length() - 1; 254 + __rlen = __buflen; 255 + } 256 + const streamsize __remainder = _M_ext_end - _M_ext_next; 257 + __rlen = __rlen > __remainder ? __rlen - __remainder : 0; 258 + 259 + // An imbue in 'read' mode implies first converting the external 260 + // chars already present. 261 + if (_M_reading && this->egptr() == this->eback() && __remainder) 262 + __rlen = 0; 263 + 264 + // Allocate buffer if necessary and move unconverted 265 + // bytes to front. 266 + if (_M_ext_buf_size < __blen) 267 + { 268 + char* __buf = new char[__blen]; 269 + if (__remainder) 270 + __builtin_memcpy(__buf, _M_ext_next, __remainder); 271 + 272 + delete [] _M_ext_buf; 273 + _M_ext_buf = __buf; 274 + _M_ext_buf_size = __blen; 275 + } 276 + else if (__remainder) 277 + __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); 278 + 279 + _M_ext_next = _M_ext_buf; 280 + _M_ext_end = _M_ext_buf + __remainder; 281 + _M_state_last = _M_state_cur; 282 + 283 + do 284 + { 285 + if (__rlen > 0) 286 + { 287 + // Sanity check! 288 + // This may fail if the return value of 289 + // codecvt::max_length() is bogus. 290 + if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) 291 + { 292 + __throw_ios_failure(__N("basic_filebuf::underflow " 293 + "codecvt::max_length() " 294 + "is not valid")); 295 + } 296 + streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); 297 + if (__elen == 0) 298 + __got_eof = true; 299 + else if (__elen == -1) 300 + break; 301 + _M_ext_end += __elen; 302 + } 303 + 304 + char_type* __iend = this->eback(); 305 + if (_M_ext_next < _M_ext_end) 306 + __r = _M_codecvt->in(_M_state_cur, _M_ext_next, 307 + _M_ext_end, _M_ext_next, 308 + this->eback(), 309 + this->eback() + __buflen, __iend); 310 + if (__r == codecvt_base::noconv) 311 + { 312 + size_t __avail = _M_ext_end - _M_ext_buf; 313 + __ilen = std::min(__avail, __buflen); 314 + traits_type::copy(this->eback(), 315 + reinterpret_cast<char_type*> 316 + (_M_ext_buf), __ilen); 317 + _M_ext_next = _M_ext_buf + __ilen; 318 + } 319 + else 320 + __ilen = __iend - this->eback(); 321 + 322 + // _M_codecvt->in may return error while __ilen > 0: this is 323 + // ok, and actually occurs in case of mixed encodings (e.g., 324 + // XML files). 325 + if (__r == codecvt_base::error) 326 + break; 327 + 328 + __rlen = 1; 329 + } 330 + while (__ilen == 0 && !__got_eof); 331 + } 332 + 333 + if (__ilen > 0) 334 + { 335 + _M_set_buffer(__ilen); 336 + _M_reading = true; 337 + __ret = traits_type::to_int_type(*this->gptr()); 338 + } 339 + else if (__got_eof) 340 + { 341 + // If the actual end of file is reached, set 'uncommitted' 342 + // mode, thus allowing an immediate write without an 343 + // intervening seek. 344 + _M_set_buffer(-1); 345 + _M_reading = false; 346 + // However, reaching it while looping on partial means that 347 + // the file has got an incomplete character. 348 + if (__r == codecvt_base::partial) 349 + __throw_ios_failure(__N("basic_filebuf::underflow " 350 + "incomplete character in file")); 351 + } 352 + else if (__r == codecvt_base::error) 353 + __throw_ios_failure(__N("basic_filebuf::underflow " 354 + "invalid byte sequence in file")); 355 + else 356 + __throw_ios_failure(__N("basic_filebuf::underflow " 357 + "error reading the file")); 358 + } 359 + return __ret; 360 + } 361 + 362 + template<typename _CharT, typename _Traits> 363 + typename basic_filebuf<_CharT, _Traits>::int_type 364 + basic_filebuf<_CharT, _Traits>:: 365 + pbackfail(int_type __i) 366 + { 367 + int_type __ret = traits_type::eof(); 368 + const bool __testin = _M_mode & ios_base::in; 369 + if (__testin) 370 + { 371 + if (_M_writing) 372 + { 373 + if (overflow() == traits_type::eof()) 374 + return __ret; 375 + _M_set_buffer(-1); 376 + _M_writing = false; 377 + } 378 + // Remember whether the pback buffer is active, otherwise below 379 + // we may try to store in it a second char (libstdc++/9761). 380 + const bool __testpb = _M_pback_init; 381 + const bool __testeof = traits_type::eq_int_type(__i, __ret); 382 + int_type __tmp; 383 + if (this->eback() < this->gptr()) 384 + { 385 + this->gbump(-1); 386 + __tmp = traits_type::to_int_type(*this->gptr()); 387 + } 388 + else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1))) 389 + { 390 + __tmp = this->underflow(); 391 + if (traits_type::eq_int_type(__tmp, __ret)) 392 + return __ret; 393 + } 394 + else 395 + { 396 + // At the beginning of the buffer, need to make a 397 + // putback position available. But the seek may fail 398 + // (f.i., at the beginning of a file, see 399 + // libstdc++/9439) and in that case we return 400 + // traits_type::eof(). 401 + return __ret; 402 + } 403 + 404 + // Try to put back __i into input sequence in one of three ways. 405 + // Order these tests done in is unspecified by the standard. 406 + if (!__testeof && traits_type::eq_int_type(__i, __tmp)) 407 + __ret = __i; 408 + else if (__testeof) 409 + __ret = traits_type::not_eof(__i); 410 + else if (!__testpb) 411 + { 412 + _M_create_pback(); 413 + _M_reading = true; 414 + *this->gptr() = traits_type::to_char_type(__i); 415 + __ret = __i; 416 + } 417 + } 418 + return __ret; 419 + } 420 + 421 + template<typename _CharT, typename _Traits> 422 + typename basic_filebuf<_CharT, _Traits>::int_type 423 + basic_filebuf<_CharT, _Traits>:: 424 + overflow(int_type __c) 425 + { 426 + int_type __ret = traits_type::eof(); 427 + const bool __testeof = traits_type::eq_int_type(__c, __ret); 428 + const bool __testout = _M_mode & ios_base::out; 429 + if (__testout) 430 + { 431 + if (_M_reading) 432 + { 433 + _M_destroy_pback(); 434 + const int __gptr_off = _M_get_ext_pos(_M_state_last); 435 + if (_M_seek(__gptr_off, ios_base::cur, _M_state_last) 436 + == pos_type(off_type(-1))) 437 + return __ret; 438 + } 439 + if (this->pbase() < this->pptr()) 440 + { 441 + // If appropriate, append the overflow char. 442 + if (!__testeof) 443 + { 444 + *this->pptr() = traits_type::to_char_type(__c); 445 + this->pbump(1); 446 + } 447 + 448 + // Convert pending sequence to external representation, 449 + // and output. 450 + if (_M_convert_to_external(this->pbase(), 451 + this->pptr() - this->pbase())) 452 + { 453 + _M_set_buffer(0); 454 + __ret = traits_type::not_eof(__c); 455 + } 456 + } 457 + else if (_M_buf_size > 1) 458 + { 459 + // Overflow in 'uncommitted' mode: set _M_writing, set 460 + // the buffer to the initial 'write' mode, and put __c 461 + // into the buffer. 462 + _M_set_buffer(0); 463 + _M_writing = true; 464 + if (!__testeof) 465 + { 466 + *this->pptr() = traits_type::to_char_type(__c); 467 + this->pbump(1); 468 + } 469 + __ret = traits_type::not_eof(__c); 470 + } 471 + else 472 + { 473 + // Unbuffered. 474 + char_type __conv = traits_type::to_char_type(__c); 475 + if (__testeof || _M_convert_to_external(&__conv, 1)) 476 + { 477 + _M_writing = true; 478 + __ret = traits_type::not_eof(__c); 479 + } 480 + } 481 + } 482 + return __ret; 483 + } 484 + 485 + template<typename _CharT, typename _Traits> 486 + bool 487 + basic_filebuf<_CharT, _Traits>:: 488 + _M_convert_to_external(_CharT* __ibuf, streamsize __ilen) 489 + { 490 + // Sizes of external and pending output. 491 + streamsize __elen; 492 + streamsize __plen; 493 + if (__check_facet(_M_codecvt).always_noconv()) 494 + { 495 + __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); 496 + __plen = __ilen; 497 + } 498 + else 499 + { 500 + // Worst-case number of external bytes needed. 501 + // XXX Not done encoding() == -1. 502 + streamsize __blen = __ilen * _M_codecvt->max_length(); 503 + char* __buf = static_cast<char*>(__builtin_alloca(__blen)); 504 + 505 + char* __bend; 506 + const char_type* __iend; 507 + codecvt_base::result __r; 508 + __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, 509 + __iend, __buf, __buf + __blen, __bend); 510 + 511 + if (__r == codecvt_base::ok || __r == codecvt_base::partial) 512 + __blen = __bend - __buf; 513 + else if (__r == codecvt_base::noconv) 514 + { 515 + // Same as the always_noconv case above. 516 + __buf = reinterpret_cast<char*>(__ibuf); 517 + __blen = __ilen; 518 + } 519 + else 520 + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " 521 + "conversion error")); 522 + 523 + __elen = _M_file.xsputn(__buf, __blen); 524 + __plen = __blen; 525 + 526 + // Try once more for partial conversions. 527 + if (__r == codecvt_base::partial && __elen == __plen) 528 + { 529 + const char_type* __iresume = __iend; 530 + streamsize __rlen = this->pptr() - __iend; 531 + __r = _M_codecvt->out(_M_state_cur, __iresume, 532 + __iresume + __rlen, __iend, __buf, 533 + __buf + __blen, __bend); 534 + if (__r != codecvt_base::error) 535 + { 536 + __rlen = __bend - __buf; 537 + __elen = _M_file.xsputn(__buf, __rlen); 538 + __plen = __rlen; 539 + } 540 + else 541 + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " 542 + "conversion error")); 543 + } 544 + } 545 + return __elen == __plen; 546 + } 547 + 548 + template<typename _CharT, typename _Traits> 549 + streamsize 550 + basic_filebuf<_CharT, _Traits>:: 551 + xsgetn(_CharT* __s, streamsize __n) 552 + { 553 + // Clear out pback buffer before going on to the real deal... 554 + streamsize __ret = 0; 555 + if (_M_pback_init) 556 + { 557 + if (__n > 0 && this->gptr() == this->eback()) 558 + { 559 + *__s++ = *this->gptr(); // emulate non-underflowing sbumpc 560 + this->gbump(1); 561 + __ret = 1; 562 + --__n; 563 + } 564 + _M_destroy_pback(); 565 + } 566 + else if (_M_writing) 567 + { 568 + if (overflow() == traits_type::eof()) 569 + return __ret; 570 + _M_set_buffer(-1); 571 + _M_writing = false; 572 + } 573 + 574 + // Optimization in the always_noconv() case, to be generalized in the 575 + // future: when __n > __buflen we read directly instead of using the 576 + // buffer repeatedly. 577 + const bool __testin = _M_mode & ios_base::in; 578 + const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; 579 + 580 + if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() 581 + && __testin) 582 + { 583 + // First, copy the chars already present in the buffer. 584 + const streamsize __avail = this->egptr() - this->gptr(); 585 + if (__avail != 0) 586 + { 587 + traits_type::copy(__s, this->gptr(), __avail); 588 + __s += __avail; 589 + this->setg(this->eback(), this->gptr() + __avail, 590 + this->egptr()); 591 + __ret += __avail; 592 + __n -= __avail; 593 + } 594 + 595 + // Need to loop in case of short reads (relatively common 596 + // with pipes). 597 + streamsize __len; 598 + for (;;) 599 + { 600 + __len = _M_file.xsgetn(reinterpret_cast<char*>(__s), 601 + __n); 602 + if (__len == -1) 603 + __throw_ios_failure(__N("basic_filebuf::xsgetn " 604 + "error reading the file")); 605 + if (__len == 0) 606 + break; 607 + 608 + __n -= __len; 609 + __ret += __len; 610 + if (__n == 0) 611 + break; 612 + 613 + __s += __len; 614 + } 615 + 616 + if (__n == 0) 617 + { 618 + _M_set_buffer(0); 619 + _M_reading = true; 620 + } 621 + else if (__len == 0) 622 + { 623 + // If end of file is reached, set 'uncommitted' 624 + // mode, thus allowing an immediate write without 625 + // an intervening seek. 626 + _M_set_buffer(-1); 627 + _M_reading = false; 628 + } 629 + } 630 + else 631 + __ret += __streambuf_type::xsgetn(__s, __n); 632 + 633 + return __ret; 634 + } 635 + 636 + template<typename _CharT, typename _Traits> 637 + streamsize 638 + basic_filebuf<_CharT, _Traits>:: 639 + xsputn(const _CharT* __s, streamsize __n) 640 + { 641 + streamsize __ret = 0; 642 + // Optimization in the always_noconv() case, to be generalized in the 643 + // future: when __n is sufficiently large we write directly instead of 644 + // using the buffer. 645 + const bool __testout = _M_mode & ios_base::out; 646 + if (__check_facet(_M_codecvt).always_noconv() 647 + && __testout && !_M_reading) 648 + { 649 + // Measurement would reveal the best choice. 650 + const streamsize __chunk = 1ul << 10; 651 + streamsize __bufavail = this->epptr() - this->pptr(); 652 + 653 + // Don't mistake 'uncommitted' mode buffered with unbuffered. 654 + if (!_M_writing && _M_buf_size > 1) 655 + __bufavail = _M_buf_size - 1; 656 + 657 + const streamsize __limit = std::min(__chunk, __bufavail); 658 + if (__n >= __limit) 659 + { 660 + const streamsize __buffill = this->pptr() - this->pbase(); 661 + const char* __buf = reinterpret_cast<const char*>(this->pbase()); 662 + __ret = _M_file.xsputn_2(__buf, __buffill, 663 + reinterpret_cast<const char*>(__s), 664 + __n); 665 + if (__ret == __buffill + __n) 666 + { 667 + _M_set_buffer(0); 668 + _M_writing = true; 669 + } 670 + if (__ret > __buffill) 671 + __ret -= __buffill; 672 + else 673 + __ret = 0; 674 + } 675 + else 676 + __ret = __streambuf_type::xsputn(__s, __n); 677 + } 678 + else 679 + __ret = __streambuf_type::xsputn(__s, __n); 680 + return __ret; 681 + } 682 + 683 + template<typename _CharT, typename _Traits> 684 + typename basic_filebuf<_CharT, _Traits>::__streambuf_type* 685 + basic_filebuf<_CharT, _Traits>:: 686 + setbuf(char_type* __s, streamsize __n) 687 + { 688 + if (!this->is_open()) 689 + { 690 + if (__s == 0 && __n == 0) 691 + _M_buf_size = 1; 692 + else if (__s && __n > 0) 693 + { 694 + // This is implementation-defined behavior, and assumes that 695 + // an external char_type array of length __n exists and has 696 + // been pre-allocated. If this is not the case, things will 697 + // quickly blow up. When __n > 1, __n - 1 positions will be 698 + // used for the get area, __n - 1 for the put area and 1 699 + // position to host the overflow char of a full put area. 700 + // When __n == 1, 1 position will be used for the get area 701 + // and 0 for the put area, as in the unbuffered case above. 702 + _M_buf = __s; 703 + _M_buf_size = __n; 704 + } 705 + } 706 + return this; 707 + } 708 + 709 + 710 + // According to 27.8.1.4 p11 - 13, seekoff should ignore the last 711 + // argument (of type openmode). 712 + template<typename _CharT, typename _Traits> 713 + typename basic_filebuf<_CharT, _Traits>::pos_type 714 + basic_filebuf<_CharT, _Traits>:: 715 + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) 716 + { 717 + int __width = 0; 718 + if (_M_codecvt) 719 + __width = _M_codecvt->encoding(); 720 + if (__width < 0) 721 + __width = 0; 722 + 723 + pos_type __ret = pos_type(off_type(-1)); 724 + const bool __testfail = __off != 0 && __width <= 0; 725 + if (this->is_open() && !__testfail) 726 + { 727 + // tellg and tellp queries do not affect any state, unless 728 + // ! always_noconv and the put sequence is not empty. 729 + // In that case, determining the position requires converting the 730 + // put sequence. That doesn't use ext_buf, so requires a flush. 731 + bool __no_movement = __way == ios_base::cur && __off == 0 732 + && (!_M_writing || _M_codecvt->always_noconv()); 733 + 734 + // Ditch any pback buffers to avoid confusion. 735 + if (!__no_movement) 736 + _M_destroy_pback(); 737 + 738 + // Correct state at destination. Note that this is the correct 739 + // state for the current position during output, because 740 + // codecvt::unshift() returns the state to the initial state. 741 + // This is also the correct state at the end of the file because 742 + // an unshift sequence should have been written at the end. 743 + __state_type __state = _M_state_beg; 744 + off_type __computed_off = __off * __width; 745 + if (_M_reading && __way == ios_base::cur) 746 + { 747 + __state = _M_state_last; 748 + __computed_off += _M_get_ext_pos(__state); 749 + } 750 + if (!__no_movement) 751 + __ret = _M_seek(__computed_off, __way, __state); 752 + else 753 + { 754 + if (_M_writing) 755 + __computed_off = this->pptr() - this->pbase(); 756 + 757 + off_type __file_off = _M_file.seekoff(0, ios_base::cur); 758 + if (__file_off != off_type(-1)) 759 + { 760 + __ret = __file_off + __computed_off; 761 + __ret.state(__state); 762 + } 763 + } 764 + } 765 + return __ret; 766 + } 767 + 768 + // _GLIBCXX_RESOLVE_LIB_DEFECTS 769 + // 171. Strange seekpos() semantics due to joint position 770 + // According to the resolution of DR 171, seekpos should ignore the last 771 + // argument (of type openmode). 772 + template<typename _CharT, typename _Traits> 773 + typename basic_filebuf<_CharT, _Traits>::pos_type 774 + basic_filebuf<_CharT, _Traits>:: 775 + seekpos(pos_type __pos, ios_base::openmode) 776 + { 777 + pos_type __ret = pos_type(off_type(-1)); 778 + if (this->is_open()) 779 + { 780 + // Ditch any pback buffers to avoid confusion. 781 + _M_destroy_pback(); 782 + __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state()); 783 + } 784 + return __ret; 785 + } 786 + 787 + template<typename _CharT, typename _Traits> 788 + typename basic_filebuf<_CharT, _Traits>::pos_type 789 + basic_filebuf<_CharT, _Traits>:: 790 + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state) 791 + { 792 + pos_type __ret = pos_type(off_type(-1)); 793 + if (_M_terminate_output()) 794 + { 795 + off_type __file_off = _M_file.seekoff(__off, __way); 796 + if (__file_off != off_type(-1)) 797 + { 798 + _M_reading = false; 799 + _M_writing = false; 800 + _M_ext_next = _M_ext_end = _M_ext_buf; 801 + _M_set_buffer(-1); 802 + _M_state_cur = __state; 803 + __ret = __file_off; 804 + __ret.state(_M_state_cur); 805 + } 806 + } 807 + return __ret; 808 + } 809 + 810 + // Returns the distance from the end of the ext buffer to the point 811 + // corresponding to gptr(). This is a negative value. Updates __state 812 + // from eback() correspondence to gptr(). 813 + template<typename _CharT, typename _Traits> 814 + int basic_filebuf<_CharT, _Traits>:: 815 + _M_get_ext_pos(__state_type& __state) 816 + { 817 + if (_M_codecvt->always_noconv()) 818 + return this->gptr() - this->egptr(); 819 + else 820 + { 821 + // Calculate offset from _M_ext_buf that corresponds to 822 + // gptr(). Precondition: __state == _M_state_last, which 823 + // corresponds to eback(). 824 + const int __gptr_off = 825 + _M_codecvt->length(__state, _M_ext_buf, _M_ext_next, 826 + this->gptr() - this->eback()); 827 + return _M_ext_buf + __gptr_off - _M_ext_end; 828 + } 829 + } 830 + 831 + template<typename _CharT, typename _Traits> 832 + bool 833 + basic_filebuf<_CharT, _Traits>:: 834 + _M_terminate_output() 835 + { 836 + // Part one: update the output sequence. 837 + bool __testvalid = true; 838 + if (this->pbase() < this->pptr()) 839 + { 840 + const int_type __tmp = this->overflow(); 841 + if (traits_type::eq_int_type(__tmp, traits_type::eof())) 842 + __testvalid = false; 843 + } 844 + 845 + // Part two: output unshift sequence. 846 + if (_M_writing && !__check_facet(_M_codecvt).always_noconv() 847 + && __testvalid) 848 + { 849 + // Note: this value is arbitrary, since there is no way to 850 + // get the length of the unshift sequence from codecvt, 851 + // without calling unshift. 852 + const size_t __blen = 128; 853 + char __buf[__blen]; 854 + codecvt_base::result __r; 855 + streamsize __ilen = 0; 856 + 857 + do 858 + { 859 + char* __next; 860 + __r = _M_codecvt->unshift(_M_state_cur, __buf, 861 + __buf + __blen, __next); 862 + if (__r == codecvt_base::error) 863 + __testvalid = false; 864 + else if (__r == codecvt_base::ok || 865 + __r == codecvt_base::partial) 866 + { 867 + __ilen = __next - __buf; 868 + if (__ilen > 0) 869 + { 870 + const streamsize __elen = _M_file.xsputn(__buf, __ilen); 871 + if (__elen != __ilen) 872 + __testvalid = false; 873 + } 874 + } 875 + } 876 + while (__r == codecvt_base::partial && __ilen > 0 && __testvalid); 877 + 878 + if (__testvalid) 879 + { 880 + // This second call to overflow() is required by the standard, 881 + // but it's not clear why it's needed, since the output buffer 882 + // should be empty by this point (it should have been emptied 883 + // in the first call to overflow()). 884 + const int_type __tmp = this->overflow(); 885 + if (traits_type::eq_int_type(__tmp, traits_type::eof())) 886 + __testvalid = false; 887 + } 888 + } 889 + return __testvalid; 890 + } 891 + 892 + template<typename _CharT, typename _Traits> 893 + int 894 + basic_filebuf<_CharT, _Traits>:: 895 + sync() 896 + { 897 + // Make sure that the internal buffer resyncs its idea of 898 + // the file position with the external file. 899 + int __ret = 0; 900 + if (this->pbase() < this->pptr()) 901 + { 902 + const int_type __tmp = this->overflow(); 903 + if (traits_type::eq_int_type(__tmp, traits_type::eof())) 904 + __ret = -1; 905 + } 906 + return __ret; 907 + } 908 + 909 + template<typename _CharT, typename _Traits> 910 + void 911 + basic_filebuf<_CharT, _Traits>:: 912 + imbue(const locale& __loc) 913 + { 914 + bool __testvalid = true; 915 + 916 + const __codecvt_type* _M_codecvt_tmp = 0; 917 + if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) 918 + _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc); 919 + 920 + if (this->is_open()) 921 + { 922 + // encoding() == -1 is ok only at the beginning. 923 + if ((_M_reading || _M_writing) 924 + && __check_facet(_M_codecvt).encoding() == -1) 925 + __testvalid = false; 926 + else 927 + { 928 + if (_M_reading) 929 + { 930 + if (__check_facet(_M_codecvt).always_noconv()) 931 + { 932 + if (_M_codecvt_tmp 933 + && !__check_facet(_M_codecvt_tmp).always_noconv()) 934 + __testvalid = this->seekoff(0, ios_base::cur, _M_mode) 935 + != pos_type(off_type(-1)); 936 + } 937 + else 938 + { 939 + // External position corresponding to gptr(). 940 + _M_ext_next = _M_ext_buf 941 + + _M_codecvt->length(_M_state_last, _M_ext_buf, 942 + _M_ext_next, 943 + this->gptr() - this->eback()); 944 + const streamsize __remainder = _M_ext_end - _M_ext_next; 945 + if (__remainder) 946 + __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); 947 + 948 + _M_ext_next = _M_ext_buf; 949 + _M_ext_end = _M_ext_buf + __remainder; 950 + _M_set_buffer(-1); 951 + _M_state_last = _M_state_cur = _M_state_beg; 952 + } 953 + } 954 + else if (_M_writing && (__testvalid = _M_terminate_output())) 955 + _M_set_buffer(-1); 956 + } 957 + } 958 + 959 + if (__testvalid) 960 + _M_codecvt = _M_codecvt_tmp; 961 + else 962 + _M_codecvt = 0; 963 + } 964 + 965 + // Inhibit implicit instantiations for required instantiations, 966 + // which are defined via explicit instantiations elsewhere. 967 + #if _GLIBCXX_EXTERN_TEMPLATE 968 + extern template class basic_filebuf<char>; 969 + extern template class basic_ifstream<char>; 970 + extern template class basic_ofstream<char>; 971 + extern template class basic_fstream<char>; 972 + 973 + #ifdef _GLIBCXX_USE_WCHAR_T 974 + extern template class basic_filebuf<wchar_t>; 975 + extern template class basic_ifstream<wchar_t>; 976 + extern template class basic_ofstream<wchar_t>; 977 + extern template class basic_fstream<wchar_t>; 978 + #endif 979 + #endif 980 + 981 + _GLIBCXX_END_NAMESPACE_VERSION 982 + } // namespace std 983 + 984 + #endif
+3
src/libstdc++darwin/genrenames.txt
··· 1 + nm filebuf_abi_fix.o | grep basic_filebuf | grep -v Ev | cut -f 3 -d' ' | sed '/^$/d' > orignames.txt 2 + ( for line in $(cat orignames.txt ); do echo "$line __darwin_$line"; done ) > renames.list 3 + ( for line in $(cat orignames.txt ); do echo "$line = __darwin_$line;"; done ) > renames.cmd
+26
src/libstdc++darwin/renames.cmd
··· 1 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE13_M_set_bufferEl = _ZNSt13basic_filebufIcSt11char_traitsIcEE13_M_set_bufferEl ; 2 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE14_M_get_ext_posER11__mbstate_t = _ZNSt13basic_filebufIcSt11char_traitsIcEE14_M_get_ext_posER11__mbstate_t ; 3 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE22_M_convert_to_externalEPcl = _ZNSt13basic_filebufIcSt11char_traitsIcEE22_M_convert_to_externalEPcl ; 4 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode = _ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode ; 5 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE5imbueERKSt6locale = _ZNSt13basic_filebufIcSt11char_traitsIcEE5imbueERKSt6locale ; 6 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE6setbufEPcl = _ZNSt13basic_filebufIcSt11char_traitsIcEE6setbufEPcl ; 7 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE6xsgetnEPcl = _ZNSt13basic_filebufIcSt11char_traitsIcEE6xsgetnEPcl ; 8 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE6xsputnEPKcl = _ZNSt13basic_filebufIcSt11char_traitsIcEE6xsputnEPKcl ; 9 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE7_M_seekElSt12_Ios_Seekdir11__mbstate_t = _ZNSt13basic_filebufIcSt11char_traitsIcEE7_M_seekElSt12_Ios_Seekdir11__mbstate_t ; 10 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode = _ZNSt13basic_filebufIcSt11char_traitsIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode ; 11 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode = _ZNSt13basic_filebufIcSt11char_traitsIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode ; 12 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE8overflowEi = _ZNSt13basic_filebufIcSt11char_traitsIcEE8overflowEi ; 13 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEE9pbackfailEi = _ZNSt13basic_filebufIcSt11char_traitsIcEE9pbackfailEi ; 14 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEEC2Ev = _ZNSt13basic_filebufIcSt11char_traitsIcEEC2Ev ; 15 + __darwin__ZNSt13basic_filebufIcSt11char_traitsIcEED2Ev = _ZNSt13basic_filebufIcSt11char_traitsIcEED2Ev ; 16 + __darwin__ZNSt15basic_streambufIcSt11char_traitsIcEE5uflowEv = _ZNSt15basic_streambufIcSt11char_traitsIcEE5uflowEv ; 17 + __darwin__ZNSt9basic_iosIcSt11char_traitsIcEEC2Ev = _ZNSt9basic_iosIcSt11char_traitsIcEEC2Ev ; 18 + __darwin__ZNSoC2EPSt15basic_streambufIcSt11char_traitsIcEE = _ZNSoC2EPSt15basic_streambufIcSt11char_traitsIcEE ; 19 + 20 + xx__darwin__ZTISt13basic_filebufIcSt11char_traitsIcEE = _ZTISt13basic_filebufIcSt11char_traitsIcEE ; 21 + xx__darwin__ZTSSt13basic_filebufIcSt11char_traitsIcEE = _ZTSSt13basic_filebufIcSt11char_traitsIcEE ; 22 + xx__darwin__ZTVSt13basic_filebufIcSt11char_traitsIcEE = _ZTVSt13basic_filebufIcSt11char_traitsIcEE ; 23 + xx_ZTSSt13basic_filebufIcSt11char_traitsIcEE = _ZTSSt13basic_filebufIcSt11char_traitsIcEE ; 24 + xx_ZTSSt13basic_filebufIcSt11char_traitsIcEE = _ZTSSt13basic_filebufIcSt11char_traitsIcEE ; 25 + xx_ZTVSt13basic_filebufIcSt11char_traitsIcEE = _ZTVSt13basic_filebufIcSt11char_traitsIcEE ; 26 + xx_ZTISt13basic_filebufIcSt11char_traitsIcEE = _ZTISt13basic_filebufIcSt11char_traitsIcEE ;