1 //===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_BASIC_PLISTSUPPORT_H 11 #define LLVM_CLANG_BASIC_PLISTSUPPORT_H 12 13 #include "clang/Basic/SourceManager.h" 14 #include "llvm/Support/raw_ostream.h" 15 16 namespace clang { 17 namespace markup { 18 typedef llvm::DenseMap<FileID, unsigned> FIDMap; 19 20 inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V, 21 const SourceManager &SM, SourceLocation L) { 22 FileID FID = SM.getFileID(SM.getExpansionLoc(L)); 23 FIDMap::iterator I = FIDs.find(FID); 24 if (I != FIDs.end()) 25 return; 26 FIDs[FID] = V.size(); 27 V.push_back(FID); 28 } 29 30 inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM, 31 SourceLocation L) { 32 FileID FID = SM.getFileID(SM.getExpansionLoc(L)); 33 FIDMap::const_iterator I = FIDs.find(FID); 34 assert(I != FIDs.end()); 35 return I->second; 36 } 37 38 inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) { 39 for (unsigned i = 0; i < indent; ++i) 40 o << ' '; 41 return o; 42 } 43 44 inline raw_ostream &EmitPlistHeader(raw_ostream &o) { 45 static const char *PlistHeader = 46 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 47 "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" " 48 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 49 "<plist version=\"1.0\">\n"; 50 return o << PlistHeader; 51 } 52 53 inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) { 54 o << "<integer>"; 55 o << value; 56 o << "</integer>"; 57 return o; 58 } 59 60 inline raw_ostream &EmitString(raw_ostream &o, StringRef s) { 61 o << "<string>"; 62 for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { 63 char c = *I; 64 switch (c) { 65 default: 66 o << c; 67 break; 68 case '&': 69 o << "&"; 70 break; 71 case '<': 72 o << "<"; 73 break; 74 case '>': 75 o << ">"; 76 break; 77 case '\'': 78 o << "'"; 79 break; 80 case '\"': 81 o << """; 82 break; 83 } 84 } 85 o << "</string>"; 86 return o; 87 } 88 89 inline void EmitLocation(raw_ostream &o, const SourceManager &SM, 90 SourceLocation L, const FIDMap &FM, unsigned indent) { 91 if (L.isInvalid()) return; 92 93 FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM)); 94 95 Indent(o, indent) << "<dict>\n"; 96 Indent(o, indent) << " <key>line</key>"; 97 EmitInteger(o, Loc.getExpansionLineNumber()) << '\n'; 98 Indent(o, indent) << " <key>col</key>"; 99 EmitInteger(o, Loc.getExpansionColumnNumber()) << '\n'; 100 Indent(o, indent) << " <key>file</key>"; 101 EmitInteger(o, GetFID(FM, SM, Loc)) << '\n'; 102 Indent(o, indent) << "</dict>\n"; 103 } 104 105 inline void EmitRange(raw_ostream &o, const SourceManager &SM, 106 CharSourceRange R, const FIDMap &FM, unsigned indent) { 107 if (R.isInvalid()) return; 108 109 assert(R.isCharRange() && "cannot handle a token range"); 110 Indent(o, indent) << "<array>\n"; 111 EmitLocation(o, SM, R.getBegin(), FM, indent + 1); 112 EmitLocation(o, SM, R.getEnd(), FM, indent + 1); 113 Indent(o, indent) << "</array>\n"; 114 } 115 } 116 } 117 118 #endif 119