1243791Sdim//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
2243791Sdim//
3243791Sdim//                     The LLVM Compiler Infrastructure
4243791Sdim//
5243791Sdim// This file is distributed under the University of Illinois Open Source
6243791Sdim// License. See LICENSE.TXT for details.
7243791Sdim//
8243791Sdim//===----------------------------------------------------------------------===//
9243791Sdim//
10243791Sdim// Pretty-printing of source code to HTML.
11243791Sdim//
12243791Sdim//===----------------------------------------------------------------------===//
13243791Sdim
14243791Sdim#include "clang/Rewrite/Frontend/ASTConsumers.h"
15243791Sdim#include "clang/AST/ASTConsumer.h"
16243791Sdim#include "clang/AST/ASTContext.h"
17243791Sdim#include "clang/AST/Decl.h"
18243791Sdim#include "clang/Basic/Diagnostic.h"
19243791Sdim#include "clang/Basic/FileManager.h"
20243791Sdim#include "clang/Basic/SourceManager.h"
21243791Sdim#include "clang/Lex/Preprocessor.h"
22243791Sdim#include "clang/Rewrite/Core/HTMLRewrite.h"
23243791Sdim#include "clang/Rewrite/Core/Rewriter.h"
24243791Sdim#include "llvm/Support/MemoryBuffer.h"
25243791Sdim#include "llvm/Support/raw_ostream.h"
26243791Sdimusing namespace clang;
27243791Sdim
28243791Sdim//===----------------------------------------------------------------------===//
29243791Sdim// Functional HTML pretty-printing.
30243791Sdim//===----------------------------------------------------------------------===//
31243791Sdim
32243791Sdimnamespace {
33243791Sdim  class HTMLPrinter : public ASTConsumer {
34243791Sdim    Rewriter R;
35243791Sdim    raw_ostream *Out;
36243791Sdim    Preprocessor &PP;
37243791Sdim    bool SyntaxHighlight, HighlightMacros;
38243791Sdim
39243791Sdim  public:
40243791Sdim    HTMLPrinter(raw_ostream *OS, Preprocessor &pp,
41243791Sdim                bool _SyntaxHighlight, bool _HighlightMacros)
42243791Sdim      : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight),
43243791Sdim        HighlightMacros(_HighlightMacros) {}
44243791Sdim
45243791Sdim    void Initialize(ASTContext &context);
46243791Sdim    void HandleTranslationUnit(ASTContext &Ctx);
47243791Sdim  };
48243791Sdim}
49243791Sdim
50243791SdimASTConsumer* clang::CreateHTMLPrinter(raw_ostream *OS,
51243791Sdim                                      Preprocessor &PP,
52243791Sdim                                      bool SyntaxHighlight,
53243791Sdim                                      bool HighlightMacros) {
54243791Sdim  return new HTMLPrinter(OS, PP, SyntaxHighlight, HighlightMacros);
55243791Sdim}
56243791Sdim
57243791Sdimvoid HTMLPrinter::Initialize(ASTContext &context) {
58243791Sdim  R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
59243791Sdim}
60243791Sdim
61243791Sdimvoid HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
62243791Sdim  if (PP.getDiagnostics().hasErrorOccurred())
63243791Sdim    return;
64243791Sdim
65243791Sdim  // Format the file.
66243791Sdim  FileID FID = R.getSourceMgr().getMainFileID();
67243791Sdim  const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
68243791Sdim  const char* Name;
69243791Sdim  // In some cases, in particular the case where the input is from stdin,
70243791Sdim  // there is no entry.  Fall back to the memory buffer for a name in those
71243791Sdim  // cases.
72243791Sdim  if (Entry)
73243791Sdim    Name = Entry->getName();
74243791Sdim  else
75243791Sdim    Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier();
76243791Sdim
77243791Sdim  html::AddLineNumbers(R, FID);
78243791Sdim  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
79243791Sdim
80243791Sdim  // If we have a preprocessor, relex the file and syntax highlight.
81243791Sdim  // We might not have a preprocessor if we come from a deserialized AST file,
82243791Sdim  // for example.
83243791Sdim
84243791Sdim  if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
85243791Sdim  if (HighlightMacros) html::HighlightMacros(R, FID, PP);
86243791Sdim  html::EscapeText(R, FID, false, true);
87243791Sdim
88243791Sdim  // Emit the HTML.
89243791Sdim  const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
90243791Sdim  char *Buffer = (char*)malloc(RewriteBuf.size());
91243791Sdim  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
92243791Sdim  Out->write(Buffer, RewriteBuf.size());
93243791Sdim  free(Buffer);
94243791Sdim}
95