forked from OSchip/llvm-project
Generate a unique filename for a given header
This patch is in preparation for writing the header replacement to disk. Added getUniqueHeaderName() that generates a unique header filename in the same directory as the header file. Differential Revision: http://llvm-reviews.chandlerc.com/D1104 llvm-svn: 186007
This commit is contained in:
parent
aafb84be9e
commit
9c7750eeae
|
@ -16,6 +16,10 @@
|
|||
#include "Core/FileOverrides.h"
|
||||
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/system_error.h"
|
||||
|
||||
void SourceOverrides::applyOverrides(clang::SourceManager &SM) const {
|
||||
clang::FileManager &FM = SM.getFileManager();
|
||||
|
@ -32,3 +36,35 @@ void SourceOverrides::applyOverrides(clang::SourceManager &SM) const {
|
|||
llvm::MemoryBuffer::getMemBuffer(I->second.FileOverride));
|
||||
}
|
||||
}
|
||||
|
||||
bool generateReplacementsFileName(llvm::StringRef SourceFile,
|
||||
llvm::StringRef HeaderFile,
|
||||
llvm::SmallVectorImpl<char> &Result,
|
||||
llvm::SmallVectorImpl<char> &Error) {
|
||||
using namespace llvm::sys;
|
||||
std::string UniqueHeaderNameModel;
|
||||
|
||||
// Get the filename portion of the path.
|
||||
llvm::StringRef SourceFileRef(path::filename(SourceFile));
|
||||
llvm::StringRef HeaderFileRef(path::filename(HeaderFile));
|
||||
|
||||
// Get the actual path for the header file.
|
||||
llvm::SmallString<128> HeaderPath(HeaderFile);
|
||||
path::remove_filename(HeaderPath);
|
||||
|
||||
// Build the model of the filename.
|
||||
llvm::raw_string_ostream UniqueHeaderNameStream(UniqueHeaderNameModel);
|
||||
UniqueHeaderNameStream << SourceFileRef << "_" << HeaderFileRef
|
||||
<< "_%%_%%_%%_%%_%%_%%" << ".yaml";
|
||||
path::append(HeaderPath, UniqueHeaderNameStream.str());
|
||||
|
||||
Error.clear();
|
||||
if (llvm::error_code EC =
|
||||
fs::createUniqueFile(HeaderPath.c_str(), Result)) {
|
||||
Error.append(EC.message().begin(), EC.message().end());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#include <string>
|
||||
|
||||
// Forward Declarations
|
||||
namespace llvm {
|
||||
template <typename T>
|
||||
class SmallVectorImpl;
|
||||
} // namespace llvm
|
||||
namespace clang {
|
||||
class SourceManager;
|
||||
class FileManager;
|
||||
|
@ -62,4 +66,24 @@ struct SourceOverrides {
|
|||
/// \brief Maps source file names to content override information.
|
||||
typedef std::map<std::string, SourceOverrides> FileOverrides;
|
||||
|
||||
/// \brief Generate a unique filename to store the replacements.
|
||||
///
|
||||
/// Generates a unique filename in the same directory as the header file. The
|
||||
/// filename is based on the following model:
|
||||
///
|
||||
/// source.cpp_header.h_%%_%%_%%_%%_%%_%%.yaml
|
||||
///
|
||||
/// where all '%' will be replaced by a randomly chosen hex number.
|
||||
///
|
||||
/// @param SourceFile Full path to the source file.
|
||||
/// @param HeaderFile Full path to the header file.
|
||||
/// @param Result The resulting unique filename in the same directory as the
|
||||
/// header file.
|
||||
/// @param Error Description of the error if there is any.
|
||||
/// @returns true if succeeded, false otherwise.
|
||||
bool generateReplacementsFileName(llvm::StringRef SourceFile,
|
||||
llvm::StringRef HeaderFile,
|
||||
llvm::SmallVectorImpl<char> &Result,
|
||||
llvm::SmallVectorImpl<char> &Error);
|
||||
|
||||
#endif // CPP11_MIGRATE_FILE_OVERRIDES_H
|
||||
|
|
|
@ -9,7 +9,8 @@ include_directories(${CPP11_MIGRATE_SOURCE_DIR})
|
|||
add_extra_unittest(Cpp11MigrateTests
|
||||
TransformTest.cpp
|
||||
IncludeExcludeTest.cpp
|
||||
PerfSupportTest.cpp)
|
||||
PerfSupportTest.cpp
|
||||
UniqueHeaderNameTest.cpp)
|
||||
|
||||
target_link_libraries(Cpp11MigrateTests
|
||||
migrateCore
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
//===- unittests/cpp11-migrate/UniqueHeaderNameTest.cpp -------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Test for the generateReplacementsFileName() in FileOverrides.h
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "Core/FileOverrides.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include "llvm/Support/system_error.h"
|
||||
|
||||
TEST(UniqueHeaderName, testUniqueHeaderName) {
|
||||
using namespace llvm::sys::path;
|
||||
|
||||
llvm::SmallString<32> TmpDir;
|
||||
system_temp_directory(true, TmpDir);
|
||||
|
||||
llvm::SmallString<128> SourceFile(TmpDir);
|
||||
append(SourceFile, "project/lib/feature.cpp");
|
||||
native(SourceFile.c_str(), SourceFile);
|
||||
|
||||
llvm::SmallString<128> HeaderFile(TmpDir);
|
||||
append(HeaderFile, "project/include/feature.h");
|
||||
native(HeaderFile.c_str(), HeaderFile);
|
||||
|
||||
llvm::SmallString<128> ExpectedName("^feature.cpp_feature.h_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}_[0-9a-f]{2}.yaml$");
|
||||
|
||||
llvm::SmallString<128> ActualName;
|
||||
llvm::SmallString<128> Error;
|
||||
bool Result =
|
||||
generateReplacementsFileName(SourceFile, HeaderFile, ActualName, Error);
|
||||
|
||||
ASSERT_TRUE(Result);
|
||||
EXPECT_TRUE(Error.empty());
|
||||
|
||||
// We need to check the directory name and filename separately since on
|
||||
// Windows, the path separator is '\' which is a regex escape character.
|
||||
llvm::SmallString<128> ExpectedHeaderPath =
|
||||
llvm::sys::path::parent_path(HeaderFile);
|
||||
llvm::SmallString<128> ActualHeaderPath =
|
||||
llvm::sys::path::parent_path(ActualName);
|
||||
llvm::SmallString<128> ActualHeaderName =
|
||||
llvm::sys::path::filename(ActualName);
|
||||
|
||||
EXPECT_STREQ(ExpectedHeaderPath.c_str(), ActualHeaderPath.c_str());
|
||||
|
||||
llvm::Regex R(ExpectedName);
|
||||
ASSERT_TRUE(R.match(ActualHeaderName))
|
||||
<< "ExpectedName: " << ExpectedName.c_str()
|
||||
<< "\nActualName: " << ActualName.c_str();
|
||||
ASSERT_TRUE(Error.empty()) << "Error: " << Error.c_str();
|
||||
}
|
Loading…
Reference in New Issue