#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include <cctype>
#include <cerrno>
#include <sys/stat.h>
-#include <sys/types.h>
-#if defined(HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
+// <fcntl.h> may provide O_BINARY.
#if defined(HAVE_FCNTL_H)
# include <fcntl.h>
#endif
+
+#if defined(HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
#if defined(HAVE_SYS_UIO_H) && defined(HAVE_WRITEV)
# include <sys/uio.h>
#endif
#if defined(_MSC_VER)
#include <io.h>
-#include <fcntl.h>
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
BufferKind Mode) {
- assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) ||
- (Mode != Unbuffered && BufferStart && Size)) &&
+ assert(((Mode == Unbuffered && !BufferStart && Size == 0) ||
+ (Mode != Unbuffered && BufferStart && Size != 0)) &&
"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).
// On MSVCRT and compatible, output of %e is incompatible to Posix
// by default. Number of exponent digits should be at least 2. "%+03d"
// FIXME: Implement our formatter to here or Support/Format.h!
+#if __cplusplus >= 201103L && defined(__MINGW32__)
+ // FIXME: It should be generic to C++11.
+ if (N == 0.0 && std::signbit(N))
+ return *this << "-0.000000e+00";
+#else
int fpcl = _fpclass(N);
// negative zero
if (fpcl == _FPCLASS_NZ)
return *this << "-0.000000e+00";
+#endif
char buf[16];
unsigned len;
/// stream should be immediately destroyed; the string will be empty
/// if no error occurred.
raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
- unsigned Flags)
- : Error(false), UseAtomicWrites(false), pos(0)
-{
- assert(Filename != 0 && "Filename is null");
- // 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!");
-
+ sys::fs::OpenFlags Flags)
+ : Error(false), UseAtomicWrites(false), pos(0) {
+ assert(Filename && "Filename is null");
ErrorInfo.clear();
// Handle "-" as stdout. Note that when we do this, we consider ourself
FD = STDOUT_FILENO;
// If user requested binary then put stdout into binary mode if
// possible.
- if (Flags & F_Binary)
- sys::Program::ChangeStdoutToBinary();
+ if (!(Flags & sys::fs::F_Text))
+ sys::ChangeStdoutToBinary();
// Close stdout when we're done, to detect any output errors.
ShouldClose = true;
return;
}
- int OpenFlags = O_WRONLY|O_CREAT;
-#ifdef O_BINARY
- if (Flags & F_Binary)
- OpenFlags |= O_BINARY;
-#endif
+ error_code EC = sys::fs::openFileForWrite(Filename, FD, Flags);
- if (Flags & F_Append)
- OpenFlags |= O_APPEND;
- else
- OpenFlags |= O_TRUNC;
- if (Flags & F_Excl)
- OpenFlags |= O_EXCL;
-
- while ((FD = open(Filename, OpenFlags, 0664)) < 0) {
- if (errno != EINTR) {
- ErrorInfo = "Error opening output file '" + std::string(Filename) + "'";
- ShouldClose = false;
- return;
- }
+ if (EC) {
+ ErrorInfo = "Error opening output file '" + std::string(Filename) + "': " +
+ EC.message();
+ ShouldClose = false;
+ return;
}
// Ok, we successfully opened the file, so it'll need to be closed.
: raw_ostream(unbuffered), FD(fd),
ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) {
#ifdef O_BINARY
- // Setting STDOUT and STDERR to binary mode is necessary in Win32
+ // Setting STDOUT to binary mode is necessary in Win32
// to avoid undesirable linefeed conversion.
- if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
+ // Don't touch STDERR, or w*printf() (in assert()) would barf wide chars.
+ if (fd == STDOUT_FILENO)
setmode(fd, O_BINARY);
#endif