diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 0fdba3671d1..a1089914fd2 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -512,6 +512,12 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, reader.raiseError("expected tag"_L1); else tokens.push(RccTag); + } else if (reader.name() == m_strings.TAG_LEGAL) { + if (tokens.isEmpty() || tokens.top() != RccTag) { + reader.raiseError("unexpected tag"_L1); + } else { + m_legal = reader.readElementText().trimmed(); + } } else if (reader.name() == m_strings.TAG_RESOURCE) { if (tokens.isEmpty() || tokens.top() != RccTag) { reader.raiseError("unexpected tag"_L1); @@ -1087,11 +1093,20 @@ void RCCResourceLibrary::writeNumber8(quint64 number) bool RCCResourceLibrary::writeHeader() { + auto writeCopyright = [this](QByteArrayView prefix) { + const QStringList lines = m_legal.split(u'\n', Qt::SkipEmptyParts); + for (const QString &line : lines) { + write(prefix.data(), prefix.size()); + writeString(line.toUtf8().trimmed()); + writeChar('\n'); + } + }; switch (m_format) { case C_Code: case Pass1: writeString("/****************************************************************************\n"); writeString("** Resource object code\n"); + writeCopyright("** "); writeString("**\n"); writeString("** Created by: The Resource Compiler for Qt version "); writeByteArray(QT_VERSION_STR); @@ -1105,6 +1120,7 @@ bool RCCResourceLibrary::writeHeader() break; case Python_Code: writeString("# Resource object code (Python 3)\n"); + writeCopyright("# "); writeString("# Created by: object code\n"); writeString("# Created by: The Resource Compiler for Qt version "); writeByteArray(QT_VERSION_STR); diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h index bfc3503da87..e2ae8c5240e 100644 --- a/src/tools/rcc/rcc.h +++ b/src/tools/rcc/rcc.h @@ -93,6 +93,7 @@ private: const QString TAG_RCC; const QString TAG_RESOURCE; const QString TAG_FILE; + const QString TAG_LEGAL = QLatin1StringView("legal"); const QString ATTRIBUTE_LANG; const QString ATTRIBUTE_PREFIX; const QString ATTRIBUTE_ALIAS; @@ -134,6 +135,7 @@ private: QString m_resourceRoot; QString m_initName; QString m_outputName; + QString m_legal; Format m_format; bool m_verbose; CompressionAlgorithm m_compressionAlgo; diff --git a/tests/auto/tools/rcc/data/.gitattributes b/tests/auto/tools/rcc/data/.gitattributes new file mode 100644 index 00000000000..89d6e8fe1c7 --- /dev/null +++ b/tests/auto/tools/rcc/data/.gitattributes @@ -0,0 +1,2 @@ +# Keep parentdir.txt with LF line endings +parentdir.txt -text diff --git a/tests/auto/tools/rcc/data/legal/legal.qrc b/tests/auto/tools/rcc/data/legal/legal.qrc new file mode 100644 index 00000000000..5eb7f584165 --- /dev/null +++ b/tests/auto/tools/rcc/data/legal/legal.qrc @@ -0,0 +1,10 @@ + + + + Copyright (C) 2024 Intel Corporation. + SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + + ../parentdir.txt + + diff --git a/tests/auto/tools/rcc/data/legal/rcc_legal.cpp b/tests/auto/tools/rcc/data/legal/rcc_legal.cpp new file mode 100644 index 00000000000..7522e1b34ff --- /dev/null +++ b/tests/auto/tools/rcc/data/legal/rcc_legal.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** Resource object code +** Copyright (C) 2024 Intel Corporation. +** SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +** +** Created by: The Resource Compiler for Qt version 6.8.0 +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#ifdef _MSC_VER +// disable informational message "function ... selected for automatic inline expansion" +#pragma warning (disable: 4711) +#endif + +static const unsigned char qt_resource_data[] = { + // parentdir.txt + 0x0,0x0,0x0,0x1a, + 0x61, + 0x62,0x63,0x64,0x65,0x66,0x67,0x69,0x68,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72, + 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0xa, + +}; + +static const unsigned char qt_resource_name[] = { + // parentdir.txt + 0x0,0xd, + 0x6,0x14,0xd1,0x74, + 0x0,0x70, + 0x0,0x61,0x0,0x72,0x0,0x65,0x0,0x6e,0x0,0x74,0x0,0x64,0x0,0x69,0x0,0x72,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74, + +}; + +static const unsigned char qt_resource_struct[] = { + // : + 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1, +0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + // :/parentdir.txt + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0, +TIMESTAMP:../parentdir.txt + +}; + +#ifdef QT_NAMESPACE +# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name +# define QT_RCC_MANGLE_NAMESPACE0(x) x +# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b +# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b) +# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \ + QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE)) +#else +# define QT_RCC_PREPEND_NAMESPACE(name) name +# define QT_RCC_MANGLE_NAMESPACE(name) name +#endif + +#if defined(QT_INLINE_NAMESPACE) +inline namespace QT_NAMESPACE { +#elif defined(QT_NAMESPACE) +namespace QT_NAMESPACE { +#endif + +bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); +bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); + +#ifdef QT_NAMESPACE +} +#endif + +int QT_RCC_MANGLE_NAMESPACE(qInitResources)(); +int QT_RCC_MANGLE_NAMESPACE(qInitResources)() +{ + int version = 3; + QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData) + (version, qt_resource_struct, qt_resource_name, qt_resource_data); + return 1; +} + +int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); +int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)() +{ + int version = 3; + QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData) + (version, qt_resource_struct, qt_resource_name, qt_resource_data); + return 1; +} + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace { + struct initializer { + initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); } + ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); } + } dummy; +} + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif diff --git a/tests/auto/tools/rcc/tst_rcc.cpp b/tests/auto/tools/rcc/tst_rcc.cpp index 88a6e17e2f2..af4a992d5cf 100644 --- a/tests/auto/tools/rcc/tst_rcc.cpp +++ b/tests/auto/tools/rcc/tst_rcc.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2012 Giuseppe D'Angelo // Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2024 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include @@ -148,6 +149,9 @@ void tst_rcc::rcc_data() QTest::newRow("size-1") << sizesPath << "size-1.qrc" << "size-1.expected"; QTest::newRow("size-2-0-35-1") << sizesPath << "size-2-0-35-1.qrc" << (sizeof(size_t) == 8 ? "size-2-0-35-1.expected" : "size-2-0-35-1.expected32"); + + QTest::newRow("legal") << m_dataPath + QLatin1StringView("/legal") + << "legal.qrc" << "rcc_legal.cpp"; } static QStringList readLinesFromFile(const QString &fileName,