From 99b5a85324c758f15a72fdf084240f3c2af8ce35 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Tue, 20 May 2014 21:43:27 +0000 Subject: VirtualFileSystem: Add YAMLVFSWriter to generate VFS mapping files This moves the logic to write a JSON VFS mapping from the C api into VirtualFileSystem, so that we can use it internally. No functional change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209241 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/libclang/BuildSystem.cpp | 150 +++-------------------------------------- 1 file changed, 9 insertions(+), 141 deletions(-) (limited to 'tools') diff --git a/tools/libclang/BuildSystem.cpp b/tools/libclang/BuildSystem.cpp index e5caa5447b..e9423c3286 100644 --- a/tools/libclang/BuildSystem.cpp +++ b/tools/libclang/BuildSystem.cpp @@ -13,13 +13,12 @@ #include "clang-c/BuildSystem.h" #include "CXString.h" -#include "llvm/ADT/ArrayRef.h" +#include "clang/Basic/VirtualFileSystem.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Optional.h" +#include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Path.h" #include "llvm/Support/TimeValue.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/YAMLParser.h" using namespace clang; using namespace llvm::sys; @@ -28,13 +27,11 @@ unsigned long long clang_getBuildSessionTimestamp(void) { return llvm::sys::TimeValue::now().toEpochTime(); } -struct CXVirtualFileOverlayImpl { - std::vector > Mappings; - Optional IsCaseSensitive; -}; +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::vfs::YAMLVFSWriter, + CXVirtualFileOverlay) CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) { - return new CXVirtualFileOverlayImpl(); + return wrap(new clang::vfs::YAMLVFSWriter()); } enum CXErrorCode @@ -56,7 +53,7 @@ clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO, return CXError_InvalidArguments; } - VFO->Mappings.push_back(std::make_pair(virtualPath, realPath)); + unwrap(VFO)->addFileMapping(virtualPath, realPath); return CXError_Success; } @@ -65,124 +62,10 @@ clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO, int caseSensitive) { if (!VFO) return CXError_InvalidArguments; - - VFO->IsCaseSensitive = caseSensitive; + unwrap(VFO)->setCaseSensitivity(caseSensitive); return CXError_Success; } -namespace { -struct EntryTy { - std::string VPath; - std::string RPath; - - friend bool operator < (const EntryTy &LHS, const EntryTy &RHS) { - return LHS.VPath < RHS.VPath; - } -}; - -class JSONVFSPrinter { - llvm::raw_ostream &OS; - CXVirtualFileOverlay VFO; - -public: - JSONVFSPrinter(llvm::raw_ostream &OS, CXVirtualFileOverlay VFO) - : OS(OS), VFO(VFO) {} - - /// Entries must be sorted. - void print(ArrayRef Entries) { - OS << "{\n" - " 'version': 0,\n"; - if (VFO->IsCaseSensitive.hasValue()) { - OS << " 'case-sensitive': '"; - if (VFO->IsCaseSensitive.getValue()) - OS << "true"; - else - OS << "false"; - OS << "',\n"; - } - OS << " 'roots': [\n"; - printDirNodes(Entries, "", 4); - OS << " ]\n" - "}\n"; - } - -private: - ArrayRef printDirNodes(ArrayRef Entries, - StringRef ParentPath, - unsigned Indent) { - while (!Entries.empty()) { - const EntryTy &Entry = Entries.front(); - OS.indent(Indent) << "{\n"; - Indent += 2; - OS.indent(Indent) << "'type': 'directory',\n"; - StringRef DirName = containedPart(ParentPath, - path::parent_path(Entry.VPath)); - OS.indent(Indent) - << "'name': \"" << llvm::yaml::escape(DirName) << "\",\n"; - OS.indent(Indent) << "'contents': [\n"; - Entries = printContents(Entries, Indent + 2); - OS.indent(Indent) << "]\n"; - Indent -= 2; - OS.indent(Indent) << '}'; - if (Entries.empty()) { - OS << '\n'; - break; - } - StringRef NextVPath = Entries.front().VPath; - if (!containedIn(ParentPath, NextVPath)) { - OS << '\n'; - break; - } - OS << ",\n"; - } - return Entries; - } - - ArrayRef printContents(ArrayRef Entries, - unsigned Indent) { - while (!Entries.empty()) { - const EntryTy &Entry = Entries.front(); - Entries = Entries.slice(1); - StringRef ParentPath = path::parent_path(Entry.VPath); - StringRef VName = path::filename(Entry.VPath); - OS.indent(Indent) << "{\n"; - Indent += 2; - OS.indent(Indent) << "'type': 'file',\n"; - OS.indent(Indent) << "'name': \"" << llvm::yaml::escape(VName) << "\",\n"; - OS.indent(Indent) << "'external-contents': \"" - << llvm::yaml::escape(Entry.RPath) << "\"\n"; - Indent -= 2; - OS.indent(Indent) << '}'; - if (Entries.empty()) { - OS << '\n'; - break; - } - StringRef NextVPath = Entries.front().VPath; - if (!containedIn(ParentPath, NextVPath)) { - OS << '\n'; - break; - } - OS << ",\n"; - if (path::parent_path(NextVPath) != ParentPath) { - Entries = printDirNodes(Entries, ParentPath, Indent); - } - } - return Entries; - } - - bool containedIn(StringRef Parent, StringRef Path) { - return Path.startswith(Parent); - } - - StringRef containedPart(StringRef Parent, StringRef Path) { - assert(containedIn(Parent, Path)); - if (Parent.empty()) - return Path; - return Path.slice(Parent.size()+1, StringRef::npos); - } -}; -} - enum CXErrorCode clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, char **out_buffer_ptr, @@ -190,24 +73,9 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, if (!VFO || !out_buffer_ptr || !out_buffer_size) return CXError_InvalidArguments; - llvm::SmallVector Entries; - for (unsigned i = 0, e = VFO->Mappings.size(); i != e; ++i) { - EntryTy Entry; - Entry.VPath = VFO->Mappings[i].first; - Entry.RPath = VFO->Mappings[i].second; - Entries.push_back(Entry); - } - - // FIXME: We should add options to determine if the paths are case sensitive - // or not. The following assumes that if paths are case-insensitive the caller - // did not mix cases in the virtual paths it provided. - - std::sort(Entries.begin(), Entries.end()); - llvm::SmallString<256> Buf; llvm::raw_svector_ostream OS(Buf); - JSONVFSPrinter Printer(OS, VFO); - Printer.print(Entries); + unwrap(VFO)->write(OS); StringRef Data = OS.str(); *out_buffer_ptr = (char*)malloc(Data.size()); @@ -217,7 +85,7 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, } void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) { - delete VFO; + delete unwrap(VFO); } -- cgit v1.2.3