summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generator/CMakeLists.txt1
-rw-r--r--generator/cppgenerator.cpp13
-rw-r--r--generator/shibokennormalize.cpp274
-rw-r--r--generator/shibokennormalize_p.h41
4 files changed, 323 insertions, 6 deletions
diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt
index 89b2ef75..1a2eb1f0 100644
--- a/generator/CMakeLists.txt
+++ b/generator/CMakeLists.txt
@@ -6,6 +6,7 @@ headergenerator.cpp
overloaddata.cpp
shiboken.cpp
shibokengenerator.cpp
+shibokennormalize.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index 9bace889..cbfa5ffc 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -22,6 +22,7 @@
*/
#include "cppgenerator.h"
+#include "shibokennormalize_p.h"
#include <reporthandler.h>
#include <typedatabase.h>
@@ -3043,11 +3044,11 @@ void CppGenerator::writeSignalInitialization(QTextStream& s, const AbstractMetaC
AbstractMetaArgument *a = cppSignal->arguments().at(i);
AbstractMetaType* type = a->type();
- QString cppSignature = QMetaObject::normalizedType(qPrintable(type->cppSignature()));
- QString originalSignature = QMetaObject::normalizedType(qPrintable(type->originalTypeDescription()));
+ QString cppSignature = SBK_NORMALIZED_TYPE(qPrintable(type->cppSignature()));
+ QString originalSignature = SBK_NORMALIZED_TYPE(qPrintable(type->originalTypeDescription()));
if (!a->defaultValueExpression().isEmpty()) {
- QString sig = QMetaObject::normalizedSignature(signature.toAscii());
+ QString sig = SBK_NORMALIZED_SIGNATURE(signature.toAscii());
if (sig.isEmpty())
sig = "void";
signatures[cppSignal->name()].append(sig);
@@ -3062,12 +3063,12 @@ void CppGenerator::writeSignalInitialization(QTextStream& s, const AbstractMetaC
<< translateType(type, metaClass, opt) << " >"
<< "(\"" << skipNamespace(originalSignature) << "\"); // " << type->cppSignature() << "\n";
}
- signature += skipNamespace(type->originalTypeDescription());
+ signature += SBK_NORMALIZED_TYPE(skipNamespace(type->originalTypeDescription()).toAscii());
}
} else {
signature = "void";
}
- signatures[cppSignal->name()].append(QMetaObject::normalizedSignature(signature.toAscii()));
+ signatures[cppSignal->name()].append(SBK_NORMALIZED_SIGNATURE(signature.toAscii()));
}
}
@@ -3706,7 +3707,7 @@ void CppGenerator::finishGeneration()
foreach (AbstractMetaArgument* arg, func->arguments()) {
if (arg->type()->isContainer()) {
QString value = translateType(arg->type(), metaClass, ExcludeConst | ExcludeReference);
- typeResolvers << QMetaObject::normalizedType(value.toAscii().constData());
+ typeResolvers << SBK_NORMALIZED_TYPE(value.toAscii().constData());
}
}
}
diff --git a/generator/shibokennormalize.cpp b/generator/shibokennormalize.cpp
new file mode 100644
index 00000000..01aad973
--- /dev/null
+++ b/generator/shibokennormalize.cpp
@@ -0,0 +1,274 @@
+/*
+ * This file is part of the PySide project.
+ * This code was extracted from qmetaobject_p.h present on Qt4.7.
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "shibokennormalize_p.h"
+#include <QVarLengthArray>
+
+#if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0))
+
+// mirrored in moc's utils.h
+static inline bool is_ident_char(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || (s >= '0' && s <= '9')
+ || s == '_'
+ );
+}
+
+static inline bool is_space(char s)
+{
+ return (s == ' ' || s == '\t');
+}
+
+static void qRemoveWhitespace(const char *s, char *d)
+{
+ char last = 0;
+ while (*s && is_space(*s))
+ s++;
+ while (*s) {
+ while (*s && !is_space(*s))
+ last = *d++ = *s++;
+ while (*s && is_space(*s))
+ s++;
+ if (*s && ((is_ident_char(*s) && is_ident_char(last))
+ || ((*s == ':') && (last == '<')))) {
+ last = *d++ = ' ';
+ }
+ }
+ *d = '\0';
+}
+
+// This code is shared with moc.cpp
+static QByteArray normalizeTypeInternalQt47(const char *t, const char *e, bool fixScope = false, bool adjustConst = true)
+{
+ int len = e - t;
+ /*
+ Convert 'char const *' into 'const char *'. Start at index 1,
+ not 0, because 'const char *' is already OK.
+ */
+ QByteArray constbuf;
+ for (int i = 1; i < len; i++) {
+ if ( t[i] == 'c'
+ && strncmp(t + i + 1, "onst", 4) == 0
+ && (i + 5 >= len || !is_ident_char(t[i + 5]))
+ && !is_ident_char(t[i-1])
+ ) {
+ constbuf = QByteArray(t, len);
+ if (is_space(t[i-1]))
+ constbuf.remove(i-1, 6);
+ else
+ constbuf.remove(i, 5);
+ constbuf.prepend("const ");
+ t = constbuf.data();
+ e = constbuf.data() + constbuf.length();
+ break;
+ }
+ /*
+ We musn't convert 'char * const *' into 'const char **'
+ and we must beware of 'Bar<const Bla>'.
+ */
+ if (t[i] == '&' || t[i] == '*' ||t[i] == '<')
+ break;
+ }
+ if (adjustConst && e > t + 6 && strncmp("const ", t, 6) == 0) {
+ if (*(e-1) == '&') { // treat const reference as value
+ t += 6;
+ --e;
+ } else if (is_ident_char(*(e-1)) || *(e-1) == '>') { // treat const value as value
+ t += 6;
+ }
+ }
+ QByteArray result;
+ result.reserve(len);
+
+#if 1
+ // consume initial 'const '
+ if (strncmp("const ", t, 6) == 0) {
+ t+= 6;
+ result += "const ";
+ }
+#endif
+
+ // some type substitutions for 'unsigned x'
+ if (strncmp("unsigned", t, 8) == 0) {
+ // make sure "unsigned" is an isolated word before making substitutions
+ if (!t[8] || !is_ident_char(t[8])) {
+ if (strncmp(" int", t+8, 4) == 0) {
+ t += 8+4;
+ result += "uint";
+ } else if (strncmp(" long", t+8, 5) == 0) {
+ if ((strlen(t + 8 + 5) < 4 || strncmp(t + 8 + 5, " int", 4) != 0) // preserve '[unsigned] long int'
+ && (strlen(t + 8 + 5) < 5 || strncmp(t + 8 + 5, " long", 5) != 0) // preserve '[unsigned] long long'
+ ) {
+ t += 8+5;
+ result += "ulong";
+ }
+ } else if (strncmp(" short", t+8, 6) != 0 // preserve unsigned short
+ && strncmp(" char", t+8, 5) != 0) { // preserve unsigned char
+ // treat rest (unsigned) as uint
+ t += 8;
+ result += "uint";
+ }
+ }
+ } else {
+ // discard 'struct', 'class', and 'enum'; they are optional
+ // and we don't want them in the normalized signature
+ struct {
+ const char *keyword;
+ int len;
+ } optional[] = {
+ { "struct ", 7 },
+ { "class ", 6 },
+ { "enum ", 5 },
+ { 0, 0 }
+ };
+ int i = 0;
+ do {
+ if (strncmp(optional[i].keyword, t, optional[i].len) == 0) {
+ t += optional[i].len;
+ break;
+ }
+ } while (optional[++i].keyword != 0);
+ }
+
+ bool star = false;
+ while (t != e) {
+ char c = *t++;
+ if (fixScope && c == ':' && *t == ':' ) {
+ ++t;
+ c = *t++;
+ int i = result.size() - 1;
+ while (i >= 0 && is_ident_char(result.at(i)))
+ --i;
+ result.resize(i + 1);
+ }
+ star = star || c == '*';
+ result += c;
+ if (c == '<') {
+ //template recursion
+ const char* tt = t;
+ int templdepth = 1;
+ while (t != e) {
+ c = *t++;
+ if (c == '<')
+ ++templdepth;
+ if (c == '>')
+ --templdepth;
+ if (templdepth == 0 || (templdepth == 1 && c == ',')) {
+ result += normalizeTypeInternalQt47(tt, t-1, fixScope, false);
+ result += c;
+ if (templdepth == 0) {
+ if (*t == '>')
+ result += ' '; // avoid >>
+ break;
+ }
+ tt = t;
+ }
+ }
+ }
+
+ // cv qualifers can appear after the type as well
+ if (!is_ident_char(c) && t != e && (e - t >= 5 && strncmp("const", t, 5) == 0)
+ && (e - t == 5 || !is_ident_char(t[5]))) {
+ t += 5;
+ while (t != e && is_space(*t))
+ ++t;
+ if (adjustConst && t != e && *t == '&') {
+ // treat const ref as value
+ ++t;
+ } else if (adjustConst && !star) {
+ // treat const as value
+ } else if (!star) {
+ // move const to the front (but not if const comes after a *)
+ result.prepend("const ");
+ } else {
+ // keep const after a *
+ result += "const";
+ }
+ }
+ }
+
+ return result;
+}
+
+static char *qNormalizeTypeQt47(char *d, int &templdepth, QByteArray &result)
+{
+ const char *t = d;
+ while (*d && (templdepth
+ || (*d != ',' && *d != ')'))) {
+ if (*d == '<')
+ ++templdepth;
+ if (*d == '>')
+ --templdepth;
+ ++d;
+ }
+ if (strncmp("void", t, d - t) != 0)
+ result += normalizeTypeInternalQt47(t, d);
+
+ return d;
+}
+
+
+QByteArray QMetaObject_normalizedTypeQt47(const char *type)
+{
+ QByteArray result;
+
+ if (!type || !*type)
+ return result;
+
+ QVarLengthArray<char> stackbuf(qstrlen(type) + 1);
+ qRemoveWhitespace(type, stackbuf.data());
+ int templdepth = 0;
+ qNormalizeTypeQt47(stackbuf.data(), templdepth, result);
+
+ return result;
+}
+
+QByteArray QMetaObject_normalizedSignatureQt47(const char *method)
+{
+ QByteArray result;
+ if (!method || !*method)
+ return result;
+ int len = int(strlen(method));
+ QVarLengthArray<char> stackbuf(len + 1);
+ char *d = stackbuf.data();
+ qRemoveWhitespace(method, d);
+
+ result.reserve(len);
+
+ int argdepth = 0;
+ int templdepth = 0;
+ while (*d) {
+ if (argdepth == 1)
+ d = qNormalizeTypeQt47(d, templdepth, result);
+ if (*d == '(')
+ ++argdepth;
+ if (*d == ')')
+ --argdepth;
+ result += *d++;
+ }
+
+ return result;
+}
+#endif
diff --git a/generator/shibokennormalize_p.h b/generator/shibokennormalize_p.h
new file mode 100644
index 00000000..0a55b507
--- /dev/null
+++ b/generator/shibokennormalize_p.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the PySide project.
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SHIBOKENNORMALIZE_P_H
+#define SHIBOKENNORMALIZE_P_H
+
+#include <QMetaObject>
+#include <QByteArray>
+
+
+#if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0))
+ QByteArray QMetaObject_normalizedTypeQt47(const char *type);
+ QByteArray QMetaObject_normalizedSignatureQt47(const char *type);
+
+ #define SBK_NORMALIZED_TYPE(x) QMetaObject_normalizedTypeQt47(x)
+ #define SBK_NORMALIZED_SIGNATURE(x) QMetaObject_normalizedSignatureQt47(x)
+#else
+ #define SBK_NORMALIZED_TYPE(x) QMetaObject::normalizedType(x)
+ #define SBK_NORMALIZED_SIGNATURE(x) QMetaObject::normalizedSignature(x)
+#endif
+
+#endif //SHIBOKENNORMALIZE_P_H