1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This implements support for bulk buffered stream output. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Format.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Program.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Process.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringExtras.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/SmallVector.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Config/config.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Compiler.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/STLExtras.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <cctype> 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <cerrno> 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <sys/stat.h> 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <sys/types.h> 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if defined(HAVE_UNISTD_H) 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman# include <unistd.h> 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if defined(HAVE_FCNTL_H) 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman# include <fcntl.h> 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#if defined(HAVE_SYS_UIO_H) && defined(HAVE_WRITEV) 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman# include <sys/uio.h> 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#if defined(__CYGWIN__) 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <io.h> 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if defined(_MSC_VER) 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <io.h> 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <fcntl.h> 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef STDIN_FILENO 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman# define STDIN_FILENO 0 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef STDOUT_FILENO 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman# define STDOUT_FILENO 1 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef STDERR_FILENO 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman# define STDERR_FILENO 2 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream::~raw_ostream() { 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // raw_ostream's subclasses should take care to flush the buffer 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // in their destructors. 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OutBufCur == OutBufStart && 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "raw_ostream destructor called with non-empty buffer!"); 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BufferMode == InternalBuffer) 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete [] OutBufStart; 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// An out of line virtual method to provide a home for the class vtable. 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_ostream::handle() {} 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumansize_t raw_ostream::preferred_buffer_size() const { 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // BUFSIZ is intended to be a reasonable default. 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return BUFSIZ; 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_ostream::SetBuffered() { 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ask the subclass to determine an appropriate buffer size. 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (size_t Size = preferred_buffer_size()) 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetBufferSize(Size); 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // It may return 0, meaning this stream should be unbuffered. 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetUnbuffered(); 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BufferKind Mode) { 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) || 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (Mode != Unbuffered && BufferStart && Size)) && 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "stream must be unbuffered or have at least one byte"); 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure the current buffer is free of content (we can't flush here; the 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // child buffer management logic will be in write_impl). 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!"); 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BufferMode == InternalBuffer) 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete [] OutBufStart; 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutBufStart = BufferStart; 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutBufEnd = OutBufStart+Size; 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutBufCur = OutBufStart; 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BufferMode = Mode; 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OutBufStart <= OutBufEnd && "Invalid size!"); 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::operator<<(unsigned long N) { 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero is a special case. 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N == 0) 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this << '0'; 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char NumberBuffer[20]; 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char *EndPtr = NumberBuffer+sizeof(NumberBuffer); 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char *CurPtr = EndPtr; 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (N) { 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *--CurPtr = '0' + char(N % 10); 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N /= 10; 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write(CurPtr, EndPtr-CurPtr); 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::operator<<(long N) { 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N < 0) { 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << '-'; 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Avoid undefined behavior on LONG_MIN with a cast. 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N = -(unsigned long)N; 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return this->operator<<(static_cast<unsigned long>(N)); 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::operator<<(unsigned long long N) { 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Output using 32-bit div/mod when possible. 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N == static_cast<unsigned long>(N)) 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return this->operator<<(static_cast<unsigned long>(N)); 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char NumberBuffer[20]; 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char *EndPtr = NumberBuffer+sizeof(NumberBuffer); 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char *CurPtr = EndPtr; 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (N) { 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *--CurPtr = '0' + char(N % 10); 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N /= 10; 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write(CurPtr, EndPtr-CurPtr); 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::operator<<(long long N) { 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N < 0) { 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << '-'; 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Avoid undefined behavior on INT64_MIN with a cast. 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N = -(unsigned long long)N; 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return this->operator<<(static_cast<unsigned long long>(N)); 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::write_hex(unsigned long long N) { 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero is a special case. 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N == 0) 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this << '0'; 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char NumberBuffer[20]; 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char *EndPtr = NumberBuffer+sizeof(NumberBuffer); 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman char *CurPtr = EndPtr; 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (N) { 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uintptr_t x = N % 16; 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *--CurPtr = (x < 10 ? '0' + x : 'a' + x - 10); 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N /= 16; 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write(CurPtr, EndPtr-CurPtr); 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanraw_ostream &raw_ostream::write_escaped(StringRef Str, 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool UseHexEscapes) { 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Str.size(); i != e; ++i) { 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned char c = Str[i]; 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (c) { 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case '\\': 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << '\\' << '\\'; 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case '\t': 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << '\\' << 't'; 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case '\n': 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << '\\' << 'n'; 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case '"': 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << '\\' << '"'; 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (std::isprint(c)) { 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << c; 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Write out the escaped representation. 20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (UseHexEscapes) { 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *this << '\\' << 'x'; 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *this << hexdigit((c >> 4 & 0xF)); 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *this << hexdigit((c >> 0) & 0xF); 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Always use a full 3-character octal escape. 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *this << '\\'; 20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *this << char('0' + ((c >> 6) & 7)); 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *this << char('0' + ((c >> 3) & 7)); 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *this << char('0' + ((c >> 0) & 7)); 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::operator<<(const void *P) { 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *this << '0' << 'x'; 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write_hex((uintptr_t) P); 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::operator<<(double N) { 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef _WIN32 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // On MSVCRT and compatible, output of %e is incompatible to Posix 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // by default. Number of exponent digits should be at least 2. "%+03d" 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: Implement our formatter to here or Support/Format.h! 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int fpcl = _fpclass(N); 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // negative zero 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (fpcl == _FPCLASS_NZ) 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this << "-0.000000e+00"; 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman char buf[16]; 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned len; 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman len = snprintf(buf, sizeof(buf), "%e", N); 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (len <= sizeof(buf) - 2) { 23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') { 23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int cs = buf[len - 4]; 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (cs == '+' || cs == '-') { 24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int c1 = buf[len - 2]; 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int c0 = buf[len - 1]; 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isdigit(c1) && isdigit(c0)) { 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Trim leading '0': "...e+012" -> "...e+12\0" 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman buf[len - 3] = c1; 24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman buf[len - 2] = c0; 24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman buf[--len] = 0; 24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return this->operator<<(buf); 25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return this->operator<<(format("%e", N)); 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_ostream::flush_nonempty() { 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty."); 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t Length = OutBufCur - OutBufStart; 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutBufCur = OutBufStart; 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman write_impl(OutBufStart, Length); 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::write(unsigned char C) { 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Group exceptional cases into a single branch. 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BUILTIN_EXPECT(OutBufCur >= OutBufEnd, false)) { 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BUILTIN_EXPECT(!OutBufStart, false)) { 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BufferMode == Unbuffered) { 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman write_impl(reinterpret_cast<char*>(&C), 1); 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set up a buffer and start over. 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetBuffered(); 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write(C); 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush_nonempty(); 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *OutBufCur++ = C; 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::write(const char *Ptr, size_t Size) { 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Group exceptional cases into a single branch. 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (BUILTIN_EXPECT(size_t(OutBufEnd - OutBufCur) < Size, false)) { 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BUILTIN_EXPECT(!OutBufStart, false)) { 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BufferMode == Unbuffered) { 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman write_impl(Ptr, Size); 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set up a buffer and start over. 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetBuffered(); 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write(Ptr, Size); 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t NumBytes = OutBufEnd - OutBufCur; 30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If the buffer is empty at this point we have a string that is larger 30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // than the buffer. Directly write the chunk that is a multiple of the 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // preferred buffer size and put the remainder in the buffer. 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (BUILTIN_EXPECT(OutBufCur == OutBufStart, false)) { 30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t BytesToWrite = Size - (Size % NumBytes); 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman write_impl(Ptr, BytesToWrite); 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman copy_to_buffer(Ptr + BytesToWrite, Size - BytesToWrite); 30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this; 30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We don't have enough space in the buffer to fit the string in. Insert as 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // much as possible, flush and start over with the remainder. 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman copy_to_buffer(Ptr, NumBytes); 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman flush_nonempty(); 31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return write(Ptr + NumBytes, Size - NumBytes); 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman copy_to_buffer(Ptr, Size); 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) { 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!"); 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Handle short strings specially, memcpy isn't very good at very short 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // strings. 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Size) { 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 4: OutBufCur[3] = Ptr[3]; // FALL THROUGH 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 3: OutBufCur[2] = Ptr[2]; // FALL THROUGH 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 2: OutBufCur[1] = Ptr[1]; // FALL THROUGH 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 0: break; 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman memcpy(OutBufCur, Ptr, Size); 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutBufCur += Size; 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Formatted output. 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) { 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have more than a few bytes left in our output buffer, try 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // formatting directly onto its end. 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t NextBufferSize = 127; 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t BufferBytesLeft = OutBufEnd - OutBufCur; 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BufferBytesLeft > 3) { 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft); 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Common case is that we have plenty of space. 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BytesUsed <= BufferBytesLeft) { 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutBufCur += BytesUsed; 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, we overflowed and the return value tells us the size to try 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // again with. 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NextBufferSize = BytesUsed; 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we got here, we didn't have enough space in the output buffer for the 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // string. Try printing into a SmallVector that is resized to have enough 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // space. Iterate until we win. 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<char, 128> V; 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (1) { 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman V.resize(NextBufferSize); 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Try formatting into the SmallVector. 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t BytesUsed = Fmt.print(V.data(), NextBufferSize); 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If BytesUsed fit into the vector, we win. 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BytesUsed <= NextBufferSize) 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write(V.data(), BytesUsed); 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, try again with a new size. 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?"); 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NextBufferSize = BytesUsed; 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// indent - Insert 'NumSpaces' spaces. 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_ostream::indent(unsigned NumSpaces) { 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static const char Spaces[] = " " 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " " 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " "; 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Usually the indentation is small, handle it with a fastpath. 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NumSpaces < array_lengthof(Spaces)) 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return write(Spaces, NumSpaces); 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (NumSpaces) { 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumToWrite = std::min(NumSpaces, 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (unsigned)array_lengthof(Spaces)-1); 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman write(Spaces, NumToWrite); 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumSpaces -= NumToWrite; 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Formatted Output 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Out of line virtual method. 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid format_object_base::home() { 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// raw_fd_ostream 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// raw_fd_ostream - Open the specified file for writing. If an error 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// occurs, information about the error is put into ErrorInfo, and the 417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// stream should be immediately destroyed; the string will be empty 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// if no error occurred. 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo, 42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Flags) 42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : Error(false), UseAtomicWrites(false), pos(0) 42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{ 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Filename != 0 && "Filename is null"); 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Verify that we don't have both "append" and "excl". 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert((!(Flags & F_Excl) || !(Flags & F_Append)) && 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Cannot specify both 'excl' and 'append' file creation flags!"); 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ErrorInfo.clear(); 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Handle "-" as stdout. Note that when we do this, we consider ourself 43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the owner of stdout. This means that we can do things like close the 43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // file descriptor when we're done and set the "binary" flag globally. 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Filename[0] == '-' && Filename[1] == 0) { 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FD = STDOUT_FILENO; 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If user requested binary then put stdout into binary mode if 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // possible. 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Flags & F_Binary) 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sys::Program::ChangeStdoutToBinary(); 43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Close stdout when we're done, to detect any output errors. 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ShouldClose = true; 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int OpenFlags = O_WRONLY|O_CREAT; 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifdef O_BINARY 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Flags & F_Binary) 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpenFlags |= O_BINARY; 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Flags & F_Append) 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpenFlags |= O_APPEND; 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpenFlags |= O_TRUNC; 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Flags & F_Excl) 455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpenFlags |= O_EXCL; 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while ((FD = open(Filename, OpenFlags, 0664)) < 0) { 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (errno != EINTR) { 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ErrorInfo = "Error opening output file '" + std::string(Filename) + "'"; 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShouldClose = false; 461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ok, we successfully opened the file, so it'll need to be closed. 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShouldClose = true; 467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If 47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ShouldClose is true, this closes the file when the stream is destroyed. 47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanraw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) 47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : raw_ostream(unbuffered), FD(fd), 47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) { 47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef O_BINARY 47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Setting STDOUT and STDERR to binary mode is necessary in Win32 47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // to avoid undesirable linefeed conversion. 47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (fd == STDOUT_FILENO || fd == STDERR_FILENO) 47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman setmode(fd, O_BINARY); 47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Get the starting position. 48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman off_t loc = ::lseek(FD, 0, SEEK_CUR); 48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (loc == (off_t)-1) 48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman pos = 0; 48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman pos = static_cast<uint64_t>(loc); 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_fd_ostream::~raw_fd_ostream() { 49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FD >= 0) { 49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman flush(); 49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ShouldClose) 49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while (::close(FD) != 0) 49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (errno != EINTR) { 49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman error_detected(); 49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef __MINGW32__ 50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // On mingw, global dtors should not call exit(). 50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // report_fatal_error() invokes exit(). We know report_fatal_error() 50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // might not write messages to stderr when any errors were detected 50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // on FD == 2. 50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FD == 2) return; 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If there are any pending errors, report them now. Clients wishing 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // to avoid report_fatal_error calls should check for errors with 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // has_error() and clear the error flag with clear_error() before 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // destructing raw_ostream objects which may have errors. 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (has_error()) 51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman report_fatal_error("IO failure on output stream."); 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FD >= 0 && "File already closed."); 519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman pos += Size; 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman do { 52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ssize_t ret; 52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check whether we should attempt to use atomic writes. 52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (BUILTIN_EXPECT(!UseAtomicWrites, true)) { 52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ret = ::write(FD, Ptr, Size); 52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Use ::writev() where available. 52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#if defined(HAVE_WRITEV) 53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman struct iovec IOV = { (void*) Ptr, Size }; 53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ret = ::writev(FD, &IOV, 1); 53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ret = ::write(FD, Ptr, Size); 53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ret < 0) { 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If it's a recoverable error, swallow it and retry the write. 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // raw_ostream isn't designed to do non-blocking I/O. However, some 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // programs, such as old versions of bjam, have mistakenly used 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // O_NONBLOCK. For compatibility, emulate blocking semantics by 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // spinning until the write succeeds. If you don't want spinning, 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // don't use O_NONBLOCK file descriptors with raw_ostream. 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (errno == EINTR || errno == EAGAIN 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifdef EWOULDBLOCK 548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || errno == EWOULDBLOCK 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ) 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise it's a non-recoverable error. Note it and quit. 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman error_detected(); 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The write may have written some or all of the data. Update the 559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // size and buffer pointer to reflect the remainder that needs 560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to be written. If there are no bytes left, we're done. 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ptr += ret; 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Size -= ret; 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } while (Size > 0); 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_fd_ostream::close() { 567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ShouldClose); 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShouldClose = false; 569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (::close(FD) != 0) 571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (errno != EINTR) { 572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman error_detected(); 573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FD = -1; 576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanuint64_t raw_fd_ostream::seek(uint64_t off) { 579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman pos = ::lseek(FD, off, SEEK_SET); 581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (pos != off) 582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman error_detected(); 583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return pos; 584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumansize_t raw_fd_ostream::preferred_buffer_size() const { 587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__minix) 588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Windows and Minix have no st_blksize. 589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FD >= 0 && "File not yet open!"); 590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman struct stat statbuf; 591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (fstat(FD, &statbuf) != 0) 592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is a terminal, don't use buffering. Line buffering 595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // would be a more traditional thing to do, but it's not worth 596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the complexity. 597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (S_ISCHR(statbuf.st_mode) && isatty(FD)) 598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Return the preferred block size. 600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return statbuf.st_blksize; 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#else 602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return raw_ostream::preferred_buffer_size(); 603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold, 607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool bg) { 608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (sys::Process::ColorNeedsFlush()) 609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const char *colorcode = 611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (colors == SAVEDCOLOR) ? sys::Process::OutputBold(bg) 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : sys::Process::OutputColor(colors, bold, bg); 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (colorcode) { 614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t len = strlen(colorcode); 615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman write(colorcode, len); 616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // don't account colors towards output characters 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman pos -= len; 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &raw_fd_ostream::resetColor() { 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (sys::Process::ColorNeedsFlush()) 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const char *colorcode = sys::Process::ResetColor(); 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (colorcode) { 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman size_t len = strlen(colorcode); 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman write(colorcode, len); 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // don't account colors towards output characters 630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman pos -= len; 631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *this; 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool raw_fd_ostream::is_displayed() const { 636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return sys::Process::FileDescriptorIsDisplayed(FD); 637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// outs(), errs(), nulls() 641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// outs() - This returns a reference to a raw_ostream for standard output. 644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Use it like: outs() << "foo" << "bar"; 645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &llvm::outs() { 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Set buffer settings to model stdout behavior. 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Delete the file descriptor when the program exists, forcing error 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // detection. If you don't want this behavior, don't use outs(). 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static raw_fd_ostream S(STDOUT_FILENO, true); 650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return S; 651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// errs() - This returns a reference to a raw_ostream for standard error. 654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Use it like: errs() << "foo" << "bar"; 655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &llvm::errs() { 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Set standard error to be unbuffered by default. 65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static raw_fd_ostream S(STDERR_FILENO, false, true); 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return S; 659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// nulls() - This returns a reference to a raw_ostream which discards output. 662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_ostream &llvm::nulls() { 663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static raw_null_ostream S; 664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return S; 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// raw_string_ostream 670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_string_ostream::~raw_string_ostream() { 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_string_ostream::write_impl(const char *Ptr, size_t Size) { 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS.append(Ptr, Size); 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// raw_svector_ostream 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The raw_svector_ostream implementation uses the SmallVector itself as the 685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// buffer for the raw_ostream. We guarantee that the raw_ostream buffer is 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// always pointing past the end of the vector, but within the vector 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// capacity. This allows raw_ostream to write directly into the correct place, 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// and we only need to set the vector size when the data is flushed. 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) { 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set up the initial external buffer. We make sure that the buffer has at 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // least 128 bytes free; raw_ostream itself only requires 64, but we want to 693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // make sure that we don't grow the buffer unnecessarily on destruction (when 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the data is flushed). See the FIXME below. 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS.reserve(OS.size() + 128); 696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetBuffer(OS.end(), OS.capacity() - OS.size()); 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_svector_ostream::~raw_svector_ostream() { 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Prevent resizing during this flush(). 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// resync - This is called when the SmallVector we're appending to is changed 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// outside of the raw_svector_ostream's control. It is only safe to do this 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// if the raw_svector_ostream has previously been flushed. 707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_svector_ostream::resync() { 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(GetNumBytesInBuffer() == 0 && "Didn't flush before mutating vector"); 709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OS.capacity() - OS.size() < 64) 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS.reserve(OS.capacity() * 2); 712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetBuffer(OS.end(), OS.capacity() - OS.size()); 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we're writing bytes from the end of the buffer into the smallvector, we 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // don't need to copy the bytes, just commit the bytes because they are 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // already in the right place. 719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Ptr == OS.end()) { 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OS.size() + Size <= OS.capacity() && "Invalid write_impl() call!"); 721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS.set_size(OS.size() + Size); 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(GetNumBytesInBuffer() == 0 && 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Should be writing from buffer if some bytes in it"); 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, do copy the bytes. 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS.append(Ptr, Ptr+Size); 727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Grow the vector if necessary. 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OS.capacity() - OS.size() < 64) 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS.reserve(OS.capacity() * 2); 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update the buffer position. 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetBuffer(OS.end(), OS.capacity() - OS.size()); 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanuint64_t raw_svector_ostream::current_pos() const { 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return OS.size(); 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanStringRef raw_svector_ostream::str() { 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return StringRef(OS.begin(), OS.size()); 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// raw_null_ostream 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanraw_null_ostream::~raw_null_ostream() { 751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ~raw_ostream asserts that the buffer is empty. This isn't necessary 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // with raw_null_ostream, but it's better to have raw_null_ostream follow 754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the rules than to change the rules just for raw_null_ostream. 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman flush(); 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid raw_null_ostream::write_impl(const char *Ptr, size_t Size) { 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanuint64_t raw_null_ostream::current_pos() const { 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 765