From ac79a25aae1a883e1587631ad531ad43b0dc8e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 28 Oct 2014 10:56:51 +0100 Subject: Fix maximal literal string limitation in moc. C++ standard advise to place 64k char limit for string literals, this patch improves moc output so it is not affected anymore. Task-number: QTBUG-36500 Change-Id: Iece630faaef45baebe8c7afe4fc51e0362c713de Reviewed-by: Olivier Goffart --- src/tools/moc/generator.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'src/tools/moc/generator.cpp') diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 912fa995fa..fcc43aca68 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -230,13 +230,23 @@ void Generator::generateCode() // // Build stringdata struct // + const int constCharArraySizeLimit = 65535; fprintf(out, "struct qt_meta_stringdata_%s_t {\n", qualifiedClassNameIdentifier.constData()); fprintf(out, " QByteArrayData data[%d];\n", strings.size()); { - int len = 0; - for (int i = 0; i < strings.size(); ++i) - len += strings.at(i).length() + 1; - fprintf(out, " char stringdata[%d];\n", len); + int stringDataLength = 0; + int stringDataCounter = 0; + for (int i = 0; i < strings.size(); ++i) { + int thisLength = strings.at(i).length() + 1; + stringDataLength += thisLength; + if (stringDataLength / constCharArraySizeLimit) { + // save previous stringdata and start computing the next one. + fprintf(out, " char stringdata%d[%d];\n", stringDataCounter++, stringDataLength - thisLength); + stringDataLength = thisLength; + } + } + fprintf(out, " char stringdata%d[%d];\n", stringDataCounter, stringDataLength); + } fprintf(out, "};\n"); @@ -247,7 +257,7 @@ void Generator::generateCode() // QByteArrayData::data() implementation returning simply "this + offset". fprintf(out, "#define QT_MOC_LITERAL(idx, ofs, len) \\\n" " Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \\\n" - " qptrdiff(offsetof(qt_meta_stringdata_%s_t, stringdata) + ofs \\\n" + " qptrdiff(offsetof(qt_meta_stringdata_%s_t, stringdata0) + ofs \\\n" " - idx * sizeof(QByteArrayData)) \\\n" " )\n", qualifiedClassNameIdentifier.constData()); @@ -282,9 +292,18 @@ void Generator::generateCode() fprintf(out, " \""); int col = 0; int len = 0; + int stringDataLength = 0; for (int i = 0; i < strings.size(); ++i) { QByteArray s = strings.at(i); len = s.length(); + stringDataLength += len + 1; + if (stringDataLength >= constCharArraySizeLimit) { + fprintf(out, "\",\n \""); + stringDataLength = len + 1; + col = 0; + } else if (i) + fputs("\\0", out); // add \0 at the end of each string + if (col && col + len >= 72) { fprintf(out, "\"\n \""); col = 0; @@ -309,9 +328,6 @@ void Generator::generateCode() idx += spanLen; col += spanLen; } - - if (i != strings.size() - 1) // skip the last \0 the c++ will add it for us - fputs("\\0", out); col += len + 2; } @@ -546,7 +562,7 @@ void Generator::generateCode() // fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData()); fprintf(out, " if (!_clname) return Q_NULLPTR;\n"); - fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata))\n" + fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata0))\n" " return static_cast(const_cast< %s*>(this));\n", qualifiedClassNameIdentifier.constData(), cdef->classname.constData()); for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one -- cgit v1.2.3