summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/qdoc/codeparser.cpp76
-rw-r--r--src/tools/qdoc/codeparser.h1
-rw-r--r--src/tools/qdoc/config.cpp199
-rw-r--r--src/tools/qdoc/config.h34
-rw-r--r--src/tools/qdoc/cppcodeparser.cpp4
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.cpp5
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.h2
-rw-r--r--src/tools/qdoc/generator.cpp110
-rw-r--r--src/tools/qdoc/generator.h1
-rw-r--r--src/tools/qdoc/helpprojectwriter.cpp1
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp6
-rw-r--r--src/tools/qdoc/location.cpp30
-rw-r--r--src/tools/qdoc/location.h4
-rw-r--r--src/tools/qdoc/main.cpp210
-rw-r--r--src/tools/qdoc/node.cpp2
-rw-r--r--src/tools/qdoc/node.h4
-rw-r--r--src/tools/qdoc/puredocparser.cpp1
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp41
-rw-r--r--src/tools/qdoc/qdocindexfiles.cpp45
-rw-r--r--src/tools/tools.pro6
20 files changed, 504 insertions, 278 deletions
diff --git a/src/tools/qdoc/codeparser.cpp b/src/tools/qdoc/codeparser.cpp
index 6ecca78a70..ea3bdc25f4 100644
--- a/src/tools/qdoc/codeparser.cpp
+++ b/src/tools/qdoc/codeparser.cpp
@@ -387,4 +387,80 @@ bool CodeParser::isParsingQdoc() const
return currentFile_.endsWith(".qdoc");
}
+/*!
+ For each node that will produce a documentation page, this function
+ ensures that the node belongs to a module. Normally, the qdoc comment
+ for an entity that will produce a documentation page will contain an
+ \inmodule command to tell qdoc which module the entity belongs to.
+
+ But now that we normally run qdoc on each module in two passes. The
+ first produces an index file; the second pass generates the docs
+ after reading all the index files it needs.
+
+ This means that all the pages generated during each pass 2 run of
+ qdoc almost certainly belong to a single module, and the name of
+ that module is, as a rule, used as the project name in the qdocconf
+ file used when running qdoc on the module.
+
+ So this function first asks if the node \a n has a non-empty module
+ name. If it it does not have a non-empty module name, it sets the
+ module name to be the project name.
+
+ In some cases it prints a qdoc warning that it has done this. Namely,
+ for C++ classes and namespaces.
+ */
+void CodeParser::checkModuleInclusion(Node* n)
+{
+ if (n->moduleName().isEmpty()) {
+ switch (n->type()) {
+ case Node::Class:
+ if (n->access() != Node::Private && !n->doc().isEmpty()) {
+ n->setModuleName(Generator::defaultModuleName());
+ n->doc().location().warning(tr("Class %1 has no \\inmodule command; "
+ "using project name by default: %2")
+ .arg(n->name()).arg(Generator::defaultModuleName()));
+ }
+ break;
+ case Node::Namespace:
+ if (n->access() != Node::Private && !n->name().isEmpty() && !n->doc().isEmpty()) {
+ n->setModuleName(Generator::defaultModuleName());
+ n->doc().location().warning(tr("Namespace %1 has no \\inmodule command; "
+ "using project name by default: %2")
+ .arg(n->name()).arg(Generator::defaultModuleName()));
+ }
+ break;
+ case Node::Document:
+ if (n->access() != Node::Private && !n->doc().isEmpty()) {
+ if (n->subType() == Node::HeaderFile) {
+ n->setModuleName(Generator::defaultModuleName());
+#if 0
+ n->doc().location().warning(tr("Header file with title \"%1\" has no \\inmodule command; "
+ "using project name by default: %2")
+ .arg(n->title()).arg(Generator::defaultModuleName()));
+#endif
+ }
+ else if (n->subType() == Node::Page) {
+ n->setModuleName(Generator::defaultModuleName());
+#if 0
+ n->doc().location().warning(tr("Page with title \"%1\" has no \\inmodule command; "
+ "using project name by default: %2")
+ .arg(n->title()).arg(Generator::defaultModuleName()));
+#endif
+ }
+ else if (n->subType() == Node::Example) {
+ n->setModuleName(Generator::defaultModuleName());
+#if 0
+ n->doc().location().warning(tr("Example with title \"%1\" has no \\inmodule command; "
+ "using project name by default: %2")
+ .arg(n->title()).arg(Generator::defaultModuleName()));
+#endif
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/codeparser.h b/src/tools/qdoc/codeparser.h
index 3d6bf89070..06839ffd80 100644
--- a/src/tools/qdoc/codeparser.h
+++ b/src/tools/qdoc/codeparser.h
@@ -72,6 +72,7 @@ public:
bool isParsingCpp() const;
bool isParsingQdoc() const;
const QString& currentFile() const { return currentFile_; }
+ void checkModuleInclusion(Node* n);
static void initialize(const Config& config);
static void terminate();
diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp
index 1ecfb6ddaf..e75ab85406 100644
--- a/src/tools/qdoc/config.cpp
+++ b/src/tools/qdoc/config.cpp
@@ -50,6 +50,7 @@
#include <qtextstream.h>
#include <qdebug.h>
#include "config.h"
+#include "generator.h"
#include <stdlib.h>
QT_BEGIN_NAMESPACE
@@ -154,6 +155,7 @@ QString Config::installDir;
QSet<QString> Config::overrideOutputFormats;
QMap<QString, QString> Config::extractedDirs;
int Config::numInstances;
+QStack<QString> Config::workingDirs_;
/*!
\class Config
@@ -171,10 +173,10 @@ Config::Config(const QString& programName)
: prog(programName)
{
loc = Location::null;
- lastLoc = Location::null;
+ lastLocation_ = Location::null;
locMap.clear();
- stringValueMap.clear();
- stringListValueMap.clear();
+ stringPairMap.clear();
+ stringListPairMap.clear();
numInstances++;
}
@@ -203,7 +205,7 @@ void Config::load(const QString& fileName)
else {
loc.setEtc(true);
}
- lastLoc = Location::null;
+ lastLocation_ = Location::null;
}
/*!
@@ -212,9 +214,9 @@ void Config::load(const QString& fileName)
*/
void Config::unload(const QString& fileName)
{
- QStringMultiMap::ConstIterator v = stringValueMap.constBegin();
- while (v != stringValueMap.constEnd()) {
- qDebug() << v.key() << " = " << v.value();
+ QStringPairMap::ConstIterator v = stringPairMap.constBegin();
+ while (v != stringPairMap.constEnd()) {
+ qDebug() << v.key() << " = " << v.value().second;
++v;
}
qDebug() << "fileName:" << fileName;
@@ -229,8 +231,10 @@ void Config::unload(const QString& fileName)
*/
void Config::setStringList(const QString& var, const QStringList& values)
{
- stringValueMap[var] = values.join(QLatin1Char(' '));
- stringListValueMap[var] = values;
+ stringPairMap[var].first = QDir::currentPath();
+ stringPairMap[var].second = values.join(QLatin1Char(' '));
+ stringListPairMap[var].first = QDir::currentPath();
+ stringListPairMap[var].second = values;
}
/*!
@@ -290,16 +294,37 @@ QSet<QString> Config::getOutputFormats() const
/*!
First, this function looks up the configuration variable \a var
in the location map and, if found, sets the internal variable
- \c{lastLoc} to the Location that \a var maps to.
+ \c{lastLocation_} to the Location that \a var maps to.
Then it looks up the configuration variable \a var in the string
- map, and returns the string that \a var maps to.
+ map and returns the string that \a var maps to.
*/
QString Config::getString(const QString& var) const
{
if (!locMap[var].isEmpty())
- (Location&) lastLoc = locMap[var];
- return stringValueMap[var];
+ (Location&) lastLocation_ = locMap[var];
+ return stringPairMap[var].second;
+}
+
+/*!
+ This function looks up the variable \a var in the location map
+ and, if found, sets the internal variable \c{lastLocation_} to the
+ location that \a var maps to.
+
+ Then it looks up \a var in the configuration variable map and,
+ if found, constructs a path from the pair value, which consists
+ of the directory path of the configuration file where the value
+ came from, and the value itself. The constructed path is returned.
+ */
+QString Config::getPath(const QString& var) const
+{
+ if (!locMap[var].isEmpty())
+ (Location&) lastLocation_ = locMap[var];
+ QString path;
+ if (stringPairMap.contains(var)) {
+ path = QDir(stringPairMap[var].first + "/" + stringPairMap[var].second).absolutePath();
+ }
+ return path;
}
/*!
@@ -315,7 +340,7 @@ QSet<QString> Config::getStringSet(const QString& var) const
/*!
First, this function looks up the configuration variable \a var
in the location map and, if found, sets the internal variable
- \c{lastLoc} to the Location that \a var maps to.
+ \c{lastLocation_} to the Location that \a var maps to.
Then it looks up the configuration variable \a var in the string
list map, and returns the string list that \a var maps to.
@@ -323,8 +348,8 @@ QSet<QString> Config::getStringSet(const QString& var) const
QStringList Config::getStringList(const QString& var) const
{
if (!locMap[var].isEmpty())
- (Location&) lastLoc = locMap[var];
- return stringListValueMap[var];
+ (Location&) lastLocation_ = locMap[var];
+ return stringListPairMap[var].second;
}
@@ -337,11 +362,11 @@ QStringList Config::getStringList(const QString& var) const
QStringList Config::getCanonicalRelativePathList(const QString& var) const
{
if (!locMap[var].isEmpty())
- (Location&) lastLoc = locMap[var];
+ (Location&) lastLocation_ = locMap[var];
QStringList t;
- QMap<QString,QStringList>::const_iterator it = stringListValueMap.constFind(var);
- if (it != stringListValueMap.constEnd()) {
- const QStringList& sl = it.value();
+ QStringListPairMap::const_iterator it = stringListPairMap.constFind(var);
+ if (it != stringListPairMap.constEnd()) {
+ const QStringList& sl = it.value().second;
if (!sl.isEmpty()) {
t.reserve(sl.size());
for (int i=0; i<sl.size(); ++i) {
@@ -361,7 +386,7 @@ QStringList Config::getCanonicalRelativePathList(const QString& var) const
First, this function looks up the configuration variable \a var
in the location map and, if found, sets the internal variable
- \c{lastLoc} the Location that \a var maps to.
+ \c{lastLocation_} the Location that \a var maps to.
Then it looks up the configuration variable \a var in the string
list map, which maps to a string list that contains file paths.
@@ -371,11 +396,11 @@ QStringList Config::getCanonicalRelativePathList(const QString& var) const
QStringList Config::getCleanPathList(const QString& var) const
{
if (!locMap[var].isEmpty())
- (Location&) lastLoc = locMap[var];
+ (Location&) lastLocation_ = locMap[var];
QStringList t;
- QMap<QString,QStringList>::const_iterator it = stringListValueMap.constFind(var);
- if (it != stringListValueMap.constEnd()) {
- const QStringList& sl = it.value();
+ QStringListPairMap::const_iterator it = stringListPairMap.constFind(var);
+ if (it != stringListPairMap.constEnd()) {
+ const QStringList& sl = it.value().second;
if (!sl.isEmpty()) {
t.reserve(sl.size());
for (int i=0; i<sl.size(); ++i) {
@@ -387,6 +412,47 @@ QStringList Config::getCleanPathList(const QString& var) const
}
/*!
+ This function should only be called when the configuration
+ variable \a var maps to a string list that contains file paths.
+ It cleans the paths with QDir::cleanPath() before returning
+ them.
+
+ First, this function looks up the configuration variable \a var
+ in the location map and, if found, sets the internal variable
+ \c{lastLocation_} the Location that \a var maps to.
+
+ Then it looks up the configuration variable \a var in the string
+ list map, which maps to a string list that contains file paths.
+ These paths might not be clean, so QDir::cleanPath() is called
+ for each one. The string list returned contains cleaned paths.
+ */
+QStringList Config::getPathList(const QString& var) const
+{
+ if (!locMap[var].isEmpty())
+ (Location&) lastLocation_ = locMap[var];
+ QStringList t;
+ QStringListPairMap::const_iterator it = stringListPairMap.constFind(var);
+ if (it != stringListPairMap.constEnd()) {
+ const QStringList& sl = it.value().second;
+ const QString d = it.value().first;
+ if (!sl.isEmpty()) {
+ t.reserve(sl.size());
+ for (int i=0; i<sl.size(); ++i) {
+ QFileInfo fileInfo;
+ QString path = d + "/" + QDir::cleanPath(sl[i]);
+ fileInfo.setFile(path);
+ if (!fileInfo.exists())
+ lastLocation_.warning(tr("File '%1' does not exist").arg(path));
+ else
+ t.append(path);
+ }
+ }
+ }
+ return t;
+}
+
+
+/*!
Calls getRegExpList() with the control variable \a var and
iterates through the resulting list of regular expressions,
concatening them with some extras characters to form a single
@@ -441,8 +507,8 @@ QSet<QString> Config::subVars(const QString& var) const
{
QSet<QString> result;
QString varDot = var + QLatin1Char('.');
- QStringMultiMap::ConstIterator v = stringValueMap.constBegin();
- while (v != stringValueMap.constEnd()) {
+ QStringPairMap::ConstIterator v = stringPairMap.constBegin();
+ while (v != stringPairMap.constEnd()) {
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
@@ -460,11 +526,11 @@ QSet<QString> Config::subVars(const QString& var) const
with the matching keys (stripped of the prefix \a var and
mapped to their values. The pairs are inserted into \a t
*/
-void Config::subVarsAndValues(const QString& var, QStringMultiMap& t) const
+void Config::subVarsAndValues(const QString& var, QStringPairMap& t) const
{
QString varDot = var + QLatin1Char('.');
- QStringMultiMap::ConstIterator v = stringValueMap.constBegin();
- while (v != stringValueMap.constEnd()) {
+ QStringPairMap::ConstIterator v = stringPairMap.constBegin();
+ while (v != stringPairMap.constEnd()) {
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
@@ -629,10 +695,10 @@ QString Config::findFile(const Location& location,
/*!
Copies the \a sourceFilePath to the file name constructed by
- concatenating \a targetDirPath and \a userFriendlySourceFilePath.
- \a location is for identifying the file and line number where
- a qdoc error occurred. The constructed output file name is
- returned.
+ concatenating \a targetDirPath and the file name from the
+ \a userFriendlySourceFilePath. \a location is for identifying
+ the file and line number where a qdoc error occurred. The
+ constructed output file name is returned.
*/
QString Config::copyFile(const Location& location,
const QString& sourceFilePath,
@@ -641,8 +707,8 @@ QString Config::copyFile(const Location& location,
{
QFile inFile(sourceFilePath);
if (!inFile.open(QFile::ReadOnly)) {
- location.fatal(tr("Cannot open input file '%1': %2")
- .arg(sourceFilePath).arg(inFile.errorString()));
+ location.warning(tr("Cannot open input file for copy: '%1': %2")
+ .arg(sourceFilePath).arg(inFile.errorString()));
return QString();
}
@@ -650,11 +716,14 @@ QString Config::copyFile(const Location& location,
int slash = outFileName.lastIndexOf(QLatin1Char('/'));
if (slash != -1)
outFileName = outFileName.mid(slash);
-
- QFile outFile(targetDirPath + QLatin1Char('/') + outFileName);
+ if ((outFileName.size()) > 0 && (outFileName[0] != '/'))
+ outFileName = targetDirPath + QLatin1Char('/') + outFileName;
+ else
+ outFileName = targetDirPath + outFileName;
+ QFile outFile(outFileName);
if (!outFile.open(QFile::WriteOnly)) {
- location.fatal(tr("Cannot open output file '%1': %2")
- .arg(outFile.fileName()).arg(outFile.errorString()));
+ location.warning(tr("Cannot open output file for copy: '%1': %2")
+ .arg(outFileName).arg(outFile.errorString()));
return QString();
}
@@ -737,6 +806,8 @@ bool Config::isMetaKeyChar(QChar ch)
*/
void Config::load(Location location, const QString& fileName)
{
+ pushWorkingDir(QFileInfo(fileName).path());
+ QDir::setCurrent(QFileInfo(fileName).path());
QRegExp keySyntax(QLatin1String("\\w+(?:\\.\\w+)*"));
#define SKIP_CHAR() \
@@ -853,9 +924,7 @@ void Config::load(Location location, const QString& fileName)
/*
Here is the recursive call.
*/
- load(location,
- QFileInfo(QFileInfo(fileName).dir(), includeFile)
- .filePath());
+ load(location, QFileInfo(QFileInfo(fileName).dir(), includeFile).filePath());
}
else {
/*
@@ -961,29 +1030,34 @@ void Config::load(Location location, const QString& fileName)
else {
locMap[*key].setEtc(true);
}
- if (stringValueMap[*key].isEmpty()) {
- stringValueMap[*key] = stringValue;
+ if (stringPairMap[*key].second.isEmpty()) {
+ stringPairMap[*key].first = QDir::currentPath();
+ stringPairMap[*key].second = stringValue;
}
else {
- stringValueMap[*key] +=
- QLatin1Char(' ') + stringValue;
+ stringPairMap[*key].second += QLatin1Char(' ') + stringValue;
}
- stringListValueMap[*key] += stringListValue;
+ stringListPairMap[*key].first = QDir::currentPath();
+ stringListPairMap[*key].second += stringListValue;
}
else {
locMap[*key] = keyLoc;
- stringValueMap[*key] = stringValue;
- stringListValueMap[*key] = stringListValue;
+ stringPairMap[*key].first = QDir::currentPath();
+ stringPairMap[*key].second = stringValue;
+ stringListPairMap[*key].first = QDir::currentPath();
+ stringListPairMap[*key].second = stringListValue;
}
++key;
}
}
}
else {
- location.fatal(tr("Unexpected character '%1' at beginning of line")
- .arg(c));
+ location.fatal(tr("Unexpected character '%1' at beginning of line").arg(c));
}
}
+ popWorkingDir();
+ if (!workingDirs_.isEmpty())
+ QDir::setCurrent(QFileInfo(workingDirs_.top()).path());
}
QStringList Config::getFilesHere(const QString& uncleanDir,
@@ -1029,4 +1103,25 @@ QStringList Config::getFilesHere(const QString& uncleanDir,
return result;
}
+/*!
+ Push \a dir onto the stack of working directories.
+ */
+void Config::pushWorkingDir(const QString& dir)
+{
+ workingDirs_.push(dir);
+}
+
+/*!
+ If the stack of working directories is not empty, pop the
+ top entry and return it. Otherwise return an empty string.
+ */
+QString Config::popWorkingDir()
+{
+ if (!workingDirs_.isEmpty()) {
+ return workingDirs_.pop();
+ }
+ qDebug() << "RETURNED EMPTY WORKING DIR";
+ return QString();
+}
+
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h
index b3a35b9c0f..f5c1999159 100644
--- a/src/tools/qdoc/config.h
+++ b/src/tools/qdoc/config.h
@@ -49,12 +49,26 @@
#include <qmap.h>
#include <qset.h>
#include <qstringlist.h>
-
+#include <qstack.h>
+#include <qpair.h>
#include "location.h"
QT_BEGIN_NAMESPACE
-typedef QMultiMap<QString, QString> QStringMultiMap;
+/*
+ In QStringPair, the first string is the path to a directory;
+ the second string is some value.
+ */
+typedef QPair<QString, QString> QStringPair;
+
+/*
+ In QStringListPair, the first string is the path to a directory;
+ the string list is a list of string values.
+ */
+typedef QPair<QString, QStringList> QStringListPair;
+typedef QMultiMap<QString, QStringPair> QStringPairMultiMap;
+typedef QMap<QString, QStringPair> QStringPairMap;
+typedef QMap<QString, QStringListPair> QStringListPairMap;
class Config
{
@@ -68,20 +82,22 @@ public:
const QString& programName() const { return prog; }
const Location& location() const { return loc; }
- const Location& lastLocation() const { return lastLoc; }
+ const Location& lastLocation() const { return lastLocation_; }
bool getBool(const QString& var) const;
int getInt(const QString& var) const;
QString getOutputDir() const;
QSet<QString> getOutputFormats() const;
QString getString(const QString& var) const;
+ QString getPath(const QString& var) const;
QSet<QString> getStringSet(const QString& var) const;
QStringList getStringList(const QString& var) const;
QStringList getCanonicalRelativePathList(const QString& var) const;
QStringList getCleanPathList(const QString& var) const;
+ QStringList getPathList(const QString& var) const;
QRegExp getRegExp(const QString& var) const;
QList<QRegExp> getRegExpList(const QString& var) const;
QSet<QString> subVars(const QString& var) const;
- void subVarsAndValues(const QString& var, QStringMultiMap& t) const;
+ void subVarsAndValues(const QString& var, QStringPairMap& t) const;
QStringList getAllFiles(const QString& filesVar,
const QString& dirsVar,
const QSet<QString> &excludedDirs = QSet<QString>(),
@@ -111,6 +127,8 @@ public:
const QString& targetDirPath);
static int numParams(const QString& value);
static bool removeDirContents(const QString& dir);
+ static void pushWorkingDir(const QString& dir);
+ static QString popWorkingDir();
QT_STATIC_CONST QString dot;
@@ -125,14 +143,18 @@ private:
QString prog;
Location loc;
- Location lastLoc;
+ Location lastLocation_;
QMap<QString, Location> locMap;
- QMap<QString, QStringList> stringListValueMap;
QMap<QString, QString> stringValueMap;
+ QMap<QString, QStringList> stringListValueMap;
+
+ QStringPairMap stringPairMap;
+ QStringListPairMap stringListPairMap;
static QMap<QString, QString> uncompressedFiles;
static QMap<QString, QString> extractedDirs;
static int numInstances;
+ static QStack<QString> workingDirs_;
};
#define CONFIG_ALIAS "alias"
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp
index d4fe0ff5f7..2fc3a6c477 100644
--- a/src/tools/qdoc/cppcodeparser.cpp
+++ b/src/tools/qdoc/cppcodeparser.cpp
@@ -2156,8 +2156,8 @@ bool CppCodeParser::matchDocsAndStuff()
while (n != nodes.end()) {
processOtherMetaCommands(*d, *n);
(*n)->setDoc(*d);
- if ((*n)->isInnerNode() &&
- ((InnerNode *)*n)->includes().isEmpty()) {
+ checkModuleInclusion(*n);
+ if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) {
InnerNode *m = static_cast<InnerNode *>(*n);
while (m->parent() != qdb_->treeRoot())
m = m->parent();
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index 563df612ab..3b7a4d09cc 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -573,7 +573,8 @@ void DitaXmlGenerator::initializeGenerator(const Config &config)
customHeadElements = config.getStringList(DitaXmlGenerator::format() +
Config::dot +
DITAXMLGENERATOR_CUSTOMHEADELEMENTS);
- codeIndent = config.getInt(CONFIG_CODEINDENT);
+ // The following line was changed to fix QTBUG-27798
+ //codeIndent = config.getInt(CONFIG_CODEINDENT);
version = config.getString(CONFIG_VERSION);
vrm = version.split(QLatin1Char('.'));
}
@@ -5883,7 +5884,7 @@ QStringList DitaXmlGenerator::getMetadataElements(const InnerNode* inner,
*/
QString DitaXmlGenerator::metadataDefault(DitaTag t) const
{
- return metadataDefaults.value(ditaTags[t]);
+ return metadataDefaults.value(ditaTags[t]).second;
}
/*!
diff --git a/src/tools/qdoc/ditaxmlgenerator.h b/src/tools/qdoc/ditaxmlgenerator.h
index 7e1f5a0d5c..3f87fae8a9 100644
--- a/src/tools/qdoc/ditaxmlgenerator.h
+++ b/src/tools/qdoc/ditaxmlgenerator.h
@@ -513,7 +513,7 @@ private:
static QString ditaTags[];
QStack<QXmlStreamWriter*> xmlWriterStack;
QStack<DitaTag> tagStack;
- QStringMultiMap metadataDefaults;
+ QStringPairMap metadataDefaults;
QVector<NodeMultiMap*> nodeTypeMaps;
QVector<NodeMultiMap*> nodeSubtypeMaps;
QVector<NodeMultiMap*> pageTypeMaps;
diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp
index c6db340f74..2854aedbbe 100644
--- a/src/tools/qdoc/generator.cpp
+++ b/src/tools/qdoc/generator.cpp
@@ -697,12 +697,14 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
if (!best.isEmpty() && !documentedItems.contains(best))
details = tr("Maybe you meant '%1'?").arg(best);
- node->doc().location().warning(tr("No such enum item '%1' in %2").arg(*a).arg(node->plainFullName()), details);
+ node->doc().location().warning(tr("No such enum item '%1' in %2")
+ .arg(*a).arg(node->plainFullName()), details);
if (*a == "Void")
qDebug() << "VOID:" << node->name() << definedItems;
}
else if (!documentedItems.contains(*a)) {
- node->doc().location().warning(tr("Undocumented enum item '%1' in %2").arg(*a).arg(node->plainFullName()));
+ node->doc().location().warning(tr("Undocumented enum item '%1' in %2")
+ .arg(*a).arg(node->plainFullName()));
}
++a;
}
@@ -1484,22 +1486,24 @@ void Generator::initialize(const Config &config)
QDir dirInfo;
if (dirInfo.exists(outDir_)) {
- if (!Config::removeDirContents(outDir_))
- config.lastLocation().error(tr("Cannot empty output directory '%1'").arg(outDir_));
+ if (!runGenerateOnly()) {
+ if (!Config::removeDirContents(outDir_))
+ config.lastLocation().error(tr("Cannot empty output directory '%1'").arg(outDir_));
+ }
}
else {
if (!dirInfo.mkpath(outDir_))
config.lastLocation().fatal(tr("Cannot create output directory '%1'").arg(outDir_));
}
- if (!dirInfo.mkdir(outDir_ + "/images"))
- config.lastLocation().fatal(tr("Cannot create output directory '%1'").arg(outDir_ + "/images"));
- if (!dirInfo.mkdir(outDir_ + "/images/used-in-examples"))
- config.lastLocation().fatal(tr("Cannot create output directory '%1'").arg(outDir_ + "/images/used-in-examples"));
- if (!dirInfo.mkdir(outDir_ + "/scripts"))
- config.lastLocation().fatal(tr("Cannot create output directory '%1'").arg(outDir_ + "/scripts"));
- if (!dirInfo.mkdir(outDir_ + "/style"))
- config.lastLocation().fatal(tr("Cannot create output directory '%1'").arg(outDir_ + "/style"));
+ if (!dirInfo.exists(outDir_ + "/images") && !dirInfo.mkdir(outDir_ + "/images"))
+ config.lastLocation().fatal(tr("Cannot create images directory '%1'").arg(outDir_ + "/images"));
+ if (!dirInfo.exists(outDir_ + "/images/used-in-examples") && !dirInfo.mkdir(outDir_ + "/images/used-in-examples"))
+ config.lastLocation().fatal(tr("Cannot create images used in examples directory '%1'").arg(outDir_ + "/images/used-in-examples"));
+ if (!dirInfo.exists(outDir_ + "/scripts") && !dirInfo.mkdir(outDir_ + "/scripts"))
+ config.lastLocation().fatal(tr("Cannot create scripts directory '%1'").arg(outDir_ + "/scripts"));
+ if (!dirInfo.exists(outDir_ + "/style") && !dirInfo.mkdir(outDir_ + "/style"))
+ config.lastLocation().fatal(tr("Cannot create style directory '%1'").arg(outDir_ + "/style"));
}
imageFiles = config.getCleanPathList(CONFIG_IMAGES);
@@ -1524,75 +1528,37 @@ void Generator::initialize(const Config &config)
if (outputFormats.contains((*g)->format())) {
currentGenerator_ = (*g);
(*g)->initializeGenerator(config);
- QStringList extraImages = config.getCleanPathList(CONFIG_EXTRAIMAGES+Config::dot+(*g)->format());
+ QStringList extraImages = config.getCleanPathList((*g)->format() +
+ Config::dot +
+ CONFIG_EXTRAIMAGES);
QStringList::ConstIterator e = extraImages.constBegin();
while (e != extraImages.constEnd()) {
- QString userFriendlyFilePath;
- QString filePath = Config::findFile(config.lastLocation(),
- imageFiles,
- imageDirs,
- *e,
- imgFileExts[(*g)->format()],
- userFriendlyFilePath);
+ QString filePath = *e;
if (!filePath.isEmpty())
- Config::copyFile(config.lastLocation(),
- filePath,
- userFriendlyFilePath,
- (*g)->outputDir() +
- "/images");
+ Config::copyFile(config.lastLocation(), filePath, filePath,
+ (*g)->outputDir() + "/images");
++e;
}
// Documentation template handling
- QString templateDir = config.getString((*g)->format() + Config::dot + CONFIG_TEMPLATEDIR);
-
- QStringList searchDirs;
- if (!templateDir.isEmpty()) {
- searchDirs.append(templateDir);
- }
- if (!Config::installDir.isEmpty()) {
- searchDirs.append(Config::installDir);
+ QStringList scripts = config.getPathList((*g)->format()+Config::dot+CONFIG_SCRIPTS);
+ e = scripts.constBegin();
+ while (e != scripts.constEnd()) {
+ QString filePath = *e;
+ if (!filePath.isEmpty())
+ Config::copyFile(config.lastLocation(), filePath, filePath,
+ (*g)->outputDir() + "/scripts");
+ ++e;
}
- if (!searchDirs.isEmpty()) {
- QStringList noExts;
- QStringList scripts = config.getCleanPathList((*g)->format()+Config::dot+CONFIG_SCRIPTS);
- e = scripts.constBegin();
- while (e != scripts.constEnd()) {
- QString userFriendlyFilePath;
- QString filePath = Config::findFile(config.lastLocation(),
- scriptFiles,
- searchDirs,
- *e,
- noExts,
- userFriendlyFilePath);
- if (!filePath.isEmpty())
- Config::copyFile(config.lastLocation(),
- filePath,
- userFriendlyFilePath,
- (*g)->outputDir() +
- "/scripts");
- ++e;
- }
-
- QStringList styles = config.getCleanPathList((*g)->format()+Config::dot+CONFIG_STYLESHEETS);
- e = styles.constBegin();
- while (e != styles.constEnd()) {
- QString userFriendlyFilePath;
- QString filePath = Config::findFile(config.lastLocation(),
- styleFiles,
- searchDirs,
- *e,
- noExts,
- userFriendlyFilePath);
- if (!filePath.isEmpty())
- Config::copyFile(config.lastLocation(),
- filePath,
- userFriendlyFilePath,
- (*g)->outputDir() +
- "/style");
- ++e;
- }
+ QStringList styles = config.getPathList((*g)->format()+Config::dot+CONFIG_STYLESHEETS);
+ e = styles.constBegin();
+ while (e != styles.constEnd()) {
+ QString filePath = *e;
+ if (!filePath.isEmpty())
+ Config::copyFile(config.lastLocation(), filePath, filePath,
+ (*g)->outputDir() + "/style");
+ ++e;
}
}
++g;
diff --git a/src/tools/qdoc/generator.h b/src/tools/qdoc/generator.h
index 3dc3b84767..8997ef0628 100644
--- a/src/tools/qdoc/generator.h
+++ b/src/tools/qdoc/generator.h
@@ -95,6 +95,7 @@ public:
static void setQDocPass(Passes pass) { qdocPass_ = pass; }
static bool runPrepareOnly() { return (qdocPass_ == Prepare); }
static bool runGenerateOnly() { return (qdocPass_ == Generate); }
+ static QString defaultModuleName() { return project; }
protected:
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
diff --git a/src/tools/qdoc/helpprojectwriter.cpp b/src/tools/qdoc/helpprojectwriter.cpp
index 15698713ae..43a781f972 100644
--- a/src/tools/qdoc/helpprojectwriter.cpp
+++ b/src/tools/qdoc/helpprojectwriter.cpp
@@ -83,6 +83,7 @@ HelpProjectWriter::HelpProjectWriter(const Config &config,
if (project.fileName.isEmpty())
project.fileName = defaultFileName;
project.extraFiles = config.getStringSet(prefix + "extraFiles");
+ project.extraFiles += config.getStringSet(CONFIG_QHP + Config::dot + "extraFiles");
project.indexTitle = config.getString(prefix + "indexTitle");
project.indexRoot = config.getString(prefix + "indexRoot");
project.filterAttributes = config.getStringList(prefix + "filterAttributes").toSet();
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index 17dc40f08a..d48c706707 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -94,7 +94,8 @@ static void addLink(const QString &linkTarget,
Constructs the HTML output generator.
*/
HtmlGenerator::HtmlGenerator()
- : helpProjectWriter(0),
+ : codeIndent(0),
+ helpProjectWriter(0),
inObsoleteLink(false),
funcLeftParen("\\S(\\()"),
obsoleteLinks(false)
@@ -210,7 +211,8 @@ void HtmlGenerator::initializeGenerator(const Config &config)
++edition;
}
- codeIndent = config.getInt(CONFIG_CODEINDENT);
+ // The following line was changed to fix QTBUG-27798
+ //codeIndent = config.getInt(CONFIG_CODEINDENT);
helpProjectWriter = new HelpProjectWriter(config, project.toLower() + ".qhp", this);
diff --git a/src/tools/qdoc/location.cpp b/src/tools/qdoc/location.cpp
index ceb5709aae..ca6521c002 100644
--- a/src/tools/qdoc/location.cpp
+++ b/src/tools/qdoc/location.cpp
@@ -42,7 +42,7 @@
#include <qdebug.h>
#include "config.h"
#include "location.h"
-
+#include "generator.h"
#include <qdir.h>
#include <qregexp.h>
#include <stdlib.h>
@@ -57,6 +57,7 @@ QT_STATIC_CONST_IMPL Location Location::null;
int Location::tabSize;
QString Location::programName;
QRegExp *Location::spuriousRegExp = 0;
+bool Location::logProgress_ = false;
/*!
\class Location
@@ -260,25 +261,30 @@ QString Location::canonicalRelativePath(const QString &path) const
/*!
Writes \a message and \a detals to stderr as a formatted
- warning message.
+ warning message. Does not write the message if qdoc is in
+ the Prepare phase.
*/
void Location::warning(const QString& message, const QString& details) const
{
- emitMessage(Warning, message, details);
+ if (!Generator::runPrepareOnly())
+ emitMessage(Warning, message, details);
}
/*!
Writes \a message and \a detals to stderr as a formatted
- error message.
+ error message. Does not write the message if qdoc is in
+ the Prepare phase.
*/
void Location::error(const QString& message, const QString& details) const
{
- emitMessage(Error, message, details);
+ if (!Generator::runPrepareOnly())
+ emitMessage(Error, message, details);
}
/*!
Writes \a message and \a detals to stderr as a formatted
- error message and then exits the program.
+ error message and then exits the program. qdoc prints fatal
+ errors in either phase (Prepare or Generate).
*/
void Location::fatal(const QString& message, const QString& details) const
{
@@ -331,6 +337,18 @@ void Location::information(const QString& message)
}
/*!
+ Prints \a message to \c stderr followed by a \c{'\n'},
+ but only if the -log-progress option is set.
+ */
+void Location::logToStdErr(const QString& message)
+{
+ if (logProgress_) {
+ fprintf(stderr, "LOG: %s\n", message.toLatin1().data());
+ fflush(stderr);
+ }
+}
+
+/*!
Report a program bug, including the \a hint.
*/
void Location::internalError(const QString& hint)
diff --git a/src/tools/qdoc/location.h b/src/tools/qdoc/location.h
index d2c9487968..0d22e94b46 100644
--- a/src/tools/qdoc/location.h
+++ b/src/tools/qdoc/location.h
@@ -96,6 +96,9 @@ public:
static void terminate();
static void information(const QString& message);
static void internalError(const QString& hint);
+ static void logToStdErr(const QString& message);
+ static void startLoggingProgress() { logProgress_ = true; }
+ static void stopLoggingProgress() { logProgress_ = false; }
private:
enum MessageType { Warning, Error };
@@ -123,6 +126,7 @@ private:
static int tabSize;
static QString programName;
static QRegExp *spuriousRegExp;
+ static bool logProgress_;
};
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp
index 5fbc01f1f0..064617e6f4 100644
--- a/src/tools/qdoc/main.cpp
+++ b/src/tools/qdoc/main.cpp
@@ -101,6 +101,9 @@ static bool obsoleteLinks = false;
static QStringList defines;
static QStringList dependModules;
static QStringList indexDirs;
+static QString currentDir;
+static QString prevCurrentDir;
+static QString documentationPath;
/*!
Print the help message to \c stdout.
@@ -118,7 +121,7 @@ static void printHelp()
" -highlighting "
"Turn on syntax highlighting (makes qdoc run slower)\n"
" -indexdir "
- "Specify a directory where QDoc should search for indices to link to\n"
+ "Specify a directory where QDoc should search for index files to load\n"
" -installdir "
"Specify the directory where the output will be after running \"make install\"\n"
" -no-examples "
@@ -150,6 +153,88 @@ static void printVersion()
Location::information(s);
}
+static void loadIndexFiles(Config& config)
+{
+ QDocDatabase* qdb = QDocDatabase::qdocDB();
+ /*
+ Read some XML indexes containing definitions from other documentation sets.
+ */
+ QStringList indexFiles = config.getStringList(CONFIG_INDEXES);
+
+ dependModules += config.getStringList(CONFIG_DEPENDS);
+
+ // Allow modules and third-party application/libraries to link
+ // to the Qt docs without having to explicitly pass --indexdir.
+ if (!indexDirs.contains(documentationPath))
+ indexDirs.append(documentationPath);
+
+ if (dependModules.size() > 0) {
+ if (indexDirs.size() > 0) {
+ for (int i = 0; i < indexDirs.size(); i++) {
+ if (indexDirs[i].startsWith("..")) {
+ const QString prefix(QDir(currentDir).relativeFilePath(prevCurrentDir));
+ if (!prefix.isEmpty())
+ indexDirs[i].prepend(prefix + QLatin1Char('/'));
+ }
+ }
+ /*
+ Add all subdirectories of the indexdirs as dependModules,
+ when an asterisk is used in the 'depends' list.
+ */
+ if (dependModules.contains("*")) {
+ dependModules.removeOne("*");
+ for (int i = 0; i < indexDirs.size(); i++) {
+ QDir scanDir = QDir(indexDirs[i]);
+ scanDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
+ QFileInfoList dirList = scanDir.entryInfoList();
+ for (int j = 0; j < dirList.size(); j++) {
+ if (dirList[j].fileName().toLower() != config.getString(CONFIG_PROJECT).toLower())
+ dependModules.append(dirList[j].fileName());
+ }
+ }
+ }
+ for (int i = 0; i < dependModules.size(); i++) {
+ QString indexToAdd;
+ QList<QFileInfo> foundIndices;
+ for (int j = 0; j < indexDirs.size(); j++) {
+ QString fileToLookFor = indexDirs[j] + QLatin1Char('/') + dependModules[i] +
+ QLatin1Char('/') + dependModules[i] + QLatin1String(".index");
+ if (QFile::exists(fileToLookFor)) {
+ QFileInfo tempFileInfo(fileToLookFor);
+ if (!foundIndices.contains(tempFileInfo))
+ foundIndices.append(tempFileInfo);
+ }
+ }
+ qSort(foundIndices.begin(), foundIndices.end(), creationTimeBefore);
+ if (foundIndices.size() > 1) {
+ /*
+ QDoc should always use the last entry in the multimap when there are
+ multiple index files for a module, since the last modified file has the
+ highest UNIX timestamp.
+ */
+ qDebug() << "Multiple indices found for dependency:" << dependModules[i] << "\nFound:";
+ for (int k = 0; k < foundIndices.size(); k++)
+ qDebug() << foundIndices[k].absoluteFilePath();
+ qDebug() << "Using" << foundIndices[foundIndices.size() - 1].absoluteFilePath()
+ << "as index for" << dependModules[i];
+ indexToAdd = foundIndices[foundIndices.size() - 1].absoluteFilePath();
+ }
+ else if (foundIndices.size() == 1) {
+ indexToAdd = foundIndices[0].absoluteFilePath();
+ }
+ if (!indexToAdd.isEmpty() && !indexFiles.contains(indexToAdd))
+ indexFiles << indexToAdd;
+ }
+ }
+ else {
+ qDebug() << "Dependant modules specified, but no index directories or "
+ << "install directory were set."
+ << "There will probably be errors for missing links.";
+ }
+ }
+ qdb->readIndexes(indexFiles);
+}
+
/*!
Processes the qdoc config file \a fileName. This is the
controller for all of qdoc.
@@ -168,8 +253,7 @@ static void processQdocconfFile(const QString &fileName)
Config config(tr("qdoc"));
int i = 0;
while (defaults[i].key) {
- config.setStringList(defaults[i].key,
- QStringList() << defaults[i].value);
+ config.setStringList(defaults[i].key, QStringList() << defaults[i].value);
++i;
}
config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false"));
@@ -177,11 +261,16 @@ static void processQdocconfFile(const QString &fileName)
config.setStringList(CONFIG_NOLINKERRORS, QStringList(noLinkErrors ? "true" : "false"));
config.setStringList(CONFIG_OBSOLETELINKS, QStringList(obsoleteLinks ? "true" : "false"));
- QString documentationPath = QLibraryInfo::rawLocation(QLibraryInfo::DocumentationPath,
- QLibraryInfo::EffectivePaths);
-
- // Set a few environment variables that can be used from the qdocconf file
- qputenv("QT_INSTALL_DOCS", documentationPath.toLatin1());
+ /*
+ If QT_INSTALL_DOCS is not set, set it here so it can be used from
+ the qdocconf files.
+ */
+ QString qt_install_docs = qgetenv("QT_INSTALL_DOCS");
+ if (qt_install_docs.isEmpty()) {
+ documentationPath = QLibraryInfo::rawLocation(QLibraryInfo::DocumentationPath,
+ QLibraryInfo::EffectivePaths);
+ qputenv("QT_INSTALL_DOCS", documentationPath.toLatin1());
+ }
/*
With the default configuration values in place, load
@@ -192,6 +281,7 @@ static void processQdocconfFile(const QString &fileName)
in the file being processed, mainly for error reporting
purposes.
*/
+ currentDir = QFileInfo(fileName).path();
Location::initialize(config);
config.load(fileName);
@@ -202,10 +292,18 @@ static void processQdocconfFile(const QString &fileName)
config.setStringList(CONFIG_DEFINES,defs);
Location::terminate();
- QString prevCurrentDir = QDir::currentPath();
- QString dir = QFileInfo(fileName).path();
- if (!dir.isEmpty())
- QDir::setCurrent(dir);
+ prevCurrentDir = QDir::currentPath();
+ currentDir = QFileInfo(fileName).path();
+ if (!currentDir.isEmpty())
+ QDir::setCurrent(currentDir);
+
+ QString phase;
+ if (Generator::runPrepareOnly())
+ phase = " in -prepare mode ";
+ else if (Generator::runGenerateOnly())
+ phase = " in -generate mode ";
+ QString msg = "Running qdoc for " + config.getString(CONFIG_PROJECT) + phase;
+ Location::logToStdErr(msg);
/*
Initialize all the classes and data structures with the
@@ -227,8 +325,7 @@ static void processQdocconfFile(const QString &fileName)
while (fn != fileNames.constEnd()) {
QTranslator *translator = new QTranslator(0);
if (!translator->load(*fn))
- config.lastLocation().error(tr("Cannot load translator '%1'")
- .arg(*fn));
+ config.lastLocation().error(tr("Cannot load translator '%1'").arg(*fn));
QCoreApplication::instance()->installTranslator(translator);
translators.append(translator);
++fn;
@@ -260,86 +357,8 @@ static void processQdocconfFile(const QString &fileName)
QSet<QString> outputFormats = config.getOutputFormats();
Location outputFormatsLocation = config.lastLocation();
- /*
- Read some XML indexes containing definitions from other documentation sets.
- */
- QStringList indexFiles = config.getStringList(CONFIG_INDEXES);
-
- dependModules += config.getStringList(CONFIG_DEPENDS);
-
- // Allow modules and third-party application/libraries to link
- // to the Qt docs without having to explicitly pass --indexdir.
- if (!indexDirs.contains(documentationPath))
- indexDirs.append(documentationPath);
-
- if (dependModules.size() > 0) {
- if (indexDirs.size() > 0) {
- for (int i = 0; i < indexDirs.size(); i++) {
- if (indexDirs[i].startsWith("..")) {
- const QString prefix(QDir(dir).relativeFilePath(prevCurrentDir));
- if (!prefix.isEmpty())
- indexDirs[i].prepend(prefix + QLatin1Char('/'));
- }
- }
- /*
- Add all subdirectories of the indexdirs as dependModules when an asterisk is used in
- the 'depends' list.
- */
- if (dependModules.contains("*")) {
- dependModules.removeOne("*");
- for (int i = 0; i < indexDirs.size(); i++) {
- QDir scanDir = QDir(indexDirs[i]);
- scanDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
- QFileInfoList dirList = scanDir.entryInfoList();
- for (int j = 0; j < dirList.size(); j++) {
- if (dirList[j].fileName().toLower() != config.getString(CONFIG_PROJECT).toLower())
- dependModules.append(dirList[j].fileName());
- }
- }
- }
- for (int i = 0; i < dependModules.size(); i++) {
- QString indexToAdd;
- QList<QFileInfo> foundIndices;
- for (int j = 0; j < indexDirs.size(); j++) {
- QString fileToLookFor = indexDirs[j] + QLatin1Char('/') + dependModules[i] +
- QLatin1Char('/') + dependModules[i] + QLatin1String(".index");
- if (QFile::exists(fileToLookFor)) {
- QFileInfo tempFileInfo(fileToLookFor);
- if (!foundIndices.contains(tempFileInfo))
- foundIndices.append(tempFileInfo);
- }
- }
- qSort(foundIndices.begin(), foundIndices.end(), creationTimeBefore);
- if (foundIndices.size() > 1) {
- /*
- QDoc should always use the last entry in the multimap when there are
- multiple index files for a module, since the last modified file has the
- highest UNIX timestamp.
- */
- qDebug() << "Multiple indices found for dependency:" << dependModules[i] << "\nFound:";
- for (int k = 0; k < foundIndices.size(); k++)
- qDebug() << foundIndices[k].absoluteFilePath();
- qDebug() << "Using" << foundIndices[foundIndices.size() - 1].absoluteFilePath()
- << "as index for" << dependModules[i];
- indexToAdd = foundIndices[foundIndices.size() - 1].absoluteFilePath();
- }
- else if (foundIndices.size() == 1) {
- indexToAdd = foundIndices[0].absoluteFilePath();
- }
- else {
- qDebug() << "No indices for" << dependModules[i] <<
- "could be found in the specified index directories.";
- }
- if (!indexToAdd.isEmpty() && !indexFiles.contains(indexToAdd))
- indexFiles << indexToAdd;
- }
- }
- else {
- qDebug() << "Dependant modules specified, but no index directories or install directory were set."
- << "There will probably be errors for missing links.";
- }
- }
- qdb->readIndexes(indexFiles);
+ if (!Generator::runPrepareOnly())
+ loadIndexFiles(config);
QSet<QString> excludedDirs;
QSet<QString> excludedFiles;
@@ -604,6 +623,9 @@ int main(int argc, char **argv)
else if (opt == "-generate") {
Generator::setQDocPass(Generator::Generate);
}
+ else if (opt == "-log-progress") {
+ Location::startLoggingProgress();
+ }
else {
qdocFiles.append(opt);
}
diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp
index 67805d3dff..3828709b7f 100644
--- a/src/tools/qdoc/node.cpp
+++ b/src/tools/qdoc/node.cpp
@@ -462,7 +462,7 @@ void Node::setLink(LinkType linkType, const QString &link, const QString &desc)
*/
void Node::setSince(const QString &since)
{
- sinc = since.simplified();
+ since_ = since.simplified();
}
/*!
diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h
index 451b666a78..05133cab0c 100644
--- a/src/tools/qdoc/node.h
+++ b/src/tools/qdoc/node.h
@@ -222,7 +222,7 @@ public:
Status inheritedStatus() const;
ThreadSafeness threadSafeness() const;
ThreadSafeness inheritedThreadSafeness() const;
- QString since() const { return sinc; }
+ QString since() const { return since_; }
QString templateStuff() const { return templateStuff_; }
PageType pageType() const { return pageType_; }
QString pageTypeString() const;
@@ -280,7 +280,7 @@ private:
QMap<LinkType, QPair<QString, QString> > linkMap_;
QString moduleName_;
QString url_;
- QString sinc;
+ QString since_;
QString templateStuff_;
mutable QString uuid_;
QString outSubDir_;
diff --git a/src/tools/qdoc/puredocparser.cpp b/src/tools/qdoc/puredocparser.cpp
index cd726c3497..9f76596e46 100644
--- a/src/tools/qdoc/puredocparser.cpp
+++ b/src/tools/qdoc/puredocparser.cpp
@@ -195,6 +195,7 @@ bool PureDocParser::processQdocComments()
while (n != nodes.end()) {
processOtherMetaCommands(*d, *n);
(*n)->setDoc(*d);
+ checkModuleInclusion(*n);
if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) {
InnerNode *m = static_cast<InnerNode *>(*n);
while (m->parent() && m->parent() != treeRoot)
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp
index 0c0b30e8c7..d5dbb84386 100644
--- a/src/tools/qdoc/qdocdatabase.cpp
+++ b/src/tools/qdoc/qdocdatabase.cpp
@@ -321,7 +321,7 @@ void QDocDatabase::findAllClasses(const InnerNode* node)
{
NodeList::const_iterator c = node->childNodes().constBegin();
while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
+ if ((*c)->access() != Node::Private) {
if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
QString className = (*c)->name();
if ((*c)->parent() &&
@@ -344,8 +344,9 @@ void QDocDatabase::findAllClasses(const InnerNode* node)
}
QString serviceName = (static_cast<const ClassNode *>(*c))->serviceName();
- if (!serviceName.isEmpty())
+ if (!serviceName.isEmpty()) {
serviceClasses_.insert(serviceName, *c);
+ }
}
else if ((*c)->type() == Node::Document &&
(*c)->subType() == Node::QmlClass &&
@@ -372,7 +373,7 @@ void QDocDatabase::findAllFunctions(const InnerNode* node)
NodeList::ConstIterator c = node->childNodes().constBegin();
while (c != node->childNodes().constEnd()) {
if ((*c)->access() != Node::Private) {
- if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
+ if ((*c)->isInnerNode()) {
findAllFunctions(static_cast<const InnerNode*>(*c));
}
else if ((*c)->type() == Node::Function) {
@@ -415,15 +416,13 @@ void QDocDatabase::findAllNamespaces(const InnerNode* node)
NodeList::ConstIterator c = node->childNodes().constBegin();
while (c != node->childNodes().constEnd()) {
if ((*c)->access() != Node::Private) {
- if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
+ if ((*c)->isInnerNode()) {
findAllNamespaces(static_cast<const InnerNode *>(*c));
if ((*c)->type() == Node::Namespace) {
- const NamespaceNode* nspace = static_cast<const NamespaceNode *>(*c);
// Ensure that the namespace's name is not empty (the root
// namespace has no name).
- if (!nspace->name().isEmpty()) {
- namespaceIndex_.insert(nspace->name(), *c);
- }
+ if (!(*c)->name().isEmpty())
+ namespaceIndex_.insert((*c)->name(), *c);
}
}
}
@@ -467,12 +466,11 @@ void QDocDatabase::findAllSince(const InnerNode* node)
nsmap.value().insert(func->name(),(*child));
}
}
- else if ((*child)->url().isEmpty()) {
- if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) {
+ else {
+ if ((*child)->type() == Node::Class) {
// Insert classes into the since and class maps.
QString className = (*child)->name();
- if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
- !(*child)->parent()->name().isEmpty()) {
+ if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) {
className = (*child)->parent()->name()+"::"+className;
}
nsmap.value().insert(className,(*child));
@@ -481,8 +479,7 @@ void QDocDatabase::findAllSince(const InnerNode* node)
else if ((*child)->subType() == Node::QmlClass) {
// Insert QML elements into the since and element maps.
QString className = (*child)->name();
- if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
- !(*child)->parent()->name().isEmpty()) {
+ if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) {
className = (*child)->parent()->name()+"::"+className;
}
nsmap.value().insert(className,(*child));
@@ -493,17 +490,15 @@ void QDocDatabase::findAllSince(const InnerNode* node)
QString propertyName = (*child)->name();
nsmap.value().insert(propertyName,(*child));
}
- }
- else {
- // Insert external documents into the general since map.
- QString name = (*child)->name();
- if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
- !(*child)->parent()->name().isEmpty()) {
- name = (*child)->parent()->name()+"::"+name;
+ else {
+ // Insert external documents into the general since map.
+ QString name = (*child)->name();
+ if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) {
+ name = (*child)->parent()->name()+"::"+name;
+ }
+ nsmap.value().insert(name,(*child));
}
- nsmap.value().insert(name,(*child));
}
-
// Recursively find child nodes with since commands.
if ((*child)->isInnerNode()) {
findAllSince(static_cast<InnerNode *>(*child));
diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp
index d68fe0e6fa..3f79675b3b 100644
--- a/src/tools/qdoc/qdocindexfiles.cpp
+++ b/src/tools/qdoc/qdocindexfiles.cpp
@@ -48,13 +48,7 @@
#include "location.h"
#include "atom.h"
#include "generator.h"
-
-//include "doc.h"
-//include "htmlgenerator.h"
-//include "node.h"
-//include "text.h"
-//include <limits.h>
-//include <qdebug.h>
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -109,8 +103,11 @@ void QDocIndexFiles::destroyQDocIndexFiles()
*/
void QDocIndexFiles::readIndexes(const QStringList& indexFiles)
{
- foreach (const QString& indexFile, indexFiles)
+ foreach (const QString& indexFile, indexFiles) {
+ QString msg = "Loading index file: " + indexFile;
+ Location::logToStdErr(msg);
readIndexFile(indexFile);
+ }
}
/*!
@@ -438,11 +435,18 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
else
section->setStatus(Node::Commendable);
- section->setModuleName(element.attribute("module"));
+ QString moduleName = element.attribute("module");
+ if (!moduleName.isEmpty())
+ section->setModuleName(moduleName);
if (!indexUrl.isEmpty()) {
section->setUrl(indexUrl + QLatin1Char('/') + href);
}
+ QString since = element.attribute("since");
+ if (!since.isEmpty()) {
+ section->setSince(since);
+ }
+
// Create some content for the node.
QSet<QString> emptySet;
Doc doc(location, location, " ", emptySet); // placeholder
@@ -502,7 +506,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
Node* node,
bool generateInternalNodes)
{
- if (!node->url().isEmpty() || node->subType() == Node::DitaMap)
+ if (node->subType() == Node::DitaMap)
return false;
QString nodeName;
@@ -642,6 +646,10 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
if ((node->type() != Node::Document) && (!node->isQmlNode()))
writer.writeAttribute("location", node->location().fileName());
+ if (!node->since().isEmpty()) {
+ writer.writeAttribute("since", node->since());
+ }
+
switch (node->type()) {
case Node::Class:
{
@@ -654,11 +662,13 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
baseStrings.insert(baseClassNode->name());
}
writer.writeAttribute("bases", QStringList(baseStrings.toList()).join(","));
- writer.writeAttribute("module", node->moduleName());
+ if (!node->moduleName().isEmpty())
+ writer.writeAttribute("module", node->moduleName());
}
break;
case Node::Namespace:
- writer.writeAttribute("module", node->moduleName());
+ if (!node->moduleName().isEmpty())
+ writer.writeAttribute("module", node->moduleName());
break;
case Node::Document:
{
@@ -666,25 +676,30 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
Document nodes (such as manual pages) contain subtypes,
titles and other attributes.
*/
+ bool writeModuleName = false;
const DocNode* docNode = static_cast<const DocNode*>(node);
switch (docNode->subType()) {
case Node::Example:
writer.writeAttribute("subtype", "example");
+ writeModuleName = true;
break;
case Node::HeaderFile:
writer.writeAttribute("subtype", "header");
+ writeModuleName = true;
break;
case Node::File:
writer.writeAttribute("subtype", "file");
break;
case Node::Group:
writer.writeAttribute("subtype", "group");
+ writeModuleName = true;
break;
case Node::Module:
writer.writeAttribute("subtype", "module");
break;
case Node::Page:
writer.writeAttribute("subtype", "page");
+ writeModuleName = true;
break;
case Node::ExternalPage:
writer.writeAttribute("subtype", "externalpage");
@@ -702,6 +717,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("fulltitle", docNode->fullTitle());
writer.writeAttribute("subtitle", docNode->subTitle());
writer.writeAttribute("location", docNode->doc().location().fileName());
+ if (!node->moduleName().isEmpty() && writeModuleName) {
+ writer.writeAttribute("module", node->moduleName());
+ }
}
break;
case Node::Function:
@@ -1048,6 +1066,9 @@ void QDocIndexFiles::generateIndex(const QString& fileName,
if (!file.open(QFile::WriteOnly | QFile::Text))
return;
+ QString msg = "Writing index file: " + fileName;
+ Location::logToStdErr(msg);
+
gen_ = g;
QXmlStreamWriter writer(&file);
writer.setAutoFormatting(true);
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
index c67d6bfd76..f7d1e651ff 100644
--- a/src/tools/tools.pro
+++ b/src/tools/tools.pro
@@ -38,6 +38,6 @@ SUBDIRS = $$TOOLS_SUBDIRS
# Ensure qdoc is built before making any docs. We rely on the existing dependency
# on bootstrap for each of the other tools to ensure they also build qdoc first,
# and likewise, the dependency of the rest of the build on tools, src, etc.
-bootstrap_docs.depends += $${src_tools_qdoc.target}-make_first
-bootstrap_docs.target = $${src_tools_bootstrap.target}-docs
-QMAKE_EXTRA_TARGETS += bootstrap_docs
+bootstrap_prepare_docs.depends += $${src_tools_qdoc.target}-make_first
+bootstrap_prepare_docs.target = $${src_tools_bootstrap.target}-prepare_docs
+QMAKE_EXTRA_TARGETS += bootstrap_prepare_docs