Compare commits

...

29 Commits

Author SHA1 Message Date
JordanTheToaster
2cb311dd24 3rdparty: Update googletest to v1.15.2 2024-12-08 11:04:38 -05:00
JordanTheToaster
ba36d4b0c8 GameDB: Fix incorrect field order in Silent Hill 3 FMVs 2024-12-08 10:16:12 -05:00
TheLastRar
5de1c60d50 DEV9: Apply const within in PacketReader 2024-12-07 09:22:26 +01:00
TheLastRar
a8a170ebe6 DEV9: Apply const to basic payload types
Propagate const into PacketReader classes as needed
Provide non-const editor version for pcap
2024-12-07 09:22:26 +01:00
PCSX2 Bot
d7937943b0 [ci skip] Qt: Update Base Translation. 2024-12-06 19:14:30 -05:00
JordanTheToaster
3f1df0ea92 3rdparty: Update WIL to v1.0.240803.1 2024-12-06 16:59:34 -05:00
JordanTheToaster
caaa3519ad 3rdparty: Update Vulkan-Headers to v1.4.303 2024-12-06 16:59:34 -05:00
JordanTheToaster
58ab271fc1 Deps: Update to libzip 1.11.2 2024-12-06 16:59:34 -05:00
JordanTheToaster
981fedfdd1 3rdparty/rcheevos: Bump to v11.6.0 2024-12-06 16:59:34 -05:00
JordanTheToaster
ac968f9a6a OSD: Fix status view regression 2024-12-06 16:59:15 -05:00
JordanTheToaster
ac15b77f89 Deps: Update to Qt 6.8.1 on Windows and Linux 2024-12-06 16:59:15 -05:00
chaoticgd
6e4dc1e8ab FileSystem: Don't follow symlinks when recursively deleting directories 2024-12-05 11:52:40 -05:00
chaoticgd
46d17fcb20 FileSystem: Add a test for deleting directories with symlinks 2024-12-05 11:52:40 -05:00
TheLastRar
f91f39afcd DEV9: Fix race-condition while handling closed connection 2024-12-05 11:32:24 -05:00
TheLastRar
f317ba327c DEV9: Correct alignment calculation in Sockets 2024-12-05 11:32:24 -05:00
TheLastRar
00f4cd5252 DEV9: Prevent out of bounds reads in ICMP fix 2024-12-05 11:32:24 -05:00
TheLastRar
0a44e20c34 DEV9: Correct function definitions 2024-12-05 11:32:24 -05:00
TheLastRar
abeb1ca49d DEV9: Skip over invalid gateways 2024-12-05 11:32:24 -05:00
PCSX2 Bot
ee3abe745c [ci skip] Qt: Update Base Translation. 2024-12-03 19:03:20 -05:00
KamFretoZ
a024c25019 Achievements: Fix progression overlay stacking 2024-12-03 17:39:17 +01:00
KamFretoZ
5bf3166832 Qt: Fix Verbose Status Formatting 2024-12-03 17:39:17 +01:00
KamFretoZ
7ef293744a Qt: Move video capture option from Tools to System 2024-12-03 17:39:17 +01:00
TheLastRar
07df874603 DEV9: Avoid iterating over modified vector in UDP_FixedPort 2024-12-03 11:10:31 -05:00
TheLastRar
687c587d19 DEV9: Always bind UDP ports 2024-12-03 11:10:31 -05:00
PCSX2 Bot
671255c684 PAD: Update to latest controller database. 2024-12-02 23:27:24 +01:00
PCSX2 Bot
c31f324853 [ci skip] Qt: Update Base Translation. 2024-11-29 01:30:06 +01:00
lightningterror
5b7122bd30 GS/TC: Remove no longer needed asserts in PreloadTarget.
Asserts are no longer needed as we check for width offset and adjust width accordingly using the offset.
2024-11-28 23:59:52 +01:00
TheLastRar
4a04100207 [SAVEVERSION+] HostFS: Always write savestate tag 2024-11-28 15:47:52 -05:00
TheLastRar
93652a3115 SaveState: Bounds check FreezeMem loads 2024-11-28 15:47:52 -05:00
126 changed files with 4612 additions and 2831 deletions

View File

@@ -20,7 +20,7 @@ LIBPNG=1.6.44
LIBWEBP=1.4.0
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
SDL=SDL2-2.30.9
QT=6.8.0
QT=6.8.1
ZSTD=1.5.6
SHADERC=2024.1
@@ -39,12 +39,12 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
24b574f71c87a763f50704bbb630cbe38298d544a1f890f099a4696b1d6beba4 $SDL.tar.gz
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
1bad481710aa27f872de6c9f72651f89a6107f0077003d0ebfcc9fd15cba3c75 qtbase-everywhere-src-$QT.tar.xz
595bf8557b91e1f8ebc726f1e09868a3c7e610ff5045068f2d4ea2428c49a5d4 qtimageformats-everywhere-src-$QT.tar.xz
cf7a593d5e520f8177240610d9e55d5b75b0887fe5f385554ff64377f1646199 qtsvg-everywhere-src-$QT.tar.xz
403115d8268503c6cc6e43310c8ae28eb9e605072a5d04e4a2de8b6af39981f7 qttools-everywhere-src-$QT.tar.xz
84bf2b67c243cd0c50a08acd7bfa9df2b1965028511815c1b6b65a0687437cb6 qttranslations-everywhere-src-$QT.tar.xz
175758591638ebf1c6fbb66ac11c7fa0eb8d4ed52e9243cc59075d06a6a2060a qtwayland-everywhere-src-$QT.tar.xz
40b14562ef3bd779bc0e0418ea2ae08fa28235f8ea6e8c0cb3bce1d6ad58dcaf qtbase-everywhere-src-$QT.tar.xz
138cc2909aa98f5ff7283e36eb3936eb5e625d3ca3b4febae2ca21d8903dd237 qtimageformats-everywhere-src-$QT.tar.xz
3d0de73596e36b2daa7c48d77c4426bb091752856912fba720215f756c560dd0 qtsvg-everywhere-src-$QT.tar.xz
9d43d409be08b8681a0155a9c65114b69c9a3fc11aef6487bb7fdc5b283c432d qttools-everywhere-src-$QT.tar.xz
635a6093e99152243b807de51077485ceadd4786d4acb135b9340b2303035a4a qttranslations-everywhere-src-$QT.tar.xz
2226fbde4e2ddd12f8bf4b239c8f38fd706a54e789e63467dfddc77129eca203 qtwayland-everywhere-src-$QT.tar.xz
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz

View File

@@ -47,7 +47,7 @@ set HARFBUZZ=10.0.1
set LIBJPEG=9f
set LIBPNG=1643
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.0
set QT=6.8.1
set QTMINOR=6.8
set SDL=SDL2-2.30.9
set WEBP=1.4.0
@@ -67,11 +67,11 @@ call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.z
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ec855bcd815b4b63d0c958c42c2923311c656227d6e0c1ae1e721406d346444b || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c3b41915341d853b6374cf93f1fcced2c8e4be9360f29c656960e1d0d15046a3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 809081a7bdf7e48262fbe9437e4e756df6ad2649433e803c4040026e650d7c91 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 89f1ef4595f68c3d34c63a7c1c4ce475e701e103f0473f3fd0718a2e5234de6e || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 3f813f49d6d28c532dc4b104084f60ff382337f184698fcd6e70ab9efad977c1 || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 91c33d9946279c9c613b02e52a33df610cc01d13ea6e321b4c4d8ee708b9a03e || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c65a89140f5d68137ffec67d631ec97002fb37077d9b4eb4ee45cbec39b1c38a || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 30a8e7773e1f274557e049a97f158b808f344247da03ae5240e4956c81d51cd5 || goto error
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error

View File

@@ -45,7 +45,7 @@ set HARFBUZZ=10.0.1
set LIBJPEG=9f
set LIBPNG=1643
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.8.0
set QT=6.8.1
set QTMINOR=6.8
set SDL=SDL2-2.30.9
set WEBP=1.4.0
@@ -65,11 +65,11 @@ call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.z
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" ec855bcd815b4b63d0c958c42c2923311c656227d6e0c1ae1e721406d346444b || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c3b41915341d853b6374cf93f1fcced2c8e4be9360f29c656960e1d0d15046a3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 809081a7bdf7e48262fbe9437e4e756df6ad2649433e803c4040026e650d7c91 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 89f1ef4595f68c3d34c63a7c1c4ce475e701e103f0473f3fd0718a2e5234de6e || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 3f813f49d6d28c532dc4b104084f60ff382337f184698fcd6e70ab9efad977c1 || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 91c33d9946279c9c613b02e52a33df610cc01d13ea6e321b4c4d8ee708b9a03e || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c65a89140f5d68137ffec67d631ec97002fb37077d9b4eb4ee45cbec39b1c38a || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 30a8e7773e1f274557e049a97f158b808f344247da03ae5240e4956c81d51cd5 || goto error
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error

View File

@@ -9,7 +9,7 @@ GoogleTest now follows the
We recommend
[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it).
We do publish occasional semantic versions, tagged with
`v${major}.${minor}.${patch}` (e.g. `v1.13.0`).
`v${major}.${minor}.${patch}` (e.g. `v1.15.0`).
#### Documentation Updates
@@ -17,25 +17,21 @@ Our documentation is now live on GitHub Pages at
https://google.github.io/googletest/. We recommend browsing the documentation on
GitHub Pages rather than directly in the repository.
#### Release 1.13.0
#### Release 1.15.0
[Release 1.13.0](https://github.com/google/googletest/releases/tag/v1.13.0) is
[Release 1.15.0](https://github.com/google/googletest/releases/tag/v1.15.0) is
now available.
The 1.13.x branch requires at least C++14.
The 1.15.x branch requires at least C++14.
#### Continuous Integration
We use Google's internal systems for continuous integration. \
GitHub Actions were added for the convenience of open-source contributors. They
are exclusively maintained by the open-source community and not used by the
GoogleTest team.
We use Google's internal systems for continuous integration.
#### Coming Soon
* We are planning to take a dependency on
[Abseil](https://github.com/abseil/abseil-cpp).
* More documentation improvements are planned.
## Welcome to **GoogleTest**, Google's C++ test framework!
@@ -100,12 +96,12 @@ tools.
In addition to many internal projects at Google, GoogleTest is also used by the
following notable projects:
* The [Chromium projects](http://www.chromium.org/) (behind the Chrome browser
and Chrome OS).
* The [LLVM](http://llvm.org/) compiler.
* The [Chromium projects](https://www.chromium.org/) (behind the Chrome
browser and Chrome OS).
* The [LLVM](https://llvm.org/) compiler.
* [Protocol Buffers](https://github.com/google/protobuf), Google's data
interchange format.
* The [OpenCV](http://opencv.org/) computer vision library.
* The [OpenCV](https://opencv.org/) computer vision library.
## Related Open Source Projects

View File

@@ -8,8 +8,8 @@ derive better designs of your system and write better tests.
It is inspired by:
* [jMock](http://www.jmock.org/)
* [EasyMock](http://www.easymock.org/)
* [Hamcrest](http://code.google.com/p/hamcrest/)
* [EasyMock](https://easymock.org/)
* [Hamcrest](https://code.google.com/p/hamcrest/)
It is designed with C++'s specifics in mind.
@@ -36,5 +36,5 @@ Details and examples can be found here:
* [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html)
GoogleMock is a part of
[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a
[GoogleTest C++ testing framework](https://github.com/google/googletest/) and a
subject to the same requirements.

View File

@@ -135,6 +135,7 @@
#endif
#include <algorithm>
#include <exception>
#include <functional>
#include <memory>
#include <string>
@@ -175,9 +176,15 @@ struct BuiltInDefaultValueGetter<T, false> {
static T Get() {
Assert(false, __FILE__, __LINE__,
"Default action undefined for the function return type.");
return internal::Invalid<T>();
#if defined(__GNUC__) || defined(__clang__)
__builtin_unreachable();
#elif defined(_MSC_VER)
__assume(0);
#else
return Invalid<T>();
// The above statement will never be reached, but is required in
// order for this function to compile.
#endif
}
};
@@ -1740,6 +1747,13 @@ struct ThrowAction {
return [copy](Args...) -> R { throw copy; };
}
};
struct RethrowAction {
std::exception_ptr exception;
template <typename R, typename... Args>
operator Action<R(Args...)>() const { // NOLINT
return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
}
};
#endif // GTEST_HAS_EXCEPTIONS
} // namespace internal
@@ -2056,13 +2070,23 @@ internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
return {pointer};
}
// Action Throw(exception) can be used in a mock function of any type
// to throw the given exception. Any copyable value can be thrown.
#if GTEST_HAS_EXCEPTIONS
// Action Throw(exception) can be used in a mock function of any type
// to throw the given exception. Any copyable value can be thrown,
// except for std::exception_ptr, which is likely a mistake if
// thrown directly.
template <typename T>
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) {
typename std::enable_if<
!std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
internal::ThrowAction<typename std::decay<T>::type>>::type
Throw(T&& exception) {
return {std::forward<T>(exception)};
}
// Action Rethrow(exception_ptr) can be used in a mock function of any type
// to rethrow any exception_ptr. Note that the same object is thrown each time.
inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
return {std::move(exception)};
}
#endif // GTEST_HAS_EXCEPTIONS
namespace internal {
@@ -2111,13 +2135,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
R operator()(Args&&... arg) const {
static constexpr size_t kMaxArgs =
sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
return Apply(MakeIndexSequence<kMaxArgs>{},
MakeIndexSequence<10 - kMaxArgs>{},
return Apply(std::make_index_sequence<kMaxArgs>{},
std::make_index_sequence<10 - kMaxArgs>{},
args_type{std::forward<Args>(arg)...});
}
template <std::size_t... arg_id, std::size_t... excess_id>
R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>,
R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,
const args_type& args) const {
// Impl need not be specific to the signature of action being implemented;
// only the implementing function body needs to have all of the specific
@@ -2150,9 +2174,9 @@ template <typename F, typename Impl>
}
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
, GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \
GMOCK_INTERNAL_ARG_UNUSED, , 10)
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i

View File

@@ -37,6 +37,7 @@
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
#include <cstddef>
#include <type_traits> // IWYU pragma: keep
#include <utility> // IWYU pragma: keep
@@ -69,22 +70,22 @@ constexpr bool PrefixOf(const char* a, const char* b) {
return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
}
template <int N, int M>
template <size_t N, size_t M>
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
return N <= M && internal::PrefixOf(prefix, str);
}
template <int N, int M>
template <size_t N, size_t M>
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
return N <= M && internal::PrefixOf(suffix, str + M - N);
}
template <int N, int M>
template <size_t N, size_t M>
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
return N == M && internal::PrefixOf(a, b);
}
template <int N>
template <size_t N>
constexpr bool ValidateSpec(const char (&spec)[N]) {
return internal::Equals("const", spec) ||
internal::Equals("override", spec) ||

View File

@@ -490,12 +490,12 @@ class MatcherBaseImpl<Derived<Ts...>> {
template <typename F>
operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit)
return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{});
return Apply<F>(std::make_index_sequence<sizeof...(Ts)>{});
}
private:
template <typename F, std::size_t... tuple_ids>
::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const {
::testing::Matcher<F> Apply(std::index_sequence<tuple_ids...>) const {
return ::testing::Matcher<F>(
new typename Derived<Ts...>::template gmock_Impl<F>(
std::get<tuple_ids>(params_)...));
@@ -1048,7 +1048,7 @@ class StartsWithMatcher {
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
const StringType& s2(s);
const StringType s2(s);
return s2.length() >= prefix_.length() &&
s2.substr(0, prefix_.length()) == prefix_;
}
@@ -1102,7 +1102,7 @@ class EndsWithMatcher {
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
const StringType& s2(s);
const StringType s2(s);
return s2.length() >= suffix_.length() &&
s2.substr(s2.length() - suffix_.length()) == suffix_;
}
@@ -2920,26 +2920,27 @@ class EachMatcher {
const M inner_matcher_;
};
struct Rank1 {};
struct Rank0 : Rank1 {};
// Use go/ranked-overloads for dispatching.
struct Rank0 {};
struct Rank1 : Rank0 {};
namespace pair_getters {
using std::get;
template <typename T>
auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT
auto First(T& x, Rank0) -> decltype(get<0>(x)) { // NOLINT
return get<0>(x);
}
template <typename T>
auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT
auto First(T& x, Rank1) -> decltype((x.first)) { // NOLINT
return x.first;
}
template <typename T>
auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT
auto Second(T& x, Rank0) -> decltype(get<1>(x)) { // NOLINT
return get<1>(x);
}
template <typename T>
auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT
auto Second(T& x, Rank1) -> decltype((x.second)) { // NOLINT
return x.second;
}
} // namespace pair_getters
@@ -2965,7 +2966,7 @@ class KeyMatcherImpl : public MatcherInterface<PairType> {
MatchResultListener* listener) const override {
StringMatchResultListener inner_listener;
const bool match = inner_matcher_.MatchAndExplain(
pair_getters::First(key_value, Rank0()), &inner_listener);
pair_getters::First(key_value, Rank1()), &inner_listener);
const std::string explanation = inner_listener.str();
if (!explanation.empty()) {
*listener << "whose first field is a value " << explanation;
@@ -3087,18 +3088,18 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
if (!listener->IsInterested()) {
// If the listener is not interested, we don't need to construct the
// explanation.
return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) &&
second_matcher_.Matches(pair_getters::Second(a_pair, Rank0()));
return first_matcher_.Matches(pair_getters::First(a_pair, Rank1())) &&
second_matcher_.Matches(pair_getters::Second(a_pair, Rank1()));
}
StringMatchResultListener first_inner_listener;
if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()),
if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank1()),
&first_inner_listener)) {
*listener << "whose first field does not match";
PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
return false;
}
StringMatchResultListener second_inner_listener;
if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()),
if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank1()),
&second_inner_listener)) {
*listener << "whose second field does not match";
PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
@@ -3151,8 +3152,8 @@ class PairMatcher {
};
template <typename T, size_t... I>
auto UnpackStructImpl(const T& t, IndexSequence<I...>, int)
-> decltype(std::tie(get<I>(t)...)) {
auto UnpackStructImpl(const T& t, std::index_sequence<I...>,
int) -> decltype(std::tie(get<I>(t)...)) {
static_assert(std::tuple_size<T>::value == sizeof...(I),
"Number of arguments doesn't match the number of fields.");
return std::tie(get<I>(t)...);
@@ -3160,97 +3161,97 @@ auto UnpackStructImpl(const T& t, IndexSequence<I...>, int)
#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<1>, char) {
const auto& [a] = t;
return std::tie(a);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<2>, char) {
const auto& [a, b] = t;
return std::tie(a, b);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<3>, char) {
const auto& [a, b, c] = t;
return std::tie(a, b, c);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<4>, char) {
const auto& [a, b, c, d] = t;
return std::tie(a, b, c, d);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<5>, char) {
const auto& [a, b, c, d, e] = t;
return std::tie(a, b, c, d, e);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<6>, char) {
const auto& [a, b, c, d, e, f] = t;
return std::tie(a, b, c, d, e, f);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<7>, char) {
const auto& [a, b, c, d, e, f, g] = t;
return std::tie(a, b, c, d, e, f, g);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<8>, char) {
const auto& [a, b, c, d, e, f, g, h] = t;
return std::tie(a, b, c, d, e, f, g, h);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<9>, char) {
const auto& [a, b, c, d, e, f, g, h, i] = t;
return std::tie(a, b, c, d, e, f, g, h, i);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<10>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<11>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<12>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<13>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<14>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<15>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<16>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<17>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<17>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<18>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<18>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) {
auto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s);
}
@@ -3258,8 +3259,8 @@ auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) {
template <size_t I, typename T>
auto UnpackStruct(const T& t)
-> decltype((UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0)) {
return (UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0);
-> decltype((UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0)) {
return (UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0);
}
// Helper function to do comma folding in C++11.
@@ -3272,7 +3273,7 @@ template <typename Struct, typename StructSize>
class FieldsAreMatcherImpl;
template <typename Struct, size_t... I>
class FieldsAreMatcherImpl<Struct, IndexSequence<I...>>
class FieldsAreMatcherImpl<Struct, std::index_sequence<I...>>
: public MatcherInterface<Struct> {
using UnpackedType =
decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>()));
@@ -3354,8 +3355,8 @@ class FieldsAreMatcher {
template <typename Struct>
operator Matcher<Struct>() const { // NOLINT
return Matcher<Struct>(
new FieldsAreMatcherImpl<const Struct&, IndexSequenceFor<Inner...>>(
matchers_));
new FieldsAreMatcherImpl<const Struct&,
std::index_sequence_for<Inner...>>(matchers_));
}
private:
@@ -5444,47 +5445,47 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
// MATCHER* macros itself are listed below.
#define MATCHER(name, description) \
class name##Matcher \
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
public: \
template <typename arg_type> \
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
public: \
gmock_Impl() {} \
bool MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener) const override; \
void DescribeTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(false); \
} \
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(true); \
} \
\
private: \
::std::string FormatDescription(bool negation) const { \
/* NOLINTNEXTLINE readability-redundant-string-init */ \
::std::string gmock_description = (description); \
if (!gmock_description.empty()) { \
return gmock_description; \
} \
return ::testing::internal::FormatMatcherDescription(negation, #name, \
{}, {}); \
} \
}; \
}; \
inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH() \
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-function") \
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \
name GMOCK_INTERNAL_WARNING_POP()() { \
return {}; \
} \
template <typename arg_type> \
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \
const
#define MATCHER(name, description) \
class name##Matcher \
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
public: \
template <typename arg_type> \
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
public: \
gmock_Impl() {} \
bool MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener) const override; \
void DescribeTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(false); \
} \
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(true); \
} \
\
private: \
::std::string FormatDescription(bool negation) const { \
/* NOLINTNEXTLINE readability-redundant-string-init */ \
::std::string gmock_description = (description); \
if (!gmock_description.empty()) { \
return gmock_description; \
} \
return ::testing::internal::FormatMatcherDescription(negation, #name, \
{}, {}); \
} \
}; \
}; \
inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH() \
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-function") \
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \
name GMOCK_INTERNAL_WARNING_POP()() { \
return {}; \
} \
template <typename arg_type> \
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
const arg_type& arg, \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener* \
result_listener) const
#define MATCHER_P(name, p0, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))
@@ -5566,11 +5567,11 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
} \
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
template <typename arg_type> \
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl< \
arg_type>::MatchAndExplain(const arg_type& arg, \
::testing::MatchResultListener* \
result_listener GTEST_ATTRIBUTE_UNUSED_) \
const
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>:: \
gmock_Impl<arg_type>::MatchAndExplain( \
const arg_type& arg, \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing:: \
MatchResultListener* result_listener) const
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
GMOCK_PP_TAIL( \
@@ -5605,8 +5606,8 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args))
#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg_unused) \
, gmock_p##i
#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg) \
, ::std::forward<arg##_type>(gmock_p##i)
// To prevent ADL on certain functions we put them on a separate namespace.
using namespace no_adl; // NOLINT

View File

@@ -592,8 +592,9 @@ namespace internal {
// Overloads for other custom-callables are provided in the
// internal/custom/gmock-generated-actions.h header.
template <typename F, typename... Args>
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
return f(args...);
auto InvokeArgument(F &&f,
Args... args) -> decltype(std::forward<F>(f)(args...)) {
return std::forward<F>(f)(args...);
}
template <std::size_t index, typename... Params>
@@ -606,7 +607,7 @@ struct InvokeArgumentAction {
internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
std::forward<Args>(args)...);
return params.Apply([&](const Params &...unpacked_params) {
auto &&callable = args_tuple.template Get<index>();
auto &&callable = std::move(args_tuple.template Get<index>());
return internal::InvokeArgument(
std::forward<decltype(callable)>(callable), unpacked_params...);
});

View File

@@ -53,13 +53,14 @@
//
// where all clauses are optional and WillOnce() can be repeated.
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-function-mocker.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h"
#include "gmock/gmock-nice-strict.h"
#include "gmock/gmock-actions.h" // IWYU pragma: export
#include "gmock/gmock-cardinalities.h" // IWYU pragma: export
#include "gmock/gmock-function-mocker.h" // IWYU pragma: export
#include "gmock/gmock-matchers.h" // IWYU pragma: export
#include "gmock/gmock-more-actions.h" // IWYU pragma: export
#include "gmock/gmock-more-matchers.h" // IWYU pragma: export
#include "gmock/gmock-nice-strict.h" // IWYU pragma: export
#include "gmock/gmock-spec-builders.h" // IWYU pragma: export
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"

View File

@@ -44,6 +44,7 @@
#include <ostream> // NOLINT
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "gmock/internal/gmock-port.h"
@@ -420,7 +421,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > {
GTEST_API_ void IllegalDoDefault(const char* file, int line);
template <typename F, typename Tuple, size_t... Idx>
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
-> decltype(std::forward<F>(f)(
std::get<Idx>(std::forward<Tuple>(args))...)) {
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
@@ -428,12 +429,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
// Apply the function to a tuple of arguments.
template <typename F, typename Tuple>
auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
auto Apply(F&& f, Tuple&& args)
-> decltype(ApplyImpl(
std::forward<F>(f), std::forward<Tuple>(args),
std::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>())) {
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
MakeIndexSequence<std::tuple_size<
std::make_index_sequence<std::tuple_size<
typename std::remove_reference<Tuple>::type>::value>());
}

View File

@@ -56,7 +56,7 @@
#include "gmock/internal/custom/gmock-port.h"
#include "gtest/internal/gtest-port.h"
#ifdef GTEST_HAS_ABSL
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#endif
@@ -73,7 +73,7 @@
#define GMOCK_FLAG(name) FLAGS_gmock_##name
// Pick a command line flags implementation.
#ifdef GTEST_HAS_ABSL
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
@@ -95,7 +95,7 @@
#define GMOCK_FLAG_SET(name, value) \
(void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
#else // GTEST_HAS_ABSL
#else // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
@@ -134,6 +134,6 @@
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
#endif // GTEST_HAS_ABSL
#endif // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_

View File

@@ -44,6 +44,7 @@
#include <iostream>
#include <ostream> // NOLINT
#include <string>
#include <utility>
#include <vector>
#include "gmock/gmock.h"
@@ -211,14 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) {
}
template <size_t... I>
constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>,
constexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>,
const char* const base64) {
return {
{UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};
}
constexpr std::array<char, 256> UnBase64(const char* const base64) {
return UnBase64Impl(MakeIndexSequence<256>{}, base64);
return UnBase64Impl(std::make_index_sequence<256>{}, base64);
}
static constexpr char kBase64[] =

View File

@@ -120,7 +120,7 @@ GTEST_API_ std::string FormatMatcherDescription(
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method".
// "Introduction to Algorithms (Second ed.)", pp. 651-664.
// [2] "Ford-Fulkerson algorithm", Wikipedia,
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
// 'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
class MaxBipartiteMatchState {
public:
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
@@ -236,9 +236,8 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
os << "{";
const char* sep = "";
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
os << sep << "\n ("
<< "element #" << it->first << ", "
<< "matcher #" << it->second << ")";
os << sep << "\n (" << "element #" << it->first << ", " << "matcher #"
<< it->second << ")";
sep = ",";
}
os << "\n}";
@@ -374,20 +373,20 @@ bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
return true;
}
if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
if (matrix.LhsSize() != matrix.RhsSize()) {
// The element count doesn't match. If the container is empty,
// there's no need to explain anything as Google Mock already
// prints the empty container. Otherwise we just need to show
// how many elements there actually are.
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
*listener << "which has " << Elements(matrix.LhsSize());
}
return false;
const bool is_exact_match_with_size_discrepency =
match_flags() == UnorderedMatcherRequire::ExactMatch &&
matrix.LhsSize() != matrix.RhsSize();
if (is_exact_match_with_size_discrepency) {
// The element count doesn't match. If the container is empty,
// there's no need to explain anything as Google Mock already
// prints the empty container. Otherwise we just need to show
// how many elements there actually are.
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
*listener << "which has " << Elements(matrix.LhsSize()) << "\n";
}
}
bool result = true;
bool result = !is_exact_match_with_size_discrepency;
::std::vector<char> element_matched(matrix.LhsSize(), 0);
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);

View File

@@ -490,6 +490,7 @@ class MockObjectRegistry {
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
internal::MutexLock l(&internal::g_gmock_mutex);
int leaked_count = 0;
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
@@ -530,7 +531,7 @@ class MockObjectRegistry {
#ifdef GTEST_OS_QURT
qurt_exception_raise_fatal();
#else
_exit(1); // We cannot call exit() as it is not reentrant and
_Exit(1); // We cannot call exit() as it is not reentrant and
// may already have been called.
#endif
}

View File

@@ -12,7 +12,7 @@ GoogleTest comes with a CMake build script
([CMakeLists.txt](https://github.com/google/googletest/blob/main/CMakeLists.txt))
that can be used on a wide range of platforms ("C" stands for cross-platform.).
If you don't have CMake installed already, you can download it for free from
<http://www.cmake.org/>.
<https://cmake.org/>.
CMake works by generating native makefiles or build projects that can be used in
the compiler environment of your choice. You can either build GoogleTest as a
@@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
with
```
git clone https://github.com/google/googletest.git -b v1.13.0
git clone https://github.com/google/googletest.git -b v1.15.0
cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output.
cd build

View File

@@ -129,7 +129,7 @@ namespace testing {
//
// Expected: Foo() is even
// Actual: it's 5
//
class GTEST_API_ AssertionResult {
public:
// Copy constructor.

View File

@@ -293,8 +293,8 @@ class GTEST_API_ KilledBySignal {
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter if and only if EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// regex_or_matcher - A regex that a macro such as EXPECT_DEATH would use
// to test the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
@@ -311,13 +311,13 @@ class GTEST_API_ KilledBySignal {
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex_or_matcher, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \

View File

@@ -59,7 +59,7 @@
#ifdef GTEST_HAS_ABSL
#include <type_traits>
#include "absl/strings/internal/has_absl_stringify.h"
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/str_cat.h"
#endif // GTEST_HAS_ABSL
@@ -121,14 +121,14 @@ class GTEST_API_ Message {
// Streams a non-pointer value to this object. If building a version of
// GoogleTest with ABSL, this overload is only enabled if the value does not
// have an AbslStringify definition.
template <typename T
template <
typename T
#ifdef GTEST_HAS_ABSL
,
typename std::enable_if<
!absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
int>::type = 0
,
typename std::enable_if<!absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0
#endif // GTEST_HAS_ABSL
>
>
inline Message& operator<<(const T& val) {
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
@@ -153,9 +153,8 @@ class GTEST_API_ Message {
// Streams a non-pointer value with an AbslStringify definition to this
// object.
template <typename T,
typename std::enable_if<
absl::strings_internal::HasAbslStringify<T>::value, // NOLINT
int>::type = 0>
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0>
inline Message& operator<<(const T& val) {
// ::operator<< is needed here for a similar reason as with the non-Abseil
// version above

View File

@@ -178,7 +178,7 @@ TEST_P(DerivedTest, DoesBlah) {
#include <utility>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util.h" // IWYU pragma: export
#include "gtest/internal/gtest-port.h"
namespace testing {
@@ -469,7 +469,7 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
return 0; \
} \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \
}; \
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)::gtest_registering_dummy_ = \
@@ -514,8 +514,8 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
DUMMY_PARAM_))))(info); \
} \
static int gtest_##prefix##test_suite_name##_dummy_ \
GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \
gtest_##prefix##test_suite_name##_dummy_ = \
::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \
.GetTestSuitePatternHolder<test_suite_name>( \

View File

@@ -116,12 +116,16 @@
#include <vector>
#ifdef GTEST_HAS_ABSL
#include "absl/strings/internal/has_absl_stringify.h"
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/str_cat.h"
#endif // GTEST_HAS_ABSL
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_INTERNAL_HAS_STD_SPAN
#include <span> // NOLINT
#endif // GTEST_INTERNAL_HAS_STD_SPAN
namespace testing {
// Definitions in the internal* namespaces are subject to change without notice.
@@ -131,13 +135,32 @@ namespace internal {
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
template <typename T>
struct IsStdSpan {
static constexpr bool value = false;
};
#if GTEST_INTERNAL_HAS_STD_SPAN
template <typename E>
struct IsStdSpan<std::span<E>> {
static constexpr bool value = true;
};
#endif // GTEST_INTERNAL_HAS_STD_SPAN
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
//
// NOTE: Since std::span does not have const_iterator until C++23, it would
// fail IsContainerTest before C++23. However, IsContainerTest only uses
// the presence of const_iterator to avoid treating iterators as containers
// because of iterator::iterator. Which means std::span satisfies the *intended*
// condition of IsContainerTest.
struct ContainerPrinter {
template <typename T,
typename = typename std::enable_if<
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value>::type>
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value) ||
IsStdSpan<T>::value>::type>
static void PrintValue(const T& container, std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
@@ -218,8 +241,8 @@ struct StreamPrinter {
// ADL (possibly involving implicit conversions).
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
// lookup properly when we do it in the template parameter list.)
static auto PrintValue(const T& value, ::std::ostream* os)
-> decltype((void)(*os << value)) {
static auto PrintValue(const T& value,
::std::ostream* os) -> decltype((void)(*os << value)) {
// Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments.
*os << value;
@@ -269,10 +292,9 @@ struct ConvertibleToStringViewPrinter {
#ifdef GTEST_HAS_ABSL
struct ConvertibleToAbslStringifyPrinter {
template <
typename T,
typename = typename std::enable_if<
absl::strings_internal::HasAbslStringify<T>::value>::type> // NOLINT
template <typename T,
typename = typename std::enable_if<
absl::HasAbslStringify<T>::value>::type> // NOLINT
static void PrintValue(const T& value, ::std::ostream* os) {
*os << absl::StrCat(value);
}
@@ -530,49 +552,63 @@ int AppropriateResolution(FloatType val) {
int full = std::numeric_limits<FloatType>::max_digits10;
if (val < 0) val = -val;
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (val < 1000000) {
FloatType mulfor6 = 1e10;
if (val >= 100000.0) { // 100,000 to 999,999
// Without these static casts, the template instantiation for float would
// fail to compile when -Wdouble-promotion is enabled, as the arithmetic and
// comparison logic would promote floats to doubles.
if (val >= static_cast<FloatType>(100000.0)) { // 100,000 to 999,999
mulfor6 = 1.0;
} else if (val >= 10000.0) {
} else if (val >= static_cast<FloatType>(10000.0)) {
mulfor6 = 1e1;
} else if (val >= 1000.0) {
} else if (val >= static_cast<FloatType>(1000.0)) {
mulfor6 = 1e2;
} else if (val >= 100.0) {
} else if (val >= static_cast<FloatType>(100.0)) {
mulfor6 = 1e3;
} else if (val >= 10.0) {
} else if (val >= static_cast<FloatType>(10.0)) {
mulfor6 = 1e4;
} else if (val >= 1.0) {
} else if (val >= static_cast<FloatType>(1.0)) {
mulfor6 = 1e5;
} else if (val >= 0.1) {
} else if (val >= static_cast<FloatType>(0.1)) {
mulfor6 = 1e6;
} else if (val >= 0.01) {
} else if (val >= static_cast<FloatType>(0.01)) {
mulfor6 = 1e7;
} else if (val >= 0.001) {
} else if (val >= static_cast<FloatType>(0.001)) {
mulfor6 = 1e8;
} else if (val >= 0.0001) {
} else if (val >= static_cast<FloatType>(0.0001)) {
mulfor6 = 1e9;
}
if (static_cast<FloatType>(static_cast<int32_t>(val * mulfor6 + 0.5)) /
if (static_cast<FloatType>(static_cast<int32_t>(
val * mulfor6 + (static_cast<FloatType>(0.5)))) /
mulfor6 ==
val)
return 6;
} else if (val < 1e10) {
FloatType divfor6 = 1.0;
if (val >= 1e9) { // 1,000,000,000 to 9,999,999,999
} else if (val < static_cast<FloatType>(1e10)) {
FloatType divfor6 = static_cast<FloatType>(1.0);
if (val >= static_cast<FloatType>(1e9)) { // 1,000,000,000 to 9,999,999,999
divfor6 = 10000;
} else if (val >= 1e8) { // 100,000,000 to 999,999,999
} else if (val >=
static_cast<FloatType>(1e8)) { // 100,000,000 to 999,999,999
divfor6 = 1000;
} else if (val >= 1e7) { // 10,000,000 to 99,999,999
} else if (val >=
static_cast<FloatType>(1e7)) { // 10,000,000 to 99,999,999
divfor6 = 100;
} else if (val >= 1e6) { // 1,000,000 to 9,999,999
} else if (val >= static_cast<FloatType>(1e6)) { // 1,000,000 to 9,999,999
divfor6 = 10;
}
if (static_cast<FloatType>(static_cast<int32_t>(val / divfor6 + 0.5)) *
if (static_cast<FloatType>(static_cast<int32_t>(
val / divfor6 + (static_cast<FloatType>(0.5)))) *
divfor6 ==
val)
return 6;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
return full;
}

View File

@@ -194,33 +194,34 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
GTEST_NAME_GENERATOR_(CaseName)
#define TYPED_TEST(CaseName, TestName) \
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
"test-name must not be empty"); \
template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
: public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
static bool gtest_##CaseName##_##TestName##_registered_ \
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
TestName)>, \
GTEST_TYPE_PARAMS_( \
CaseName)>::Register("", \
::testing::internal::CodeLocation( \
__FILE__, __LINE__), \
GTEST_STRINGIFY_(CaseName), \
GTEST_STRINGIFY_(TestName), 0, \
::testing::internal::GenerateNames< \
GTEST_NAME_GENERATOR_(CaseName), \
GTEST_TYPE_PARAMS_(CaseName)>()); \
template <typename gtest_TypeParam_> \
void GTEST_TEST_CLASS_NAME_(CaseName, \
#define TYPED_TEST(CaseName, TestName) \
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
"test-name must not be empty"); \
template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
: public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
gtest_##CaseName##_##TestName##_registered_ = \
::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_( \
CaseName, TestName)>, \
GTEST_TYPE_PARAMS_( \
CaseName)>::Register("", \
::testing::internal::CodeLocation( \
__FILE__, __LINE__), \
GTEST_STRINGIFY_(CaseName), \
GTEST_STRINGIFY_(TestName), 0, \
::testing::internal::GenerateNames< \
GTEST_NAME_GENERATOR_(CaseName), \
GTEST_TYPE_PARAMS_(CaseName)>()); \
template <typename gtest_TypeParam_> \
void GTEST_TEST_CLASS_NAME_(CaseName, \
TestName)<gtest_TypeParam_>::TestBody()
// Legacy API is deprecated but still available
@@ -267,22 +268,23 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define TYPED_TEST_P(SuiteName, TestName) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
template <typename gtest_TypeParam_> \
class TestName : public SuiteName<gtest_TypeParam_> { \
private: \
typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \
template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \
#define TYPED_TEST_P(SuiteName, TestName) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
template <typename gtest_TypeParam_> \
class TestName : public SuiteName<gtest_TypeParam_> { \
private: \
typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
gtest_##TestName##_defined_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \
template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
// Note: this won't work correctly if the trailing arguments are macros.
@@ -290,8 +292,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const \
GTEST_REGISTERED_TEST_NAMES_(SuiteName) = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
@@ -303,22 +305,24 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
REGISTER_TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
"test-suit-prefix must not be empty"); \
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTestSuite< \
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
::testing::internal::GenerateTypeList<Types>::type>:: \
Register(GTEST_STRINGIFY_(Prefix), \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
&GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
GTEST_STRINGIFY_(SuiteName), \
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
::testing::internal::GenerateNames< \
::testing::internal::NameGeneratorSelector< \
__VA_ARGS__>::type, \
::testing::internal::GenerateTypeList<Types>::type>())
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
"test-suit-prefix must not be empty"); \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \
gtest_##Prefix##_##SuiteName = \
::testing::internal::TypeParameterizedTestSuite< \
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
::testing::internal::GenerateTypeList<Types>::type>:: \
Register( \
GTEST_STRINGIFY_(Prefix), \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
&GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
GTEST_STRINGIFY_(SuiteName), \
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
::testing::internal::GenerateNames< \
::testing::internal::NameGeneratorSelector< \
__VA_ARGS__>::type, \
::testing::internal::GenerateTypeList<Types>::type>())
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_

View File

@@ -51,7 +51,6 @@
#include <cstddef>
#include <cstdint>
#include <iomanip>
#include <limits>
#include <memory>
#include <ostream>
@@ -61,16 +60,16 @@
#include <type_traits>
#include <vector>
#include "gtest/gtest-assertion-result.h"
#include "gtest/gtest-death-test.h"
#include "gtest/gtest-matchers.h"
#include "gtest/gtest-message.h"
#include "gtest/gtest-param-test.h"
#include "gtest/gtest-printers.h"
#include "gtest/gtest-test-part.h"
#include "gtest/gtest-typed-test.h"
#include "gtest/gtest_pred_impl.h"
#include "gtest/gtest_prod.h"
#include "gtest/gtest-assertion-result.h" // IWYU pragma: export
#include "gtest/gtest-death-test.h" // IWYU pragma: export
#include "gtest/gtest-matchers.h" // IWYU pragma: export
#include "gtest/gtest-message.h" // IWYU pragma: export
#include "gtest/gtest-param-test.h" // IWYU pragma: export
#include "gtest/gtest-printers.h" // IWYU pragma: export
#include "gtest/gtest-test-part.h" // IWYU pragma: export
#include "gtest/gtest-typed-test.h" // IWYU pragma: export
#include "gtest/gtest_pred_impl.h" // IWYU pragma: export
#include "gtest/gtest_prod.h" // IWYU pragma: export
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
@@ -608,7 +607,7 @@ class GTEST_API_ TestInfo {
friend class internal::UnitTestImpl;
friend class internal::StreamingListenerTest;
friend TestInfo* internal::MakeAndRegisterTestInfo(
const char* test_suite_name, const char* name, const char* type_param,
std::string test_suite_name, const char* name, const char* type_param,
const char* value_param, internal::CodeLocation code_location,
internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc,
@@ -616,7 +615,7 @@ class GTEST_API_ TestInfo {
// Constructs a TestInfo object. The newly constructed instance assumes
// ownership of the factory object.
TestInfo(const std::string& test_suite_name, const std::string& name,
TestInfo(std::string test_suite_name, std::string name,
const char* a_type_param, // NULL if not a type-parameterized test
const char* a_value_param, // NULL if not a value-parameterized test
internal::CodeLocation a_code_location,
@@ -684,7 +683,7 @@ class GTEST_API_ TestSuite {
// this is not a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite(const char* name, const char* a_type_param,
TestSuite(const std::string& name, const char* a_type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc);
@@ -1263,6 +1262,20 @@ class GTEST_API_ UnitTest {
// total_test_suite_count() - 1. If i is not in that range, returns NULL.
TestSuite* GetMutableTestSuite(int i);
// Invokes OsStackTrackGetterInterface::UponLeavingGTest. UponLeavingGTest()
// should be called immediately before Google Test calls user code. It saves
// some information about the current stack that CurrentStackTrace() will use
// to find and hide Google Test stack frames.
void UponLeavingGTest();
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite)
GTEST_LOCK_EXCLUDED_(mutex_);
// Sets the TestInfo object for the test that's currently running.
void set_current_test_info(TestInfo* a_current_test_info)
GTEST_LOCK_EXCLUDED_(mutex_);
// Accessors for the implementation object.
internal::UnitTestImpl* impl() { return impl_; }
const internal::UnitTestImpl* impl() const { return impl_; }
@@ -1271,6 +1284,8 @@ class GTEST_API_ UnitTest {
// members of UnitTest.
friend class ScopedTrace;
friend class Test;
friend class TestInfo;
friend class TestSuite;
friend class internal::AssertHelper;
friend class internal::StreamingListenerTest;
friend class internal::UnitTestRecordPropertyTestHelper;
@@ -1574,12 +1589,12 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
}
::std::stringstream lhs_ss;
lhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
<< lhs_value;
lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
lhs_ss << lhs_value;
::std::stringstream rhs_ss;
rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
<< rhs_value;
rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
rhs_ss << rhs_value;
return EqFailure(lhs_expression, rhs_expression,
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
@@ -1752,6 +1767,7 @@ class TestWithParam : public Test, public WithParamInterface<T> {};
// generic name and clashes with some other libraries.
#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
#define FAIL() GTEST_FAIL()
#define FAIL_AT(file, line) GTEST_FAIL_AT(file, line)
#endif
// Generates a success with a generic message.
@@ -2308,7 +2324,8 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
// tests are successful, or 1 otherwise.
//
// RUN_ALL_TESTS() should be invoked after the command line has been
// parsed by InitGoogleTest().
// parsed by InitGoogleTest(). RUN_ALL_TESTS will tear down and delete any
// installed environments and should only be called once per binary.
//
// This function was formerly a macro; thus, it is in the global
// namespace and has an all-caps name.

View File

@@ -46,17 +46,38 @@
#include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
GTEST_DECLARE_string_(internal_run_death_test);
namespace testing {
namespace internal {
// Names of the flags (needed for parsing Google Test flags).
const char kDeathTestStyleFlag[] = "death_test_style";
const char kDeathTestUseFork[] = "death_test_use_fork";
// Name of the flag (needed for parsing Google Test flag).
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
const ::std::string& regex) {
return ContainsRegex(regex);
}
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
Matcher<const ::std::string&> matcher) {
return matcher;
}
#ifdef GTEST_HAS_DEATH_TEST
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
@@ -73,7 +94,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
//
// exit status: The integer exit information in the format specified
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// exit code: The integer code passed to exit(3), _Exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
public:
@@ -170,28 +191,6 @@ class DefaultDeathTestFactory : public DeathTestFactory {
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
const ::std::string& regex) {
return ContainsRegex(regex);
}
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
Matcher<const ::std::string&> matcher) {
return matcher;
}
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
#if GTEST_HAS_EXCEPTIONS

View File

@@ -43,6 +43,7 @@
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include <string>
#include <utility>
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-string.h"
@@ -70,8 +71,9 @@ class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") {}
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {}
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {
Normalize();
}
@@ -79,6 +81,10 @@ class GTEST_API_ FilePath {
Set(rhs);
return *this;
}
FilePath& operator=(FilePath&& rhs) noexcept {
pathname_ = std::move(rhs.pathname_);
return *this;
}
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }

View File

@@ -58,7 +58,6 @@
#include <cstdint>
#include <functional>
#include <iomanip>
#include <limits>
#include <map>
#include <set>
@@ -79,7 +78,7 @@
//
// will result in the token foo__LINE__, instead of foo followed by
// the current line number. For more details, see
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
// https://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
@@ -170,7 +169,7 @@ namespace edit_distance {
// All edits cost the same, with replace having lower priority than
// add/remove.
// Simple implementation of the Wagner-Fischer algorithm.
// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
// See https://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
enum EditType { kMatch, kAdd, kRemove, kReplace };
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
const std::vector<size_t>& left, const std::vector<size_t>& right);
@@ -237,7 +236,7 @@ GTEST_API_ std::string GetBoolAssertionFailureMessage(
// For double, there are 11 exponent bits and 52 fraction bits.
//
// More details can be found at
// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
// https://en.wikipedia.org/wiki/IEEE_floating-point_standard.
//
// Template parameter:
//
@@ -282,7 +281,7 @@ class FloatingPoint {
// bits. Therefore, 4 should be enough for ordinary use.
//
// See the following article for more details on ULP:
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
static const uint32_t kMaxUlps = 4;
// Constructs a FloatingPoint from a raw floating-point number.
@@ -363,7 +362,7 @@ class FloatingPoint {
// N - 1 (the biggest number representable using
// sign-and-magnitude) is represented by 2N - 1.
//
// Read http://en.wikipedia.org/wiki/Signed_number_representations
// Read https://en.wikipedia.org/wiki/Signed_number_representations
// for more details on signed number representations.
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
if (kSignBitMask & sam) {
@@ -475,8 +474,8 @@ using SetUpTestSuiteFunc = void (*)();
using TearDownTestSuiteFunc = void (*)();
struct CodeLocation {
CodeLocation(const std::string& a_file, int a_line)
: file(a_file), line(a_line) {}
CodeLocation(std::string a_file, int a_line)
: file(std::move(a_file)), line(a_line) {}
std::string file;
int line;
@@ -556,7 +555,7 @@ struct SuiteApiResolver : T {
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
// value_param: text representation of the test's value parameter,
// or NULL if this is not a type-parameterized test.
// or NULL if this is not a value-parameterized test.
// code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test suite
@@ -565,7 +564,7 @@ struct SuiteApiResolver : T {
// The newly created TestInfo instance will assume
// ownership of the factory object.
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* test_suite_name, const char* name, const char* type_param,
std::string test_suite_name, const char* name, const char* type_param,
const char* value_param, CodeLocation code_location,
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
@@ -596,8 +595,7 @@ class GTEST_API_ TypedTestSuitePState {
fflush(stderr);
posix::Abort();
}
registered_tests_.insert(
::std::make_pair(test_name, CodeLocation(file, line)));
registered_tests_.emplace(test_name, CodeLocation(file, line));
return true;
}
@@ -701,7 +699,7 @@ class TypeParameterizedTest {
// specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
// Types). Valid values for 'index' are [0, N - 1] where N is the
// length of Types.
static bool Register(const char* prefix, const CodeLocation& code_location,
static bool Register(const char* prefix, CodeLocation code_location,
const char* case_name, const char* test_names, int index,
const std::vector<std::string>& type_names =
GenerateNames<DefaultNameGenerator, Types>()) {
@@ -713,8 +711,7 @@ class TypeParameterizedTest {
// list.
MakeAndRegisterTestInfo(
(std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
"/" + type_names[static_cast<size_t>(index)])
.c_str(),
"/" + type_names[static_cast<size_t>(index)]),
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
GetTypeName<Type>().c_str(),
nullptr, // No value parameter.
@@ -726,13 +723,9 @@ class TypeParameterizedTest {
new TestFactoryImpl<TestClass>);
// Next, recurses (at compile time) with the tail of the type list.
return TypeParameterizedTest<Fixture, TestSel,
typename Types::Tail>::Register(prefix,
code_location,
case_name,
test_names,
index + 1,
type_names);
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::
Register(prefix, std::move(code_location), case_name, test_names,
index + 1, type_names);
}
};
@@ -740,7 +733,7 @@ class TypeParameterizedTest {
template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, internal::None> {
public:
static bool Register(const char* /*prefix*/, const CodeLocation&,
static bool Register(const char* /*prefix*/, CodeLocation,
const char* /*case_name*/, const char* /*test_names*/,
int /*index*/,
const std::vector<std::string>& =
@@ -787,7 +780,8 @@ class TypeParameterizedTestSuite {
// Next, recurses (at compile time) with the tail of the test list.
return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
Types>::Register(prefix, code_location,
Types>::Register(prefix,
std::move(code_location),
state, case_name,
SkipComma(test_names),
type_names);
@@ -1143,40 +1137,6 @@ class NativeArray {
void (NativeArray::*clone_)(const Element*, size_t);
};
// Backport of std::index_sequence.
template <size_t... Is>
struct IndexSequence {
using type = IndexSequence;
};
// Double the IndexSequence, and one if plus_one is true.
template <bool plus_one, typename T, size_t sizeofT>
struct DoubleSequence;
template <size_t... I, size_t sizeofT>
struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
};
template <size_t... I, size_t sizeofT>
struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
using type = IndexSequence<I..., (sizeofT + I)...>;
};
// Backport of std::make_index_sequence.
// It uses O(ln(N)) instantiation depth.
template <size_t N>
struct MakeIndexSequenceImpl
: DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
N / 2>::type {};
template <>
struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
template <size_t N>
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
template <typename... T>
using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
template <size_t>
struct Ignore {
Ignore(...); // NOLINT
@@ -1185,7 +1145,7 @@ struct Ignore {
template <typename>
struct ElemFromListImpl;
template <size_t... I>
struct ElemFromListImpl<IndexSequence<I...>> {
struct ElemFromListImpl<std::index_sequence<I...>> {
// We make Ignore a template to solve a problem with MSVC.
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
// MSVC doesn't understand how to deal with that pack expansion.
@@ -1196,9 +1156,8 @@ struct ElemFromListImpl<IndexSequence<I...>> {
template <size_t N, typename... T>
struct ElemFromList {
using type =
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
static_cast<T (*)()>(nullptr)...));
using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(
static_cast<T (*)()>(nullptr)...));
};
struct FlatTupleConstructTag {};
@@ -1223,9 +1182,9 @@ template <typename Derived, typename Idx>
struct FlatTupleBase;
template <size_t... Idx, typename... T>
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
using Indices = IndexSequence<Idx...>;
using Indices = std::index_sequence<Idx...>;
FlatTupleBase() = default;
template <typename... Args>
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
@@ -1260,14 +1219,15 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
// implementations.
// FlatTuple and ElemFromList are not recursive and have a fixed depth
// regardless of T...
// MakeIndexSequence, on the other hand, it is recursive but with an
// std::make_index_sequence, on the other hand, it is recursive but with an
// instantiation depth of O(ln(N)).
template <typename... T>
class FlatTuple
: private FlatTupleBase<FlatTuple<T...>,
typename MakeIndexSequence<sizeof...(T)>::type> {
using Indices = typename FlatTupleBase<
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
std::make_index_sequence<sizeof...(T)>> {
using Indices =
typename FlatTupleBase<FlatTuple<T...>,
std::make_index_sequence<sizeof...(T)>>::Indices;
public:
FlatTuple() = default;
@@ -1541,7 +1501,8 @@ class NeverThrown {
\
private: \
void TestBody() override; \
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const \
test_info_; \
}; \
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \

View File

@@ -47,6 +47,7 @@
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -85,7 +86,7 @@ namespace internal {
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
CodeLocation code_location);
const CodeLocation& code_location);
template <typename>
class ParamGeneratorInterface;
@@ -379,9 +380,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
// integer test parameter index.
template <class ParamType>
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
Message name_stream;
name_stream << info.index;
return name_stream.GetString();
return std::to_string(info.index);
}
template <typename T = int>
@@ -513,9 +512,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
explicit ParameterizedTestSuiteInfo(const char* name,
explicit ParameterizedTestSuiteInfo(std::string name,
CodeLocation code_location)
: test_suite_name_(name), code_location_(code_location) {}
: test_suite_name_(std::move(name)),
code_location_(std::move(code_location)) {}
// Test suite base name for display purposes.
const std::string& GetTestSuiteName() const override {
@@ -529,20 +529,21 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test suite base name and DoBar is test base name.
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
void AddTestPattern(const char*,
const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory,
CodeLocation code_location) {
tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
test_suite_name, test_base_name, meta_factory, code_location)));
tests_.emplace_back(
new TestInfo(test_base_name, meta_factory, std::move(code_location)));
}
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
// about a generator.
int AddTestSuiteInstantiation(const std::string& instantiation_name,
int AddTestSuiteInstantiation(std::string instantiation_name,
GeneratorCreationFunc* func,
ParamNameGeneratorFunc* name_func,
const char* file, int line) {
instantiations_.push_back(
InstantiationInfo(instantiation_name, func, name_func, file, line));
instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
file, line);
return 0; // Return value used only to run this method in namespace scope.
}
// UnitTest class invokes this method to register tests in this test suite
@@ -553,60 +554,61 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
void RegisterTests() override {
bool generated_instantiations = false;
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
std::shared_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin();
gen_it != instantiations_.end(); ++gen_it) {
const std::string& instantiation_name = gen_it->name;
ParamGenerator<ParamType> generator((*gen_it->generator)());
ParamNameGeneratorFunc* name_func = gen_it->name_func;
const char* file = gen_it->file;
int line = gen_it->line;
std::string test_suite_name;
std::string test_name;
for (const std::shared_ptr<TestInfo>& test_info : tests_) {
for (const InstantiationInfo& instantiation : instantiations_) {
const std::string& instantiation_name = instantiation.name;
ParamGenerator<ParamType> generator((*instantiation.generator)());
ParamNameGeneratorFunc* name_func = instantiation.name_func;
const char* file = instantiation.file;
int line = instantiation.line;
std::string test_suite_name;
if (!instantiation_name.empty())
test_suite_name = instantiation_name + "/";
test_suite_name += test_info->test_suite_base_name;
else
test_suite_name.clear();
test_suite_name += test_suite_name_;
size_t i = 0;
std::set<std::string> test_param_names;
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
for (const auto& param : generator) {
generated_instantiations = true;
Message test_name_stream;
test_name.clear();
std::string param_name =
name_func(TestParamInfo<ParamType>(*param_it, i));
name_func(TestParamInfo<ParamType>(param, i));
GTEST_CHECK_(IsValidParamName(param_name))
<< "Parameterized test name '" << param_name
<< "' is invalid, in " << file << " line " << line << std::endl;
<< "' is invalid (contains spaces, dashes, or any "
"non-alphanumeric characters other than underscores), in "
<< file << " line " << line << "" << std::endl;
GTEST_CHECK_(test_param_names.count(param_name) == 0)
<< "Duplicate parameterized test name '" << param_name << "', in "
<< file << " line " << line << std::endl;
test_param_names.insert(param_name);
if (!test_info->test_base_name.empty()) {
test_name_stream << test_info->test_base_name << "/";
test_name.append(test_info->test_base_name).append("/");
}
test_name_stream << param_name;
test_name += param_name;
test_param_names.insert(std::move(param_name));
MakeAndRegisterTestInfo(
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
test_suite_name, test_name.c_str(),
nullptr, // No type parameter.
PrintToString(*param_it).c_str(), test_info->code_location,
PrintToString(param).c_str(), test_info->code_location,
GetTestSuiteTypeId(),
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
} // for test_it
test_info->test_meta_factory->CreateTestFactory(param));
++i;
} // for param
} // for instantiation
} // for test_info
if (!generated_instantiations) {
// There are no generaotrs, or they all generate nothing ...
@@ -619,15 +621,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
TestInfo(const char* a_test_base_name,
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
CodeLocation a_code_location)
: test_suite_base_name(a_test_suite_base_name),
test_base_name(a_test_base_name),
: test_base_name(a_test_base_name),
test_meta_factory(a_test_meta_factory),
code_location(a_code_location) {}
code_location(std::move(a_code_location)) {}
const std::string test_suite_base_name;
const std::string test_base_name;
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
const CodeLocation code_location;
@@ -637,11 +637,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// <Instantiation name, Sequence generator creation function,
// Name generator function, Source file, Source line>
struct InstantiationInfo {
InstantiationInfo(const std::string& name_in,
GeneratorCreationFunc* generator_in,
InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
ParamNameGeneratorFunc* name_func_in, const char* file_in,
int line_in)
: name(name_in),
: name(std::move(name_in)),
generator(generator_in),
name_func(name_func_in),
file(file_in),
@@ -702,29 +701,32 @@ class ParameterizedTestSuiteRegistry {
// tests and instantiations of a particular test suite.
template <class TestSuite>
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
const char* test_suite_name, CodeLocation code_location) {
std::string test_suite_name, CodeLocation code_location) {
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
for (auto& test_suite_info : test_suite_infos_) {
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test suite setup and tear-down in this case.
ReportInvalidTestSuiteType(test_suite_name, code_location);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info = CheckedDowncastToActualType<
ParameterizedTestSuiteInfo<TestSuite>>(test_suite_info);
}
break;
auto item_it = suite_name_to_info_index_.find(test_suite_name);
if (item_it != suite_name_to_info_index_.end()) {
auto* test_suite_info = test_suite_infos_[item_it->second];
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test suite setup and tear-down in this case.
ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info =
CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
test_suite_info);
}
}
if (typed_test_info == nullptr) {
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
test_suite_name, code_location);
test_suite_name, std::move(code_location));
suite_name_to_info_index_.emplace(std::move(test_suite_name),
test_suite_infos_.size());
test_suite_infos_.push_back(typed_test_info);
}
return typed_test_info;
@@ -738,8 +740,9 @@ class ParameterizedTestSuiteRegistry {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name, CodeLocation code_location) {
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
std::string test_case_name, CodeLocation code_location) {
return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
std::move(code_location));
}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
@@ -748,6 +751,7 @@ class ParameterizedTestSuiteRegistry {
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
TestSuiteInfoContainer test_suite_infos_;
::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
delete;
@@ -774,7 +778,7 @@ class TypeParameterizedTestSuiteRegistry {
private:
struct TypeParameterizedTestSuiteInfo {
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
: code_location(c), instantiated(false) {}
: code_location(std::move(c)), instantiated(false) {}
CodeLocation code_location;
bool instantiated;
@@ -803,12 +807,12 @@ class ValueArray {
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));
}
private:
template <typename T, size_t... I>
std::vector<T> MakeVector(IndexSequence<I...>) const {
std::vector<T> MakeVector(std::index_sequence<I...>) const {
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
}
@@ -838,7 +842,7 @@ class CartesianProductGenerator
template <class I>
class IteratorImpl;
template <size_t... I>
class IteratorImpl<IndexSequence<I...>>
class IteratorImpl<std::index_sequence<I...>>
: public ParamIteratorInterface<ParamType> {
public:
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
@@ -929,7 +933,7 @@ class CartesianProductGenerator
std::shared_ptr<ParamType> current_value_;
};
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;
std::tuple<ParamGenerator<T>...> generators_;
};

View File

@@ -56,6 +56,8 @@
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
#define GTEST_OS_WINDOWS_PHONE 1
#define GTEST_OS_WINDOWS_TV_TITLE 1
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
#define GTEST_OS_WINDOWS_GAMES 1
#else
// WINAPI_FAMILY defined but no known partition matched.
// Default to desktop.

View File

@@ -194,8 +194,6 @@
//
// Macros for basic C++ coding:
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
// variable don't have to be used.
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
// suppressed (constant conditional).
@@ -208,6 +206,8 @@
// or
// UniversalPrinter<absl::optional>
// specializations. Always defined to 0 or 1.
// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>
// specializations. Always defined to 0 or 1
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
// Matcher<absl::string_view>
// specializations. Always defined to 0 or 1.
@@ -279,6 +279,22 @@
#error C++ versions less than C++14 are not supported.
#endif
// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.
#ifdef __has_include
#define GTEST_INTERNAL_HAS_INCLUDE __has_include
#else
#define GTEST_INTERNAL_HAS_INCLUDE(...) 0
#endif
// Detect C++ feature test macros as gracefully as possible.
// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.
#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \
(!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<version>))
#include <version> // C++20 and later
#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))
#include <ciso646> // Pre-C++20
#endif
#include <ctype.h> // for isspace, etc
#include <stddef.h> // for ptrdiff_t
#include <stdio.h>
@@ -320,7 +336,8 @@
#define GTEST_HAS_NOTIFICATION_ 0
#endif
#ifdef GTEST_HAS_ABSL
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
#define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file.
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#include "absl/flags/reflection.h"
@@ -590,7 +607,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \
defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \
defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \
defined(GTEST_OS_GNU_HURD))
defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS))
#define GTEST_HAS_PTHREAD 1
#else
#define GTEST_HAS_PTHREAD 0
@@ -609,7 +627,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// Determines whether clone(2) is supported.
// Usually it will only be available on Linux, excluding
// Linux on the Itanium architecture.
// Also see http://linux.die.net/man/2/clone.
// Also see https://linux.die.net/man/2/clone.
#ifndef GTEST_HAS_CLONE
// The user didn't tell us, so we need to figure it out.
@@ -640,9 +658,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// platforms except known mobile / embedded ones. Also, if the port doesn't have
// a file system, stream redirection is not supported.
#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \
defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \
!GTEST_HAS_FILE_SYSTEM
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \
defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM
#define GTEST_HAS_STREAM_REDIRECTION 0
#else
#define GTEST_HAS_STREAM_REDIRECTION 1
@@ -652,7 +670,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// Determines whether to support death tests.
// pops up a dialog window that cannot be suppressed programmatically.
#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_CYGWIN) || \
defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_ZOS) || \
(defined(GTEST_OS_MAC) && !defined(GTEST_OS_IOS)) || \
(defined(GTEST_OS_WINDOWS_DESKTOP) && _MSC_VER) || \
defined(GTEST_OS_WINDOWS_MINGW) || defined(GTEST_OS_AIX) || \
@@ -730,6 +748,20 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_HAVE_ATTRIBUTE_(x) 0
#endif
// GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE
//
// A function-like feature checking macro that accepts C++11 style attributes.
// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
// find `__has_cpp_attribute`, will evaluate to 0.
#if defined(__has_cpp_attribute)
// NOTE: requiring __cplusplus above should not be necessary, but
// works around https://bugs.llvm.org/show_bug.cgi?id=23435.
#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
#else
#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) 0
#endif
// GTEST_HAVE_FEATURE_
//
// A function-like feature checking macro that is a wrapper around
@@ -741,14 +773,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif
// Use this annotation after a variable or parameter declaration to tell the
// compiler the variable/parameter does not have to be used.
// compiler the variable/parameter may be used.
// Example:
//
// GTEST_ATTRIBUTE_UNUSED_ int foo = bar();
#if GTEST_HAVE_ATTRIBUTE_(unused)
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
// GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar();
//
// This can be removed once we only support only C++17 or newer and
// [[maybe_unused]] is available on all supported platforms.
#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused)
#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
#elif GTEST_HAVE_ATTRIBUTE_(unused)
// This is inferior to [[maybe_unused]] as it can produce a
// -Wused-but-marked-unused warning on optionally used symbols, but it is all we
// have.
#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__))
#else
#define GTEST_ATTRIBUTE_UNUSED_
#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED
#endif
// Use this annotation before a function that takes a printf format string.
@@ -827,9 +867,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_API_
#ifdef _MSC_VER
#if GTEST_LINKED_AS_SHARED_LIBRARY
#if defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllimport)
#elif GTEST_CREATE_SHARED_LIBRARY
#elif defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY
#define GTEST_API_ __declspec(dllexport)
#endif
#elif GTEST_HAVE_ATTRIBUTE_(visibility)
@@ -1987,7 +2027,9 @@ inline std::string StripTrailingSpaces(std::string str) {
namespace posix {
// File system porting.
#if GTEST_HAS_FILE_SYSTEM
// Note: Not every I/O-related function is related to file systems, so don't
// just disable all of them here. For example, fileno() and isatty(), etc. must
// always be available in order to detect if a pipe points to a terminal.
#ifdef GTEST_OS_WINDOWS
typedef struct _stat StatStruct;
@@ -1998,27 +2040,32 @@ inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
// time and thus not defined there.
#else
inline int FileNo(FILE* file) { return _fileno(file); }
#if GTEST_HAS_FILE_SYSTEM
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
inline int RmDir(const char* dir) { return _rmdir(dir); }
inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }
#endif
#endif // GTEST_OS_WINDOWS_MOBILE
#elif defined(GTEST_OS_ESP8266)
typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); }
#if GTEST_HAS_FILE_SYSTEM
inline int Stat(const char* path, StatStruct* buf) {
// stat function not implemented on ESP8266
return 0;
}
inline int RmDir(const char* dir) { return rmdir(dir); }
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif
#else
typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); }
#if GTEST_HAS_FILE_SYSTEM
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
#ifdef GTEST_OS_QURT
// QuRT doesn't support any directory functions, including rmdir
@@ -2027,9 +2074,9 @@ inline int RmDir(const char*) { return 0; }
inline int RmDir(const char* dir) { return rmdir(dir); }
#endif
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif
#endif // GTEST_OS_WINDOWS
#endif // GTEST_HAS_FILE_SYSTEM
// Other functions with a different name on Windows.
@@ -2082,8 +2129,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
// defined there.
#if GTEST_HAS_FILE_SYSTEM
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_ESP8266) && \
!defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT)
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \
!defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \
!defined(GTEST_OS_QURT)
inline int ChDir(const char* dir) { return chdir(dir); }
#endif
inline FILE* FOpen(const char* path, const char* mode) {
@@ -2227,7 +2275,7 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
#endif // !defined(GTEST_FLAG)
// Pick a command line flags implementation.
#ifdef GTEST_HAS_ABSL
#ifdef GTEST_INTERNAL_HAS_ABSL_FLAGS
// Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \
@@ -2252,7 +2300,8 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
(void)(::absl::SetFlag(&GTEST_FLAG(name), value))
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0
#else // GTEST_HAS_ABSL
#undef GTEST_INTERNAL_HAS_ABSL_FLAGS
#else // ndef GTEST_INTERNAL_HAS_ABSL_FLAGS
// Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \
@@ -2294,7 +2343,7 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)
#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_ABSL_FLAGS
// Thread annotations
#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)
@@ -2349,9 +2398,9 @@ using Any = ::absl::any;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
(!defined(_MSC_VER) || GTEST_HAS_RTTI)
#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \
(!defined(_MSC_VER) || GTEST_HAS_RTTI))
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_ANY 1
@@ -2363,8 +2412,7 @@ using Any = ::std::any;
} // namespace testing
// The case where absl is configured NOT to alias std::any is not
// supported.
#endif // __has_include(<any>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#endif // __has_include
#endif // __cpp_lib_any
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_ANY
@@ -2384,8 +2432,8 @@ inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
@@ -2399,14 +2447,22 @@ inline ::std::nullopt_t Nullopt() { return ::std::nullopt; }
} // namespace testing
// The case where absl is configured NOT to alias std::optional is not
// supported.
#endif // __has_include(<optional>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#endif // __has_include
#endif // __cpp_lib_optional
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_OPTIONAL
#define GTEST_INTERNAL_HAS_OPTIONAL 0
#endif
#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)
#define GTEST_INTERNAL_HAS_STD_SPAN 1
#endif // __cpp_lib_span
#ifndef GTEST_INTERNAL_HAS_STD_SPAN
#define GTEST_INTERNAL_HAS_STD_SPAN 0
#endif
#ifdef GTEST_HAS_ABSL
// Always use absl::string_view for Matcher<> specializations if googletest
// is built with absl support.
@@ -2418,8 +2474,9 @@ using StringView = ::absl::string_view;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#if defined(__cpp_lib_string_view) || \
(GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::string_view for Matcher<>
// specializations.
#define GTEST_INTERNAL_HAS_STRING_VIEW 1
@@ -2431,9 +2488,7 @@ using StringView = ::std::string_view;
} // namespace testing
// The case where absl is configured NOT to alias std::string_view is not
// supported.
#endif // __has_include(<string_view>) && GTEST_INTERNAL_CPLUSPLUS_LANG >=
// 201703L
#endif // __has_include
#endif // __cpp_lib_string_view
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_STRING_VIEW
@@ -2452,8 +2507,8 @@ using Variant = ::absl::variant<T...>;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \
GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_VARIANT 1
@@ -2465,16 +2520,16 @@ using Variant = ::std::variant<T...>;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::variant is not supported.
#endif // __has_include(<variant>) && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#endif // __has_include
#endif // __cpp_lib_variant
#endif // GTEST_HAS_ABSL
#ifndef GTEST_INTERNAL_HAS_VARIANT
#define GTEST_INTERNAL_HAS_VARIANT 0
#endif
#if defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L
#if (defined(__cpp_constexpr) && !defined(__cpp_inline_variables)) || \
(defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \
GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L)
#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1
#endif

View File

@@ -71,7 +71,7 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
// Strip redundant spaces in typename to match MSVC
// For example, std::pair<int, bool> -> std::pair<int,bool>
static const char to_search[] = ", ";
static const char replace_str[] = ",";
const char replace_char = ',';
size_t pos = 0;
while (true) {
// Get the next occurrence from the current position
@@ -80,8 +80,8 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
break;
}
// Replace this occurrence of substring
s.replace(pos, strlen(to_search), replace_str);
pos += strlen(replace_str);
s.replace(pos, strlen(to_search), 1, replace_char);
++pos;
}
return s;
}

View File

@@ -32,6 +32,8 @@
#include "gtest/gtest-death-test.h"
#include <stdlib.h>
#include <functional>
#include <memory>
#include <sstream>
@@ -115,7 +117,7 @@ GTEST_DEFINE_string_(
GTEST_DEFINE_bool_(
death_test_use_fork,
testing::internal::BoolFromGTestEnv("death_test_use_fork", false),
"Instructs to use fork()/_exit() instead of clone() in death tests. "
"Instructs to use fork()/_Exit() instead of clone() in death tests. "
"Ignored and always uses fork() on POSIX systems where clone() is not "
"implemented. Useful when running under valgrind or similar tools if "
"those do not support clone(). Valgrind 3.3.1 will just fail if "
@@ -299,7 +301,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
fputc(kDeathTestInternalError, parent);
fprintf(parent, "%s", message.c_str());
fflush(parent);
_exit(1);
_Exit(1);
} else {
fprintf(stderr, "%s", message.c_str());
fflush(stderr);
@@ -511,7 +513,7 @@ std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }
// Signals that the death test code which should have exited, didn't.
// Should be called only in a death test child process.
// Writes a status byte to the child's status file descriptor, then
// calls _exit(1).
// calls _Exit(1).
void DeathTestImpl::Abort(AbortReason reason) {
// The parent process considers the death test to be a failure if
// it finds any data in our pipe. So, here we write a single flag byte
@@ -523,13 +525,13 @@ void DeathTestImpl::Abort(AbortReason reason) {
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
// We are leaking the descriptor here because on some platforms (i.e.,
// when built as Windows DLL), destructors of global objects will still
// run after calling _exit(). On such systems, write_fd_ will be
// run after calling _Exit(). On such systems, write_fd_ will be
// indirectly closed from the destructor of UnitTestImpl, causing double
// close if it is also closed here. On debug configurations, double close
// may assert. As there are no in-process buffers to flush here, we are
// relying on the OS to close the descriptor after the process terminates
// when the destructors are not run.
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
_Exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
}
// Returns an indented copy of stderr output for a death test.
@@ -628,13 +630,13 @@ bool DeathTestImpl::Passed(bool status_ok) {
#ifndef GTEST_OS_WINDOWS
// Note: The return value points into args, so the return value's lifetime is
// bound to that of args.
static std::unique_ptr<char*[]> CreateArgvFromArgs(
std::vector<std::string>& args) {
auto result = std::make_unique<char*[]>(args.size() + 1);
for (size_t i = 0; i < args.size(); ++i) {
result[i] = &args[i][0];
static std::vector<char*> CreateArgvFromArgs(std::vector<std::string>& args) {
std::vector<char*> result;
result.reserve(args.size() + 1);
for (auto& arg : args) {
result.push_back(&arg[0]);
}
result[args.size()] = nullptr; // extra null terminator
result.push_back(nullptr); // Extra null terminator.
return result;
}
#endif
@@ -783,7 +785,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +
// size_t has the same width as pointers on both 32-bit and 64-bit
// Windows platforms.
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
// See https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + "|" +
StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
@@ -1034,8 +1036,8 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
// "Fuchsia Test Component" which contains a "Fuchsia Component Manifest")
// Launching processes is a privileged operation in Fuchsia, and the
// declaration indicates that the ability is required for the component.
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(),
std::vector<char*> argv = CreateArgvFromArgs(args);
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(),
nullptr, 2, spawn_actions,
child_process_.reset_and_get_address(), nullptr);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
@@ -1333,7 +1335,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {
#endif // GTEST_HAS_CLONE
if (use_fork && (child_pid = fork()) == 0) {
_exit(ExecDeathTestChildMain(&args));
_Exit(ExecDeathTestChildMain(&args));
}
#endif // GTEST_OS_QNX
#ifdef GTEST_OS_LINUX
@@ -1386,8 +1388,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// is necessary.
FlushInfoLog();
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]);
std::vector<char*> argv = CreateArgvFromArgs(args);
const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
set_child_pid(child_pid);
set_read_fd(pipe_fd[0]);

View File

@@ -336,7 +336,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
return false;
}
if (pathname_.length() == 0 || this->DirectoryExists()) {
if (pathname_.empty() || this->DirectoryExists()) {
return true;
}

View File

@@ -46,6 +46,7 @@
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "gtest/internal/gtest-port.h"
@@ -312,7 +313,7 @@ void ShuffleRange(internal::Random* random, int begin, int end,
<< begin << ", " << size << "].";
// Fisher-Yates shuffle, from
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
// https://en.wikipedia.org/wiki/Fisher-Yates_shuffle
for (int range_width = end - begin; range_width >= 2; range_width--) {
const int last_in_range = begin + range_width - 1;
const int selected =
@@ -649,13 +650,15 @@ class GTEST_API_ UnitTestImpl {
// this is not a typed or a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
TestSuite* GetTestSuite(const std::string& test_suite_name,
const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc);
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
TestCase* GetTestCase(const char* test_case_name, const char* type_param,
TestCase* GetTestCase(const std::string& test_case_name,
const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc) {
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
@@ -681,13 +684,13 @@ class GTEST_API_ UnitTestImpl {
// AddTestInfo(), which is called to register a TEST or TEST_F
// before main() is reached.
if (original_working_dir_.IsEmpty()) {
original_working_dir_.Set(FilePath::GetCurrentDir());
original_working_dir_ = FilePath::GetCurrentDir();
GTEST_CHECK_(!original_working_dir_.IsEmpty())
<< "Failed to get the current working directory.";
}
#endif // GTEST_HAS_FILE_SYSTEM
GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
GetTestSuite(test_info->test_suite_name_, test_info->type_param(),
set_up_tc, tear_down_tc)
->AddTestInfo(test_info);
}
@@ -709,18 +712,6 @@ class GTEST_API_ UnitTestImpl {
return type_parameterized_test_registry_;
}
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
}
// Sets the TestInfo object for the test that's currently running. If
// current_test_info is NULL, the assertion results will be stored in
// ad_hoc_test_result_.
void set_current_test_info(TestInfo* a_current_test_info) {
current_test_info_ = a_current_test_info;
}
// Registers all parameterized tests defined using TEST_P and
// INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
// combination. This method can be called more then once; it has guards
@@ -835,12 +826,30 @@ class GTEST_API_ UnitTestImpl {
bool catch_exceptions() const { return catch_exceptions_; }
private:
struct CompareTestSuitesByPointer {
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
return lhs->name_ < rhs->name_;
}
};
friend class ::testing::UnitTest;
// Used by UnitTest::Run() to capture the state of
// GTEST_FLAG(catch_exceptions) at the moment it starts.
void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
}
// Sets the TestInfo object for the test that's currently running. If
// current_test_info is NULL, the assertion results will be stored in
// ad_hoc_test_result_.
void set_current_test_info(TestInfo* a_current_test_info) {
current_test_info_ = a_current_test_info;
}
// The UnitTest object that owns this implementation object.
UnitTest* const parent_;
@@ -873,6 +882,9 @@ class GTEST_API_ UnitTestImpl {
// elements in the vector.
std::vector<TestSuite*> test_suites_;
// The set of TestSuites by name.
std::unordered_map<std::string, TestSuite*> test_suites_by_name_;
// Provides a level of indirection for the test suite list to allow
// easy shuffling and restoring the test suite order. The i-th
// element of this vector is the index of the i-th test suite in the

View File

@@ -158,13 +158,13 @@ size_t GetThreadCount() {
// we cannot detect it.
size_t GetThreadCount() {
int mib[] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid(),
CTL_KERN,
KERN_PROC,
KERN_PROC_PID,
getpid(),
#ifdef GTEST_OS_NETBSD
sizeof(struct kinfo_proc),
1,
sizeof(struct kinfo_proc),
1,
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);
@@ -587,9 +587,11 @@ class ThreadLocalRegistryImpl {
// thread's ID.
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
// Holds the thread id and thread handle that we pass from
// StartWatcherThreadFor to WatcherThreadFunc.
typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
struct WatcherThreadParams {
DWORD thread_id;
HANDLE handle;
Notification has_initialized;
};
static void StartWatcherThreadFor(DWORD thread_id) {
// The returned handle will be kept in thread_map and closed by
@@ -597,15 +599,20 @@ class ThreadLocalRegistryImpl {
HANDLE thread =
::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
GTEST_CHECK_(thread != nullptr);
WatcherThreadParams* watcher_thread_params = new WatcherThreadParams;
watcher_thread_params->thread_id = thread_id;
watcher_thread_params->handle = thread;
// We need to pass a valid thread ID pointer into CreateThread for it
// to work correctly under Win98.
DWORD watcher_thread_id;
HANDLE watcher_thread = ::CreateThread(
nullptr, // Default security.
0, // Default stack size
&ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
CREATE_SUSPENDED, &watcher_thread_id);
HANDLE watcher_thread =
::CreateThread(nullptr, // Default security.
0, // Default stack size
&ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(watcher_thread_params),
CREATE_SUSPENDED, &watcher_thread_id);
GTEST_CHECK_(watcher_thread != nullptr)
<< "CreateThread failed with error " << ::GetLastError() << ".";
// Give the watcher thread the same priority as ours to avoid being
@@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl {
::GetThreadPriority(::GetCurrentThread()));
::ResumeThread(watcher_thread);
::CloseHandle(watcher_thread);
// Wait for the watcher thread to start to avoid race conditions.
// One specific race condition that can happen is that we have returned
// from main and have started to tear down, the newly spawned watcher
// thread may access already-freed variables, like global shared_ptrs.
watcher_thread_params->has_initialized.WaitForNotification();
}
// Monitors exit from a given thread and notifies those
// ThreadIdToThreadLocals about thread termination.
static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
const ThreadIdAndHandle* tah =
reinterpret_cast<const ThreadIdAndHandle*>(param);
GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
OnThreadExit(tah->first);
::CloseHandle(tah->second);
delete tah;
WatcherThreadParams* watcher_thread_params =
reinterpret_cast<WatcherThreadParams*>(param);
watcher_thread_params->has_initialized.Notify();
GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle,
INFINITE) == WAIT_OBJECT_0);
OnThreadExit(watcher_thread_params->thread_id);
::CloseHandle(watcher_thread_params->handle);
delete watcher_thread_params;
return 0;
}
@@ -697,13 +712,24 @@ bool RE::PartialMatch(const char* str, const RE& re) {
void RE::Init(const char* regex) {
pattern_ = regex;
// NetBSD (and Android, which takes its regex implemntation from NetBSD) does
// not include the GNU regex extensions (such as Perl style character classes
// like \w) in REG_EXTENDED. REG_EXTENDED is only specified to include the
// [[:alpha:]] style character classes. Enable REG_GNU wherever it is defined
// so users can use those extensions.
#if defined(REG_GNU)
constexpr int reg_flags = REG_EXTENDED | REG_GNU;
#else
constexpr int reg_flags = REG_EXTENDED;
#endif
// Reserves enough bytes to hold the regular expression used for a
// full match.
const size_t full_regex_len = strlen(regex) + 10;
char* const full_pattern = new char[full_regex_len];
snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
is_valid_ = regcomp(&full_regex_, full_pattern, reg_flags) == 0;
// We want to call regcomp(&partial_regex_, ...) even if the
// previous expression returns false. Otherwise partial_regex_ may
// not be properly initialized can may cause trouble when it's
@@ -714,7 +740,7 @@ void RE::Init(const char* regex) {
// regex. We change it to an equivalent form "()" to be safe.
if (is_valid_) {
const char* const partial_regex = (*regex == '\0') ? "()" : regex;
is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
is_valid_ = regcomp(&partial_regex_, partial_regex, reg_flags) == 0;
}
EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex
@@ -1022,11 +1048,21 @@ GTestLog::~GTestLog() {
}
}
#if GTEST_HAS_STREAM_REDIRECTION
// Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
#if GTEST_HAS_STREAM_REDIRECTION
namespace {
#if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS)
bool EndsWithPathSeparator(const std::string& path) {
return !path.empty() && path.back() == GTEST_PATH_SEP_[0];
}
#endif
} // namespace
// Object that captures an output stream (stdout/stderr).
class CapturedStream {
@@ -1064,7 +1100,13 @@ class CapturedStream {
// The location /data/local/tmp is directly accessible from native code.
// '/sdcard' and other variants cannot be relied on, as they are not
// guaranteed to be mounted, or may have a delay in mounting.
name_template = "/data/local/tmp/";
//
// However, prefer using the TMPDIR environment variable if set, as newer
// devices may have /data/local/tmp read-only.
name_template = TempDir();
if (!EndsWithPathSeparator(name_template))
name_template.push_back(GTEST_PATH_SEP_[0]);
#elif defined(GTEST_OS_IOS)
char user_temp_dir[PATH_MAX + 1];
@@ -1084,7 +1126,7 @@ class CapturedStream {
::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));
name_template = user_temp_dir;
if (name_template.back() != GTEST_PATH_SEP_[0])
if (!EndsWithPathSeparator(name_template))
name_template.push_back(GTEST_PATH_SEP_[0]);
#else
name_template = "/tmp/";
@@ -1306,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
) {
Message msg;
msg << "WARNING: " << src_text
<< " is expected to be a 32-bit integer, but actually"
<< " has value " << str << ", which overflows.\n";
<< " is expected to be a 32-bit integer, but actually" << " has value "
<< str << ", which overflows.\n";
printf("%s", msg.GetString().c_str());
fflush(stdout);
return false;

View File

@@ -43,6 +43,7 @@
#include <algorithm>
#include <chrono> // NOLINT
#include <cmath>
#include <csignal> // NOLINT: raise(3) is used on some platforms
#include <cstdint>
#include <cstdlib>
#include <cstring>
@@ -161,6 +162,10 @@
#define GTEST_HAS_BUILTIN(x) 0
#endif // defined(__has_builtin)
#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)
#define GTEST_HAS_ABSL_FLAGS
#endif
namespace testing {
using internal::CountIf;
@@ -374,7 +379,7 @@ GTEST_DEFINE_string_(
testing::internal::StringFromGTestEnv("stream_result_to", ""),
"This flag specifies the host name and the port number on which to stream "
"test results. Example: \"localhost:555\". The flag is effective only on "
"Linux.");
"Linux and macOS.");
GTEST_DEFINE_bool_(
throw_on_failure,
@@ -446,6 +451,19 @@ static bool ShouldRunTestSuite(const TestSuite* test_suite) {
return test_suite->should_run();
}
namespace {
// Returns true if test part results of type `type` should include a stack
// trace.
bool ShouldEmitStackTraceForResultType(TestPartResult::Type type) {
// Suppress emission of the stack trace for SUCCEED() since it likely never
// requires investigation, and GTEST_SKIP() since skipping is an intentional
// act by the developer rather than a failure requiring investigation.
return type != TestPartResult::kSuccess && type != TestPartResult::kSkip;
}
} // namespace
// AssertHelper constructor.
AssertHelper::AssertHelper(TestPartResult::Type type, const char* file,
int line, const char* message)
@@ -458,7 +476,9 @@ void AssertHelper::operator=(const Message& message) const {
UnitTest::GetInstance()->AddTestPartResult(
data_->type, data_->file, data_->line,
AppendUserMessage(data_->message, message),
UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1)
ShouldEmitStackTraceForResultType(data_->type)
? UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1)
: ""
// Skips the stack frame for this function itself.
); // NOLINT
}
@@ -516,7 +536,8 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location,
if (ignored.find(name) != ignored.end()) return;
const char kMissingInstantiation[] = //
" is defined via TEST_P, but never instantiated. None of the test cases "
" is defined via TEST_P, but never instantiated. None of the test "
"cases "
"will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only "
"ones provided expand to nothing."
"\n\n"
@@ -557,7 +578,7 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location,
void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
CodeLocation code_location) {
GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(
test_suite_name, code_location);
test_suite_name, std::move(code_location));
}
void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
@@ -568,7 +589,7 @@ void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {
void TypeParameterizedTestSuiteRegistry::RegisterTestSuite(
const char* test_suite_name, CodeLocation code_location) {
suites_.emplace(std::string(test_suite_name),
TypeParameterizedTestSuiteInfo(code_location));
TypeParameterizedTestSuiteInfo(std::move(code_location)));
}
void TypeParameterizedTestSuiteRegistry::RegisterInstantiation(
@@ -595,10 +616,12 @@ void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() {
"\n\n"
"Ideally, TYPED_TEST_P definitions should only ever be included as "
"part of binaries that intend to use them. (As opposed to, for "
"example, being placed in a library that may be linked in to get other "
"example, being placed in a library that may be linked in to get "
"other "
"utilities.)"
"\n\n"
"To suppress this error for this test suite, insert the following line "
"To suppress this error for this test suite, insert the following "
"line "
"(in a non-header) in the namespace it is defined in:"
"\n\n"
"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" +
@@ -638,11 +661,14 @@ static ::std::vector<std::string> g_argvs;
FilePath GetCurrentExecutableName() {
FilePath result;
auto args = GetArgvs();
if (!args.empty()) {
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_OS2)
result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe"));
result.Set(FilePath(args[0]).RemoveExtension("exe"));
#else
result.Set(FilePath(GetArgvs()[0]));
result.Set(FilePath(args[0]));
#endif // GTEST_OS_WINDOWS
}
return result.RemoveDirectoryName();
}
@@ -778,7 +804,7 @@ class UnitTestFilter {
// Returns true if and only if name matches at least one of the patterns in
// the filter.
bool MatchesName(const std::string& name) const {
return exact_match_patterns_.count(name) > 0 ||
return exact_match_patterns_.find(name) != exact_match_patterns_.end() ||
std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
[&name](const std::string& pattern) {
return PatternMatchesString(
@@ -879,7 +905,7 @@ int UnitTestOptions::GTestProcessSEH(DWORD seh_code, const char* location) {
// apparently).
//
// SEH exception code for C++ exceptions.
// (see http://support.microsoft.com/kb/185294 for more information).
// (see https://support.microsoft.com/kb/185294 for more information).
const DWORD kCxxExceptionCode = 0xe06d7363;
if (!GTEST_FLAG_GET(catch_exceptions) || seh_code == kCxxExceptionCode ||
@@ -2317,7 +2343,7 @@ static const char* const kReservedTestCaseAttributes[] = {
"type_param", "value_param", "file", "line"};
// Use a slightly different set for allowed output to ensure existing tests can
// still RecordProperty("result") or "RecordProperty(timestamp")
// still RecordProperty("result") or RecordProperty("timestamp")
static const char* const kReservedOutputTestCaseAttributes[] = {
"classname", "name", "status", "time", "type_param",
"value_param", "file", "line", "result", "timestamp"};
@@ -2717,18 +2743,16 @@ bool Test::IsSkipped() {
// Constructs a TestInfo object. It assumes ownership of the test factory
// object.
TestInfo::TestInfo(const std::string& a_test_suite_name,
const std::string& a_name, const char* a_type_param,
const char* a_value_param,
TestInfo::TestInfo(std::string a_test_suite_name, std::string a_name,
const char* a_type_param, const char* a_value_param,
internal::CodeLocation a_code_location,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory)
: test_suite_name_(a_test_suite_name),
// begin()/end() is MSVC 17.3.3 ASAN crash workaround (GitHub issue #3997)
name_(a_name.begin(), a_name.end()),
: test_suite_name_(std::move(a_test_suite_name)),
name_(std::move(a_name)),
type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
location_(a_code_location),
location_(std::move(a_code_location)),
fixture_class_id_(fixture_class_id),
should_run_(false),
is_disabled_(false),
@@ -2761,19 +2785,19 @@ namespace internal {
// The newly created TestInfo instance will assume
// ownership of the factory object.
TestInfo* MakeAndRegisterTestInfo(
const char* test_suite_name, const char* name, const char* type_param,
std::string test_suite_name, const char* name, const char* type_param,
const char* value_param, CodeLocation code_location,
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {
TestInfo* const test_info =
new TestInfo(test_suite_name, name, type_param, value_param,
code_location, fixture_class_id, factory);
new TestInfo(std::move(test_suite_name), name, type_param, value_param,
std::move(code_location), fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info;
}
void ReportInvalidTestSuiteType(const char* test_suite_name,
CodeLocation code_location) {
const CodeLocation& code_location) {
Message errors;
errors
<< "Attempted redefinition of test suite " << test_suite_name << ".\n"
@@ -2813,14 +2837,13 @@ void TestInfo::Run() {
}
// Tells UnitTest where to store test result.
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(this);
UnitTest::GetInstance()->set_current_test_info(this);
// Notifies the unit test event listeners that a test is about to start.
repeater->OnTestStart(*this);
result_.set_start_timestamp(internal::GetTimeInMillis());
internal::Timer timer;
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
// Creates the test object.
Test* const test = internal::HandleExceptionsInMethodIfSupported(
@@ -2838,7 +2861,7 @@ void TestInfo::Run() {
if (test != nullptr) {
// Deletes the test object.
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
test, &Test::DeleteSelf_, "the test fixture's destructor");
}
@@ -2850,15 +2873,14 @@ void TestInfo::Run() {
// Tells UnitTest to stop associating assertion results to this
// test.
impl->set_current_test_info(nullptr);
UnitTest::GetInstance()->set_current_test_info(nullptr);
}
// Skip and records a skipped test result for this object.
void TestInfo::Skip() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(this);
UnitTest::GetInstance()->set_current_test_info(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
@@ -2867,12 +2889,13 @@ void TestInfo::Skip() {
const TestPartResult test_part_result =
TestPartResult(TestPartResult::kSkip, this->file(), this->line(), "");
impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(
test_part_result);
internal::GetUnitTestImpl()
->GetTestPartResultReporterForCurrentThread()
->ReportTestPartResult(test_part_result);
// Notifies the unit test event listener that a test has just finished.
repeater->OnTestEnd(*this);
impl->set_current_test_info(nullptr);
UnitTest::GetInstance()->set_current_test_info(nullptr);
}
// class TestSuite
@@ -2926,7 +2949,7 @@ int TestSuite::total_test_count() const {
// this is not a typed or a type-parameterized test suite.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite::TestSuite(const char* a_name, const char* a_type_param,
TestSuite::TestSuite(const std::string& a_name, const char* a_type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc)
: name_(a_name),
@@ -2968,8 +2991,7 @@ void TestSuite::AddTestInfo(TestInfo* test_info) {
void TestSuite::Run() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_suite(this);
UnitTest::GetInstance()->set_current_test_suite(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
@@ -2999,7 +3021,7 @@ void TestSuite::Run() {
repeater->OnTestCaseStart(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
@@ -3024,7 +3046,7 @@ void TestSuite::Run() {
}
elapsed_time_ = timer.Elapsed();
impl->os_stack_trace_getter()->UponLeavingGTest();
UnitTest::GetInstance()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()");
@@ -3035,15 +3057,14 @@ void TestSuite::Run() {
repeater->OnTestCaseEnd(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
impl->set_current_test_suite(nullptr);
UnitTest::GetInstance()->set_current_test_suite(nullptr);
}
// Skips all tests under this TestSuite.
void TestSuite::Skip() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_suite(this);
UnitTest::GetInstance()->set_current_test_suite(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
@@ -3065,7 +3086,7 @@ void TestSuite::Skip() {
repeater->OnTestCaseEnd(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
impl->set_current_test_suite(nullptr);
UnitTest::GetInstance()->set_current_test_suite(nullptr);
}
// Clears the results of all tests in this test suite.
@@ -3166,9 +3187,9 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) {
}
// class PrettyUnitTestResultPrinter
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \
!defined(GTEST_OS_WINDOWS_MINGW)
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)
// Returns the character attribute for the given color.
static WORD GetColorAttribute(GTestColor color) {
@@ -3228,7 +3249,8 @@ static const char* GetAnsiColorCode(GTestColor color) {
case GTestColor::kYellow:
return "3";
default:
return nullptr;
assert(false);
return "9";
}
}
@@ -3251,6 +3273,7 @@ bool ShouldUseColor(bool stdout_is_tty) {
term != nullptr && (String::CStringEquals(term, "xterm") ||
String::CStringEquals(term, "xterm-color") ||
String::CStringEquals(term, "xterm-kitty") ||
String::CStringEquals(term, "alacritty") ||
String::CStringEquals(term, "screen") ||
String::CStringEquals(term, "tmux") ||
String::CStringEquals(term, "rxvt-unicode") ||
@@ -3281,11 +3304,9 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_start(args, fmt);
static const bool in_color_mode =
#if GTEST_HAS_FILE_SYSTEM
// We don't condition this on GTEST_HAS_FILE_SYSTEM because we still need
// to be able to detect terminal I/O regardless.
ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
#else
false;
#endif // GTEST_HAS_FILE_SYSTEM
const bool use_color = in_color_mode && (color != GTestColor::kDefault);
@@ -3295,9 +3316,9 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
return;
}
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \
!defined(GTEST_OS_WINDOWS_MINGW)
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \
!defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
// Gets the current text color.
@@ -4420,8 +4441,8 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
Message attributes;
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
attributes << " " << property.key() << "="
<< "\"" << EscapeXmlAttribute(property.value()) << "\"";
attributes << " " << property.key() << "=" << "\""
<< EscapeXmlAttribute(property.value()) << "\"";
}
return attributes.GetString();
}
@@ -4725,28 +4746,53 @@ void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream,
const TestResult& result) {
const std::string kIndent = Indent(10);
int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
if (part.failed()) {
*stream << ",\n";
if (++failures == 1) {
*stream << kIndent << "\""
<< "failures"
<< "\": [\n";
{
int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
if (part.failed()) {
*stream << ",\n";
if (++failures == 1) {
*stream << kIndent << "\"" << "failures" << "\": [\n";
}
const std::string location =
internal::FormatCompilerIndependentFileLocation(part.file_name(),
part.line_number());
const std::string message =
EscapeJson(location + "\n" + part.message());
*stream << kIndent << " {\n"
<< kIndent << " \"failure\": \"" << message << "\",\n"
<< kIndent << " \"type\": \"\"\n"
<< kIndent << " }";
}
const std::string location =
internal::FormatCompilerIndependentFileLocation(part.file_name(),
part.line_number());
const std::string message = EscapeJson(location + "\n" + part.message());
*stream << kIndent << " {\n"
<< kIndent << " \"failure\": \"" << message << "\",\n"
<< kIndent << " \"type\": \"\"\n"
<< kIndent << " }";
}
if (failures > 0) *stream << "\n" << kIndent << "]";
}
{
int skipped = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
if (part.skipped()) {
*stream << ",\n";
if (++skipped == 1) {
*stream << kIndent << "\"" << "skipped" << "\": [\n";
}
const std::string location =
internal::FormatCompilerIndependentFileLocation(part.file_name(),
part.line_number());
const std::string message =
EscapeJson(location + "\n" + part.message());
*stream << kIndent << " {\n"
<< kIndent << " \"message\": \"" << message << "\"\n"
<< kIndent << " }";
}
}
if (skipped > 0) *stream << "\n" << kIndent << "]";
}
if (failures > 0) *stream << "\n" << kIndent << "]";
*stream << "\n" << Indent(8) << "}";
}
@@ -4883,8 +4929,8 @@ std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
attributes << ",\n"
<< indent << "\"" << property.key() << "\": "
<< "\"" << EscapeJson(property.value()) << "\"";
<< indent << "\"" << property.key() << "\": " << "\""
<< EscapeJson(property.value()) << "\"";
}
return attributes.GetString();
}
@@ -5282,6 +5328,22 @@ TestSuite* UnitTest::GetMutableTestSuite(int i) {
return impl()->GetMutableSuiteCase(i);
}
void UnitTest::UponLeavingGTest() {
impl()->os_stack_trace_getter()->UponLeavingGTest();
}
// Sets the TestSuite object for the test that's currently running.
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
internal::MutexLock lock(&mutex_);
impl_->set_current_test_suite(a_current_test_suite);
}
// Sets the TestInfo object for the test that's currently running.
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
internal::MutexLock lock(&mutex_);
impl_->set_current_test_info(a_current_test_info);
}
// Returns the list of event listeners that can be used to track events
// inside Google Test.
TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); }
@@ -5399,7 +5461,7 @@ void UnitTest::RecordProperty(const std::string& key,
int UnitTest::Run() {
#ifdef GTEST_HAS_DEATH_TEST
const bool in_death_test_child_process =
GTEST_FLAG_GET(internal_run_death_test).length() > 0;
!GTEST_FLAG_GET(internal_run_death_test).empty();
// Google Test implements this protocol for catching that a test
// program exits before returning control to Google Test:
@@ -5441,7 +5503,7 @@ int UnitTest::Run() {
// about crashes - they are expected.
if (impl()->catch_exceptions() || in_death_test_child_process) {
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \
!defined(GTEST_OS_WINDOWS_RT)
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES)
// SetErrorMode doesn't exist on CE.
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
@@ -5711,29 +5773,6 @@ void UnitTestImpl::PostFlagParsingInit() {
}
}
// A predicate that checks the name of a TestSuite against a known
// value.
//
// This is used for implementation of the UnitTest class only. We put
// it in the anonymous namespace to prevent polluting the outer
// namespace.
//
// TestSuiteNameIs is copyable.
class TestSuiteNameIs {
public:
// Constructor.
explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
// Returns true if and only if the name of test_suite matches name_.
bool operator()(const TestSuite* test_suite) const {
return test_suite != nullptr &&
strcmp(test_suite->name(), name_.c_str()) == 0;
}
private:
std::string name_;
};
// Finds and returns a TestSuite with the given name. If one doesn't
// exist, creates one and returns it. It's the CALLER'S
// RESPONSIBILITY to ensure that this function is only called WHEN THE
@@ -5747,19 +5786,27 @@ class TestSuiteNameIs {
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite* UnitTestImpl::GetTestSuite(
const char* test_suite_name, const char* type_param,
const std::string& test_suite_name, const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc) {
// Can we find a TestSuite with the given name?
const auto test_suite =
std::find_if(test_suites_.rbegin(), test_suites_.rend(),
TestSuiteNameIs(test_suite_name));
// During initialization, all TestInfos for a given suite are added in
// sequence. To optimize this case, see if the most recently added suite is
// the one being requested now.
if (!test_suites_.empty() &&
(*test_suites_.rbegin())->name_ == test_suite_name) {
return *test_suites_.rbegin();
}
if (test_suite != test_suites_.rend()) return *test_suite;
// Fall back to searching the collection.
auto item_it = test_suites_by_name_.find(test_suite_name);
if (item_it != test_suites_by_name_.end()) {
return item_it->second;
}
// No. Let's create one.
// Not found. Create a new instance.
auto* const new_test_suite =
new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);
test_suites_by_name_.emplace(test_suite_name, new_test_suite);
const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter);
// Is this a death test suite?
@@ -5972,6 +6019,12 @@ bool UnitTestImpl::RunAllTests() {
}
repeater->OnTestProgramEnd(*parent_);
// Destroy environments in normal code, not in static teardown.
bool delete_environment_on_teardown = true;
if (delete_environment_on_teardown) {
ForEach(environments_, internal::Delete<Environment>);
environments_.clear();
}
if (!gtest_is_initialized_before_run_all_tests) {
ColoredPrintf(
@@ -6105,12 +6158,11 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
int num_runnable_tests = 0;
int num_selected_tests = 0;
for (auto* test_suite : test_suites_) {
const std::string& test_suite_name = test_suite->name();
const std::string& test_suite_name = test_suite->name_;
test_suite->set_should_run(false);
for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
TestInfo* const test_info = test_suite->test_info_list()[j];
const std::string test_name(test_info->name());
for (TestInfo* test_info : test_suite->test_info_list()) {
const std::string& test_name = test_info->name_;
// A test is disabled if test suite name or test name matches
// kDisableTestFilter.
const bool is_disabled =
@@ -6201,8 +6253,8 @@ void UnitTestImpl::ListTestsMatchingFilter() {
#if GTEST_HAS_FILE_SYSTEM
const std::string& output_format = UnitTestOptions::GetOutputFormat();
if (output_format == "xml" || output_format == "json") {
FILE* fileout = OpenFileForWriting(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
FILE* fileout =
OpenFileForWriting(UnitTestOptions::GetAbsolutePathToOutputFile());
std::stringstream stream;
if (output_format == "xml") {
XmlUnitTestResultPrinter(
@@ -6651,17 +6703,17 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
}
if (remove_flag) {
// Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as
// well.
for (int j = i; j != *argc; j++) {
argv[j] = argv[j + 1];
// Shift the remainder of the argv list left by one.
for (int j = i + 1; j < *argc; ++j) {
argv[j - 1] = argv[j];
}
// Decrements the argument count.
(*argc)--;
// Terminate the array with nullptr.
argv[*argc] = nullptr;
// We also need to decrement the iterator as we just removed
// an element.
i--;
@@ -6683,7 +6735,7 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
// remain in place. Unrecognized flags are not reported and do not cause the
// program to exit.
void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
#ifdef GTEST_HAS_ABSL
#ifdef GTEST_HAS_ABSL_FLAGS
if (*argc <= 0) return;
std::vector<char*> positional_args;
@@ -6769,11 +6821,13 @@ void InitGoogleTestImpl(int* argc, CharType** argv) {
#ifdef GTEST_HAS_ABSL
absl::InitializeSymbolizer(g_argvs[0].c_str());
#ifdef GTEST_HAS_ABSL_FLAGS
// When using the Abseil Flags library, set the program usage message to the
// help message, but remove the color-encoding from the message first.
absl::SetProgramUsageMessage(absl::StrReplaceAll(
kColorEncodedHelpMessage,
{{"@D", ""}, {"@R", ""}, {"@G", ""}, {"@Y", ""}, {"@@", "@"}}));
#endif // GTEST_HAS_ABSL_FLAGS
#endif // GTEST_HAS_ABSL
ParseGoogleTestFlagsOnly(argc, argv);

View File

@@ -123,14 +123,64 @@ typedef char bool;
#endif
#endif
#ifndef HAVE_FSEEKO
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
#if defined(HAVE__FSEEKI64) && defined(HAVE__FSTAT64) && defined(HAVE__SEEK64)
/* Windows API using int64 */
typedef zip_int64_t zip_off_t;
typedef struct _stat64 zip_os_stat_t;
#define zip_os_stat _stat64
#define zip_os_fstat _fstat64
#define zip_os_seek _fseeki64
#define ZIP_FSEEK_MAX ZIP_INT64_MAX
#define ZIP_FSEEK_MIN ZIP_INT64_MIN
#else
/* Normal API */
#include <sys/stat.h>
typedef struct stat zip_os_stat_t;
#define zip_os_fstat fstat
#define zip_os_stat stat
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
/* Using off_t */
typedef off_t zip_off_t;
#if SIZEOF_OFF_T == 8
#define ZIP_OFF_MAX ZIP_INT64_MAX
#define ZIP_OFF_MIN ZIP_INT64_MIN
#elif SIZEOF_OFF_T == 4
#define ZIP_OFF_MAX ZIP_INT32_MAX
#define ZIP_OFF_MIN ZIP_INT32_MIN
#elif SIZEOF_OFF_T == 2
#define ZIP_OFF_MAX ZIP_INT16_MAX
#define ZIP_OFF_MIN ZIP_INT16_MIN
#else
#error unsupported size of off_t
#endif
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
#define zip_os_fseek fseeko
#define zip_os_ftell ftello
#else
/* Using long */
typedef long zip_off_t;
#include <limits.h>
#define ZIP_FSEEK_MAX LONG_MAX
#define ZIP_FSEEK_MIN LONG_MIN
#define zip_os_fseek fseek
#define zip_os_ftell ftell
#endif
#endif
#ifndef HAVE_FTELLO
#define ftello(s) ((long)ftell((s)))
#endif
#ifdef HAVE_LOCALTIME_S
#ifdef _WIN32
/* Windows is incompatible to the C11 standard, hurray! */
@@ -179,27 +229,6 @@ typedef char bool;
#endif
#endif
#if SIZEOF_OFF_T == 8
#define ZIP_OFF_MAX ZIP_INT64_MAX
#define ZIP_OFF_MIN ZIP_INT64_MIN
#elif SIZEOF_OFF_T == 4
#define ZIP_OFF_MAX ZIP_INT32_MAX
#define ZIP_OFF_MIN ZIP_INT32_MIN
#elif SIZEOF_OFF_T == 2
#define ZIP_OFF_MAX ZIP_INT16_MAX
#define ZIP_OFF_MIN ZIP_INT16_MIN
#else
#error unsupported size of off_t
#endif
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
#else
#include <limits.h>
#define ZIP_FSEEK_MAX LONG_MAX
#define ZIP_FSEEK_MIN LONG_MIN
#endif
#ifndef SIZE_MAX
#if SIZEOF_SIZE_T == 8

View File

@@ -39,7 +39,6 @@
#include <time.h>
#include <zlib.h>
#include "zip.h"
#include "zipint.h"
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str, bool check_consistency);
@@ -283,6 +282,7 @@ _zip_dirent_init(zip_dirent_t *de) {
de->cloned = 0;
de->crc_valid = true;
de->last_mod_mtime_valid = false;
de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8);
de->version_needed = 10; /* 1.0 */
de->bitflags = 0;
@@ -1264,3 +1264,12 @@ zip_dirent_check_consistency(zip_dirent_t *dirent) {
}
return 0;
}
time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de) {
if (!de->last_mod_mtime_valid) {
de->last_mod_mtime = _zip_d2u_time(&de->last_mod);
de->last_mod_mtime_valid = true;
}
return de->last_mod_mtime;
}

View File

@@ -33,8 +33,7 @@
#include "zipint.h"
ZIP_EXTERN int
zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
static int zip_file_set_time(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags, time_t *mtime) {
zip_entry_t *e;
if (_zip_get_dirent(za, idx, 0, NULL) == NULL) {
@@ -66,18 +65,29 @@ zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16
e->changes->last_mod.time = dtime;
e->changes->last_mod.date = ddate;
if (mtime != NULL) {
e->changes->last_mod_mtime = *mtime;
e->changes->last_mod_mtime_valid = true;
}
else {
e->changes->last_mod_mtime_valid = false;
}
e->changes->changed |= ZIP_DIRENT_LAST_MOD;
return 0;
}
ZIP_EXTERN int
zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
ZIP_EXTERN int zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
return zip_file_set_time(za, idx, dtime, ddate, flags, NULL);
}
ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
zip_dostime_t dostime;
if (_zip_u2d_time(mtime, &dostime, &za->error) < 0) {
return -1;
}
return zip_file_set_dostime(za, idx, dostime.time, dostime.date, flags);
return zip_file_set_time(za, idx, dostime.time, dostime.date, flags, &mtime);
}

View File

@@ -68,6 +68,7 @@ _zip_new(zip_error_t *error) {
za->nopen_source = za->nopen_source_alloc = 0;
za->open_source = NULL;
za->progress = NULL;
za->torrent_mtime = 0;
return za;
}

View File

@@ -39,7 +39,6 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#ifdef _WIN32
#ifndef S_IWUSR
@@ -120,7 +119,7 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset,
}
#endif
if (fseeko((FILE *)f, (off_t)offset, whence) < 0) {
if (zip_os_fseek((FILE *)f, (zip_off_t)offset, whence) < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
return false;
}
@@ -130,15 +129,15 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset,
bool
_zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
struct stat sb;
zip_os_stat_t sb;
int ret;
if (ctx->fname) {
ret = stat(ctx->fname, &sb);
ret = zip_os_stat(ctx->fname, &sb);
}
else {
ret = fstat(fileno((FILE *)ctx->f), &sb);
ret = zip_os_fstat(fileno((FILE *)ctx->f), &sb);
}
if (ret < 0) {
@@ -168,7 +167,7 @@ _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
zip_int64_t
_zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) {
off_t offset = ftello((FILE *)f);
zip_off_t offset = zip_os_ftell((FILE *)f);
if (offset < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);

View File

@@ -178,9 +178,9 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin
{
int fd;
struct file_clone_range range;
struct stat st;
zip_os_stat_t st;
if (fstat(fileno(ctx->f), &st) < 0) {
if (zip_os_fstat(fileno(ctx->f), &st) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
return -1;
}
@@ -223,7 +223,7 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin
ctx->tmpname = NULL;
return -1;
}
if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) {
if (zip_os_fseek(tfp, (zip_off_t)offset, SEEK_SET) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
(void)fclose(tfp);
(void)remove(ctx->tmpname);
@@ -290,11 +290,11 @@ _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64
static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) {
char *temp;
int mode;
struct stat st;
zip_os_stat_t st;
int fd = 0;
char *start, *end;
if (stat(ctx->fname, &st) == 0) {
if (zip_os_stat(ctx->fname, &st) == 0) {
mode = st.st_mode;
}
else {
@@ -344,7 +344,7 @@ static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) {
}
}
else {
if (stat(temp, &st) < 0) {
if (zip_os_stat(temp, &st) < 0) {
if (errno == ENOENT) {
break;
}

View File

@@ -77,7 +77,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
}
if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_LAST_MOD) {
st->mtime = _zip_d2u_time(&de->last_mod);
st->mtime = zip_dirent_get_last_mod_mtime(de);
st->valid |= ZIP_STAT_MTIME;
}
}
@@ -86,7 +86,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
st->crc = de->crc;
st->size = de->uncomp_size;
st->mtime = _zip_d2u_time(&de->last_mod);
st->mtime = zip_dirent_get_last_mod_mtime(de);
st->comp_size = de->comp_size;
st->comp_method = (zip_uint16_t)de->comp_method;
st->encryption_method = de->encryption_method;
@@ -97,9 +97,12 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
}
if ((za->ch_flags & ZIP_AFL_WANT_TORRENTZIP) && (flags & ZIP_FL_UNCHANGED) == 0) {
zip_dostime_t dostime = {0xbc00, 0x2198};
if (za->torrent_mtime == 0) {
zip_dostime_t dostime = {0xbc00, 0x2198};
za->torrent_mtime = _zip_d2u_time(&dostime);
}
st->comp_method = ZIP_CM_DEFLATE;
st->mtime = _zip_d2u_time(&dostime);
st->mtime = za->torrent_mtime;
st->valid |= ZIP_STAT_MTIME | ZIP_STAT_COMP_METHOD;
st->valid &= ~ZIP_STAT_COMP_SIZE;
}

View File

@@ -314,6 +314,7 @@ struct zip {
zip_progress_t *progress; /* progress callback for zip_close() */
zip_uint32_t* write_crc; /* have _zip_write() compute CRC */
time_t torrent_mtime;
};
/* file in zip archive, part of API */
@@ -346,6 +347,7 @@ struct zip_dirent {
bool cloned; /* whether this instance is cloned, and thus shares non-changed strings */
bool crc_valid; /* if CRC is valid (sometimes not for encrypted archives) */
bool last_mod_mtime_valid;
zip_uint16_t version_madeby; /* (c) version of creator */
zip_uint16_t version_needed; /* (cl) version needed to extract */
@@ -366,6 +368,8 @@ struct zip_dirent {
zip_uint32_t compression_level; /* level of compression to use (never valid in orig) */
zip_uint16_t encryption_method; /* encryption method, computed from other fields */
char *password; /* file specific encryption password */
time_t last_mod_mtime; /* cached last_mod in Unix time format */
};
/* zip archive central directory */
@@ -553,6 +557,7 @@ int zip_dirent_check_consistency(zip_dirent_t *dirent);
zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *);
void _zip_dirent_free(zip_dirent_t *);
void _zip_dirent_finalize(zip_dirent_t *);
time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de);
void _zip_dirent_init(zip_dirent_t *);
bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t);
zip_dirent_t *_zip_dirent_new(void);

View File

@@ -220,6 +220,8 @@ typedef struct rc_api_award_achievement_request_t {
uint32_t hardcore;
/* The hash associated to the game being played */
const char* game_hash;
/* The number of seconds since the achievement was unlocked */
uint32_t seconds_since_unlock;
}
rc_api_award_achievement_request_t;
@@ -263,6 +265,8 @@ typedef struct rc_api_submit_lboard_entry_request_t {
int32_t score;
/* The hash associated to the game being played */
const char* game_hash;
/* The number of seconds since the leaderboard attempt was completed */
uint32_t seconds_since_completion;
}
rc_api_submit_lboard_entry_request_t;

View File

@@ -412,6 +412,8 @@ int rc_api_init_award_achievement_request(rc_api_request_t* request, const rc_ap
rc_url_builder_append_unum_param(&builder, "h", api_params->hardcore ? 1 : 0);
if (api_params->game_hash && *api_params->game_hash)
rc_url_builder_append_str_param(&builder, "m", api_params->game_hash);
if (api_params->seconds_since_unlock)
rc_url_builder_append_unum_param(&builder, "o", api_params->seconds_since_unlock);
/* Evaluate the signature. */
md5_init(&md5);
@@ -420,6 +422,14 @@ int rc_api_init_award_achievement_request(rc_api_request_t* request, const rc_ap
md5_append(&md5, (md5_byte_t*)api_params->username, (int)strlen(api_params->username));
snprintf(buffer, sizeof(buffer), "%d", api_params->hardcore ? 1 : 0);
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
if (api_params->seconds_since_unlock) {
/* second achievement id is needed by delegated unlock. including it here allows overloading
* the hash generating code on the server */
snprintf(buffer, sizeof(buffer), "%u", api_params->achievement_id);
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
snprintf(buffer, sizeof(buffer), "%u", api_params->seconds_since_unlock);
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
}
md5_finish(&md5, digest);
rc_format_md5(buffer, digest);
rc_url_builder_append_str_param(&builder, "v", buffer);
@@ -505,6 +515,9 @@ int rc_api_init_submit_lboard_entry_request(rc_api_request_t* request, const rc_
if (api_params->game_hash && *api_params->game_hash)
rc_url_builder_append_str_param(&builder, "m", api_params->game_hash);
if (api_params->seconds_since_completion)
rc_url_builder_append_unum_param(&builder, "o", api_params->seconds_since_completion);
/* Evaluate the signature. */
md5_init(&md5);
snprintf(buffer, sizeof(buffer), "%u", api_params->leaderboard_id);
@@ -512,6 +525,10 @@ int rc_api_init_submit_lboard_entry_request(rc_api_request_t* request, const rc_
md5_append(&md5, (md5_byte_t*)api_params->username, (int)strlen(api_params->username));
snprintf(buffer, sizeof(buffer), "%d", api_params->score);
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
if (api_params->seconds_since_completion) {
snprintf(buffer, sizeof(buffer), "%u", api_params->seconds_since_completion);
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
}
md5_finish(&md5, digest);
rc_format_md5(buffer, digest);
rc_url_builder_append_str_param(&builder, "v", buffer);

View File

@@ -578,13 +578,7 @@ static int rc_client_get_image_url(char buffer[], size_t buffer_size, int image_
image_request.image_name = image_name;
result = rc_api_init_fetch_image_request(&request, &image_request);
if (result == RC_OK)
{
const size_t url_length = strlen(request.url);
if (url_length >= buffer_size)
result = RC_INSUFFICIENT_BUFFER;
else
memcpy(buffer, request.url, url_length + 1);
}
snprintf(buffer, buffer_size, "%s", request.url);
rc_api_destroy_request(&request);
return result;
@@ -1440,7 +1434,6 @@ static void rc_client_activate_game(rc_client_load_state_t* load_state, rc_api_s
rc_mutex_lock(&client->state.mutex);
load_state->progress = (client->state.load == load_state) ?
RC_CLIENT_LOAD_GAME_STATE_DONE : RC_CLIENT_LOAD_GAME_STATE_ABORTED;
client->state.load = NULL;
rc_mutex_unlock(&client->state.mutex);
if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_DONE) {
@@ -1461,17 +1454,15 @@ static void rc_client_activate_game(rc_client_load_state_t* load_state, rc_api_s
start_session_response->num_unlocks, RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE);
}
/* make the loaded game active if another game is not aleady being loaded. */
rc_mutex_lock(&client->state.mutex);
if (client->state.load == NULL)
if (client->state.load == load_state)
client->game = load_state->game;
else
load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED;
rc_mutex_unlock(&client->state.mutex);
if (client->game != load_state->game) {
/* previous load state was aborted */
if (load_state->callback)
load_state->callback(RC_ABORTED, "The requested game is no longer active", client, load_state->callback_userdata);
}
else {
if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_ABORTED) {
/* if a change media request is pending, kick it off */
rc_client_pending_media_t* pending_media;
@@ -1481,6 +1472,9 @@ static void rc_client_activate_game(rc_client_load_state_t* load_state, rc_api_s
rc_mutex_unlock(&load_state->client->state.mutex);
if (pending_media) {
/* rc_client_check_pending_media will fail if it can't find the game in client->game or
* client->state.load->game. since we've detached the load_state, this has to occur after
* we've made the game active. */
if (pending_media->hash) {
rc_client_begin_change_media_from_hash(client, pending_media->hash,
pending_media->callback, pending_media->callback_userdata);
@@ -1494,12 +1488,50 @@ static void rc_client_activate_game(rc_client_load_state_t* load_state, rc_api_s
rc_client_free_pending_media(pending_media);
}
/* client->game must be set before calling this function so it can query the console_id */
rc_mutex_lock(&client->state.mutex);
if (client->state.load != load_state)
load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED;
rc_mutex_unlock(&client->state.mutex);
}
/* if the game is still being loaded, make sure all the required memory addresses are accessible
* so we can mark achievements as unsupported before loading them into the runtime. */
if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_ABORTED) {
/* TODO: it is desirable to not do memory reads from a background thread. Some emulators (like Dolphin) don't
* allow it. Dolphin's solution is to use a dummy read function that says all addresses are valid and
* switches to the actual read function after the callback is called. latter invalid reads will
* mark achievements as unsupported. */
/* ASSERT: client->game must be set before calling this function so the read_memory callback can query the console_id */
rc_client_validate_addresses(load_state->game, client);
rc_mutex_lock(&client->state.mutex);
if (client->state.load != load_state)
load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED;
rc_mutex_unlock(&client->state.mutex);
}
/* if the game is still being loaded, load any active acheivements/leaderboards into the runtime */
if (load_state->progress != RC_CLIENT_LOAD_GAME_STATE_ABORTED) {
rc_client_activate_achievements(load_state->game, client);
rc_client_activate_leaderboards(load_state->game, client);
/* detach the load state to indicate that loading is fully complete */
rc_mutex_lock(&client->state.mutex);
if (client->state.load == load_state)
client->state.load = NULL;
else
load_state->progress = RC_CLIENT_LOAD_GAME_STATE_ABORTED;
rc_mutex_unlock(&client->state.mutex);
}
/* one last sanity check to make sure the game is still being loaded. */
if (load_state->progress == RC_CLIENT_LOAD_GAME_STATE_ABORTED) {
/* game has been unloaded, or another game is being loaded over the top of this game */
if (load_state->callback)
load_state->callback(RC_ABORTED, "The requested game is no longer active", client, load_state->callback_userdata);
}
else {
if (load_state->hash->hash[0] != '[') {
if (load_state->client->state.spectator_mode != RC_CLIENT_SPECTATOR_MODE_LOCKED) {
/* schedule the periodic ping */
@@ -2007,7 +2039,6 @@ static int rc_client_attach_load_state(rc_client_t* client, rc_client_load_state
{
if (client->state.load == NULL) {
rc_client_unload_game(client);
client->state.load = load_state;
if (load_state->game == NULL) {
load_state->game = rc_client_allocate_game();
@@ -2018,6 +2049,10 @@ static int rc_client_attach_load_state(rc_client_t* client, rc_client_load_state
return 0;
}
}
rc_mutex_lock(&client->state.mutex);
client->state.load = load_state;
rc_mutex_unlock(&client->state.mutex);
}
else if (client->state.load != load_state) {
/* previous load was aborted */
@@ -2621,8 +2656,6 @@ static void rc_client_game_mark_ui_to_be_hidden(rc_client_t* client, rc_client_g
void rc_client_unload_game(rc_client_t* client)
{
rc_client_game_info_t* game;
rc_client_scheduled_callback_data_t** last;
rc_client_scheduled_callback_data_t* next;
if (!client)
return;
@@ -2649,29 +2682,38 @@ void rc_client_unload_game(rc_client_t* client)
if (client->state.load) {
/* this mimics rc_client_abort_async without nesting the lock */
client->state.load->async_handle.aborted = RC_CLIENT_ASYNC_ABORTED;
/* if the game is still being loaded, let the load process clean it up */
if (client->state.load->game == game)
game = NULL;
client->state.load = NULL;
}
if (client->state.spectator_mode == RC_CLIENT_SPECTATOR_MODE_LOCKED)
client->state.spectator_mode = RC_CLIENT_SPECTATOR_MODE_ON;
if (game != NULL)
if (game != NULL) {
rc_client_scheduled_callback_data_t** last;
rc_client_scheduled_callback_data_t* next;
rc_client_game_mark_ui_to_be_hidden(client, game);
last = &client->state.scheduled_callbacks;
do {
next = *last;
if (!next)
break;
last = &client->state.scheduled_callbacks;
do {
next = *last;
if (!next)
break;
/* remove rich presence ping scheduled event for game */
if (next->callback == rc_client_ping && game && next->related_id == game->public_.id) {
*last = next->next;
continue;
}
/* remove rich presence ping scheduled event for game */
if (next->callback == rc_client_ping && next->related_id == game->public_.id) {
*last = next->next;
continue;
}
last = &next->next;
} while (1);
last = &next->next;
} while (1);
}
rc_mutex_unlock(&client->state.mutex);
@@ -3534,7 +3576,7 @@ typedef struct rc_client_award_achievement_callback_data_t
uint32_t retry_count;
uint8_t hardcore;
const char* game_hash;
time_t unlock_time;
rc_clock_t unlock_time;
rc_client_t* client;
rc_client_scheduled_callback_data_t* scheduled_callback_data;
} rc_client_award_achievement_callback_data_t;
@@ -3685,6 +3727,11 @@ static void rc_client_award_achievement_server_call(rc_client_award_achievement_
api_params.hardcore = ach_data->hardcore;
api_params.game_hash = ach_data->game_hash;
if (ach_data->retry_count) {
const rc_clock_t now = ach_data->client->callbacks.get_time_millisecs(ach_data->client);
api_params.seconds_since_unlock = (uint32_t)((now - ach_data->unlock_time) / 1000);
}
result = rc_api_init_award_achievement_request(&request, &api_params);
if (result != RC_OK) {
RC_CLIENT_LOG_ERR_FORMATTED(ach_data->client, "Error constructing unlock request for achievement %u: %s", ach_data->id, rc_error_str(result));
@@ -3751,7 +3798,8 @@ static void rc_client_award_achievement(rc_client_t* client, rc_client_achieveme
callback_data->client = client;
callback_data->id = achievement->public_.id;
callback_data->hardcore = client->state.hardcore;
callback_data->unlock_time = achievement->public_.unlock_time;
callback_data->game_hash = client->game->public_.hash;
callback_data->unlock_time = client->callbacks.get_time_millisecs(client);
if (client->game) /* may be NULL if this gets called while unloading the game (from another thread - events are raised outside the lock) */
callback_data->game_hash = client->game->public_.hash;
@@ -4185,7 +4233,7 @@ typedef struct rc_client_submit_leaderboard_entry_callback_data_t
int32_t score;
uint32_t retry_count;
const char* game_hash;
time_t submit_time;
rc_clock_t submit_time;
rc_client_t* client;
rc_client_scheduled_callback_data_t* scheduled_callback_data;
} rc_client_submit_leaderboard_entry_callback_data_t;
@@ -4340,6 +4388,11 @@ static void rc_client_submit_leaderboard_entry_server_call(rc_client_submit_lead
api_params.score = lboard_data->score;
api_params.game_hash = lboard_data->game_hash;
if (lboard_data->retry_count) {
const rc_clock_t now = lboard_data->client->callbacks.get_time_millisecs(lboard_data->client);
api_params.seconds_since_completion = (uint32_t)((now - lboard_data->submit_time) / 1000);
}
result = rc_api_init_submit_lboard_entry_request(&request, &api_params);
if (result != RC_OK) {
RC_CLIENT_LOG_ERR_FORMATTED(lboard_data->client, "Error constructing submit leaderboard entry for leaderboard %u: %s", lboard_data->id, rc_error_str(result));
@@ -4383,7 +4436,7 @@ static void rc_client_submit_leaderboard_entry(rc_client_t* client, rc_client_le
callback_data->id = leaderboard->public_.id;
callback_data->score = leaderboard->value;
callback_data->game_hash = client->game->public_.hash;
callback_data->submit_time = time(NULL);
callback_data->submit_time = client->callbacks.get_time_millisecs(client);
RC_CLIENT_LOG_INFO_FORMATTED(client, "Submitting %s (%d) for leaderboard %u: %s",
leaderboard->public_.tracker_value, leaderboard->value, leaderboard->public_.id, leaderboard->public_.title);

View File

@@ -36,6 +36,17 @@ typedef struct rc_disallowed_core_settings_t
const rc_disallowed_setting_t* disallowed_settings;
} rc_disallowed_core_settings_t;
static const rc_disallowed_setting_t _rc_disallowed_beetle_psx_settings[] = {
{ "beetle_psx_cpu_freq_scale", "<100" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_beetle_psx_hw_settings[] = {
{ "beetle_psx_hw_cpu_freq_scale", "<100" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_bsnes_settings[] = {
{ "bsnes_region", "pal" },
{ NULL, NULL }
@@ -80,6 +91,11 @@ static const rc_disallowed_setting_t _rc_disallowed_fceumm_settings[] = {
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_flycast_settings[] = {
{ "reicast_sh4clock", "<200" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_gpgx_settings[] = {
{ "genesis_plus_gx_lock_on", ",action replay (pro),game genie" },
{ "genesis_plus_gx_region_detect", "pal" },
@@ -108,6 +124,7 @@ static const rc_disallowed_setting_t _rc_disallowed_neocd_settings[] = {
};
static const rc_disallowed_setting_t _rc_disallowed_pcsx_rearmed_settings[] = {
{ "pcsx_rearmed_psxclock", "<55" },
{ "pcsx_rearmed_region", "pal" },
{ NULL, NULL }
};
@@ -140,6 +157,11 @@ static const rc_disallowed_setting_t _rc_disallowed_snes9x_settings[] = {
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_swanstation_settings[] = {
{ "swanstation_CPU_Overclock", "<100" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_vice_settings[] = {
{ "vice_autostart", "disabled" }, /* autostart dictates initial load and reset from menu */
{ "vice_reset", "!autostart" }, /* reset dictates behavior when pressing reset button (END) */
@@ -152,6 +174,8 @@ static const rc_disallowed_setting_t _rc_disallowed_virtual_jaguar_settings[] =
};
static const rc_disallowed_core_settings_t rc_disallowed_core_settings[] = {
{ "Beetle PSX", _rc_disallowed_beetle_psx_settings },
{ "Beetle PSX HW", _rc_disallowed_beetle_psx_hw_settings },
{ "bsnes-mercury", _rc_disallowed_bsnes_settings },
{ "cap32", _rc_disallowed_cap32_settings },
{ "dolphin-emu", _rc_disallowed_dolphin_settings },
@@ -160,6 +184,7 @@ static const rc_disallowed_core_settings_t rc_disallowed_core_settings[] = {
{ "ecwolf", _rc_disallowed_ecwolf_settings },
{ "FCEUmm", _rc_disallowed_fceumm_settings },
{ "FinalBurn Neo", _rc_disallowed_fbneo_settings },
{ "Flycast", _rc_disallowed_flycast_settings },
{ "Genesis Plus GX", _rc_disallowed_gpgx_settings },
{ "Genesis Plus GX Wide", _rc_disallowed_gpgx_wide_settings },
{ "Mesen", _rc_disallowed_mesen_settings },
@@ -171,6 +196,7 @@ static const rc_disallowed_core_settings_t rc_disallowed_core_settings[] = {
{ "QUASI88", _rc_disallowed_quasi88_settings },
{ "SMS Plus GX", _rc_disallowed_smsplus_settings },
{ "Snes9x", _rc_disallowed_snes9x_settings },
{ "SwanStation", _rc_disallowed_swanstation_settings },
{ "VICE x64", _rc_disallowed_vice_settings },
{ "Virtual Jaguar", _rc_disallowed_virtual_jaguar_settings },
{ NULL, NULL }
@@ -186,6 +212,12 @@ static int rc_libretro_string_equal_nocase_wildcard(const char* test, const char
return (*value == '\0');
}
static int rc_libretro_numeric_less_than(const char* test, const char* value) {
int test_num = atoi(test);
int value_num = atoi(value);
return (test_num < value_num);
}
static int rc_libretro_match_value(const char* val, const char* match) {
/* if value starts with a comma, it's a CSV list of potential matches */
if (*match == ',') {
@@ -218,6 +250,10 @@ static int rc_libretro_match_value(const char* val, const char* match) {
if (*match == '!')
return !rc_libretro_match_value(val, &match[1]);
/* a leading less tahn means the provided value is the minimum allowed */
if (*match == '<')
return rc_libretro_numeric_less_than(val, &match[1]);
/* just a single value, attempt to match it */
return rc_libretro_string_equal_nocase_wildcard(val, match);
}

View File

@@ -8,7 +8,7 @@
RC_BEGIN_C_DECLS
#define RCHEEVOS_VERSION_MAJOR 11
#define RCHEEVOS_VERSION_MINOR 5
#define RCHEEVOS_VERSION_MINOR 6
#define RCHEEVOS_VERSION_PATCH 0
#define RCHEEVOS_MAKE_VERSION(major, minor, patch) (major * 1000000 + minor * 1000 + patch)

View File

@@ -721,16 +721,29 @@ static const rc_memory_regions_t rc_memory_regions_n64 = { _rc_memory_regions_n6
/* ===== Nintendo DS ===== */
/* https://www.akkit.org/info/gbatek.htm#dsmemorymaps */
static const rc_memory_region_t _rc_memory_regions_nintendo_ds[] = {
{ 0x000000U, 0x3FFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
{ 0x0000000U, 0x03FFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
/* To keep DS/DSi memory maps aligned, padding is set here for the DSi's extra RAM */
{ 0x0400000U, 0x0FFFFFFU, 0x02400000U, RC_MEMORY_TYPE_UNUSED, "Unused (DSi exclusive)" },
/* The DS/DSi have "tightly coupled memory": very fast memory directly connected to the CPU.
* This memory has an instruction variant (ITCM) and a data variant (DTCM).
* For achievement purposes it is useful to be able to access the data variant.
* This memory does not have a fixed address on console, being able to be moved to any $0xxxx000 region.
* While normally this kind of memory is addressed outside of the possible native addressing space, this is simply not possible,
* as the DS/DSi's address space covers all possible uint32_t values.
* $0E000000 is used here as a "pseudo-end," as this is nearly the end of all the memory actually mapped to addresses
* This means that (with the exception of $FFFF0000 onwards, which has the ARM9 BIOS mapped) $0E000000 onwards has nothing mapped to it
*/
{ 0x1000000U, 0x1003FFFU, 0x0E000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Data TCM" }
};
static const rc_memory_regions_t rc_memory_regions_nintendo_ds = { _rc_memory_regions_nintendo_ds, 1 };
static const rc_memory_regions_t rc_memory_regions_nintendo_ds = { _rc_memory_regions_nintendo_ds, 3 };
/* ===== Nintendo DSi ===== */
/* https://problemkaputt.de/gbatek.htm#dsiiomap */
static const rc_memory_region_t _rc_memory_regions_nintendo_dsi[] = {
{ 0x000000U, 0xFFFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
{ 0x0000000U, 0x0FFFFFFU, 0x02000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x1000000U, 0x1003FFFU, 0x0E000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Data TCM" }
};
static const rc_memory_regions_t rc_memory_regions_nintendo_dsi = { _rc_memory_regions_nintendo_dsi, 1 };
static const rc_memory_regions_t rc_memory_regions_nintendo_dsi = { _rc_memory_regions_nintendo_dsi, 2 };
/* ===== Oric ===== */
static const rc_memory_region_t _rc_memory_regions_oric[] = {
@@ -956,6 +969,31 @@ static const rc_memory_region_t _rc_memory_regions_wonderswan[] = {
};
static const rc_memory_regions_t rc_memory_regions_wonderswan = { _rc_memory_regions_wonderswan, 2 };
/* ===== ZX Spectrum ===== */
/* https://github.com/TASEmulators/BizHawk/blob/3a3b22c/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum16K/ZX16.cs
* https://github.com/TASEmulators/BizHawk/blob/3a3b22c/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Memory.cs
* https://worldofspectrum.org/faq/reference/128kreference.htm */
static const rc_memory_region_t _rc_memory_regions_zx_spectrum[] = {
/* ZX Spectrum is complicated as multiple models exist with varying amounts of memory.
* In practice, this can be reduced to two categories: 16K/48K units, and 128K units.
* 16K/48K units have RAM starting at $4000 onwards, 16K ending at $7FFF, 48K ending at $FFFF.
* 128K units have banked memory, with $4000-$7FFF normally having RAM bank 5, and $8000-$BFFF normally having RAM bank 2.
* $C000-$FFFF is normally reserved for banked RAM, having any of banks 0-7.
* For the purposes of the RAM map, $C000-$FFFF is assumed to be bank 0, and $10000 onwards has the other banks in order (1, 3, 4, 6, 7)
* Doing it this way always for 16K/48K games to have the same memory map on the 128K, and thus avoid issues due to the model selected.
* Later 128K units also have a special banking mode that changes up banking completely, but for 16K/48K compatibility purposes this doesn't matter, and so is irrelevant.
*/
{ 0x00000U, 0x03FFFU, 0x04000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen RAM" }, /* RAM bank 5 on 128K units */
{ 0x04000U, 0x07FFFU, 0x08000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 2 on 128K units */
{ 0x08000U, 0x0BFFFU, 0x0C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 0-7 on 128K units, assumed to be bank 0 here */
{ 0x0C000U, 0x0FFFFU, 0x10000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 1 on 128K units */
{ 0x10000U, 0x13FFFU, 0x14000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 3 on 128K units */
{ 0x14000U, 0x17FFFU, 0x18000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 4 on 128K units */
{ 0x18000U, 0x1BFFFU, 0x1C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RAM bank 6 on 128K units */
{ 0x1C000U, 0x1FFFFU, 0x20000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Screen RAM" } /* RAM bank 7 on 128K units */
};
static const rc_memory_regions_t rc_memory_regions_zx_spectrum = { _rc_memory_regions_zx_spectrum, 8 };
/* ===== default ===== */
static const rc_memory_regions_t rc_memory_regions_none = { 0, 0 };
@@ -1141,6 +1179,9 @@ const rc_memory_regions_t* rc_console_memory_regions(uint32_t console_id)
case RC_CONSOLE_WONDERSWAN:
return &rc_memory_regions_wonderswan;
case RC_CONSOLE_ZX_SPECTRUM:
return &rc_memory_regions_zx_spectrum;
default:
return &rc_memory_regions_none;
}

View File

@@ -199,19 +199,19 @@ int rc_evaluate_lboard(rc_lboard_t* self, int32_t* value, rc_peek_t peek, void*
/* start and submit are both true in the same frame, just submit without announcing the leaderboard is available */
self->state = RC_LBOARD_STATE_TRIGGERED;
}
else if (self->start.requirement == 0 && self->start.alternative == 0) {
/* start condition is empty - this leaderboard is submit-only with no measured progress */
else if (!self->start.requirement && !self->start.alternative) {
/* start trigger is empty. assume the leaderboard is in development and ignore */
}
else {
/* start the leaderboard attempt */
self->state = RC_LBOARD_STATE_STARTED;
/* reset any hit counts in the value */
if (self->progress)
rc_reset_value(self->progress);
rc_reset_value(&self->value);
}
/* reset any hit counts in the value */
if (self->progress)
rc_reset_value(self->progress);
rc_reset_value(&self->value);
}
break;

View File

@@ -726,6 +726,7 @@ static int rc_validate_conflicting_conditions(const rc_condset_t* conditions, co
const rc_condition_t* condition;
const rc_condition_t* condition_chain_start;
int overlap;
int chain_matches;
/* empty group */
if (conditions == NULL || compare_conditions == NULL)
@@ -777,9 +778,9 @@ static int rc_validate_conflicting_conditions(const rc_condset_t* conditions, co
/* if combining conditions exist, make sure the same combining conditions exist in the
* compare logic. conflicts can only occur if the combinining conditions match. */
chain_matches = 1;
if (condition_chain_start != condition)
{
int chain_matches = 1;
const rc_condition_t* condition_chain_iter = condition_chain_start;
while (condition_chain_iter != condition)
{
@@ -795,11 +796,8 @@ static int rc_validate_conflicting_conditions(const rc_condset_t* conditions, co
if (compare_condition->oper != RC_OPERATOR_NONE &&
!rc_validate_are_operands_equal(&compare_condition->operand2, &condition_chain_iter->operand2))
{
if (compare_condition->operand2.type != condition_chain_iter->operand2.type)
{
chain_matches = 0;
break;
}
chain_matches = 0;
break;
}
if (!compare_condition->next)
@@ -808,17 +806,27 @@ static int rc_validate_conflicting_conditions(const rc_condset_t* conditions, co
break;
}
if (compare_condition->type != RC_CONDITION_ADD_ADDRESS &&
compare_condition->type != RC_CONDITION_ADD_SOURCE &&
compare_condition->type != RC_CONDITION_SUB_SOURCE &&
compare_condition->type != RC_CONDITION_AND_NEXT)
{
/* things like AddHits and OrNext are hard to definitively detect conflicts. ignore them. */
chain_matches = 0;
break;
}
compare_condition = compare_condition->next;
condition_chain_iter = condition_chain_iter->next;
}
}
/* combining field didn't match, or there's more unmatched combining fields. ignore this condition */
if (!chain_matches || rc_validate_is_combining_condition(compare_condition))
{
while (compare_condition->next && rc_validate_is_combining_condition(compare_condition))
compare_condition = compare_condition->next;
continue;
}
/* combining field didn't match, or there's more unmatched combining fields. ignore this condition */
if (!chain_matches || rc_validate_is_combining_condition(compare_condition))
{
while (compare_condition->next && rc_validate_is_combining_condition(compare_condition))
compare_condition = compare_condition->next;
continue;
}
if (compare_condition->required_hits)

View File

@@ -360,6 +360,9 @@ static const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup
do
{
line = nextline;
if (line == NULL)
break;
nextline = rc_parse_line(line, &endline, parse);
if (endline - line < 2) {
@@ -438,6 +441,9 @@ static const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup
/* insert the current item and continue scanning the next one */
rc_insert_richpresence_lookup_item(lookup, first, last, label, (int)(endline - label), parse);
if (parse->offset < 0)
break;
line = endptr + 1;
} while (line < endline);

View File

@@ -3113,6 +3113,7 @@ int rc_hash_generate_from_buffer(char hash[33], uint32_t console_id, const uint8
case RC_CONSOLE_VIRTUAL_BOY:
case RC_CONSOLE_WASM4:
case RC_CONSOLE_WONDERSWAN:
case RC_CONSOLE_ZX_SPECTRUM:
return rc_hash_buffer(hash, buffer, buffer_size);
case RC_CONSOLE_ARDUBOY:
@@ -3411,6 +3412,7 @@ int rc_hash_generate_from_file(char hash[33], uint32_t console_id, const char* p
case RC_CONSOLE_VIRTUAL_BOY:
case RC_CONSOLE_WASM4:
case RC_CONSOLE_WONDERSWAN:
case RC_CONSOLE_ZX_SPECTRUM:
/* generic whole-file hash - don't buffer */
return rc_hash_whole_file(hash, path);
@@ -3466,6 +3468,9 @@ int rc_hash_generate_from_file(char hash[33], uint32_t console_id, const char* p
case RC_CONSOLE_NINTENDO_64:
return rc_hash_n64(hash, path);
case RC_CONSOLE_NINTENDO_3DS:
return rc_hash_nintendo_3ds(hash, path);
case RC_CONSOLE_NINTENDO_DS:
case RC_CONSOLE_NINTENDO_DSI:
return rc_hash_nintendo_ds(hash, path);
@@ -3573,6 +3578,7 @@ static void rc_hash_initialize_dsk_iterator(struct rc_hash_iterator* iterator, c
/* check MSX first, as Apple II isn't supported by RetroArch, and RAppleWin won't use the iterator */
rc_hash_iterator_append_console(iterator, RC_CONSOLE_MSX);
rc_hash_iterator_append_console(iterator, RC_CONSOLE_AMSTRAD_PC);
rc_hash_iterator_append_console(iterator, RC_CONSOLE_ZX_SPECTRUM);
rc_hash_iterator_append_console(iterator, RC_CONSOLE_APPLE_II);
}
@@ -3725,6 +3731,10 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
{
iterator->consoles[0] = RC_CONSOLE_NINTENDO_3DS;
}
else if (rc_path_compare_extension(ext, "csw"))
{
iterator->consoles[0] = RC_CONSOLE_ZX_SPECTRUM;
}
break;
case 'd':
@@ -3808,6 +3818,7 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
iterator->consoles[1] = RC_CONSOLE_PSP;
iterator->consoles[2] = RC_CONSOLE_3DO;
iterator->consoles[3] = RC_CONSOLE_SEGA_CD; /* ASSERT: handles both Sega CD and Saturn */
iterator->consoles[4] = RC_CONSOLE_GAMECUBE;
need_path = 1;
}
break;
@@ -3909,6 +3920,10 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
{
iterator->consoles[0] = RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER;
}
else if (rc_path_compare_extension(ext, "pzx"))
{
iterator->consoles[0] = RC_CONSOLE_ZX_SPECTRUM;
}
break;
case 'r':
@@ -3947,11 +3962,16 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
{
iterator->consoles[0] = RC_CONSOLE_THOMSONTO8; /* disk */
}
else if (rc_path_compare_extension(ext, "scl"))
{
iterator->consoles[0] = RC_CONSOLE_ZX_SPECTRUM;
}
break;
case 't':
if (rc_path_compare_extension(ext, "tap"))
{
/* also Commodore 64 and ZX Spectrum, but all are full file hashes */
iterator->consoles[0] = RC_CONSOLE_ORIC;
}
else if (rc_path_compare_extension(ext, "tic"))
@@ -3962,6 +3982,11 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
{
iterator->consoles[0] = RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER;
}
else if (rc_path_compare_extension(ext, "trd") ||
rc_path_compare_extension(ext, "tzx"))
{
iterator->consoles[0] = RC_CONSOLE_ZX_SPECTRUM;
}
break;
case 'u':

View File

@@ -132,7 +132,7 @@ typedef enum StdVideoAV1FrameRestorationType {
typedef enum StdVideoAV1ColorPrimaries {
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_709 = 1,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED = 2,
STD_VIDEO_AV1_COLOR_PRIMARIES_UNSPECIFIED = 2,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_M = 4,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_470_B_G = 5,
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_601 = 6,
@@ -144,6 +144,8 @@ typedef enum StdVideoAV1ColorPrimaries {
STD_VIDEO_AV1_COLOR_PRIMARIES_SMPTE_432 = 12,
STD_VIDEO_AV1_COLOR_PRIMARIES_EBU_3213 = 22,
STD_VIDEO_AV1_COLOR_PRIMARIES_INVALID = 0x7FFFFFFF,
// STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED is a deprecated alias
STD_VIDEO_AV1_COLOR_PRIMARIES_BT_UNSPECIFIED = STD_VIDEO_AV1_COLOR_PRIMARIES_UNSPECIFIED,
STD_VIDEO_AV1_COLOR_PRIMARIES_MAX_ENUM = 0x7FFFFFFF
} StdVideoAV1ColorPrimaries;

View File

@@ -0,0 +1,143 @@
#ifndef VULKAN_VIDEO_CODEC_AV1STD_ENCODE_H_
#define VULKAN_VIDEO_CODEC_AV1STD_ENCODE_H_ 1
/*
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
// vulkan_video_codec_av1std_encode is a preprocessor guard. Do not pass it to API calls.
#define vulkan_video_codec_av1std_encode 1
#include "vulkan_video_codec_av1std.h"
#define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0)
#define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_API_VERSION_1_0_0
#define VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_av1_encode"
typedef struct StdVideoEncodeAV1DecoderModelInfo {
uint8_t buffer_delay_length_minus_1;
uint8_t buffer_removal_time_length_minus_1;
uint8_t frame_presentation_time_length_minus_1;
uint8_t reserved1;
uint32_t num_units_in_decoding_tick;
} StdVideoEncodeAV1DecoderModelInfo;
typedef struct StdVideoEncodeAV1ExtensionHeader {
uint8_t temporal_id;
uint8_t spatial_id;
} StdVideoEncodeAV1ExtensionHeader;
typedef struct StdVideoEncodeAV1OperatingPointInfoFlags {
uint32_t decoder_model_present_for_this_op : 1;
uint32_t low_delay_mode_flag : 1;
uint32_t initial_display_delay_present_for_this_op : 1;
uint32_t reserved : 29;
} StdVideoEncodeAV1OperatingPointInfoFlags;
typedef struct StdVideoEncodeAV1OperatingPointInfo {
StdVideoEncodeAV1OperatingPointInfoFlags flags;
uint16_t operating_point_idc;
uint8_t seq_level_idx;
uint8_t seq_tier;
uint32_t decoder_buffer_delay;
uint32_t encoder_buffer_delay;
uint8_t initial_display_delay_minus_1;
} StdVideoEncodeAV1OperatingPointInfo;
typedef struct StdVideoEncodeAV1PictureInfoFlags {
uint32_t error_resilient_mode : 1;
uint32_t disable_cdf_update : 1;
uint32_t use_superres : 1;
uint32_t render_and_frame_size_different : 1;
uint32_t allow_screen_content_tools : 1;
uint32_t is_filter_switchable : 1;
uint32_t force_integer_mv : 1;
uint32_t frame_size_override_flag : 1;
uint32_t buffer_removal_time_present_flag : 1;
uint32_t allow_intrabc : 1;
uint32_t frame_refs_short_signaling : 1;
uint32_t allow_high_precision_mv : 1;
uint32_t is_motion_mode_switchable : 1;
uint32_t use_ref_frame_mvs : 1;
uint32_t disable_frame_end_update_cdf : 1;
uint32_t allow_warped_motion : 1;
uint32_t reduced_tx_set : 1;
uint32_t skip_mode_present : 1;
uint32_t delta_q_present : 1;
uint32_t delta_lf_present : 1;
uint32_t delta_lf_multi : 1;
uint32_t segmentation_enabled : 1;
uint32_t segmentation_update_map : 1;
uint32_t segmentation_temporal_update : 1;
uint32_t segmentation_update_data : 1;
uint32_t UsesLr : 1;
uint32_t usesChromaLr : 1;
uint32_t show_frame : 1;
uint32_t showable_frame : 1;
uint32_t reserved : 3;
} StdVideoEncodeAV1PictureInfoFlags;
typedef struct StdVideoEncodeAV1PictureInfo {
StdVideoEncodeAV1PictureInfoFlags flags;
StdVideoAV1FrameType frame_type;
uint32_t frame_presentation_time;
uint32_t current_frame_id;
uint8_t order_hint;
uint8_t primary_ref_frame;
uint8_t refresh_frame_flags;
uint8_t coded_denom;
uint16_t render_width_minus_1;
uint16_t render_height_minus_1;
StdVideoAV1InterpolationFilter interpolation_filter;
StdVideoAV1TxMode TxMode;
uint8_t delta_q_res;
uint8_t delta_lf_res;
uint8_t ref_order_hint[STD_VIDEO_AV1_NUM_REF_FRAMES];
int8_t ref_frame_idx[STD_VIDEO_AV1_REFS_PER_FRAME];
uint8_t reserved1[3];
uint32_t delta_frame_id_minus_1[STD_VIDEO_AV1_REFS_PER_FRAME];
const StdVideoAV1TileInfo* pTileInfo;
const StdVideoAV1Quantization* pQuantization;
const StdVideoAV1Segmentation* pSegmentation;
const StdVideoAV1LoopFilter* pLoopFilter;
const StdVideoAV1CDEF* pCDEF;
const StdVideoAV1LoopRestoration* pLoopRestoration;
const StdVideoAV1GlobalMotion* pGlobalMotion;
const StdVideoEncodeAV1ExtensionHeader* pExtensionHeader;
const uint32_t* pBufferRemovalTimes;
} StdVideoEncodeAV1PictureInfo;
typedef struct StdVideoEncodeAV1ReferenceInfoFlags {
uint32_t disable_frame_end_update_cdf : 1;
uint32_t segmentation_enabled : 1;
uint32_t reserved : 30;
} StdVideoEncodeAV1ReferenceInfoFlags;
typedef struct StdVideoEncodeAV1ReferenceInfo {
StdVideoEncodeAV1ReferenceInfoFlags flags;
uint32_t RefFrameId;
StdVideoAV1FrameType frame_type;
uint8_t OrderHint;
uint8_t reserved1[3];
const StdVideoEncodeAV1ExtensionHeader* pExtensionHeader;
} StdVideoEncodeAV1ReferenceInfo;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -53,13 +53,14 @@ typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
// VK_AMDX_shader_enqueue is a preprocessor guard. Do not pass it to API calls.
#define VK_AMDX_shader_enqueue 1
#define VK_AMDX_SHADER_ENQUEUE_SPEC_VERSION 1
#define VK_AMDX_SHADER_ENQUEUE_SPEC_VERSION 2
#define VK_AMDX_SHADER_ENQUEUE_EXTENSION_NAME "VK_AMDX_shader_enqueue"
#define VK_SHADER_INDEX_UNUSED_AMDX (~0U)
typedef struct VkPhysicalDeviceShaderEnqueueFeaturesAMDX {
VkStructureType sType;
void* pNext;
VkBool32 shaderEnqueue;
VkBool32 shaderMeshEnqueue;
} VkPhysicalDeviceShaderEnqueueFeaturesAMDX;
typedef struct VkPhysicalDeviceShaderEnqueuePropertiesAMDX {
@@ -70,12 +71,16 @@ typedef struct VkPhysicalDeviceShaderEnqueuePropertiesAMDX {
uint32_t maxExecutionGraphShaderPayloadSize;
uint32_t maxExecutionGraphShaderPayloadCount;
uint32_t executionGraphDispatchAddressAlignment;
uint32_t maxExecutionGraphWorkgroupCount[3];
uint32_t maxExecutionGraphWorkgroups;
} VkPhysicalDeviceShaderEnqueuePropertiesAMDX;
typedef struct VkExecutionGraphPipelineScratchSizeAMDX {
VkStructureType sType;
void* pNext;
VkDeviceSize size;
VkDeviceSize minSize;
VkDeviceSize maxSize;
VkDeviceSize sizeGranularity;
} VkExecutionGraphPipelineScratchSizeAMDX;
typedef struct VkExecutionGraphPipelineCreateInfoAMDX {
@@ -116,12 +121,12 @@ typedef struct VkPipelineShaderStageNodeCreateInfoAMDX {
} VkPipelineShaderStageNodeCreateInfoAMDX;
typedef VkResult (VKAPI_PTR *PFN_vkCreateExecutionGraphPipelinesAMDX)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineScratchSizeAMDX)(VkDevice device, VkPipeline executionGraph, VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineNodeIndexAMDX)(VkDevice device, VkPipeline executionGraph, const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, uint32_t* pNodeIndex);
typedef void (VKAPI_PTR *PFN_vkCmdInitializeGraphScratchMemoryAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch);
typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo);
typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo);
typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectCountAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceAddress countInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineScratchSizeAMDX)(VkDevice device, VkPipeline executionGraph, VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineNodeIndexAMDX)(VkDevice device, VkPipeline executionGraph, const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, uint32_t* pNodeIndex);
typedef void (VKAPI_PTR *PFN_vkCmdInitializeGraphScratchMemoryAMDX)(VkCommandBuffer commandBuffer, VkPipeline executionGraph, VkDeviceAddress scratch, VkDeviceSize scratchSize);
typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceSize scratchSize, const VkDispatchGraphCountInfoAMDX* pCountInfo);
typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceSize scratchSize, const VkDispatchGraphCountInfoAMDX* pCountInfo);
typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectCountAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceSize scratchSize, VkDeviceAddress countInfo);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateExecutionGraphPipelinesAMDX(
@@ -145,21 +150,26 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetExecutionGraphPipelineNodeIndexAMDX(
VKAPI_ATTR void VKAPI_CALL vkCmdInitializeGraphScratchMemoryAMDX(
VkCommandBuffer commandBuffer,
VkDeviceAddress scratch);
VkPipeline executionGraph,
VkDeviceAddress scratch,
VkDeviceSize scratchSize);
VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphAMDX(
VkCommandBuffer commandBuffer,
VkDeviceAddress scratch,
VkDeviceSize scratchSize,
const VkDispatchGraphCountInfoAMDX* pCountInfo);
VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectAMDX(
VkCommandBuffer commandBuffer,
VkDeviceAddress scratch,
VkDeviceSize scratchSize,
const VkDispatchGraphCountInfoAMDX* pCountInfo);
VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectCountAMDX(
VkCommandBuffer commandBuffer,
VkDeviceAddress scratch,
VkDeviceSize scratchSize,
VkDeviceAddress countInfo);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2398,7 +2398,7 @@ RETURN_IF_FAILED(wil::stream_seek_nothrow(source, LLONG_MAX, STREAM_SEEK_CUR));
@param stream The stream to seek
@param offset The position, in bytes from the current position, to seek
@param from The starting point from which to seek, from the STREAM_SEEK_* set of values
@param value Optionally recieves the new absolute position from the stream
@param value Optionally receives the new absolute position from the stream
*/
inline HRESULT stream_seek_nothrow(_In_ IStream* stream, long long offset, unsigned long from, _Out_opt_ unsigned long long* value = nullptr)
{
@@ -2418,7 +2418,7 @@ RETURN_HR(wil::stream_set_position_nothrow(source, 16));
~~~~
@param stream The stream whose size is to be returned in `value`
@param offset The position, in bytes from the start of the stream, to seek to
@param value Optionally recieves the new absolute position from the stream
@param value Optionally receives the new absolute position from the stream
*/
inline HRESULT stream_set_position_nothrow(_In_ IStream* stream, unsigned long long offset, _Out_opt_ unsigned long long* value = nullptr)
{
@@ -2888,7 +2888,7 @@ if (wcscmp(content.get(), L"waffles") == 0)
@endcode
@param source The stream from which to read a string
@param options Controls the behavior when reading a zero-length string
@return An non-null string (but possibly zero lengh) string read from `source`
@return An non-null string (but possibly zero length) string read from `source`
*/
inline wil::unique_cotaskmem_string stream_read_string(_In_ ISequentialStream* source, empty_string_options options = empty_string_options::returns_empty)
{

View File

@@ -526,7 +526,7 @@ to be able to layer additional functionality into other libraries by their mere
of initialization should be used whenever they are available.
~~~~
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WI_HEADER_INITITALIZATION_FUNCTION(InitializeDesktopFamilyApis, []
WI_HEADER_INITIALIZATION_FUNCTION(InitializeDesktopFamilyApis, []
{
g_pfnGetModuleName = GetCurrentModuleName;
g_pfnFailFastInLoaderCallout = FailFastInLoaderCallout;
@@ -537,16 +537,16 @@ WI_HEADER_INITITALIZATION_FUNCTION(InitializeDesktopFamilyApis, []
The above example is used within WIL to decide whether or not the library containing WIL is allowed to use
desktop APIs. Building this functionality as `#IFDEF`s within functions would create ODR violations, whereas
doing it with global function pointers and header initialization allows a runtime determination. */
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn)
#define WI_HEADER_INITIALIZATION_FUNCTION(name, fn)
#elif defined(_M_IX86)
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) \
#define WI_HEADER_INITIALIZATION_FUNCTION(name, fn) \
extern "C" \
{ \
__declspec(selectany) unsigned char g_header_init_##name = static_cast<unsigned char>(fn()); \
} \
__pragma(comment(linker, "/INCLUDE:_g_header_init_" #name))
#elif defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64)
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) \
#define WI_HEADER_INITIALIZATION_FUNCTION(name, fn) \
extern "C" \
{ \
__declspec(selectany) unsigned char g_header_init_##name = static_cast<unsigned char>(fn()); \
@@ -556,6 +556,9 @@ doing it with global function pointers and header initialization allows a runtim
#error linker pragma must include g_header_init variation
#endif
// Keep the misspelled name for backward compatibility.
#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) WI_HEADER_INITIALIZATION_FUNCTION(name, fn)
/** All Windows Implementation Library classes and functions are located within the "wil" namespace.
The 'wil' namespace is an intentionally short name as the intent is for code to be able to reference
the namespace directly (example: `wil::srwlock lock;`) without a using statement. Resist adding a using
@@ -687,32 +690,32 @@ boolean, BOOLEAN, and classes with an explicit bool cast.
@param val The logical bool expression
@return A C++ bool representing the evaluation of `val`. */
template <typename T, __R_ENABLE_IF_IS_CLASS(T)>
_Post_satisfies_(return == static_cast<bool>(val)) __forceinline constexpr bool verify_bool(const T& val)
_Post_satisfies_(return == static_cast<bool>(val)) __forceinline constexpr bool verify_bool(const T& val) WI_NOEXCEPT
{
return static_cast<bool>(val);
}
template <typename T, __R_ENABLE_IF_IS_NOT_CLASS(T)>
__forceinline constexpr bool verify_bool(T /*val*/)
__forceinline constexpr bool verify_bool(T /*val*/) WI_NOEXCEPT
{
static_assert(!wistd::is_same<T, T>::value, "Wrong Type: bool/BOOL/BOOLEAN/boolean expected");
return false;
}
template <>
_Post_satisfies_(return == val) __forceinline constexpr bool verify_bool<bool>(bool val)
_Post_satisfies_(return == val) __forceinline constexpr bool verify_bool<bool>(bool val) WI_NOEXCEPT
{
return val;
}
template <>
_Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<int>(int val)
_Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<int>(int val) WI_NOEXCEPT
{
return (val != 0);
}
template <>
_Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<unsigned char>(unsigned char val)
_Post_satisfies_(return == (val != 0)) __forceinline constexpr bool verify_bool<unsigned char>(unsigned char val) WI_NOEXCEPT
{
return (val != 0);
}
@@ -723,7 +726,7 @@ accept any `int` value as long as that is the underlying typedef behind `BOOL`.
@param val The Win32 BOOL returning expression
@return A Win32 BOOL representing the evaluation of `val`. */
template <typename T>
_Post_satisfies_(return == val) __forceinline constexpr int verify_BOOL(T val)
_Post_satisfies_(return == val) __forceinline constexpr int verify_BOOL(T val) WI_NOEXCEPT
{
// Note: Written in terms of 'int' as BOOL is actually: typedef int BOOL;
static_assert((wistd::is_same<T, int>::value), "Wrong Type: BOOL expected");
@@ -752,7 +755,7 @@ RETURN_HR_IF(static_cast<HRESULT>(UIA_E_NOTSUPPORTED), (patternId != UIA_DragPat
@param hr The HRESULT returning expression
@return An HRESULT representing the evaluation of `val`. */
template <typename T>
_Post_satisfies_(return == hr) inline constexpr long verify_hresult(T hr)
_Post_satisfies_(return == hr) inline constexpr long verify_hresult(T hr) WI_NOEXCEPT
{
// Note: Written in terms of 'long' as HRESULT is actually: typedef _Return_type_success_(return >= 0) long HRESULT
static_assert(wistd::is_same<T, long>::value, "Wrong Type: HRESULT expected");
@@ -781,7 +784,7 @@ NT_RETURN_IF_FALSE(static_cast<NTSTATUS>(STATUS_NOT_SUPPORTED), (dispatch->Versi
@param status The NTSTATUS returning expression
@return An NTSTATUS representing the evaluation of `val`. */
template <typename T>
_Post_satisfies_(return == status) inline long verify_ntstatus(T status)
_Post_satisfies_(return == status) inline long verify_ntstatus(T status) WI_NOEXCEPT
{
// Note: Written in terms of 'long' as NTSTATUS is actually: typedef _Return_type_success_(return >= 0) long NTSTATUS
static_assert(wistd::is_same<T, long>::value, "Wrong Type: NTSTATUS expected");
@@ -795,7 +798,7 @@ commonly used when manipulating Win32 error codes.
@param error The Win32 error code returning expression
@return An Win32 error code representing the evaluation of `error`. */
template <typename T>
_Post_satisfies_(return == error) inline T verify_win32(T error)
_Post_satisfies_(return == error) inline T verify_win32(T error) WI_NOEXCEPT
{
// Note: Win32 error code are defined as 'long' (#define ERROR_SUCCESS 0L), but are more frequently used as DWORD (unsigned
// long). This accept both types.
@@ -810,7 +813,7 @@ _Post_satisfies_(return == error) inline T verify_win32(T error)
// Implementation details for macros and helper functions... do not use directly.
namespace details
{
// Use size-specific casts to avoid sign extending numbers -- avoid warning C4310: cast truncates constant value
// Use size-specific casts to avoid sign extending numbers -- avoid warning C4310: cast truncates constant value
#define __WI_MAKE_UNSIGNED(val) \
(__pragma(warning(push)) __pragma(warning(disable : 4310 4309))( \
sizeof(val) == 1 ? static_cast<unsigned char>(val) \

View File

@@ -191,7 +191,7 @@ struct com_task;
/// @cond
namespace wil::details::coro
{
// task and com_task are convertable to each other. However, not
// task and com_task are convertible to each other. However, not
// all consumers of this header have COM enabled. Support for saving
// COM thread-local error information and restoring it on the resuming
// thread is enabled using these function pointers. If COM is not
@@ -764,8 +764,8 @@ inline void __stdcall DestroyRestrictedErrorInformation(_In_ void* restricted_er
struct apartment_info
{
APTTYPE aptType;
APTTYPEQUALIFIER aptTypeQualifier;
APTTYPE aptType{};
APTTYPEQUALIFIER aptTypeQualifier{};
void load()
{
@@ -814,7 +814,7 @@ struct apartment_resumer
__WI_COROUTINE_NAMESPACE::coroutine_handle<> waiter;
wil::com_ptr<IContextCallback> context{nullptr};
apartment_info info;
apartment_info info{};
HRESULT resume_result = S_OK;
void capture_context(__WI_COROUTINE_NAMESPACE::coroutine_handle<> handle)
@@ -925,7 +925,7 @@ auto task_base<T>::resume_same_apartment() && noexcept
// This section is lit up when COM headers are available. Initialize the global function
// pointers such that error information can be saved and restored across thread boundaries.
WI_HEADER_INITITALIZATION_FUNCTION(CoroutineRestrictedErrorInitialize, [] {
WI_HEADER_INITIALIZATION_FUNCTION(CoroutineRestrictedErrorInitialize, [] {
::wil::details::coro::g_pfnCaptureRestrictedErrorInformation = ::wil::details::coro::CaptureRestrictedErrorInformation;
::wil::details::coro::g_pfnRestoreRestrictedErrorInformation = ::wil::details::coro::RestoreRestrictedErrorInformation;
::wil::details::coro::g_pfnDestroyRestrictedErrorInformation = ::wil::details::coro::DestroyRestrictedErrorInformation;

View File

@@ -255,7 +255,7 @@ namespace details
{
#ifndef CPPWINRT_SUPPRESS_STATIC_INITIALIZERS
WI_ODR_PRAGMA("CPPWINRT_SUPPRESS_STATIC_INITIALIZERS", "0")
WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_CppWinRT, [] {
WI_HEADER_INITIALIZATION_FUNCTION(WilInitialize_CppWinRT, [] {
::wil::WilInitialize_CppWinRT();
return 1;
});

View File

@@ -476,7 +476,7 @@ next_entry_offset_iterator<T> create_next_entry_offset_iterator(T* p)
enum class FolderChangeEvent : DWORD
{
ChangesLost = 0, // requies special handling, reset state as events were lost
ChangesLost = 0, // requires special handling, reset state as events were lost
Added = FILE_ACTION_ADDED,
Removed = FILE_ACTION_REMOVED,
Modified = FILE_ACTION_MODIFIED,
@@ -1122,9 +1122,9 @@ struct file_and_error_result
DWORD last_error{};
};
/** Non-throwing open existing using OPEN_EXISTING.
/** Non-throwing open existing using OPEN_EXISTING, returns handle and error code.
~~~
auto handle = wil::try_open_file(filePath.c_str());
auto [handle, error] = wil::try_open_file(filePath.c_str());
~~~
*/
inline file_and_error_result try_open_file(
@@ -1150,7 +1150,7 @@ inline wil::unique_hfile open_file(
DWORD dwDesiredAccess = GENERIC_READ,
DWORD dwShareMode = FILE_SHARE_READ,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
bool inheritHandle = false) noexcept
bool inheritHandle = false)
{
auto result = try_open_file(path, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes, inheritHandle);
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
@@ -1173,7 +1173,7 @@ namespace details
/** create using CREATE_NEW, returns handle and error code.
~~~
auto [handle, error = wil::try_create_new_file(filePath.c_str());
auto [handle, error] = wil::try_create_new_file(filePath.c_str());
~~~
*/
inline file_and_error_result try_create_new_file(
@@ -1189,7 +1189,7 @@ inline file_and_error_result try_create_new_file(
/** create using OPEN_ALWAYS, returns handle and error code.
~~~
auto [handle, error = wil::try_open_or_create_file(filePath.c_str());
auto [handle, error] = wil::try_open_or_create_file(filePath.c_str());
~~~
*/
inline file_and_error_result try_open_or_create_file(
@@ -1205,7 +1205,7 @@ inline file_and_error_result try_open_or_create_file(
/** create using CREATE_ALWAYS, returns handle and error code.
~~~
auto [handle, error = wil::try_open_or_truncate_existing_file(filePath.c_str());
auto [handle, error] = wil::try_open_or_truncate_existing_file(filePath.c_str());
~~~
*/
inline file_and_error_result try_open_or_truncate_existing_file(
@@ -1221,7 +1221,7 @@ inline file_and_error_result try_open_or_truncate_existing_file(
/** create using TRUNCATE_EXISTING, returns handle and error code.
~~~
auto [handle, error = wil::try_truncate_existing_file(filePath.c_str());
auto [handle, error] = wil::try_truncate_existing_file(filePath.c_str());
~~~
*/
inline file_and_error_result try_truncate_existing_file(
@@ -1247,7 +1247,7 @@ inline wil::unique_hfile create_new_file(
DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept
HANDLE hTemplateFile = nullptr)
{
auto result = try_create_new_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
@@ -1265,7 +1265,7 @@ inline wil::unique_hfile open_or_create_file(
DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept
HANDLE hTemplateFile = nullptr)
{
auto result = try_open_or_create_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
THROW_WIN32_IF(result.last_error, !result.file.is_valid());
@@ -1283,7 +1283,7 @@ inline wil::unique_hfile open_or_truncate_existing_file(
DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept
HANDLE hTemplateFile = nullptr)
{
auto result = try_open_or_truncate_existing_file(
path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);
@@ -1302,7 +1302,7 @@ inline wil::unique_hfile truncate_existing_file(
DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
HANDLE hTemplateFile = nullptr) noexcept
HANDLE hTemplateFile = nullptr)
{
auto result =
try_truncate_existing_file(path, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, hTemplateFile);

View File

@@ -27,10 +27,10 @@
// stdint.h and intsafe.h have conflicting definitions, so it's not safe to include either to pick up our dependencies,
// so the definitions we need are copied below
#ifdef _WIN64
#define __WI_SIZE_MAX 0xffffffffffffffffui64 // UINT64_MAX
#else /* _WIN64 */
#define __WI_SIZE_MAX 0xffffffffui32 // UINT32_MAX
#endif /* _WIN64 */
#define __WI_SIZE_MAX 0xffffffffffffffffULL // UINT64_MAX
#else /* _WIN64 */
#define __WI_SIZE_MAX 0xffffffffUL // UINT32_MAX
#endif /* _WIN64 */
/// @endcond
// Forward declaration
@@ -721,7 +721,7 @@ class com_ptr_t; // forward
namespace details
{
// The first two attach_to_smart_pointer() overloads are ambiguous when passed a com_ptr_t.
// To solve that use this functions return type to elminate the reset form for com_ptr_t.
// To solve that use this functions return type to eliminate the reset form for com_ptr_t.
template <typename T, typename err>
wistd::false_type use_reset(wil::com_ptr_t<T, err>*)
{
@@ -1025,7 +1025,7 @@ struct empty_deleter
};
/** unique_any_array_ptr is a RAII type for managing conformant arrays that need to be freed and have elements that may need to be
freed. The intented use for this RAII type would be to capture out params from API like IPropertyValue::GetStringArray. This class
freed. The intended use for this RAII type would be to capture out params from API like IPropertyValue::GetStringArray. This class
also maintains the size of the array, so it can iterate over the members and deallocate them before it deallocates the base array
pointer.
@@ -2892,6 +2892,7 @@ typedef unique_any_t<event_t<details::unique_storage<details::handle_resource_po
typedef unique_any_t<event_t<details::unique_storage<details::handle_resource_policy>, err_exception_policy>> unique_event;
#endif
#ifndef WIL_NO_SLIM_EVENT
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && \
((_WIN32_WINNT >= _WIN32_WINNT_WIN8) || (__WIL_RESOURCE_ENABLE_QUIRKS && (_WIN32_WINNT >= _WIN32_WINNT_WIN7)))
enum class SlimEventType
@@ -2973,13 +2974,13 @@ public:
return !!ReadAcquire(&m_isSignaled);
}
bool wait(DWORD timeoutMiliseconds) WI_NOEXCEPT
bool wait(DWORD timeoutMilliseconds) WI_NOEXCEPT
{
if (timeoutMiliseconds == 0)
if (timeoutMilliseconds == 0)
{
return TryAcquireEvent();
}
else if (timeoutMiliseconds == INFINITE)
else if (timeoutMilliseconds == INFINITE)
{
return wait();
}
@@ -2991,12 +2992,12 @@ public:
while (!TryAcquireEvent())
{
if (elapsedTimeMilliseconds >= timeoutMiliseconds)
if (elapsedTimeMilliseconds >= timeoutMilliseconds)
{
return false;
}
DWORD newTimeout = static_cast<DWORD>(timeoutMiliseconds - elapsedTimeMilliseconds);
DWORD newTimeout = static_cast<DWORD>(timeoutMilliseconds - elapsedTimeMilliseconds);
if (!WaitForSignal(newTimeout))
{
@@ -3039,10 +3040,10 @@ private:
}
}
bool WaitForSignal(DWORD timeoutMiliseconds) WI_NOEXCEPT
bool WaitForSignal(DWORD timeoutMilliseconds) WI_NOEXCEPT
{
LONG falseValue = FALSE;
BOOL waitResult = WaitOnAddress(&m_isSignaled, &falseValue, sizeof(m_isSignaled), timeoutMiliseconds);
BOOL waitResult = WaitOnAddress(&m_isSignaled, &falseValue, sizeof(m_isSignaled), timeoutMilliseconds);
__FAIL_FAST_ASSERT__(waitResult || ::GetLastError() == ERROR_TIMEOUT);
return !!waitResult;
}
@@ -3060,6 +3061,7 @@ using slim_event_manual_reset = slim_event_t<SlimEventType::ManualReset>;
using slim_event = slim_event_auto_reset;
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
#endif // WIL_NO_SLIM_EVENT
typedef unique_any<HANDLE, decltype(&details::ReleaseMutex), details::ReleaseMutex, details::pointer_access_none> mutex_release_scope_exit;
@@ -4731,7 +4733,7 @@ inline unique_hstring make_unique_string_nothrow<unique_hstring>(
_When_((source != nullptr) && length == static_cast<size_t>(-1), _In_z_) PCWSTR source,
size_t length) WI_NOEXCEPT
{
WI_ASSERT(source != nullptr); // the HSTRING version of this function does not suport this case
WI_ASSERT(source != nullptr); // the HSTRING version of this function does not support this case
if (length == static_cast<size_t>(-1))
{
length = wcslen(source);
@@ -5218,7 +5220,7 @@ struct cert_context_t
}
/** A wrapper around CertEnumCertificatesInStore.
CertEnumCertificatesInStore takes ownership of its second paramter in an unclear fashion,
CertEnumCertificatesInStore takes ownership of its second parameter in an unclear fashion,
making it error-prone to use in combination with unique_cert_context. This wrapper helps
manage the resource correctly while ensuring the GetLastError state set by CertEnumCertificatesInStore.
is not lost. See MSDN for more information on `CertEnumCertificatesInStore`.
@@ -6264,7 +6266,7 @@ using wdf_wait_lock_release_scope_exit =
using unique_wdf_device_init = unique_any<WDFDEVICE_INIT*, decltype(&::WdfDeviceInitFree), ::WdfDeviceInitFree>;
#endif
inline WI_NODISCARD _IRQL_requires_max_(PASSIVE_LEVEL)
WI_NODISCARD inline _IRQL_requires_max_(PASSIVE_LEVEL)
_Acquires_lock_(lock)
wdf_wait_lock_release_scope_exit acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT
{
@@ -6272,7 +6274,7 @@ wdf_wait_lock_release_scope_exit acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEX
return wdf_wait_lock_release_scope_exit(lock);
}
inline WI_NODISCARD _IRQL_requires_max_(APC_LEVEL)
WI_NODISCARD inline _IRQL_requires_max_(APC_LEVEL)
_When_(return, _Acquires_lock_(lock))
wdf_wait_lock_release_scope_exit try_acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT
{
@@ -6291,7 +6293,7 @@ wdf_wait_lock_release_scope_exit try_acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_
using wdf_spin_lock_release_scope_exit =
unique_any<WDFSPINLOCK, decltype(&::WdfSpinLockRelease), ::WdfSpinLockRelease, details::pointer_access_none>;
inline WI_NODISCARD _IRQL_requires_max_(DISPATCH_LEVEL)
WI_NODISCARD inline _IRQL_requires_max_(DISPATCH_LEVEL)
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(lock)
wdf_spin_lock_release_scope_exit acquire_wdf_spin_lock(WDFSPINLOCK lock) WI_NOEXCEPT
@@ -6507,7 +6509,7 @@ private:
// function only if the call-site source location is obtained from elsewhere (i.e., plumbed
// through other abstractions).
template <typename wdf_object_t>
inline WI_NODISCARD unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment(
WI_NODISCARD inline unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment(
wdf_object_t wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT
{
// Parameter is incorrectly marked as non-const, so the const-cast is required.
@@ -6516,7 +6518,7 @@ inline WI_NODISCARD unique_wdf_object_reference<wdf_object_t> wdf_object_referen
}
template <typename wdf_object_t>
inline WI_NODISCARD unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment(
WI_NODISCARD inline unique_wdf_object_reference<wdf_object_t> wdf_object_reference_increment(
const wil::unique_wdf_any<wdf_object_t>& wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT
{
return wdf_object_reference_increment(wdfObject.get(), tag, lineNumber, fileName);
@@ -7451,7 +7453,7 @@ namespace details
{
// Only those lock types specialized by lock_proof_traits will allow either a write_lock_required or
// read_lock_required to be constructed. The allows_exclusive value indicates if the type represents an exclusive,
// write-safe lock aquisition, or a shared, read-only lock acquisition.
// write-safe lock acquisition, or a shared, read-only lock acquisition.
template <typename T>
struct lock_proof_traits
{
@@ -7480,7 +7482,7 @@ another function that requires them.
These types are implicitly convertible from various lock holding types, enabling callers to provide them as
proof of the lock that they hold.
The following example is intentially contrived to demonstrate multiple use cases:
The following example is intentionally contrived to demonstrate multiple use cases:
- Methods that require only shared/read access
- Methods that require only exclusive write access
- Methods that pass their proof-of-lock to a helper

View File

@@ -435,7 +435,7 @@ namespace details_abi
private:
struct Node
{
DWORD threadId = ULONG_MAX;
DWORD threadId = 0xffffffff; // MAXDWORD
Node* pNext = nullptr;
T value{};
};
@@ -1169,7 +1169,7 @@ namespace details
__declspec(selectany)::wil::details_abi::ProcessLocalStorage<::wil::details_abi::ProcessLocalData> g_processLocalData("WilError_03");
__declspec(selectany)::wil::details_abi::ThreadLocalStorage<ThreadFailureCallbackHolder*> g_threadFailureCallbacks;
WI_HEADER_INITITALIZATION_FUNCTION(InitializeResultHeader, [] {
WI_HEADER_INITIALIZATION_FUNCTION(InitializeResultHeader, [] {
g_pfnGetContextAndNotifyFailure = GetContextAndNotifyFailure;
::wil::details_abi::g_pProcessLocalData = &g_processLocalData;
g_pThreadFailureCallbacks = &g_threadFailureCallbacks;

View File

@@ -93,7 +93,7 @@ typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
#endif
#ifndef __NTSTATUS_FROM_WIN32
#define __NTSTATUS_FROM_WIN32(x) \
((NTSTATUS)(x) <= 0 ? ((NTSTATUS)(x)) : ((NTSTATUS)(((x)&0x0000FFFF) | (FACILITY_WIN32 << 16) | ERROR_SEVERITY_ERROR)))
((NTSTATUS)(x) <= 0 ? ((NTSTATUS)(x)) : ((NTSTATUS)(((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | ERROR_SEVERITY_ERROR)))
#endif
#ifndef WIL_AllocateMemory
@@ -757,6 +757,14 @@ WI_ODR_PRAGMA("WIL_FreeMemory", "0")
return __hr; \
} \
__WI_SUPPRESS_4127_E while ((void)0, 0)
#define __RETURN_HR_FAIL_SUPPRESS_TELEMETRY(hr, str) \
__WI_SUPPRESS_4127_S do \
{ \
const HRESULT __hr = (hr); \
__R_FN(Return_HrSuppressTelemetry)(__R_INFO(str) __hr); \
return __hr; \
} \
__WI_SUPPRESS_4127_E while ((void)0, 0)
#define __RETURN_HR_FAIL_NOFILE(hr, str) \
__WI_SUPPRESS_4127_S do \
{ \
@@ -1097,6 +1105,21 @@ WI_ODR_PRAGMA("WIL_FreeMemory", "0")
} \
} while ((void)0, 0)
// Always logs failed HR, if expected, telemetry will be called with 'alreadyReported'
#define RETURN_IF_FAILED_SUPPRESS_TELEMETRY_IF_EXPECTED(hr, hrExpected, ...) \
do \
{ \
const auto __hrRet = wil::verify_hresult(hr); \
if (FAILED(__hrRet)) \
{ \
if ((__hrRet == wil::verify_hresult(hrExpected)) WI_FOREACH(__WI_OR_IS_EXPECTED_HRESULT, ##__VA_ARGS__)) \
{ \
__RETURN_HR_FAIL_SUPPRESS_TELEMETRY(__hrRet, #hr); \
} \
__RETURN_HR_FAIL(__hrRet, #hr); \
} \
} while ((void)0, 0)
//*****************************************************************************
// Macros for logging failures (ignore or pass-through)
//*****************************************************************************
@@ -1267,7 +1290,7 @@ WI_ODR_PRAGMA("WIL_FreeMemory", "0")
if (!wil::verify_bool(condition)) \
{ \
WI_ASSERT_FAIL(#condition); \
__RFF_FN(FailFast_Unexpected)(__RFF_INFO_ONLY(#condition)) \
__RFF_FN(FailFast_Unexpected)(__RFF_INFO_ONLY(#condition)); \
} \
} while (0, 0)
#define WI_FAIL_FAST_ASSERT_MSG(condition, msg) \
@@ -1738,7 +1761,7 @@ inline HRESULT GetFailureLogString(
_Pre_satisfies_(cchDest > 0) _In_ size_t cchDest,
_In_ FailureInfo const& failure) WI_NOEXCEPT
{
// This function was lenient to empty strings at one point and some callers became dependent on this beahvior
// This function was lenient to empty strings at one point and some callers became dependent on this behavior
if ((cchDest == 0) || (pszDest == nullptr))
{
return S_OK;
@@ -2155,6 +2178,7 @@ namespace details
_Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars,
_Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString,
_Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars,
FailureFlags flags,
_Out_ FailureInfo* failure) WI_NOEXCEPT;
__declspec(noinline) inline void ReportFailure(
@@ -2168,12 +2192,13 @@ namespace details
__R_FN_PARAMS_FULL,
const ResultStatus& resultPair,
_In_opt_ PCWSTR message = nullptr,
ReportFailureOptions options = ReportFailureOptions::None);
ReportFailureOptions options = ReportFailureOptions::None,
FailureFlags flags = FailureFlags::None);
template <FailureType>
inline void ReportFailure_ReplaceMsg(__R_FN_PARAMS_FULL, HRESULT hr, _Printf_format_string_ PCSTR formatString, ...);
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, FailureType type, HRESULT hr);
template <FailureType>
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr);
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags flags = FailureFlags::None);
template <FailureType>
__declspec(noinline) inline HRESULT
ReportFailure_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported = SupportedExceptions::Default);
@@ -2745,7 +2770,7 @@ namespace details
{
status =
((NTSTATUS)(hr) <= 0 ? ((NTSTATUS)(hr))
: ((NTSTATUS)(((hr)&0x0000FFFF) | (FACILITY_SSPI << 16) | ERROR_SEVERITY_ERROR)));
: ((NTSTATUS)(((hr) & 0x0000FFFF) | (FACILITY_SSPI << 16) | ERROR_SEVERITY_ERROR)));
}
else
{
@@ -2826,8 +2851,8 @@ namespace details
// NOTE: The following two functions are unfortunate copies of strsafe.h functions that have been copied to reduce the friction associated with using
// Result.h and ResultException.h in a build that does not have WINAPI_PARTITION_DESKTOP defined (where these are conditionally enabled).
static STRSAFEAPI WilStringLengthWorkerA(
_In_reads_or_z_(cchMax) STRSAFE_PCNZCH psz,
inline HRESULT WilStringLengthWorkerA(
_In_reads_or_z_(cchMax) PCNZCH psz,
_In_ _In_range_(<=, STRSAFE_MAX_CCH) size_t cchMax,
_Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t* pcchLength)
{
@@ -2858,8 +2883,8 @@ namespace details
}
_Must_inspect_result_
STRSAFEAPI StringCchLengthA(
_In_reads_or_z_(cchMax) STRSAFE_PCNZCH psz,
inline HRESULT StringCchLengthA(
_In_reads_or_z_(cchMax) PCNZCH psz,
_In_ _In_range_(1, STRSAFE_MAX_CCH) size_t cchMax,
_Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<=, _String_length_(psz)) size_t* pcchLength)
{
@@ -2880,8 +2905,8 @@ namespace details
}
#pragma warning(pop)
_Post_satisfies_(cchDest > 0 && cchDest <= cchMax) static STRSAFEAPI
WilStringValidateDestA(_In_reads_opt_(cchDest) STRSAFE_PCNZCH /*pszDest*/, _In_ size_t cchDest, _In_ const size_t cchMax)
_Post_satisfies_(cchDest > 0 && cchDest <= cchMax) inline HRESULT
WilStringValidateDestA(_In_reads_opt_(cchDest) PCNZCH /*pszDest*/, _In_ size_t cchDest, _In_ const size_t cchMax)
{
HRESULT hr = S_OK;
if ((cchDest == 0) || (cchDest > cchMax))
@@ -2891,7 +2916,7 @@ namespace details
return hr;
}
static STRSAFEAPI WilStringVPrintfWorkerA(
inline HRESULT WilStringVPrintfWorkerA(
_Out_writes_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest,
_In_ _In_range_(1, STRSAFE_MAX_CCH) size_t cchDest,
_Always_(_Out_opt_ _Deref_out_range_(<=, cchDest - 1)) size_t* pcchNewDestLength,
@@ -2948,7 +2973,7 @@ namespace details
return hr;
}
__inline HRESULT StringCchPrintfA(
inline HRESULT StringCchPrintfA(
_Out_writes_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest,
_In_ size_t cchDest,
_In_ _Printf_format_string_ STRSAFE_LPCSTR pszFormat,
@@ -3080,7 +3105,7 @@ namespace details
{
#ifndef RESULT_SUPPRESS_STATIC_INITIALIZERS
#if !defined(BUILD_WINDOWS) || defined(WIL_SUPPRESS_PRIVATE_API_USE)
WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse, [] {
WI_HEADER_INITIALIZATION_FUNCTION(WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse, [] {
::wil::WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse();
return 1;
});
@@ -3091,7 +3116,7 @@ namespace details
#else // !WINAPI_PARTITION_DESKTOP, !WINAPI_PARTITION_SYSTEM, explicitly assume these modules can direct link
namespace details
{
WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_ResultMacros_AppOnly, [] {
WI_HEADER_INITIALIZATION_FUNCTION(WilInitialize_ResultMacros_AppOnly, [] {
g_pfnRaiseFailFastException = ::RaiseFailFastException;
return 1;
});
@@ -3869,7 +3894,7 @@ namespace details
}
#if !defined(RESULT_SUPPRESS_STATIC_INITIALIZERS)
WI_HEADER_INITITALIZATION_FUNCTION(InitializeWinRt, [] {
WI_HEADER_INITIALIZATION_FUNCTION(InitializeWinRt, [] {
g_pfnResultFromCaughtException_WinRt = ResultFromCaughtException_WinRt;
g_pfnResultFromKnownExceptions_WinRt = ResultFromKnownExceptions_WinRt;
g_pfnThrowPlatformException = ThrowPlatformException;
@@ -4124,7 +4149,7 @@ namespace details
}
}
WI_HEADER_INITITALIZATION_FUNCTION(InitializeResultExceptions, [] {
WI_HEADER_INITIALIZATION_FUNCTION(InitializeResultExceptions, [] {
g_pfnRunFunctorWithExceptionFilter = RunFunctorWithExceptionFilter;
g_pfnRethrow = Rethrow;
g_pfnThrowResultException = ThrowResultExceptionInternal;
@@ -4320,6 +4345,7 @@ namespace details
_Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars,
_Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString,
_Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars,
FailureFlags flags,
_Out_ FailureInfo* failure) WI_NOEXCEPT
{
debugString[0] = L'\0';
@@ -4360,7 +4386,7 @@ namespace details
};
failure->type = type;
failure->flags = FailureFlags::None;
failure->flags = flags;
WI_SetFlagIf(failure->flags, FailureFlags::NtStatus, resultPair.kind == ResultStatus::Kind::NtStatus);
failure->failureId = ::InterlockedIncrementNoFence(&s_failureId);
failure->pszMessage = ((message != nullptr) && (message[0] != L'\0')) ? message : nullptr;
@@ -4501,7 +4527,8 @@ namespace details
}
template <FailureType T>
inline __declspec(noinline) void ReportFailure_Return(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options)
inline __declspec(noinline) void ReportFailure_Return(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags flags)
{
bool needPlatformException =
((T == FailureType::Exception) && WI_IsFlagClear(options, ReportFailureOptions::MayRethrow) &&
@@ -4522,6 +4549,7 @@ namespace details
ARRAYSIZE(debugString),
callContextString,
ARRAYSIZE(callContextString),
flags,
&failure);
if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast))
@@ -4531,9 +4559,10 @@ namespace details
}
template <FailureType T, bool SuppressAction>
inline __declspec(noinline) void ReportFailure_Base(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options)
inline __declspec(noinline) void ReportFailure_Base(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags flags)
{
ReportFailure_Return<T>(__R_FN_CALL_FULL, resultPair, message, options);
ReportFailure_Return<T>(__R_FN_CALL_FULL, resultPair, message, options, flags);
}
template <FailureType T>
@@ -4559,6 +4588,7 @@ namespace details
ARRAYSIZE(debugString),
callContextString,
ARRAYSIZE(callContextString),
FailureFlags::None,
&failure);
__WI_SUPPRESS_4127_S
if ((T == FailureType::FailFast) || WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast))
@@ -4587,14 +4617,14 @@ namespace details
template <>
inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base<FailureType::FailFast, false>(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options)
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags)
{
ReportFailure_NoReturn<FailureType::FailFast>(__R_FN_CALL_FULL, resultPair, message, options);
}
template <>
inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base<FailureType::Exception, false>(
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options)
__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options, FailureFlags)
{
ReportFailure_NoReturn<FailureType::Exception>(__R_FN_CALL_FULL, resultPair, message, options);
}
@@ -4764,19 +4794,22 @@ namespace details
}
template <FailureType T>
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr)
__declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags flags)
{
ReportFailure_Base<T>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr));
ReportFailure_Base<T>(
__R_FN_CALL_FULL, ResultStatus::FromResult(hr), nullptr /*message*/, ReportFailureOptions::None /*options*/, flags);
}
template <>
__declspec(noinline) inline RESULT_NORETURN void ReportFailure_Hr<FailureType::FailFast>(__R_FN_PARAMS_FULL, HRESULT hr)
__declspec(noinline) inline RESULT_NORETURN
void ReportFailure_Hr<FailureType::FailFast>(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags)
{
ReportFailure_Base<FailureType::FailFast>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr));
}
template <>
__declspec(noinline) inline RESULT_NORETURN void ReportFailure_Hr<FailureType::Exception>(__R_FN_PARAMS_FULL, HRESULT hr)
__declspec(noinline) inline RESULT_NORETURN
void ReportFailure_Hr<FailureType::Exception>(__R_FN_PARAMS_FULL, HRESULT hr, FailureFlags)
{
ReportFailure_Base<FailureType::Exception>(__R_FN_CALL_FULL, ResultStatus::FromResult(hr));
}
@@ -5182,6 +5215,7 @@ namespace details
ARRAYSIZE(debugString),
callContextString,
ARRAYSIZE(callContextString),
FailureFlags::None,
&failure);
if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast))
@@ -5228,6 +5262,13 @@ namespace details
wil::details::ReportFailure_Hr<FailureType::Return>(__R_DIRECT_FN_CALL hr);
}
__R_DIRECT_METHOD(void, Return_HrSuppressTelemetry)(__R_DIRECT_FN_PARAMS HRESULT hr) WI_NOEXCEPT
{
__R_FN_LOCALS;
const FailureFlags flags = FailureFlags::RequestSuppressTelemetry;
wil::details::ReportFailure_Hr<FailureType::Return>(__R_DIRECT_FN_CALL hr, flags);
}
_Success_(true)
_Translates_Win32_to_HRESULT_(err)
__R_DIRECT_METHOD(HRESULT, Return_Win32)(__R_DIRECT_FN_PARAMS DWORD err) WI_NOEXCEPT

View File

@@ -122,7 +122,7 @@ namespace details
} // namespace wil
// Automatically call RoOriginateError upon error origination by including this file
WI_HEADER_INITITALIZATION_FUNCTION(ResultStowedExceptionInitialize, [] {
WI_HEADER_INITIALIZATION_FUNCTION(ResultStowedExceptionInitialize, [] {
::wil::SetOriginateErrorCallback(::wil::details::RaiseRoOriginateOnWilExceptions);
::wil::SetFailfastWithContextCallback(::wil::details::FailfastWithContextCallback);
return 1;

View File

@@ -106,7 +106,7 @@ namespace details
wistd::is_same<T, int>::value || wistd::is_same<T, unsigned int>::value || wistd::is_same<T, long>::value ||
wistd::is_same<T, unsigned long>::value || wistd::is_same<T, __int64>::value || wistd::is_same<T, unsigned __int64>::value;
// True when either type is potentialy variably sized (e.g. size_t, ptrdiff_t)
// True when either type is potentially variably sized (e.g. size_t, ptrdiff_t)
template <typename OldT, typename NewT>
constexpr bool is_potentially_variably_sized_cast_v =
is_potentially_variably_sized_type_v<OldT> || is_potentially_variably_sized_type_v<NewT>;

View File

@@ -24,19 +24,64 @@ namespace details
{
};
template <typename TCallback>
BOOL __stdcall EnumWindowsCallbackNoThrow(HWND hwnd, LPARAM lParam)
{
auto pCallback = reinterpret_cast<TCallback*>(lParam);
#ifdef __cpp_if_constexpr
using result_t = decltype((*pCallback)(hwnd));
if constexpr (wistd::is_void_v<result_t>)
{
(*pCallback)(hwnd);
return TRUE;
}
else if constexpr (wistd::is_same_v<result_t, HRESULT>)
{
// NB: this works for both HRESULT and NTSTATUS as both S_OK and ERROR_SUCCESS are 0
return (S_OK == (*pCallback)(hwnd)) ? TRUE : FALSE;
}
else if constexpr (std::is_same_v<result_t, bool>)
{
return (*pCallback)(hwnd) ? TRUE : FALSE;
}
else
{
static_assert(details::always_false<TCallback>::value, "Callback must return void, bool, or HRESULT");
}
#else
return (*pCallback)(hwnd);
#endif
}
template <typename TEnumApi, typename TCallback>
void DoEnumWindowsNoThrow(TEnumApi&& enumApi, TCallback&& callback) noexcept
{
auto enumproc = [](HWND hwnd, LPARAM lParam) -> BOOL {
auto pCallback = reinterpret_cast<TCallback*>(lParam);
enumApi(EnumWindowsCallbackNoThrow<TCallback>, reinterpret_cast<LPARAM>(&callback));
}
#ifdef WIL_ENABLE_EXCEPTIONS
template <typename TCallback>
struct EnumWindowsCallbackData
{
std::exception_ptr exception;
TCallback* pCallback;
};
template <typename TCallback>
BOOL __stdcall EnumWindowsCallback(HWND hwnd, LPARAM lParam)
{
auto pCallbackData = reinterpret_cast<EnumWindowsCallbackData<TCallback>*>(lParam);
try
{
auto pCallback = pCallbackData->pCallback;
#ifdef __cpp_if_constexpr
using result_t = decltype((*pCallback)(hwnd));
if constexpr (wistd::is_void_v<result_t>)
if constexpr (std::is_void_v<result_t>)
{
(*pCallback)(hwnd);
return TRUE;
}
else if constexpr (wistd::is_same_v<result_t, HRESULT>)
else if constexpr (std::is_same_v<result_t, HRESULT>)
{
// NB: this works for both HRESULT and NTSTATUS as both S_OK and ERROR_SUCCESS are 0
return (S_OK == (*pCallback)(hwnd)) ? TRUE : FALSE;
@@ -52,55 +97,19 @@ namespace details
#else
return (*pCallback)(hwnd);
#endif
};
enumApi(enumproc, reinterpret_cast<LPARAM>(&callback));
}
}
catch (...)
{
pCallbackData->exception = std::current_exception();
return FALSE;
}
};
#ifdef WIL_ENABLE_EXCEPTIONS
template <typename TEnumApi, typename TCallback>
void DoEnumWindows(TEnumApi&& enumApi, TCallback&& callback)
{
struct
{
std::exception_ptr exception;
TCallback* pCallback;
} callbackData = {nullptr, &callback};
auto enumproc = [](HWND hwnd, LPARAM lParam) -> BOOL {
auto pCallbackData = reinterpret_cast<decltype(&callbackData)>(lParam);
try
{
auto pCallback = pCallbackData->pCallback;
#ifdef __cpp_if_constexpr
using result_t = decltype((*pCallback)(hwnd));
if constexpr (std::is_void_v<result_t>)
{
(*pCallback)(hwnd);
return TRUE;
}
else if constexpr (std::is_same_v<result_t, HRESULT>)
{
// NB: this works for both HRESULT and NTSTATUS as both S_OK and ERROR_SUCCESS are 0
return (S_OK == (*pCallback)(hwnd)) ? TRUE : FALSE;
}
else if constexpr (std::is_same_v<result_t, bool>)
{
return (*pCallback)(hwnd) ? TRUE : FALSE;
}
else
{
static_assert(details::always_false<TCallback>::value, "Callback must return void, bool, or HRESULT");
}
#else
return (*pCallback)(hwnd);
#endif
}
catch (...)
{
pCallbackData->exception = std::current_exception();
return FALSE;
}
};
enumApi(enumproc, reinterpret_cast<LPARAM>(&callbackData));
EnumWindowsCallbackData<TCallback> callbackData = {nullptr, &callback};
enumApi(EnumWindowsCallback<TCallback>, reinterpret_cast<LPARAM>(&callbackData));
if (callbackData.exception)
{
std::rethrow_exception(callbackData.exception);

View File

@@ -271,7 +271,7 @@ struct TwoPhaseHStringConstructor
return TwoPhaseHStringConstructor{characterLength};
}
//! Returns the HSTRING after it has been populated like Detatch() or release(); be sure to put this in a RAII type to manage
//! Returns the HSTRING after it has been populated like Detach() or release(); be sure to put this in a RAII type to manage
//! its lifetime.
HSTRING Promote()
{
@@ -1700,8 +1700,8 @@ hr = run_when_complete_nothrow<StorageFile*>(getFileOp.Get(), [](HRESULT hr, ISt
~~~
*/
//! Run a fuction when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler agile
//! and run on the async thread.
//! Run a function when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler
//! agile and run on the async thread.
template <typename TAgility = IUnknown, typename TFunc>
HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func) WI_NOEXCEPT
{
@@ -1727,8 +1727,8 @@ HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncActionWit
}
#ifdef WIL_ENABLE_EXCEPTIONS
//! Run a fuction when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler agile
//! and run on the async thread.
//! Run a function when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler
//! agile and run on the async thread.
template <typename TAgility = IUnknown, typename TFunc>
void run_when_complete(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func)
{

View File

@@ -33,7 +33,7 @@
// and non-exception based code should utilize this functionality.
// This header mimics libc++'s '__config' header to the extent necessary to get the wistd::* definitions compiling. Note
// that this has a few key differences since libc++'s MSVC compatability is currently not functional and a bit behind
// that this has a few key differences since libc++'s MSVC compatibility is currently not functional and a bit behind
#ifndef _WISTD_CONFIG_H_
#define _WISTD_CONFIG_H_
@@ -130,7 +130,7 @@
#define __WI_CLANG_DISABLE_WARNING(warning)
#endif
// NOTE: MSVC, which is what we primarily target, is severly underrepresented in libc++ and checks such as
// NOTE: MSVC, which is what we primarily target, is severely underrepresented in libc++ and checks such as
// __has_feature(...) are always false for MSVC, even when the feature being tested _is_ present in MSVC. Therefore, we
// instead modify all checks to be __WI_HAS_FEATURE_IS_UNION, etc., which provides the correct value for MSVC and falls
// back to the __has_feature(...), etc. value otherwise. We intentionally leave '__has_feature', etc. undefined for MSVC

View File

@@ -1946,7 +1946,7 @@ struct __numeric_type<void>
// __promote
template <class _A1, class _A2 = void, class _A3 = void, bool = __numeric_type<_A1>::value&& __numeric_type<_A2>::value&& __numeric_type<_A3>::value>
template <class _A1, class _A2 = void, class _A3 = void, bool = __numeric_type<_A1>::value && __numeric_type<_A2>::value && __numeric_type<_A3>::value>
class __promote_imp
{
public:
@@ -4775,7 +4775,7 @@ struct underlying_type
{
static_assert(
_Support,
"The underyling_type trait requires compiler "
"The underlying_type trait requires compiler "
"support. Either no such support exists or "
"libc++ does not know how to use it.");
};

View File

@@ -16715,6 +16715,7 @@ SLES-51434:
- SoftwareRendererFMVHack # Fixes blackscreen when FMV.
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes menu transparancy effects and text.
deinterlace: 9 # Fixes incorrect field order in FMVs.
memcardFilters:
- "SLES-51434"
- "SLES-50382"
@@ -29241,6 +29242,7 @@ SLKA-25065:
- SoftwareRendererFMVHack # Fixes blackscreen when FMV.
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes menu transparancy effects and text.
deinterlace: 9 # Fixes incorrect field order in FMVs.
SLKA-25066:
name: "Zone of the Enders - The 2nd Runner SE"
region: "NTSC-K"
@@ -38472,6 +38474,7 @@ SLPM-65257:
- SoftwareRendererFMVHack # Fixes blackscreen when FMV.
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes menu transparancy effects and text.
deinterlace: 9 # Fixes incorrect field order in FMVs.
memcardFilters:
- "SLPM-65257"
- "SLPM-65622"
@@ -40463,6 +40466,7 @@ SLPM-65622:
- SoftwareRendererFMVHack # Fixes blackscreen when FMV.
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes menu transparancy effects and text.
deinterlace: 9 # Fixes incorrect field order in FMVs.
memcardFilters:
- "SLPM-65257"
- "SLPM-65622"
@@ -42715,6 +42719,7 @@ SLPM-66018:
- SoftwareRendererFMVHack # Fixes blackscreen when FMV.
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes menu transparancy effects and text.
deinterlace: 9 # Fixes incorrect field order in FMVs.
memcardFilters:
- "SLPM-65257"
- "SLPM-65622"
@@ -61354,6 +61359,7 @@ SLUS-20622:
- SoftwareRendererFMVHack # Fixes blackscreen when FMV.
gsHWFixes:
recommendedBlendingLevel: 4 # Fixes menu transparancy effects and text.
deinterlace: 9 # Fixes incorrect field order in FMVs.
memcardFilters: # Reads Silent Hill 2 for easter egg.
- "SLUS-20622"
- "SLUS-20228"

View File

@@ -176,8 +176,8 @@
030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
03000000bd12000002e0000000000000,Dual Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
03000000ff1100003133000000000000,DualForce,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b1,platform:Windows,
030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
03000000317300000100000000000000,DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
030000008f0e00000910000000000000,Sony DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
03000000317300000100000000000000,Sony DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
030000006f0e00003001000000000000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000fc0400000250000000000000,Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
03000000bc2000000091000000000000,EasySMX Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -273,8 +273,8 @@
030000000d0f00005100000000000000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00008600000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f0000ba00000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00008800000000000000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
030000000d0f00008700000000000000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
030000000d0f00008800000000000000,Hori Fighting Stick mini 4 PS3,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
030000000d0f00008700000000000000,Hori Fighting Stick mini 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
030000000d0f00001000000000000000,Hori Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00003200000000000000,Hori Fightstick 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f0000c000000000000000,Hori Fightstick 4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
@@ -489,13 +489,13 @@
030000006f0e00000901000000000000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00008901000000000000,PDP Realmz Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows,
03000000666600006706000000000000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
03000000e30500009605000000000000,PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000632500002306000000000000,PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000f0250000c183000000000000,PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d9040000160f000000000000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000666600006706000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
03000000e30500009605000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
030000004c050000da0c000000000000,Sony PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000632500002306000000000000,Sony PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000f0250000c183000000000000,Sony PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d9040000160f000000000000,Sony PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
030000004c0500003713000000000000,Sony PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000011a7000000000000,PowerA Core Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000dd62000015a7000000000000,PowerA Fusion Nintendo Switch Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -691,7 +691,7 @@
03000000380700001722000000000000,Speedlink Competition Pro,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,x:b2,y:b3,platform:Windows,
030000008f0e00000800000000000000,Speedlink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
03000000d11800000094000000000000,Google Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
03000000de280000fc11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000120c0000160e000000000000,Steel Play Metaltech PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
@@ -721,12 +721,12 @@
03000000591c00002600000000000000,THEGamepad,a:b2,b:b1,back:b6,leftx:a0,lefty:a1,start:b7,x:b3,y:b0,platform:Windows,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f0400000ed0000000000000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000008d0000000000000,ThrustMaster Ferrari 150 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f0400000ed0000000000000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000008d0000000000000,Thrustmaster Ferrari 150 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
030000004f04000003d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000009d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000003d0000000000000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000009d0000000000000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
03000000666600000288000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000666600000488000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
@@ -931,8 +931,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00008400000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00008500000000010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000341a00000302000014010000,Hori Fighting Stick Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00008800000000010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00008700000000010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000000d0f00008800000000010000,Hori Fighting Stick mini 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00008700000000010000,Hori Fighting Stick mini 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000000d0f00004d00000000000000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00003801000008010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Mac OS X,
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -998,9 +998,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004b120000014d000000010000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Mac OS X,
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000666600006706000088020000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Mac OS X,
030000004c050000da0c000000010000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
030000004c0500003713000000010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000666600006706000088020000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Mac OS X,
030000004c050000da0c000000010000,Sony PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
030000004c0500003713000000010000,Sony PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000d620000011a7000010050000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -1018,7 +1018,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
050000004c050000f20d000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000005e040000e002000001000000,PXN P30 Pro Mobile,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000222c00000225000000010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000222c00000225000000010000,Qanba Dragon Arcade Joystick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000222c00000020000000010000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000009b2800005600000020020000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Mac OS X,
030000009b2800008000000022020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Mac OS X,
@@ -1053,7 +1053,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,
030000004c050000a00b000000000000,Sony DualShock 4 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000d11800000094000000010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
@@ -1072,7 +1072,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000591c00002400000021000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000591c00002600000021000000,THEGamepad,a:b2,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Mac OS X,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
030000004f0400000ed0000000020000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f0400000ed0000000020000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
03000000571d00002100000021000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Mac OS X,
03000000bd12000015d0000000010000,Tomee Retro Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
@@ -1285,7 +1285,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
190000004b4800000011000000010000,GO-Super Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b2,y:b3,platform:Linux,
03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000001010000,GPD Win Max 2 (6800U) Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000001010000,GPD Win Max 2 6800U Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
@@ -1303,8 +1303,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00003701000013010000,Hori Fighting Stick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b3,y:b2,platform:Linux,
030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000000d0f00008800000011010000,Hori Fighting Stick mini 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00008700000011010000,Hori Fighting Stick mini 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1382,7 +1382,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000380700001647000010040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000120c00000500000000010000,Manta DualShock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
030000008f0e00001330000010010000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
@@ -1468,8 +1468,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b8,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500001720000001800000,NSO SNES Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
03000000550900001472000011010000,NVIDIA Controller,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b8,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
05000000550900001472000001000000,NVIDIA Controller,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b8,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
030000004b120000014d000000010000,NYKO Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
@@ -1494,10 +1494,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000d802000006640000,PDP Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000ef02000007640000,PDP Xbox Series Kinetic Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000666600006706000000010000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000666600006706000000010000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
030000004c050000da0c000011010000,Sony PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000d9040000160f000000010000,Sony PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
030000004c0500003713000011010000,Sony PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d620000011a7000011010000,PowerA Core Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -1556,14 +1556,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000f20d000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,
03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
03000000222c00001220000011010000,Qanba Drone 2 Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00001020000011010000,Qanba Drone 2 Arcade Joystick (PS5),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00000225000011010000,Qanba Dragon Arcade Joystick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00000025000011010000,Qanba Dragon Arcade Joystick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
03000000222c00001220000011010000,Qanba Drone 2 Arcade Joystick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00001020000011010000,Qanba Drone 2 Arcade Joystick PS5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00000020000011010000,Qanba Drone Arcade PS4 Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,
03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,
0300132d9b2800006500000000000000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
@@ -1603,7 +1603,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000a306000023f6000011010000,Saitek Cyborg PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,
03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,
@@ -1635,8 +1635,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
05000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000d11800000094000011010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
05000000d11800000094000000010000,Google Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
@@ -1732,6 +1732,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000ea02000011050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000ea02000015050000,Xbox One S Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
060000005e040000ea02000016050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,

View File

@@ -1225,7 +1225,12 @@ bool FileSystem::RecursiveDeleteDirectory(const char* path)
{
for (const FILESYSTEM_FIND_DATA& fd : results)
{
if (fd.Attributes & FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY)
if (IsSymbolicLink(fd.FileName.c_str()))
{
if (!DeleteSymbolicLink(fd.FileName.c_str()))
return false;
}
else if ((fd.Attributes & FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY))
{
if (!RecursiveDeleteDirectory(fd.FileName.c_str()))
return false;
@@ -1650,21 +1655,6 @@ bool FileSystem::DirectoryExists(const char* path)
return false;
}
bool FileSystem::IsRealDirectory(const char* path)
{
// convert to wide string
const std::wstring wpath = GetWin32Path(path);
if (wpath.empty())
return false;
// determine attributes for the path. if it's a directory, things have to be handled differently..
const DWORD fileAttributes = GetFileAttributesW(wpath.c_str());
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
return false;
return ((fileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) != FILE_ATTRIBUTE_DIRECTORY);
}
bool FileSystem::DirectoryIsEmpty(const char* path)
{
std::wstring wpath = GetWin32Path(path);
@@ -1935,6 +1925,52 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
return result;
}
bool FileSystem::IsSymbolicLink(const char* path)
{
// convert to wide string
const std::wstring wpath = GetWin32Path(path);
if (wpath.empty())
return false;
// determine attributes for the path
const DWORD fileAttributes = GetFileAttributesW(wpath.c_str());
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
return false;
return fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT;
}
bool FileSystem::DeleteSymbolicLink(const char* path, Error* error)
{
// convert to wide string
const std::wstring wpath = GetWin32Path(path);
if (wpath.empty())
{
Error::SetStringView(error, "Invalid path.");
return false;
}
// delete the symbolic link
if (DirectoryExists(path))
{
if (!RemoveDirectoryW(wpath.c_str()))
{
Error::SetWin32(error, "RemoveDirectoryW() failed: ", GetLastError());
return false;
}
}
else
{
if (!DeleteFileW(wpath.c_str()))
{
Error::SetWin32(error, "DeleteFileW() failed: ", GetLastError());
return false;
}
}
return true;
}
#else
// No 32-bit file offsets breaking stuff please.
@@ -2216,15 +2252,6 @@ bool FileSystem::DirectoryExists(const char* path)
return false;
}
bool FileSystem::IsRealDirectory(const char* path)
{
struct stat sysStatData;
if (lstat(path, &sysStatData) < 0)
return false;
return (S_ISDIR(sysStatData.st_mode) && !S_ISLNK(sysStatData.st_mode));
}
bool FileSystem::DirectoryIsEmpty(const char* path)
{
DIR* pDir = opendir(path);
@@ -2478,6 +2505,26 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
return false;
}
bool FileSystem::IsSymbolicLink(const char* path)
{
struct stat sysStatData;
if (lstat(path, &sysStatData) < 0)
return false;
return S_ISLNK(sysStatData.st_mode);
}
bool FileSystem::DeleteSymbolicLink(const char* path, Error* error)
{
if (unlink(path) != 0)
{
Error::SetErrno(error, "unlink() failed: ", errno);
return false;
}
return true;
}
FileSystem::POSIXLock::POSIXLock(int fd)
{
if (lockf(fd, F_LOCK, 0) == 0)

View File

@@ -84,7 +84,6 @@ namespace FileSystem
/// Directory exists?
bool DirectoryExists(const char* path);
bool IsRealDirectory(const char* path);
/// Directory does not contain any files?
bool DirectoryIsEmpty(const char* path);
@@ -170,6 +169,12 @@ namespace FileSystem
/// Does nothing and returns false on non-Windows platforms.
bool SetPathCompression(const char* path, bool enable);
/// Checks if a file or directory is a symbolic link.
bool IsSymbolicLink(const char* path);
/// Deletes a symbolic link (either a file or directory).
bool DeleteSymbolicLink(const char* path, Error* error = nullptr);
#ifdef _WIN32
// Path limit remover, but also converts to a wide string at the same time.
bool GetWin32Path(std::wstring* dest, std::string_view str);

View File

@@ -27,7 +27,7 @@
</widget>
<widget class="QToolBar" name="toolBar">
<property name="contextMenuPolicy">
<enum>Qt::PreventContextMenu</enum>
<enum>Qt::ContextMenuPolicy::PreventContextMenu</enum>
</property>
<property name="movable">
<bool>false</bool>
@@ -39,7 +39,7 @@
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
<enum>Qt::ToolButtonStyle::ToolButtonTextBesideIcon</enum>
</property>
<property name="floatable">
<bool>false</bool>
@@ -59,8 +59,7 @@
</widget>
<action name="actionRun">
<property name="icon">
<iconset theme="play-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="play-line"/>
</property>
<property name="text">
<string>Run</string>
@@ -68,8 +67,7 @@
</action>
<action name="actionStepInto">
<property name="icon">
<iconset theme="debug-step-into-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="debug-step-into-line"/>
</property>
<property name="text">
<string>Step Into</string>
@@ -80,8 +78,7 @@
</action>
<action name="actionStepOver">
<property name="icon">
<iconset theme="debug-step-over-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="debug-step-over-line"/>
</property>
<property name="text">
<string>Step Over</string>
@@ -92,8 +89,7 @@
</action>
<action name="actionStepOut">
<property name="icon">
<iconset theme="debug-step-out-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="debug-step-out-line"/>
</property>
<property name="text">
<string>Step Out</string>
@@ -107,8 +103,7 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="pin-filled">
<normaloff>.</normaloff>.</iconset>
<iconset theme="pin-filled"/>
</property>
<property name="text">
<string>Always On Top</string>
@@ -119,8 +114,7 @@
</action>
<action name="actionAnalyse">
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="magnifier-line"/>
</property>
<property name="text">
<string>Analyze</string>

View File

@@ -31,7 +31,7 @@
<x>0</x>
<y>0</y>
<width>1050</width>
<height>22</height>
<height>27</height>
</rect>
</property>
<widget class="QMenu" name="menuSystem">
@@ -40,11 +40,10 @@
</property>
<widget class="QMenu" name="menuChangeDisc">
<property name="title">
<string>Change Disc</string>
<string>&amp;Change Disc</string>
</property>
<property name="icon">
<iconset theme="disc-eject-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="disc-eject-line"/>
</property>
<actiongroup name="actionGroupChangeDiscSubImages"/>
<addaction name="actionChangeDiscFromFile"/>
@@ -55,20 +54,18 @@
</widget>
<widget class="QMenu" name="menuLoadState">
<property name="title">
<string>Load State</string>
<string>&amp;Load State</string>
</property>
<property name="icon">
<iconset theme="floppy-out-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="floppy-out-line"/>
</property>
</widget>
<widget class="QMenu" name="menuSaveState">
<property name="title">
<string>Save State</string>
<string>Sa&amp;ve State</string>
</property>
<property name="icon">
<iconset theme="floppy-in-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="floppy-in-line"/>
</property>
</widget>
<addaction name="actionStartFile"/>
@@ -83,6 +80,7 @@
<addaction name="menuChangeDisc"/>
<addaction name="separator"/>
<addaction name="actionScreenshot"/>
<addaction name="actionVideoCapture"/>
<addaction name="separator"/>
<addaction name="menuLoadState"/>
<addaction name="menuSaveState"/>
@@ -92,7 +90,7 @@
</widget>
<widget class="QMenu" name="menuSettings">
<property name="title">
<string>S&amp;ettings</string>
<string>Setti&amp;ngs</string>
</property>
<addaction name="actionViewGameProperties"/>
<addaction name="separator"/>
@@ -132,11 +130,10 @@
</property>
<widget class="QMenu" name="menuDebugSwitchRenderer">
<property name="title">
<string>Switch Renderer</string>
<string>&amp;Switch Renderer</string>
</property>
<property name="icon">
<iconset theme="brush-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="brush-line"/>
</property>
</widget>
<addaction name="menuDebugSwitchRenderer"/>
@@ -158,8 +155,7 @@
<string>&amp;Window Size</string>
</property>
<property name="icon">
<iconset theme="window-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="window-2-line"/>
</property>
</widget>
<addaction name="actionViewToolbar"/>
@@ -185,11 +181,10 @@
</property>
<widget class="QMenu" name="menuInputRecording">
<property name="title">
<string>Input Recording</string>
<string>&amp;Input Recording</string>
</property>
<property name="icon">
<iconset theme="keyboard-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="keyboard-line"/>
</property>
<addaction name="actionInputRecNew"/>
<addaction name="actionInputRecPlay"/>
@@ -202,14 +197,13 @@
</widget>
<addaction name="actionOpenDataDirectory"/>
<addaction name="actionCoverDownloader"/>
<addaction name="actionToggleSoftwareRendering"/>
<addaction name="separator"/>
<addaction name="actionEditCheats"/>
<addaction name="actionEditPatches"/>
<addaction name="actionReloadPatches"/>
<addaction name="separator"/>
<addaction name="actionToggleSoftwareRendering"/>
<addaction name="menuInputRecording"/>
<addaction name="actionVideoCapture"/>
<addaction name="separator"/>
<addaction name="actionEnableSystemConsole"/>
<addaction name="actionEnableDebugConsole"/>
@@ -242,7 +236,7 @@
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
<enum>Qt::ToolButtonStyle::ToolButtonTextUnderIcon</enum>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
@@ -274,8 +268,7 @@
<widget class="QStatusBar" name="statusBar"/>
<action name="actionStartFile">
<property name="icon">
<iconset theme="file-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="file-line"/>
</property>
<property name="text">
<string>Start &amp;File...</string>
@@ -283,8 +276,7 @@
</action>
<action name="actionToolbarStartFile">
<property name="icon">
<iconset theme="file-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="file-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Start File</string>
@@ -292,17 +284,15 @@
</action>
<action name="actionStartDisc">
<property name="icon">
<iconset theme="disc-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="disc-2-line"/>
</property>
<property name="text">
<string>Start &amp;Disc...</string>
<string>Start D&amp;isc...</string>
</property>
</action>
<action name="actionToolbarStartDisc">
<property name="icon">
<iconset theme="disc-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="disc-2-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Start Disc</string>
@@ -310,8 +300,7 @@
</action>
<action name="actionStartBios">
<property name="icon">
<iconset theme="chip-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="chip-line"/>
</property>
<property name="text">
<string>Start &amp;BIOS</string>
@@ -319,8 +308,7 @@
</action>
<action name="actionToolbarStartBios">
<property name="icon">
<iconset theme="chip-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="chip-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Start BIOS</string>
@@ -328,8 +316,7 @@
</action>
<action name="actionScanForNewGames">
<property name="icon">
<iconset theme="file-search-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="file-search-line"/>
</property>
<property name="text">
<string>&amp;Scan For New Games</string>
@@ -337,8 +324,7 @@
</action>
<action name="actionRescanAllGames">
<property name="icon">
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="refresh-line"/>
</property>
<property name="text">
<string>&amp;Rescan All Games</string>
@@ -346,8 +332,7 @@
</action>
<action name="actionPowerOff">
<property name="icon">
<iconset theme="shut-down-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="shut-down-line"/>
</property>
<property name="text">
<string>Shut &amp;Down</string>
@@ -355,8 +340,7 @@
</action>
<action name="actionToolbarPowerOff">
<property name="icon">
<iconset theme="shut-down-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="shut-down-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Shut Down</string>
@@ -364,8 +348,7 @@
</action>
<action name="actionPowerOffWithoutSaving">
<property name="icon">
<iconset theme="close-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="close-line"/>
</property>
<property name="text">
<string>Shut Down &amp;Without Saving</string>
@@ -373,8 +356,7 @@
</action>
<action name="actionReset">
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="restart-line"/>
</property>
<property name="text">
<string>&amp;Reset</string>
@@ -382,8 +364,7 @@
</action>
<action name="actionToolbarReset">
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="restart-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Reset</string>
@@ -394,8 +375,7 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="pause-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="pause-line"/>
</property>
<property name="text">
<string>&amp;Pause</string>
@@ -406,8 +386,7 @@
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="pause-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="pause-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Pause</string>
@@ -415,8 +394,7 @@
</action>
<action name="actionToolbarLoadState">
<property name="icon">
<iconset theme="floppy-out-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="floppy-out-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Load State</string>
@@ -424,8 +402,7 @@
</action>
<action name="actionToolbarSaveState">
<property name="icon">
<iconset theme="floppy-in-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="floppy-in-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Save State</string>
@@ -433,8 +410,7 @@
</action>
<action name="actionExit">
<property name="icon">
<iconset theme="door-open-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="door-open-line"/>
</property>
<property name="text">
<string>E&amp;xit</string>
@@ -442,8 +418,7 @@
</action>
<action name="actionBIOSSettings">
<property name="icon">
<iconset theme="chip-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="chip-line"/>
</property>
<property name="text">
<string>&amp;BIOS</string>
@@ -451,17 +426,15 @@
</action>
<action name="actionEmulationSettings">
<property name="icon">
<iconset theme="emulation-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="emulation-line"/>
</property>
<property name="text">
<string>Emulation</string>
<string>&amp;Emulation</string>
</property>
</action>
<action name="actionControllerSettings">
<property name="icon">
<iconset theme="controller-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="controller-line"/>
</property>
<property name="text">
<string>&amp;Controllers</string>
@@ -469,8 +442,7 @@
</action>
<action name="actionToolbarControllerSettings">
<property name="icon">
<iconset theme="controller-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="controller-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Controllers</string>
@@ -478,8 +450,7 @@
</action>
<action name="actionHotkeySettings">
<property name="icon">
<iconset theme="keyboard-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="keyboard-line"/>
</property>
<property name="text">
<string>&amp;Hotkeys</string>
@@ -487,8 +458,7 @@
</action>
<action name="actionGraphicsSettings">
<property name="icon">
<iconset theme="image-fill">
<normaloff>.</normaloff>.</iconset>
<iconset theme="image-fill"/>
</property>
<property name="text">
<string>&amp;Graphics</string>
@@ -496,11 +466,10 @@
</action>
<action name="actionAchievementSettings">
<property name="icon">
<iconset theme="trophy-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="trophy-line"/>
</property>
<property name="text">
<string>A&amp;chievements</string>
<string>Achie&amp;vements</string>
</property>
</action>
<action name="actionPostProcessingSettings">
@@ -510,17 +479,15 @@
</action>
<action name="actionFullscreen">
<property name="icon">
<iconset theme="fullscreen-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="fullscreen-line"/>
</property>
<property name="text">
<string>Fullscreen</string>
<string>&amp;Fullscreen</string>
</property>
</action>
<action name="actionToolbarFullscreen">
<property name="icon">
<iconset theme="fullscreen-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="fullscreen-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Fullscreen</string>
@@ -533,8 +500,7 @@
</action>
<action name="actionGitHubRepository">
<property name="icon">
<iconset theme="github">
<normaloff>.</normaloff>.</iconset>
<iconset theme="github"/>
</property>
<property name="text">
<string>&amp;GitHub Repository...</string>
@@ -542,8 +508,7 @@
</action>
<action name="actionSupportForums">
<property name="icon">
<iconset theme="at">
<normaloff>.</normaloff>.</iconset>
<iconset theme="at"/>
</property>
<property name="text">
<string>Support &amp;Forums...</string>
@@ -551,8 +516,7 @@
</action>
<action name="actionDiscordServer">
<property name="icon">
<iconset theme="discord">
<normaloff>.</normaloff>.</iconset>
<iconset theme="discord"/>
</property>
<property name="text">
<string>&amp;Discord Server...</string>
@@ -560,8 +524,7 @@
</action>
<action name="actionCheckForUpdates">
<property name="icon">
<iconset theme="download-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="download-2-line"/>
</property>
<property name="text">
<string>Check for &amp;Updates...</string>
@@ -587,8 +550,7 @@
</action>
<action name="actionToolbarChangeDisc">
<property name="icon">
<iconset theme="disc-eject-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="disc-eject-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Change Disc...</string>
@@ -596,8 +558,7 @@
</action>
<action name="actionAudioSettings">
<property name="icon">
<iconset theme="volume-up-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="volume-up-line"/>
</property>
<property name="text">
<string>&amp;Audio</string>
@@ -605,73 +566,68 @@
</action>
<action name="actionGameListSettings">
<property name="icon">
<iconset theme="folder-open-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="folder-open-line"/>
</property>
<property name="text">
<string>Game List</string>
<string>Game &amp;List</string>
</property>
</action>
<action name="actionInterfaceSettings">
<property name="icon">
<iconset theme="interface-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="interface-line"/>
</property>
<property name="text">
<string>Interface</string>
<string>&amp;Interface</string>
</property>
</action>
<action name="actionAddGameDirectory">
<property name="icon">
<iconset theme="folder-add-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="folder-add-line"/>
</property>
<property name="text">
<string>Add Game Directory...</string>
<string>Add Game &amp;Directory...</string>
</property>
</action>
<action name="actionSettings">
<property name="icon">
<iconset theme="settings-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="settings-3-line"/>
</property>
<property name="text">
<string>&amp;Settings</string>
<string>S&amp;ettings</string>
</property>
<property name="menuRole">
<enum>QAction::PreferencesRole</enum>
<enum>QAction::MenuRole::PreferencesRole</enum>
</property>
</action>
<action name="actionToolbarSettings">
<property name="icon">
<iconset theme="settings-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="settings-3-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Settings</string>
</property>
<property name="menuRole">
<enum>QAction::PreferencesRole</enum>
<enum>QAction::MenuRole::PreferencesRole</enum>
</property>
</action>
<action name="actionChangeDiscFromFile">
<property name="text">
<string>From File...</string>
<string>&amp;From File...</string>
</property>
</action>
<action name="actionChangeDiscFromDevice">
<property name="text">
<string>From Device...</string>
<string>From &amp;Device...</string>
</property>
</action>
<action name="actionChangeDiscFromGameList">
<property name="text">
<string>From Game List...</string>
<string>From &amp;Game List...</string>
</property>
</action>
<action name="actionRemoveDisc">
<property name="text">
<string>Remove Disc</string>
<string>&amp;Remove Disc</string>
</property>
</action>
<action name="actionGlobal_State">
@@ -681,8 +637,7 @@
</action>
<action name="actionScreenshot">
<property name="icon">
<iconset theme="screenshot-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="screenshot-2-line"/>
</property>
<property name="text">
<string>&amp;Screenshot</string>
@@ -690,8 +645,7 @@
</action>
<action name="actionToolbarScreenshot">
<property name="icon">
<iconset theme="screenshot-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="screenshot-2-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Screenshot</string>
@@ -699,8 +653,7 @@
</action>
<action name="actionMemoryCardSettings">
<property name="icon">
<iconset theme="memcard-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="memcard-line"/>
</property>
<property name="text">
<string>&amp;Memory Cards</string>
@@ -708,8 +661,7 @@
</action>
<action name="actionDEV9Settings">
<property name="icon">
<iconset theme="global-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="global-line"/>
</property>
<property name="text">
<string>&amp;Network &amp;&amp; HDD</string>
@@ -717,8 +669,7 @@
</action>
<action name="actionFolderSettings">
<property name="icon">
<iconset theme="folder-settings-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="folder-settings-line"/>
</property>
<property name="text">
<string>&amp;Folders</string>
@@ -743,7 +694,7 @@
<bool>false</bool>
</property>
<property name="text">
<string>Lock Toolbar</string>
<string>Loc&amp;k Toolbar</string>
</property>
</action>
<action name="actionViewStatusBar">
@@ -765,13 +716,12 @@
<bool>true</bool>
</property>
<property name="text">
<string>Verbose Status</string>
<string>&amp;Verbose Status</string>
</property>
</action>
<action name="actionViewGameList">
<property name="icon">
<iconset theme="list-check">
<normaloff>.</normaloff>.</iconset>
<iconset theme="list-check"/>
</property>
<property name="text">
<string>Game &amp;List</string>
@@ -782,8 +732,7 @@
<bool>false</bool>
</property>
<property name="icon">
<iconset theme="tv-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="tv-2-line"/>
</property>
<property name="text">
<string extracomment="This grayed-out at first option will become available while there is a game emulated and the game list is displayed over the actual emulation, to let users display the system emulation once more.">System &amp;Display</string>
@@ -794,8 +743,7 @@
<bool>false</bool>
</property>
<property name="icon">
<iconset theme="file-settings-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="file-settings-line"/>
</property>
<property name="text">
<string>Game &amp;Properties</string>
@@ -803,8 +751,7 @@
</action>
<action name="actionViewGameGrid">
<property name="icon">
<iconset theme="function-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="function-line"/>
</property>
<property name="text">
<string>Game &amp;Grid</string>
@@ -817,14 +764,16 @@
<property name="checked">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="price-tag-3-line"/>
</property>
<property name="text">
<string>Show Titles (Grid View)</string>
<string>Show Titl&amp;es (Grid View)</string>
</property>
</action>
<action name="actionGridViewZoomIn">
<property name="icon">
<iconset theme="zoom-in-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="zoom-in-line"/>
</property>
<property name="text">
<string>Zoom &amp;In (Grid View)</string>
@@ -835,8 +784,7 @@
</action>
<action name="actionGridViewZoomOut">
<property name="icon">
<iconset theme="zoom-out-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="zoom-out-line"/>
</property>
<property name="text">
<string>Zoom &amp;Out (Grid View)</string>
@@ -847,8 +795,7 @@
</action>
<action name="actionGridViewRefreshCovers">
<property name="icon">
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="refresh-line"/>
</property>
<property name="text">
<string>Refresh &amp;Covers (Grid View)</string>
@@ -856,8 +803,7 @@
</action>
<action name="actionOpen_Memory_Card_Directory">
<property name="icon">
<iconset theme="memcard-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="memcard-line"/>
</property>
<property name="text">
<string>Open Memory Card Directory...</string>
@@ -865,38 +811,34 @@
</action>
<action name="actionOpenDataDirectory">
<property name="icon">
<iconset theme="folder-open-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="folder-open-line"/>
</property>
<property name="text">
<string>Open Data Directory...</string>
<string>&amp;Open Data Directory...</string>
</property>
</action>
<action name="actionToggleSoftwareRendering">
<property name="icon">
<iconset theme="brush-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="brush-line"/>
</property>
<property name="text">
<string>Toggle Software Rendering</string>
<string>&amp;Toggle Software Rendering</string>
</property>
</action>
<action name="actionDebugger">
<property name="icon">
<iconset theme="heart-circle-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="heart-circle-line"/>
</property>
<property name="text">
<string>Open Debugger</string>
<string>&amp;Open Debugger</string>
</property>
</action>
<action name="actionReloadPatches">
<property name="icon">
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="refresh-line"/>
</property>
<property name="text">
<string>Reload Cheats/Patches</string>
<string>&amp;Reload Cheats/Patches</string>
</property>
</action>
<action name="actionEnableSystemConsole">
@@ -904,7 +846,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable System Console</string>
<string>E&amp;nable System Console</string>
</property>
</action>
<action name="actionEnableDebugConsole">
@@ -912,7 +854,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable Debug Console</string>
<string>Enable &amp;Debug Console</string>
</property>
</action>
<action name="actionEnableLogWindow">
@@ -920,7 +862,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable Log Window</string>
<string>Enable &amp;Log Window</string>
</property>
</action>
<action name="actionEnableVerboseLogging">
@@ -928,7 +870,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable Verbose Logging</string>
<string>Enable &amp;Verbose Logging</string>
</property>
</action>
<action name="actionEnableEEConsoleLogging">
@@ -936,7 +878,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable EE Console Logging</string>
<string>Enable EE Console &amp;Logging</string>
</property>
</action>
<action name="actionEnableIOPConsoleLogging">
@@ -944,16 +886,15 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable IOP Console Logging</string>
<string>Enable &amp;IOP Console Logging</string>
</property>
</action>
<action name="actionSaveGSDump">
<property name="icon">
<iconset theme="save-3-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="save-3-line"/>
</property>
<property name="text">
<string>Save Single Frame GS Dump</string>
<string>Save Single Frame &amp;GS Dump</string>
</property>
</action>
<action name="actionInputRecNew">
@@ -961,7 +902,7 @@
<bool>false</bool>
</property>
<property name="text">
<string extracomment="This section refers to the Input Recording submenu.">New</string>
<string extracomment="This section refers to the Input Recording submenu.">&amp;New</string>
</property>
</action>
<action name="actionInputRecPlay">
@@ -969,7 +910,7 @@
<bool>false</bool>
</property>
<property name="text">
<string extracomment="This section refers to the Input Recording submenu.">Play</string>
<string extracomment="This section refers to the Input Recording submenu.">&amp;Play</string>
</property>
</action>
<action name="actionInputRecStop">
@@ -977,7 +918,7 @@
<bool>false</bool>
</property>
<property name="text">
<string extracomment="This section refers to the Input Recording submenu.">Stop</string>
<string extracomment="This section refers to the Input Recording submenu.">&amp;Stop</string>
</property>
</action>
<action name="actionRecording_Console_Logs">
@@ -990,7 +931,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Controller Logs</string>
<string>&amp;Controller Logs</string>
</property>
</action>
<action name="actionInputRecConsoleLogs">
@@ -998,7 +939,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Input Recording Logs</string>
<string>&amp;Input Recording Logs</string>
</property>
</action>
<action name="actionEnableFileLogging">
@@ -1014,7 +955,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable CDVD Read Logging</string>
<string>Enable &amp;CDVD Read Logging</string>
</property>
</action>
<action name="actionSaveBlockDump">
@@ -1022,7 +963,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Save CDVD Block Dump</string>
<string>Save CDVD &amp;Block Dump</string>
</property>
</action>
<action name="actionEnableLogTimestamps">
@@ -1030,22 +971,20 @@
<bool>true</bool>
</property>
<property name="text">
<string>Enable Log Timestamps</string>
<string>&amp;Enable Log Timestamps</string>
</property>
</action>
<action name="actionStartFullscreenUI">
<property name="icon">
<iconset theme="tv-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="tv-2-line"/>
</property>
<property name="text">
<string>Start Big Picture Mode</string>
<string>Start Big Picture &amp;Mode</string>
</property>
</action>
<action name="actionToolbarStartFullscreenUI">
<property name="icon">
<iconset theme="tv-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="tv-2-line"/>
</property>
<property name="text">
<string comment="In Toolbar">Big Picture</string>
@@ -1053,11 +992,10 @@
</action>
<action name="actionCoverDownloader">
<property name="icon">
<iconset theme="artboard-2-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="artboard-2-line"/>
</property>
<property name="text">
<string>Cover Downloader...</string>
<string>&amp;Cover Downloader...</string>
</property>
</action>
<action name="actionShowAdvancedSettings">
@@ -1065,42 +1003,39 @@
<bool>true</bool>
</property>
<property name="text">
<string>Show Advanced Settings</string>
<string>&amp;Show Advanced Settings</string>
</property>
</action>
<action name="actionInputRecOpenViewer">
<property name="text">
<string>Recording Viewer</string>
<string>&amp;Recording Viewer</string>
</property>
</action>
<action name="actionVideoCapture">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Video Capture</string>
</property>
<property name="icon">
<iconset theme="camera-video">
<normaloff>.</normaloff>.</iconset>
<iconset theme="camera-video"/>
</property>
<property name="text">
<string>&amp;Video Capture</string>
</property>
</action>
<action name="actionEditCheats">
<property name="text">
<string>Edit Cheats...</string>
</property>
<property name="icon">
<iconset theme="pencil-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="pencil-line"/>
</property>
<property name="text">
<string>&amp;Edit Cheats...</string>
</property>
</action>
<action name="actionEditPatches">
<property name="text">
<string>Edit Patches...</string>
</property>
<property name="icon">
<iconset theme="pencil-line">
<normaloff>.</normaloff>.</iconset>
<iconset theme="pencil-line"/>
</property>
<property name="text">
<string>Edit &amp;Patches...</string>
</property>
</action>
</widget>

View File

@@ -998,7 +998,7 @@ void EmuThread::updatePerformanceMetrics(bool force)
QString gs_stat;
if (THREAD_VU1)
{
gs_stat = tr("Slot: %1 | Volume: %2% | %3 |EE: %4% | VU: %5% | GS: %6%")
gs_stat = tr("Slot: %1 | Volume: %2% | %3 | EE: %4% | VU: %5% | GS: %6%")
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())
@@ -1008,7 +1008,7 @@ void EmuThread::updatePerformanceMetrics(bool force)
}
else
{
gs_stat = tr("Slot: %1 | Volume: %2% | 3% | EE: %4% | GS: %5%")
gs_stat = tr("Slot: %1 | Volume: %2% | %3 | EE: %4% | GS: %5%")
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())

View File

@@ -4792,53 +4792,53 @@ Do you want to overwrite?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="66"/>
<location filename="../Debugger/DebuggerWindow.ui" line="65"/>
<location filename="../Debugger/DebuggerWindow.cpp" line="76"/>
<source>Run</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="75"/>
<location filename="../Debugger/DebuggerWindow.ui" line="73"/>
<source>Step Into</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="78"/>
<location filename="../Debugger/DebuggerWindow.ui" line="76"/>
<source>F11</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="87"/>
<location filename="../Debugger/DebuggerWindow.ui" line="84"/>
<source>Step Over</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="90"/>
<location filename="../Debugger/DebuggerWindow.ui" line="87"/>
<source>F10</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="99"/>
<location filename="../Debugger/DebuggerWindow.ui" line="95"/>
<source>Step Out</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="102"/>
<location filename="../Debugger/DebuggerWindow.ui" line="98"/>
<source>Shift+F11</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="114"/>
<location filename="../Debugger/DebuggerWindow.ui" line="109"/>
<source>Always On Top</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="117"/>
<location filename="../Debugger/DebuggerWindow.ui" line="112"/>
<source>Show this window on top</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="126"/>
<location filename="../Debugger/DebuggerWindow.ui" line="120"/>
<source>Analyze</source>
<translation type="unfinished"></translation>
</message>
@@ -5036,12 +5036,12 @@ Do you want to overwrite?</source>
<name>EmuThread</name>
<message>
<location filename="../QtHost.cpp" line="1001"/>
<source>Slot: %1 | Volume: %2% | %3 |EE: %4% | VU: %5% | GS: %6%</source>
<source>Slot: %1 | Volume: %2% | %3 | EE: %4% | VU: %5% | GS: %6%</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../QtHost.cpp" line="1011"/>
<source>Slot: %1 | Volume: %2% | 3% | EE: %4% | GS: %5%</source>
<source>Slot: %1 | Volume: %2% | %3 | EE: %4% | GS: %5%</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -15422,566 +15422,586 @@ Right click to clear binding</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="43"/>
<location filename="../MainWindow.cpp" line="1406"/>
<location filename="../MainWindow.cpp" line="1467"/>
<source>Change Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="58"/>
<location filename="../MainWindow.cpp" line="2785"/>
<source>Load State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="67"/>
<source>Save State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="95"/>
<location filename="../MainWindow.ui" line="596"/>
<source>S&amp;ettings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="118"/>
<location filename="../MainWindow.ui" line="116"/>
<source>&amp;Help</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="131"/>
<location filename="../MainWindow.ui" line="129"/>
<source>&amp;Debug</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="135"/>
<source>Switch Renderer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="154"/>
<location filename="../MainWindow.ui" line="151"/>
<source>&amp;View</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="158"/>
<location filename="../MainWindow.ui" line="155"/>
<source>&amp;Window Size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="184"/>
<location filename="../MainWindow.ui" line="180"/>
<source>&amp;Tools</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="188"/>
<source>Input Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="236"/>
<location filename="../MainWindow.ui" line="230"/>
<source>Toolbar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="281"/>
<location filename="../MainWindow.ui" line="274"/>
<source>Start &amp;File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="299"/>
<source>Start &amp;Disc...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="317"/>
<location filename="../MainWindow.ui" line="306"/>
<source>Start &amp;BIOS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="335"/>
<location filename="../MainWindow.ui" line="322"/>
<source>&amp;Scan For New Games</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="344"/>
<location filename="../MainWindow.ui" line="330"/>
<source>&amp;Rescan All Games</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="353"/>
<location filename="../MainWindow.ui" line="338"/>
<source>Shut &amp;Down</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="371"/>
<location filename="../MainWindow.ui" line="354"/>
<source>Shut Down &amp;Without Saving</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="380"/>
<location filename="../MainWindow.ui" line="362"/>
<source>&amp;Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="401"/>
<location filename="../MainWindow.ui" line="381"/>
<source>&amp;Pause</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="440"/>
<location filename="../MainWindow.ui" line="416"/>
<source>E&amp;xit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="449"/>
<location filename="../MainWindow.ui" line="424"/>
<source>&amp;BIOS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="458"/>
<source>Emulation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="467"/>
<location filename="../MainWindow.ui" line="440"/>
<source>&amp;Controllers</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="485"/>
<location filename="../MainWindow.ui" line="456"/>
<source>&amp;Hotkeys</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="494"/>
<location filename="../MainWindow.ui" line="464"/>
<source>&amp;Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="503"/>
<source>A&amp;chievements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="508"/>
<location filename="../MainWindow.ui" line="477"/>
<source>&amp;Post-Processing Settings...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="517"/>
<source>Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="531"/>
<location filename="../MainWindow.ui" line="498"/>
<source>Resolution Scale</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="540"/>
<location filename="../MainWindow.ui" line="506"/>
<source>&amp;GitHub Repository...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="549"/>
<location filename="../MainWindow.ui" line="514"/>
<source>Support &amp;Forums...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="558"/>
<location filename="../MainWindow.ui" line="522"/>
<source>&amp;Discord Server...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="567"/>
<location filename="../MainWindow.ui" line="530"/>
<source>Check for &amp;Updates...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="576"/>
<location filename="../MainWindow.ui" line="539"/>
<source>About &amp;Qt...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="585"/>
<location filename="../MainWindow.ui" line="548"/>
<source>&amp;About PCSX2...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="526"/>
<location filename="../MainWindow.ui" line="493"/>
<source>Fullscreen</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="594"/>
<location filename="../MainWindow.ui" line="556"/>
<source>Change Disc...</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="603"/>
<location filename="../MainWindow.ui" line="564"/>
<source>&amp;Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="612"/>
<source>Game List</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="621"/>
<source>Interface</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="630"/>
<source>Add Game Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="639"/>
<source>&amp;Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="659"/>
<source>From File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="664"/>
<source>From Device...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="669"/>
<source>From Game List...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="674"/>
<source>Remove Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="679"/>
<location filename="../MainWindow.ui" line="635"/>
<source>Global State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="688"/>
<location filename="../MainWindow.ui" line="643"/>
<source>&amp;Screenshot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="290"/>
<location filename="../MainWindow.ui" line="282"/>
<source>Start File</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="308"/>
<location filename="../MainWindow.ui" line="43"/>
<source>&amp;Change Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="57"/>
<source>&amp;Load State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="65"/>
<source>Sa&amp;ve State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="93"/>
<source>Setti&amp;ngs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="133"/>
<source>&amp;Switch Renderer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="184"/>
<source>&amp;Input Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="290"/>
<source>Start D&amp;isc...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="298"/>
<source>Start Disc</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="326"/>
<location filename="../MainWindow.ui" line="314"/>
<source>Start BIOS</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="362"/>
<location filename="../MainWindow.ui" line="346"/>
<source>Shut Down</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="389"/>
<location filename="../MainWindow.ui" line="370"/>
<source>Reset</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="413"/>
<location filename="../MainWindow.ui" line="392"/>
<source>Pause</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="422"/>
<location filename="../MainWindow.ui" line="400"/>
<source>Load State</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="431"/>
<location filename="../MainWindow.ui" line="408"/>
<source>Save State</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="476"/>
<location filename="../MainWindow.ui" line="432"/>
<source>&amp;Emulation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="448"/>
<source>Controllers</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="651"/>
<location filename="../MainWindow.ui" line="472"/>
<source>Achie&amp;vements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="485"/>
<source>&amp;Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="580"/>
<source>&amp;Interface</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="588"/>
<source>Add Game &amp;Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="607"/>
<source>Settings</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="697"/>
<location filename="../MainWindow.ui" line="615"/>
<source>&amp;From File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="620"/>
<source>From &amp;Device...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="625"/>
<source>From &amp;Game List...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="630"/>
<source>&amp;Remove Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="651"/>
<source>Screenshot</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="706"/>
<location filename="../MainWindow.ui" line="659"/>
<source>&amp;Memory Cards</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="715"/>
<location filename="../MainWindow.ui" line="667"/>
<source>&amp;Network &amp;&amp; HDD</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="724"/>
<location filename="../MainWindow.ui" line="675"/>
<source>&amp;Folders</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="735"/>
<location filename="../MainWindow.ui" line="686"/>
<source>&amp;Toolbar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="746"/>
<source>Lock Toolbar</source>
<location filename="../MainWindow.ui" line="771"/>
<source>Show Titl&amp;es (Grid View)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="757"/>
<location filename="../MainWindow.ui" line="817"/>
<source>&amp;Open Data Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="825"/>
<source>&amp;Toggle Software Rendering</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="833"/>
<source>&amp;Open Debugger</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="841"/>
<source>&amp;Reload Cheats/Patches</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="849"/>
<source>E&amp;nable System Console</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="857"/>
<source>Enable &amp;Debug Console</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="865"/>
<source>Enable &amp;Log Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="873"/>
<source>Enable &amp;Verbose Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="881"/>
<source>Enable EE Console &amp;Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="889"/>
<source>Enable &amp;IOP Console Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="897"/>
<source>Save Single Frame &amp;GS Dump</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="905"/>
<source>&amp;New</source>
<extracomment>This section refers to the Input Recording submenu.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="913"/>
<source>&amp;Play</source>
<extracomment>This section refers to the Input Recording submenu.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="921"/>
<source>&amp;Stop</source>
<extracomment>This section refers to the Input Recording submenu.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="934"/>
<source>&amp;Controller Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="942"/>
<source>&amp;Input Recording Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="958"/>
<source>Enable &amp;CDVD Read Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="966"/>
<source>Save CDVD &amp;Block Dump</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="974"/>
<source>&amp;Enable Log Timestamps</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="982"/>
<source>Start Big Picture &amp;Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="998"/>
<source>&amp;Cover Downloader...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1006"/>
<source>&amp;Show Advanced Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1011"/>
<source>&amp;Recording Viewer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1022"/>
<source>&amp;Video Capture</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1030"/>
<source>&amp;Edit Cheats...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1038"/>
<source>Edit &amp;Patches...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="708"/>
<source>&amp;Status Bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="768"/>
<source>Verbose Status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="777"/>
<location filename="../MainWindow.ui" line="572"/>
<location filename="../MainWindow.ui" line="727"/>
<source>Game &amp;List</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="789"/>
<location filename="../MainWindow.ui" line="697"/>
<source>Loc&amp;k Toolbar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="719"/>
<source>&amp;Verbose Status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="738"/>
<source>System &amp;Display</source>
<extracomment>This grayed-out at first option will become available while there is a game emulated and the game list is displayed over the actual emulation, to let users display the system emulation once more.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="801"/>
<location filename="../MainWindow.ui" line="749"/>
<source>Game &amp;Properties</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="810"/>
<location filename="../MainWindow.ui" line="757"/>
<source>Game &amp;Grid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="821"/>
<source>Show Titles (Grid View)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="830"/>
<location filename="../MainWindow.ui" line="779"/>
<source>Zoom &amp;In (Grid View)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="833"/>
<location filename="../MainWindow.ui" line="782"/>
<source>Ctrl++</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="842"/>
<location filename="../MainWindow.ui" line="790"/>
<source>Zoom &amp;Out (Grid View)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="845"/>
<location filename="../MainWindow.ui" line="793"/>
<source>Ctrl+-</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="854"/>
<location filename="../MainWindow.ui" line="801"/>
<source>Refresh &amp;Covers (Grid View)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="863"/>
<location filename="../MainWindow.ui" line="809"/>
<source>Open Memory Card Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="872"/>
<source>Open Data Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="881"/>
<source>Toggle Software Rendering</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="890"/>
<source>Open Debugger</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="899"/>
<source>Reload Cheats/Patches</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="907"/>
<source>Enable System Console</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="915"/>
<source>Enable Debug Console</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="923"/>
<source>Enable Log Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="931"/>
<source>Enable Verbose Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="939"/>
<source>Enable EE Console Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="947"/>
<source>Enable IOP Console Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="956"/>
<source>Save Single Frame GS Dump</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="964"/>
<source>New</source>
<extracomment>This section refers to the Input Recording submenu.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="972"/>
<source>Play</source>
<extracomment>This section refers to the Input Recording submenu.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="980"/>
<source>Stop</source>
<extracomment>This section refers to the Input Recording submenu.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="985"/>
<location filename="../MainWindow.ui" line="1001"/>
<location filename="../MainWindow.ui" line="926"/>
<source>Input Recording Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="993"/>
<source>Controller Logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1009"/>
<location filename="../MainWindow.ui" line="950"/>
<source>Enable &amp;File Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1017"/>
<source>Enable CDVD Read Logging</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1025"/>
<source>Save CDVD Block Dump</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1033"/>
<source>Enable Log Timestamps</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1042"/>
<location filename="../MainWindow.cpp" line="1510"/>
<source>Start Big Picture Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1051"/>
<location filename="../MainWindow.ui" line="990"/>
<location filename="../MainWindow.cpp" line="1511"/>
<source>Big Picture</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1060"/>
<source>Cover Downloader...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1068"/>
<location filename="../MainWindow.cpp" line="673"/>
<source>Show Advanced Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1073"/>
<source>Recording Viewer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1081"/>
<location filename="../MainWindow.cpp" line="742"/>
<source>Video Capture</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1090"/>
<source>Edit Cheats...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1099"/>
<source>Edit Patches...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="251"/>
<source>Internal Resolution</source>
@@ -18450,7 +18470,7 @@ Ejecting {3} and replacing it with {2}.</source>
<context>
<name>SaveState</name>
<message>
<location filename="../../pcsx2/SaveState.cpp" line="1095"/>
<location filename="../../pcsx2/SaveState.cpp" line="1098"/>
<source>This save state is outdated and is no longer compatible with the current version of PCSX2.
If you have any unsaved progress on this save state, you can download the compatible version (PCSX2 {}) from pcsx2.net, load the save state, and save your progress to the memory card.</source>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#FFFFFF"
width="800px"
height="800px"
viewBox="0 0 512 512"
version="1.1"
id="svg1"
sodipodi:docname="magnifier-line.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.005"
inkscape:cx="250.24876"
inkscape:cy="399.50249"
inkscape:window-width="1920"
inkscape:window-height="1008"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
id="path1"
style="fill:#000000" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#FFFFFF"
width="800px"
height="800px"
viewBox="0 0 512 512"
version="1.1"
id="svg1"
sodipodi:docname="search2.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.005"
inkscape:cx="250.24876"
inkscape:cy="399.50249"
inkscape:window-width="1920"
inkscape:window-height="1008"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
id="path1" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -63,6 +63,7 @@
<file>icons/black/svg/lightbulb-line.svg</file>
<file>icons/black/svg/list-check.svg</file>
<file>icons/black/svg/login-box-line.svg</file>
<file>icons/black/svg/magnifier-line.svg</file>
<file>icons/black/svg/memcard-line.svg</file>
<file>icons/black/svg/mic-line.svg</file>
<file>icons/black/svg/minus-line.svg</file>
@@ -166,6 +167,7 @@
<file>icons/white/svg/lightbulb-line.svg</file>
<file>icons/white/svg/list-check.svg</file>
<file>icons/white/svg/login-box-line.svg</file>
<file>icons/white/svg/magnifier-line.svg</file>
<file>icons/white/svg/memcard-line.svg</file>
<file>icons/white/svg/mic-line.svg</file>
<file>icons/white/svg/minus-line.svg</file>

View File

@@ -2008,7 +2008,7 @@ void Achievements::DrawGameOverlays()
s_active_progress_indicator.reset();
}
position.y -= image_size.y - padding * 3.0f;
position.y -= image_size.y + padding * 3.0f;
}
if (!s_active_leaderboard_trackers.empty())
@@ -2058,7 +2058,7 @@ void Achievements::DrawGameOverlays()
}
// Uncomment if there are any other overlays above this one.
//position.y -= image_size.y - padding * 3.0f;
//position.y -= image_size.y + padding * 3.0f;
}
}

View File

@@ -384,7 +384,8 @@ std::vector<IP_Address> AdapterUtils::GetGateways(const Adapter* adapter)
if (ReadAddressFamily(address->Address.lpSockaddr) == AF_INET)
{
const sockaddr_in* sockaddr = reinterpret_cast<sockaddr_in*>(address->Address.lpSockaddr);
collection.push_back(std::bit_cast<IP_Address>(sockaddr->sin_addr));
if (sockaddr->sin_addr.S_un.S_addr != 0)
collection.push_back(std::bit_cast<IP_Address>(sockaddr->sin_addr));
}
address = address->Next;
}

View File

@@ -16,7 +16,7 @@ namespace PacketReader::ARP
{
}
ARP_Packet::ARP_Packet(u8* buffer, int bufferSize)
ARP_Packet::ARP_Packet(const u8* buffer, int bufferSize)
{
int offset = 0;

View File

@@ -22,7 +22,7 @@ namespace PacketReader::ARP
std::unique_ptr<u8[]> targetProtocolAddress;
ARP_Packet(u8 hwAddrLen, u8 procAddrLen);
ARP_Packet(u8* buffer, int bufferSize);
ARP_Packet(const u8* buffer, int bufferSize);
ARP_Packet(const ARP_Packet&);
virtual int GetLength();

View File

@@ -11,59 +11,59 @@
namespace PacketReader::ARP
{
ARP_PacketEditor::ARP_PacketEditor(PayloadPtr* pkt)
ARP_PacketEditor::ARP_PacketEditor(PayloadPtrEditor* pkt)
: basePkt{pkt}
{
}
u16 ARP_PacketEditor::GetHardwareType()
u16 ARP_PacketEditor::GetHardwareType() const
{
return ntohs(*(u16*)&basePkt->data[0]);
}
u16 ARP_PacketEditor::GetProtocol()
u16 ARP_PacketEditor::GetProtocol() const
{
return ntohs(*(u16*)&basePkt->data[2]);
}
u8 ARP_PacketEditor::GetHardwareAddressLength()
u8 ARP_PacketEditor::GetHardwareAddressLength() const
{
return basePkt->data[4];
}
u8 ARP_PacketEditor::GetProtocolAddressLength()
u8 ARP_PacketEditor::GetProtocolAddressLength() const
{
return basePkt->data[5];
}
u16 ARP_PacketEditor::GetOp()
u16 ARP_PacketEditor::GetOp() const
{
return ntohs(*(u16*)&basePkt->data[6]);
}
u8* ARP_PacketEditor::SenderHardwareAddress()
u8* ARP_PacketEditor::SenderHardwareAddress() const
{
return &basePkt->data[8];
}
u8* ARP_PacketEditor::SenderProtocolAddress()
u8* ARP_PacketEditor::SenderProtocolAddress() const
{
int offset = 8 + GetHardwareAddressLength();
const int offset = 8 + GetHardwareAddressLength();
return &basePkt->data[offset];
}
u8* ARP_PacketEditor::TargetHardwareAddress()
u8* ARP_PacketEditor::TargetHardwareAddress() const
{
int offset = 8 + GetHardwareAddressLength() + GetProtocolAddressLength();
const int offset = 8 + GetHardwareAddressLength() + GetProtocolAddressLength();
return &basePkt->data[offset];
}
u8* ARP_PacketEditor::TargetProtocolAddress()
u8* ARP_PacketEditor::TargetProtocolAddress() const
{
int offset = 8 + 2 * GetHardwareAddressLength() + GetProtocolAddressLength();
const int offset = 8 + 2 * GetHardwareAddressLength() + GetProtocolAddressLength();
return &basePkt->data[offset];
}
int ARP_PacketEditor::GetLength()
int ARP_PacketEditor::GetLength() const
{
return 8 + 2 * GetHardwareAddressLength() + 2 * GetProtocolAddressLength();
}

View File

@@ -10,22 +10,22 @@ namespace PacketReader::ARP
class ARP_PacketEditor
{
private:
PayloadPtr* basePkt;
PayloadPtrEditor* basePkt;
public:
ARP_PacketEditor(PayloadPtr* pkt);
ARP_PacketEditor(PayloadPtrEditor* pkt);
u16 GetHardwareType();
u16 GetProtocol();
u8 GetHardwareAddressLength();
u8 GetProtocolAddressLength();
u16 GetOp();
u16 GetHardwareType() const;
u16 GetProtocol() const;
u8 GetHardwareAddressLength() const;
u8 GetProtocolAddressLength() const;
u16 GetOp() const;
u8* SenderHardwareAddress();
u8* SenderProtocolAddress();
u8* TargetHardwareAddress();
u8* TargetProtocolAddress();
u8* SenderHardwareAddress() const;
u8* SenderProtocolAddress() const;
u8* TargetHardwareAddress() const;
u8* TargetProtocolAddress() const;
int GetLength();
int GetLength() const;
};
} // namespace PacketReader::ARP

View File

@@ -19,10 +19,10 @@ namespace PacketReader
//Note: we don't have to worry about the Ethernet Frame CRC as it is not included in the packet
//Note: We don't support tagged frames
payload = std::make_unique<PayloadPtr>((u8*)&basePkt->buffer[14], pkt->size - headerLength);
payload = std::make_unique<PayloadPtrEditor>((u8*)&basePkt->buffer[14], pkt->size - headerLength);
}
MAC_Address EthernetFrameEditor::GetDestinationMAC()
MAC_Address EthernetFrameEditor::GetDestinationMAC() const
{
return *(MAC_Address*)&basePkt->buffer[0];
}
@@ -31,7 +31,7 @@ namespace PacketReader
*(MAC_Address*)&basePkt->buffer[0] = value;
}
MAC_Address EthernetFrameEditor::GetSourceMAC()
MAC_Address EthernetFrameEditor::GetSourceMAC() const
{
return *(MAC_Address*)&basePkt->buffer[6];
}
@@ -40,12 +40,12 @@ namespace PacketReader
*(MAC_Address*)&basePkt->buffer[6] = value;
}
u16 EthernetFrameEditor::GetProtocol()
u16 EthernetFrameEditor::GetProtocol() const
{
return ntohs(*(u16*)&basePkt->buffer[12]);
}
PayloadPtr* EthernetFrameEditor::GetPayload()
PayloadPtrEditor* EthernetFrameEditor::GetPayload() const
{
return payload.get();
}

View File

@@ -16,18 +16,18 @@ namespace PacketReader
//Length
private:
NetPacket* basePkt;
std::unique_ptr<PayloadPtr> payload;
std::unique_ptr<PayloadPtrEditor> payload;
public:
EthernetFrameEditor(NetPacket* pkt);
MAC_Address GetDestinationMAC();
MAC_Address GetDestinationMAC() const;
void SetDestinationMAC(MAC_Address value);
MAC_Address GetSourceMAC();
MAC_Address GetSourceMAC() const;
void SetSourceMAC(MAC_Address value);
u16 GetProtocol();
u16 GetProtocol() const;
PayloadPtr* GetPayload();
PayloadPtrEditor* GetPayload() const;
};
} // namespace PacketReader

View File

@@ -10,7 +10,7 @@ namespace PacketReader::IP::ICMP
: payload{data}
{
}
ICMP_Packet::ICMP_Packet(u8* buffer, int bufferSize)
ICMP_Packet::ICMP_Packet(const u8* buffer, int bufferSize)
{
int offset = 0;
//Bits 0-31
@@ -34,7 +34,7 @@ namespace PacketReader::IP::ICMP
memcpy(headerData, original.headerData, 4);
}
Payload* ICMP_Packet::GetPayload()
Payload* ICMP_Packet::GetPayload() const
{
return payload.get();
}
@@ -59,7 +59,7 @@ namespace PacketReader::IP::ICMP
return new ICMP_Packet(*this);
}
u8 ICMP_Packet::GetProtocol()
u8 ICMP_Packet::GetProtocol() const
{
return (u8)protocol;
}
@@ -102,7 +102,7 @@ namespace PacketReader::IP::ICMP
if (counter != pHeaderLen)
NetLib::WriteByte08(segment, &counter, 0);
u16 csumCal = IP_Packet::InternetChecksum(segment, pHeaderLen);
const u16 csumCal = IP_Packet::InternetChecksum(segment, pHeaderLen);
delete[] segment;
return (csumCal == 0);

View File

@@ -27,16 +27,16 @@ namespace PacketReader::IP::ICMP
public:
//Takes ownership of payload
ICMP_Packet(Payload* data);
ICMP_Packet(u8* buffer, int bufferSize);
ICMP_Packet(const u8* buffer, int bufferSize);
ICMP_Packet(const ICMP_Packet&);
Payload* GetPayload();
Payload* GetPayload() const;
virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset);
virtual ICMP_Packet* Clone() const;
virtual u8 GetProtocol();
virtual u8 GetProtocol() const;
virtual bool VerifyChecksum(IP_Address srcIP, IP_Address dstIP);
virtual void CalculateChecksum(IP_Address srcIP, IP_Address dstIP);

View File

@@ -6,20 +6,20 @@
namespace PacketReader::IP
{
bool IPOption::IsCopyOnFragment()
bool IPOption::IsCopyOnFragment() const
{
return ((GetCode() & (1 << 0x7)) != 0);
}
u8 IPOption::GetClass()
u8 IPOption::GetClass() const
{
return (GetCode() >> 5) & 0x3;
}
u8 IPOption::GetNumber()
u8 IPOption::GetNumber() const
{
return GetCode() & 0x1F;
}
IPopUnk::IPopUnk(u8* data, int offset)
IPopUnk::IPopUnk(const u8* data, int offset)
{
NetLib::ReadByte08(data, &offset, &code);
NetLib::ReadByte08(data, &offset, &length);
@@ -27,7 +27,7 @@ namespace PacketReader::IP
value.resize(length - 2);
NetLib::ReadByteArray(data, &offset, length - 2, &value[0]);
}
void IPopUnk::WriteBytes(u8* buffer, int* offset)
void IPopUnk::WriteBytes(u8* buffer, int* offset) const
{
NetLib::WriteByte08(buffer, offset, code);
NetLib::WriteByte08(buffer, offset, length);
@@ -38,12 +38,12 @@ namespace PacketReader::IP
: value{parValue}
{
}
IPopRouterAlert::IPopRouterAlert(u8* data, int offset)
IPopRouterAlert::IPopRouterAlert(const u8* data, int offset)
{
offset += 2;
NetLib::ReadUInt16(data, &offset, &value);
}
void IPopRouterAlert::WriteBytes(u8* buffer, int* offset)
void IPopRouterAlert::WriteBytes(u8* buffer, int* offset) const
{
NetLib::WriteByte08(buffer, offset, GetCode());
NetLib::WriteByte08(buffer, offset, GetLength());

View File

@@ -12,9 +12,9 @@ namespace PacketReader::IP
class BaseOption
{
public:
virtual u8 GetLength() = 0;
virtual u8 GetCode() = 0;
virtual void WriteBytes(u8* buffer, int* offset) = 0;
virtual u8 GetLength() const = 0;
virtual u8 GetCode() const = 0;
virtual void WriteBytes(u8* buffer, int* offset) const = 0;
virtual BaseOption* Clone() const = 0;
virtual ~BaseOption() {}
};
@@ -22,9 +22,9 @@ namespace PacketReader::IP
class IPOption : public BaseOption
{
public:
bool IsCopyOnFragment();
u8 GetClass(); //0 = control, 2 = debugging and measurement
u8 GetNumber();
bool IsCopyOnFragment() const;
u8 GetClass() const; //0 = control, 2 = debugging and measurement
u8 GetNumber() const;
virtual IPOption* Clone() const = 0;
};
@@ -35,12 +35,12 @@ namespace PacketReader::IP
std::vector<u8> value;
public:
IPopUnk(u8* data, int offset);
IPopUnk(const u8* data, int offset);
virtual u8 GetLength() { return length; }
virtual u8 GetCode() { return code; }
virtual u8 GetLength() const { return length; }
virtual u8 GetCode() const { return code; }
void WriteBytes(u8* buffer, int* offset);
void WriteBytes(u8* buffer, int* offset) const;
virtual IPopUnk* Clone() const
{
@@ -51,10 +51,10 @@ namespace PacketReader::IP
class IPopNOP : public IPOption
{
public:
virtual u8 GetLength() { return 1; }
virtual u8 GetCode() { return 1; }
virtual u8 GetLength() const { return 1; }
virtual u8 GetCode() const { return 1; }
virtual void WriteBytes(u8* buffer, int* offset)
virtual void WriteBytes(u8* buffer, int* offset) const
{
buffer[*offset] = GetCode();
(*offset)++;
@@ -73,12 +73,12 @@ namespace PacketReader::IP
u16 value;
IPopRouterAlert(u16 parValue);
IPopRouterAlert(u8* data, int offset);
IPopRouterAlert(const u8* data, int offset);
virtual u8 GetLength() { return 4; }
virtual u8 GetCode() { return 148; }
virtual u8 GetLength() const { return 4; }
virtual u8 GetCode() const { return 148; }
virtual void WriteBytes(u8* buffer, int* offset);
virtual void WriteBytes(u8* buffer, int* offset) const;
virtual IPopRouterAlert* Clone() const
{

View File

@@ -4,25 +4,26 @@
#include "IP_Packet.h"
#include "DEV9/PacketReader/NetLib.h"
#include "common/BitUtils.h"
#include "common/Console.h"
namespace PacketReader::IP
{
int IP_Packet::GetHeaderLength()
int IP_Packet::GetHeaderLength() const
{
return headerLength;
}
u8 IP_Packet::GetDscpValue()
u8 IP_Packet::GetDscpValue() const
{
return (dscp >> 2) & 0x3F;
}
void IP_Packet::GetDscpValue(u8 value)
void IP_Packet::SetDscpValue(u8 value)
{
dscp = (dscp & ~(0x3F << 2)) | ((value & 0x3F) << 2);
}
u8 IP_Packet::GetDscpECN()
u8 IP_Packet::GetDscpECN() const
{
return dscp & 0x3;
}
@@ -31,7 +32,7 @@ namespace PacketReader::IP
dscp = (dscp & ~0x3) | (value & 0x3);
}
bool IP_Packet::GetDoNotFragment()
bool IP_Packet::GetDoNotFragment() const
{
return (fragmentFlags1 & (1 << 6)) != 0;
}
@@ -40,7 +41,7 @@ namespace PacketReader::IP
fragmentFlags1 = (fragmentFlags1 & ~(0x1 << 6)) | ((value & 0x1) << 6);
}
bool IP_Packet::GetMoreFragments()
bool IP_Packet::GetMoreFragments() const
{
return (fragmentFlags1 & (1 << 5)) != 0;
}
@@ -49,11 +50,11 @@ namespace PacketReader::IP
fragmentFlags1 = (fragmentFlags1 & ~(0x1 << 5)) | ((value & 0x1) << 5);
}
u16 IP_Packet::GetFragmentOffset()
u16 IP_Packet::GetFragmentOffset() const
{
int x = 0;
u8 fF1masked = fragmentFlags1 & 0x1F;
u8 data[2] = {fF1masked, fragmentFlags2};
const u8 fF1masked = fragmentFlags1 & 0x1F;
const u8 data[2] = {fF1masked, fragmentFlags2};
u16 offset;
NetLib::ReadUInt16(data, &x, &offset);
return offset;
@@ -65,7 +66,7 @@ namespace PacketReader::IP
{
}
IP_Packet::IP_Packet(u8* buffer, int bufferSize, bool fromICMP)
IP_Packet::IP_Packet(const u8* buffer, int bufferSize, bool fromICMP)
{
int offset = 0;
@@ -105,8 +106,8 @@ namespace PacketReader::IP
bool opReadFin = false;
do
{
u8 opKind = buffer[offset];
u8 opLen = buffer[offset + 1];
const u8 opKind = buffer[offset];
const u8 opLen = buffer[offset + 1];
switch (opKind)
{
case 0:
@@ -153,7 +154,7 @@ namespace PacketReader::IP
options.push_back(original.options[i]->Clone());
}
IP_Payload* IP_Packet::GetPayload()
IP_Payload* IP_Packet::GetPayload() const
{
return payload.get();
}
@@ -166,7 +167,7 @@ namespace PacketReader::IP
void IP_Packet::WriteBytes(u8* buffer, int* offset)
{
int startOff = *offset;
const int startOff = *offset;
CalculateChecksum(); //ReComputeHeaderLen called in CalculateChecksum
payload->CalculateChecksum(sourceIP, destinationIP);
@@ -209,8 +210,8 @@ namespace PacketReader::IP
for (size_t i = 0; i < options.size(); i++)
opOffset += options[i]->GetLength();
opOffset += opOffset % 4; //needs to be a whole number of 32bits
headerLength = opOffset;
//needs to be a whole number of 32bits
headerLength = Common::AlignUpPow2(opOffset, 4);
}
void IP_Packet::CalculateChecksum()
@@ -289,7 +290,7 @@ namespace PacketReader::IP
delete options[i];
}
u16 IP_Packet::InternetChecksum(u8* buffer, int length)
u16 IP_Packet::InternetChecksum(const u8* buffer, int length)
{
//source http://stackoverflow.com/a/2201090

View File

@@ -54,7 +54,7 @@ namespace PacketReader::IP
std::unique_ptr<IP_Payload> payload;
public:
int GetHeaderLength();
int GetHeaderLength() const;
//DSCP/TOS Flags
@@ -85,8 +85,8 @@ namespace PacketReader::IP
* Class 5, Expedited Forwarding, 3
* bit0: Set to zero
*/
u8 GetDscpValue();
void GetDscpValue(u8 value);
u8 GetDscpValue() const;
void SetDscpValue(u8 value);
/* 2 bits
* In TOS, defined as follows
@@ -97,34 +97,34 @@ namespace PacketReader::IP
* 1,2 ECN Supported
* 3 = Congestion Encountered
*/
u8 GetDscpECN();
u8 GetDscpECN() const;
void SetDscpECN(u8 value);
//Fragment Flags
//bit 0, reserverd
bool GetDoNotFragment();
bool GetDoNotFragment() const;
void SetDoNotFragment(bool value);
bool GetMoreFragments();
bool GetMoreFragments() const;
void SetMoreFragments(bool value);
//Untested
u16 GetFragmentOffset();
u16 GetFragmentOffset() const;
//Takes ownership of payload
IP_Packet(IP_Payload* data);
IP_Packet(u8* buffer, int bufferSize, bool fromICMP = false);
IP_Packet(const u8* buffer, int bufferSize, bool fromICMP = false);
IP_Packet(const IP_Packet&);
IP_Payload* GetPayload();
IP_Payload* GetPayload() const;
virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset);
virtual IP_Packet* Clone() const;
bool VerifyChecksum();
static u16 InternetChecksum(u8* buffer, int length);
static u16 InternetChecksum(const u8* buffer, int length);
~IP_Packet();

View File

@@ -12,7 +12,7 @@ namespace PacketReader::IP
public: //Nedd GetProtocol
virtual int GetLength() = 0;
virtual void WriteBytes(u8* buffer, int* offset) = 0;
virtual u8 GetProtocol() = 0;
virtual u8 GetProtocol() const = 0;
virtual bool VerifyChecksum(IP_Address srcIP, IP_Address dstIP) { return false; }
virtual void CalculateChecksum(IP_Address srcIP, IP_Address dstIP) {}
virtual IP_Payload* Clone() const = 0;
@@ -25,23 +25,21 @@ namespace PacketReader::IP
std::unique_ptr<u8[]> data;
private:
int length;
u8 protocol;
const int length;
const u8 protocol;
public:
IP_PayloadData(int len, u8 prot)
: length{len}
, protocol{prot}
{
protocol = prot;
length = len;
if (len != 0)
data = std::make_unique<u8[]>(len);
}
IP_PayloadData(const IP_PayloadData& original)
: length{original.length}
, protocol{original.protocol}
{
protocol = original.protocol;
length = original.length;
if (length != 0)
{
data = std::make_unique<u8[]>(length);
@@ -60,7 +58,7 @@ namespace PacketReader::IP
memcpy(&buffer[*offset], data.get(), length);
*offset += length;
}
virtual u8 GetProtocol()
virtual u8 GetProtocol() const
{
return protocol;
}
@@ -74,18 +72,18 @@ namespace PacketReader::IP
class IP_PayloadPtr : public IP_Payload
{
public:
u8* data;
const u8* data;
private:
int length;
u8 protocol;
const int length;
const u8 protocol;
public:
IP_PayloadPtr(u8* ptr, int len, u8 prot)
IP_PayloadPtr(const u8* ptr, int len, u8 prot)
: data{ptr}
, length{len}
, protocol{prot}
{
data = ptr;
length = len;
protocol = prot;
}
IP_PayloadPtr(const IP_PayloadPtr&) = delete;
virtual int GetLength()
@@ -108,7 +106,7 @@ namespace PacketReader::IP
memcpy(ret->data.get(), data, length);
return ret;
}
virtual u8 GetProtocol()
virtual u8 GetProtocol() const
{
return protocol;
}

View File

@@ -10,12 +10,12 @@ namespace PacketReader::IP::TCP
: maxSegmentSize{mss}
{
}
TCPopMSS::TCPopMSS(u8* data, int offset)
TCPopMSS::TCPopMSS(const u8* data, int offset)
{
offset += 2;
NetLib::ReadUInt16(data, &offset, &maxSegmentSize);
}
void TCPopMSS::WriteBytes(u8* buffer, int* offset)
void TCPopMSS::WriteBytes(u8* buffer, int* offset) const
{
NetLib::WriteByte08(buffer, offset, GetCode());
NetLib::WriteByte08(buffer, offset, GetLength());
@@ -27,12 +27,12 @@ namespace PacketReader::IP::TCP
: windowScale{ws}
{
}
TCPopWS::TCPopWS(u8* data, int offset)
TCPopWS::TCPopWS(const u8* data, int offset)
{
offset += 2;
NetLib::ReadByte08(data, &offset, &windowScale);
}
void TCPopWS::WriteBytes(u8* buffer, int* offset)
void TCPopWS::WriteBytes(u8* buffer, int* offset) const
{
NetLib::WriteByte08(buffer, offset, GetCode());
NetLib::WriteByte08(buffer, offset, GetLength());
@@ -45,13 +45,13 @@ namespace PacketReader::IP::TCP
, echoTimeStamp{echoTS}
{
}
TCPopTS::TCPopTS(u8* data, int offset)
TCPopTS::TCPopTS(const u8* data, int offset)
{
offset += 2;
NetLib::ReadUInt32(data, &offset, &senderTimeStamp);
NetLib::ReadUInt32(data, &offset, &echoTimeStamp);
}
void TCPopTS::WriteBytes(u8* buffer, int* offset)
void TCPopTS::WriteBytes(u8* buffer, int* offset) const
{
NetLib::WriteByte08(buffer, offset, GetCode());
NetLib::WriteByte08(buffer, offset, GetLength());

View File

@@ -9,10 +9,10 @@ namespace PacketReader::IP::TCP
{
class TCPopNOP : public BaseOption
{
virtual u8 GetLength() { return 1; }
virtual u8 GetCode() { return 1; }
virtual u8 GetLength() const { return 1; }
virtual u8 GetCode() const { return 1; }
virtual void WriteBytes(u8* buffer, int* offset)
virtual void WriteBytes(u8* buffer, int* offset) const
{
buffer[*offset] = GetCode();
(*offset)++;
@@ -30,12 +30,12 @@ namespace PacketReader::IP::TCP
u16 maxSegmentSize;
TCPopMSS(u16 mss);
TCPopMSS(u8* data, int offset); //Offset will include Kind and Len
TCPopMSS(const u8* data, int offset); //Offset will include Kind and Len
virtual u8 GetLength() { return 4; }
virtual u8 GetCode() { return 2; }
virtual u8 GetLength() const { return 4; }
virtual u8 GetCode() const { return 2; }
virtual void WriteBytes(u8* buffer, int* offset);
virtual void WriteBytes(u8* buffer, int* offset) const;
virtual TCPopMSS* Clone() const
{
@@ -49,12 +49,12 @@ namespace PacketReader::IP::TCP
u8 windowScale;
TCPopWS(u8 ws);
TCPopWS(u8* data, int offset); //Offset will include Kind and Len
TCPopWS(const u8* data, int offset); //Offset will include Kind and Len
virtual u8 GetLength() { return 3; }
virtual u8 GetCode() { return 3; }
virtual u8 GetLength() const { return 3; }
virtual u8 GetCode() const { return 3; }
virtual void WriteBytes(u8* buffer, int* offset);
virtual void WriteBytes(u8* buffer, int* offset) const;
virtual TCPopWS* Clone() const
{
@@ -69,12 +69,12 @@ namespace PacketReader::IP::TCP
u32 echoTimeStamp;
TCPopTS(u32 senderTS, u32 echoTS);
TCPopTS(u8* data, int offset); //Offset will include Kind and Len
TCPopTS(const u8* data, int offset); //Offset will include Kind and Len
virtual u8 GetLength() { return 10; }
virtual u8 GetCode() { return 8; }
virtual u8 GetLength() const { return 10; }
virtual u8 GetCode() const { return 8; }
virtual void WriteBytes(u8* buffer, int* offset);
virtual void WriteBytes(u8* buffer, int* offset) const;
virtual TCPopTS* Clone() const
{

Some files were not shown because too many files have changed in this diff Show More