summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@digia.com>2013-04-29 10:00:45 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-30 12:45:30 +0200
commita2892ad1d7584de62a1356812a4f9348f37e1d29 (patch)
tree3ad89d0ac60f3120bba46f5b2d2a81152e351a0c /src
parent542e3be40d0323e239a2e6381e7fd60de9153a06 (diff)
qdoc: Config class keeps track of current path
The Config class is modified to build a single multimap containing a record for each variable found in each .qdocconf file. Each reacord contains not only the name and value of the variable, but also its location in the qdocconf file it was read from and the path to that file. This single multimap replaces 3 maps in the Config class. Task-number: QTBUG-30725 Change-Id: I049a69790f943b24c014a24b55b2b39725a1b56f Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/tools/qdoc/config.cpp313
-rw-r--r--src/tools/qdoc/config.h39
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.cpp13
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.h4
-rw-r--r--src/tools/qdoc/location.cpp29
-rw-r--r--src/tools/qdoc/location.h3
6 files changed, 221 insertions, 180 deletions
diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp
index 766697dfc2..5467791316 100644
--- a/src/tools/qdoc/config.cpp
+++ b/src/tools/qdoc/config.cpp
@@ -55,8 +55,9 @@
QT_BEGIN_NAMESPACE
-/*
- An entry on the MetaStack.
+/*!
+ An entry in a stack, where each entry is a list
+ of string values.
*/
class MetaStackEntry
{
@@ -68,14 +69,19 @@ public:
QStringList next;
};
-/*
+/*!
+ Start accumulating values in a list by appending an empty
+ string to the list.
*/
void MetaStackEntry::open()
{
next.append(QString());
}
-/*
+/*!
+ Stop accumulating values and append the list of accumulated
+ values to the complete list of accumulated values.
+
*/
void MetaStackEntry::close()
{
@@ -83,8 +89,10 @@ void MetaStackEntry::close()
next.clear();
}
-/*
- ###
+/*!
+ \class MetaStack
+
+ This class maintains a stack of values of config file variables.
*/
class MetaStack : private QStack<MetaStackEntry>
{
@@ -97,12 +105,21 @@ public:
QStringList getExpanded(const Location& location);
};
+/*!
+ The default constructor pushes a new stack entry and
+ opens it.
+ */
MetaStack::MetaStack()
{
push(MetaStackEntry());
top().open();
}
+/*!
+ Processes the character \a ch using the \a location.
+ It really just builds up a name by appending \a ch to
+ it.
+ */
void MetaStack::process(QChar ch, const Location& location)
{
if (ch == QLatin1Char('{')) {
@@ -133,6 +150,9 @@ void MetaStack::process(QChar ch, const Location& location)
top().open();
}
else {
+ /*
+ This is where all the processing is done.
+ */
QStringList::Iterator pre = top().next.begin();
while (pre != top().next.end()) {
*pre += ch;
@@ -141,6 +161,9 @@ void MetaStack::process(QChar ch, const Location& location)
}
}
+/*!
+ Returns the accumulated string values.
+ */
QStringList MetaStack::getExpanded(const Location& location)
{
if (count() > 1)
@@ -176,9 +199,7 @@ Config::Config(const QString& programName)
{
loc = Location::null;
lastLocation_ = Location::null;
- locMap.clear();
- stringPairMap.clear();
- stringListPairMap.clear();
+ configVars_.clear();
numInstances++;
}
@@ -211,19 +232,6 @@ void Config::load(const QString& fileName)
}
/*!
- Writes the qdoc configuration data to the named file.
- The previous contents of the file are overwritten.
- */
-void Config::unload(const QString& fileName)
-{
- QStringPairMap::ConstIterator v = stringPairMap.constBegin();
- while (v != stringPairMap.constEnd()) {
- qDebug() << v.key() << " = " << v.value().second;
- ++v;
- }
- qDebug() << "fileName:" << fileName;
-}
-/*!
Joins all the strings in \a values into a single string with the
individual \a values separated by ' '. Then it inserts the result
into the string list map with \a var as the key.
@@ -233,10 +241,7 @@ void Config::unload(const QString& fileName)
*/
void Config::setStringList(const QString& var, const QStringList& values)
{
- stringPairMap[var].first = QDir::currentPath();
- stringPairMap[var].second = values.join(QLatin1Char(' '));
- stringListPairMap[var].first = QDir::currentPath();
- stringListPairMap[var].second = values;
+ configVars_.insert(var,ConfigVar(var, values, QDir::currentPath()));
}
/*!
@@ -303,30 +308,29 @@ QSet<QString> Config::getOutputFormats() const
*/
QString Config::getString(const QString& var) const
{
- if (!locMap[var].isEmpty())
- (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();
+ QList<ConfigVar> configVars = configVars_.values(var);
+ QString value;
+ int high = 0;
+ if (!configVars.empty()) {
+ int i = configVars.size() - 1;
+ while (i >= 0) {
+ const ConfigVar& cv = configVars[i];
+ if (!cv.location_.isEmpty())
+ (Location&) lastLocation_ = cv.location_;
+ if (!cv.values_.isEmpty()) {
+ if (!cv.plus_)
+ value.clear();
+ for (int j=0; j<cv.values_.size(); ++j) {
+ if (!value.isEmpty() && !value.endsWith(QChar('\n')))
+ value.append(QChar(' '));
+ value.append(cv.values_[j]);
+ high = j;
+ }
+ }
+ --i;
+ }
}
- return path;
+ return value;
}
/*!
@@ -341,20 +345,36 @@ 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
+ in the location map. If found, it sets the internal variable
\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.
+ Then it looks up the configuration variable \a var in the map of
+ configuration variable records. If found, it gets a list of all
+ the records for \a var. Then it appends all the values for \a var
+ to a list and returns the list. As it appends the values from each
+ record, if the \a var used '=' instead of '+=' the list is cleared
+ before the values are appended. \note '+=' should always be used.
+ The final list is returned.
*/
QStringList Config::getStringList(const QString& var) const
{
- if (!locMap[var].isEmpty())
- (Location&) lastLocation_ = locMap[var];
- return stringListPairMap[var].second;
+ QList<ConfigVar> configVars = configVars_.values(var);
+ QStringList values;
+ if (!configVars.empty()) {
+ int i = configVars.size() - 1;
+ while (i >= 0) {
+ if (!configVars[i].location_.isEmpty())
+ (Location&) lastLocation_ = configVars[i].location_;
+ if (configVars[i].plus_)
+ values.append(configVars[i].values_);
+ else
+ values = configVars[i].values_;
+ --i;
+ }
+ }
+ return values;
}
-
/*!
\brief Returns the a path list where all paths are canonicalized, then
made relative to the config file.
@@ -363,18 +383,26 @@ QStringList Config::getStringList(const QString& var) const
*/
QStringList Config::getCanonicalRelativePathList(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;
- if (!sl.isEmpty()) {
- t.reserve(sl.size());
- for (int i=0; i<sl.size(); ++i) {
- const QString &canonicalized = location().canonicalRelativePath(sl[i]);
- t.append(canonicalized);
+ QList<ConfigVar> configVars = configVars_.values(var);
+ if (!configVars.empty()) {
+ int i = configVars.size() - 1;
+ while (i >= 0) {
+ const ConfigVar& cv = configVars[i];
+ if (!cv.location_.isEmpty())
+ (Location&) lastLocation_ = cv.location_;
+ if (!cv.plus_)
+ t.clear();
+ const QString d = cv.currentPath_;
+ const QStringList& sl = cv.values_;
+ if (!sl.isEmpty()) {
+ t.reserve(t.size() + sl.size());
+ for (int i=0; i<sl.size(); ++i) {
+ const QString& crp = Location::canonicalRelativePath(sl[i], d);
+ t.append(crp);
+ }
}
+ --i;
}
}
return t;
@@ -382,32 +410,30 @@ QStringList Config::getCanonicalRelativePathList(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.
+ variable \a var maps to string lists that contain 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::getCleanPathList(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;
- if (!sl.isEmpty()) {
- t.reserve(sl.size());
- for (int i=0; i<sl.size(); ++i) {
- t.append(QDir::cleanPath(sl[i]));
+ QList<ConfigVar> configVars = configVars_.values(var);
+ if (!configVars.empty()) {
+ int i = configVars.size() - 1;
+ while (i >= 0) {
+ const ConfigVar& cv = configVars[i];
+ if (!cv.plus_)
+ t.clear();
+ if (!cv.location_.isEmpty())
+ (Location&) lastLocation_ = cv.location_;
+ const QStringList& sl = cv.values_;
+ if (!sl.isEmpty()) {
+ t.reserve(t.size() + sl.size());
+ for (int i=0; i<sl.size(); ++i) {
+ t.append(QDir::cleanPath(sl[i].simplified()));
+ }
}
+ --i;
}
}
return t;
@@ -415,7 +441,7 @@ 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.
+ variable \a var maps to string lists that contain file paths.
It cleans the paths with QDir::cleanPath() before returning
them.
@@ -424,30 +450,39 @@ QStringList Config::getCleanPathList(const QString& var) const
\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.
+ list map, which maps to one or more records that each contains a
+ list of 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);
+ QList<ConfigVar> configVars = configVars_.values(var);
+ if (!configVars.empty()) {
+ int i = configVars.size() - 1;
+ while (i >= 0) {
+ const ConfigVar& cv = configVars[i];
+ if (!cv.plus_)
+ t.clear();
+ if (!cv.location_.isEmpty())
+ (Location&) lastLocation_ = cv.location_;
+ const QString d = cv.currentPath_;
+ const QStringList& sl = cv.values_;
+ if (!sl.isEmpty()) {
+ t.reserve(t.size() + sl.size());
+ for (int i=0; i<sl.size(); ++i) {
+ QFileInfo fileInfo;
+ QString path = d + "/" + QDir::cleanPath(sl[i].simplified());
+ fileInfo.setFile(path);
+ if (!fileInfo.exists())
+ lastLocation_.warning(tr("File '%1' does not exist").arg(path));
+ else
+ t.append(path);
+ }
}
+ --i;
}
}
return t;
@@ -509,30 +544,31 @@ QSet<QString> Config::subVars(const QString& var) const
{
QSet<QString> result;
QString varDot = var + QLatin1Char('.');
- QStringPairMap::ConstIterator v = stringPairMap.constBegin();
- while (v != stringPairMap.constEnd()) {
- if (v.key().startsWith(varDot)) {
- QString subVar = v.key().mid(varDot.length());
+ ConfigVarMultimap::ConstIterator i = configVars_.constBegin();
+ while (i != configVars_.constEnd()) {
+ if (i.key().startsWith(varDot)) {
+ QString subVar = i.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
if (dot != -1)
subVar.truncate(dot);
- result.insert(subVar);
+ if (!result.contains(subVar))
+ result.insert(subVar);
}
- ++v;
+ ++i;
}
return result;
}
/*!
- Same as subVars(), but in this case we return a string map
- with the matching keys (stripped of the prefix \a var and
- mapped to their values. The pairs are inserted into \a t
+ Same as subVars(), but in this case we return a config var
+ multimap 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, QStringPairMap& t) const
+void Config::subVarsAndValues(const QString& var, ConfigVarMultimap& t) const
{
QString varDot = var + QLatin1Char('.');
- QStringPairMap::ConstIterator v = stringPairMap.constBegin();
- while (v != stringPairMap.constEnd()) {
+ ConfigVarMultimap::ConstIterator v = configVars_.constBegin();
+ while (v != configVars_.constEnd()) {
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
@@ -869,7 +905,7 @@ void Config::load(Location location, const QString& fileName)
Location keyLoc = location;
bool plus = false;
QString stringValue;
- QStringList stringListValue;
+ QStringList rhsValues;
QString word;
bool inQuote = false;
bool prevWordQuoted = true;
@@ -931,6 +967,7 @@ void Config::load(Location location, const QString& fileName)
else {
/*
It wasn't an include statement, so it's something else.
+ We must see either '=' or '+=' next. If not, fatal error.
*/
if (cc == '+') {
plus = true;
@@ -972,7 +1009,12 @@ void Config::load(Location location, const QString& fileName)
if (metWord)
stringValue += QLatin1Char(' ');
stringValue += word;
- stringListValue << word;
+#if 0
+ if (metWord)
+ rhsValues << QString(" " + word);
+ else
+#endif
+ rhsValues << word;
metWord = true;
word.clear();
prevWordQuoted = false;
@@ -988,7 +1030,7 @@ void Config::load(Location location, const QString& fileName)
stringValue += QLatin1Char(' ');
stringValue += word;
if (!word.isEmpty())
- stringListValue << word;
+ rhsValues << word;
metWord = true;
word.clear();
prevWordQuoted = true;
@@ -1025,30 +1067,9 @@ void Config::load(Location location, const QString& fileName)
if (!keySyntax.exactMatch(*key))
keyLoc.fatal(tr("Invalid key '%1'").arg(*key));
- if (plus) {
- if (locMap[*key].isEmpty()) {
- locMap[*key] = keyLoc;
- }
- else {
- locMap[*key].setEtc(true);
- }
- if (stringPairMap[*key].second.isEmpty()) {
- stringPairMap[*key].first = QDir::currentPath();
- stringPairMap[*key].second = stringValue;
- }
- else {
- stringPairMap[*key].second += QLatin1Char(' ') + stringValue;
- }
- stringListPairMap[*key].first = QDir::currentPath();
- stringListPairMap[*key].second += stringListValue;
- }
- else {
- locMap[*key] = keyLoc;
- stringPairMap[*key].first = QDir::currentPath();
- stringPairMap[*key].second = stringValue;
- stringListPairMap[*key].first = QDir::currentPath();
- stringListPairMap[*key].second = stringListValue;
- }
+ ConfigVarMultimap::Iterator i;
+ i = configVars_.insert(*key, ConfigVar(*key, rhsValues, QDir::currentPath(), keyLoc));
+ i.value().plus_ = (plus ? true : false);
++key;
}
}
@@ -1058,8 +1079,9 @@ void Config::load(Location location, const QString& fileName)
}
}
popWorkingDir();
- if (!workingDirs_.isEmpty())
- QDir::setCurrent(QFileInfo(workingDirs_.top()).path());
+ if (!workingDirs_.isEmpty()) {
+ QDir::setCurrent(workingDirs_.top());
+ }
}
QStringList Config::getFilesHere(const QString& uncleanDir,
@@ -1068,8 +1090,7 @@ QStringList Config::getFilesHere(const QString& uncleanDir,
const QSet<QString> &excludedDirs,
const QSet<QString> &excludedFiles)
{
- //
- QString dir = location.isEmpty() ? QDir::cleanPath(uncleanDir) : location.canonicalRelativePath(uncleanDir);
+ QString dir = location.isEmpty() ? QDir::cleanPath(uncleanDir) : Location::canonicalRelativePath(uncleanDir);
QStringList result;
if (excludedDirs.contains(dir))
return result;
diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h
index 521f1c12b8..c601cc062e 100644
--- a/src/tools/qdoc/config.h
+++ b/src/tools/qdoc/config.h
@@ -56,19 +56,29 @@
QT_BEGIN_NAMESPACE
/*
- In QStringPair, the first string is the path to a directory;
- the second string is some value.
+ This struct contains all the information for
+ one config variable found in a qdocconf file.
*/
-typedef QPair<QString, QString> QStringPair;
+struct ConfigVar {
+ bool plus_;
+ QString name_;
+ QStringList values_;
+ QString currentPath_;
+ Location location_;
+
+ ConfigVar() : plus_(false) { }
+
+ ConfigVar(const QString& name, const QStringList& values, const QString& dir)
+ : plus_(true), name_(name), values_(values), currentPath_(dir) { }
+
+ ConfigVar(const QString& name, const QStringList& values, const QString& dir, const Location& loc)
+ : plus_(false), name_(name), values_(values), currentPath_(dir), location_(loc) { }
+};
/*
- In QStringListPair, the first string is the path to a directory;
- the string list is a list of string values.
+ In this multimap, the key is a config variable name.
*/
-typedef QPair<QString, QStringList> QStringListPair;
-typedef QMultiMap<QString, QStringPair> QStringPairMultiMap;
-typedef QMap<QString, QStringPair> QStringPairMap;
-typedef QMap<QString, QStringListPair> QStringListPairMap;
+typedef QMultiMap<QString, ConfigVar> ConfigVarMultimap;
class Config
{
@@ -79,7 +89,6 @@ public:
~Config();
void load(const QString& fileName);
- void unload(const QString& fileName);
void setStringList(const QString& var, const QStringList& values);
const QString& programName() const { return prog; }
@@ -90,7 +99,6 @@ public:
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;
@@ -99,7 +107,7 @@ public:
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, QStringPairMap& t) const;
+ void subVarsAndValues(const QString& var, ConfigVarMultimap& t) const;
QStringList getAllFiles(const QString& filesVar,
const QString& dirsVar,
const QSet<QString> &excludedDirs = QSet<QString>(),
@@ -146,12 +154,7 @@ private:
QString prog;
Location loc;
Location lastLocation_;
- QMap<QString, Location> locMap;
- QMap<QString, QString> stringValueMap;
- QMap<QString, QStringList> stringListValueMap;
-
- QStringPairMap stringPairMap;
- QStringListPairMap stringListPairMap;
+ ConfigVarMultimap configVars_;
static QMap<QString, QString> uncompressedFiles;
static QMap<QString, QString> extractedDirs;
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index a828101551..314dda3a9d 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -5829,8 +5829,11 @@ bool DitaXmlGenerator::writeMetadataElements(const InnerNode* inner,
QString DitaXmlGenerator::getMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t)
{
QString s = Generator::getMetadataElement(inner, ditaTags[t]);
- if (s.isEmpty())
- s = metadataDefault(t);
+ if (s.isEmpty()) {
+ QStringList sl = metadataDefault(t);
+ if (!sl.isEmpty())
+ s = sl[0];
+ }
return s;
}
@@ -5850,7 +5853,7 @@ QStringList DitaXmlGenerator::getMetadataElements(const InnerNode* inner,
{
QStringList s = Generator::getMetadataElements(inner,ditaTags[t]);
if (s.isEmpty())
- s.append(metadataDefault(t));
+ s = metadataDefault(t);
return s;
}
@@ -5858,9 +5861,9 @@ QStringList DitaXmlGenerator::getMetadataElements(const InnerNode* inner,
Returns the value of key \a t or an empty string
if \a t is not found in the map.
*/
-QString DitaXmlGenerator::metadataDefault(DitaTag t) const
+QStringList DitaXmlGenerator::metadataDefault(DitaTag t) const
{
- return metadataDefaults.value(ditaTags[t]).second;
+ return metadataDefaults.value(ditaTags[t]).values_;
}
/*!
diff --git a/src/tools/qdoc/ditaxmlgenerator.h b/src/tools/qdoc/ditaxmlgenerator.h
index 15ef4260b2..a55ccf81c8 100644
--- a/src/tools/qdoc/ditaxmlgenerator.h
+++ b/src/tools/qdoc/ditaxmlgenerator.h
@@ -458,7 +458,7 @@ private:
int leaveSection();
bool inSection() const { return (sectionNestingLevel > 0); }
int currentSectionNestingLevel() const { return sectionNestingLevel; }
- QString metadataDefault(DitaTag t) const;
+ QStringList metadataDefault(DitaTag t) const;
QString stripMarkup(const QString& src) const;
Node* collectNodesByTypeAndSubtype(const InnerNode* parent);
void writeDitaRefs(const DitaRefList& ditarefs);
@@ -507,7 +507,7 @@ private:
static QString ditaTags[];
QStack<QXmlStreamWriter*> xmlWriterStack;
QStack<DitaTag> tagStack;
- QStringPairMap metadataDefaults;
+ ConfigVarMultimap metadataDefaults;
QVector<NodeMultiMap*> nodeTypeMaps;
QVector<NodeMultiMap*> nodeSubtypeMaps;
QVector<NodeMultiMap*> pageTypeMaps;
diff --git a/src/tools/qdoc/location.cpp b/src/tools/qdoc/location.cpp
index 86329b9190..91ee214aa1 100644
--- a/src/tools/qdoc/location.cpp
+++ b/src/tools/qdoc/location.cpp
@@ -229,15 +229,13 @@ QString Location::fileName() const
/*!
- * \brief Returns \a path which is canonicalized and relative to the config file.
- *
- * QDir::relativeFilePath does not canonicalize the paths, so
- * if the config file is located at qtbase\src\widgets\doc\qtwidgets.qdocconf
- * and it has a reference to any ancestor folder (e.g. ".." or even "../doc")
- * \param path
- * \return
+ \brief Returns \a path which is canonicalized and relative to the config file.
+
+ QDir::relativeFilePath does not canonicalize the paths, so
+ if the config file is located at qtbase\src\widgets\doc\qtwidgets.qdocconf
+ and it has a reference to any ancestor folder (e.g. ".." or even "../doc")
*/
-QString Location::canonicalRelativePath(const QString &path) const
+QString Location::canonicalRelativePath(const QString &path)
{
QDir configFileDir(QDir::current());
QDir dir(path);
@@ -245,6 +243,21 @@ QString Location::canonicalRelativePath(const QString &path) const
return configFileDir.relativeFilePath(canon);
}
+/*!
+ \brief Returns \a path which is canonicalized and relative to the \a configDir.
+
+ QDir::relativeFilePath does not canonicalize the paths, so
+ if the config file is located at qtbase\src\widgets\doc\qtwidgets.qdocconf
+ and it has a reference to any ancestor folder (e.g. ".." or even "../doc")
+ */
+QString Location::canonicalRelativePath(const QString &path, const QString &configDir)
+{
+ QDir configFileDir(configDir);
+ QDir dir(path);
+ const QString canon = dir.canonicalPath();
+ return configFileDir.relativeFilePath(canon);
+}
+
/*! \fn int Location::lineNo() const
Returns the current line number.
Must not be called on an empty Location object.
diff --git a/src/tools/qdoc/location.h b/src/tools/qdoc/location.h
index 20ddfd076e..4604358fe5 100644
--- a/src/tools/qdoc/location.h
+++ b/src/tools/qdoc/location.h
@@ -81,7 +81,6 @@ public:
int depth() const { return stkDepth; }
const QString& filePath() const { return stkTop->filePath; }
QString fileName() const;
- QString canonicalRelativePath(const QString &path) const;
int lineNo() const { return stkTop->lineNo; }
int columnNo() const { return stkTop->columnNo; }
bool etc() const { return etcetera; }
@@ -101,6 +100,8 @@ public:
static void logToStdErr(const QString& message);
static void startLoggingProgress() { logProgress_ = true; }
static void stopLoggingProgress() { logProgress_ = false; }
+ static QString canonicalRelativePath(const QString &path);
+ static QString canonicalRelativePath(const QString &path, const QString &configDir);
private:
enum MessageType { Warning, Error };