From: Chris Lattner Date: Sun, 27 Jan 2008 23:55:11 +0000 (+0000) Subject: Make -o work with -E, patch contributed by Shantonu Sen! X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e988bc25106a41f1e3cd432a7c265b99b01b9d6a;p=clang Make -o work with -E, patch contributed by Shantonu Sen! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46426 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/PrintPreprocessedOutput.cpp b/Driver/PrintPreprocessedOutput.cpp index f6f7a8cf92..f338b07225 100644 --- a/Driver/PrintPreprocessedOutput.cpp +++ b/Driver/PrintPreprocessedOutput.cpp @@ -36,32 +36,52 @@ using namespace clang; // slow system code. In practice, using 'write' directly makes 'clang -E -P' // about 10% faster than using the stdio path on darwin. -#ifdef HAVE_UNISTD_H +#if defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H) #include +#include #else #define USE_STDIO 1 #endif +#ifdef USE_STDIO +FILE *OutputFILE; +#else +static int OutputFD; static char *OutBufStart = 0, *OutBufEnd, *OutBufCur; +#endif /// InitOutputBuffer - Initialize our output buffer. /// -static void InitOutputBuffer() { -#ifndef USE_STDIO +static void InitOutputBuffer(const std::string& Output) { +#ifdef USE_STDIO + if (!Output.size() || Output == "-") + OutputFILE = stdout; + else + OutputFILE = fopen(Output.c_str(), "w+"); + + assert(OutputFILE && "failed to open output file"); +#else OutBufStart = new char[64*1024]; OutBufEnd = OutBufStart+64*1024; OutBufCur = OutBufStart; + + if (!Output.size() || Output == "-") + OutputFD = STDOUT_FILENO; + else + OutputFD = open(Output.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644); + + assert(OutputFD >= 0 && "failed to open output file"); #endif } +#ifndef USE_STDIO /// FlushBuffer - Write the accumulated bytes to the output stream. /// static void FlushBuffer() { -#ifndef USE_STDIO - write(STDOUT_FILENO, OutBufStart, OutBufCur-OutBufStart); + write(OutputFD, OutBufStart, OutBufCur-OutBufStart); OutBufCur = OutBufStart; -#endif } +#endif /// CleanupOutputBuffer - Finish up output. /// @@ -74,9 +94,9 @@ static void CleanupOutputBuffer() { static void OutputChar(char c) { #if defined(_MSC_VER) - putchar(c); + putc(c, OutputFILE); #elif defined(USE_STDIO) - putchar_unlocked(c); + putc_unlocked(c, OutputFILE); #else if (OutBufCur >= OutBufEnd) FlushBuffer(); @@ -86,7 +106,7 @@ static void OutputChar(char c) { static void OutputString(const char *Ptr, unsigned Size) { #ifdef USE_STDIO - fwrite(Ptr, Size, 1, stdout); + fwrite(Ptr, Size, 1, OutputFILE); #else if (OutBufCur+Size >= OutBufEnd) FlushBuffer(); @@ -571,12 +591,12 @@ bool PrintPPOutputPPCallbacks::AvoidConcat(const Token &PrevTok, /// DoPrintPreprocessedInput - This implements -E mode. /// -void clang::DoPrintPreprocessedInput(Preprocessor &PP) { +void clang::DoPrintPreprocessedInput(Preprocessor &PP, const std::string& OutFile) { // Inform the preprocessor whether we want it to retain comments or not, due // to -C or -CC. PP.SetCommentRetentionState(EnableCommentOutput, EnableMacroCommentOutput); - InitOutputBuffer(); + InitOutputBuffer(OutFile); InitAvoidConcatTokenInfo(); Token Tok, PrevTok; diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 02f8321b68..5eabc72711 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -1024,7 +1024,7 @@ static void ProcessInputFile(Preprocessor &PP, const std::string &InFile, } case PrintPreprocessedInput: // -E mode. - DoPrintPreprocessedInput(PP); + DoPrintPreprocessedInput(PP, OutputFile); ClearSourceMgr = true; break; diff --git a/Driver/clang.h b/Driver/clang.h index e493338334..97a9480566 100644 --- a/Driver/clang.h +++ b/Driver/clang.h @@ -27,7 +27,7 @@ class IdentifierTable; class SourceManager; /// DoPrintPreprocessedInput - Implement -E mode. -void DoPrintPreprocessedInput(Preprocessor &PP); +void DoPrintPreprocessedInput(Preprocessor &PP, const std::string& OutFile); /// CreatePrintParserActionsAction - Return the actions implementation that /// implements the -parse-print-callbacks option.