rcc: add the ability to output copyrights in the output
According to gnu.org[1] > When a file is automatically generated from some other file in the > distribution, it is useful for the automatic procedure to copy the > copyright notice and permission notice of the file it is generated > from, if possible. This commit allows us to add copyright notices to the .qrc files themselves and additionally have that be output into the generated .rcc (of which we have a few committed to the repository) [ChangeLog][rcc] The Qt Resource Compiler now accepts a <legal> XML tag inside the main <RCC> entry, which can be used to document the copyright of the resource file itself and other terms of use (even though the file is probably created by a tool like Qt Creator's resource editor). The text of this copyright will be emitted in the generated C++ or Python source code. [1] https://www.gnu.org/prep/maintain/html_node/Copyright-Notices.html Change-Id: If05cb740b64f42eba21efffd17d00417433f1ee9 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
24b1e52a1a
commit
d5dd7da3ee
@ -512,6 +512,12 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
|
|||||||
reader.raiseError("expected <RCC> tag"_L1);
|
reader.raiseError("expected <RCC> tag"_L1);
|
||||||
else
|
else
|
||||||
tokens.push(RccTag);
|
tokens.push(RccTag);
|
||||||
|
} else if (reader.name() == m_strings.TAG_LEGAL) {
|
||||||
|
if (tokens.isEmpty() || tokens.top() != RccTag) {
|
||||||
|
reader.raiseError("unexpected <legal> tag"_L1);
|
||||||
|
} else {
|
||||||
|
m_legal = reader.readElementText().trimmed();
|
||||||
|
}
|
||||||
} else if (reader.name() == m_strings.TAG_RESOURCE) {
|
} else if (reader.name() == m_strings.TAG_RESOURCE) {
|
||||||
if (tokens.isEmpty() || tokens.top() != RccTag) {
|
if (tokens.isEmpty() || tokens.top() != RccTag) {
|
||||||
reader.raiseError("unexpected <RESOURCE> tag"_L1);
|
reader.raiseError("unexpected <RESOURCE> tag"_L1);
|
||||||
@ -1087,11 +1093,20 @@ void RCCResourceLibrary::writeNumber8(quint64 number)
|
|||||||
|
|
||||||
bool RCCResourceLibrary::writeHeader()
|
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) {
|
switch (m_format) {
|
||||||
case C_Code:
|
case C_Code:
|
||||||
case Pass1:
|
case Pass1:
|
||||||
writeString("/****************************************************************************\n");
|
writeString("/****************************************************************************\n");
|
||||||
writeString("** Resource object code\n");
|
writeString("** Resource object code\n");
|
||||||
|
writeCopyright("** ");
|
||||||
writeString("**\n");
|
writeString("**\n");
|
||||||
writeString("** Created by: The Resource Compiler for Qt version ");
|
writeString("** Created by: The Resource Compiler for Qt version ");
|
||||||
writeByteArray(QT_VERSION_STR);
|
writeByteArray(QT_VERSION_STR);
|
||||||
@ -1105,6 +1120,7 @@ bool RCCResourceLibrary::writeHeader()
|
|||||||
break;
|
break;
|
||||||
case Python_Code:
|
case Python_Code:
|
||||||
writeString("# Resource object code (Python 3)\n");
|
writeString("# Resource object code (Python 3)\n");
|
||||||
|
writeCopyright("# ");
|
||||||
writeString("# Created by: object code\n");
|
writeString("# Created by: object code\n");
|
||||||
writeString("# Created by: The Resource Compiler for Qt version ");
|
writeString("# Created by: The Resource Compiler for Qt version ");
|
||||||
writeByteArray(QT_VERSION_STR);
|
writeByteArray(QT_VERSION_STR);
|
||||||
|
@ -93,6 +93,7 @@ private:
|
|||||||
const QString TAG_RCC;
|
const QString TAG_RCC;
|
||||||
const QString TAG_RESOURCE;
|
const QString TAG_RESOURCE;
|
||||||
const QString TAG_FILE;
|
const QString TAG_FILE;
|
||||||
|
const QString TAG_LEGAL = QLatin1StringView("legal");
|
||||||
const QString ATTRIBUTE_LANG;
|
const QString ATTRIBUTE_LANG;
|
||||||
const QString ATTRIBUTE_PREFIX;
|
const QString ATTRIBUTE_PREFIX;
|
||||||
const QString ATTRIBUTE_ALIAS;
|
const QString ATTRIBUTE_ALIAS;
|
||||||
@ -134,6 +135,7 @@ private:
|
|||||||
QString m_resourceRoot;
|
QString m_resourceRoot;
|
||||||
QString m_initName;
|
QString m_initName;
|
||||||
QString m_outputName;
|
QString m_outputName;
|
||||||
|
QString m_legal;
|
||||||
Format m_format;
|
Format m_format;
|
||||||
bool m_verbose;
|
bool m_verbose;
|
||||||
CompressionAlgorithm m_compressionAlgo;
|
CompressionAlgorithm m_compressionAlgo;
|
||||||
|
2
tests/auto/tools/rcc/data/.gitattributes
vendored
Normal file
2
tests/auto/tools/rcc/data/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Keep parentdir.txt with LF line endings
|
||||||
|
parentdir.txt -text
|
10
tests/auto/tools/rcc/data/legal/legal.qrc
Normal file
10
tests/auto/tools/rcc/data/legal/legal.qrc
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE RCC>
|
||||||
|
<RCC version="1.0">
|
||||||
|
<legal>
|
||||||
|
Copyright (C) 2024 Intel Corporation.
|
||||||
|
SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
</legal>
|
||||||
|
<qresource>
|
||||||
|
<file>../parentdir.txt</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
101
tests/auto/tools/rcc/data/legal/rcc_legal.cpp
Normal file
101
tests/auto/tools/rcc/data/legal/rcc_legal.cpp
Normal file
@ -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
|
@ -1,5 +1,6 @@
|
|||||||
// Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>
|
// Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>
|
||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
// Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
// Copyright (C) 2024 Intel Corporation.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
@ -148,6 +149,9 @@ void tst_rcc::rcc_data()
|
|||||||
QTest::newRow("size-1") << sizesPath << "size-1.qrc" << "size-1.expected";
|
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" <<
|
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");
|
(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,
|
static QStringList readLinesFromFile(const QString &fileName,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user