Add support for surrogate code points U+D800 through U+DFFF,
represent them with JSON escape sequences.
https://github.com/tc39/proposal-well-formed-stringify
Change-Id: I84fea53a8ef400beebefdba10ea82dc510fe7dda
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
In preparation of deprecating QLinkedList.
This actually simplifies the code, since std::list has a ctor from size,
which QLinkedList lacks, and which the code worked around by using
initializer_list.
Change-Id: I07f9d590f863d9e4e00de73339cdfa27079f6e03
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The TZ environment variable can validly contain a POSIX rule, rather
than an IANA ID, as described here:
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
However, if TZ were set to such a value, leading to it being used as
systemTimeZoneId(), it would be passed to QTzTimeZonePrivate::init(),
which is a no-op unless it manages to open a zoneinfo/ file with the
given ianaId as name. When the environment variable doesn't name a
zoneinfo/ file, we would thus get an invalid time-zone. We can,
instead, check whether the ianaId looks like a valid POSIX rule and,
if it does, use it as m_posixRule, enabling us to correctly handle
this case.
Tweak parsing of POSIX rules so that a zone using name "UTC" or "GMT"
with an offset other than 0 will be rejected as invalid. This avoids
parsing a zone name such as "GMT+17" or "UTC+00:01" as a POSIX rule,
where it should be understood as an offset from UTC (and only certain
well-established offsets are supported).
Added two test-cases to tst_QTimeZone::tzTest() for validity of a
POSIX zone value - a simple one constructed during discussion of the
bug, the other taken from an example in:
http://leaf.sourceforge.net/doc/buci-tz3.html
Task-number: QTBUG-75565
Change-Id: Ia5cb1cc56b13b0f6b56258e48be98d04d909e32a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Conflicts:
src/corelib/tools/qlocale_data_p.h
(Regenerated by running the scripts in util/local_database/)
src/gui/opengl/qopengltextureuploader.cpp
Done-With: Edward Welbourne <edward.welbourne@qt.io>
Done-With: Allan Sandfeld Jensen <allan.jensen@qt.io>
Change-Id: I12df7f066ed0a25eb109f61c4b8d8dea63b683e2
If the deadline is far in the future, the conversions to nanoseconds
or internal arithmetic may overflow and give an invalid object, thus
the deadline may end up in the past. Added a test to the testlib
selftest for sleep.
[ChangeLog][QtCore][QDeadlineTimer] Fixed integer overflows
leading to immediate timeouts.
Task-number: QTBUG-69750
Change-Id: I9814eccdf9f9b3add9ca66ec3e27e10cd5ad54a8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Users should use range constructors instead to do the conversion.
Keep conversion methods between QList and QVector as these will turn
into a no-op in Qt 6, whereas forcing people to use range constructors
would lead to deep copies of the data.
Change-Id: Id9fc9e4d007044e019826da523e8418857c91283
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This closes one compatibility gap with QList, to make
it easier to replace QList with QVector in Qt6.
Change-Id: I5655bc4cd2150a6f09a1ed68c0742f3b42ca47e4
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
The formatting of times in Norwegian has reverted to using dots in
place of colons, as it did before v31 (commit 82deb0ad1), so reverted
the tests to their state before that.
Change-Id: I8a09ce253731bb0f0f3caca117f06ad568940a81
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
ask our users to use the range constructors instead. This will allow
us to remove the include dependency towards <list> and <vector> in
Qt 6.
Change-Id: Id90f2058432e19941de1fa847100a7920432ad71
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Remove remaining handling of missing support for rvalue refs.
Change-Id: I78bab8bccfeeb9c76f464f345874364a37e4840a
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Mimicking what we currently have for QSharedPointer, but also adding
* snake_case version (matching the ones in std)
* rvalue-overloaded versions (matching the C++2a overloads).
[ChangeLog][QtCore][QSharedPointer] Overloads of
qSharedPointerObjectCast have been added to work on std::shared_ptr.
Change-Id: I26ddffd82b000bf876e7c141fdce86a7b8c1d75a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The file system appears to cache too aggressively, so if the reported
storage size doesn't change after flushing to disk, ignore the failure.
Change-Id: Iba7dce79591447fac296bfe92c2dc993d36d0c2a
Fixes: QTBUG-69868
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
QLineF::intersect() does not follow the naming rules for functions.
Therefore add a replacement function intersects() instead and also
rename the return type from IntersectType to IntersectionType
[ChangeLog][QtCore][QLineF] added QLineF::intersects() as a replacement
for QLineF::intersect()
Change-Id: I744b960ea339cb817facb12f296f78cca3e7d938
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io>
Reviewed-by: Konstantin Shegunov <kshegunov@gmail.com>
QMap and QMultiMap will go in a separate commit, due to QMap's
insertion behavior that "reverses" the inserted elements.
[ChangeLog][QtCore][QHash] Added range constructor.
[ChangeLog][QtCore][QMultiHash] Added range constructor.
Change-Id: Icfd0d0afde27792e8439ed6df3e8774696b134d3
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Sérgio Martins <sergio.martins@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
These methods give the first and last QDateTime values in the given
day, for a given time-zone or time-spec. These are usually the
relevant midnight, or the millisecond before, except when time-zone
transitions (typically DST changes) skip it, when care is needed to
select the right moment. Adapted some code to make use of the new
API, eliminating some old cruft from qdatetimeparser_p.h in the
process.
[ChangeLog][QtCore][QDate] Added startOfDay() and endOfDay() methods
to provide a QDateTime at the start and end of a given date, taking
account of any time skipped by transitions, e.g. a DST spring-forward,
which can lead to a day starting at 01:00 or ending just before 23:00.
Task-number: QTBUG-64485
Change-Id: I3dd7a34bedfbec8f8af00c43d13f50f99346ecd0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
In QCOMPARE, handle NaNs and infinities the way tests want them
handled, rather than by strict IEEE rules. In particular, if a test
expects NaN, this lets it treat that just like any other expected
value, despite NaN != NaN as float16 values. Likewise, format
infinities and NaNs specially in toString() so that they're reported
consistently.
Enable the qfloat16 tests that depend on this QCOMPARE() behavior.
Refise the testlib selftest's float test to test qfloat16 the same way
it tests float and double (and format the test the same way).
This is a follow-up to 37f617c405.
Change-Id: I433256a09b1657e6725d68d07c5f80d805bf586a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This extends support for qfloat16 sufficiently for the things testlib
needs in order to treat it as a first-class citizen. Extended tests
for qfloat to check qFpClassify() on it.
Change-Id: I906292afaf51cd9c94ba384ff5aaa855edd56da1
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This shall make it more nearly a first-class numeric type; in
particular, I need some of these for testlib's comparing and
formatting of float16 to handle NaNs and infinities sensibly.
Change-Id: Ic894dd0eb3e05653cd7645ab496463e7a884dff8
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
QDateTime's short names setUtcOffset() and utcOffset() have been
deprecated since 5.2, in favor of setOffsetFromUtc() and
offsetFromUtc().
QDate's shortDayName() and shortMOnthName() have been deprecated since
5.10, in favor of QLocale's dayName() and monthName(). Also, the
tests that were using them are testing methods only present when the
datestring feature is enabled; so condition them on that feature.
Change-Id: Ibfd4b132523ca8fbc1cb163353a44e0500877fd5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Something nice we'd like to detect for array-backed containers
is if the iterator passed is a Contiguous one; if the type is also
trivially copyable / Q_PRIMITIVE_TYPE, we could memcpy() the whole
range.
However, there's no trait in the Standard to detect contiguous
iterators (the best approximation would be detecting if the iterator
is actually a pointer). Also, it's probably not smart to do the work
now for QVector since QVector needs refactoring anyhow, and this work
will be lost.
QString and QByteArray are left in another commit.
[ChangeLog][QtCore][QVector] Added range constructor.
[ChangeLog][QtCore][QVarLengthArray] Added range constructor.
[ChangeLog][QtCore][QList] Added range constructor.
[ChangeLog][QtCore][QStringList] Added range constructor.
[ChangeLog][QtCore][QLinkedList] Added range constructor.
[ChangeLog][QtCore][QSet] Added range constructor.
Change-Id: I220edb796053c9c4d31a6dbdc7efc5fc0f6678f9
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
[ChangeLog][QtCore][QMetaObject] Non-copyable lambdas can now be used
with invokeMethod(). For consistency reasons, the functor object is
now always moved.
Fixes: QTBUG-69683
Change-Id: I66ff5e21d6d1926f0f7c5f8c304bed1a90b69917
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Usually, when you load a plugin, you don't want to load just any plugin
that fulfills a given interface, but rather a specific one. When loading
dynamic plugins you can differentiate the plugins by file name. This
doesn't work in the static case, and file names are also separate from
the plugin metadata shipped inside the plugin files.
To solve this problem, different hacks have been developed in various
places. QML extension plugins add a special property "uri" via the -M
option of moc, QML debug plugins expect you to add a json file with
an array of "Keys", Qt Creator plugins have a "Name" in their json
files, etc.
By allowing the identifier for the plugin to be specified inline with
the metadata declaration we can make many of the above workarounds
obsolete and provide a clean way for users to find their plugins.
Task-number: QTBUG-74775
Change-Id: Ie2af16c49d4c5aa5a77fab0fae1e0a4449bd7a39
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Without this change, the target of a symbolic link that points to a UNC
share would include UNC in the target path, and not be correctly made
absolute.
Add a relevant test case, and use the opportunity to factor out the
helper code that creates NTFS symlinks into a function that takes
care of error handling.
The file created with the new test case only gets cleaned up correctly
when passing the file path into QDir::rmdir, which is either way the
right thing to do.
[ChangeLog][QtCore][QFileInfo] Fixed resolving of symbolic links to UNC
shares on NTFS file systems.
Change-Id: I9ba75d627aedf7c4cc289f0cb71088d795d30d8a
Fixes: QTBUG-73688
Task-number: QTBUG-63970
Task-number: QTBUG-30401
Task-number: QTBUG-20791
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
QMetaObject::newInstance returns a QObject, thus it's not possible to
create a new instance of a Q_GADGET using this function. Previously, we
returned a non-null QObject pointer for such scenarios, which then
leads to crashes when one tries to use it. Now, we check whether the
meta object inherits QObject's meta object, and error out early
otherwise.
Change-Id: I7b1fb6c8d48b3e98161894be2f281a491963345e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The first replacement had missed objective-C++ code some places ourside
the src dir.
In C-files Q_DECL_NOTHROW is replaced with Q_DECL_NOEXCEPT as we still
need to turn it off when compiled in C mode, but can get rid of the old
NOTHROW moniker.
Change-Id: I6370f57066679c5120d0265a69e7e378e09d4759
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The test changes the current directory to the test directory
in fromUserInputWithCwd(), but did not restore it, causing:
Totals 898 passed, 0 failed, 1 skipped, 0 blacklisted, 368ms
********* Finished testing of tst_QUrl *********
QTemporaryDir Unable to remove "C:\\TEMP\\tst_qurl-ryVxqu" most likely due to the presence of read-only files.
Restore the old directory at the end to fix this.
Change-Id: I62669868f3c6d97dd38ebac76515428c14b7e1e7
Reviewed-by: David Faure <david.faure@kdab.com>
QTimer::singleShot is optimized for zero timeouts when using the API
taking a string method name. This optimization was not used for the API
taking a PMF or functor. This patch adds it, making the various API
calls behave similarly from a performance point of view.
The approach taken here requires a QObject context object. If none is
available, e.g. a nullptr was passed explicitly, or the
QTimer::singleShot(O, Functor) API was used, the optimization could
not easily be applied. This is not only bad from a performance POV,
but also poses as a potential source for heisenbugs: Using the
different API versions of QTimer::singleShot would use different code
paths internally, which then would not ensure the expected slot call
order. This problem actually existed already when mixing the
string-based slot syntax with PMF/functors in the QTimer::singleShot
API.
This patch overcomes this hurdle and fixes all of the above: When we
encounter a 0ms single shot timer, and no QObject context object is
available, we fall back to the main thread, or create a temporary
QObject for any other thread. The updated and extended benchmark
shows that this is still a significant performance improvement
over using a timer:
********* Start testing of qtimer_vs_qmetaobject *********
Config: Using QtTest library 5.14.0, Qt 5.14.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 8.2.1 20181127)
PASS : qtimer_vs_qmetaobject::initTestCase()
PASS : qtimer_vs_qmetaobject::bench(singleShot_slot)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_slot":
7.48 msecs per iteration (total: 748, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(singleShot_pmf)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_pmf":
7.20 msecs per iteration (total: 720, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(singleShot_functor)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_functor":
6.79 msecs per iteration (total: 679, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(singleShot_functor_noctx)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_functor_noctx":
6.92 msecs per iteration (total: 693, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(invokeMethod_string)
RESULT : qtimer_vs_qmetaobject::bench():"invokeMethod_string":
7.34 msecs per iteration (total: 735, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(invokeMethod_pmf)
RESULT : qtimer_vs_qmetaobject::bench():"invokeMethod_pmf":
6.90 msecs per iteration (total: 690, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(invokeMethod_functor)
RESULT : qtimer_vs_qmetaobject::bench():"invokeMethod_functor":
6.62 msecs per iteration (total: 662, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_slot)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_slot":
7.45 msecs per iteration (total: 745, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_pmf)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_pmf":
7.46 msecs per iteration (total: 747, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_functor)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_functor":
6.70 msecs per iteration (total: 671, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_functor_noctx)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_functor_noctx":
13.75 msecs per iteration (total: 1,376, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(invokeMethod_string)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"invokeMethod_string":
7.05 msecs per iteration (total: 706, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(invokeMethod_pmf)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"invokeMethod_pmf":
6.70 msecs per iteration (total: 670, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(invokeMethod_functor)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"invokeMethod_functor":
6.58 msecs per iteration (total: 658, iterations: 100)
PASS : qtimer_vs_qmetaobject::cleanupTestCase()
Totals: 16 passed, 0 failed, 0 skipped, 0 blacklisted, 20977ms
********* Finished testing of qtimer_vs_qmetaobject *********
Without the change to qtimer.cpp, the results are:
********* Start testing of qtimer_vs_qmetaobject *********
Config: Using QtTest library 5.14.0, Qt 5.14.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 8.2.1 20181127)
PASS : qtimer_vs_qmetaobject::initTestCase()
PASS : qtimer_vs_qmetaobject::bench(singleShot_slot)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_slot":
7.45 msecs per iteration (total: 745, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(singleShot_pmf)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_pmf":
112.84 msecs per iteration (total: 11,285, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(singleShot_functor)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_functor":
115.62 msecs per iteration (total: 11,563, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(singleShot_functor_noctx)
RESULT : qtimer_vs_qmetaobject::bench():"singleShot_functor_noctx":
110.81 msecs per iteration (total: 11,082, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(invokeMethod_string)
RESULT : qtimer_vs_qmetaobject::bench():"invokeMethod_string":
7.04 msecs per iteration (total: 704, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(invokeMethod_pmf)
RESULT : qtimer_vs_qmetaobject::bench():"invokeMethod_pmf":
6.62 msecs per iteration (total: 662, iterations: 100)
PASS : qtimer_vs_qmetaobject::bench(invokeMethod_functor)
RESULT : qtimer_vs_qmetaobject::bench():"invokeMethod_functor":
6.62 msecs per iteration (total: 662, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_slot)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_slot":
7.45 msecs per iteration (total: 746, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_pmf)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_pmf":
118.42 msecs per iteration (total: 11,842, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_functor)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_functor":
119.35 msecs per iteration (total: 11,936, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(singleShot_functor_noctx)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"singleShot_functor_noctx":
130.96 msecs per iteration (total: 13,096, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(invokeMethod_string)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"invokeMethod_string":
8.08 msecs per iteration (total: 808, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(invokeMethod_pmf)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"invokeMethod_pmf":
6.79 msecs per iteration (total: 680, iterations: 100)
PASS : qtimer_vs_qmetaobject::benchBackgroundThread(invokeMethod_functor)
RESULT : qtimer_vs_qmetaobject::benchBackgroundThread():"invokeMethod_functor":
7.49 msecs per iteration (total: 749, iterations: 100)
PASS : qtimer_vs_qmetaobject::cleanupTestCase()
Totals: 16 passed, 0 failed, 0 skipped, 0 blacklisted, 153995ms
********* Finished testing of qtimer_vs_qmetaobject *********
Additionally, this patch adds a unit test to verify that the slot call
order for 0ms single shot timers is followed while mixing the various
API versions. It fails without this patch but passes now.
Finally, another test is added to verify that using QTimer::singleShot
before a QCoreApplication was constructed is still working properly.
Change-Id: I0d6211554b6198cb3e527be9ec3adc572b1b54ee
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Until now, QEasingCurve was not streaming all it's internal state.
Therefore, doing store/reload operation through QDataStream would not
yield the same curve as the original. This patch fixes it.
[ChangeLog][QtCore][QEasingCurve] QEasingCurve now properly streams all
the data needed to QDataStream.
Change-Id: I1619501f5b4237983c8c68e148745a5e58863f55
Fixes: QTBUG-68181
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Removes handling of missing Q_COMPILER_NULLPTR, Q_COMPILER_AUTODECL,
Q_COMPILER_LAMBDA, Q_COMPILER_VARIADIC_MACROS and
Q_COMPILER_AUTO_FUNCTION.
We haven't supported any compilers without these for a long time.
Change-Id: I3df88206516a25763e2c28b083733780f35a8764
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Includes a fixup for 03fadc26e7, which
removed the check on empty transition list, needed when no data are
available. Ensured that such a data-free zone would in fact be
noticed as invalid during init().
Fixed handling of times before the epoch (we still want to consult a
POSIX rule, if that's all that's available) while ensuring we (as
documented) ignore DST for such times.
Fixed handling of large times (milliseconds since epoch outside int
range) when looking up POSIX rules. Gave QTimeZonePrivate a YearRange
enum (to be moved to QTimeZone once this merges up to dev) so as to
eliminate a magic number (and avoid adding another). Moved
year-munging in POSIX rules after the one early return, which doesn't
need the year range.
Added test-cases for the distant past/future (just checking UTC's
offsets; SLES has a minimal version of the UTC data-file that triggers
the bugs fixed here for them).
Fixes: QTBUG-74666
Fixes: QTBUG-74550
Change-Id: Ief7b7e55c62cf11064700934f404b2fc283614e1
Reviewed-by: Tony Sarajärvi <tony.sarajarvi@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Enum class are serialized using the declared size.
[ChangeLog][QtCore][QDataStream] Enumerations can now
be serialized through QDataStream without the need of
manually defining streaming operators.
Change-Id: Iae9a63eb62b5a5615b657766a3c4c66ba4d98d0e
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Paolo Dastoli <paolo.dastoli@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>