[PATCH] Add support to read include/exclude path lists from file

Jack Yang jack.yang at intel.com
Wed Apr 17 12:05:48 PDT 2013


  Sorry for misunderstanding. You're right. Splitting by \n leaves a trailing \r when handling DOS file's CRLF line terminators. I've added a check to drop any trailing \r characters.

Hi revane,

http://llvm-reviews.chandlerc.com/D681

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D681?vs=1670&id=1673#toc

Files:
  cpp11-migrate/Core/IncludeExcludeInfo.cpp
  cpp11-migrate/Core/IncludeExcludeInfo.h
  cpp11-migrate/tool/Cpp11Migrate.cpp
  unittests/cpp11-migrate/IncludeExcludeTest.cpp

Index: cpp11-migrate/Core/IncludeExcludeInfo.cpp
===================================================================
--- cpp11-migrate/Core/IncludeExcludeInfo.cpp
+++ cpp11-migrate/Core/IncludeExcludeInfo.cpp
@@ -16,7 +16,9 @@
 #include "IncludeExcludeInfo.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
@@ -46,25 +48,64 @@
   return true;
 }
 
-/// \brief Helper function to parse a string of comma seperated paths into
+/// \brief Helper function to tokenize a string of filepaths and populate
 /// the vector.
-void parseCLInput(StringRef Line, std::vector<std::string> &List) {
+error_code parseCLInput(StringRef Line, std::vector<std::string> &List,
+                        StringRef Separator) {
   SmallVector<StringRef, 32> Tokens;
-  Line.split(Tokens, ",", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  Line.split(Tokens, Separator, /*MaxSplit=*/ -1, /*KeepEmpty=*/ false);
   for (SmallVectorImpl<StringRef>::iterator I = Tokens.begin(),
                                             E = Tokens.end();
        I != E; ++I) {
     // Convert each path to its absolute path.
     SmallString<64> AbsolutePath = *I;
-    sys::fs::make_absolute(AbsolutePath);
+    if (error_code Err = sys::fs::make_absolute(AbsolutePath))
+      return Err;
+
+    // Drop any trailing '\r' when parsing DOS files with CRLF line terminators.
+    if (AbsolutePath.str().back() == '\r')
+      AbsolutePath = AbsolutePath.str().drop_back();
+
     List.push_back(std::string(AbsolutePath.str()));
   }
+  return error_code::success();
 }
 } // end anonymous namespace
 
-IncludeExcludeInfo::IncludeExcludeInfo(StringRef Include, StringRef Exclude) {
-  parseCLInput(Include, IncludeList);
-  parseCLInput(Exclude, ExcludeList);
+error_code IncludeExcludeInfo::readListFromString(StringRef IncludeString,
+                                                  StringRef ExcludeString) {
+  if (error_code Err = parseCLInput(IncludeString, IncludeList,
+                                    /*Separator=*/ ","))
+    return Err;
+  if (error_code Err = parseCLInput(ExcludeString, ExcludeList,
+                                    /*Separator=*/ ","))
+    return Err;
+  return error_code::success();
+}
+
+error_code IncludeExcludeInfo::readListFromFile(StringRef IncludeListFile,
+                                                StringRef ExcludeListFile) {
+  if (!IncludeListFile.empty()) {
+    OwningPtr<MemoryBuffer> FileBuf;
+    if (error_code Err = MemoryBuffer::getFile(IncludeListFile, FileBuf)) {
+      errs() << "Unable to read from include file.\n";
+      return Err;
+    }
+    if (error_code Err = parseCLInput(FileBuf->getBuffer(), IncludeList,
+                                      /*Separator=*/ "\n"))
+      return Err;
+  }
+  if (!ExcludeListFile.empty()) {
+    OwningPtr<MemoryBuffer> FileBuf;
+    if (error_code Err = MemoryBuffer::getFile(ExcludeListFile, FileBuf)) {
+      errs() << "Unable to read from exclude file.\n";
+      return Err;
+    }
+    if (error_code Err = parseCLInput(FileBuf->getBuffer(), ExcludeList,
+                                      /*Separator=*/ "\n"))
+      return Err;
+  }
+  return error_code::success();
 }
 
 bool IncludeExcludeInfo::isFileIncluded(StringRef FilePath) {
Index: cpp11-migrate/Core/IncludeExcludeInfo.h
===================================================================
--- cpp11-migrate/Core/IncludeExcludeInfo.h
+++ cpp11-migrate/Core/IncludeExcludeInfo.h
@@ -16,16 +16,28 @@
 #define LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_INCLUDEEXCLUDEINFO_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/system_error.h"
 #include <vector>
 
 /// \brief Class encapsulating the handling of include and exclude paths
 /// provided by the user through command line options.
 class IncludeExcludeInfo {
 public:
-  /// \brief Determine if the given file is safe to transform.
+  /// \brief Read and parse a comma-seperated lists of filepaths from
+  /// \a IncludeString and \a ExcludeString.
   ///
-  /// \a Include and \a Exclude must be formatted as a comma-seperated list.
-  IncludeExcludeInfo(llvm::StringRef Include, llvm::StringRef Exclude);
+  /// Returns error_code::success() on successful parse of the strings or
+  /// an error_code indicating the encountered error.
+  llvm::error_code readListFromString(llvm::StringRef IncludeString,
+                                      llvm::StringRef ExcludeString);
+
+  /// \brief Read and parse the lists of filepaths from \a IncludeListFile
+  /// and \a ExcludeListFile. Each file should contain one filepath per line.
+  ///
+  /// Returns error_code::success() on successful read and parse of both files
+  /// or an error_code indicating the encountered error.
+  llvm::error_code readListFromFile(llvm::StringRef IncludeListFile,
+                                    llvm::StringRef ExcludeListFile);
 
   /// \brief Determine if the given filepath is in the list of include paths but
   /// not in the list of exclude paths.
Index: cpp11-migrate/tool/Cpp11Migrate.cpp
===================================================================
--- cpp11-migrate/tool/Cpp11Migrate.cpp
+++ cpp11-migrate/tool/Cpp11Migrate.cpp
@@ -60,6 +60,14 @@
 ExcludePaths("exclude", cl::Hidden,
              cl::desc("Comma seperated list of filepaths that can not "
                       "be transformed"));
+static cl::opt<std::string>
+IncludeFromFile("include-from", cl::Hidden, cl::value_desc("filename"),
+                cl::desc("File containing a list of filepaths to consider to "
+                         "be transformed"));
+static cl::opt<std::string>
+ExcludeFromFile("exclude-from", cl::Hidden, cl::value_desc("filename"),
+                cl::desc("File containing a list of filepaths that can not be "
+                         "transforms"));
 
 class EndSyntaxArgumentsAdjuster : public ArgumentsAdjuster {
   CommandLineArguments Adjust(const CommandLineArguments &Args) {
Index: unittests/cpp11-migrate/IncludeExcludeTest.cpp
===================================================================
--- unittests/cpp11-migrate/IncludeExcludeTest.cpp
+++ unittests/cpp11-migrate/IncludeExcludeTest.cpp
@@ -1,24 +1,21 @@
 #include "Core/IncludeExcludeInfo.h"
 #include "gtest/gtest.h"
 
-IncludeExcludeInfo IEManager(/*include=*/ "a,b/b2,c/c2/c3",
-                             /*exclude=*/ "a/af.cpp,a/a2,b/b2/b2f.cpp,c/c2/c3");
+TEST(IncludeExcludeTest, FunctionalityTest) {
+  IncludeExcludeInfo IEManager;
+  IEManager.readListFromString(/*include=*/ "a,b/b2,c/c2",
+                               /*exclude=*/ "a/af.cpp,a/a2,b/b2/b2f.cpp,c/c2");
 
-TEST(IncludeExcludeTest, NoMatchOnIncludeList) {
   // If the file does not appear on the include list then it is not safe to
   // transform. Files are not safe to transform by default.
   EXPECT_FALSE(IEManager.isFileIncluded("f.cpp"));
   EXPECT_FALSE(IEManager.isFileIncluded("b/dir/f.cpp"));
-}
 
-TEST(IncludeExcludeTest, MatchOnIncludeList) {
   // If the file appears on only the include list then it is safe to transform.
   EXPECT_TRUE(IEManager.isFileIncluded("a/f.cpp"));
   EXPECT_TRUE(IEManager.isFileIncluded("a/dir/f.cpp"));
   EXPECT_TRUE(IEManager.isFileIncluded("b/b2/f.cpp"));
-}
 
-TEST(IncludeExcludeTest, MatchOnBothLists) {
   // If the file appears on both the include or exclude list then it is not
   // safe to transform.
   EXPECT_FALSE(IEManager.isFileIncluded("a/af.cpp"));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D681.3.patch
Type: text/x-patch
Size: 7560 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130417/d58472af/attachment.bin>


More information about the cfe-commits mailing list