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