[clang-tools-extra] r186007 - Generate a unique filename for a given header

Tareq A. Siraj tareq.a.sriaj at intel.com
Wed Jul 10 09:09:37 PDT 2013


Author: tasiraj
Date: Wed Jul 10 11:09:36 2013
New Revision: 186007

URL: http://llvm.org/viewvc/llvm-project?rev=186007&view=rev
Log:
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

Added:
    clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp
Modified:
    clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp
    clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h
    clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt

Modified: clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp?rev=186007&r1=186006&r2=186007&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.cpp Wed Jul 10 11:09:36 2013
@@ -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(cla
         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;
+}
+

Modified: clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h?rev=186007&r1=186006&r2=186007&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/FileOverrides.h Wed Jul 10 11:09:36 2013
@@ -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

Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt?rev=186007&r1=186006&r2=186007&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/CMakeLists.txt Wed Jul 10 11:09:36 2013
@@ -9,7 +9,8 @@ include_directories(${CPP11_MIGRATE_SOUR
 add_extra_unittest(Cpp11MigrateTests
   TransformTest.cpp
   IncludeExcludeTest.cpp
-  PerfSupportTest.cpp)
+  PerfSupportTest.cpp
+  UniqueHeaderNameTest.cpp)
 
 target_link_libraries(Cpp11MigrateTests
   migrateCore

Added: clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp?rev=186007&view=auto
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp (added)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/UniqueHeaderNameTest.cpp Wed Jul 10 11:09:36 2013
@@ -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();
+}





More information about the cfe-commits mailing list