From 7937ef37969f7d46d8626e2b61a6ae8361afbea6 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 28 Jun 2016 02:09:39 +0000 Subject: Reapply "[llvm-cov] Add an -output-dir option for the show sub-command"" Passing -output-dir path/to/dir to llvm-cov show creates path/to/dir if it doesn't already exist, and prints reports into that directory. In function view mode, all views are written into path/to/dir/functions.$EXTENSION. In file view mode, all views are written into path/to/dir/coverage/$PATH.$EXTENSION. Changes since the initial commit: - Avoid accidentally closing stdout twice. llvm-svn: 273985 --- llvm/tools/llvm-cov/SourceCoverageView.cpp | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'llvm/tools/llvm-cov/SourceCoverageView.cpp') diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp index 3309189a935..f9ce946dc5f 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp @@ -15,7 +15,9 @@ #include "SourceCoverageViewText.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/LineIterator.h" +#include "llvm/Support/Path.h" using namespace llvm; @@ -34,6 +36,51 @@ std::string SourceCoverageView::formatCount(uint64_t N) { return Result; } +void SourceCoverageView::StreamDestructor::operator()(raw_ostream *OS) const { + if (OS == &outs()) + return; + delete OS; +} + +/// \brief Create a file at ``Dir/ToplevelDir/@Path.Extension``. If +/// \p ToplevelDir is empty, its path component is skipped. +static Expected +createFileInDirectory(StringRef Dir, StringRef ToplevelDir, StringRef Path, + StringRef Extension) { + assert(Extension.size() && "The file extension may not be empty"); + + SmallString<256> FullPath(Dir); + if (!ToplevelDir.empty()) + sys::path::append(FullPath, ToplevelDir); + + auto PathBaseDir = sys::path::relative_path(sys::path::parent_path(Path)); + sys::path::append(FullPath, PathBaseDir); + + if (auto E = sys::fs::create_directories(FullPath)) + return errorCodeToError(E); + + auto PathFilename = (sys::path::filename(Path) + "." + Extension).str(); + sys::path::append(FullPath, PathFilename); + + std::error_code E; + auto OS = SourceCoverageView::OwnedStream( + new raw_fd_ostream(FullPath, E, sys::fs::F_RW)); + if (E) + return errorCodeToError(E); + return std::move(OS); +} + +Expected +SourceCoverageView::createOutputStream(const CoverageViewOptions &Opts, + StringRef Path, StringRef Extension, + bool InToplevel) { + if (Opts.ShowOutputDirectory == "") + return OwnedStream(&outs()); + + return createFileInDirectory(Opts.ShowOutputDirectory, + InToplevel ? "" : "coverage", Path, Extension); +} + void SourceCoverageView::addExpansion( const coverage::CounterMappingRegion &Region, std::unique_ptr View) { -- cgit v1.2.3