summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 };