add and document regex support for FileCheck. You can now do stuff like:
[oota-llvm.git] / lib / Support / raw_ostream.cpp
index 2181ccec0b1a5fba9a43ae5c7d2f1b75490f1828..0a82cc1d10c394ff33fceb2b55bcdc2c26d5f63e 100644 (file)
@@ -19,7 +19,8 @@
 #include "llvm/Config/config.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
-#include <ostream>
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -83,8 +84,8 @@ void raw_ostream::SetBuffered() {
 void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, 
                                     BufferKind Mode) {
   assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) || 
-          (Mode != Unbuffered && BufferStart && Size >= 64)) &&
-         "stream must be unbuffered, or have >= 64 bytes of buffer");
+          (Mode != Unbuffered && BufferStart && Size)) &&
+         "stream must be unbuffered or have at least one byte");
   // Make sure the current buffer is free of content (we can't flush here; the
   // child buffer management logic will be in write_impl).
   assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
@@ -173,6 +174,13 @@ raw_ostream &raw_ostream::operator<<(const void *P) {
   return write_hex((uintptr_t) P);
 }
 
+raw_ostream &raw_ostream::operator<<(double N) {
+  this->operator<<(ftostr(N));
+  return *this;
+}
+
+
+
 void raw_ostream::flush_nonempty() {
   assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
   size_t Length = OutBufCur - OutBufStart;
@@ -253,12 +261,12 @@ raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
   // If we have more than a few bytes left in our output buffer, try
   // formatting directly onto its end.
   size_t NextBufferSize = 127;
-  if (OutBufEnd-OutBufCur > 3) {
-    size_t BufferBytesLeft = OutBufEnd-OutBufCur;
+  size_t BufferBytesLeft = OutBufEnd - OutBufCur;
+  if (BufferBytesLeft > 3) {
     size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
     
     // Common case is that we have plenty of space.
-    if (BytesUsed < BufferBytesLeft) {
+    if (BytesUsed <= BufferBytesLeft) {
       OutBufCur += BytesUsed;
       return *this;
     }
@@ -277,11 +285,11 @@ raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
     V.resize(NextBufferSize);
     
     // Try formatting into the SmallVector.
-    size_t BytesUsed = Fmt.print(&V[0], NextBufferSize);
+    size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
     
     // If BytesUsed fit into the vector, we win.
     if (BytesUsed <= NextBufferSize)
-      return write(&V[0], BytesUsed);
+      return write(V.data(), BytesUsed);
     
     // Otherwise, try again with a new size.
     assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
@@ -291,14 +299,17 @@ raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
 
 /// indent - Insert 'NumSpaces' spaces.
 raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
-  const char *Spaces = "                ";
+  static const char Spaces[] = "                                "
+                               "                                "
+                               "                ";
 
   // Usually the indentation is small, handle it with a fastpath.
-  if (NumSpaces <= 16)
+  if (NumSpaces < array_lengthof(Spaces))
     return write(Spaces, NumSpaces);
   
   while (NumSpaces) {
-    unsigned NumToWrite = std::min(NumSpaces, 16U);
+    unsigned NumToWrite = std::min(NumSpaces,
+                                   (unsigned)array_lengthof(Spaces)-1);
     write(Spaces, NumToWrite);
     NumSpaces -= NumToWrite;
   }
@@ -324,9 +335,9 @@ void format_object_base::home() {
 /// if no error occurred.
 raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
                                unsigned Flags) : pos(0) {
-  // Verify that we don't have both "append" and "force".
-  assert((!(Flags & F_Force) || !(Flags & F_Append)) &&
-         "Cannot specify both 'force' and 'append' file creation flags!");
+  // Verify that we don't have both "append" and "excl".
+  assert((!(Flags & F_Excl) || !(Flags & F_Append)) &&
+         "Cannot specify both 'excl' and 'append' file creation flags!");
   
   ErrorInfo.clear();
 
@@ -347,11 +358,11 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
     OpenFlags |= O_BINARY;
 #endif
   
-  if (Flags & F_Force)
-    OpenFlags |= O_TRUNC;
-  else if (Flags & F_Append)
+  if (Flags & F_Append)
     OpenFlags |= O_APPEND;
   else
+    OpenFlags |= O_TRUNC;
+  if (Flags & F_Excl)
     OpenFlags |= O_EXCL;
   
   FD = open(Filename, OpenFlags, 0664);
@@ -443,6 +454,10 @@ raw_ostream &raw_fd_ostream::resetColor() {
   return *this;
 }
 
+bool raw_fd_ostream::is_displayed() const {
+  return sys::Process::FileDescriptorIsDisplayed(FD);
+}
+
 //===----------------------------------------------------------------------===//
 //  raw_stdout/err_ostream
 //===----------------------------------------------------------------------===//
@@ -477,19 +492,6 @@ raw_ostream &llvm::nulls() {
   return S;
 }
 
-//===----------------------------------------------------------------------===//
-//  raw_os_ostream
-//===----------------------------------------------------------------------===//
-
-raw_os_ostream::~raw_os_ostream() {
-  flush();
-}
-
-void raw_os_ostream::write_impl(const char *Ptr, size_t Size) {
-  OS.write(Ptr, Size);
-}
-
-uint64_t raw_os_ostream::current_pos() { return OS.tellp(); }
 
 //===----------------------------------------------------------------------===//
 //  raw_string_ostream