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