aboutsummaryrefslogtreecommitdiff
path: root/lib/Rewrite/HTMLRewrite.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-03-18 23:08:51 +0000
committerTed Kremenek <kremenek@apple.com>2008-03-18 23:08:51 +0000
commitb485cd1e0a5a1e942d0e682b9b1c4bc9df111528 (patch)
treeb32c93235dec858e9e29be5f3c40027f6532e027 /lib/Rewrite/HTMLRewrite.cpp
parent5e0020ee6182f63cd5f4a53e240dc08bd02d7728 (diff)
Some cleanups to the HTMLRewrite API. Added support for printing out line
numbers (more work to be done on aesthetics). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48512 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Rewrite/HTMLRewrite.cpp')
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp128
1 files changed, 105 insertions, 23 deletions
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 717f6cec81..f8c96cca39 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/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;
+ }
+ }
+}