summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/Driver/HTMLPrint.cpp7
-rw-r--r--clang/include/clang/Rewrite/HTMLRewrite.h18
-rw-r--r--clang/lib/Rewrite/HTMLRewrite.cpp128
3 files changed, 124 insertions, 29 deletions
diff --git a/clang/Driver/HTMLPrint.cpp b/clang/Driver/HTMLPrint.cpp
index d347901e8b5..940016afd24 100644
--- a/clang/Driver/HTMLPrint.cpp
+++ b/clang/Driver/HTMLPrint.cpp
@@ -49,9 +49,10 @@ HTMLPrinter::~HTMLPrinter() {
html::EscapeText(R, FileID);
html::AddLineNumbers(R, FileID);
-// html::InsertTag(R, html::HEAD, StartLoc, EndLoc, true);
-// html::InsertTag(R, html::BODY, StartLoc, EndLoc, true);
-// html::InsertTag(R, html::PRE, StartLoc, EndLoc);
+ html::InsertTag(R, html::PRE, StartLoc, EndLoc, 0, 0, true);
+ html::InsertTag(R, html::BODY, StartLoc, EndLoc, NULL, "\n", true);
+ html::InsertTag(R, html::HEAD, StartLoc, StartLoc, 0, 0, true);
+ html::InsertTag(R, html::HTML, StartLoc, EndLoc, NULL, "\n", true);
// Emit the HTML.
diff --git a/clang/include/clang/Rewrite/HTMLRewrite.h b/clang/include/clang/Rewrite/HTMLRewrite.h
index 43923ae3328..3f821cc1fdb 100644
--- a/clang/include/clang/Rewrite/HTMLRewrite.h
+++ b/clang/include/clang/Rewrite/HTMLRewrite.h
@@ -23,14 +23,26 @@ class Rewriter;
namespace html {
- enum Tags { PRE, HEAD, BODY };
+ // Basic operations.
+
+ enum Tags { BODY,
+ DIV,
+ HEAD,
+ HTML,
+ PRE,
+ SPAN };
void EscapeText(Rewriter& R, unsigned FileID, bool EscapeSpaces = false);
void InsertTag(Rewriter& R, Tags tag,
SourceLocation OpenLoc, SourceLocation CloseLoc,
- bool NewlineOpen = false, bool NewlineClose = true,
- bool OutermostTag = false);
+ const char* Attributes = NULL, const char* Content = NULL,
+ bool Newline = false,
+ bool OpenInsertBefore = true, bool CloseInsertAfter = true);
+
+ // High-level operations.
+
+ void AddLineNumbers(Rewriter& R, unsigned FileID);
} // end html namespace
} // end clang namespace
diff --git a/clang/lib/Rewrite/HTMLRewrite.cpp b/clang/lib/Rewrite/HTMLRewrite.cpp
index 717f6cec812..f8c96cca394 100644
--- a/clang/lib/Rewrite/HTMLRewrite.cpp
+++ b/clang/lib/Rewrite/HTMLRewrite.cpp
@@ -20,6 +20,10 @@
using namespace clang;
+//===----------------------------------------------------------------------===//
+// Basic operations.
+//===----------------------------------------------------------------------===//
+
void html::EscapeText(Rewriter& R, unsigned FileID, bool EscapeSpaces) {
const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
@@ -46,46 +50,124 @@ void html::EscapeText(Rewriter& R, unsigned FileID, bool EscapeSpaces) {
}
}
+
+static void TagOpen(std::ostringstream& os, const char* TagStr,
+ const char* Attr, const char* Content) {
+
+ os << '<' << TagStr;
+ if (Attr) os << ' ' << Attr;
+ os << '>';
+ if (Content) os << Content;
+}
+
+static void TagClose(std::ostringstream& os, const char* TagStr) {
+ os << "</" << TagStr << ">";
+}
+
void html::InsertTag(Rewriter& R, html::Tags tag,
SourceLocation B, SourceLocation E,
- bool NewlineOpen, bool NewlineClose, bool OutermostTag) {
+ const char* Attributes,
+ const char* Content, bool Newline,
+ bool OpenInsertBefore, bool CloseInsertAfter) {
const char* TagStr = 0;
switch (tag) {
default: break;
- case PRE: TagStr = "pre"; break;
- case HEAD: TagStr = "head"; break;
case BODY: TagStr = "body"; break;
+ case DIV: TagStr = "div"; break;
+ case HEAD: TagStr = "head"; break;
+ case HTML: TagStr = "html"; break;
+ case PRE: TagStr = "pre"; break;
+ case SPAN: TagStr = "span"; break;
}
assert (TagStr && "Tag not supported.");
- { // Generate the opening tag.
- std::ostringstream os;
- os << '<' << TagStr << '>';
- if (NewlineOpen) os << '\n';
-
- const char* s = os.str().c_str();
- unsigned n = os.str().size();
+ // Generate the opening tag. We also generate the closing
+ // tag of the start and end SourceLocations are the same.
+
+ {
+ std::ostringstream os;
+ TagOpen(os, TagStr, Attributes, Content);
+ if (B == E) {
+ TagClose(os, TagStr);
+ if (Newline) os << '\n';
+ }
- if (OutermostTag)
- R.InsertTextBefore(B, s, n);
+ if (OpenInsertBefore)
+ R.InsertTextBefore(B, os.str().c_str(), os.str().size());
else
- R.InsertTextAfter(B, s, n);
+ R.InsertTextAfter(B, os.str().c_str(), os.str().size());
}
- { // Generate the closing tag.
- std::ostringstream os;
- os << "</" << TagStr << '>';
- if (NewlineClose) os << '\n';
-
- const char* s = os.str().c_str();
- unsigned n = os.str().size();
+ // Generate the closing tag if the start and end SourceLocations
+ // are different.
+
+ if (B != E) {
+ std::ostringstream os;
+ TagClose(os, TagStr);
+ if (Newline) os << '\n';
- if (OutermostTag)
- R.InsertTextAfter(E, s, n);
+ if (CloseInsertAfter)
+ R.InsertTextAfter(E, os.str().c_str(), os.str().size());
else
- R.InsertTextBefore(E, s, n);
+ R.InsertTextBefore(E, os.str().c_str(), os.str().size());
}
}
+
+//===----------------------------------------------------------------------===//
+// High-level operations.
+//===----------------------------------------------------------------------===//
+
+static void AddLineNumber(Rewriter& R, unsigned LineNo,
+ SourceLocation B, SourceLocation E) {
+
+ // Add two "div" tags: one to contain the line number, and the other
+ // to contain the content of the line.
+
+ std::ostringstream os;
+ os << LineNo;
+ html::InsertTag(R, html::SPAN, B, E, "class=Line");
+ html::InsertTag(R, html::SPAN, B, B, "class=Num", os.str().c_str());
+}
+
+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;
+ }
+ }
+}
OpenPOWER on IntegriCloud