• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
HTMLPrinter(raw_ostream * OS,Preprocessor & pp,bool _SyntaxHighlight,bool _HighlightMacros)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  
CreateHTMLPrinter(raw_ostream * OS,Preprocessor & PP,bool SyntaxHighlight,bool HighlightMacros)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  
Initialize(ASTContext & context)58  void HTMLPrinter::Initialize(ASTContext &context) {
59    R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
60  }
61  
HandleTranslationUnit(ASTContext & Ctx)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