//== HTMLRewrite.cpp - Translate source code into prettified HTML --*- C++ -*-// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the HTMLRewriter clas, which is used to translate the // text of a source file into prettified HTML. // //===----------------------------------------------------------------------===// #include "clang/Rewrite/Rewriter.h" #include "clang/Rewrite/HTMLRewrite.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/MemoryBuffer.h" #include using namespace clang; void html::EscapeText(Rewriter& R, unsigned FileID, bool EscapeSpaces) { const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); const char* C = Buf->getBufferStart(); const char* FileEnd = Buf->getBufferEnd(); assert (C <= FileEnd); for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) { SourceLocation Loc = SourceLocation::getFileLoc(FileID, FilePos); switch (*C) { default: break; case ' ': if (EscapeSpaces) R.ReplaceText(Loc, 1, " ", 5); break; case '<': R.ReplaceText(Loc, 1, "<", 4); break; case '>': R.ReplaceText(Loc, 1, ">", 4); break; case '&': R.ReplaceText(Loc, 1, "&", 5); break; } } } static void AddLineNumber(Rewriter& R, unsigned LineNo, SourceLocation B, SourceLocation E) { // Surround the line with a span tag. R.InsertTextBefore(E, "", 7); R.InsertTextBefore(B, "", 18); // Insert a span tag for the line number. std::ostringstream os; os << "" << LineNo << ""; R.InsertTextBefore(B, os.str().c_str(), os.str().size()); } void html::AddLineNumbers(Rewriter& R, unsigned FileID) { const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); const char* FileBeg = Buf->getBufferStart(); const char* FileEnd = Buf->getBufferEnd(); const char* C = FileBeg; assert (C <= FileEnd); unsigned LineNo = 0; unsigned FilePos = 0; while (C != FileEnd) { ++LineNo; unsigned LineStartPos = FilePos; unsigned LineEndPos = FileEnd - FileBeg; assert (FilePos <= LineEndPos); assert (C < FileEnd); // Scan until the newline (or end-of-file). for ( ; C != FileEnd ; ++C, ++FilePos) if (*C == '\n') { LineEndPos = FilePos; break; } AddLineNumber(R, LineNo, SourceLocation::getFileLoc(FileID, LineStartPos), SourceLocation::getFileLoc(FileID, LineEndPos)); if (C != FileEnd) { ++C; ++FilePos; } } }