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 "Core/FileOverrides.h"
|
||||||
|
|
||||||
#include "clang/Basic/SourceManager.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 {
|
void SourceOverrides::applyOverrides(clang::SourceManager &SM) const {
|
||||||
clang::FileManager &FM = SM.getFileManager();
|
clang::FileManager &FM = SM.getFileManager();
|
||||||
|
@ -32,3 +36,35 @@ void SourceOverrides::applyOverrides(clang::SourceManager &SM) const {
|
||||||
llvm::MemoryBuffer::getMemBuffer(I->second.FileOverride));
|
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>
|
#include <string>
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
|
namespace llvm {
|
||||||
|
template <typename T>
|
||||||
|
class SmallVectorImpl;
|
||||||
|
} // namespace llvm
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class SourceManager;
|
class SourceManager;
|
||||||
class FileManager;
|
class FileManager;
|
||||||
|
@ -62,4 +66,24 @@ struct SourceOverrides {
|
||||||
/// \brief Maps source file names to content override information.
|
/// \brief Maps source file names to content override information.
|
||||||
typedef std::map<std::string, SourceOverrides> FileOverrides;
|
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
|
#endif // CPP11_MIGRATE_FILE_OVERRIDES_H
|
||||||
|
|
|
@ -9,7 +9,8 @@ include_directories(${CPP11_MIGRATE_SOURCE_DIR})
|
||||||
add_extra_unittest(Cpp11MigrateTests
|
add_extra_unittest(Cpp11MigrateTests
|
||||||
TransformTest.cpp
|
TransformTest.cpp
|
||||||
IncludeExcludeTest.cpp
|
IncludeExcludeTest.cpp
|
||||||
PerfSupportTest.cpp)
|
PerfSupportTest.cpp
|
||||||
|
UniqueHeaderNameTest.cpp)
|
||||||
|
|
||||||
target_link_libraries(Cpp11MigrateTests
|
target_link_libraries(Cpp11MigrateTests
|
||||||
migrateCore
|
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