rcc: Support Python as output format
Start with rcc -g python|python2 $name.qrc. [ChangeLog][rcc] Added support for Python as output format. Done-with: Friedemann Kleint <Friedemann.Kleint@qt.io> Fixes: PYSIDE-855 Change-Id: I97a642c3721d6d95b7cd0972d21abb0b2752fd4f Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
This commit is contained in:
parent
de1e15af44
commit
f91aae6397
@ -155,6 +155,11 @@ int runRcc(int argc, char *argv[])
|
|||||||
QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
|
QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
|
||||||
parser.addOption(binaryOption);
|
parser.addOption(binaryOption);
|
||||||
|
|
||||||
|
QCommandLineOption generatorOption(QStringList{QStringLiteral("g"), QStringLiteral("generator")});
|
||||||
|
generatorOption.setDescription(QStringLiteral("Select generator."));
|
||||||
|
generatorOption.setValueName(QStringLiteral("cpp|python|python2"));
|
||||||
|
parser.addOption(generatorOption);
|
||||||
|
|
||||||
QCommandLineOption passOption(QStringLiteral("pass"), QStringLiteral("Pass number for big resources"), QStringLiteral("number"));
|
QCommandLineOption passOption(QStringLiteral("pass"), QStringLiteral("Pass number for big resources"), QStringLiteral("number"));
|
||||||
parser.addOption(passOption);
|
parser.addOption(passOption);
|
||||||
|
|
||||||
@ -220,6 +225,18 @@ int runRcc(int argc, char *argv[])
|
|||||||
library.setCompressThreshold(parser.value(thresholdOption).toInt());
|
library.setCompressThreshold(parser.value(thresholdOption).toInt());
|
||||||
if (parser.isSet(binaryOption))
|
if (parser.isSet(binaryOption))
|
||||||
library.setFormat(RCCResourceLibrary::Binary);
|
library.setFormat(RCCResourceLibrary::Binary);
|
||||||
|
if (parser.isSet(generatorOption)) {
|
||||||
|
auto value = parser.value(generatorOption);
|
||||||
|
if (value == QLatin1String("cpp"))
|
||||||
|
library.setFormat(RCCResourceLibrary::C_Code);
|
||||||
|
else if (value == QLatin1String("python"))
|
||||||
|
library.setFormat(RCCResourceLibrary::Python3_Code);
|
||||||
|
else if (value == QLatin1String("python2"))
|
||||||
|
library.setFormat(RCCResourceLibrary::Python2_Code);
|
||||||
|
else
|
||||||
|
errorMsg = QLatin1String("Invalid generator: ") + value;
|
||||||
|
}
|
||||||
|
|
||||||
if (parser.isSet(passOption)) {
|
if (parser.isSet(passOption)) {
|
||||||
if (parser.value(passOption) == QLatin1String("1"))
|
if (parser.value(passOption) == QLatin1String("1"))
|
||||||
library.setFormat(RCCResourceLibrary::Pass1);
|
library.setFormat(RCCResourceLibrary::Pass1);
|
||||||
@ -280,6 +297,8 @@ int runRcc(int argc, char *argv[])
|
|||||||
switch (library.format()) {
|
switch (library.format()) {
|
||||||
case RCCResourceLibrary::C_Code:
|
case RCCResourceLibrary::C_Code:
|
||||||
case RCCResourceLibrary::Pass1:
|
case RCCResourceLibrary::Pass1:
|
||||||
|
case RCCResourceLibrary::Python3_Code:
|
||||||
|
case RCCResourceLibrary::Python2_Code:
|
||||||
mode = QIODevice::WriteOnly | QIODevice::Text;
|
mode = QIODevice::WriteOnly | QIODevice::Text;
|
||||||
break;
|
break;
|
||||||
case RCCResourceLibrary::Pass2:
|
case RCCResourceLibrary::Pass2:
|
||||||
|
@ -68,6 +68,17 @@ enum {
|
|||||||
|
|
||||||
#define writeString(s) write(s, sizeof(s))
|
#define writeString(s) write(s, sizeof(s))
|
||||||
|
|
||||||
|
static const char pythonHeader1[] =
|
||||||
|
R"(# Created by: object code
|
||||||
|
# Created by: The Resource Compiler for Qt version )";
|
||||||
|
|
||||||
|
static const char pythonHeader2[] = R"(
|
||||||
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
from PySide2 import QtCore
|
||||||
|
|
||||||
|
)";
|
||||||
|
|
||||||
void RCCResourceLibrary::write(const char *str, int len)
|
void RCCResourceLibrary::write(const char *str, int len)
|
||||||
{
|
{
|
||||||
--len; // trailing \0 on string literals...
|
--len; // trailing \0 on string literals...
|
||||||
@ -176,6 +187,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
|
|||||||
{
|
{
|
||||||
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
|
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
|
||||||
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
||||||
|
const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
|
||||||
|
|| lib.m_format == RCCResourceLibrary::Python2_Code;
|
||||||
//some info
|
//some info
|
||||||
if (text || pass1) {
|
if (text || pass1) {
|
||||||
if (m_language != QLocale::C) {
|
if (m_language != QLocale::C) {
|
||||||
@ -222,6 +235,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
|
|||||||
}
|
}
|
||||||
if (text || pass1)
|
if (text || pass1)
|
||||||
lib.writeChar('\n');
|
lib.writeChar('\n');
|
||||||
|
else if (python)
|
||||||
|
lib.writeString("\\\n");
|
||||||
|
|
||||||
if (lib.formatVersion() >= 2) {
|
if (lib.formatVersion() >= 2) {
|
||||||
// last modified time stamp
|
// last modified time stamp
|
||||||
@ -236,6 +251,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
|
|||||||
lib.writeNumber8(lastmod);
|
lib.writeNumber8(lastmod);
|
||||||
if (text || pass1)
|
if (text || pass1)
|
||||||
lib.writeChar('\n');
|
lib.writeChar('\n');
|
||||||
|
else if (python)
|
||||||
|
lib.writeString("\\\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,6 +263,8 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
|||||||
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
||||||
const bool pass2 = lib.m_format == RCCResourceLibrary::Pass2;
|
const bool pass2 = lib.m_format == RCCResourceLibrary::Pass2;
|
||||||
const bool binary = lib.m_format == RCCResourceLibrary::Binary;
|
const bool binary = lib.m_format == RCCResourceLibrary::Binary;
|
||||||
|
const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
|
||||||
|
|| lib.m_format == RCCResourceLibrary::Python2_Code;
|
||||||
|
|
||||||
//capture the offset
|
//capture the offset
|
||||||
m_dataOffset = offset;
|
m_dataOffset = offset;
|
||||||
@ -343,20 +362,24 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write the length
|
// write the length
|
||||||
|
if (text || binary || pass2 || python)
|
||||||
if (text || binary || pass2)
|
|
||||||
lib.writeNumber4(data.size());
|
lib.writeNumber4(data.size());
|
||||||
if (text || pass1)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
|
else if (python)
|
||||||
|
lib.writeString("\\\n");
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
// write the payload
|
// write the payload
|
||||||
const char *p = data.constData();
|
const char *p = data.constData();
|
||||||
if (text) {
|
if (text || python) {
|
||||||
for (int i = data.size(), j = 0; --i >= 0; --j) {
|
for (int i = data.size(), j = 0; --i >= 0; --j) {
|
||||||
lib.writeHex(*p++);
|
lib.writeHex(*p++);
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
lib.writeString("\n ");
|
if (text)
|
||||||
|
lib.writeString("\n ");
|
||||||
|
else
|
||||||
|
lib.writeString("\\\n");
|
||||||
j = 16;
|
j = 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,6 +391,9 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
|
|||||||
// done
|
// done
|
||||||
if (text || pass1)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
|
else if (python)
|
||||||
|
lib.writeString("\\\n");
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,6 +401,8 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
|
|||||||
{
|
{
|
||||||
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
|
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
|
||||||
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
|
||||||
|
const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
|
||||||
|
|| lib.m_format == RCCResourceLibrary::Python2_Code;
|
||||||
|
|
||||||
// capture the offset
|
// capture the offset
|
||||||
m_nameOffset = offset;
|
m_nameOffset = offset;
|
||||||
@ -390,12 +418,16 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
|
|||||||
lib.writeNumber2(m_name.length());
|
lib.writeNumber2(m_name.length());
|
||||||
if (text || pass1)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
|
else if (python)
|
||||||
|
lib.writeString("\\\n");
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
// write the hash
|
// write the hash
|
||||||
lib.writeNumber4(qt_hash(m_name));
|
lib.writeNumber4(qt_hash(m_name));
|
||||||
if (text || pass1)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
|
else if (python)
|
||||||
|
lib.writeString("\\\n");
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
// write the m_name
|
// write the m_name
|
||||||
@ -404,12 +436,17 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
|
|||||||
lib.writeNumber2(unicode[i].unicode());
|
lib.writeNumber2(unicode[i].unicode());
|
||||||
if ((text || pass1) && i % 16 == 0)
|
if ((text || pass1) && i % 16 == 0)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
|
else if (python && i % 16 == 0)
|
||||||
|
lib.writeString("\\\n");
|
||||||
}
|
}
|
||||||
offset += m_name.length()*2;
|
offset += m_name.length()*2;
|
||||||
|
|
||||||
// done
|
// done
|
||||||
if (text || pass1)
|
if (text || pass1)
|
||||||
lib.writeString("\n ");
|
lib.writeString("\n ");
|
||||||
|
else if (python)
|
||||||
|
lib.writeString("\\\n");
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,18 +996,37 @@ void RCCResourceLibrary::writeDecimal(int value)
|
|||||||
write(buf, n + 1); // write() takes a size including terminating NUL
|
write(buf, n + 1); // write() takes a size including terminating NUL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char hexDigits[] = "0123456789abcdef";
|
||||||
|
|
||||||
|
inline void RCCResourceLibrary::write2HexDigits(quint8 number)
|
||||||
|
{
|
||||||
|
writeChar(hexDigits[number >> 4]);
|
||||||
|
writeChar(hexDigits[number & 0xf]);
|
||||||
|
}
|
||||||
|
|
||||||
void RCCResourceLibrary::writeHex(quint8 tmp)
|
void RCCResourceLibrary::writeHex(quint8 tmp)
|
||||||
{
|
{
|
||||||
const char digits[] = "0123456789abcdef";
|
switch (m_format) {
|
||||||
writeChar('0');
|
case RCCResourceLibrary::Python3_Code:
|
||||||
writeChar('x');
|
case RCCResourceLibrary::Python2_Code:
|
||||||
if (tmp < 16) {
|
if (tmp >= 32 && tmp < 127 && tmp != '"' && tmp != '\\') {
|
||||||
writeChar(digits[tmp]);
|
writeChar(char(tmp));
|
||||||
} else {
|
} else {
|
||||||
writeChar(digits[tmp >> 4]);
|
writeChar('\\');
|
||||||
writeChar(digits[tmp & 0xf]);
|
writeChar('x');
|
||||||
|
write2HexDigits(tmp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
writeChar('0');
|
||||||
|
writeChar('x');
|
||||||
|
if (tmp < 16)
|
||||||
|
writeChar(hexDigits[tmp]);
|
||||||
|
else
|
||||||
|
write2HexDigits(tmp);
|
||||||
|
writeChar(',');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
writeChar(',');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCCResourceLibrary::writeNumber2(quint16 number)
|
void RCCResourceLibrary::writeNumber2(quint16 number)
|
||||||
@ -1038,7 +1094,9 @@ void RCCResourceLibrary::writeNumber8(quint64 number)
|
|||||||
|
|
||||||
bool RCCResourceLibrary::writeHeader()
|
bool RCCResourceLibrary::writeHeader()
|
||||||
{
|
{
|
||||||
if (m_format == C_Code || m_format == Pass1) {
|
switch (m_format) {
|
||||||
|
case C_Code:
|
||||||
|
case Pass1:
|
||||||
writeString("/****************************************************************************\n");
|
writeString("/****************************************************************************\n");
|
||||||
writeString("** Resource object code\n");
|
writeString("** Resource object code\n");
|
||||||
writeString("**\n");
|
writeString("**\n");
|
||||||
@ -1047,7 +1105,17 @@ bool RCCResourceLibrary::writeHeader()
|
|||||||
writeString("\n**\n");
|
writeString("\n**\n");
|
||||||
writeString("** WARNING! All changes made in this file will be lost!\n");
|
writeString("** WARNING! All changes made in this file will be lost!\n");
|
||||||
writeString( "*****************************************************************************/\n\n");
|
writeString( "*****************************************************************************/\n\n");
|
||||||
} else if (m_format == Binary) {
|
break;
|
||||||
|
case Python3_Code:
|
||||||
|
case Python2_Code:
|
||||||
|
writeString("# Resource object code (Python ");
|
||||||
|
writeChar(m_format == Python3_Code ? '3' : '2');
|
||||||
|
writeString(")\n");
|
||||||
|
writeString(pythonHeader1);
|
||||||
|
writeByteArray(QT_VERSION_STR);
|
||||||
|
writeString(pythonHeader2);
|
||||||
|
break;
|
||||||
|
case Binary:
|
||||||
writeString("qres");
|
writeString("qres");
|
||||||
writeNumber4(0);
|
writeNumber4(0);
|
||||||
writeNumber4(0);
|
writeNumber4(0);
|
||||||
@ -1055,6 +1123,9 @@ bool RCCResourceLibrary::writeHeader()
|
|||||||
writeNumber4(0);
|
writeNumber4(0);
|
||||||
if (m_formatVersion >= 3)
|
if (m_formatVersion >= 3)
|
||||||
writeNumber4(m_overallFlags);
|
writeNumber4(m_overallFlags);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1062,10 +1133,21 @@ bool RCCResourceLibrary::writeHeader()
|
|||||||
bool RCCResourceLibrary::writeDataBlobs()
|
bool RCCResourceLibrary::writeDataBlobs()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_errorDevice);
|
Q_ASSERT(m_errorDevice);
|
||||||
if (m_format == C_Code) {
|
switch (m_format) {
|
||||||
|
case C_Code:
|
||||||
writeString("static const unsigned char qt_resource_data[] = {\n");
|
writeString("static const unsigned char qt_resource_data[] = {\n");
|
||||||
} else if (m_format == Binary) {
|
break;
|
||||||
|
case Python3_Code:
|
||||||
|
writeString("qt_resource_data = b\"\\\n");
|
||||||
|
break;
|
||||||
|
case Python2_Code:
|
||||||
|
writeString("qt_resource_data = \"\\\n");
|
||||||
|
break;
|
||||||
|
case Binary:
|
||||||
m_dataOffset = m_out.size();
|
m_dataOffset = m_out.size();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_root)
|
if (!m_root)
|
||||||
@ -1091,24 +1173,46 @@ bool RCCResourceLibrary::writeDataBlobs()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_format == C_Code)
|
switch (m_format) {
|
||||||
|
case C_Code:
|
||||||
writeString("\n};\n\n");
|
writeString("\n};\n\n");
|
||||||
else if (m_format == Pass1) {
|
break;
|
||||||
|
case Python3_Code:
|
||||||
|
case Python2_Code:
|
||||||
|
writeString("\"\n\n");
|
||||||
|
break;
|
||||||
|
case Pass1:
|
||||||
if (offset < 8)
|
if (offset < 8)
|
||||||
offset = 8;
|
offset = 8;
|
||||||
writeString("\nstatic const unsigned char qt_resource_data[");
|
writeString("\nstatic const unsigned char qt_resource_data[");
|
||||||
writeByteArray(QByteArray::number(offset));
|
writeByteArray(QByteArray::number(offset));
|
||||||
writeString("] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };\n\n");
|
writeString("] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };\n\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RCCResourceLibrary::writeDataNames()
|
bool RCCResourceLibrary::writeDataNames()
|
||||||
{
|
{
|
||||||
if (m_format == C_Code || m_format == Pass1)
|
switch (m_format) {
|
||||||
|
case C_Code:
|
||||||
|
case Pass1:
|
||||||
writeString("static const unsigned char qt_resource_name[] = {\n");
|
writeString("static const unsigned char qt_resource_name[] = {\n");
|
||||||
else if (m_format == Binary)
|
break;
|
||||||
|
case Python3_Code:
|
||||||
|
writeString("qt_resource_name = b\"\\\n");
|
||||||
|
break;
|
||||||
|
case Python2_Code:
|
||||||
|
writeString("qt_resource_name = \"\\\n");
|
||||||
|
break;
|
||||||
|
case Binary:
|
||||||
m_namesOffset = m_out.size();
|
m_namesOffset = m_out.size();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
QHash<QString, int> names;
|
QHash<QString, int> names;
|
||||||
QStack<RCCFileInfo*> pending;
|
QStack<RCCFileInfo*> pending;
|
||||||
@ -1133,8 +1237,18 @@ bool RCCResourceLibrary::writeDataNames()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_format == C_Code || m_format == Pass1)
|
switch (m_format) {
|
||||||
|
case C_Code:
|
||||||
|
case Pass1:
|
||||||
writeString("\n};\n\n");
|
writeString("\n};\n\n");
|
||||||
|
break;
|
||||||
|
case Python3_Code:
|
||||||
|
case Python2_Code:
|
||||||
|
writeString("\"\n\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1149,10 +1263,24 @@ struct qt_rcc_compare_hash
|
|||||||
|
|
||||||
bool RCCResourceLibrary::writeDataStructure()
|
bool RCCResourceLibrary::writeDataStructure()
|
||||||
{
|
{
|
||||||
if (m_format == C_Code || m_format == Pass1)
|
switch (m_format) {
|
||||||
|
case C_Code:
|
||||||
|
case Pass1:
|
||||||
writeString("static const unsigned char qt_resource_struct[] = {\n");
|
writeString("static const unsigned char qt_resource_struct[] = {\n");
|
||||||
else if (m_format == Binary)
|
break;
|
||||||
|
case Python3_Code:
|
||||||
|
writeString("qt_resource_struct = b\"\\\n");
|
||||||
|
break;
|
||||||
|
case Python2_Code:
|
||||||
|
writeString("qt_resource_struct = \"\\\n");
|
||||||
|
break;
|
||||||
|
case Binary:
|
||||||
m_treeOffset = m_out.size();
|
m_treeOffset = m_out.size();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
QStack<RCCFileInfo*> pending;
|
QStack<RCCFileInfo*> pending;
|
||||||
|
|
||||||
if (!m_root)
|
if (!m_root)
|
||||||
@ -1196,8 +1324,18 @@ bool RCCResourceLibrary::writeDataStructure()
|
|||||||
pending.push(child);
|
pending.push(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_format == C_Code || m_format == Pass1)
|
switch (m_format) {
|
||||||
|
case C_Code:
|
||||||
|
case Pass1:
|
||||||
writeString("\n};\n\n");
|
writeString("\n};\n\n");
|
||||||
|
break;
|
||||||
|
case Python3_Code:
|
||||||
|
case Python2_Code:
|
||||||
|
writeString("\"\n\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1387,6 +1525,19 @@ bool RCCResourceLibrary::writeInitializer()
|
|||||||
p[i++] = (m_overallFlags >> 8) & 0xff;
|
p[i++] = (m_overallFlags >> 8) & 0xff;
|
||||||
p[i++] = (m_overallFlags >> 0) & 0xff;
|
p[i++] = (m_overallFlags >> 0) & 0xff;
|
||||||
}
|
}
|
||||||
|
} else if (m_format == Python3_Code || m_format == Python2_Code) {
|
||||||
|
writeString(R"(def qInitResources():
|
||||||
|
QtCore.qRegisterResourceData(0x)");
|
||||||
|
write2HexDigits(m_formatVersion);
|
||||||
|
writeString(R"(, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||||
|
|
||||||
|
def qCleanupResources():
|
||||||
|
QtCore.qUnregisterResourceData(0x)");
|
||||||
|
write2HexDigits(m_formatVersion);
|
||||||
|
writeString(R"(, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||||
|
|
||||||
|
qInitResources()
|
||||||
|
)");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
bool readFiles(bool listMode, QIODevice &errorDevice);
|
bool readFiles(bool listMode, QIODevice &errorDevice);
|
||||||
|
|
||||||
enum Format { Binary, C_Code, Pass1, Pass2 };
|
enum Format { Binary, C_Code, Pass1, Pass2, Python3_Code, Python2_Code };
|
||||||
void setFormat(Format f) { m_format = f; }
|
void setFormat(Format f) { m_format = f; }
|
||||||
Format format() const { return m_format; }
|
Format format() const { return m_format; }
|
||||||
|
|
||||||
@ -136,6 +136,7 @@ private:
|
|||||||
void writeAddNamespaceFunction(const QByteArray &name);
|
void writeAddNamespaceFunction(const QByteArray &name);
|
||||||
void writeDecimal(int value);
|
void writeDecimal(int value);
|
||||||
void writeHex(quint8 number);
|
void writeHex(quint8 number);
|
||||||
|
void write2HexDigits(quint8 number);
|
||||||
void writeNumber2(quint16 number);
|
void writeNumber2(quint16 number);
|
||||||
void writeNumber4(quint32 number);
|
void writeNumber4(quint32 number);
|
||||||
void writeNumber8(quint64 number);
|
void writeNumber8(quint64 number);
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
# Resource object code (Python 3)
|
||||||
|
# Created by: object code
|
||||||
|
# Created by: The Resource Compiler for Qt version 5.14.0
|
||||||
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
from PySide2 import QtCore
|
||||||
|
|
||||||
|
qt_resource_data = b"\
|
||||||
|
\x00\x00\x00\x02\
|
||||||
|
0\
|
||||||
|
1\
|
||||||
|
\x00\x00\x00#\
|
||||||
|
0\
|
||||||
|
123456789 012345\
|
||||||
|
6789 0123456789 \
|
||||||
|
12\
|
||||||
|
\x00\x00\x00\x01\
|
||||||
|
@\
|
||||||
|
\
|
||||||
|
\x00\x00\x00\x00\
|
||||||
|
\
|
||||||
|
"
|
||||||
|
|
||||||
|
qt_resource_name = b"\
|
||||||
|
\x00\x04\
|
||||||
|
\x00\x06\xa8\xa1\
|
||||||
|
\x00d\
|
||||||
|
\x00a\x00t\x00a\
|
||||||
|
\x00\x0a\
|
||||||
|
\x04\x08\x0a\xb4\
|
||||||
|
\x00d\
|
||||||
|
\x00a\x00t\x00a\x00-\x002\x00.\x00t\x00x\x00t\
|
||||||
|
\x00\x0b\
|
||||||
|
\x00\xb5Ot\
|
||||||
|
\x00d\
|
||||||
|
\x00a\x00t\x00a\x00-\x003\x005\x00.\x00t\x00x\x00t\
|
||||||
|
\x00\x0a\
|
||||||
|
\x04\x11\x0a\xb4\
|
||||||
|
\x00d\
|
||||||
|
\x00a\x00t\x00a\x00-\x001\x00.\x00t\x00x\x00t\
|
||||||
|
\x00\x0a\
|
||||||
|
\x04\x0e\x0a\xb4\
|
||||||
|
\x00d\
|
||||||
|
\x00a\x00t\x00a\x00-\x000\x00.\x00t\x00x\x00t\
|
||||||
|
"
|
||||||
|
|
||||||
|
qt_resource_struct = b"\
|
||||||
|
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||||
|
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||||
|
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\
|
||||||
|
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||||
|
\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\
|
||||||
|
IGNORE: (time stamp)
|
||||||
|
\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||||
|
IGNORE: (time stamp)
|
||||||
|
\x00\x00\x00^\x00\x00\x00\x00\x00\x01\x00\x00\x002\
|
||||||
|
IGNORE: (time stamp)
|
||||||
|
\x00\x00\x00D\x00\x00\x00\x00\x00\x01\x00\x00\x00-\
|
||||||
|
IGNORE: (time stamp)
|
||||||
|
"
|
||||||
|
|
||||||
|
def qInitResources():
|
||||||
|
QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||||
|
|
||||||
|
def qCleanupResources():
|
||||||
|
QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||||
|
|
||||||
|
qInitResources()
|
@ -89,6 +89,8 @@ private slots:
|
|||||||
void readback_data();
|
void readback_data();
|
||||||
void readback();
|
void readback();
|
||||||
|
|
||||||
|
void python();
|
||||||
|
|
||||||
void cleanupTestCase();
|
void cleanupTestCase();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -107,6 +109,12 @@ void tst_rcc::initTestCase()
|
|||||||
QVERIFY(!m_dataPath.isEmpty());
|
QVERIFY(!m_dataPath.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool isPythonComment(const QString &line)
|
||||||
|
{
|
||||||
|
return line.startsWith(QLatin1Char('#'));
|
||||||
|
}
|
||||||
|
|
||||||
static QString doCompare(const QStringList &actual, const QStringList &expected,
|
static QString doCompare(const QStringList &actual, const QStringList &expected,
|
||||||
const QString &timeStampPath)
|
const QString &timeStampPath)
|
||||||
{
|
{
|
||||||
@ -116,10 +124,13 @@ static QString doCompare(const QStringList &actual, const QStringList &expected,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
|
const bool isPython = isPythonComment(expected.constFirst());
|
||||||
for (int i = 0, n = expected.size(); i != n; ++i) {
|
for (int i = 0, n = expected.size(); i != n; ++i) {
|
||||||
QString expectedLine = expected.at(i);
|
QString expectedLine = expected.at(i);
|
||||||
if (expectedLine.startsWith("IGNORE:"))
|
if (expectedLine.startsWith("IGNORE:"))
|
||||||
continue;
|
continue;
|
||||||
|
if (isPython && isPythonComment(expectedLine) && isPythonComment(actual.at(i)))
|
||||||
|
continue;
|
||||||
if (expectedLine.startsWith("TIMESTAMP:")) {
|
if (expectedLine.startsWith("TIMESTAMP:")) {
|
||||||
const QString relativePath = expectedLine.mid(strlen("TIMESTAMP:"));
|
const QString relativePath = expectedLine.mid(strlen("TIMESTAMP:"));
|
||||||
const QFileInfo fi(timeStampPath + QLatin1Char('/') + relativePath);
|
const QFileInfo fi(timeStampPath + QLatin1Char('/') + relativePath);
|
||||||
@ -405,6 +416,36 @@ void tst_rcc::readback()
|
|||||||
QCOMPARE(resourceData, fileSystemData);
|
QCOMPARE(resourceData, fileSystemData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_rcc::python()
|
||||||
|
{
|
||||||
|
const QString path = m_dataPath + QLatin1String("/sizes");
|
||||||
|
const QString testFileRoot = path + QLatin1String("/size-2-0-35-1");
|
||||||
|
const QString qrcFile = testFileRoot + QLatin1String(".qrc");
|
||||||
|
const QString expectedFile = testFileRoot + QLatin1String("_python.expected");
|
||||||
|
const QString actualFile = testFileRoot + QLatin1String(".rcc");
|
||||||
|
|
||||||
|
QProcess process;
|
||||||
|
process.setWorkingDirectory(path);
|
||||||
|
process.start(m_rcc, { "-g", "python", "-o", actualFile, qrcFile});
|
||||||
|
QVERIFY2(process.waitForStarted(), msgProcessStartFailed(process).constData());
|
||||||
|
if (!process.waitForFinished()) {
|
||||||
|
process.kill();
|
||||||
|
QFAIL(msgProcessTimeout(process).constData());
|
||||||
|
}
|
||||||
|
QVERIFY2(process.exitStatus() == QProcess::NormalExit,
|
||||||
|
msgProcessCrashed(process).constData());
|
||||||
|
QVERIFY2(process.exitCode() == 0,
|
||||||
|
msgProcessFailed(process).constData());
|
||||||
|
|
||||||
|
const auto actualLines = readLinesFromFile(actualFile, QString::KeepEmptyParts);
|
||||||
|
QVERIFY(!actualLines.isEmpty());
|
||||||
|
const auto expectedLines = readLinesFromFile(expectedFile, QString::KeepEmptyParts);
|
||||||
|
QVERIFY(!expectedLines.isEmpty());
|
||||||
|
const QString diff = doCompare(actualLines, expectedLines, path);
|
||||||
|
if (!diff.isEmpty())
|
||||||
|
QFAIL(qPrintable(diff));
|
||||||
|
}
|
||||||
|
|
||||||
void tst_rcc::cleanupTestCase()
|
void tst_rcc::cleanupTestCase()
|
||||||
{
|
{
|
||||||
QDir dataDir(m_dataPath + QLatin1String("/binary"));
|
QDir dataDir(m_dataPath + QLatin1String("/binary"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user