johannes updated this revision to Diff 112127.
johannes added a comment.

casing


https://reviews.llvm.org/D36686

Files:
  tools/clang-diff/ClangDiff.cpp

Index: tools/clang-diff/ClangDiff.cpp
===================================================================
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -16,6 +16,7 @@
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Program.h"
 
 using namespace llvm;
 using namespace clang;
@@ -33,9 +34,9 @@
     cl::desc("Print the internal representation of the AST as JSON."),
     cl::init(false), cl::cat(ClangDiffCategory));
 
-static cl::opt<bool>
-    PrintMatches("dump-matches", cl::desc("Print the matched nodes."),
-                 cl::init(false), cl::cat(ClangDiffCategory));
+static cl::opt<bool> PrintMatches("dump-matches",
+                                  cl::desc("Print the matched nodes."),
+                                  cl::init(false), cl::cat(ClangDiffCategory));
 
 static cl::opt<bool> HtmlDiff("html",
                               cl::desc("Output a side-by-side diff in HTML."),
@@ -55,6 +56,12 @@
                                       cl::Optional, cl::init(""),
                                       cl::cat(ClangDiffCategory));
 
+static cl::opt<std::string>
+    GitRevision("git-rev",
+                cl::desc("Compare a file between a revision range (<rev>..HEAD "
+                         "is assumed if a single revision is given."),
+                cl::Optional, cl::init(""), cl::cat(ClangDiffCategory));
+
 static cl::opt<int> MaxSize("s", cl::desc("<maxsize>"), cl::Optional,
                             cl::init(-1), cl::cat(ClangDiffCategory));
 
@@ -441,6 +448,19 @@
   }
 }
 
+std::string Exec(const char *Command) {
+  char Buffer[128];
+  std::string Result;
+  std::shared_ptr<FILE> Pipe(popen(Command, "r"), pclose);
+  if (!Pipe)
+    return Result;
+  while (!feof(Pipe.get())) {
+    if (fgets(Buffer, 128, Pipe.get()) != nullptr)
+      Result += Buffer;
+  }
+  return Result;
+}
+
 int main(int argc, const char **argv) {
   std::string ErrorMessage;
   std::unique_ptr<CompilationDatabase> CommonCompilations =
@@ -476,13 +496,55 @@
     return 0;
   }
 
-  if (DestinationPath.empty()) {
+  if (DestinationPath.empty() && GitRevision.empty()) {
     llvm::errs() << "Error: Exactly two paths are required.\n";
     return 1;
   }
 
-  std::unique_ptr<ASTUnit> Src = getAST(CommonCompilations, SourcePath);
-  std::unique_ptr<ASTUnit> Dst = getAST(CommonCompilations, DestinationPath);
+  std::unique_ptr<ASTUnit> Src, Dst;
+
+  if (!GitRevision.empty()) {
+    std::string Git;
+    auto ErrorOrGit = llvm::sys::findProgramByName("git");
+    if (!ErrorOrGit) {
+      llvm::errs() << "Error: Could not find git executable.\n";
+      return 1;
+    }
+    Git = ErrorOrGit.get();
+    if (GitRevision.find("..") == std::string::npos)
+      GitRevision += "..HEAD";
+    size_t Dots = GitRevision.find("..");
+    GitRevision.replace(Dots, 2, "  ");
+    GitRevision += " HEAD";
+    std::string RevParseCommand = "git rev-parse " + GitRevision;
+    std::string Revisions = Exec(RevParseCommand.data());
+    std::transform(Revisions.begin(), Revisions.end(), Revisions.begin(),
+                   [](char C) { return C == '\n' ? '\0' : C; });
+    auto SrcRev = Revisions.data();
+    size_t Offset = Revisions.find('\0') + 1;
+    auto DstRev = Revisions.data() + Offset;
+    auto UserRev = Revisions.data() + Revisions.find('\0', Offset) + 1;
+    const char *CheckoutCommand[] = {"git", "checkout", nullptr, nullptr};
+    auto Checkout = [&](const char *Rev) {
+      CheckoutCommand[2] = Rev;
+      if (llvm::sys::ExecuteAndWait(Git, CheckoutCommand)) {
+        llvm::errs() << "Error: Failed to checkout " << Rev << "\n";
+        return false;
+      }
+      return true;
+    };
+    if (!Checkout(SrcRev))
+      return 1;
+    Src = getAST(CommonCompilations, SourcePath);
+    if (!Checkout(DstRev))
+      return 1;
+    Dst = getAST(CommonCompilations, SourcePath);
+    Checkout(UserRev);
+  } else {
+    Src = getAST(CommonCompilations, SourcePath);
+    Dst = getAST(CommonCompilations, DestinationPath);
+  }
+
   if (!Src || !Dst)
     return 1;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to