diff options
author | Martin Smith <martin.smith@digia.com> | 2012-10-05 14:35:00 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-10-08 09:12:20 +0200 |
commit | bac9d5921f0da609eedd72e371dae7c8321dc410 (patch) | |
tree | 02745b326af37af5c91b6bcec38fa9df1008d2df /src/tools/qdoc/qdocdatabase.cpp | |
parent | 50eab48fce0f5957ca09343448e018fb2f0cbfd9 (diff) |
qdoc: Simplification of target ref construction
This change is being done to simplify qdoc,
but the motivation was to fix a segfault in
qdoc when running the release version of
qdoc on linux. The change improves qdoc by
simplifying the code whether it fixes the
segfault or not.
Change-Id: I2c865f7f1e2a44763aa7349d1bd739ad562f4029
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Diffstat (limited to 'src/tools/qdoc/qdocdatabase.cpp')
-rw-r--r-- | src/tools/qdoc/qdocdatabase.cpp | 267 |
1 files changed, 152 insertions, 115 deletions
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index 9d3a8bee5c..8780c67361 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "generator.h" #include "atom.h" #include "tree.h" #include "qdocdatabase.h" @@ -639,62 +640,84 @@ const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* r void QDocDatabase::insertTarget(const QString& name, Node* node, int priority) { Target target; - target.node = node; - target.priority = priority; - target.atom = new Atom(Atom::Target, name); - targetHash_.insert(name, target); + target.node_ = node; + target.priority_ = priority; + Atom a = Atom(Atom::Target, name); + target.ref_ = refForAtom(&a); + targetMultiMap_.insert(name, target); } -static const int NumSuffixes = 3; -static const char* const suffixes[NumSuffixes] = { "", "s", "es" }; - /*! This function searches for a \a target anchor node. If it - finds one, it sets \a atom from the found node and returns - the found node. + finds one, it sets \a ref and returns the found node. */ const Node* -QDocDatabase::findUnambiguousTarget(const QString& target, Atom *&atom, const Node* relative) const +QDocDatabase::findUnambiguousTarget(const QString& target, QString& ref, const Node* relative) const { - Target bestTarget = {0, 0, INT_MAX}; + Target bestTarget; int numBestTargets = 0; QList<Target> bestTargetList; - for (int pass = 0; pass < NumSuffixes; ++pass) { - TargetHash::const_iterator i = targetHash_.constFind(Doc::canonicalTitle(target + suffixes[pass])); - if (i != targetHash_.constEnd()) { - TargetHash::const_iterator j = i; - do { - const Target& candidate = j.value(); - if (candidate.priority < bestTarget.priority) { - bestTarget = candidate; - bestTargetList.clear(); - bestTargetList.append(candidate); - numBestTargets = 1; - } else if (candidate.priority == bestTarget.priority) { - bestTargetList.append(candidate); - ++numBestTargets; - } - ++j; - } while (j != targetHash_.constEnd() && j.key() == i.key()); - - if (numBestTargets == 1) { - atom = bestTarget.atom; - return bestTarget.node; + bool debug = false; + if (target == "Manager" && Generator::debugging()) + debug = true; + + QString key = Doc::canonicalTitle(target); + TargetMultiMap::const_iterator i = targetMultiMap_.constFind(key); + if (i != targetMultiMap_.constEnd()) { + if (debug) + qDebug() << "DEBUG: A"; + TargetMultiMap::const_iterator j = i; + do { + const Target& candidate = j.value(); + if (candidate.priority_ < bestTarget.priority_) { + if (debug) + qDebug() << "DEBUG: B"; + bestTarget = candidate; + bestTargetList.clear(); + bestTargetList.append(candidate); + numBestTargets = 1; + } else if (candidate.priority_ == bestTarget.priority_) { + if (debug) + qDebug() << "DEBUG: C"; + bestTargetList.append(candidate); + ++numBestTargets; } - else if (bestTargetList.size() > 1) { - if (relative && !relative->qmlModuleIdentifier().isEmpty()) { - for (int i=0; i<bestTargetList.size(); ++i) { - const Node* n = bestTargetList.at(i).node; - if (n && relative->qmlModuleIdentifier() == n->qmlModuleIdentifier()) { - atom = bestTargetList.at(i).atom; - return n; - } + ++j; + } while (j != targetMultiMap_.constEnd() && j.key() == i.key()); + + if (debug) + qDebug() << "DEBUG: D"; + if (numBestTargets == 1) { + if (debug) + qDebug() << "DEBUG: E"; + ref = bestTarget.ref_; + return bestTarget.node_; + } + else if (bestTargetList.size() > 1) { + if (debug) + qDebug() << "DEBUG: F"; + if (relative && !relative->qmlModuleIdentifier().isEmpty()) { + if (debug) + qDebug() << "DEBUG: G"; + for (int i=0; i<bestTargetList.size(); ++i) { + if (debug) + qDebug() << "DEBUG: H"; + const Node* n = bestTargetList.at(i).node_; + if (debug) + qDebug() << "DEBUG: I"; + if (n && relative->qmlModuleIdentifier() == n->qmlModuleIdentifier()) { + if (debug) + qDebug() << "DEBUG: J"; + ref = bestTargetList.at(i).ref_; + return n; } } } } } + if (debug) + qDebug() << "DEBUG: K"; return 0; } @@ -705,77 +728,74 @@ QDocDatabase::findUnambiguousTarget(const QString& target, Atom *&atom, const No */ const DocNode* QDocDatabase::findDocNodeByTitle(const QString& title, const Node* relative) const { - for (int pass = 0; pass < NumSuffixes; ++pass) { - DocNodeHash::const_iterator i = docNodesByTitle_.constFind(Doc::canonicalTitle(title + suffixes[pass])); - if (i != docNodesByTitle_.constEnd()) { - if (relative && !relative->qmlModuleIdentifier().isEmpty()) { - const DocNode* dn = i.value(); - InnerNode* parent = dn->parent(); - if (parent && parent->type() == Node::Document && parent->subType() == Node::Collision) { - const NodeList& nl = parent->childNodes(); - NodeList::ConstIterator it = nl.constBegin(); - while (it != nl.constEnd()) { - if ((*it)->qmlModuleIdentifier() == relative->qmlModuleIdentifier()) { - /* - By returning here, we avoid printing all the duplicate - header warnings, which are not really duplicates now, - because of the QML module identifier being used as a - namespace qualifier. - */ - dn = static_cast<const DocNode*>(*it); - return dn; - } - ++it; + QString key = Doc::canonicalTitle(title); + DocNodeMultiMap::const_iterator i = docNodesByTitle_.constFind(key); + if (i != docNodesByTitle_.constEnd()) { + if (relative && !relative->qmlModuleIdentifier().isEmpty()) { + const DocNode* dn = i.value(); + InnerNode* parent = dn->parent(); + if (parent && parent->type() == Node::Document && parent->subType() == Node::Collision) { + const NodeList& nl = parent->childNodes(); + NodeList::ConstIterator it = nl.constBegin(); + while (it != nl.constEnd()) { + if ((*it)->qmlModuleIdentifier() == relative->qmlModuleIdentifier()) { + /* + By returning here, we avoid printing all the duplicate + header warnings, which are not really duplicates now, + because of the QML module identifier being used as a + namespace qualifier. + */ + dn = static_cast<const DocNode*>(*it); + return dn; } + ++it; } } - /* - Reporting all these duplicate section titles is probably - overkill. We should report the duplicate file and let - that suffice. - */ - DocNodeHash::const_iterator j = i; - ++j; - if (j != docNodesByTitle_.constEnd() && j.key() == i.key()) { - QList<Location> internalLocations; - while (j != docNodesByTitle_.constEnd()) { - if (j.key() == i.key() && j.value()->url().isEmpty()) - internalLocations.append(j.value()->location()); - ++j; - } - if (internalLocations.size() > 0) { - i.value()->location().warning(tr("This page exists in more than one file: \"%1\"").arg(title)); - foreach (const Location &location, internalLocations) - location.warning(tr("[It also exists here]")); - } + } + /* + Reporting all these duplicate section titles is probably + overkill. We should report the duplicate file and let + that suffice. + */ + DocNodeMultiMap::const_iterator j = i; + ++j; + if (j != docNodesByTitle_.constEnd() && j.key() == i.key()) { + QList<Location> internalLocations; + while (j != docNodesByTitle_.constEnd()) { + if (j.key() == i.key() && j.value()->url().isEmpty()) + internalLocations.append(j.value()->location()); + ++j; + } + if (internalLocations.size() > 0) { + i.value()->location().warning(tr("This page exists in more than one file: \"%1\"").arg(title)); + foreach (const Location &location, internalLocations) + location.warning(tr("[It also exists here]")); } - return i.value(); } + return i.value(); } return 0; } /*! This function searches for a node with a canonical title - constructed from \a target and each of the possible suffixes. - If the node it finds is \a node, it returns the Atom from that - node. Otherwise it returns null. - */ -Atom* QDocDatabase::findTarget(const QString& target, const Node* node) const -{ - for (int pass = 0; pass < NumSuffixes; ++pass) { - QString key = Doc::canonicalTitle(target + suffixes[pass]); - TargetHash::const_iterator i = targetHash_.constFind(key); - - if (i != targetHash_.constEnd()) { - do { - if (i.value().node == node) - return i.value().atom; - ++i; - } while (i != targetHash_.constEnd() && i.key() == key); - } + constructed from \a target. If the node it finds is \a node, + it returns the ref from that node. Otherwise it returns an + empty string. + */ +QString QDocDatabase::findTarget(const QString& target, const Node* node) const +{ + QString key = Doc::canonicalTitle(target); + TargetMultiMap::const_iterator i = targetMultiMap_.constFind(key); + + if (i != targetMultiMap_.constEnd()) { + do { + if (i.value().node_ == node) + return i.value().ref_; + ++i; + } while (i != targetMultiMap_.constEnd() && i.key() == key); } - return 0; + return QString(); } /*! @@ -787,8 +807,10 @@ void QDocDatabase::resolveTargets(InnerNode* root) foreach (Node* child, root->childNodes()) { if (child->type() == Node::Document) { DocNode* node = static_cast<DocNode*>(child); - if (!node->title().isEmpty()) - docNodesByTitle_.insert(Doc::canonicalTitle(node->title()), node); + if (!node->title().isEmpty()) { + QString key = Doc::canonicalTitle(node->title()); + docNodesByTitle_.insert(key, node); + } if (node->subType() == Node::Collision) { resolveTargets(node); } @@ -797,36 +819,40 @@ void QDocDatabase::resolveTargets(InnerNode* root) if (child->doc().hasTableOfContents()) { const QList<Atom*>& toc = child->doc().tableOfContents(); Target target; - target.node = child; - target.priority = 3; + target.node_ = child; + target.priority_ = 3; for (int i = 0; i < toc.size(); ++i) { - target.atom = toc.at(i); - QString title = Text::sectionHeading(target.atom).toString(); - if (!title.isEmpty()) - targetHash_.insert(Doc::canonicalTitle(title), target); + target.ref_ = refForAtom(toc.at(i)); + QString title = Text::sectionHeading(toc.at(i)).toString(); + if (!title.isEmpty()) { + QString key = Doc::canonicalTitle(title); + targetMultiMap_.insert(key, target); + } } } if (child->doc().hasKeywords()) { const QList<Atom*>& keywords = child->doc().keywords(); Target target; - target.node = child; - target.priority = 1; + target.node_ = child; + target.priority_ = 1; for (int i = 0; i < keywords.size(); ++i) { - target.atom = keywords.at(i); - targetHash_.insert(Doc::canonicalTitle(target.atom->string()), target); + target.ref_ = refForAtom(keywords.at(i)); + QString key = Doc::canonicalTitle(keywords.at(i)->string()); + targetMultiMap_.insert(key, target); } } if (child->doc().hasTargets()) { const QList<Atom*>& toc = child->doc().targets(); Target target; - target.node = child; - target.priority = 2; + target.node_ = child; + target.priority_ = 2; for (int i = 0; i < toc.size(); ++i) { - target.atom = toc.at(i); - targetHash_.insert(Doc::canonicalTitle(target.atom->string()), target); + target.ref_ = refForAtom(toc.at(i)); + QString key = Doc::canonicalTitle(toc.at(i)->string()); + targetMultiMap_.insert(key, target); } } } @@ -867,4 +893,15 @@ void QDocDatabase::generateIndex(const QString& fileName, QDocIndexFiles::destroyQDocIndexFiles(); } +QString QDocDatabase::refForAtom(const Atom* atom) +{ + if (atom) { + if (atom->type() == Atom::SectionLeft) + return Doc::canonicalTitle(Text::sectionHeading(atom).toString()); + if (atom->type() == Atom::Target) + return Doc::canonicalTitle(atom->string()); + } + return QString(); +} + QT_END_NAMESPACE |