summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMichael Brasser <michael.brasser@nokia.com>2009-09-29 04:09:01 (GMT)
committerMichael Brasser <michael.brasser@nokia.com>2009-09-29 04:09:01 (GMT)
commit575ad2c60482b279f828cfa87186b5fbb10f76c6 (patch)
tree101df52cd4b769dc8d10ef60714f25d819636e70 /tools
parenta913e326409062bbc1cad4d5898181c7b81cba23 (diff)
parent638f46a96b68d21137c4903c68015752ebdf58dc (diff)
downloadQt-575ad2c60482b279f828cfa87186b5fbb10f76c6.zip
Qt-575ad2c60482b279f828cfa87186b5fbb10f76c6.tar.gz
Qt-575ad2c60482b279f828cfa87186b5fbb10f76c6.tar.bz2
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into kinetic-declarativeui
Conflicts: configure.exe mkspecs/features/qt.prf
Diffstat (limited to 'tools')
-rw-r--r--tools/configure/configureapp.cpp2
-rw-r--r--tools/designer/src/lib/shared/qdesigner_menubar.cpp2
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertysheet.cpp11
-rw-r--r--tools/designer/src/lib/shared/qdesigner_utils_p.h1
-rw-r--r--tools/designer/translations/translations.pro2
-rw-r--r--tools/linguist/lconvert/main.cpp4
-rw-r--r--tools/linguist/linguist/linguist.pro3
-rw-r--r--tools/linguist/lupdate/cpp.cpp830
-rw-r--r--tools/linguist/lupdate/main.cpp33
-rw-r--r--tools/linguist/phrasebooks/russian.qph92
-rw-r--r--tools/qdoc3/atom.cpp2
-rw-r--r--tools/qdoc3/atom.h4
-rw-r--r--tools/qdoc3/doc.cpp23
-rw-r--r--tools/qdoc3/generator.cpp9
-rw-r--r--tools/qdoc3/htmlgenerator.cpp64
-rw-r--r--tools/qdoc3/htmlgenerator.h3
-rw-r--r--tools/qdoc3/main.cpp1
-rw-r--r--tools/qdoc3/test/macros.qdocconf5
-rw-r--r--tools/qdoc3/test/qt-build-docs.qdocconf2
-rw-r--r--tools/qdoc3/test/qt-cpp-ignore.qdocconf1
-rw-r--r--tools/qdoc3/test/qt.qdocconf2
-rw-r--r--tools/xmlpatternsvalidator/main.cpp87
-rw-r--r--tools/xmlpatternsvalidator/main.h2
23 files changed, 747 insertions, 438 deletions
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 3bbc607..afb2dec 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -1169,7 +1169,7 @@ void Configure::parseCmdLine()
dictionary["QTBUILDINSTRUCTION"] = dictionary["MAKE"];
if (dictionary.contains("XQMAKESPEC")) {
if (dictionary["XQMAKESPEC"].startsWith("symbian")) {
- dictionary["QTBUILDINSTRUCTION"] = dictionary["MAKE"] + QString(" debug-winscw|debug-armv5|release-armv5");
+ dictionary["QTBUILDINSTRUCTION"] = QString("make debug-winscw|debug-armv5|release-armv5");
} else if (dictionary["XQMAKESPEC"].startsWith("wince")) {
dictionary["QTBUILDINSTRUCTION"] =
QString("setcepaths.bat ") + dictionary["XQMAKESPEC"] + QString(" && ") + dictionary["MAKE"];
diff --git a/tools/designer/src/lib/shared/qdesigner_menubar.cpp b/tools/designer/src/lib/shared/qdesigner_menubar.cpp
index 6d231ca..80c7b53 100644
--- a/tools/designer/src/lib/shared/qdesigner_menubar.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_menubar.cpp
@@ -104,6 +104,8 @@ QDesignerMenuBar::QDesignerMenuBar(QWidget *parent) :
setContextMenuPolicy(Qt::DefaultContextMenu);
setAcceptDrops(true); // ### fake
+ // Fake property: Keep the menu bar editable in the form even if a native menu bar is used.
+ setNativeMenuBar(false);
m_addMenu->setText(tr("Type Here"));
addAction(m_addMenu);
diff --git a/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp b/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp
index 851bfc1..7574fdd 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp
@@ -63,6 +63,7 @@
#include <QtGui/QApplication>
#include <QtGui/QToolBar>
#include <QtGui/QMainWindow>
+#include <QtGui/QMenuBar>
QT_BEGIN_NAMESPACE
@@ -611,9 +612,15 @@ QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent)
createFakeProperty(QLatin1String("dragEnabled"));
// windowModality is visible only for the main container, in which case the form windows enables it on loading
setVisible(createFakeProperty(QLatin1String("windowModality")), false);
- if (qobject_cast<const QToolBar *>(d->m_object)) // prevent toolbars from being dragged off
+ if (qobject_cast<const QToolBar *>(d->m_object)) { // prevent toolbars from being dragged off
createFakeProperty(QLatin1String("floatable"), QVariant(true));
-
+ } else {
+ if (qobject_cast<const QMenuBar *>(d->m_object)) {
+ // Keep the menu bar editable in the form even if a native menu bar is used.
+ const bool nativeMenuBarDefault = !qApp->testAttribute(Qt::AA_DontUseNativeMenuBar);
+ createFakeProperty(QLatin1String("nativeMenuBar"), QVariant(nativeMenuBarDefault));
+ }
+ }
if (d->m_canHaveLayoutAttributes) {
static const QString layoutGroup = QLatin1String("Layout");
const char* fakeLayoutProperties[] = {
diff --git a/tools/designer/src/lib/shared/qdesigner_utils_p.h b/tools/designer/src/lib/shared/qdesigner_utils_p.h
index 0b9f925..a860b61 100644
--- a/tools/designer/src/lib/shared/qdesigner_utils_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_utils_p.h
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/tools/designer/translations/translations.pro b/tools/designer/translations/translations.pro
index 8395259..c8cd76d 100644
--- a/tools/designer/translations/translations.pro
+++ b/tools/designer/translations/translations.pro
@@ -133,7 +133,7 @@ HEADERS += ../../shared/findwidget/abstractfindwidget.h \
TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/designer_de.ts \
$$[QT_INSTALL_TRANSLATIONS]/designer_ja.ts \
$$[QT_INSTALL_TRANSLATIONS]/designer_pl.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/designer_ru.ts \
$$[QT_INSTALL_TRANSLATIONS]/designer_zh_CN.ts \
$$[QT_INSTALL_TRANSLATIONS]/designer_zh_TW.ts \
$$[QT_INSTALL_TRANSLATIONS]/designer_untranslated.ts
-
diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp
index fb869ec..67553a0 100644
--- a/tools/linguist/lconvert/main.cpp
+++ b/tools/linguist/lconvert/main.cpp
@@ -103,6 +103,8 @@ static int usage(const QStringList &args)
" Drop obsolete messages.\n\n"
" --no-finished\n"
" Drop finished messages.\n\n"
+ " --sort-contexts\n"
+ " Sort contexts in output TS file alphabetically.\n\n"
" --locations {absolute|relative|none}\n"
" Override how source code references are saved in TS files.\n"
" Default is absolute.\n\n"
@@ -201,6 +203,8 @@ int main(int argc, char *argv[])
noObsolete = true;
} else if (args[i] == QLatin1String("-no-finished")) {
noFinished = true;
+ } else if (args[i] == QLatin1String("-sort-contexts")) {
+ cd.m_sortContexts = true;
} else if (args[i] == QLatin1String("-locations")) {
if (++i >= args.size())
return usage(args);
diff --git a/tools/linguist/linguist/linguist.pro b/tools/linguist/linguist/linguist.pro
index 314163c..00ebec1 100644
--- a/tools/linguist/linguist/linguist.pro
+++ b/tools/linguist/linguist/linguist.pro
@@ -81,9 +81,6 @@ PROJECTNAME = Qt \
Linguist
target.path = $$[QT_INSTALL_BINS]
INSTALLS += target
-linguisttranslations.files = *.qm
-linguisttranslations.path = $$[QT_INSTALL_TRANSLATIONS]
-INSTALLS += linguisttranslations
phrasebooks.path = $$[QT_INSTALL_DATA]/phrasebooks
# ## will this work on windows?
diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp
index be86c93..ed41edb 100644
--- a/tools/linguist/lupdate/cpp.cpp
+++ b/tools/linguist/lupdate/cpp.cpp
@@ -43,6 +43,7 @@
#include <translator.h>
+#include <QtCore/QBitArray>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtCore/QStack>
@@ -56,74 +57,133 @@ QT_BEGIN_NAMESPACE
/* qmake ignore Q_OBJECT */
-static const char MagicComment[] = "TRANSLATOR ";
+static QString MagicComment(QLatin1String("TRANSLATOR"));
#define STRING(s) static QString str##s(QLatin1String(#s))
//#define DIAGNOSE_RETRANSLATABILITY // FIXME: should make a runtime option of this
-uint qHash(const QStringList &qsl)
+class HashString {
+public:
+ HashString() : m_hashed(false) {}
+ explicit HashString(const QString &str) : m_str(str), m_hashed(false) {}
+ void setValue(const QString &str) { m_str = str; m_hashed = false; }
+ const QString &value() const { return m_str; }
+ bool operator==(const HashString &other) const { return m_str == other.m_str; }
+private:
+ QString m_str;
+ mutable uint m_hash;
+ mutable bool m_hashed;
+ friend uint qHash(const HashString &str);
+};
+
+uint qHash(const HashString &str)
{
- uint hash = 0;
- foreach (const QString &qs, qsl) {
- hash ^= qHash(qs) ^ 0xa09df22f;
- hash = (hash << 13) | (hash >> 19);
+ if (!str.m_hashed) {
+ str.m_hashed = true;
+ str.m_hash = qHash(str.m_str);
+ }
+ return str.m_hash;
+}
+
+class HashStringList {
+public:
+ explicit HashStringList(const QList<HashString> &list) : m_list(list), m_hashed(false) {}
+ const QList<HashString> &value() const { return m_list; }
+ bool operator==(const HashStringList &other) const { return m_list == other.m_list; }
+private:
+ QList<HashString> m_list;
+ mutable uint m_hash;
+ mutable bool m_hashed;
+ friend uint qHash(const HashStringList &list);
+};
+
+uint qHash(const HashStringList &list)
+{
+ if (!list.m_hashed) {
+ list.m_hashed = true;
+ uint hash = 0;
+ foreach (const HashString &qs, list.m_list) {
+ hash ^= qHash(qs) ^ 0xa09df22f;
+ hash = (hash << 13) | (hash >> 19);
+ }
+ list.m_hash = hash;
}
- return hash;
+ return list.m_hash;
}
+typedef QList<HashString> NamespaceList;
+
struct Namespace {
Namespace() :
- isClass(false),
- hasTrFunctions(false), needsTrFunctions(false), complained(false)
+ classDef(this),
+ hasTrFunctions(false), complained(false)
{}
+ ~Namespace()
+ {
+ qDeleteAll(children);
+ }
- QString name;
- QMap<QString, Namespace *> children;
- QMap<QString, QStringList> aliases;
- QSet<QStringList> usings;
+ QHash<HashString, Namespace *> children;
+ QHash<HashString, NamespaceList> aliases;
+ QList<HashStringList> usings;
- int fileId;
+ // Class declarations set no flags and create no namespaces, so they are ignored.
+ // Class definitions may appear multiple times - but only because we are trying to
+ // "compile" all sources irrespective of build configuration.
+ // Nested classes may be forward-declared inside a definition, and defined in another file.
+ // The latter will detach the class' child list, so clones need a backlink to the original
+ // definition (either one in case of multiple definitions).
+ Namespace *classDef;
- bool isClass;
+ QString trQualification;
bool hasTrFunctions;
- bool needsTrFunctions;
bool complained; // ... that tr functions are missing.
};
-typedef QList<Namespace *> NamespaceList;
+static int nextFileId;
-struct ParseResults {
-
- ParseResults()
+class VisitRecorder {
+public:
+ VisitRecorder()
{
- static int nextFileId;
- rootNamespace.fileId = nextFileId++;
- tor = 0;
+ m_ba.resize(nextFileId);
}
- bool detachNamespace(Namespace **that);
- Namespace *include(Namespace *that, const Namespace *other);
- void unite(const ParseResults *other);
+ bool tryVisit(int fileId)
+ {
+ if (m_ba.at(fileId))
+ return false;
+ m_ba[fileId] = true;
+ return true;
+ }
+private:
+ QBitArray m_ba;
+};
+struct ParseResults {
+ int fileId;
Namespace rootNamespace;
- Translator *tor;
- QSet<QString> allIncludes;
+ QSet<const ParseResults *> includes;
};
typedef QHash<QString, const ParseResults *> ParseResultHash;
+typedef QHash<QString, const Translator *> TranslatorHash;
class CppFiles {
public:
static const ParseResults *getResults(const QString &cleanFile);
static void setResults(const QString &cleanFile, const ParseResults *results);
+ static const Translator *getTranslator(const QString &cleanFile);
+ static void setTranslator(const QString &cleanFile, const Translator *results);
static bool isBlacklisted(const QString &cleanFile);
static void setBlacklisted(const QString &cleanFile);
private:
static ParseResultHash &parsedFiles();
+ static TranslatorHash &translatedFiles();
static QSet<QString> &blacklistedFiles();
};
@@ -133,16 +193,16 @@ public:
CppParser(ParseResults *results = 0);
void setInput(const QString &in);
void setInput(QTextStream &ts, const QString &fileName);
- void setTranslator(Translator *tor) { results->tor = tor; }
+ void setTranslator(Translator *_tor) { tor = _tor; }
void parse(const QString &initialContext, ConversionData &cd, QSet<QString> &inclusions);
void parseInternal(ConversionData &cd, QSet<QString> &inclusions);
- const ParseResults *getResults() const { return results; }
+ const ParseResults *recordResults(bool isHeader);
void deleteResults() { delete results; }
struct SavedState {
- QStringList namespaces;
+ NamespaceList namespaces;
QStack<int> namespaceDepths;
- QStringList functionContext;
+ NamespaceList functionContext;
QString functionContextUnresolved;
QString pendingContext;
};
@@ -164,10 +224,10 @@ private:
uint getChar();
uint getToken();
+ bool getMacroArgs();
bool match(uint t);
bool matchString(QString *s);
bool matchEncoding(bool *utf8);
- bool matchInteger(qlonglong *number);
bool matchStringOrNull(QString *s);
bool matchExpression();
@@ -185,15 +245,28 @@ private:
static QString stringifyNamespace(const NamespaceList &namespaces);
static QStringList stringListifyNamespace(const NamespaceList &namespaces);
- void modifyNamespace(NamespaceList *namespaces);
- NamespaceList resolveNamespaces(const QStringList &segments);
- bool qualifyOne(const NamespaceList &namespaces, int nsIdx, const QString &segment,
- NamespaceList *resolved);
- bool fullyQualify(const NamespaceList &namespaces, const QStringList &segments,
+ typedef bool (CppParser::*VisitNamespaceCallback)(const Namespace *ns, void *context) const;
+ bool visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context,
+ VisitRecorder &vr, const ParseResults *rslt) const;
+ bool visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context) const;
+ static QStringList stringListifySegments(const QList<HashString> &namespaces);
+ bool qualifyOneCallbackOwn(const Namespace *ns, void *context) const;
+ bool qualifyOneCallbackUsing(const Namespace *ns, void *context) const;
+ bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
+ NamespaceList *resolved) const;
+ bool fullyQualify(const NamespaceList &namespaces, const QList<HashString> &segments,
+ bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const;
+ bool fullyQualify(const NamespaceList &namespaces, const QString &segments,
bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved);
- void enterNamespace(NamespaceList *namespaces, const QString &name);
+ NamespaceList *resolved, QStringList *unresolved) const;
+ bool findNamespaceCallback(const Namespace *ns, void *context) const;
+ const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const;
+ void enterNamespace(NamespaceList *namespaces, const HashString &name);
void truncateNamespaces(NamespaceList *namespaces, int lenght);
+ Namespace *modifyNamespace(NamespaceList *namespaces, bool tryOrigin = true);
enum {
Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return,
@@ -202,7 +275,7 @@ private:
Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon,
Tok_Equals,
Tok_LeftBrace = 30, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon,
- Tok_Integer = 40,
+ Tok_Null = 40, Tok_Integer,
Tok_QuotedInclude = 50, Tok_AngledInclude,
Tok_Other = 99
};
@@ -227,7 +300,7 @@ private:
QTextCodec *yySourceCodec;
bool yySourceIsUnicode;
QString yyInStr;
- int yyInPos;
+ const ushort *yyInPtr;
// Parser state
uint yyTok;
@@ -239,6 +312,7 @@ private:
QString prospectiveContext;
QString pendingContext;
ParseResults *results;
+ Translator *tor;
bool directInclude;
SavedState savedState;
@@ -248,6 +322,7 @@ private:
CppParser::CppParser(ParseResults *_results)
{
+ tor = 0;
if (_results) {
results = _results;
directInclude = true;
@@ -255,7 +330,6 @@ CppParser::CppParser(ParseResults *_results)
results = new ParseResults;
directInclude = false;
}
- yyInPos = 0;
yyBraceDepth = 0;
yyParenDepth = 0;
yyCurLineNo = 1;
@@ -308,29 +382,32 @@ void CppParser::setInput(QTextStream &ts, const QString &fileName)
uint CppParser::getChar()
{
- int len = yyInStr.size();
- const ushort *uc = (const ushort *)yyInStr.unicode();
+ const ushort *uc = yyInPtr;
forever {
- if (yyInPos >= len)
+ ushort c = *uc;
+ if (!c) {
+ yyInPtr = uc;
return EOF;
- uint c = uc[yyInPos++];
- if (c == '\\' && yyInPos < len) {
- if (uc[yyInPos] == '\n') {
+ }
+ ++uc;
+ if (c == '\\') {
+ ushort cc = *uc;
+ if (cc == '\n') {
++yyCurLineNo;
- ++yyInPos;
+ ++uc;
continue;
}
- if (uc[yyInPos] == '\r') {
+ if (cc == '\r') {
++yyCurLineNo;
- ++yyInPos;
- if (yyInPos < len && uc[yyInPos] == '\n')
- ++yyInPos;
+ ++uc;
+ if (*uc == '\n')
+ ++uc;
continue;
}
}
if (c == '\r') {
- if (yyInPos < len && uc[yyInPos] == '\n')
- ++yyInPos;
+ if (*uc == '\n')
+ ++uc;
c = '\n';
++yyCurLineNo;
yyAtNewline = true;
@@ -340,10 +417,39 @@ uint CppParser::getChar()
} else if (c != ' ' && c != '\t' && c != '#') {
yyAtNewline = false;
}
+ yyInPtr = uc;
return c;
}
}
+// This ignores commas, parens and comments.
+// IOW, it understands only a single, simple argument.
+bool CppParser::getMacroArgs()
+{
+ // Failing this assertion would mean losing the preallocated buffer.
+ Q_ASSERT(yyWord.isDetached());
+ yyWord.resize(0);
+
+ while (isspace(yyCh))
+ yyCh = getChar();
+ if (yyCh != '(')
+ return false;
+ do {
+ yyCh = getChar();
+ } while (isspace(yyCh));
+ ushort *ptr = (ushort *)yyWord.unicode();
+ while (yyCh != ')') {
+ if (yyCh == EOF)
+ return false;
+ *ptr++ = yyCh;
+ yyCh = getChar();
+ }
+ yyCh = getChar();
+ for (; ptr != (ushort *)yyWord.unicode() && isspace(*(ptr - 1)); --ptr) ;
+ yyWord.resize(ptr - (ushort *)yyWord.unicode());
+ return true;
+}
+
STRING(Q_OBJECT);
STRING(Q_DECLARE_TR_FUNCTIONS);
STRING(QT_TR_NOOP);
@@ -561,12 +667,13 @@ uint CppParser::getToken()
}
} while (yyCh != '\n' && yyCh != EOF);
yyCh = getChar();
- } else if (isalpha(yyCh) || yyCh == '_') {
+ } else if ((yyCh >= 'A' && yyCh <= 'Z') || (yyCh >= 'a' && yyCh <= 'z') || yyCh == '_') {
ushort *ptr = (ushort *)yyWord.unicode();
do {
*ptr++ = yyCh;
yyCh = getChar();
- } while (isalnum(yyCh) || yyCh == '_');
+ } while ((yyCh >= 'A' && yyCh <= 'Z') || (yyCh >= 'a' && yyCh <= 'z')
+ || (yyCh >= '0' && yyCh <= '9') || yyCh == '_');
yyWord.resize(ptr - (ushort *)yyWord.unicode());
//qDebug() << "IDENT: " << yyWord;
@@ -795,6 +902,17 @@ uint CppParser::getToken()
yyCh = getChar();
return Tok_Semicolon;
case '0':
+ yyCh = getChar();
+ if (yyCh == 'x') {
+ do {
+ yyCh = getChar();
+ } while ((yyCh >= '0' && yyCh <= '9')
+ || (yyCh >= 'a' && yyCh <= 'f') || (yyCh >= 'A' && yyCh <= 'F'));
+ return Tok_Integer;
+ }
+ if (yyCh < '0' || yyCh > '9')
+ return Tok_Null;
+ // Fallthrough
case '1':
case '2':
case '3':
@@ -804,25 +922,10 @@ uint CppParser::getToken()
case '7':
case '8':
case '9':
- {
- QByteArray ba;
- ba += yyCh;
+ do {
yyCh = getChar();
- bool hex = yyCh == 'x';
- if (hex) {
- ba += yyCh;
- yyCh = getChar();
- }
- while (hex ? isxdigit(yyCh) : isdigit(yyCh)) {
- ba += yyCh;
- yyCh = getChar();
- }
- bool ok;
- yyInteger = ba.toLongLong(&ok);
- if (ok)
- return Tok_Integer;
- break;
- }
+ } while (yyCh >= '0' && yyCh <= '9');
+ return Tok_Integer;
default:
yyCh = getChar();
break;
@@ -839,86 +942,40 @@ uint CppParser::getToken()
void CppParser::saveState(SavedState *state)
{
- state->namespaces = stringListifyNamespace(namespaces);
+ state->namespaces = namespaces;
state->namespaceDepths = namespaceDepths;
- state->functionContext = stringListifyNamespace(functionContext);
+ state->functionContext = functionContext;
state->functionContextUnresolved = functionContextUnresolved;
state->pendingContext = pendingContext;
}
void CppParser::loadState(const SavedState *state)
{
- namespaces = resolveNamespaces(state->namespaces);
+ namespaces = state->namespaces;
namespaceDepths = state->namespaceDepths;
- functionContext = resolveNamespaces(state->functionContext);
+ functionContext = state->functionContext;
functionContextUnresolved = state->functionContextUnresolved;
pendingContext = state->pendingContext;
}
-bool ParseResults::detachNamespace(Namespace **that)
+Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool tryOrigin)
{
- if ((*that)->fileId != rootNamespace.fileId) {
- Namespace *newThat = new Namespace;
- *newThat = **that;
- newThat->fileId = rootNamespace.fileId;
- *that = newThat;
- return true;
- }
- return false;
-}
-
-Namespace *ParseResults::include(Namespace *that, const Namespace *other)
-{
- Namespace *origThat = that;
- foreach (Namespace *otherSub, other->children) {
- if (Namespace *thisSub = that->children.value(otherSub->name)) {
- // Don't make these cause a detach - it's best
- // (though not necessary) if they are shared
- thisSub->isClass |= otherSub->isClass;
- thisSub->hasTrFunctions |= otherSub->hasTrFunctions;
- thisSub->needsTrFunctions |= otherSub->needsTrFunctions;
- thisSub->complained |= otherSub->complained;
-
- if (Namespace *newSub = include(thisSub, otherSub)) {
- thisSub = newSub;
- detachNamespace(&that);
- that->children[thisSub->name] = thisSub;
- }
- } else {
- detachNamespace(&that);
- that->children[otherSub->name] = otherSub;
- }
- }
- if ((that->aliases != other->aliases && !other->aliases.isEmpty())
- || (that->usings != other->usings && !other->usings.isEmpty())) {
- detachNamespace(&that);
- that->aliases.unite(other->aliases);
- that->usings.unite(other->usings);
- }
- return (that != origThat) ? that : 0;
-}
-
-void ParseResults::unite(const ParseResults *other)
-{
- allIncludes.unite(other->allIncludes);
- include(&rootNamespace, &other->rootNamespace);
-}
-
-void CppParser::modifyNamespace(NamespaceList *namespaces)
-{
- Namespace *pns = 0;
- int i = namespaces->count();
- forever {
- --i;
- Namespace *ns = namespaces->at(i);
- bool detached = results->detachNamespace(&ns);
- if (pns)
- ns->children[pns->name] = pns;
- if (!detached) // Known to be true for root namespace
- return;
+ Namespace *pns, *ns = &results->rootNamespace;
+ for (int i = 1; i < namespaces->count(); ++i) {
pns = ns;
- namespaces->replace(i, ns);
+ if (!(ns = pns->children.value(namespaces->at(i)))) {
+ do {
+ ns = new Namespace;
+ if (tryOrigin)
+ if (const Namespace *ons = findNamespace(*namespaces, i + 1))
+ ns->classDef = ons->classDef;
+ pns->children.insert(namespaces->at(i), ns);
+ pns = ns;
+ } while (++i < namespaces->count());
+ break;
+ }
}
+ return ns;
}
QString CppParser::stringifyNamespace(const NamespaceList &namespaces)
@@ -927,7 +984,7 @@ QString CppParser::stringifyNamespace(const NamespaceList &namespaces)
for (int i = 1; i < namespaces.count(); ++i) {
if (i > 1)
ret += QLatin1String("::");
- ret += namespaces.at(i)->name;
+ ret += namespaces.at(i).value();
}
return ret;
}
@@ -936,58 +993,102 @@ QStringList CppParser::stringListifyNamespace(const NamespaceList &namespaces)
{
QStringList ret;
for (int i = 1; i < namespaces.count(); ++i)
- ret << namespaces.at(i)->name;
+ ret << namespaces.at(i).value();
return ret;
}
-// This function is called only with known-existing namespaces
-NamespaceList CppParser::resolveNamespaces(const QStringList &segments)
+bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context,
+ VisitRecorder &vr, const ParseResults *rslt) const
{
- NamespaceList ret;
- Namespace *ns = &results->rootNamespace;
- ret << ns;
- foreach (const QString &seg, segments) {
- ns = ns->children.value(seg);
- ret << ns;
- }
+ const Namespace *ns = &rslt->rootNamespace;
+ for (int i = 1; i < nsCount; ++i)
+ if (!(ns = ns->children.value(namespaces.at(i))))
+ goto supers;
+ if ((this->*callback)(ns, context))
+ return true;
+supers:
+ foreach (const ParseResults *sup, rslt->includes)
+ if (vr.tryVisit(sup->fileId)
+ && visitNamespace(namespaces, nsCount, callback, context, vr, sup))
+ return true;
+ return false;
+}
+
+bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount,
+ VisitNamespaceCallback callback, void *context) const
+{
+ VisitRecorder vr;
+ return visitNamespace(namespaces, nsCount, callback, context, vr, results);
+}
+
+QStringList CppParser::stringListifySegments(const QList<HashString> &segments)
+{
+ QStringList ret;
+ for (int i = 0; i < segments.count(); ++i)
+ ret << segments.at(i).value();
return ret;
}
-bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsIdx, const QString &segment,
- NamespaceList *resolved)
+struct QualifyOneData {
+ const NamespaceList &namespaces;
+ int nsCount;
+ const HashString &segment;
+ NamespaceList *resolved;
+ QSet<HashStringList> visitedUsings;
+};
+
+bool CppParser::qualifyOneCallbackOwn(const Namespace *ns, void *context) const
{
- const Namespace *ns = namespaces.at(nsIdx);
- QMap<QString, Namespace *>::ConstIterator cnsi = ns->children.constFind(segment);
- if (cnsi != ns->children.constEnd()) {
- *resolved = namespaces.mid(0, nsIdx + 1);
- *resolved << *cnsi;
+ QualifyOneData *data = (QualifyOneData *)context;
+ if (ns->children.contains(data->segment)) {
+ *data->resolved = data->namespaces.mid(0, data->nsCount);
+ *data->resolved << data->segment;
return true;
}
- QMap<QString, QStringList>::ConstIterator nsai = ns->aliases.constFind(segment);
+ QHash<HashString, NamespaceList>::ConstIterator nsai = ns->aliases.constFind(data->segment);
if (nsai != ns->aliases.constEnd()) {
- *resolved = resolveNamespaces(*nsai);
+ *data->resolved = *nsai;
return true;
}
- foreach (const QStringList &use, ns->usings) {
- NamespaceList usedNs = resolveNamespaces(use);
- if (qualifyOne(usedNs, usedNs.count() - 1, segment, resolved))
- return true;
- }
return false;
}
-bool CppParser::fullyQualify(const NamespaceList &namespaces, const QStringList &segments,
+bool CppParser::qualifyOneCallbackUsing(const Namespace *ns, void *context) const
+{
+ QualifyOneData *data = (QualifyOneData *)context;
+ foreach (const HashStringList &use, ns->usings)
+ if (!data->visitedUsings.contains(use)) {
+ data->visitedUsings.insert(use);
+ if (qualifyOne(use.value(), use.value().count(), data->segment, data->resolved))
+ return true;
+ }
+ return false;
+}
+
+bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
+ NamespaceList *resolved) const
+{
+ QualifyOneData data = { namespaces, nsCnt, segment, resolved, QSet<HashStringList>() };
+
+ if (visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackOwn, &data))
+ return true;
+
+ return visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackUsing, &data);
+}
+
+bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList<HashString> &segments,
bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved)
+ NamespaceList *resolved, QStringList *unresolved) const
{
int nsIdx;
int initSegIdx;
- if (segments.first().isEmpty()) {
+ if (segments.first().value().isEmpty()) {
// fully qualified
if (segments.count() == 1) {
resolved->clear();
- *resolved << &results->rootNamespace;
+ *resolved << HashString(QString());
return true;
}
initSegIdx = 1;
@@ -998,12 +1099,12 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QStringList
}
do {
- if (qualifyOne(namespaces, nsIdx, segments[initSegIdx], resolved)) {
+ if (qualifyOne(namespaces, nsIdx + 1, segments[initSegIdx], resolved)) {
int segIdx = initSegIdx;
while (++segIdx < segments.count()) {
- if (!qualifyOne(*resolved, resolved->count() - 1, segments[segIdx], resolved)) {
+ if (!qualifyOne(*resolved, resolved->count(), segments[segIdx], resolved)) {
if (unresolved)
- *unresolved = segments.mid(segIdx);
+ *unresolved = stringListifySegments(segments.mid(segIdx));
return false;
}
}
@@ -1011,23 +1112,44 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QStringList
}
} while (!isDeclaration && --nsIdx >= 0);
resolved->clear();
- *resolved << &results->rootNamespace;
+ *resolved << HashString(QString());
if (unresolved)
- *unresolved = segments.mid(initSegIdx);
+ *unresolved = stringListifySegments(segments.mid(initSegIdx));
return false;
}
-void CppParser::enterNamespace(NamespaceList *namespaces, const QString &name)
+bool CppParser::fullyQualify(const NamespaceList &namespaces, const QString &quali,
+ bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const
{
- Namespace *ns = namespaces->last()->children.value(name);
- if (!ns) {
- ns = new Namespace;
- ns->fileId = results->rootNamespace.fileId;
- ns->name = name;
- modifyNamespace(namespaces);
- namespaces->last()->children[name] = ns;
- }
- *namespaces << ns;
+ static QString strColons(QLatin1String("::"));
+
+ QList<HashString> segments;
+ foreach (const QString &str, quali.split(strColons)) // XXX slow, but needs to be fast(?)
+ segments << HashString(str);
+ return fullyQualify(namespaces, segments, isDeclaration, resolved, unresolved);
+}
+
+bool CppParser::findNamespaceCallback(const Namespace *ns, void *context) const
+{
+ *((const Namespace **)context) = ns;
+ return true;
+}
+
+const Namespace *CppParser::findNamespace(const NamespaceList &namespaces, int nsCount) const
+{
+ const Namespace *ns = 0;
+ if (nsCount == -1)
+ nsCount = namespaces.count();
+ visitNamespace(namespaces, nsCount, &CppParser::findNamespaceCallback, &ns);
+ return ns;
+}
+
+void CppParser::enterNamespace(NamespaceList *namespaces, const HashString &name)
+{
+ *namespaces << name;
+ if (!findNamespace(*namespaces))
+ modifyNamespace(namespaces, false);
}
void CppParser::truncateNamespaces(NamespaceList *namespaces, int length)
@@ -1047,6 +1169,13 @@ ParseResultHash &CppFiles::parsedFiles()
return parsed;
}
+TranslatorHash &CppFiles::translatedFiles()
+{
+ static TranslatorHash tors;
+
+ return tors;
+}
+
QSet<QString> &CppFiles::blacklistedFiles()
{
static QSet<QString> blacklisted;
@@ -1056,10 +1185,7 @@ QSet<QString> &CppFiles::blacklistedFiles()
const ParseResults *CppFiles::getResults(const QString &cleanFile)
{
- ParseResultHash::ConstIterator it = parsedFiles().find(cleanFile);
- if (it == parsedFiles().constEnd())
- return 0;
- return *it;
+ return parsedFiles().value(cleanFile);
}
void CppFiles::setResults(const QString &cleanFile, const ParseResults *results)
@@ -1067,6 +1193,16 @@ void CppFiles::setResults(const QString &cleanFile, const ParseResults *results)
parsedFiles().insert(cleanFile, results);
}
+const Translator *CppFiles::getTranslator(const QString &cleanFile)
+{
+ return translatedFiles().value(cleanFile);
+}
+
+void CppFiles::setTranslator(const QString &cleanFile, const Translator *tor)
+{
+ translatedFiles().insert(cleanFile, tor);
+}
+
bool CppFiles::isBlacklisted(const QString &cleanFile)
{
return blacklistedFiles().contains(cleanFile);
@@ -1077,6 +1213,12 @@ void CppFiles::setBlacklisted(const QString &cleanFile)
blacklistedFiles().insert(cleanFile);
}
+static bool isHeader(const QString &name)
+{
+ QString fileExt = QFileInfo(name).suffix();
+ return fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive);
+}
+
void CppParser::processInclude(const QString &file, ConversionData &cd,
QSet<QString> &inclusions)
{
@@ -1095,21 +1237,15 @@ void CppParser::processInclude(const QString &file, ConversionData &cd,
bool isIndirect = false;
if (namespaces.count() == 1 && functionContext.count() == 1
&& functionContextUnresolved.isEmpty() && pendingContext.isEmpty()
- && !CppFiles::isBlacklisted(cleanFile)) {
- QString fileExt = QFileInfo(cleanFile).suffix();
- if (fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive)) {
-
- if (results->allIncludes.contains(cleanFile))
- return;
- results->allIncludes.insert(cleanFile);
+ && !CppFiles::isBlacklisted(cleanFile)
+ && isHeader(cleanFile)) {
- if (const ParseResults *res = CppFiles::getResults(cleanFile)) {
- results->unite(res);
- return;
- }
-
- isIndirect = true;
+ if (const ParseResults *res = CppFiles::getResults(cleanFile)) {
+ results->includes.insert(res);
+ return;
}
+
+ isIndirect = true;
}
QFile f(cleanFile);
@@ -1134,8 +1270,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd,
}
parser.setInput(ts, cleanFile);
parser.parse(cd.m_defaultContext, cd, inclusions);
- CppFiles::setResults(cleanFile, parser.getResults());
- results->unite(parser.results);
+ results->includes.insert(parser.recordResults(true));
} else {
CppParser parser(results);
parser.namespaces = namespaces;
@@ -1144,12 +1279,6 @@ void CppParser::processInclude(const QString &file, ConversionData &cd,
parser.pendingContext = pendingContext;
parser.setInput(ts, cleanFile);
parser.parseInternal(cd, inclusions);
- // Don't wreak havoc if not enough braces were found.
- truncateNamespaces(&parser.namespaces, namespaces.count());
- truncateNamespaces(&parser.functionContext, functionContext.count());
- // Copy them back - the pointers might have changed.
- namespaces = parser.namespaces;
- functionContext = parser.functionContext;
// Avoid that messages obtained by direct scanning are used
CppFiles::setBlacklisted(cleanFile);
}
@@ -1176,26 +1305,28 @@ bool CppParser::match(uint t)
bool CppParser::matchString(QString *s)
{
- bool matches = (yyTok == Tok_String);
+ bool matches = false;
s->clear();
- while (yyTok == Tok_String) {
+ forever {
+ while (yyTok == Tok_Comment)
+ yyTok = getToken();
+ if (yyTok != Tok_String)
+ return matches;
+ matches = true;
*s += yyWord;
s->detach();
- do {
- yyTok = getToken();
- } while (yyTok == Tok_Comment);
+ yyTok = getToken();
}
- return matches;
}
+STRING(QApplication);
+STRING(QCoreApplication);
+STRING(UnicodeUTF8);
+STRING(DefaultCodec);
+STRING(CodecForTr);
+
bool CppParser::matchEncoding(bool *utf8)
{
- STRING(QApplication);
- STRING(QCoreApplication);
- STRING(UnicodeUTF8);
- STRING(DefaultCodec);
- STRING(CodecForTr);
-
if (yyTok != Tok_Ident)
return false;
if (yyWord == strQApplication || yyWord == strQCoreApplication) {
@@ -1211,28 +1342,14 @@ bool CppParser::matchEncoding(bool *utf8)
if (yyWord == strDefaultCodec || yyWord == strCodecForTr) {
*utf8 = false;
yyTok = getToken();
- return true;
+ return true;
}
return false;
}
-bool CppParser::matchInteger(qlonglong *number)
-{
- bool matches = (yyTok == Tok_Integer);
- if (matches) {
- yyTok = getToken();
- *number = yyInteger;
- }
- return matches;
-}
-
bool CppParser::matchStringOrNull(QString *s)
{
- bool matches = matchString(s);
- qlonglong num = 0;
- if (!matches)
- matches = matchInteger(&num);
- return matches && num == 0;
+ return matchString(s) || match(Tok_Null);
}
/*
@@ -1251,7 +1368,7 @@ bool CppParser::matchStringOrNull(QString *s)
*/
bool CppParser::matchExpression()
{
- if (match(Tok_Integer))
+ if (match(Tok_Null) || match(Tok_Integer))
return true;
int parenlevel = 0;
@@ -1339,16 +1456,16 @@ void CppParser::recordMessage(
msg.setExtras(extra);
if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit())
msg.setUtf8(true);
- results->tor->append(msg);
+ tor->append(msg);
}
void CppParser::parse(const QString &initialContext, ConversionData &cd,
QSet<QString> &inclusions)
{
- if (results->tor)
- yyCodecIsUtf8 = (results->tor->codecName() == "UTF-8");
+ if (tor)
+ yyCodecIsUtf8 = (tor->codecName() == "UTF-8");
- namespaces << &results->rootNamespace;
+ namespaces << HashString();
functionContext = namespaces;
functionContextUnresolved = initialContext;
@@ -1375,6 +1492,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
bool yyTokColonSeen = false; // Start of c'tor's initializer list
yyWord.reserve(yyInStr.size()); // Rather insane. That's because we do no length checking.
+ yyInPtr = (const ushort *)yyInStr.unicode();
yyCh = getChar();
yyTok = getToken();
while (yyTok != Tok_Eof) {
@@ -1411,8 +1529,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
case Tok_friend:
yyTok = getToken();
- // Ensure that these don't end up being interpreted as forward declarations
- // (they are forwards, but with different namespacing).
+ // These are forward declarations, so ignore them.
if (yyTok == Tok_class)
yyTok = getToken();
break;
@@ -1423,7 +1540,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
*/
yyTok = getToken();
if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) {
- QStringList fct;
+ QList<HashString> quali;
+ HashString fct;
do {
/*
This code should execute only once, but we play
@@ -1433,50 +1551,50 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
*/
text = yyWord;
text.detach();
- fct = QStringList(text);
+ fct.setValue(text);
yyTok = getToken();
} while (yyTok == Tok_Ident);
while (yyTok == Tok_ColonColon) {
yyTok = getToken();
if (yyTok != Tok_Ident)
break; // Oops ...
+ quali << fct;
text = yyWord;
text.detach();
- fct += text;
+ fct.setValue(text);
yyTok = getToken();
}
- if (fct.count() > 1) {
- // Forward-declared class definitions can be namespaced
- NamespaceList nsl;
- if (!fullyQualify(namespaces, fct, true, &nsl, 0)) {
- qWarning("%s:%d: Ignoring definition of undeclared qualified class\n",
- qPrintable(yyFileName), yyLineNo);
- break;
- }
- namespaceDepths.push(namespaces.count());
- namespaces = nsl;
- } else {
- namespaceDepths.push(namespaces.count());
- enterNamespace(&namespaces, fct.first());
- }
- namespaces.last()->isClass = true;
-
while (yyTok == Tok_Comment)
yyTok = getToken();
if (yyTok == Tok_Colon) {
- // Skip any token until '{' since lupdate might do things wrong if it finds
+ // Skip any token until '{' since we might do things wrong if we find
// a '::' token here.
do {
yyTok = getToken();
} while (yyTok != Tok_LeftBrace && yyTok != Tok_Eof);
} else {
if (yyTok != Tok_LeftBrace) {
- // Obviously a forward decl
- truncateNamespaces(&namespaces, namespaceDepths.pop());
+ // Obviously a forward declaration. We skip those, as they
+ // don't create actually usable namespaces.
break;
}
}
+ if (!quali.isEmpty()) {
+ // Forward-declared class definitions can be namespaced.
+ NamespaceList nsl;
+ if (!fullyQualify(namespaces, quali, true, &nsl, 0)) {
+ qWarning("%s:%d: Ignoring definition of undeclared qualified class\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ namespaceDepths.push(namespaces.count());
+ namespaces = nsl;
+ } else {
+ namespaceDepths.push(namespaces.count());
+ }
+ enterNamespace(&namespaces, fct);
+
functionContext = namespaces;
functionContextUnresolved.clear(); // Pointless
prospectiveContext.clear();
@@ -1487,8 +1605,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
yyTokColonSeen = false;
yyTok = getToken();
if (yyTok == Tok_Ident) {
- QString ns = yyWord;
- ns.detach();
+ text = yyWord;
+ text.detach();
+ HashString ns = HashString(text);
yyTok = getToken();
if (yyTok == Tok_LeftBrace) {
namespaceDepths.push(namespaces.count());
@@ -1496,25 +1615,23 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
yyTok = getToken();
} else if (yyTok == Tok_Equals) {
// e.g. namespace Is = OuterSpace::InnerSpace;
- QStringList fullName;
+ QList<HashString> fullName;
yyTok = getToken();
if (yyTok == Tok_ColonColon)
- fullName.append(QString());
+ fullName.append(HashString(QString()));
while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
if (yyTok == Tok_Ident) {
text = yyWord;
text.detach();
- fullName.append(text);
+ fullName.append(HashString(text));
}
yyTok = getToken();
}
if (fullName.isEmpty())
break;
NamespaceList nsl;
- if (fullyQualify(namespaces, fullName, false, &nsl, 0)) {
- modifyNamespace(&namespaces);
- namespaces.last()->aliases.insert(ns, stringListifyNamespace(nsl));
- }
+ if (fullyQualify(namespaces, fullName, false, &nsl, 0))
+ modifyNamespace(&namespaces, false)->aliases[ns] = nsl;
}
} else if (yyTok == Tok_LeftBrace) {
// Anonymous namespace
@@ -1524,49 +1641,45 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
break;
case Tok_using:
yyTok = getToken();
+ // XXX this should affect only the current scope, not the entire current namespace
if (yyTok == Tok_namespace) {
- QStringList fullName;
+ QList<HashString> fullName;
yyTok = getToken();
if (yyTok == Tok_ColonColon)
- fullName.append(QString());
+ fullName.append(HashString(QString()));
while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
if (yyTok == Tok_Ident) {
text = yyWord;
text.detach();
- fullName.append(text);
+ fullName.append(HashString(text));
}
yyTok = getToken();
}
NamespaceList nsl;
- QStringList unresolved;
- if (fullyQualify(namespaces, fullName, false, &nsl, &unresolved)) {
- modifyNamespace(&namespaces);
- namespaces.last()->usings.insert(stringListifyNamespace(nsl));
- }
+ if (fullyQualify(namespaces, fullName, false, &nsl, 0))
+ modifyNamespace(&namespaces, false)->usings << HashStringList(nsl);
} else {
- QStringList fullName;
+ QList<HashString> fullName;
if (yyTok == Tok_ColonColon)
- fullName.append(QString());
+ fullName.append(HashString(QString()));
while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
if (yyTok == Tok_Ident) {
text = yyWord;
text.detach();
- fullName.append(text);
+ fullName.append(HashString(text));
}
yyTok = getToken();
}
if (fullName.isEmpty())
break;
NamespaceList nsl;
- if (fullyQualify(namespaces, fullName, false, &nsl, 0)) {
- modifyNamespace(&namespaces);
- namespaces.last()->aliases.insert(nsl.last()->name, stringListifyNamespace(nsl));
- }
+ if (fullyQualify(namespaces, fullName, false, &nsl, 0))
+ modifyNamespace(&namespaces, true)->aliases[nsl.last()] = nsl;
}
break;
case Tok_tr:
case Tok_trUtf8:
- if (!results->tor)
+ if (!tor)
goto case_default;
if (!sourcetext.isEmpty())
qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n",
@@ -1589,8 +1702,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
if (!pendingContext.isEmpty()) {
QStringList unresolved;
- if (!fullyQualify(namespaces, pendingContext.split(strColons), true,
- &functionContext, &unresolved)) {
+ if (!fullyQualify(namespaces, pendingContext, true, &functionContext, &unresolved)) {
functionContextUnresolved = unresolved.join(strColons);
qWarning("%s:%d: Qualifying with unknown namespace/class %s::%s\n",
qPrintable(yyFileName), yyLineNo,
@@ -1607,25 +1719,32 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
qPrintable(yyFileName), yyLineNo);
break;
}
- while (!functionContext.at(idx - 1)->hasTrFunctions) {
- if (idx == 1 || !functionContext.at(idx - 2)->isClass) {
- idx = functionContext.length();
- if (!functionContext.last()->complained) {
+ Namespace *fctx;
+ while (!(fctx = findNamespace(functionContext, idx)->classDef)->hasTrFunctions) {
+ if (idx == 1) {
+ context = stringifyNamespace(functionContext);
+ fctx = findNamespace(functionContext)->classDef;
+ if (!fctx->complained) {
qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
qPrintable(yyFileName), yyLineNo,
- qPrintable(stringifyNamespace(functionContext)));
- functionContext.last()->complained = true;
+ qPrintable(context));
+ fctx->complained = true;
}
- break;
+ goto gotctx;
}
--idx;
}
- context.clear();
- for (int i = 1;;) {
- context += functionContext.at(i)->name;
- if (++i == idx)
- break;
- context += strColons;
+ if (fctx->trQualification.isEmpty()) {
+ context.clear();
+ for (int i = 1;;) {
+ context += functionContext.at(i).value();
+ if (++i == idx)
+ break;
+ context += strColons;
+ }
+ fctx->trQualification = context;
+ } else {
+ context = fctx->trQualification;
}
} else {
context = (stringListifyNamespace(functionContext)
@@ -1644,20 +1763,27 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
prefix.chop(2);
NamespaceList nsl;
QStringList unresolved;
- if (fullyQualify(functionContext, prefix.split(strColons), false, &nsl, &unresolved)) {
- if (!nsl.last()->hasTrFunctions && !nsl.last()->complained) {
+ if (fullyQualify(functionContext, prefix, false, &nsl, &unresolved)) {
+ Namespace *fctx = findNamespace(nsl)->classDef;
+ if (fctx->trQualification.isEmpty()) {
+ context = stringifyNamespace(nsl);
+ fctx->trQualification = context;
+ } else {
+ context = fctx->trQualification;
+ }
+ if (!fctx->hasTrFunctions && !fctx->complained) {
qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
qPrintable(yyFileName), yyLineNo,
- qPrintable(stringifyNamespace(nsl)));
- nsl.last()->complained = true;
+ qPrintable(context));
+ fctx->complained = true;
}
- context = stringifyNamespace(nsl);
} else {
context = (stringListifyNamespace(nsl) + unresolved).join(strColons);
}
prefix.clear();
}
+ gotctx:
recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
}
extracomment.clear();
@@ -1666,7 +1792,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
break;
case Tok_translateUtf8:
case Tok_translate:
- if (!results->tor)
+ if (!tor)
goto case_default;
if (!sourcetext.isEmpty())
qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n",
@@ -1721,7 +1847,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
extra.clear();
break;
case Tok_trid:
- if (!results->tor)
+ if (!tor)
goto case_default;
if (sourcetext.isEmpty()) {
yyTok = getToken();
@@ -1744,8 +1870,16 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
extra.clear();
break;
case Tok_Q_DECLARE_TR_FUNCTIONS:
+ if (getMacroArgs()) {
+ Namespace *ns = modifyNamespace(&namespaces, true);
+ ns->hasTrFunctions = true;
+ ns->trQualification = yyWord;
+ ns->trQualification.detach();
+ }
+ yyTok = getToken();
+ break;
case Tok_Q_OBJECT:
- namespaces.last()->hasTrFunctions = true;
+ modifyNamespace(&namespaces, true)->hasTrFunctions = true;
yyTok = getToken();
break;
case Tok_Ident:
@@ -1759,7 +1893,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
break;
case Tok_Comment:
- if (!results->tor)
+ if (!tor)
goto case_default;
if (yyWord.startsWith(QLatin1Char(':'))) {
yyWord.remove(0, 1);
@@ -1814,9 +1948,15 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
sourcetext.resize(ptr - (ushort *)sourcetext.data());
} else {
- comment = yyWord.simplified();
- if (comment.startsWith(QLatin1String(MagicComment))) {
- comment.remove(0, sizeof(MagicComment) - 1);
+ const ushort *uc = (const ushort *)yyWord.unicode(); // Is zero-terminated
+ int idx = 0;
+ ushort c;
+ while ((c = uc[idx]) == ' ' || c == '\t' || c == '\n')
+ ++idx;
+ if (!memcmp(uc + idx, MagicComment.unicode(), MagicComment.length() * 2)) {
+ idx += MagicComment.length();
+ comment = QString::fromRawData(yyWord.unicode() + idx,
+ yyWord.length() - idx).simplified();
int k = comment.indexOf(QLatin1Char(' '));
if (k == -1) {
context = comment;
@@ -1826,11 +1966,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
recordMessage(yyLineNo, context, QString(), comment, extracomment,
QString(), TranslatorMessage::ExtraData(), false, false);
extracomment.clear();
- results->tor->setExtras(extra);
+ tor->setExtras(extra);
extra.clear();
}
- } else {
- comment.detach();
}
}
yyTok = getToken();
@@ -1854,17 +1992,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
#endif
break;
case Tok_RightBrace:
- if (yyBraceDepth + 1 == namespaceDepths.count()) {
- // class or namespace
- Namespace *ns = namespaces.last();
- if (ns->needsTrFunctions && !ns->hasTrFunctions && !ns->complained) {
- qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(stringifyNamespace(namespaces)));
- ns->complained = true;
- }
+ if (yyBraceDepth + 1 == namespaceDepths.count()) // class or namespace
truncateNamespaces(&namespaces, namespaceDepths.pop());
- }
if (yyBraceDepth == namespaceDepths.count()) {
// function, class or namespace
if (!yyBraceDepth && !directInclude) {
@@ -1922,6 +2051,37 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
qPrintable(yyFileName), yyParenLineNo);
}
+const ParseResults *CppParser::recordResults(bool isHeader)
+{
+ if (tor) {
+ if (tor->messageCount()) {
+ CppFiles::setTranslator(yyFileName, tor);
+ } else {
+ delete tor;
+ tor = 0;
+ }
+ }
+ if (isHeader) {
+ const ParseResults *pr;
+ if (!tor && results->includes.count() == 1
+ && results->rootNamespace.children.isEmpty()
+ && results->rootNamespace.aliases.isEmpty()
+ && results->rootNamespace.usings.isEmpty()) {
+ // This is a forwarding header. Slash it.
+ pr = *results->includes.begin();
+ delete results;
+ } else {
+ results->fileId = nextFileId++;
+ pr = results;
+ }
+ CppFiles::setResults(yyFileName, pr);
+ return pr;
+ } else {
+ delete results;
+ return 0;
+ }
+}
+
/*
Fetches tr() calls in C++ code in UI files (inside "<function>"
tag). This mechanism is obsolete.
@@ -1966,12 +2126,12 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
parser.setTranslator(tor);
QSet<QString> inclusions;
parser.parse(cd.m_defaultContext, cd, inclusions);
- CppFiles::setResults(filename, parser.getResults());
+ parser.recordResults(isHeader(filename));
}
- foreach (const QString filename, filenames)
+ foreach (const QString &filename, filenames)
if (!CppFiles::isBlacklisted(filename))
- if (Translator *tor = CppFiles::getResults(filename)->tor)
+ if (const Translator *tor = CppFiles::getTranslator(filename))
foreach (const TranslatorMessage &msg, tor->messages())
translator.extend(msg);
}
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index f867a45..24da253 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -62,23 +62,14 @@ static void printOut(const QString & out)
}
static void recursiveFileInfoList(const QDir &dir,
- const QStringList &nameFilters, QDir::Filters filter, bool recursive,
+ const QSet<QString> &nameFilters, QDir::Filters filter,
QFileInfoList *fileinfolist)
{
- if (recursive)
- filter |= QDir::AllDirs;
- QFileInfoList entries = dir.entryInfoList(nameFilters, filter);
-
- QFileInfoList::iterator it;
- for (it = entries.begin(); it != entries.end(); ++it) {
- QString fname = it->fileName();
- if (fname != QLatin1String(".") && fname != QLatin1String("..")) {
- if (it->isDir())
- recursiveFileInfoList(QDir(it->absoluteFilePath()), nameFilters, filter, recursive, fileinfolist);
- else
- fileinfolist->append(*it);
- }
- }
+ foreach (const QFileInfo &fi, dir.entryInfoList(filter))
+ if (fi.isDir())
+ recursiveFileInfoList(QDir(fi.absoluteFilePath()), nameFilters, filter, fileinfolist);
+ else if (nameFilters.contains(fi.suffix()))
+ fileinfolist->append(fi);
}
static void printUsage()
@@ -243,7 +234,7 @@ int main(int argc, char **argv)
bool recursiveScan = true;
QString extensions = m_defaultExtensions;
- QStringList extensionsNameFilters;
+ QSet<QString> extensionsNameFilters;
for (int i = 1; i < argc; ++i) {
if (args.at(i) == QLatin1String("-ts"))
@@ -418,15 +409,15 @@ int main(int argc, char **argv)
foreach (QString ext, extensions.split(QLatin1Char(','))) {
ext = ext.trimmed();
if (ext.startsWith(QLatin1Char('.')))
- ext.remove(0,1);
- ext.insert(0, QLatin1String("*."));
- extensionsNameFilters << ext;
+ ext.remove(0, 1);
+ extensionsNameFilters.insert(ext);
}
}
QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
+ if (recursiveScan)
+ filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
QFileInfoList fileinfolist;
- recursiveFileInfoList(dir, extensionsNameFilters, filters,
- recursiveScan, &fileinfolist);
+ recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
int scanRootLen = dir.absolutePath().length();
foreach (const QFileInfo &fi, fileinfolist) {
QString fn = QDir::cleanPath(fi.absoluteFilePath());
diff --git a/tools/linguist/phrasebooks/russian.qph b/tools/linguist/phrasebooks/russian.qph
index 69af041..9d40bd3 100644
--- a/tools/linguist/phrasebooks/russian.qph
+++ b/tools/linguist/phrasebooks/russian.qph
@@ -201,10 +201,6 @@
<target>разделить выбранные элементы</target>
</phrase>
<phrase>
- <source>dock</source>
- <target>док</target>
-</phrase>
-<phrase>
<source>document</source>
<target>документ</target>
</phrase>
@@ -302,7 +298,7 @@
</phrase>
<phrase>
<source>font style</source>
- <target>стиль шрифта</target>
+ <target>начертание</target>
</phrase>
<phrase>
<source>function key</source>
@@ -510,7 +506,7 @@
</phrase>
<phrase>
<source>OK</source>
- <target>Готово</target>
+ <target>ОК</target>
</phrase>
<phrase>
<source>OLE</source>
@@ -1038,10 +1034,6 @@
</phrase>
<phrase>
<source>OK</source>
- <target>Выбрать</target>
-</phrase>
-<phrase>
- <source>OK</source>
<target>Закрыть</target>
</phrase>
<phrase>
@@ -1092,4 +1084,84 @@
<source>Checkable</source>
<target>Переключаемое</target>
</phrase>
+<phrase>
+ <source>Style</source>
+ <target>Начертание</target>
+</phrase>
+<phrase>
+ <source>Point size</source>
+ <target>Размер</target>
+</phrase>
+<phrase>
+ <source>Family</source>
+ <target>Шрифт</target>
+</phrase>
+<phrase>
+ <source>Writing system</source>
+ <target>Система письма</target>
+</phrase>
+<phrase>
+ <source>OK</source>
+ <target>Удалить</target>
+</phrase>
+<phrase>
+ <source>Style</source>
+ <target>Стиль</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Изменить</target>
+</phrase>
+<phrase>
+ <source>Invalid</source>
+ <target>Некорректный</target>
+</phrase>
+<phrase>
+ <source>Invalid</source>
+ <target>Некорректная</target>
+</phrase>
+<phrase>
+ <source>Invalid</source>
+ <target>Некорректное</target>
+</phrase>
+<phrase>
+ <source>tag</source>
+ <target>тэг</target>
+</phrase>
+<phrase>
+ <source>tab order</source>
+ <target>порядок обхода</target>
+</phrase>
+<phrase>
+ <source>Ascending</source>
+ <target>По возрастанию</target>
+</phrase>
+<phrase>
+ <source>Descending</source>
+ <target>По убыванию</target>
+</phrase>
+<phrase>
+ <source>Reset</source>
+ <target>Сбросить</target>
+</phrase>
+<phrase>
+ <source>Sort order</source>
+ <target>Порядок сортировки</target>
+</phrase>
+<phrase>
+ <source>Appearance</source>
+ <target>Внешний вид</target>
+</phrase>
+<phrase>
+ <source>View</source>
+ <target>Просмотр</target>
+</phrase>
+<phrase>
+ <source>Actions</source>
+ <target>Действия</target>
+</phrase>
+<phrase>
+ <source>Table of Contents</source>
+ <target>Оглавление</target>
+</phrase>
</QPH>
diff --git a/tools/qdoc3/atom.cpp b/tools/qdoc3/atom.cpp
index 69204d4..834a5d7 100644
--- a/tools/qdoc3/atom.cpp
+++ b/tools/qdoc3/atom.cpp
@@ -143,6 +143,7 @@ QString Atom::UPPERROMAN_ ("upperroman");
\value SectionHeadingRight
\value SidebarLeft
\value SidebarRight
+ \value SinceList
\value String
\value TableLeft
\value TableRight
@@ -220,6 +221,7 @@ static const struct {
{ "SectionHeadingRight", Atom::SectionHeadingRight },
{ "SidebarLeft", Atom::SidebarLeft },
{ "SidebarRight", Atom::SidebarRight },
+ { "SinceList", Atom::SinceList },
{ "SnippetCommand", Atom::SnippetCommand },
{ "SnippetIdentifier", Atom::SnippetIdentifier },
{ "SnippetLocation", Atom::SnippetLocation },
diff --git a/tools/qdoc3/atom.h b/tools/qdoc3/atom.h
index 95faa8f..99f9b57 100644
--- a/tools/qdoc3/atom.h
+++ b/tools/qdoc3/atom.h
@@ -112,7 +112,9 @@ class Atom
SectionRight,
SectionHeadingLeft,
SectionHeadingRight,
- SidebarLeft, SidebarRight,
+ SidebarLeft,
+ SidebarRight,
+ SinceList,
SnippetCommand,
SnippetIdentifier,
SnippetLocation,
diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp
index b918fa5..c202d71 100644
--- a/tools/qdoc3/doc.cpp
+++ b/tools/qdoc3/doc.cpp
@@ -90,10 +90,10 @@ enum {
CMD_PRINTUNTIL, CMD_QUOTATION, CMD_QUOTEFILE,
CMD_QUOTEFROMFILE, CMD_QUOTEFUNCTION, CMD_RAW, CMD_ROW,
CMD_SA, CMD_SECTION1, CMD_SECTION2, CMD_SECTION3,
- CMD_SECTION4, CMD_SIDEBAR, CMD_SKIPLINE, CMD_SKIPTO,
- CMD_SKIPUNTIL, CMD_SNIPPET, CMD_SUB, CMD_SUP, CMD_TABLE,
- CMD_TABLEOFCONTENTS, CMD_TARGET, CMD_TT, CMD_UNDERLINE,
- CMD_UNICODE, CMD_VALUE, CMD_WARNING,
+ CMD_SECTION4, CMD_SIDEBAR, CMD_SINCELIST, CMD_SKIPLINE,
+ CMD_SKIPTO, CMD_SKIPUNTIL, CMD_SNIPPET, CMD_SUB, CMD_SUP,
+ CMD_TABLE, CMD_TABLEOFCONTENTS, CMD_TARGET, CMD_TT,
+ CMD_UNDERLINE, CMD_UNICODE, CMD_VALUE, CMD_WARNING,
#ifdef QDOC_QML
CMD_QML, CMD_ENDQML, CMD_CPP, CMD_ENDCPP, CMD_QMLTEXT,
CMD_ENDQMLTEXT, CMD_CPPTEXT, CMD_ENDCPPTEXT,
@@ -177,6 +177,7 @@ static struct {
{ "section3", CMD_SECTION3, 0 },
{ "section4", CMD_SECTION4, 0 },
{ "sidebar", CMD_SIDEBAR, 0 }, // ### don't document for now
+ { "sincelist", CMD_SINCELIST, 0 },
{ "skipline", CMD_SKIPLINE, 0 },
{ "skipto", CMD_SKIPTO, 0 },
{ "skipuntil", CMD_SKIPUNTIL, 0 },
@@ -727,6 +728,9 @@ void DocParser::parse(const QString& source,
case CMD_ANNOTATEDLIST:
append(Atom::AnnotatedList, getArgument());
break;
+ case CMD_SINCELIST:
+ append(Atom::SinceList, getArgument());
+ break;
case CMD_GENERATELIST:
append(Atom::GeneratedList, getArgument());
break;
@@ -2664,13 +2668,18 @@ Text Doc::trimmedBriefText(const QString &className) const
standardWording = false;
}
- if (!w.isEmpty() && (w.first() == "class" || w.first() == "widget"
- || w.first() == "namespace" || w.first() == "header"))
+ if (!w.isEmpty() && ((w.first() == "class") ||
+ (w.first() == "function") ||
+ (w.first() == "macro") ||
+ (w.first() == "widget") ||
+ (w.first() == "namespace") ||
+ (w.first() == "header")))
w.removeFirst();
else {
location().warning(
tr("Nonstandard wording in '\\%1' text for '%2' ("
- "expected 'class', 'widget', 'namespace' or 'header')")
+ "expected 'class', 'function', 'macro', 'widget', "
+ "'namespace' or 'header')")
.arg(COMMAND_BRIEF).arg(className));
standardWording = false;
}
diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp
index 2d03860..47fe4b5 100644
--- a/tools/qdoc3/generator.cpp
+++ b/tools/qdoc3/generator.cpp
@@ -562,24 +562,21 @@ void Generator::generateModuleWarning(const ClassNode *classe,
QString module = classe->moduleName();
if (!module.isEmpty()) {
Text text;
- if (Tokenizer::isTrue("defined(consoleedition)")
- && !editionModuleMap["Console"].contains(module)) {
+ if (!editionModuleMap["Console"].contains(module)) {
text << Atom::ParaLeft
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
<< "This class is not part of the Qt Console Edition."
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
<< Atom::ParaRight;
}
- else if (Tokenizer::isTrue("defined(desktoplightedition)")
- && !editionModuleMap["DesktopLight"].contains(module)) {
+ else if (!editionModuleMap["DesktopLight"].contains(module)) {
text << Atom::ParaLeft
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
<< "This class is not part of the Qt Desktop Light Edition."
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
<< Atom::ParaRight;
}
- else if (module == "Qt3Support" &&
- Tokenizer::isTrue("defined(opensourceedition)")) {
+ else if (module == "Qt3Support") {
text << Atom::ParaLeft
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
<< "Note to Qt Desktop Light Edition users:"
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index b7ed702..5406017 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -330,6 +330,7 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
#ifdef ZZZ_QDOC_QML
findAllQmlClasses(tree->root());
#endif
+ findAllSince(tree->root(),tree->version());
PageGenerator::generateTree(tree, marker);
@@ -539,7 +540,6 @@ int HtmlGenerator::generateAtom(const Atom *atom,
break;
case Atom::AnnotatedList:
{
- //qDebug() << "ANNOTATED LIS:";
QList<Node*> values = tre->groups().values(atom->string());
QMap<QString, const Node*> nodeMap;
for (int i = 0; i < values.size(); ++i) {
@@ -653,7 +653,26 @@ int HtmlGenerator::generateAtom(const Atom *atom,
}
}
break;
- case Atom::Image:
+ case Atom::SinceList:
+ {
+ QList<Node*> values;
+ if (atom->string() == "classes") {
+ values = sinceClasses.values();
+ }
+ else if (atom->string() == "functions") {
+ values = sinceFunctions.values();
+ }
+ if (!values.isEmpty()) {
+ QMap<QString, const Node*> nodeMap;
+ for (int i=0; i<values.size(); ++i) {
+ const Node* n = values.at(i);
+ nodeMap.insert(n->nameForLists(),n);
+ }
+ generateAnnotatedList(relative, marker, nodeMap);
+ }
+ }
+ break;
+case Atom::Image:
case Atom::InlineImage:
{
QString fileName = imageFileName(relative, atom->string());
@@ -1475,7 +1494,7 @@ void HtmlGenerator::generateHeader(const QString& title,
if ((project != "Qtopia") && (project != "Qt Extended")) {
shortVersion = project + " " + shortVersion + ": ";
if (node && !node->doc().location().isEmpty())
- out() << "<!-- " << node->doc().location().filePath() << " -->\n";
+ out() << "<!-- " << node->doc().location().fileName() << " -->\n";
shortVersion = tre->version();
if (shortVersion.count(QChar('.')) == 2)
@@ -3495,6 +3514,45 @@ void HtmlGenerator::findAllClasses(const InnerNode *node)
}
}
+/*!
+ For generating the "Since x.y" page.
+ */
+void HtmlGenerator::findAllSince(const InnerNode *node, QString version)
+{
+ const QRegExp versionSeparator("[\\-\\.]");
+ const int minorIndex = version.indexOf(versionSeparator);
+ const int patchIndex = version.indexOf(versionSeparator, minorIndex+1);
+ version = version.left(patchIndex);
+
+ NodeList::const_iterator c = node->childNodes().constBegin();
+ while (c != node->childNodes().constEnd()) {
+ if (((*c)->access() != Node::Private) && ((*c)->since() == version)) {
+ if ((*c)->type() == Node::Function) {
+ FunctionNode *func = static_cast<FunctionNode *>(*c);
+ if ((func->status() > Node::Obsolete) &&
+ (func->metaness() != FunctionNode::Ctor) &&
+ (func->metaness() != FunctionNode::Dtor)) {
+ sinceFunctions.insert(func->name(), func);
+ }
+ }
+ else if ((*c)->url().isEmpty()) {
+ if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
+ QString className = (*c)->name();
+ if ((*c)->parent() &&
+ (*c)->parent()->type() == Node::Namespace &&
+ !(*c)->parent()->name().isEmpty())
+ className = (*c)->parent()->name()+"::"+className;
+ sinceClasses.insert(className, *c);
+ }
+ }
+ if ((*c)->isInnerNode()) {
+ findAllSince(static_cast<InnerNode *>(*c),version);
+ }
+ }
+ ++c;
+ }
+}
+
void HtmlGenerator::findAllFunctions(const InnerNode *node)
{
NodeList::ConstIterator c = node->childNodes().begin();
diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h
index fabe585..24e2986 100644
--- a/tools/qdoc3/htmlgenerator.h
+++ b/tools/qdoc3/htmlgenerator.h
@@ -216,6 +216,7 @@ class HtmlGenerator : public PageGenerator
#ifdef ZZZ_QDOC_QML
void findAllQmlClasses(const InnerNode *node);
#endif
+ void findAllSince(const InnerNode *node, QString version);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
virtual QString getLink(const Atom *atom,
@@ -285,6 +286,8 @@ class HtmlGenerator : public PageGenerator
#endif
QMap<QString, QMap<QString, const Node *> > funcIndex;
QMap<Text, const Node *> legaleseTexts;
+ QMap<QString, Node*> sinceClasses;
+ QMap<QString, Node*> sinceFunctions;
};
#define HTMLGENERATOR_ADDRESS "address"
diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp
index aac4ee8..8658428 100644
--- a/tools/qdoc3/main.cpp
+++ b/tools/qdoc3/main.cpp
@@ -336,7 +336,6 @@ static void processQdocconfFile(const QString &fileName)
/*
Generate the XML tag file, if it was requested.
*/
-
QString tagFile = config.getString(CONFIG_TAGFILE);
if (!tagFile.isEmpty())
tree->generateTagFile(tagFile);
diff --git a/tools/qdoc3/test/macros.qdocconf b/tools/qdoc3/test/macros.qdocconf
index f7dcdc0..dbb8ab8 100644
--- a/tools/qdoc3/test/macros.qdocconf
+++ b/tools/qdoc3/test/macros.qdocconf
@@ -28,3 +28,8 @@ macro.begincomment = "\\c{/*}"
macro.endcomment = "\\c{*/}"
macro.uuml.HTML = "&uuml;"
macro.mdash.HTML = "&mdash;"
+
+macro.beginfloatleft.HTML = "<div style=\"float: left; margin-right: 2em\">"
+macro.beginfloatright.HTML = "<div style=\"float: right; margin-left: 2em\">"
+macro.endfloat.HTML = "</div>"
+macro.clearfloat.HTML = "<div style=\"clear: both\">"
diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf
index deaf8a8..c0b8334 100644
--- a/tools/qdoc3/test/qt-build-docs.qdocconf
+++ b/tools/qdoc3/test/qt-build-docs.qdocconf
@@ -112,3 +112,5 @@ imagedirs = $QT_SOURCE_TREE/doc/src/images \
outputdir = $QT_BUILD_TREE/doc/html
tagfile = $QT_BUILD_TREE/doc/html/qt.tags
base = file:$QT_BUILD_TREE/doc/html
+
+HTML.generatemacrefs = "true"
diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
index 5be9fa5..dcf33dc 100644
--- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf
+++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
@@ -26,6 +26,7 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
QT_WIDGET_PLUGIN_EXPORT \
Q_COMPAT_EXPORT \
Q_CORE_EXPORT \
+ Q_CORE_EXPORT_INLINE \
Q_EXPLICIT \
Q_EXPORT \
Q_EXPORT_CODECS_CN \
diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf
index 7bd4e52..9b5937d 100644
--- a/tools/qdoc3/test/qt.qdocconf
+++ b/tools/qdoc3/test/qt.qdocconf
@@ -114,3 +114,5 @@ imagedirs = $QTDIR/doc/src/images \
outputdir = $QTDIR/doc/html
tagfile = $QTDIR/doc/html/qt.tags
base = file:$QTDIR/doc/html
+
+HTML.generatemacrefs = "true"
diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp
index 2fbe176..eef8132 100644
--- a/tools/xmlpatternsvalidator/main.cpp
+++ b/tools/xmlpatternsvalidator/main.cpp
@@ -43,6 +43,7 @@
#include <QtCore/QDebug>
#include <QtCore/QFile>
+#include <QtCore/QStringList>
#include <QtCore/QUrl>
#include <QtXmlPatterns/QXmlSchema>
#include <QtXmlPatterns/QXmlSchemaValidator>
@@ -62,14 +63,15 @@ int main(int argc, char **argv)
{
InvalidMode,
SchemaOnlyMode,
- SchemaAndInstanceMode,
- InstanceOnlyMode
+ InstanceOnlyMode,
+ SchemaAndInstanceMode
};
const QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName(QLatin1String("xmlpatternsvalidator"));
- if (argc != 2 && argc != 3) {
+ QStringList arguments = QCoreApplication::arguments();
+ if (arguments.size() != 2 && arguments.size() != 3) {
qDebug() << QXmlPatternistCLI::tr("usage: xmlpatternsvalidator (<schema url> | <instance url> <schema url> | <instance url>)");
return ParseError;
}
@@ -77,57 +79,52 @@ int main(int argc, char **argv)
// parse command line arguments
ExecutionMode mode = InvalidMode;
- if (argc == 2) {
- // either it is a schema or instance document
+ QUrl schemaUri;
+ QUrl instanceUri;
- QString url = QFile::decodeName(argv[1]);
- if (url.toLower().endsWith(QLatin1String(".xsd"))) {
- mode = SchemaOnlyMode;
- } else {
- // as we could validate all types of xml documents, don't check the extension here
- mode = InstanceOnlyMode;
+ {
+ QUrl url = arguments[1];
+
+ if (url.isRelative())
+ url = QUrl::fromLocalFile(arguments[1]);
+
+ if (arguments.size() == 2) {
+ // either it is a schema or instance document
+
+ if (arguments[1].toLower().endsWith(QLatin1String(".xsd"))) {
+ schemaUri = url;
+ mode = SchemaOnlyMode;
+ } else {
+ // as we could validate all types of xml documents, don't check the extension here
+ instanceUri = url;
+ mode = InstanceOnlyMode;
+ }
+ } else if (arguments.size() == 3) {
+ instanceUri = url;
+ schemaUri = arguments[2];
+
+ if (schemaUri.isRelative())
+ schemaUri = QUrl::fromLocalFile(schemaUri.toString());
+
+ mode = SchemaAndInstanceMode;
}
- } else if (argc == 3) {
- mode = SchemaAndInstanceMode;
}
- // do validation
+ // Validate schema
QXmlSchema schema;
-
- if (mode == SchemaOnlyMode) {
- const QString schemaUri = QFile::decodeName(argv[1]);
-
- schema.load(QUrl(schemaUri));
-
- if (schema.isValid())
- return Valid;
- else
- return Invalid;
- } else if (mode == SchemaAndInstanceMode) {
- const QString instanceUri = QFile::decodeName(argv[1]);
- const QString schemaUri = QFile::decodeName(argv[2]);
-
- schema.load(QUrl(schemaUri));
-
+ if (InstanceOnlyMode != mode) {
+ schema.load(schemaUri);
if (!schema.isValid())
return Invalid;
-
- QXmlSchemaValidator validator(schema);
- if (validator.validate(QUrl(instanceUri)))
- return Valid;
- else
- return Invalid;
- } else if (mode == InstanceOnlyMode) {
- const QString instanceUri = QFile::decodeName(argv[1]);
-
- QXmlSchemaValidator validator(schema);
- if (validator.validate(QUrl(instanceUri)))
- return Valid;
- else
- return Invalid;
}
- Q_ASSERT(false);
+ if (SchemaOnlyMode == mode)
+ return Valid;
+
+ // Validate instance
+ QXmlSchemaValidator validator(schema);
+ if (validator.validate(instanceUri))
+ return Valid;
return Invalid;
}
diff --git a/tools/xmlpatternsvalidator/main.h b/tools/xmlpatternsvalidator/main.h
index 6dd9a1b..f2c607e 100644
--- a/tools/xmlpatternsvalidator/main.h
+++ b/tools/xmlpatternsvalidator/main.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the Patternist project on Qt Labs.
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage