You've already forked linux-packaging-mono
							
							
		
			
	
	
		
			173 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			173 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | //===- DiffPrinter.h ------------------------------------------ *- C++ --*-===//
 | ||
|  | //
 | ||
|  | //                     The LLVM Compiler Infrastructure
 | ||
|  | //
 | ||
|  | // This file is distributed under the University of Illinois Open Source
 | ||
|  | // License. See LICENSE.TXT for details.
 | ||
|  | //
 | ||
|  | //===----------------------------------------------------------------------===//
 | ||
|  | 
 | ||
|  | #ifndef LLVM_TOOLS_LLVMPDBDUMP_DIFFPRINTER_H
 | ||
|  | #define LLVM_TOOLS_LLVMPDBDUMP_DIFFPRINTER_H
 | ||
|  | 
 | ||
|  | #include "llvm/ADT/ArrayRef.h"
 | ||
|  | #include "llvm/ADT/StringMap.h"
 | ||
|  | #include "llvm/ADT/StringRef.h"
 | ||
|  | #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
 | ||
|  | #include "llvm/Support/FormatVariadic.h"
 | ||
|  | #include "llvm/Support/raw_ostream.h"
 | ||
|  | 
 | ||
|  | #include <list>
 | ||
|  | #include <unordered_set>
 | ||
|  | 
 | ||
|  | namespace std { | ||
|  | template <> struct hash<llvm::pdb::PdbRaw_FeatureSig> { | ||
|  |   typedef llvm::pdb::PdbRaw_FeatureSig argument_type; | ||
|  |   typedef std::size_t result_type; | ||
|  |   result_type operator()(argument_type Item) const { | ||
|  |     return std::hash<uint32_t>{}(uint32_t(Item)); | ||
|  |   } | ||
|  | }; | ||
|  | } // namespace std
 | ||
|  | 
 | ||
