Commit 68e56910 authored by Tobias Hunger's avatar Tobias Hunger Committed by Tim Jenssen

BaseQtVersion: Fix Qt build string parsing

This fixes Qt build string parsing based on feedback from Thiago.

Also adds unit test for the code that parses the build string so that
we can be more sure that it actually works as expected.

Change-Id: I23cff7125be4c7c87d5eba4b1db7cb47c2479b66
Reviewed-by: default avatarThiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent 3df1d5ef
......@@ -1746,7 +1746,7 @@ static QByteArray scanQtBinaryForBuildString(const FileName &library)
const size_t oneMiB = 1024 * 1024;
const size_t keepSpace = 4096;
const size_t bufferSize = oneMiB + keepSpace;
QByteArray buffer(bufferSize, '\0');
QByteArray buffer(bufferSize, Qt::Uninitialized);
char *const readStart = buffer.data() + keepSpace;
auto readStartIt = buffer.begin() + keepSpace;
......@@ -1794,39 +1794,72 @@ static QByteArray scanQtBinaryForBuildString(const FileName &library)
return buildString;
}
static Abi refineAbiFromBuildString(const QByteArray &buildString, const Abi &probableAbi)
static QStringList extractFieldsFromBuildString(const QByteArray &buildString)
{
if (buildString.isEmpty()
|| buildString.count() > 4096)
return Abi();
return QStringList();
const QRegularExpression buildStringMatcher("^Qt "
"([\\d\\.a-zA-Z]*) " // Qt version
"([\\d\\.a-zA-Z]*) " // Qt version
"\\("
"([a-z\\d_]*)-" // CPU
"(big|little)_endian-"
"([a-z]+(?:32|64))" // pointer information
"(?:-(qreal|))?" // extra information like -qreal
"(?:-([^-]+))? " // ABI information
"([\\w_-]+) " // Abi information
"(shared|static) (?:\\(dynamic\\) )?"
"(debug|release)"
" build; by "
"(.*)" // compiler with extra info
"(.*)" // compiler with extra info
"\\)$");
QTC_ASSERT(buildStringMatcher.isValid(), qWarning() << buildStringMatcher.errorString());
const QRegularExpressionMatch match = buildStringMatcher.match(QString::fromUtf8(buildString));
QTC_ASSERT(match.hasMatch(), return Abi());
// const QString qtVersion = match.captured(1);
// const QString cpu = match.captured(2);
// const bool littleEndian = (match.captured(3) == "little");
// const QString pointer = match.captured(4);
// const QString extra = match.captured(5);
// const QString abiString = match.captured(6);
// const QString linkage = match.captured(7);
// const QString buildType = match.captured(8);
const QString compiler = match.captured(9);
if (!match.hasMatch())
return QStringList();
QStringList result;
result.append(match.captured(1)); // qtVersion
// Abi info string:
QStringList abiInfo = match.captured(2).split('-', QString::SkipEmptyParts);
result.append(abiInfo.takeFirst()); // cpu
const QString endian = abiInfo.takeFirst();
QTC_ASSERT(endian.endsWith("_endian"), return QStringList());
result.append(endian.left(endian.count() - 7)); // without the "_endian"
result.append(abiInfo.takeFirst()); // pointer
if (abiInfo.isEmpty()) {
// no extra info whatsoever:
result.append(""); // qreal is unset
result.append(""); // extra info is unset
} else {
const QString next = abiInfo.at(0);
if (next.startsWith("qreal_")) {
abiInfo.takeFirst();
result.append(next.mid(6)); // qreal: without the "qreal_" part;
} else {
result.append(""); // qreal is unset!
}
result.append(abiInfo.join('-')); // extra abi strings
}
result.append(match.captured(3)); // linkage
result.append(match.captured(4)); // buildType
result.append(match.captured(5)); // compiler
return result;
}
static Abi refineAbiFromBuildString(const QByteArray &buildString, const Abi &probableAbi)
{
QStringList buildStringData = extractFieldsFromBuildString(buildString);
if (buildStringData.count() != 9)
return probableAbi;
const QString compiler = buildStringData.at(8);
Abi::Architecture arch = probableAbi.architecture();
Abi::OS os = probableAbi.os();
......@@ -1879,3 +1912,57 @@ QList<Abi> BaseQtVersion::qtAbisFromLibrary(const FileNameList &coreLibraries)
}
return res;
}
#if defined(WITH_TESTS)
#include <QTest>
#include "qtsupportplugin.h"
void QtSupportPlugin::testQtBuildStringParsing_data()
{
QTest::addColumn<QByteArray>("buildString");
QTest::addColumn<QString>("expected");
QTest::newRow("invalid build string")
<< QByteArray("Qt with invalid buildstring") << QString();
QTest::newRow("empty build string")
<< QByteArray("") << QString();
QTest::newRow("huge build string")
<< QByteArray(8192, 'x') << QString();
QTest::newRow("valid build string")
<< QByteArray("Qt 5.7.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 6.2.1 20160830)")
<< "5.7.1;x86_64;little;lp64;;;shared;release;GCC 6.2.1 20160830";
QTest::newRow("with qreal")
<< QByteArray("Qt 5.7.1 (x86_64-little_endian-lp64-qreal___fp16 shared (dynamic) release build; by GCC 6.2.1 20160830)")
<< "5.7.1;x86_64;little;lp64;__fp16;;shared;release;GCC 6.2.1 20160830";
QTest::newRow("with qreal and abi")
<< QByteArray("Qt 5.7.1 (x86_64-little_endian-lp64-qreal___fp16-eabi shared (dynamic) release build; by GCC 6.2.1 20160830)")
<< "5.7.1;x86_64;little;lp64;__fp16;eabi;shared;release;GCC 6.2.1 20160830";
QTest::newRow("with qreal, eabi and softfloat")
<< QByteArray("Qt 5.7.1 (x86_64-little_endian-lp64-qreal___fp16-eabi-softfloat shared (dynamic) release build; by GCC 6.2.1 20160830)")
<< "5.7.1;x86_64;little;lp64;__fp16;eabi-softfloat;shared;release;GCC 6.2.1 20160830";
QTest::newRow("with eabi")
<< QByteArray("Qt 5.7.1 (x86_64-little_endian-lp64-eabi shared (dynamic) release build; by GCC 6.2.1 20160830)")
<< "5.7.1;x86_64;little;lp64;;eabi;shared;release;GCC 6.2.1 20160830";
QTest::newRow("with eabi and softfloat")
<< QByteArray("Qt 5.7.1 (x86_64-little_endian-lp64-eabi-softfloat shared (dynamic) release build; by GCC 6.2.1 20160830)")
<< "5.7.1;x86_64;little;lp64;;eabi-softfloat;shared;release;GCC 6.2.1 20160830";
}
void QtSupportPlugin::testQtBuildStringParsing()
{
QFETCH(QByteArray, buildString);
QFETCH(QString, expected);
QStringList expectedList;
if (!expected.isEmpty())
expectedList = expected.split(';');
QStringList actual = extractFieldsFromBuildString(buildString);
QCOMPARE(expectedList, actual);
}
#endif // WITH_TESTS
......@@ -53,6 +53,10 @@ private slots:
void testQtProjectImporter_oneProject_data();
void testQtProjectImporter_oneProject();
void testQtBuildStringParsing_data();
void testQtBuildStringParsing();
#if 0
void testQtProjectImporter_oneProjectExistingKit();
void testQtProjectImporter_oneProjectNewKitExistingQt();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment