comparison lib/Support/raw_ostream.cpp @ 77:54457678186b

LLVM 3.6
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Mon, 08 Sep 2014 22:06:00 +0900
parents 95c75e76d11b
children 60c9769439b8
comparison
equal deleted inserted replaced
34:e874dbf0ad9d 77:54457678186b
20 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/FileSystem.h" 21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/Format.h" 22 #include "llvm/Support/Format.h"
23 #include "llvm/Support/Process.h" 23 #include "llvm/Support/Process.h"
24 #include "llvm/Support/Program.h" 24 #include "llvm/Support/Program.h"
25 #include "llvm/Support/system_error.h"
26 #include <cctype> 25 #include <cctype>
27 #include <cerrno> 26 #include <cerrno>
28 #include <sys/stat.h> 27 #include <sys/stat.h>
28 #include <system_error>
29 29
30 // <fcntl.h> may provide O_BINARY. 30 // <fcntl.h> may provide O_BINARY.
31 #if defined(HAVE_FCNTL_H) 31 #if defined(HAVE_FCNTL_H)
32 # include <fcntl.h> 32 # include <fcntl.h>
33 #endif 33 #endif
85 SetUnbuffered(); 85 SetUnbuffered();
86 } 86 }
87 87
88 void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, 88 void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
89 BufferKind Mode) { 89 BufferKind Mode) {
90 assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) || 90 assert(((Mode == Unbuffered && !BufferStart && Size == 0) ||
91 (Mode != Unbuffered && BufferStart && Size)) && 91 (Mode != Unbuffered && BufferStart && Size != 0)) &&
92 "stream must be unbuffered or have at least one byte"); 92 "stream must be unbuffered or have at least one byte");
93 // Make sure the current buffer is free of content (we can't flush here; the 93 // Make sure the current buffer is free of content (we can't flush here; the
94 // child buffer management logic will be in write_impl). 94 // child buffer management logic will be in write_impl).
95 assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!"); 95 assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
96 96
225 raw_ostream &raw_ostream::operator<<(double N) { 225 raw_ostream &raw_ostream::operator<<(double N) {
226 #ifdef _WIN32 226 #ifdef _WIN32
227 // On MSVCRT and compatible, output of %e is incompatible to Posix 227 // On MSVCRT and compatible, output of %e is incompatible to Posix
228 // by default. Number of exponent digits should be at least 2. "%+03d" 228 // by default. Number of exponent digits should be at least 2. "%+03d"
229 // FIXME: Implement our formatter to here or Support/Format.h! 229 // FIXME: Implement our formatter to here or Support/Format.h!
230 #if __cplusplus >= 201103L && defined(__MINGW32__)
231 // FIXME: It should be generic to C++11.
232 if (N == 0.0 && std::signbit(N))
233 return *this << "-0.000000e+00";
234 #else
230 int fpcl = _fpclass(N); 235 int fpcl = _fpclass(N);
231 236
232 // negative zero 237 // negative zero
233 if (fpcl == _FPCLASS_NZ) 238 if (fpcl == _FPCLASS_NZ)
234 return *this << "-0.000000e+00"; 239 return *this << "-0.000000e+00";
240 #endif
235 241
236 char buf[16]; 242 char buf[16];
237 unsigned len; 243 unsigned len;
238 len = snprintf(buf, sizeof(buf), "%e", N); 244 len = snprintf(buf, sizeof(buf), "%e", N);
239 if (len <= sizeof(buf) - 2) { 245 if (len <= sizeof(buf) - 2) {
418 424
419 //===----------------------------------------------------------------------===// 425 //===----------------------------------------------------------------------===//
420 // raw_fd_ostream 426 // raw_fd_ostream
421 //===----------------------------------------------------------------------===// 427 //===----------------------------------------------------------------------===//
422 428
423 /// raw_fd_ostream - Open the specified file for writing. If an error 429 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
424 /// occurs, information about the error is put into ErrorInfo, and the
425 /// stream should be immediately destroyed; the string will be empty
426 /// if no error occurred.
427 raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
428 sys::fs::OpenFlags Flags) 430 sys::fs::OpenFlags Flags)
429 : Error(false), UseAtomicWrites(false), pos(0) { 431 : Error(false), UseAtomicWrites(false), pos(0) {
430 assert(Filename != 0 && "Filename is null"); 432 EC = std::error_code();
431 ErrorInfo.clear();
432
433 // Handle "-" as stdout. Note that when we do this, we consider ourself 433 // Handle "-" as stdout. Note that when we do this, we consider ourself
434 // the owner of stdout. This means that we can do things like close the 434 // the owner of stdout. This means that we can do things like close the
435 // file descriptor when we're done and set the "binary" flag globally. 435 // file descriptor when we're done and set the "binary" flag globally.
436 if (Filename[0] == '-' && Filename[1] == 0) { 436 if (Filename == "-") {
437 FD = STDOUT_FILENO; 437 FD = STDOUT_FILENO;
438 // If user requested binary then put stdout into binary mode if 438 // If user requested binary then put stdout into binary mode if
439 // possible. 439 // possible.
440 if (Flags & sys::fs::F_Binary) 440 if (!(Flags & sys::fs::F_Text))
441 sys::ChangeStdoutToBinary(); 441 sys::ChangeStdoutToBinary();
442 // Close stdout when we're done, to detect any output errors. 442 // Close stdout when we're done, to detect any output errors.
443 ShouldClose = true; 443 ShouldClose = true;
444 return; 444 return;
445 } 445 }
446 446
447 error_code EC = sys::fs::openFileForWrite(Filename, FD, Flags); 447 EC = sys::fs::openFileForWrite(Filename, FD, Flags);
448 448
449 if (EC) { 449 if (EC) {
450 ErrorInfo = "Error opening output file '" + std::string(Filename) + "': " +
451 EC.message();
452 ShouldClose = false; 450 ShouldClose = false;
453 return; 451 return;
454 } 452 }
455 453
456 // Ok, we successfully opened the file, so it'll need to be closed. 454 // Ok, we successfully opened the file, so it'll need to be closed.
461 /// ShouldClose is true, this closes the file when the stream is destroyed. 459 /// ShouldClose is true, this closes the file when the stream is destroyed.
462 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) 460 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
463 : raw_ostream(unbuffered), FD(fd), 461 : raw_ostream(unbuffered), FD(fd),
464 ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) { 462 ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) {
465 #ifdef O_BINARY 463 #ifdef O_BINARY
466 // Setting STDOUT and STDERR to binary mode is necessary in Win32 464 // Setting STDOUT to binary mode is necessary in Win32
467 // to avoid undesirable linefeed conversion. 465 // to avoid undesirable linefeed conversion.
468 if (fd == STDOUT_FILENO || fd == STDERR_FILENO) 466 // Don't touch STDERR, or w*printf() (in assert()) would barf wide chars.
467 if (fd == STDOUT_FILENO)
469 setmode(fd, O_BINARY); 468 setmode(fd, O_BINARY);
470 #endif 469 #endif
471 470
472 // Get the starting position. 471 // Get the starting position.
473 off_t loc = ::lseek(FD, 0, SEEK_CUR); 472 off_t loc = ::lseek(FD, 0, SEEK_CUR);
651 650
652 /// outs() - This returns a reference to a raw_ostream for standard output. 651 /// outs() - This returns a reference to a raw_ostream for standard output.
653 /// Use it like: outs() << "foo" << "bar"; 652 /// Use it like: outs() << "foo" << "bar";
654 raw_ostream &llvm::outs() { 653 raw_ostream &llvm::outs() {
655 // Set buffer settings to model stdout behavior. 654 // Set buffer settings to model stdout behavior.
656 // Delete the file descriptor when the program exists, forcing error 655 // Delete the file descriptor when the program exits, forcing error
657 // detection. If you don't want this behavior, don't use outs(). 656 // detection. If you don't want this behavior, don't use outs().
658 static raw_fd_ostream S(STDOUT_FILENO, true); 657 static raw_fd_ostream S(STDOUT_FILENO, true);
659 return S; 658 return S;
660 } 659 }
661 660
720 OS.reserve(OS.capacity() * 2); 719 OS.reserve(OS.capacity() * 2);
721 SetBuffer(OS.end(), OS.capacity() - OS.size()); 720 SetBuffer(OS.end(), OS.capacity() - OS.size());
722 } 721 }
723 722
724 void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { 723 void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
725 // If we're writing bytes from the end of the buffer into the smallvector, we
726 // don't need to copy the bytes, just commit the bytes because they are
727 // already in the right place.
728 if (Ptr == OS.end()) { 724 if (Ptr == OS.end()) {
729 assert(OS.size() + Size <= OS.capacity() && "Invalid write_impl() call!"); 725 // Grow the buffer to include the scratch area without copying.
730 OS.set_size(OS.size() + Size); 726 size_t NewSize = OS.size() + Size;
727 assert(NewSize <= OS.capacity() && "Invalid write_impl() call!");
728 OS.set_size(NewSize);
731 } else { 729 } else {
732 assert(GetNumBytesInBuffer() == 0 && 730 assert(!GetNumBytesInBuffer());
733 "Should be writing from buffer if some bytes in it"); 731 OS.append(Ptr, Ptr + Size);
734 // Otherwise, do copy the bytes. 732 }
735 OS.append(Ptr, Ptr+Size); 733
736 } 734 OS.reserve(OS.size() + 64);
737
738 // Grow the vector if necessary.
739 if (OS.capacity() - OS.size() < 64)
740 OS.reserve(OS.capacity() * 2);
741
742 // Update the buffer position.
743 SetBuffer(OS.end(), OS.capacity() - OS.size()); 735 SetBuffer(OS.end(), OS.capacity() - OS.size());
744 } 736 }
745 737
746 uint64_t raw_svector_ostream::current_pos() const { 738 uint64_t raw_svector_ostream::current_pos() const {
747 return OS.size(); 739 return OS.size();