|  | namespace llvm { | ||
|  | namespace pdb { | ||
|  | 
 | ||
|  | class PDBFile; | ||
|  | 
 | ||
|  | enum class DiffResult { UNSPECIFIED, IDENTICAL, EQUIVALENT, DIFFERENT }; | ||
|  | 
 | ||
|  | struct IdenticalDiffProvider { | ||
|  |   template <typename T, typename U> | ||
|  |   DiffResult compare(const T &Left, const U &Right) { | ||
|  |     return (Left == Right) ? DiffResult::IDENTICAL : DiffResult::DIFFERENT; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename T> std::string format(const T &Item, bool Right) { | ||
|  |     return formatv("{0}", Item).str(); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | struct EquivalentDiffProvider { | ||
|  |   template <typename T, typename U> | ||
|  |   DiffResult compare(const T &Left, const U &Right) { | ||
|  |     return (Left == Right) ? DiffResult::IDENTICAL : DiffResult::EQUIVALENT; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename T> std::string format(const T &Item, bool Right) { | ||
|  |     return formatv("{0}", Item).str(); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | class DiffPrinter { | ||
|  | public: | ||
|  |   DiffPrinter(uint32_t Indent, StringRef Header, uint32_t PropertyWidth, | ||
|  |               uint32_t FieldWidth, bool Result, bool Values, | ||
|  |               raw_ostream &Stream); | ||
|  |   ~DiffPrinter(); | ||
|  | 
 | ||
|  |   template <typename T, typename U> struct Identical {}; | ||
|  | 
 | ||
|  |   template <typename Provider = IdenticalDiffProvider, typename T, typename U> | ||
|  |   void print(StringRef Property, const T &Left, const U &Right, | ||
|  |              Provider P = Provider()) { | ||
|  |     std::string L = P.format(Left, false); | ||
|  |     std::string R = P.format(Right, true); | ||
|  | 
 | ||
|  |     DiffResult Result = P.compare(Left, Right); | ||
|  |     printExplicit(Property, Result, L, R); | ||
|  |   } | ||
|  | 
 | ||
|  |   void printExplicit(StringRef Property, DiffResult C, StringRef Left, | ||
|  |                      StringRef Right); | ||
|  | 
 | ||
|  |   template <typename T, typename U> | ||
|  |   void printExplicit(StringRef Property, DiffResult C, const T &Left, | ||
|  |                      const U &Right) { | ||
|  |     std::string L = formatv("{0}", Left).str(); | ||
|  |     std::string R = formatv("{0}", Right).str(); | ||
|  |     printExplicit(Property, C, StringRef(L), StringRef(R)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename T, typename U> | ||
|  |   void diffUnorderedArray(StringRef Property, ArrayRef<T> Left, | ||
|  |                           ArrayRef<U> Right) { | ||
|  |     std::unordered_set<T> LS(Left.begin(), Left.end()); | ||
|  |     std::unordered_set<U> RS(Right.begin(), Right.end()); | ||
|  |     std::string Count1 = formatv("{0} element(s)", Left.size()); | ||
|  |     std::string Count2 = formatv("{0} element(s)", Right.size()); | ||
|  |     print(std::string(Property) + "s (set)", Count1, Count2); | ||
|  |     for (const auto &L : LS) { | ||
|  |       auto Iter = RS.find(L); | ||
|  |       std::string Text = formatv("{0}", L).str(); | ||
|  |       if (Iter == RS.end()) { | ||
|  |         print(Property, Text, "(not present)"); | ||
|  |         continue; | ||
|  |       } | ||
|  |       print(Property, Text, Text); | ||
|  |       RS.erase(Iter); | ||
|  |     } | ||
|  |     for (const auto &R : RS) { | ||
|  |       auto Iter = LS.find(R); | ||
|  |       std::string Text = formatv("{0}", R).str(); | ||
|  |       if (Iter == LS.end()) { | ||
|  |         print(Property, "(not present)", Text); | ||
|  |         continue; | ||
|  |       } | ||
|  |       print(Property, Text, Text); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename ValueProvider = IdenticalDiffProvider, typename T, | ||
|  |             typename U> | ||
|  |   void diffUnorderedMap(StringRef Property, const StringMap<T> &Left, | ||
|  |                         const StringMap<U> &Right, | ||
|  |                         ValueProvider P = ValueProvider()) { | ||
|  |     StringMap<U> RightCopy(Right); | ||
|  | 
 | ||
|  |     std::string Count1 = formatv("{0} element(s)", Left.size()); | ||
|  |     std::string Count2 = formatv("{0} element(s)", Right.size()); | ||
|  |     print(std::string(Property) + "s (map)", Count1, Count2); | ||
|  | 
 | ||
|  |     for (const auto &L : Left) { | ||
|  |       auto Iter = RightCopy.find(L.getKey()); | ||
|  |       if (Iter == RightCopy.end()) { | ||
|  |         printExplicit(L.getKey(), DiffResult::DIFFERENT, L.getValue(), | ||
|  |                       "(not present)"); | ||
|  |         continue; | ||
|  |       } | ||
|  | 
 | ||
|  |       print(L.getKey(), L.getValue(), Iter->getValue(), P); | ||
|  |       RightCopy.erase(Iter); | ||
|  |     } | ||
|  | 
 | ||
|  |     for (const auto &R : RightCopy) { | ||
|  |       printExplicit(R.getKey(), DiffResult::DIFFERENT, "(not present)", | ||
|  |                     R.getValue()); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   void printFullRow(StringRef Text); | ||
|  | 
 | ||
|  | private: | ||
|  |   uint32_t tableWidth() const; | ||
|  | 
 | ||
|  |   void printHeaderRow(); | ||
|  |   void printSeparatorRow(); | ||
|  |   void newLine(char InitialChar = '|'); | ||
|  |   void printValue(StringRef Value, DiffResult C, AlignStyle Style, | ||
|  |                   uint32_t Width, bool Force); | ||
|  |   void printResult(DiffResult Result); | ||
|  | 
 | ||
|  |   bool PrintResult; | ||
|  |   bool PrintValues; | ||
|  |   uint32_t Indent; | ||
|  |   uint32_t PropertyWidth; | ||
|  |   uint32_t FieldWidth; | ||
|  |   raw_ostream &OS; | ||
|  | }; | ||
|  | } // namespace pdb
 | ||
|  | } // namespace llvm
 | ||
|  | 
 | ||
|  | #endif
 |