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" 26using namespace clang; 27 28//===----------------------------------------------------------------------===// 29// Functional HTML pretty-printing. 30//===----------------------------------------------------------------------===// 31 32namespace { 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); 46 void HandleTranslationUnit(ASTContext &Ctx); 47 }; 48} 49 50ASTConsumer* clang::CreateHTMLPrinter(raw_ostream *OS, 51 Preprocessor &PP, 52 bool SyntaxHighlight, 53 bool HighlightMacros) { 54 return new HTMLPrinter(OS, PP, SyntaxHighlight, HighlightMacros); 55} 56 57void HTMLPrinter::Initialize(ASTContext &context) { 58 R.setSourceMgr(context.getSourceManager(), context.getLangOpts()); 59} 60 61void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) { 62 if (PP.getDiagnostics().hasErrorOccurred()) 63 return; 64 65 // Format the file. 66 FileID FID = R.getSourceMgr().getMainFileID(); 67 const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID); 68 const char* Name; 69 // In some cases, in particular the case where the input is from stdin, 70 // there is no entry. Fall back to the memory buffer for a name in those 71 // cases. 72 if (Entry) 73 Name = Entry->getName(); 74 else 75 Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier(); 76 77 html::AddLineNumbers(R, FID); 78 html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name); 79 80 // If we have a preprocessor, relex the file and syntax highlight. 81 // We might not have a preprocessor if we come from a deserialized AST file, 82 // for example. 83 84 if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP); 85 if (HighlightMacros) html::HighlightMacros(R, FID, PP); 86 html::EscapeText(R, FID, false, true); 87 88 // Emit the HTML. 89 const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID); 90 char *Buffer = (char*)malloc(RewriteBuf.size()); 91 std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer); 92 Out->write(Buffer, RewriteBuf.size()); 93 free(Buffer); 94} 95