diff options
author | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-07-23 13:07:55 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-07-24 08:51:33 +0000 |
commit | 906ad92fbfb20e1665d55bb6c447bbf67c66ee27 (patch) | |
tree | 962aff0bba53107631531609afd583ed2e8981a5 /src/tools/qdoc/htmlgenerator.cpp | |
parent | 57bd6e67f74f063073e842aa1e159e811bdb554f (diff) |
Some further optimizations in the qdoc code
Replace a lot of c strings with QLatin1String to avoid
utf conversions. Make one constant data structure static to
avoid it being recreated the whole time, and optimize our
tag replacement code.
Change-Id: I6513f3c70781a1bac658cbb3164c45d4cab36f57
Reviewed-by: Martin Smith <martin.smith@digia.com>
Diffstat (limited to 'src/tools/qdoc/htmlgenerator.cpp')
-rw-r--r-- | src/tools/qdoc/htmlgenerator.cpp | 220 |
1 files changed, 98 insertions, 122 deletions
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index f9fc534c70..fc880b404f 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -49,6 +49,7 @@ #include <qiterator.h> #include <qtextcodec.h> #include <quuid.h> +#include <qmap.h> QT_BEGIN_NAMESPACE @@ -71,11 +72,11 @@ static void addLink(const QString &linkTarget, QString *res) { if (!linkTarget.isEmpty()) { - *res += "<a href=\""; + *res += QLatin1String("<a href=\""); *res += linkTarget; - *res += "\">"; + *res += QLatin1String("\">"); *res += nestedStuff; - *res += "</a>"; + *res += QLatin1String("</a>"); } else { *res += nestedStuff; @@ -139,8 +140,8 @@ void HtmlGenerator::initializeGenerator(const Config &config) */ int i = 0; while (defaults[i].key) { - formattingLeftMap().insert(defaults[i].key, defaults[i].left); - formattingRightMap().insert(defaults[i].key, defaults[i].right); + formattingLeftMap().insert(QLatin1String(defaults[i].key), QLatin1String(defaults[i].left)); + formattingRightMap().insert(QLatin1String(defaults[i].key), QLatin1String(defaults[i].right)); i++; } @@ -180,7 +181,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) projectDescription = config.getString(CONFIG_DESCRIPTION); if (projectDescription.isEmpty() && !project.isEmpty()) - projectDescription = project + " Reference Documentation"; + projectDescription = project + QLatin1String(" Reference Documentation"); projectUrl = config.getString(CONFIG_URL); tagFile_ = config.getString(CONFIG_TAGFILE); @@ -236,8 +237,8 @@ void HtmlGenerator::initializeGenerator(const Config &config) headerStyles = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSTYLES); QString prefix = CONFIG_QHP + Config::dot + project + Config::dot; - manifestDir = "qthelp://" + config.getString(prefix + "namespace"); - manifestDir += QLatin1Char('/') + config.getString(prefix + "virtualFolder") + QLatin1Char('/'); + manifestDir = QLatin1String("qthelp://") + config.getString(prefix + QLatin1String("namespace")); + manifestDir += QLatin1Char('/') + config.getString(prefix + QLatin1String("virtualFolder")) + QLatin1Char('/'); readManifestMetaContent(config); examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH); if (!examplesPath.isEmpty()) @@ -285,7 +286,7 @@ void HtmlGenerator::generateKeywordAnchors(const Node* node) if (!node->doc().isEmpty()) { const QList<Atom*>& keywords = node->doc().keywords(); foreach (Atom* a, keywords) { - out() << "<a name=\"" << Doc::canonicalTitle(a->string()) << "\"></a>"; + out() << QLatin1String("<a name=\"") << Doc::canonicalTitle(a->string()) << QLatin1String("\"></a>"); } } } @@ -539,9 +540,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark else out() << "variable"; QStringList words = str.split(QLatin1Char(' ')); - if (!(words.first() == "contains" || words.first() == "specifies" - || words.first() == "describes" || words.first() == "defines" - || words.first() == "holds" || words.first() == "determines")) + if (!(words.first() == QLatin1String("contains") || words.first() == QLatin1String("specifies") + || words.first() == QLatin1String("describes") || words.first() == QLatin1String("defines") + || words.first() == QLatin1String("holds") || words.first() == QLatin1String("determines"))) out() << " holds "; else out() << ' '; @@ -666,20 +667,20 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark } break; case Atom::GeneratedList: - if (atom->string() == "annotatedclasses") { + if (atom->string() == QLatin1String("annotatedclasses")) { generateAnnotatedList(relative, marker, qdb_->getCppClasses()); } - else if (atom->string() == "classes") { + else if (atom->string() == QLatin1String("classes")) { generateCompactList(Generic, relative, qdb_->getCppClasses(), true, QStringLiteral("")); } else if (atom->string().contains("classes ")) { QString rootName = atom->string().mid(atom->string().indexOf("classes") + 7).trimmed(); generateCompactList(Generic, relative, qdb_->getCppClasses(), true, rootName); } - else if (atom->string() == "qmlbasictypes") { + else if (atom->string() == QLatin1String("qmlbasictypes")) { generateCompactList(Generic, relative, qdb_->getQmlBasicTypes(), true, QStringLiteral("")); } - else if (atom->string() == "qmltypes") { + else if (atom->string() == QLatin1String("qmltypes")) { generateCompactList(Generic, relative, qdb_->getQmlTypes(), true, QStringLiteral("")); } else if (atom->string().contains("classesbymodule")) { @@ -694,40 +695,40 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark } } } - else if (atom->string() == "classhierarchy") { + else if (atom->string() == QLatin1String("classhierarchy")) { generateClassHierarchy(relative, qdb_->getCppClasses()); } - else if (atom->string() == "obsoleteclasses") { + else if (atom->string() == QLatin1String("obsoleteclasses")) { generateCompactList(Generic, relative, qdb_->getObsoleteClasses(), false, QStringLiteral("Q")); } - else if (atom->string() == "obsoleteqmltypes") { + else if (atom->string() == QLatin1String("obsoleteqmltypes")) { generateCompactList(Generic, relative, qdb_->getObsoleteQmlTypes(), false, QStringLiteral("")); } - else if (atom->string() == "obsoletecppmembers") { + else if (atom->string() == QLatin1String("obsoletecppmembers")) { generateCompactList(Obsolete, relative, qdb_->getClassesWithObsoleteMembers(), false, QStringLiteral("Q")); } - else if (atom->string() == "obsoleteqmlmembers") { + else if (atom->string() == QLatin1String("obsoleteqmlmembers")) { generateCompactList(Obsolete, relative, qdb_->getQmlTypesWithObsoleteMembers(), false, QStringLiteral("")); } - else if (atom->string() == "functionindex") { + else if (atom->string() == QLatin1String("functionindex")) { generateFunctionIndex(relative); } - else if (atom->string() == "legalese") { + else if (atom->string() == QLatin1String("legalese")) { generateLegaleseList(relative, marker); } - else if (atom->string() == "overviews") { + else if (atom->string() == QLatin1String("overviews")) { generateList(relative, marker, "overviews"); } - else if (atom->string() == "cpp-modules") { + else if (atom->string() == QLatin1String("cpp-modules")) { generateList(relative, marker, "cpp-modules"); } - else if (atom->string() == "qml-modules") { + else if (atom->string() == QLatin1String("qml-modules")) { generateList(relative, marker, "qml-modules"); } - else if (atom->string() == "namespaces") { + else if (atom->string() == QLatin1String("namespaces")) { generateAnnotatedList(relative, marker, qdb_->getNamespaces()); } - else if (atom->string() == "related") { + else if (atom->string() == QLatin1String("related")) { generateList(relative, marker, "related"); } #if 0 @@ -735,7 +736,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark This is not used in Qt5, as of 10/02/2014 Remove permanently if it is not missed. */ - else if (atom->string() == "relatedinline") { + else if (atom->string() == QLatin1String("relatedinline")) { const DocumentNode *dn = static_cast<const DocumentNode *>(relative); if (dn && !dn->members().isEmpty()) { // Reverse the list into the original scan order. @@ -1210,13 +1211,13 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark p2 = atom->string(1); } if (!p1.isEmpty()) { - if (p1 == "borderless") + if (p1 == QLatin1String("borderless")) attr = p1; else if (p1.contains("%")) width = p1; } if (!p2.isEmpty()) { - if (p2 == "borderless") + if (p2 == QLatin1String("borderless")) attr = p2; else if (p2.contains("%")) width = p2; @@ -3158,13 +3159,13 @@ void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const { CNMap cnm; Node::Genus genus = Node::DontCare; - if (selector == "overviews") + if (selector == QLatin1String("overviews")) genus = Node::DOC; - else if (selector == "cpp-modules") + else if (selector == QLatin1String("cpp-modules")) genus = Node::CPP; - else if (selector == "qml-modules") + else if (selector == QLatin1String("qml-modules")) genus = Node::QML; - else if (selector == "js-modules") + else if (selector == QLatin1String("js-modules")) genus = Node::JS; if (genus != Node::DontCare) { NodeList nl; @@ -3409,6 +3410,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, { QString src = markedCode; QString html; + html.reserve(src.size()); QStringRef arg; QStringRef par1; @@ -3421,62 +3423,30 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, static const QString linkTag("link"); // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)" + // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" + // replace all "(<@(type|headerfile)(?: +[^>]*)?>)(.*)(</@\\2>)" tags bool done = false; for (int i = 0, srcSize = src.size(); i < srcSize;) { if (src.at(i) == charLangle && src.at(i + 1) == charAt) { if (alignNames && !done) { - html += "</td><td class=\"memItemRight bottomAlign\">"; + html += QLatin1String("</td><td class=\"memItemRight bottomAlign\">"); done = true; } i += 2; if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) { - html += "<b>"; + html += QLatin1String("<b>"); const Node* n = CodeMarker::nodeForString(par1.toString()); QString link = linkForNode(n, relative); addLink(link, arg, &html); - html += "</b>"; + html += QLatin1String("</b>"); } - else { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - - // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" - src = html; - html = QString(); - for (int i = 0, srcSize = src.size(); i < srcSize;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { - i += 2; - if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { + else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { const Node* n = qdb_->findFunctionNode(par1.toString(), relative, Node::DontCare); QString link = linkForNode(n, relative); addLink(link, arg, &html); par1 = QStringRef(); } - else { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - - // replace all "(<@(type|headerfile)(?: +[^>]*)?>)(.*)(</@\\2>)" tags - src = html; - html = QString(); - - for (int i=0, srcSize=src.size(); i<srcSize;) { - if (src.at(i) == charLangle && src.at(i+1) == charAt) { - i += 2; - bool handled = false; - if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { + else if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); const Node* n = qdb_->findTypeNode(arg.toString(), relative); html += QLatin1String("<span class=\"type\">"); @@ -3489,7 +3459,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, else addLink(linkForNode(n,relative), arg, &html); html += QLatin1String("</span>"); - handled = true; } else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); @@ -3502,9 +3471,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, else html += arg; } - handled = true; } - if (!handled) { + else { html += charLangle; html += charAt; } @@ -3527,60 +3495,68 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, // "</@(?:comment|preprocessor|string|char|number|op|type|name|keyword)>" -> "</span>" src = html; html = QString(); - static const QString spanTags[] = { - "<@comment>", "<span class=\"comment\">", - "<@preprocessor>", "<span class=\"preprocessor\">", - "<@string>", "<span class=\"string\">", - "<@char>", "<span class=\"char\">", - "<@number>", "<span class=\"number\">", - "<@op>", "<span class=\"operator\">", - "<@type>", "<span class=\"type\">", - "<@name>", "<span class=\"name\">", - "<@keyword>", "<span class=\"keyword\">", - "</@comment>", "</span>", - "</@preprocessor>", "</span>", - "</@string>", "</span>", - "</@char>", "</span>", - "</@number>", "</span>", - "</@op>", "</span>", - "</@type>", "</span>", - "</@name>", "</span>", - "</@keyword>", "</span>", + html.reserve(src.size()); + static const QLatin1String spanTags[] = { + QLatin1String("comment>"), QLatin1String("<span class=\"comment\">"), + QLatin1String("preprocessor>"), QLatin1String("<span class=\"preprocessor\">"), + QLatin1String("string>"), QLatin1String("<span class=\"string\">"), + QLatin1String("char>"), QLatin1String("<span class=\"char\">"), + QLatin1String("number>"), QLatin1String("<span class=\"number\">"), + QLatin1String("op>"), QLatin1String("<span class=\"operator\">"), + QLatin1String("type>"), QLatin1String("<span class=\"type\">"), + QLatin1String("name>"), QLatin1String("<span class=\"name\">"), + QLatin1String("keyword>"), QLatin1String("<span class=\"keyword\">") }; + int nTags = 9; // Update the upper bound of k in the following code to match the length // of the above array. for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle) { - bool handled = false; - for (int k = 0; k != 18; ++k) { - const QString & tag = spanTags[2 * k]; - if (i + tag.length() <= src.length() && - tag == QStringRef(&src, i, tag.length())) { - html += spanTags[2 * k + 1]; - i += tag.length(); - handled = true; - break; + if (src.at(i) == QLatin1Char('<')) { + if (src.at(i + 1) == QLatin1Char('@')) { + i += 2; + bool handled = false; + for (int k = 0; k != nTags; ++k) { + const QLatin1String& tag = spanTags[2 * k]; + if (i + tag.size() <= src.length() && + tag == QStringRef(&src, i, tag.size())) { + html += spanTags[2 * k + 1]; + i += tag.size(); + handled = true; + break; + } } - } - if (!handled) { - ++i; - if (src.at(i) == charAt || - (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) { + if (!handled) { // drop 'our' unknown tags (the ones still containing '@') while (i < n && src.at(i) != QLatin1Char('>')) ++i; ++i; } - else { - // retain all others - html += charLangle; + continue; + } + else if (src.at(i + 1) == QLatin1Char('/') && src.at(i + 2) == QLatin1Char('@')) { + i += 3; + bool handled = false; + for (int k = 0; k != nTags; ++k) { + const QLatin1String& tag = spanTags[2 * k]; + if (i + tag.size() <= src.length() && + tag == QStringRef(&src, i, tag.size())) { + html += QLatin1String("</span>"); + i += tag.size(); + handled = true; + break; + } } + if (!handled) { + // drop 'our' unknown tags (the ones still containing '@') + while (i < n && src.at(i) != QLatin1Char('>')) + ++i; + ++i; + } + continue; } } - else { - html += src.at(i); - ++i; - } + html += src.at(i); + ++i; } return html; } @@ -3655,7 +3631,7 @@ QString HtmlGenerator::protect(const QString &string, const QString &outputEncod APPEND(">"); } else if (ch == QLatin1Char('"')) { APPEND("""); - } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F) + } else if ((outputEncoding == QLatin1String("ISO-8859-1") && ch.unicode() > 0x007F) || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/')) || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) { // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator @@ -3684,10 +3660,10 @@ QString HtmlGenerator::fileBase(const Node *node) const if (!node->isAggregate()) { switch (node->status()) { case Node::Compat: - result += "-compat"; + result += QLatin1String("-compat"); break; case Node::Obsolete: - result += "-obsolete"; + result += QLatin1String("-obsolete"); break; default: ; @@ -4423,7 +4399,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString QString fileName = manifest +"-manifest.xml"; QFile file(outputDir() + QLatin1Char('/') + fileName); bool demos = false; - if (manifest == "demos") + if (manifest == QLatin1String("demos")) demos = true; bool proceed = false; |