qdoc: Implements the -no-link-errors option

The -no-link-errors flag tells qdoc not to print any link error
messages at all. This is useful for finding and fixing all non-link
errors in a module.

Task number: QTBUG-26870

Change-Id: Id4b0eebb6c0509c57d2f01763b6dedbfb6756a91
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Reviewed-by: Martin Smith <martin.smith@digia.com>
This commit is contained in:
Martin Smith 2012-10-08 12:49:39 +02:00 committed by The Qt Project
parent c12b4f2685
commit 9418be80ec
8 changed files with 36 additions and 50 deletions

View File

@ -164,6 +164,7 @@ private:
#define CONFIG_LANGUAGE "language" #define CONFIG_LANGUAGE "language"
#define CONFIG_MACRO "macro" #define CONFIG_MACRO "macro"
#define CONFIG_NATURALLANGUAGE "naturallanguage" #define CONFIG_NATURALLANGUAGE "naturallanguage"
#define CONFIG_NOLINKERRORS "nolinkerrors"
#define CONFIG_OBSOLETELINKS "obsoletelinks" #define CONFIG_OBSOLETELINKS "obsoletelinks"
#define CONFIG_OUTPUTDIR "outputdir" #define CONFIG_OUTPUTDIR "outputdir"
#define CONFIG_OUTPUTENCODING "outputencoding" #define CONFIG_OUTPUTENCODING "outputencoding"

View File

@ -1337,7 +1337,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
QString myLink = getLink(atom, relative, &node); QString myLink = getLink(atom, relative, &node);
if (myLink.isEmpty()) if (myLink.isEmpty())
myLink = getCollisionLink(atom); myLink = getCollisionLink(atom);
if (myLink.isEmpty()) if (myLink.isEmpty() && !noLinkErrors())
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string())); relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
else if (!inSectionHeading_) else if (!inSectionHeading_)
beginLink(myLink); beginLink(myLink);

View File

