1139f7f9bSDimitry Andric //===--- ClangCommentHTMLNamedCharacterReferenceEmitter.cpp -----------------=// 2139f7f9bSDimitry Andric // 3139f7f9bSDimitry Andric // The LLVM Compiler Infrastructure 4139f7f9bSDimitry Andric // 5139f7f9bSDimitry Andric // This file is distributed under the University of Illinois Open Source 6139f7f9bSDimitry Andric // License. See LICENSE.TXT for details. 7139f7f9bSDimitry Andric // 8139f7f9bSDimitry Andric //===----------------------------------------------------------------------===// 9139f7f9bSDimitry Andric // 10139f7f9bSDimitry Andric // This tablegen backend emits an fficient function to translate HTML named 11139f7f9bSDimitry Andric // character references to UTF-8 sequences. 12139f7f9bSDimitry Andric // 13139f7f9bSDimitry Andric //===----------------------------------------------------------------------===// 14139f7f9bSDimitry Andric 15139f7f9bSDimitry Andric #include "llvm/ADT/SmallString.h" 16139f7f9bSDimitry Andric #include "llvm/Support/ConvertUTF.h" 17139f7f9bSDimitry Andric #include "llvm/TableGen/Error.h" 18139f7f9bSDimitry Andric #include "llvm/TableGen/Record.h" 19139f7f9bSDimitry Andric #include "llvm/TableGen/StringMatcher.h" 20139f7f9bSDimitry Andric #include "llvm/TableGen/TableGenBackend.h" 21139f7f9bSDimitry Andric #include <vector> 22139f7f9bSDimitry Andric 23139f7f9bSDimitry Andric using namespace llvm; 24139f7f9bSDimitry Andric 25139f7f9bSDimitry Andric /// \brief Convert a code point to the corresponding UTF-8 sequence represented 26139f7f9bSDimitry Andric /// as a C string literal. 27139f7f9bSDimitry Andric /// 28139f7f9bSDimitry Andric /// \returns true on success. 29139f7f9bSDimitry Andric static bool translateCodePointToUTF8(unsigned CodePoint, 30139f7f9bSDimitry Andric SmallVectorImpl<char> &CLiteral) { 31139f7f9bSDimitry Andric char Translated[UNI_MAX_UTF8_BYTES_PER_CODE_POINT]; 32139f7f9bSDimitry Andric char *TranslatedPtr = Translated; 33139f7f9bSDimitry Andric if (!ConvertCodePointToUTF8(CodePoint, TranslatedPtr)) 34139f7f9bSDimitry Andric return false; 35139f7f9bSDimitry Andric 36139f7f9bSDimitry Andric StringRef UTF8(Translated, TranslatedPtr - Translated); 37139f7f9bSDimitry Andric 38139f7f9bSDimitry Andric raw_svector_ostream OS(CLiteral); 39139f7f9bSDimitry Andric OS << "\""; 40139f7f9bSDimitry Andric for (size_t i = 0, e = UTF8.size(); i != e; ++i) { 41139f7f9bSDimitry Andric OS << "\\x"; 42139f7f9bSDimitry Andric OS.write_hex(static_cast<unsigned char>(UTF8[i])); 43139f7f9bSDimitry Andric } 44139f7f9bSDimitry Andric OS << "\""; 45139f7f9bSDimitry Andric 46139f7f9bSDimitry Andric return true; 47139f7f9bSDimitry Andric } 48139f7f9bSDimitry Andric 49139f7f9bSDimitry Andric namespace clang { 50139f7f9bSDimitry Andric void EmitClangCommentHTMLNamedCharacterReferences(RecordKeeper &Records, 51139f7f9bSDimitry Andric raw_ostream &OS) { 52139f7f9bSDimitry Andric std::vector<Record *> Tags = Records.getAllDerivedDefinitions("NCR"); 53139f7f9bSDimitry Andric std::vector<StringMatcher::StringPair> NameToUTF8; 54139f7f9bSDimitry Andric SmallString<32> CLiteral; 55139f7f9bSDimitry Andric for (std::vector<Record *>::iterator I = Tags.begin(), E = Tags.end(); 56139f7f9bSDimitry Andric I != E; ++I) { 57139f7f9bSDimitry Andric Record &Tag = **I; 58139f7f9bSDimitry Andric std::string Spelling = Tag.getValueAsString("Spelling"); 59139f7f9bSDimitry Andric uint64_t CodePoint = Tag.getValueAsInt("CodePoint"); 60139f7f9bSDimitry Andric CLiteral.clear(); 61139f7f9bSDimitry Andric CLiteral.append("return "); 62139f7f9bSDimitry Andric if (!translateCodePointToUTF8(CodePoint, CLiteral)) { 63139f7f9bSDimitry Andric SrcMgr.PrintMessage(Tag.getLoc().front(), 64139f7f9bSDimitry Andric SourceMgr::DK_Error, 65139f7f9bSDimitry Andric Twine("invalid code point")); 66139f7f9bSDimitry Andric continue; 67139f7f9bSDimitry Andric } 68139f7f9bSDimitry Andric CLiteral.append(";"); 69139f7f9bSDimitry Andric 70139f7f9bSDimitry Andric StringMatcher::StringPair Match(Spelling, CLiteral.str()); 71139f7f9bSDimitry Andric NameToUTF8.push_back(Match); 72139f7f9bSDimitry Andric } 73139f7f9bSDimitry Andric 74139f7f9bSDimitry Andric emitSourceFileHeader("HTML named character reference to UTF-8 " 75139f7f9bSDimitry Andric "translation", OS); 76139f7f9bSDimitry Andric 77139f7f9bSDimitry Andric OS << "StringRef translateHTMLNamedCharacterReferenceToUTF8(\n" 78139f7f9bSDimitry Andric " StringRef Name) {\n"; 79139f7f9bSDimitry Andric StringMatcher("Name", NameToUTF8, OS).Emit(); 80139f7f9bSDimitry Andric OS << " return StringRef();\n" 81139f7f9bSDimitry Andric << "}\n\n"; 82139f7f9bSDimitry Andric } 83139f7f9bSDimitry Andric 84139f7f9bSDimitry Andric } // end namespace clang 85139f7f9bSDimitry Andric 86