1 //===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===// 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 // Pretty-printing of source code to HTML. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Rewrite/Frontend/ASTConsumers.h" 15 #include "clang/AST/ASTConsumer.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/Basic/Diagnostic.h" 19 #include "clang/Basic/FileManager.h" 20 #include "clang/Basic/SourceManager.h" 21 #include "clang/Lex/Preprocessor.h" 22 #include "clang/Rewrite/Core/HTMLRewrite.h" 23 #include "clang/Rewrite/Core/Rewriter.h" 24 #include "llvm/Support/MemoryBuffer.h" 25 #include "llvm/Support/raw_ostream.h" 26 using namespace clang; 27 28 //===----------------------------------------------------------------------===// 29 // Functional HTML pretty-printing. 30 //===----------------------------------------------------------------------===// 31 32 namespace { 33 class HTMLPrinter : public ASTConsumer { 34 Rewriter R; 35 raw_ostream *Out; 36 Preprocessor &PP; 37 bool SyntaxHighlight, HighlightMacros; 38 39 public: 40 HTMLPrinter(raw_ostream *OS, Preprocessor &pp, 41 bool _SyntaxHighlight, bool _HighlightMacros) 42 : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight), 43 HighlightMacros(_HighlightMacros) {} 44 45 void Initialize(ASTContext &context) override; 46 void HandleTranslationUnit(ASTContext &Ctx) override; 47 }; 48 } 49 50 std::unique_ptr<ASTConsumer> clang::CreateHTMLPrinter(raw_ostream *OS, 51 Preprocessor &PP, 52 bool SyntaxHighlight, 53 bool HighlightMacros) { 54 return llvm::make_unique<HTMLPrinter>(OS, PP, SyntaxHighlight, 55 HighlightMacros); 56 } 57 58 void HTMLPrinter::Initialize(ASTContext &context) { 59 R.setSourceMgr(context.getSourceManager(), context.getLangOpts()); 60 } 61 62 void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) { 63 if (PP.getDiagnostics().hasErrorOccurred()) 64 return; 65 66 // Format the file. 67 FileID FID = R.getSourceMgr().getMainFileID(); 68 const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID); 69 const char* Name; 70 // In some cases, in particular the case where the input is from stdin, 71 // there is no entry. Fall back to the memory buffer for a name in those 72 // cases. 73 if (Entry) 74 Name = Entry->getName(); 75 else 76 Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier(); 77 78 html::AddLineNumbers(R, FID); 79 html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name); 80 81 // If we have a preprocessor, relex the file and syntax highlight. 82 // We might not have a preprocessor if we come from a deserialized AST file, 83 // for example. 84 85 if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP); 86 if (HighlightMacros) html::HighlightMacros(R, FID, PP); 87 html::EscapeText(R, FID, false, true); 88 89 // Emit the HTML. 90 const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID); 91 char *Buffer = (char*)malloc(RewriteBuf.size()); 92 std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer); 93 Out->write(Buffer, RewriteBuf.size()); 94 free(Buffer); 95 } 96