@ -95,6 +95,7 @@ QString Generator::sinceTitles[] =
QStringList Generator::styleDirs; QStringList Generator::styleDirs;
QStringList Generator::styleFiles; QStringList Generator::styleFiles;
bool Generator::debugging_ = false; bool Generator::debugging_ = false;
bool Generator::noLinkErrors_ = false;
void Generator::setDebugSegfaultFlag(bool b) void Generator::setDebugSegfaultFlag(bool b)
{ {
@ -1641,6 +1642,7 @@ void Generator::initialize(const Config &config)
} }
else else
outputPrefixes[QLatin1String("QML")] = QLatin1String("qml-"); outputPrefixes[QLatin1String("QML")] = QLatin1String("qml-");
noLinkErrors_ = config.getBool(QLatin1String(CONFIG_NOLINKERRORS));
} }
/*! /*!

View File

@ -89,6 +89,7 @@ public:
static void debugSegfault(const QString& message); static void debugSegfault(const QString& message);
static void setDebugSegfaultFlag(bool b); static void setDebugSegfaultFlag(bool b);
static bool debugging() { return debugging_; } static bool debugging() { return debugging_; }
static bool noLinkErrors() { return noLinkErrors_; }
protected: protected:
virtual void beginSubPage(const InnerNode* node, const QString& fileName); virtual void beginSubPage(const InnerNode* node, const QString& fileName);
@ -191,6 +192,7 @@ private:
static QStringList styleDirs; static QStringList styleDirs;
static QStringList styleFiles; static QStringList styleFiles;
static bool debugging_; static bool debugging_;
static bool noLinkErrors_;
void appendFullName(Text& text, void appendFullName(Text& text,
const Node *apparentNode, const Node *apparentNode,

View File

@ -791,9 +791,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
QString myLink = getLink(atom, relative, &node); QString myLink = getLink(atom, relative, &node);
if (myLink.isEmpty()) { if (myLink.isEmpty()) {
myLink = getCollisionLink(atom); myLink = getCollisionLink(atom);
if (myLink.isEmpty()) { if (myLink.isEmpty() && !noLinkErrors()) {
relative->doc().location().warning(tr("Can't create link to '%1'") relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
.arg(atom->string()));
} }
else else
node = 0; node = 0;

View File

@ -95,6 +95,7 @@ bool creationTimeBefore(const QFileInfo &fi1, const QFileInfo &fi2)
static bool highlighting = false; static bool highlighting = false;
static bool showInternal = false; static bool showInternal = false;
static bool noLinkErrors = false;
static bool obsoleteLinks = false; static bool obsoleteLinks = false;
static QStringList defines; static QStringList defines;
static QStringList dependModules; static QStringList dependModules;
@ -121,6 +122,8 @@ static void printHelp()
"Specify the directory where the output will be after running \"make install\"\n" "Specify the directory where the output will be after running \"make install\"\n"
" -no-examples " " -no-examples "
"Do not generate documentation for examples\n" "Do not generate documentation for examples\n"
" -no-link-errors "
"Do not print link errors (i.e. missing targets)\n"
" -obsoletelinks " " -obsoletelinks "
"Report links from obsolete items to non-obsolete items\n" "Report links from obsolete items to non-obsolete items\n"
" -outputdir " " -outputdir "
@ -166,6 +169,7 @@ static void processQdocconfFile(const QString &fileName)
} }
config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false")); config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false"));
config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false")); config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false"));
config.setStringList(CONFIG_NOLINKERRORS, QStringList(noLinkErrors ? "true" : "false"));
config.setStringList(CONFIG_OBSOLETELINKS, QStringList(obsoleteLinks ? "true" : "false")); config.setStringList(CONFIG_OBSOLETELINKS, QStringList(obsoleteLinks ? "true" : "false"));
/* /*
@ -572,6 +576,9 @@ int main(int argc, char **argv)
Config::overrideOutputFormats.insert(argv[i]); Config::overrideOutputFormats.insert(argv[i]);
i++; i++;
} }
else if (opt == "-no-link-errors") {
noLinkErrors = true;
}
else if (opt == "-debug") { else if (opt == "-debug") {
Generator::setDebugSegfaultFlag(true); Generator::setDebugSegfaultFlag(true);
} }

View File

@ -652,63 +652,39 @@ void QDocDatabase::insertTarget(const QString& name, Node* node, int priority)
finds one, it sets \a ref and returns the found node. finds one, it sets \a ref and returns the found node.
*/ */
const Node* const Node*
QDocDatabase::findUnambiguousTarget(const QString& target, QString& ref, const Node* relative) const QDocDatabase::findUnambiguousTarget(const QString& target, QString& ref, const Node* relative)
{ {
Target bestTarget; Target bestTarget;
int numBestTargets = 0; int numBestTargets = 0;
QList<Target> bestTargetList; QList<Target> bestTargetList;
bool debug = false;
if (target == "Manager" && Generator::debugging())
debug = true;
QString key = Doc::canonicalTitle(target); QString key = Doc::canonicalTitle(target);
TargetMultiMap::const_iterator i = targetMultiMap_.constFind(key); TargetMultiMap::iterator i = targetMultiMap_.find(key);
if (i != targetMultiMap_.constEnd()) { while (i != targetMultiMap_.end()) {
if (debug) if (i.key() != key)
qDebug() << "DEBUG: A"; break;
TargetMultiMap::const_iterator j = i; const Target& candidate = i.value();
do { if (candidate.priority_ < bestTarget.priority_) {
const Target& candidate = j.value(); bestTarget = candidate;
if (candidate.priority_ < bestTarget.priority_) { bestTargetList.clear();
if (debug) bestTargetList.append(candidate);
qDebug() << "DEBUG: B"; numBestTargets = 1;
bestTarget = candidate; } else if (candidate.priority_ == bestTarget.priority_) {
bestTargetList.clear(); bestTargetList.append(candidate);
bestTargetList.append(candidate); ++numBestTargets;
numBestTargets = 1; }
} else if (candidate.priority_ == bestTarget.priority_) { ++i;
if (debug) }
qDebug() << "DEBUG: C"; if (numBestTargets > 0) {
bestTargetList.append(candidate);
++numBestTargets;
}
++j;
} while (j != targetMultiMap_.constEnd() && j.key() == i.key());
if (debug)
qDebug() << "DEBUG: D";
if (numBestTargets == 1) { if (numBestTargets == 1) {
if (debug)
qDebug() << "DEBUG: E";
ref = bestTarget.ref_; ref = bestTarget.ref_;
return bestTarget.node_; return bestTarget.node_;
} }
else if (bestTargetList.size() > 1) { else if (bestTargetList.size() > 1) {
if (debug)
qDebug() << "DEBUG: F";
if (relative && !relative->qmlModuleIdentifier().isEmpty()) { if (relative && !relative->qmlModuleIdentifier().isEmpty()) {
if (debug)
qDebug() << "DEBUG: G";
for (int i=0; i<bestTargetList.size(); ++i) { for (int i=0; i<bestTargetList.size(); ++i) {
if (debug)
qDebug() << "DEBUG: H";
const Node* n = bestTargetList.at(i).node_; const Node* n = bestTargetList.at(i).node_;
if (debug)
qDebug() << "DEBUG: I";
if (n && relative->qmlModuleIdentifier() == n->qmlModuleIdentifier()) { if (n && relative->qmlModuleIdentifier() == n->qmlModuleIdentifier()) {
if (debug)
qDebug() << "DEBUG: J";
ref = bestTargetList.at(i).ref_; ref = bestTargetList.at(i).ref_;
return n; return n;
} }
@ -716,8 +692,7 @@ QDocDatabase::findUnambiguousTarget(const QString& target, QString& ref, const N
} }
} }
} }
if (debug) ref.clear();
qDebug() << "DEBUG: K";
return 0; return 0;
} }

View File

@ -146,7 +146,7 @@ class QDocDatabase
} }
const DocNode* findDocNodeByTitle(const QString& title, const Node* relative = 0) const; const DocNode* findDocNodeByTitle(const QString& title, const Node* relative = 0) const;
const Node *findUnambiguousTarget(const QString &target, QString& ref, const Node* relative) const; const Node *findUnambiguousTarget(const QString &target, QString& ref, const Node* relative);
QString findTarget(const QString &target, const Node *node) const; QString findTarget(const QString &target, const Node *node) const;
void resolveTargets(InnerNode* root); void resolveTargets(InnerNode* root);
@ -221,8 +221,8 @@ class QDocDatabase
NodeMultiMapMap newSinceMaps_; NodeMultiMapMap newSinceMaps_;
NodeMapMap funcIndex_; NodeMapMap funcIndex_;
TextToNodeMap legaleseTexts_; TextToNodeMap legaleseTexts_;
TargetMultiMap targetMultiMap_;
DocNodeMultiMap docNodesByTitle_; DocNodeMultiMap docNodesByTitle_;
TargetMultiMap targetMultiMap_;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE