#include "clang/AST/CommentLexer.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/Basic/ConvertUTF.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
namespace comments {
void Token::dump(const Lexer &L, const SourceManager &SM) const {
llvm::errs() << "comments::Token Kind=" << Kind << " ";
Loc.dump(SM);
llvm::errs() << " " << Length << " \"" << L.getSpelling(*this, SM) << "\"\n";
}
namespace {
bool isHTMLNamedCharacterReferenceCharacter(char C) {
return (C >= 'a' && C <= 'z') ||
(C >= 'A' && C <= 'Z');
}
bool isHTMLDecimalCharacterReferenceCharacter(char C) {
return C >= '0' && C <= '9';
}
bool isHTMLHexCharacterReferenceCharacter(char C) {
return (C >= '0' && C <= '9') ||
(C >= 'a' && C <= 'f') ||
(C >= 'A' && C <= 'F');
}
bool isHTMLTagName(StringRef Name) {
return llvm::StringSwitch<bool>(Name)
.Cases("em", "strong", true)
.Cases("tt", "i", "b", "big", "small", true)
.Cases("strike", "s", "u", "font", true)
.Case("a", true)
.Case("hr", true)
.Cases("div", "span", true)
.Cases("h1", "h2", "h3", true)
.Cases("h4", "h5", "h6", true)
.Case("code", true)
.Case("blockquote", true)
.Cases("sub", "sup", true)
.Case("img", true)
.Case("p", true)
.Case("br", true)
.Case("pre", true)
.Cases("ins", "del", true)
.Cases("ul", "ol", "li", true)
.Cases("dl", "dt", "dd", true)
.Cases("table", "caption", true)
.Cases("thead", "tfoot", "tbody", true)
.Cases("colgroup", "col", true)
.Cases("tr", "th", "td", true)
.Default(false);
}
} // unnamed namespace
StringRef Lexer::resolveHTMLNamedCharacterReference(StringRef Name) const {
return llvm::StringSwitch<StringRef>(Name)
.Case("amp", "&")
.Case("lt", "<")
.Case("gt", ">")
.Case("quot", "\"")
.Case("apos", "\'")
.Default("");
}
StringRef Lexer::resolveHTMLDecimalCharacterReference(StringRef Name) const {
unsigned CodePoint = 0;
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
assert(isHTMLDecimalCharacterReferenceCharacter(Name[i]));
CodePoint *= 10;
CodePoint += Name[i] - '0';
}
char *Resolved = Allocator.Allocate<char>(UNI_MAX_UTF8_BYTES_PER_CODE_POINT);
char *ResolvedPtr = Resolved;
if (ConvertCodePointToUTF8(CodePoint, ResolvedPtr))
return StringRef(Resolved, ResolvedPtr - Resolved);
else
return StringRef();
}
StringRef Lexer::resolveHTMLHexCharacterReference(StringRef Name) const {
unsigned CodePoint = 0;
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
CodePoint *= 16;
const char C = Name[i];
assert(isHTMLHexCharacterReferenceCharacter(C));
if (C >= '0' && C <= '9')
CodePoint += Name[i] - '0';
else if (C >= 'a' && C <= 'f')
CodePoint += Name[i] - 'a' + 10;
else
CodePoint += Name[i] - 'A' + 10;
}
char *Resolved = Allocator.Allocate<char>(UNI_MAX_UTF8_BYTES_PER_CODE_POINT);
char *ResolvedPtr = Resolved;
if (ConvertCodePointToUTF8(CodePoint, ResolvedPtr))
return StringRef(Resolved, ResolvedPtr - Resolved);
else
return StringRef();
}
void Lexer::skipLineStartingDecorations() {
<