diff --git a/Libraries/CANAPI/uvcanpcb.rc b/Libraries/CANAPI/uvcanpcb.rc index 6fe6218..80ae685 100644 Binary files a/Libraries/CANAPI/uvcanpcb.rc and b/Libraries/CANAPI/uvcanpcb.rc differ diff --git a/Libraries/PeakCAN/PeakCAN.rc b/Libraries/PeakCAN/PeakCAN.rc index 8953218..f6f8c3a 100644 Binary files a/Libraries/PeakCAN/PeakCAN.rc and b/Libraries/PeakCAN/PeakCAN.rc differ diff --git a/README.md b/README.md index 421b315..29e2b4c 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ Type `can_test /?` to display all program options. ### Development Environment -- Microsoft Visual Studio Community 2022 (Version 17.10.1) +- Microsoft Visual Studio Community 2022 (Version 17.10.5) ### Required PCANBasic DLL diff --git a/Sources/CANAPI/CANAPI_Types.h b/Sources/CANAPI/CANAPI_Types.h index 1d09faf..c2f72e0 100644 --- a/Sources/CANAPI/CANAPI_Types.h +++ b/Sources/CANAPI/CANAPI_Types.h @@ -49,9 +49,9 @@ * * @brief CAN API V3 for generic CAN Interfaces - Data Types and Defines * - * @author $Author: quaoar $ + * @author $Author: makemake $ * - * @version $Rev: 1286 $ + * @version $Rev: 1356 $ * * @addtogroup can_api * @{ @@ -350,6 +350,19 @@ extern "C" { #define CANPROP_SET_FILTER_11BIT 42U /**< set value for acceptance filter code and mask for 11-bit identifier (uint64_t) */ #define CANPROP_SET_FILTER_29BIT 43U /**< set value for acceptance filter code and mask for 29-bit identifier (uint64_t) */ #define CANPROP_SET_FILTER_RESET 44U /**< reset acceptance filter code and mask to default values (NULL) */ +#define CANPROP_SET_FROMTO_11BIT 45U /**< add an 11-bit identifier range to the from-to filter list (uint64_t) */ +#define CANPROP_SET_FROMTO_29BIT 46U /**< add an 11-bit identifier range to the from-to filter list (uint64_t) */ +#define CANPROP_GET_TRACE_ACTIVE 48U /**< trace file activation state: STOPPED/RUNNING (uint8_t) */ +#define CANPROP_GET_TRACE_FOLDER 49U /**< trace file folder location (directory only) (char[]) */ +#define CANPROP_GET_TRACE_TYPE 50U /**< trace file type (for possible values see below) (uint8_t) */ +#define CANPROP_GET_TRACE_MODE 51U /**< trace file mode (for possible options see below) (uint16_t) */ +#define CANPROP_GET_TRACE_SIZE 52U /**< trace file segment size (in 10 KB steps, 0 = 100MB) (uint 16_t) */ +#define CANPROP_GET_TRACE_FILE 55U /**< trace file name: directory + basename + extension (char[]) */ +#define CANPROP_SET_TRACE_ACTIVE 56U /**< start/stop trace file logging with configured settings (uint8_t) */ +#define CANPROP_SET_TRACE_FOLDER 57U /**< set trace file folder location (directory only) (char[]) */ +#define CANPROP_SET_TRACE_TYPE 58U /**< set trace file type (for possible values see below) (uint8_t) */ +#define CANPROP_SET_TRACE_MODE 59U /**< set trace file mode (for possible options see below) (uint16_t) */ +#define CANPROP_SET_TRACE_SIZE 60U /**< set trace file segment size (in 10 KB steps, 0 = 100MB) (uint 16_t) */ #if (OPTION_CANAPI_LIBRARY != 0) /* - - build-in bit-rate conversion - - - - - - - - - - - - - - - - - */ #define CANPROP_GET_BTR_INDEX 64U /**< bit-rate as CiA index (int32_t) */ @@ -428,6 +441,26 @@ extern "C" { /** @name Property Values * @brief Values which can be used as property value (argument) * @{ */ +/* - - trace file - - - - - - - - - - - - - - - - - - - - - - - - - - */ +#define CANPARA_TRACE_OFF 0U /**< trace file activation: STOP */ +#define CANPARA_TRACE_ON 1U /**< trace file activation: START */ +/* - - trace file type - - - - - - - - - - - - - - - - - - - - - - - - */ +#define CANPARA_TRACE_TYPE_BINARY 0U /**< trace file: binary format */ +#define CANPARA_TRACE_TYPE_LOGGER 1U /**< trace file: CSV format */ +#define CANPARA_TRACE_TYPE_VENDOR 0x80U /**< trace file: vendor-specific */ +/* - - trace file mode - - - - - - - - - - - - - - - - - - - - - - - - */ +#define CANPARA_TRACE_MODE_DEFAULT 0x0000U /**< trace file: default (create/append) */ +#define CANPARA_TRACE_MODE_OVERWRITE 0x80U /**< trace file: overwrite existing */ +#define CANPARA_TRACE_MODE_SEGMENTED 0x01U /**< trace file: segmented trace file */ +#define CANPARA_TRACE_MODE_COMPRESSED 0x40U /**< trace file: compressed trace file */ +#define CANPARA_TRACE_MODE_PREFIX_DATE 0x02U /**< trace file: date as file name prefix */ +#define CANPARA_TRACE_MODE_PREFIX_TIME 0x04U /**< trace file: time as file name prefix */ +#define CANPARA_TRACE_MODE_OUTPUT_DLC 0x000U /**< trace file: length as Data Length Code */ +#define CANPARA_TRACE_MODE_OUTPUT_LEN 0x100U /**< trace file: length as LENGTH in bytes */ +#define CANPARA_TRACE_MODE_OUTPUT_HEX 0x000U /**< trace file: Id., length and data as HEX */ +#define CANPARA_TRACE_MODE_OUTPUT_DEC 0x200U /**< trace file: Id., length and data as DEC */ +#define CANPARA_TRACE_MODE_CUSTOM_NAME 0x8000U /**< trace file: use of custom file name (basename and extension) */ +/* - - message formatter - - - - - - - - - - - - - - - - - - - - - - - */ #define CANPARA_FORMAT_DEFAULT 0 /**< message formatter output (default) */ /* - - formatter option: ON or OFF - - - - - - - - - - - - - - - - - - */ #define CANPARA_OPTION_OFF 0 /**< formatter option: OFF (false, no, 0) */ diff --git a/Sources/CANAPI/README.md b/Sources/CANAPI/README.md index af72cb6..fa9440c 100644 --- a/Sources/CANAPI/README.md +++ b/Sources/CANAPI/README.md @@ -1,9 +1,9 @@ ### CAN Interface API, Version 3 -_Copyright © 2004-2024 Uwe Vogt, UV Software, Berlin (info@uv-software.com)_ \ +_Copyright © 2004-2024 Uwe Vogt, UV Software, Berlin (info@uv-software.com)_ \ _All rights reserved._ -Version $Rev: 1312 $ +Version $Rev: 1356 $ # A CAN Interface Wrapper Specification diff --git a/Sources/CANAPI/can_msg.h b/Sources/CANAPI/can_msg.h index badf12f..796d79f 100644 --- a/Sources/CANAPI/can_msg.h +++ b/Sources/CANAPI/can_msg.h @@ -49,9 +49,9 @@ * * @brief CAN Message Formatter * - * @author $Author: eris $ + * @author $Author: makemake $ * - * @version $Rev: 1270 $ + * @version $Rev: 1355 $ * * @defgroup can_msg CAN Message Formatter * @{ @@ -66,18 +66,21 @@ extern "C" { /* ----------- includes ----------------------------------------------- */ -#if (OPTION_CANAPI_COMPANIONS != 0) // set it in the build environment! -#include "CANAPI_Types.h" // use CAN API V3 types and defines -#else // otherwise: -#define CANBTR_STANDALONE_VARIANT // don't include CAN API V3 headers -#include // C99 header for sized integer types -#include // C99 header for boolean type -#include // time types for time-stamp +#if (OPTION_CANAPI_COMPANIONS != 0) /* set it in the build environment! */ +#include "CANAPI_Types.h" /* use CAN API V3 types and defines */ +#else /* otherwise: */ +#define CANMSG_STANDALONE_VARIANT /* don't include CAN API V3 headers */ +#include /* C99 header for sized integer types */ +#include /* C99 header for boolean type */ +#include /* for structure 'timespec' */ #endif /* ----------- options ------------------------------------------------ */ +/** @name Compiler Switches + * @brief Options for conditional compilation. + * @{ */ /** @note Set define OPTION_CANAPI_COMPANIONS to a non-zero value to compile * this module in conjunction with the CAN API V3 sources (e.g. in * the build environment). @@ -85,18 +88,22 @@ extern "C" { /** @note Set define OPTION_CAN_2_0_ONLY to a non-zero value to compile * with CAN 2.0 frame format only (e.g. in the build environment). */ -#if (OPTION_CAN_2_0_ONLY != 0) +#ifndef OPTION_DISABLED +#define OPTION_DISABLED 0 /**< if a define is not defined, it is automatically set to 0 */ +#endif +#if (OPTION_CAN_2_0_ONLY != OPTION_DISABLED) #ifdef _MSC_VER -#pragma message ( "Compilation with with legacy CAN 2.0 frame format!" ) +#pragma message ( "Compilation with legacy CAN 2.0 frame format!" ) #else -#warning Compilation with with legacy CAN 2.0 frame format! +#warning Compilation with legacy CAN 2.0 frame format! #endif #endif +/** @} */ /* ----------- defines ------------------------------------------------ */ -#ifdef CANBTR_STANDALONE_VARIANT +#ifdef CANMSG_STANDALONE_VARIANT /** @name CAN Identifier * @brief CAN Identifier range * @{ */ @@ -223,14 +230,14 @@ typedef enum msg_fmt_wraparound_t_ { /** @brief CAN Time-stamp: */ -#ifdef CANMSG_STANDALONE +#ifdef CANMSG_STANDALONE_VARIANT typedef struct timespec msg_timestamp_t; /* w/ nanoseconds resolution */ #else typedef can_timestamp_t msg_timestamp_t; /* CAN API V3 time-stamp */ #endif /** @brief CAN Message (with Time-stamp): */ -#ifdef CANMSG_STANDALONE +#ifdef CANMSG_STANDALONE_VARIANT typedef struct msg_message_t_ { uint32_t id; /**< CAN identifier */ struct { diff --git a/Sources/PeakCAN_Defines.h b/Sources/PeakCAN_Defines.h index 2098ecc..608c43e 100644 --- a/Sources/PeakCAN_Defines.h +++ b/Sources/PeakCAN_Defines.h @@ -171,7 +171,7 @@ extern "C" { #define PCAN_LIB_BASIC "libPCBUSB.dylib" #define PCAN_LIB_WRAPPER "libUVCANPCB.dylib" #define PCAN_LIB_MIN_MAJOR 0U - #define PCAN_LIB_MIN_MINOR 9U + #define PCAN_LIB_MIN_MINOR 13U #elif defined(__linux__) #define PCAN_LIB_BASIC "libpcanbasic.so" #define PCAN_LIB_WRAPPER "libuvcanpcb.so" diff --git a/Sources/Version.h b/Sources/Version.h index fef1865..6c88d6e 100644 --- a/Sources/Version.h +++ b/Sources/Version.h @@ -52,11 +52,11 @@ #ifdef _MSC_VER #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 1 +#define VERSION_PATCH 2 #else #define VERSION_MAJOR 0 -#define VERSION_MINOR 2 -#define VERSION_PATCH 9 +#define VERSION_MINOR 3 +#define VERSION_PATCH 0 #endif #define VERSION_BUILD BUILD_NO #if (VERSION_PATCH == 0) diff --git a/Sources/Wrapper/can_api.c b/Sources/Wrapper/can_api.c index 88abaa7..ff82857 100644 --- a/Sources/Wrapper/can_api.c +++ b/Sources/Wrapper/can_api.c @@ -1378,9 +1378,26 @@ static TPCANStatus pcan_reset_filter(int handle) assert(IS_HANDLE_VALID(handle)); // just to make sure +#if defined(__linux__) + UINT64 value = 0x0ull; // PCAN filter value + + // note: it seems that the hardware filter is not resetted by 'PCAN_MESSAGE_FILTER' := 'PCAN_FILTER_OPEN' + switch (can[handle].filter.mode) { + case FILTER_STD: // 11-bit identifier + value = (FILTER_RESET_VALUE ^ FILTER_STD_XOR_MASK); // SJA100 has inverted masks bits! + (void)CAN_SetValue(can[handle].board, PCAN_ACCEPTANCE_FILTER_11BIT, (void*)&value, sizeof(value)); + break; + case FILTER_XTD: // 29-bit identifier + value = (FILTER_RESET_VALUE ^ FILTER_XTD_XOR_MASK); // SJA100 has inverted masks bits! + (void)CAN_SetValue(can[handle].board, PCAN_ACCEPTANCE_FILTER_29BIT, (void*)&value, sizeof(value)); + break; + default: // no filtering + break; + } +#endif // reset the filter value to device if ((sts = CAN_SetValue(can[handle].board, (BYTE)PCAN_MESSAGE_FILTER, - (void*)&filter, (DWORD)sizeof(uint8_t))) == PCAN_ERROR_OK) { + (void*)&filter, (DWORD)sizeof(uint8_t))) == PCAN_ERROR_OK) { can[handle].filter.mode = FILTER_OFF; } return sts; @@ -1592,7 +1609,6 @@ static int drv_parameter(int handle, uint16_t param, void *value, size_t nbyte) can_mode_t mode; // current operation mode uint8_t status = 0u; // status register uint8_t load = 0u; // bus load - uint64_t filter = 0ull; // acceptance filter char str[MAX_LENGTH_HARDWARE_NAME+1]; // device name TPCANStatus sts; // represents a status diff --git a/Tests/Driver.h b/Tests/Driver.h index 9918d8d..7cc6816 100644 --- a/Tests/Driver.h +++ b/Tests/Driver.h @@ -63,18 +63,19 @@ typedef CPeakCAN CCanDriver; // ($4) define macros for driver-specific features // at least the mandatory macros (cf. compiler warnings) -#define FEATURE_BITRATE_5K FEATURE_UNSUPPORTED -#define FEATURE_BITRATE_800K FEATURE_SUPPORTED -#define FEATURE_BITRATE_SAM FEATURE_SUPPORTED -#define FEATURE_BITRATE_FD_SAM FEATURE_UNSUPPORTED -#define FEATURE_BITRATE_SJA1000 FEATURE_SUPPORTED -#define FEATURE_FILTERING FEATURE_SUPPORTED -#define FEATURE_ERROR_FRAMES FEATURE_SUPPORTED -#define FEATURE_ERROR_CODE_CAPTURE FEATURE_SUPPORTED -#define FEATURE_BLOCKING_READ FEATURE_SUPPORTED -#define FEATURE_BLOCKING_WRITE FEATURE_UNSUPPORTED -#define FEATURE_SIZE_RECEIVE_QUEUE 32767 -#define FEATURE_SIZE_TRANSMIT_QUEUE 32767 +#define FEATURE_BITRATE_5K FEATURE_UNSUPPORTED +#define FEATURE_BITRATE_800K FEATURE_SUPPORTED +#define FEATURE_BITRATE_SAM FEATURE_SUPPORTED +#define FEATURE_BITRATE_FD_SAM FEATURE_UNSUPPORTED +#define FEATURE_BITRATE_SJA1000 FEATURE_SUPPORTED +#define FEATURE_FILTERING FEATURE_SUPPORTED +#define FEATURE_TRACE_FILE FEATURE_UNSUPPORTED +#define FEATURE_ERROR_FRAMES FEATURE_SUPPORTED +#define FEATURE_ERROR_CODE_CAPTURE FEATURE_SUPPORTED +#define FEATURE_BLOCKING_READ FEATURE_SUPPORTED +#define FEATURE_BLOCKING_WRITE FEATURE_UNSUPPORTED +#define FEATURE_SIZE_RECEIVE_QUEUE 32767 +#define FEATURE_SIZE_TRANSMIT_QUEUE 32767 // (§5) define macros for CAN Classic bit-rate settings // at least BITRATE_1M, BITRATE_500K, BITRATE_250K, BITRATE_125K, diff --git a/Tests/GoogleTest/CONTRIBUTORS b/Tests/GoogleTest/CONTRIBUTORS index 77397a5..ccea41e 100644 --- a/Tests/GoogleTest/CONTRIBUTORS +++ b/Tests/GoogleTest/CONTRIBUTORS @@ -55,6 +55,7 @@ Russ Cox Russ Rufer Sean Mcafee Sigurður Ásgeirsson +Soyeon Kim Sverre Sundsdal Szymon Sobik Takeshi Yoshino diff --git a/Tests/GoogleTest/README.md b/Tests/GoogleTest/README.md index 443e020..f50c670 100644 --- a/Tests/GoogleTest/README.md +++ b/Tests/GoogleTest/README.md @@ -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 diff --git a/Tests/GoogleTest/README.txt b/Tests/GoogleTest/README.txt index 326a8a5..f2e1623 100644 --- a/Tests/GoogleTest/README.txt +++ b/Tests/GoogleTest/README.txt @@ -13,15 +13,15 @@ URL: https://github.com/google/googletest Current Version used by CAN API V3 C++ Testing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -v1.14.0 (https://github.com/google/googletest/releases/tag/v1.14.0) +v1.14.0 (https://github.com/google/googletest/releases/tag/v1.15.0) Installation and Usage of GoogleTest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Clone the GoogleTest main branch or download the sources from a tag e.g. into 'C:\Projekte\gtest' -2. Copy all header files from 'C:\Projekte\gtest\googletest\include' - into '$(PROJROOT)\Tests\GoogleTest\include' -3. Build static libraries for x64_x84 and x86_x64 with CMake +2. Copy all header files from 'C:\Projekte\gtest\googletest\include\gtest' + into '$(PROJROOT)\Tests\GoogleTest\include\gtest' +3. Build static libraries for x64 and x86 with CMake note: GoogleMock (aka gmock) does not need to be created for this project. 4. Copy all files from 'C:\Projekte\gtest\googletest\out\build\x64-Debug\lib' into $(PROJROOT)\Tests\GoogleTest\build\x64-Debug\lib' @@ -35,4 +35,4 @@ Important Notes Last Updated ~~~~~~~~~~~~ -August 23, 2023 +August 17, 2024 diff --git a/Tests/GoogleTest/build/x64-Debug/lib/gtest.lib b/Tests/GoogleTest/Windows/x64-Debug/lib/gtest.lib similarity index 57% rename from Tests/GoogleTest/build/x64-Debug/lib/gtest.lib rename to Tests/GoogleTest/Windows/x64-Debug/lib/gtest.lib index ca07f2b..f506607 100644 Binary files a/Tests/GoogleTest/build/x64-Debug/lib/gtest.lib and b/Tests/GoogleTest/Windows/x64-Debug/lib/gtest.lib differ diff --git a/Tests/GoogleTest/Windows/x64-Debug/lib/gtest_main.lib b/Tests/GoogleTest/Windows/x64-Debug/lib/gtest_main.lib new file mode 100644 index 0000000..45cb9ab Binary files /dev/null and b/Tests/GoogleTest/Windows/x64-Debug/lib/gtest_main.lib differ diff --git a/Tests/GoogleTest/Windows/x64-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/Windows/x64-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb new file mode 100644 index 0000000..cad960c Binary files /dev/null and b/Tests/GoogleTest/Windows/x64-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb differ diff --git a/Tests/GoogleTest/Windows/x64-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/Windows/x64-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb new file mode 100644 index 0000000..0f98b74 Binary files /dev/null and b/Tests/GoogleTest/Windows/x64-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb differ diff --git a/Tests/GoogleTest/build/x86-Debug/lib/gtest.lib b/Tests/GoogleTest/Windows/x86-Debug/lib/gtest.lib similarity index 50% rename from Tests/GoogleTest/build/x86-Debug/lib/gtest.lib rename to Tests/GoogleTest/Windows/x86-Debug/lib/gtest.lib index 50aa597..9845092 100644 Binary files a/Tests/GoogleTest/build/x86-Debug/lib/gtest.lib and b/Tests/GoogleTest/Windows/x86-Debug/lib/gtest.lib differ diff --git a/Tests/GoogleTest/Windows/x86-Debug/lib/gtest_main.lib b/Tests/GoogleTest/Windows/x86-Debug/lib/gtest_main.lib new file mode 100644 index 0000000..652d049 Binary files /dev/null and b/Tests/GoogleTest/Windows/x86-Debug/lib/gtest_main.lib differ diff --git a/Tests/GoogleTest/Windows/x86-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/Windows/x86-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb new file mode 100644 index 0000000..4cc1520 Binary files /dev/null and b/Tests/GoogleTest/Windows/x86-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb differ diff --git a/Tests/GoogleTest/Windows/x86-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/Windows/x86-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb new file mode 100644 index 0000000..567e0f9 Binary files /dev/null and b/Tests/GoogleTest/Windows/x86-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb differ diff --git a/Tests/GoogleTest/build/x64-Debug/lib/gtest_main.lib b/Tests/GoogleTest/build/x64-Debug/lib/gtest_main.lib deleted file mode 100644 index 6e46986..0000000 Binary files a/Tests/GoogleTest/build/x64-Debug/lib/gtest_main.lib and /dev/null differ diff --git a/Tests/GoogleTest/build/x64-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/build/x64-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb deleted file mode 100644 index bcd6958..0000000 Binary files a/Tests/GoogleTest/build/x64-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb and /dev/null differ diff --git a/Tests/GoogleTest/build/x64-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/build/x64-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb deleted file mode 100644 index c9e6bff..0000000 Binary files a/Tests/GoogleTest/build/x64-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb and /dev/null differ diff --git a/Tests/GoogleTest/build/x86-Debug/lib/gtest_main.lib b/Tests/GoogleTest/build/x86-Debug/lib/gtest_main.lib deleted file mode 100644 index 881d618..0000000 Binary files a/Tests/GoogleTest/build/x86-Debug/lib/gtest_main.lib and /dev/null differ diff --git a/Tests/GoogleTest/build/x86-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/build/x86-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb deleted file mode 100644 index f672b28..0000000 Binary files a/Tests/GoogleTest/build/x86-Debug/lib/gtest_mainpdb_debug_postfix-NOTFOUND.pdb and /dev/null differ diff --git a/Tests/GoogleTest/build/x86-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb b/Tests/GoogleTest/build/x86-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb deleted file mode 100644 index 5733dcf..0000000 Binary files a/Tests/GoogleTest/build/x86-Debug/lib/gtestpdb_debug_postfix-NOTFOUND.pdb and /dev/null differ diff --git a/Tests/GoogleTest/include/gtest/gtest-assertion-result.h b/Tests/GoogleTest/include/gtest/gtest-assertion-result.h index 56fe128..74eb2b1 100644 --- a/Tests/GoogleTest/include/gtest/gtest-assertion-result.h +++ b/Tests/GoogleTest/include/gtest/gtest-assertion-result.h @@ -129,7 +129,7 @@ namespace testing { // // Expected: Foo() is even // Actual: it's 5 -// + class GTEST_API_ AssertionResult { public: // Copy constructor. diff --git a/Tests/GoogleTest/include/gtest/gtest-death-test.h b/Tests/GoogleTest/include/gtest/gtest-death-test.h index 08fef8c..3c61909 100644 --- a/Tests/GoogleTest/include/gtest/gtest-death-test.h +++ b/Tests/GoogleTest/include/gtest/gtest-death-test.h @@ -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 \ diff --git a/Tests/GoogleTest/include/gtest/gtest-message.h b/Tests/GoogleTest/include/gtest/gtest-message.h index 59b805e..448ac6b 100644 --- a/Tests/GoogleTest/include/gtest/gtest-message.h +++ b/Tests/GoogleTest/include/gtest/gtest-message.h @@ -59,7 +59,7 @@ #ifdef GTEST_HAS_ABSL #include -#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 ::value, // NOLINT - int>::type = 0 + , + typename std::enable_if::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 ::value, // NOLINT - int>::type = 0> + typename std::enable_if::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 diff --git a/Tests/GoogleTest/include/gtest/gtest-param-test.h b/Tests/GoogleTest/include/gtest/gtest-param-test.h index 49a47ea..55ee088 100644 --- a/Tests/GoogleTest/include/gtest/gtest-param-test.h +++ b/Tests/GoogleTest/include/gtest/gtest-param-test.h @@ -178,7 +178,7 @@ TEST_P(DerivedTest, DoesBlah) { #include #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 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 ConvertGenerator( ::testing::internal::DefaultParamName, \ 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( \ diff --git a/Tests/GoogleTest/include/gtest/gtest-printers.h b/Tests/GoogleTest/include/gtest/gtest-printers.h index d1766e6..b2822bc 100644 --- a/Tests/GoogleTest/include/gtest/gtest-printers.h +++ b/Tests/GoogleTest/include/gtest/gtest-printers.h @@ -116,12 +116,16 @@ #include #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 // 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 void UniversalPrint(const T& value, ::std::ostream* os); +template +struct IsStdSpan { + static constexpr bool value = false; +}; + +#if GTEST_INTERNAL_HAS_STD_SPAN +template +struct IsStdSpan> { + 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 (0)) == sizeof(IsContainer)) && - !IsRecursiveContainer::value>::type> + ((sizeof(IsContainerTest(0)) == sizeof(IsContainer)) && + !IsRecursiveContainer::value) || + IsStdSpan::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::value>::type> // NOLINT + template ::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::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(100000.0)) { // 100,000 to 999,999 mulfor6 = 1.0; - } else if (val >= 10000.0) { + } else if (val >= static_cast(10000.0)) { mulfor6 = 1e1; - } else if (val >= 1000.0) { + } else if (val >= static_cast(1000.0)) { mulfor6 = 1e2; - } else if (val >= 100.0) { + } else if (val >= static_cast(100.0)) { mulfor6 = 1e3; - } else if (val >= 10.0) { + } else if (val >= static_cast(10.0)) { mulfor6 = 1e4; - } else if (val >= 1.0) { + } else if (val >= static_cast(1.0)) { mulfor6 = 1e5; - } else if (val >= 0.1) { + } else if (val >= static_cast(0.1)) { mulfor6 = 1e6; - } else if (val >= 0.01) { + } else if (val >= static_cast(0.01)) { mulfor6 = 1e7; - } else if (val >= 0.001) { + } else if (val >= static_cast(0.001)) { mulfor6 = 1e8; - } else if (val >= 0.0001) { + } else if (val >= static_cast(0.0001)) { mulfor6 = 1e9; } - if (static_cast(static_cast(val * mulfor6 + 0.5)) / + if (static_cast(static_cast( + val * mulfor6 + (static_cast(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(1e10)) { + FloatType divfor6 = static_cast(1.0); + if (val >= static_cast(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(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(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(1e6)) { // 1,000,000 to 9,999,999 divfor6 = 10; } - if (static_cast(static_cast(val / divfor6 + 0.5)) * + if (static_cast(static_cast( + val / divfor6 + (static_cast(0.5)))) * divfor6 == val) return 6; } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif return full; } diff --git a/Tests/GoogleTest/include/gtest/gtest-typed-test.h b/Tests/GoogleTest/include/gtest/gtest-typed-test.h index 72de536..305b0b5 100644 --- a/Tests/GoogleTest/include/gtest/gtest-typed-test.h +++ b/Tests/GoogleTest/include/gtest/gtest-typed-test.h @@ -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 \ - class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ - : public CaseName { \ - private: \ - typedef CaseName 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_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 \ - 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 \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName 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_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 \ + void GTEST_TEST_CLASS_NAME_(CaseName, \ TestName)::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 \ - class TestName : public SuiteName { \ - private: \ - typedef SuiteName 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 \ - void GTEST_SUITE_NAMESPACE_( \ +#define TYPED_TEST_P(SuiteName, TestName) \ + namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ + template \ + class TestName : public SuiteName { \ + private: \ + typedef SuiteName 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 \ + void GTEST_SUITE_NAMESPACE_( \ SuiteName)::TestName::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::type>:: \ - Register(GTEST_STRINGIFY_(Prefix), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), \ - >EST_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::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::type>:: \ + Register( \ + GTEST_STRINGIFY_(Prefix), \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_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::type>()) // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ diff --git a/Tests/GoogleTest/include/gtest/gtest.h b/Tests/GoogleTest/include/gtest/gtest.h index de7d528..c899669 100644 --- a/Tests/GoogleTest/include/gtest/gtest.h +++ b/Tests/GoogleTest/include/gtest/gtest.h @@ -51,7 +51,6 @@ #include #include -#include #include #include #include @@ -61,16 +60,16 @@ #include #include -#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::digits10 + 2) - << lhs_value; + lhs_ss.precision(std::numeric_limits::digits10 + 2); + lhs_ss << lhs_value; ::std::stringstream rhs_ss; - rhs_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << rhs_value; + rhs_ss.precision(std::numeric_limits::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 {}; // 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. diff --git a/Tests/GoogleTest/include/gtest/internal/gtest-death-test-internal.h b/Tests/GoogleTest/include/gtest/internal/gtest-death-test-internal.h index 8e9c988..b363259 100644 --- a/Tests/GoogleTest/include/gtest/internal/gtest-death-test-internal.h +++ b/Tests/GoogleTest/include/gtest/internal/gtest-death-test-internal.h @@ -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 MakeDeathTestMatcher( + ::testing::internal::RE regex) { + return ContainsRegex(regex.pattern()); +} +inline Matcher MakeDeathTestMatcher(const char* regex) { + return ContainsRegex(regex); +} +inline Matcher MakeDeathTestMatcher( + const ::std::string& regex) { + return ContainsRegex(regex); +} + +// If a Matcher is passed to EXPECT_DEATH (etc.), it's +// used directly. +inline Matcher MakeDeathTestMatcher( + Matcher 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 MakeDeathTestMatcher( - ::testing::internal::RE regex) { - return ContainsRegex(regex.pattern()); -} -inline Matcher MakeDeathTestMatcher(const char* regex) { - return ContainsRegex(regex); -} -inline Matcher MakeDeathTestMatcher( - const ::std::string& regex) { - return ContainsRegex(regex); -} - -// If a Matcher is passed to EXPECT_DEATH (etc.), it's -// used directly. -inline Matcher MakeDeathTestMatcher( - Matcher 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 diff --git a/Tests/GoogleTest/include/gtest/internal/gtest-filepath.h b/Tests/GoogleTest/include/gtest/internal/gtest-filepath.h index 5189c81..6dc47be 100644 --- a/Tests/GoogleTest/include/gtest/internal/gtest-filepath.h +++ b/Tests/GoogleTest/include/gtest/internal/gtest-filepath.h @@ -43,6 +43,7 @@ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #include +#include #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_; } diff --git a/Tests/GoogleTest/include/gtest/internal/gtest-internal.h b/Tests/GoogleTest/include/gtest/internal/gtest-internal.h index a04a920..7e55dc6 100644 --- a/Tests/GoogleTest/include/gtest/internal/gtest-internal.h +++ b/Tests/GoogleTest/include/gtest/internal/gtest-internal.h @@ -58,7 +58,6 @@ #include #include -#include #include #include #include @@ -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 CalculateOptimalEdits( const std::vector& left, const std::vector& 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& type_names = GenerateNames()) { @@ -713,8 +711,7 @@ class TypeParameterizedTest { // list. MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + - "/" + type_names[static_cast(index)]) - .c_str(), + "/" + type_names[static_cast(index)]), StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), GetTypeName().c_str(), nullptr, // No value parameter. @@ -726,13 +723,9 @@ class TypeParameterizedTest { new TestFactoryImpl); // Next, recurses (at compile time) with the tail of the type list. - return TypeParameterizedTest::Register(prefix, - code_location, - case_name, - test_names, - index + 1, - type_names); + return TypeParameterizedTest:: + Register(prefix, std::move(code_location), case_name, test_names, + index + 1, type_names); } }; @@ -740,7 +733,7 @@ class TypeParameterizedTest { template class TypeParameterizedTest { 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& = @@ -787,7 +780,8 @@ class TypeParameterizedTestSuite { // Next, recurses (at compile time) with the tail of the test list. return TypeParameterizedTestSuite::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 -struct IndexSequence { - using type = IndexSequence; -}; - -// Double the IndexSequence, and one if plus_one is true. -template -struct DoubleSequence; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; - -// Backport of std::make_index_sequence. -// It uses O(ln(N)) instantiation depth. -template -struct MakeIndexSequenceImpl - : DoubleSequence::type, - N / 2>::type {}; - -template <> -struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; - -template -using MakeIndexSequence = typename MakeIndexSequenceImpl::type; - -template -using IndexSequenceFor = typename MakeIndexSequence::type; - template struct Ignore { Ignore(...); // NOLINT @@ -1185,7 +1145,7 @@ struct Ignore { template struct ElemFromListImpl; template -struct ElemFromListImpl> { +struct ElemFromListImpl> { // 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> { template struct ElemFromList { - using type = - decltype(ElemFromListImpl::type>::Apply( - static_cast(nullptr)...)); + using type = decltype(ElemFromListImpl>::Apply( + static_cast(nullptr)...)); }; struct FlatTupleConstructTag {}; @@ -1223,9 +1182,9 @@ template struct FlatTupleBase; template -struct FlatTupleBase, IndexSequence> +struct FlatTupleBase, std::index_sequence> : FlatTupleElemBase, Idx>... { - using Indices = IndexSequence; + using Indices = std::index_sequence; FlatTupleBase() = default; template explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args) @@ -1260,14 +1219,15 @@ struct FlatTupleBase, IndexSequence> // 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 class FlatTuple : private FlatTupleBase, - typename MakeIndexSequence::type> { - using Indices = typename FlatTupleBase< - FlatTuple, typename MakeIndexSequence::type>::Indices; + std::make_index_sequence> { + using Indices = + typename FlatTupleBase, + std::make_index_sequence>::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, \ diff --git a/Tests/GoogleTest/include/gtest/internal/gtest-param-util.h b/Tests/GoogleTest/include/gtest/internal/gtest-param-util.h index 6a81c37..cc7ea53 100644 --- a/Tests/GoogleTest/include/gtest/internal/gtest-param-util.h +++ b/Tests/GoogleTest/include/gtest/internal/gtest-param-util.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -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 class ParamGeneratorInterface; @@ -379,9 +380,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { // integer test parameter index. template std::string DefaultParamName(const TestParamInfo& info) { - Message name_stream; - name_stream << info.index; - return name_stream.GetString(); + return std::to_string(info.index); } template @@ -513,9 +512,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { typedef ParamGenerator(GeneratorCreationFunc)(); using ParamNameGeneratorFunc = std::string(const TestParamInfo&); - 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* meta_factory, CodeLocation code_location) { - tests_.push_back(std::shared_ptr(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 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 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_suite_name; + std::string test_name; + for (const std::shared_ptr& test_info : tests_) { + for (const InstantiationInfo& instantiation : instantiations_) { + const std::string& instantiation_name = instantiation.name; + ParamGenerator generator((*instantiation.generator)()); + ParamNameGeneratorFunc* name_func = instantiation.name_func; + const char* file = instantiation.file; + int line = instantiation.line; + 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 test_param_names; - for (typename ParamGenerator::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(*param_it, i)); + name_func(TestParamInfo(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::GetSetUpCaseOrSuite(file, line), SuiteApiResolver::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* 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> test_meta_factory; const CodeLocation code_location; @@ -637,11 +637,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { // 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 ParameterizedTestSuiteInfo* GetTestSuitePatternHolder( - const char* test_suite_name, CodeLocation code_location) { + std::string test_suite_name, CodeLocation code_location) { ParameterizedTestSuiteInfo* 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()) { - // 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>(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()) { + // 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>( + test_suite_info); } } if (typed_test_info == nullptr) { typed_test_info = new ParameterizedTestSuiteInfo( - 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 ParameterizedTestCaseInfo* GetTestCasePatternHolder( - const char* test_case_name, CodeLocation code_location) { - return GetTestSuitePatternHolder(test_case_name, code_location); + std::string test_case_name, CodeLocation code_location) { + return GetTestSuitePatternHolder(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; TestSuiteInfoContainer test_suite_infos_; + ::std::unordered_map 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 operator ParamGenerator() const { // NOLINT - return ValuesIn(MakeVector(MakeIndexSequence())); + return ValuesIn(MakeVector(std::make_index_sequence())); } private: template - std::vector MakeVector(IndexSequence) const { + std::vector MakeVector(std::index_sequence) const { return std::vector{static_cast(v_.template Get())...}; } @@ -838,7 +842,7 @@ class CartesianProductGenerator template class IteratorImpl; template - class IteratorImpl> + class IteratorImpl> : public ParamIteratorInterface { public: IteratorImpl(const ParamGeneratorInterface* base, @@ -929,7 +933,7 @@ class CartesianProductGenerator std::shared_ptr current_value_; }; - using Iterator = IteratorImpl::type>; + using Iterator = IteratorImpl>; std::tuple...> generators_; }; diff --git a/Tests/GoogleTest/include/gtest/internal/gtest-port-arch.h b/Tests/GoogleTest/include/gtest/internal/gtest-port-arch.h index 3162f2b..7ec968f 100644 --- a/Tests/GoogleTest/include/gtest/internal/gtest-port-arch.h +++ b/Tests/GoogleTest/include/gtest/internal/gtest-port-arch.h @@ -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. diff --git a/Tests/GoogleTest/include/gtest/internal/gtest-port.h b/Tests/GoogleTest/include/gtest/internal/gtest-port.h index b887e24..8d27c2c 100644 --- a/Tests/GoogleTest/include/gtest/internal/gtest-port.h +++ b/Tests/GoogleTest/include/gtest/internal/gtest-port.h @@ -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 // specializations. Always defined to 0 or 1. +// GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter +// specializations. Always defined to 0 or 1 // GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher or // Matcher // 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()) +#include // C++20 and later +#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE()) +#include // Pre-C++20 +#endif + #include // for isspace, etc #include // for ptrdiff_t #include @@ -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(_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(>EST_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() && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \ - (!defined(_MSC_VER) || GTEST_HAS_RTTI) +#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE() && \ + 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() && 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() && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L +#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE() && \ + 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() && 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() && \ + 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() && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L +#if defined(__cpp_lib_string_view) || \ + (GTEST_INTERNAL_HAS_INCLUDE() && \ + 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() && 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; } // namespace internal } // namespace testing #else -#ifdef __has_include -#if __has_include() && GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L +#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE() && \ + 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; } // namespace internal } // namespace testing // The case where absl is configured NOT to alias std::variant is not supported. -#endif // __has_include() && 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 diff --git a/Tests/GoogleTest/include/gtest/internal/gtest-type-util.h b/Tests/GoogleTest/include/gtest/internal/gtest-type-util.h index f94cf61..78da053 100644 --- a/Tests/GoogleTest/include/gtest/internal/gtest-type-util.h +++ b/Tests/GoogleTest/include/gtest/internal/gtest-type-util.h @@ -71,7 +71,7 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) { // Strip redundant spaces in typename to match MSVC // For example, std::pair -> std::pair 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; } diff --git a/Tests/Testcases/TC00_SmokeTest.cc b/Tests/Testcases/TC00_SmokeTest.cc index 4e0b0a5..5009e68 100644 --- a/Tests/Testcases/TC00_SmokeTest.cc +++ b/Tests/Testcases/TC00_SmokeTest.cc @@ -240,7 +240,10 @@ TEST_F(SmokeTest, DefaultScenario) { CCanApi::EChannelState state; CANAPI_Status_t status = {}; CANAPI_Return_t retVal; - +#if (FEATURE_TRACE_FILE == FEATURE_SUPPORTED) + uint8_t trace = CANPARA_TRACE_ON; + char traceFile[CANPROP_MAX_STRING_LENGTH+1] = ""; +#endif // @pre: // @- show test configuration dut1.ShowDeviceInformation("[ DUT1 ]"); @@ -279,6 +282,20 @@ TEST_F(SmokeTest, DefaultScenario) { retVal = dut1.GetStatus(status); EXPECT_EQ(CCanApi::NoError, retVal); EXPECT_FALSE(status.can_stopped); +#if (FEATURE_TRACE_FILE == FEATURE_SUPPORTED) + // @- open trace file for DUT1 (if supported) + trace = CANPARA_TRACE_TYPE_BINARY; // TODO: format from command line + retVal = dut1.SetProperty(CANPROP_SET_TRACE_TYPE, (void*)&trace, sizeof(trace)); + EXPECT_EQ(CCanApi::NoError, retVal); + trace = CANPARA_TRACE_ON; + retVal = dut1.SetProperty(CANPROP_SET_TRACE_ACTIVE, (void*)&trace, sizeof(trace)); + EXPECT_EQ(CCanApi::NoError, retVal); + // @- check if trace file is open + trace = CANPARA_TRACE_OFF; + retVal = dut1.GetProperty(CANPROP_GET_TRACE_ACTIVE, (void*)&trace, sizeof(trace)); + EXPECT_EQ(CCanApi::NoError, retVal); + EXPECT_EQ(CANPARA_TRACE_ON, trace); +#endif // @- send some frames to DUT2 and receive some frames from DUT2 int32_t frames = g_Options.GetNumberOfSmokeTestFrames(); EXPECT_EQ(frames, dut1.SendSomeFrames(dut2, frames)); @@ -287,6 +304,24 @@ TEST_F(SmokeTest, DefaultScenario) { retVal = dut1.GetStatus(status); EXPECT_EQ(CCanApi::NoError, retVal); EXPECT_FALSE(status.can_stopped); +#if (FEATURE_TRACE_FILE == FEATURE_SUPPORTED) + // @- show file name of trace file written + if (CANPARA_TRACE_ON == trace) { + if (dut1.GetProperty(CANPROP_GET_TRACE_FILE, (void*)traceFile, CANPROP_MAX_STRING_LENGTH) == CCanApi::NoError) { + traceFile[CANPROP_MAX_STRING_LENGTH] = '\0'; + std::cout << "[ FILE ] " << traceFile << std::endl; + } + } + // @- close trace file for DUT1 + trace = CANPARA_TRACE_OFF; + retVal = dut1.SetProperty(CANPROP_SET_TRACE_ACTIVE, (void*)&trace, sizeof(trace)); + EXPECT_EQ(CCanApi::NoError, retVal); + // @- check if trace file is closed + trace = CANPARA_TRACE_ON; + retVal = dut1.GetProperty(CANPROP_GET_TRACE_ACTIVE, (void*)&trace, sizeof(trace)); + EXPECT_EQ(CCanApi::NoError, retVal); + EXPECT_EQ(CANPARA_TRACE_OFF, trace); +#endif // @- stop/reset DUT1 retVal = dut1.ResetController(); EXPECT_EQ(CCanApi::NoError, retVal); @@ -300,4 +335,4 @@ TEST_F(SmokeTest, DefaultScenario) { // @end. } -// $Id: TC00_SmokeTest.cc 1272 2024-04-16 19:55:27Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TC00_SmokeTest.cc 1357 2024-07-14 17:33:37Z makemake $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC23_SetFilter11Bit.cc b/Tests/Testcases/TC23_SetFilter11Bit.cc index a15ea92..6e39d6f 100644 --- a/Tests/Testcases/TC23_SetFilter11Bit.cc +++ b/Tests/Testcases/TC23_SetFilter11Bit.cc @@ -196,7 +196,12 @@ TEST_F(SetFilter11Bit, GTEST_TESTCASE(SunnydayScenario, GTEST_SUNNYDAY)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter11Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC23_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -336,7 +341,12 @@ TEST_F(SetFilter11Bit, GTEST_TESTCASE(IfControllerNotStarted, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter11Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC23_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -497,7 +507,12 @@ TEST_F(SetFilter11Bit, GTEST_TESTCASE(IfControllerStopped, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter11Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC23_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -637,7 +652,12 @@ TEST_F(SetFilter11Bit, GTEST_TESTCASE(WithValidValues, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter11Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC23_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet[i], codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet[i] & maskSet[j], codeGet); +#endif EXPECT_EQ(maskSet[j], maskGet); // @-- start DUT1 with configured bit-rate settings retVal = dut1.StartController(); @@ -769,4 +789,4 @@ TEST_F(SetFilter11Bit, GTEST_TESTCASE(WithInvalidValues, GTEST_ENABLED)) { #endif // FEATURE_FILTERING != FEATURE_UNSUPPORTED -// $Id: TC23_SetFilter11Bit.cc 1272 2024-04-16 19:55:27Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TC23_SetFilter11Bit.cc 1373 2024-07-31 18:55:39Z gonggong $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC25_SetFilter29Bit.cc b/Tests/Testcases/TC25_SetFilter29Bit.cc index fcf9ff7..2b2975f 100644 --- a/Tests/Testcases/TC25_SetFilter29Bit.cc +++ b/Tests/Testcases/TC25_SetFilter29Bit.cc @@ -196,7 +196,12 @@ TEST_F(SetFilter29Bit, GTEST_TESTCASE(SunnydayScenario, GTEST_SUNNYDAY)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter29Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC25_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -337,7 +342,12 @@ TEST_F(SetFilter29Bit, GTEST_TESTCASE(IfControllerNotStarted, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter29Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC25_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -498,7 +508,12 @@ TEST_F(SetFilter29Bit, GTEST_TESTCASE(IfControllerStopped, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter29Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC25_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -638,7 +653,12 @@ TEST_F(SetFilter29Bit, GTEST_TESTCASE(WithValidValues, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter29Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC25_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet[i], codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet[i] & maskSet[j], codeGet); +#endif EXPECT_EQ(maskSet[j], maskGet); // @-- start DUT1 with configured bit-rate settings retVal = dut1.StartController(); @@ -838,4 +858,4 @@ TEST_F(SetFilter29Bit, GTEST_TESTCASE(IfXtdFramesSuppressed, GTEST_ENABLED)) { #endif // FEATURE_FILTERING != FEATURE_UNSUPPORTED -// $Id: TC25_SetFilter29Bit.cc 1272 2024-04-16 19:55:27Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TC25_SetFilter29Bit.cc 1373 2024-07-31 18:55:39Z gonggong $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Testcases/TC27_ResetFilter.cc b/Tests/Testcases/TC27_ResetFilter.cc index bed5e87..f2c30a3 100644 --- a/Tests/Testcases/TC27_ResetFilter.cc +++ b/Tests/Testcases/TC27_ResetFilter.cc @@ -112,7 +112,12 @@ TEST_F(ResetFilter, GTEST_TESTCASE(SunnydayScenario, GTEST_SUNNYDAY)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter11Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC27_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -139,8 +144,13 @@ TEST_F(ResetFilter, GTEST_TESTCASE(SunnydayScenario, GTEST_SUNNYDAY)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter29Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC27_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); - EXPECT_EQ(maskGet, maskGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif + EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! retVal = dut1.ResetFilters(); @@ -270,7 +280,12 @@ TEST_F(ResetFilter, GTEST_TESTCASE(IfControllerNotStarted, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter11Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC27_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -297,7 +312,12 @@ TEST_F(ResetFilter, GTEST_TESTCASE(IfControllerNotStarted, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter29Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC27_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -478,7 +498,12 @@ TEST_F(ResetFilter, GTEST_TESTCASE(IfControllerStopped, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter11Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC27_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -505,7 +530,12 @@ TEST_F(ResetFilter, GTEST_TESTCASE(IfControllerStopped, GTEST_ENABLED)) { codeGet = 0xFFFFFFFFU; maskGet = 0xFFFFFFFFU; retVal = dut1.GetFilter29Bit(codeGet, maskGet); EXPECT_EQ(CCanApi::NoError, retVal); +#if (TC27_X_ISSUE_PCBUSB_FILTER_CODE != WORKAROUND_ENABLED) EXPECT_EQ(codeSet, codeGet); +#else + // @ issue(PCBUSB): code is bit-wise ANDed with mask (Linux) + EXPECT_EQ(codeSet & maskSet, codeGet); +#endif EXPECT_EQ(maskGet, maskGet); // @- reset acceptance filter // @ note: SJA100 has only one filter for 11-bit and 29-bit identifier! @@ -598,4 +628,4 @@ TEST_F(ResetFilter, GTEST_TESTCASE(IfChannelTornDown, GTEST_ENABLED)) { #endif // FEATURE_FILTERING != FEATURE_UNSUPPORTED -// $Id: TC27_ResetFilter.cc 1272 2024-04-16 19:55:27Z makemake $ Copyright (c) UV Software, Berlin. +// $Id: TC27_ResetFilter.cc 1373 2024-07-31 18:55:39Z gonggong $ Copyright (c) UV Software, Berlin. diff --git a/Tests/Version.h b/Tests/Version.h index 1305776..fb3e648 100644 --- a/Tests/Version.h +++ b/Tests/Version.h @@ -47,8 +47,8 @@ // #ifndef VERSION_H_INCLUDED #define VERSION_H_INCLUDED -// SVN revision number (update with each commit: XXIV) -#define REVISION_NO "$Rev: 1336 $" +// SVN revision number (update with each commit: XXVII) +#define REVISION_NO "$Rev: 1373 $" #endif // VERSION_H_INCLUDED -// $Id: Version.h 1336 2024-06-03 06:58:36Z makemake $ Copyright (c) UV Software, Berlin // +// $Id: Version.h 1373 2024-07-31 18:55:39Z gonggong $ Copyright (c) UV Software, Berlin // diff --git a/Tests/pcb_testing.vcxproj b/Tests/pcb_testing.vcxproj index 15d554e..6bc6e68 100644 --- a/Tests/pcb_testing.vcxproj +++ b/Tests/pcb_testing.vcxproj @@ -56,7 +56,7 @@ Console true - .\GoogleTest\build\x86-Debug\lib\gtest.lib;..\Binaries\x86\lib\Debug\uvPeakCAN.lib;..\Binaries\x86\lib\Debug\PCANBasic.lib;%(AdditionalDependencies) + .\GoogleTest\Windows\x86-Debug\lib\gtest.lib;..\Binaries\x86\lib\Debug\uvPeakCAN.lib;..\Binaries\x86\lib\Debug\PCANBasic.lib;%(AdditionalDependencies) @@ -73,7 +73,7 @@ Console true - .\GoogleTest\build\x64-Debug\lib\gtest.lib;..\Binaries\x64\lib\Debug\uvPeakCAN.lib;..\Binaries\x64\lib\Debug\PCANBasic.lib;%(AdditionalDependencies) + .\GoogleTest\Windows\x64-Debug\lib\gtest.lib;..\Binaries\x64\lib\Debug\uvPeakCAN.lib;..\Binaries\x64\lib\Debug\PCANBasic.lib;%(AdditionalDependencies) diff --git a/Trial/Sources/main.cpp b/Trial/Sources/main.cpp index df820e1..3099975 100644 --- a/Trial/Sources/main.cpp +++ b/Trial/Sources/main.cpp @@ -20,8 +20,11 @@ #include //#define SECOND_CHANNEL +#ifdef __APPLE__ +#define ISSUE_198 (1) +#else #define ISSUE_198 (0) - +#endif #if (OPTION_PCAN_BIT_TIMING == 1) #define BITRATE_1M(x) PEAKCAN_BR_1M(x) #define BITRATE_800K(x) PEAKCAN_BR_800K(x) @@ -34,16 +37,16 @@ #define BITRATE_10K(x) PEAKCAN_BR_10K(x) #define BITRATE_5K(x) PEAKCAN_BR_5K(x) #else -#define BITRATE_1M(x) DEFAULT_CAN_BR_1M(x) +#define BITRATE_1M(x) DEFAULT_CAN_BR_1M(x) #define BITRATE_800K(x) DEFAULT_CAN_BR_800K(x) #define BITRATE_500K(x) DEFAULT_CAN_BR_500K(x) #define BITRATE_250K(x) DEFAULT_CAN_BR_250K(x) #define BITRATE_125K(x) DEFAULT_CAN_BR_125K(x) #define BITRATE_100K(x) DEFAULT_CAN_BR_100K(x) -#define BITRATE_50K(x) DEFAULT_CAN_BR_50K(x) -#define BITRATE_20K(x) DEFAULT_CAN_BR_20K(x) -#define BITRATE_10K(x) DEFAULT_CAN_BR_10K(x) -#define BITRATE_5K(x) DEFAULT_CAN_BR_5K(x) +#define BITRATE_50K(x) DEFAULT_CAN_BR_50K(x) +#define BITRATE_20K(x) DEFAULT_CAN_BR_20K(x) +#define BITRATE_10K(x) DEFAULT_CAN_BR_10K(x) +#define BITRATE_5K(x) DEFAULT_CAN_BR_5K(x) #endif #if (OPTION_PCAN_BIT_TIMING == 1) #define BITRATE_FD_1M(x) PEAKCAN_FD_BR_1M(x) @@ -144,13 +147,14 @@ int main(int argc, const char * argv[]) { int option_retry = OPTION_NO; int option_reply = OPTION_NO; int option_transmit = OPTION_NO; + int option_extended = OPTION_NO; // int option_device_id = OPTION_NO; // int option_trace = OPTION_NO; // int option_log = OPTION_NO; int option_xor = OPTION_NO; uint64_t received = 0ULL; uint64_t expected = 0ULL; - time_t now = time(NULL); + time_t now = 0L; for (int i = 1, opt = 0; i < argc; i++) { /* PCAN-USB channel */ @@ -209,6 +213,7 @@ int main(int argc, const char * argv[]) { if (!strncmp(argv[i], "R:", 2) && sscanf(argv[i], "R:%i", &opt) == 1) rxTimeout = (useconds_t)opt; /* transmit messages */ if ((sscanf(argv[i], "%i", &opt) == 1) && (opt > 0)) option_transmit = opt; + if (!strcmp(argv[i], "EXT") || !strcmp(argv[i], "EXTENDED")) option_extended = OPTION_YES; // if (!strncmp(argv[i], "T:", 2) && sscanf(argv[i], "T:%i", &opt) == 1) txTimeout = (useconds_t)opt; if (!strncmp(argv[i], "C:", 2) && sscanf(argv[i], "C:%i", &opt) == 1) txDelay = (useconds_t)opt * 1000U; if (!strncmp(argv[i], "U:", 2) && sscanf(argv[i], "U:%i", &opt) == 1) txDelay = (useconds_t)opt; @@ -516,7 +521,7 @@ int main(int argc, const char * argv[]) { verbose(opMode, bitrate, speed); uint32_t code, mask; - if ((myDriver.GetFilter11Bit(code, mask) == CCanApi::NoError) && + if ((myDriver.GetFilter11Bit(code, mask) == CCanApi::NoError) && ((code != CANACC_CODE_11BIT) || (mask != CANACC_MASK_11BIT))) fprintf(stdout, " Filter11: code = 0x%03X, mask = 0x%03X\n", code, mask); if ((myDriver.GetFilter29Bit(code, mask) == CCanApi::NoError) && @@ -543,9 +548,15 @@ int main(int argc, const char * argv[]) { #endif /* transmit messages */ if (option_transmit) { +#ifdef __linux__ + if (!option_retry) + fprintf(stdout, "Attention: The program will throw errors if the transmit queue is full.\n" + " Use program option RETRY to avoid this.\n"); +#else // if ((txTimeout == 0U) && !option_retry) // fprintf(stdout, "Attention: The program will be aborted when the transmitter is busy.\n" // " Use program option RETRY or T: to avoid this.\n"); +#endif fprintf(stdout, "Press Ctrl+C to abort..."); fflush(stdout); frames = 0; now = time(NULL); @@ -563,6 +574,7 @@ int main(int argc, const char * argv[]) { message.dlc = CANFD_MAX_DLC; } #endif + message.xtd = option_extended ? 1 : 0; message.id = (uint32_t)frames & (message.xtd ? CAN_MAX_XTD_ID : CAN_MAX_STD_ID); message.data[0] = (uint8_t)(((uint64_t)frames & 0x00000000000000FF) >> 0); message.data[1] = (uint8_t)(((uint64_t)frames & 0x000000000000FF00) >> 8); @@ -588,7 +600,8 @@ int main(int argc, const char * argv[]) { if (myDriver.GetStatus(status) == CCanApi::NoError) { fprintf(stdout, ">>> myDriver.WriteMessage: status = 0x%02X\n", status.byte); } - fprintf(stdout, " %i message(s) sent (took %.1lfs)\n", frames, difftime(time(NULL), now)); + fprintf(stdout, " %i %s message(s) sent (took %.1lfs)\n", frames, option_extended ? "extended" : "standard", + difftime(time(NULL), now)); if (option_exit) goto teardown; } diff --git a/Utilities/can_moni/Driver.h b/Utilities/can_moni/Driver.h index 7675d2c..a7edba7 100644 --- a/Utilities/can_moni/Driver.h +++ b/Utilities/can_moni/Driver.h @@ -25,7 +25,8 @@ #if (OPTION_CAN_2_0_ONLY != 0) #error Compilation with legacy CAN 2.0 frame format! #else -#define CAN_FD_SUPPORTED 1 // don't touch that dial +#define CAN_FD_SUPPORTED 1 // don't touch that dial +#define CAN_TRACE_SUPPORTED 0 // write trace file (1=PCAN) #endif #define MONITOR_INTERFACE "PEAK-System PCAN Interfaces" #define MONITOR_COPYRIGHT "2007,2012-2024 by Uwe Vogt, UV Software, Berlin" diff --git a/Utilities/can_moni/README.md b/Utilities/can_moni/README.md index 813c06c..a1da4d5 100644 --- a/Utilities/can_moni/README.md +++ b/Utilities/can_moni/README.md @@ -1,4 +1,4 @@ -__CAN Monitor for PEAK-System PCAN Interfaces, Version 0.5.1__ \ +__CAN Monitor for PEAK-System PCAN Interfaces, Version 0.5.2__ \ Copyright © 2007,2012-2024 by Uwe Vogt, UV Software, Berlin ``` diff --git a/Utilities/can_moni/Sources/Options.h b/Utilities/can_moni/Sources/Options.h index fdcd8b5..3e8aef2 100644 --- a/Utilities/can_moni/Sources/Options.h +++ b/Utilities/can_moni/Sources/Options.h @@ -68,6 +68,14 @@ struct SOptions { uint32_t m_u32Mask; } m_StdFilter, m_XtdFilter; char* m_szExcludeList; +#if (CAN_TRACE_SUPPORTED != 0) + enum { + eTraceOff, + eTraceBinary, + eTraceLogger, + eTraceVendor + } m_eTraceMode; +#endif bool m_fListBitrates; bool m_fListBoards; bool m_fTestBoards; diff --git a/Utilities/can_moni/Sources/Options_p.cpp b/Utilities/can_moni/Sources/Options_p.cpp index ed8b3cd..3eb700f 100644 --- a/Utilities/can_moni/Sources/Options_p.cpp +++ b/Utilities/can_moni/Sources/Options_p.cpp @@ -55,7 +55,6 @@ static const char* c_szWarranty = CAN_MONI_WARRANTY; static const char* c_szLicense = CAN_MONI_LICENSE; static const char* c_szBasename = CAN_MONI_PROGRAM; static const char* c_szInterface = "(unknown)"; -static const char* c_szExcludeList = "~0x00-0x7FF"; SOptions::SOptions() { // to have default bus speed from bit-timing index @@ -77,12 +76,14 @@ SOptions::SOptions() { m_StdFilter.m_u32Mask = CANACC_MASK_11BIT; m_XtdFilter.m_u32Code = CANACC_CODE_29BIT; m_XtdFilter.m_u32Mask = CANACC_MASK_29BIT; - m_szExcludeList = (char*)c_szExcludeList; + m_szExcludeList = (char*)NULL; +#if (CAN_TRACE_SUPPORTED != 0) + m_eTraceMode = SOptions::eTraceOff; +#endif m_fListBitrates = false; m_fListBoards = false; m_fTestBoards = false; m_fVerbose = false; - m_fVerbose = false; m_fExit = false; } @@ -110,6 +111,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optFmtWrap = 0; #endif int optExclude = 0; +#if (CAN_TRACE_SUPPORTED != 0) + int optTraceMode = 0; +#endif int optListBitrates = 0; int optListBoards = 0; int optTestBoards = 0; @@ -154,6 +158,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) {"wraparound", required_argument, 0, 'w'}, {"exclude", required_argument, 0, 'x'}, {"script", required_argument, 0, 's'}, + {"trace", required_argument, 0, 'y'}, {"list-bitrates", optional_argument, 0, 'l'}, #if (OPTION_CANAPI_LIBRARY != 0) {"list-boards", optional_argument, 0, 'L'}, @@ -179,9 +184,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) #endif // (2) scan command-line for options #if (OPTION_CANAPI_LIBRARY != 0) - while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:t:i:d:a:w:x:s:lLTh", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:t:i:d:a:w:x:s:y:lLTh", long_options, NULL)) != -1) { #else - while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:t:i:d:a:w:x:s:lLTj:h", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:t:i:d:a:w:x:s:y:lLTj:h", long_options, NULL)) != -1) { #endif switch (opt) { /* option '--baudrate=' (-b) */ @@ -323,8 +328,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--error-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_ERR; - + m_OpMode.byte |= CANMODE_ERR; break; /* option '--no-extended-frames' */ case 'X': @@ -336,7 +340,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--no-extended-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NXTD; + m_OpMode.byte |= CANMODE_NXTD; break; /* option '--no-remote-frames' */ case 'R': @@ -348,7 +352,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: missing argument for option `--no-remote-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NRTR; + m_OpMode.byte |= CANMODE_NRTR; break; /* option '--code=<11-bit-code>' */ case '1': @@ -430,6 +434,36 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) } m_XtdFilter.m_u32Mask = (uint32_t)intarg; break; + /* option '--trace=(ON|OFF)' (-y) */ +#if (CAN_TRACE_SUPPORTED != 0) + case 'y': + if (optTraceMode++) { + fprintf(err, "%s: duplicated option `--trace'\n", m_szBasename); + return 1; + } + if (optarg == NULL) { + fprintf(err, "%s: missing argument for option `--trace'\n", m_szBasename); + return 1; + } +#if (CAN_TRACE_SUPPORTED == 1) + if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) + m_eTraceMode = SOptions::eTraceOff; + else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) + m_eTraceMode = SOptions::eTraceVendor; +#else + if (!strcasecmp(optarg, "BIN") || !strcasecmp(optarg, "BINARY") || !strcasecmp(optarg, "default")) + m_eTraceMode = SOptions::eTraceBinary; + else if (!strcasecmp(optarg, "CSV") || !strcasecmp(optarg, "logger") || !strcasecmp(optarg, "log")) + m_eTraceMode = SOptions::eTraceLogger; + else if (!strcasecmp(optarg, "TRC") || !strcasecmp(optarg, "vendor")) + m_eTraceMode = SOptions::eTraceVendor; +#endif + else { + fprintf(err, "%s: illegal argument for option `--trace'\n", m_szBasename); + return 1; + } + break; +#endif /* option '--time=(ABS|REL|ZERO)' (-t) */ case 't': if (optFmtTime++) { @@ -761,6 +795,9 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " -b, --baudrate= CAN bit-timing in kbps (default=250), or\n"); fprintf(stream, " --bitrate= CAN bit-rate settings (as key/value list)\n"); fprintf(stream, " -v, --verbose show detailed bit-rate settings\n"); +#if (CAN_TRACE_SUPPORTED != 0) + fprintf(stream, " -y, --trace=(ON|OFF) write a trace file (default=OFF)\n"); +#endif #if (CAN_FD_SUPPORTED != 0) fprintf(stream, " --list-bitrates[=] list standard bit-rate settings and exit\n"); #else diff --git a/Utilities/can_moni/Sources/Options_w.cpp b/Utilities/can_moni/Sources/Options_w.cpp index 3a232f0..ded83b4 100644 --- a/Utilities/can_moni/Sources/Options_w.cpp +++ b/Utilities/can_moni/Sources/Options_w.cpp @@ -29,6 +29,13 @@ extern "C" { #include "dosopt.h" } +#if defined(_WIN64) +#define PLATFORM "x64" +#elif defined(_WIN32) +#define PLATFORM "x86" +#else +#error Platform not supported +#endif #ifdef _MSC_VER //not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw #define strncasecmp _strnicmp @@ -74,19 +81,21 @@ extern "C" { #define XTD_MASK_CHR 32 #define SCRIPT_STR 33 #define SCRIPT_CHR 34 -#define LISTBITRATES_STR 35 -#define LISTBOARDS_STR 36 -#define LISTBOARDS_CHR 37 -#define TESTBOARDS_STR 38 -#define TESTBOARDS_CHR 39 -#define JSON_STR 40 -#define JSON_CHR 41 -#define HELP 42 -#define QUESTION_MARK 43 -#define ABOUT 44 -#define CHARACTER_MJU 45 -#define VERSION 46 -#define MAX_OPTIONS 47 +#define TRACEFILE_STR 35 +#define TRACEFILE_CHR 36 +#define LISTBITRATES_STR 37 +#define LISTBOARDS_STR 38 +#define LISTBOARDS_CHR 39 +#define TESTBOARDS_STR 40 +#define TESTBOARDS_CHR 41 +#define JSON_STR 42 +#define JSON_CHR 43 +#define HELP 44 +#define QUESTION_MARK 45 +#define ABOUT 46 +#define CHARACTER_MJU 47 +#define VERSION 48 +#define MAX_OPTIONS 49 static char* option[MAX_OPTIONS] = { (char*)"BAUDRATE", (char*)"bd", @@ -107,6 +116,7 @@ static char* option[MAX_OPTIONS] = { (char*)"CODE", (char*)"MASK", (char*)"XTD-CODE", (char*)"XTD-MASK", (char*)"SCRIPT", (char*)"s", + (char*)"TRACE", (char*)"trc", (char*)"LIST-BITRATES", (char*)"LIST-BOARDS", (char*)"list", (char*)"TEST-BOARDS", (char*)"test", @@ -125,14 +135,13 @@ static const char* c_szWarranty = CAN_MONI_WARRANTY; static const char* c_szLicense = CAN_MONI_LICENSE; static const char* c_szBasename = CAN_MONI_PROGRAM; static const char* c_szInterface = "(unknown)"; -static const char* c_szExcludeList = "~0x00-0x7FF"; #if (USE_BASENAME != 0) static char* basename(char* path); #endif SOptions::SOptions() { - // to have dault bus speed from bit-timing index + // to have default bus speed from bit-timing index (void)CCanDriver::MapIndex2Bitrate(DEFAULT_BAUDRATE, m_Bitrate); (void)CCanDriver::MapBitrate2Speed(m_Bitrate, m_BusSpeed); // initialization @@ -151,12 +160,14 @@ SOptions::SOptions() { m_StdFilter.m_u32Mask = CANACC_MASK_11BIT; m_XtdFilter.m_u32Code = CANACC_CODE_29BIT; m_XtdFilter.m_u32Mask = CANACC_MASK_29BIT; - m_szExcludeList = (char*)c_szExcludeList; + m_szExcludeList = (char*)NULL; +#if (CAN_TRACE_SUPPORTED != 0) + m_eTraceMode = SOptions::eTraceOff; +#endif m_fListBitrates = false; m_fListBoards = false; m_fTestBoards = false; m_fVerbose = false; - m_fVerbose = false; m_fExit = false; } @@ -174,16 +185,21 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optErrorFrames = 0; int optExtendedFrames = 0; int optRemoteFrames = 0; - int optTime = 0; - int optId = 0; - int optData = 0; - int optAscii = 0; - int optWrap = 0; - int optExclude = 0; - int optCode = 0; - int optMask = 0; + int optStdCode = 0; + int optStdMask = 0; int optXtdCode = 0; int optXtdMask = 0; + int optFmtTime = 0; + int optFmtId = 0; + int optFmtData = 0; + int optFmtAscii = 0; +#if (CAN_FD_SUPPORTED != 0) + int optFmtWrap = 0; +#endif + int optExclude = 0; +#if (CAN_TRACE_SUPPORTED != 0) + int optTraceMode = 0; +#endif int optListBitrates = 0; int optListBoards = 0; int optTestBoards = 0; @@ -193,16 +209,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optJson = 0; #endif /* default format options */ - CCanMessage::EFormatTimestamp modeTime = CCanMessage::OptionZero; - CCanMessage::EFormatNumber modeId = CCanMessage::OptionHex; - CCanMessage::EFormatNumber modeData = CCanMessage::OptionHex; - CCanMessage::EFormatOption modeAscii = CCanMessage::OptionOn; - CCanMessage::EFormatWraparound wraparound = CCanMessage::OptionWraparoundNo; - (void)CCanMessage::SetTimestampFormat(modeTime); - (void)CCanMessage::SetIdentifierFormat(modeId); - (void)CCanMessage::SetDataFormat(modeData); - (void)CCanMessage::SetAsciiFormat(modeAscii); - (void)CCanMessage::SetWraparound(wraparound); + CCanMessage::EFormatTimestamp fmtModeTime = CCanMessage::OptionZero; + CCanMessage::EFormatNumber fmtModeId = CCanMessage::OptionHex; + CCanMessage::EFormatNumber fmtModeData = CCanMessage::OptionHex; + CCanMessage::EFormatOption fmtModeAscii = CCanMessage::OptionOn; + CCanMessage::EFormatWraparound fmtWraparound = CCanMessage::OptionWraparoundNo; + (void)CCanMessage::SetTimestampFormat(fmtModeTime); + (void)CCanMessage::SetIdentifierFormat(fmtModeId); + (void)CCanMessage::SetDataFormat(fmtModeData); + (void)CCanMessage::SetAsciiFormat(fmtModeAscii); + (void)CCanMessage::SetWraparound(fmtWraparound); // (0) sanity check if ((argc <= 0) || (argv == NULL)) @@ -211,7 +227,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return (-1); // (1) get basename from command-line #if (USE_BASENAME != 0) - m_szBasename = Basename(argv[0]); + m_szBasename = basename((char*)argv[0]); #endif // (2) scan command-line for options while ((optind = getOption(argc, (char**)argv, MAX_OPTIONS, option)) != EOF) { @@ -287,7 +303,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) m_fVerbose = true; break; #if (OPTION_CANAPI_LIBRARY != 0) - /* option '--path' (-p) */ + /* option '--path=' (-p) */ case JSON_STR: case JSON_CHR: if ((optPath++)) { @@ -438,10 +454,121 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } break; + /* option '--code=<11-bit-code>' */ + case STD_CODE_STR: + if ((optStdCode++)) { + fprintf(err, "%s: duplicated option /CODE\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /CODE\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_STD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); + return 1; + } + m_StdFilter.m_u32Code = (uint32_t)intarg; + break; + /* option '--mask=<11-bit-mask>' */ + case STD_MASK_CHR: + if ((optStdMask++)) { + fprintf(err, "%s: duplicated option /MASK\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /MASK\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_STD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); + return 1; + } + m_StdFilter.m_u32Mask = (uint32_t)intarg; + break; + /* option '--xtd-code=<29-bit-code>' */ + case XTD_CODE_STR: + if ((optXtdCode++)) { + fprintf(err, "%s: duplicated option /XTD-CODE\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /XTD-CODE\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_XTD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); + return 1; + } + m_XtdFilter.m_u32Code = (uint32_t)intarg; + break; + /* option '--xtd-mask=<29-bit-mask>' */ + case XTD_MASK_CHR: + if ((optXtdMask++)) { + fprintf(err, "%s: duplicated option /XTD-MASK\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /XTD-MASK\n", m_szBasename); + return 1; + } + if (sscanf_s(optarg, "%lli", &intarg) != 1) { + fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); + return 1; + } + if ((intarg & ~CAN_MAX_XTD_ID) != 0) { + fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); + return 1; + } + m_XtdFilter.m_u32Mask = (uint32_t)intarg; + break; + /* option '--trace=(ON|OFF)' (-y) */ +#if (CAN_TRACE_SUPPORTED != 0) + case TRACEFILE_STR: + case TRACEFILE_CHR: + if (optTraceMode++) { + fprintf(err, "%s: duplicated option /TRACE\n", m_szBasename); + return 1; + } + if ((optarg = getOptionParameter()) == NULL) { + fprintf(err, "%s: missing argument for option /TRACE\n", m_szBasename); + return 1; + } +#if (CAN_TRACE_SUPPORTED == 1) + if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) + m_eTraceMode = SOptions::eTraceOff; + else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) + m_eTraceMode = SOptions::eTraceVendor; +#else + if (!strcasecmp(optarg, "BIN") || !strcasecmp(optarg, "BINARY") || !strcasecmp(optarg, "default")) + m_eTraceMode = SOptions::eTraceBinary; + else if (!strcasecmp(optarg, "CSV") || !strcasecmp(optarg, "logger") || !strcasecmp(optarg, "log")) + m_eTraceMode = SOptions::eTraceLogger; + else if (!strcasecmp(optarg, "TRC") || !strcasecmp(optarg, "vendor")) + m_eTraceMode = SOptions::eTraceVendor; +#endif + else { + fprintf(err, "%s: illegal argument for option /TRACE\n", m_szBasename); + return 1; + } + break; +#endif /* option '--time=(ABS|REL|ZERO)' (-t) */ case MODE_TIME_STR: case MODE_TIME_CHR: - if ((optTime++)) { + if ((optFmtTime++)) { fprintf(err, "%s: duplicated option /TIME\n", m_szBasename); return 1; } @@ -450,16 +577,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "ABSOLUTE") || !strcasecmp(optarg, "ABS") || !strcasecmp(optarg, "a")) - modeTime = CCanMessage::OptionAbsolute; + fmtModeTime = CCanMessage::OptionAbsolute; else if (!strcasecmp(optarg, "RELATIVE") || !strcasecmp(optarg, "REL") || !strcasecmp(optarg, "r")) - modeTime = CCanMessage::OptionRelative; + fmtModeTime = CCanMessage::OptionRelative; else if (!strcasecmp(optarg, "ZERO") || !strcasecmp(optarg, "0") || !strcasecmp(optarg, "z")) - modeTime = CCanMessage::OptionZero; + fmtModeTime = CCanMessage::OptionZero; else { fprintf(err, "%s: illegal argument for option /TIME\n", m_szBasename); return 1; } - if (!CCanMessage::SetTimestampFormat(modeTime)) { + if (!CCanMessage::SetTimestampFormat(fmtModeTime)) { fprintf(err, "%s: illegal argument for option /TIME\n", m_szBasename); return 1; } @@ -467,7 +594,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--id=(HEX|DEC|OCT)' (-i) */ case MODE_ID_STR: case MODE_ID_CHR: - if ((optId++)) { + if ((optFmtId++)) { fprintf(err, "%s: duplicated option /ID\n", m_szBasename); return 1; } @@ -476,16 +603,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "HEXADECIMAL") || !strcasecmp(optarg, "HEX") || !strcasecmp(optarg, "h") || !strcasecmp(optarg, "16")) - modeId = CCanMessage::OptionHex; + fmtModeId = CCanMessage::OptionHex; else if (!strcasecmp(optarg, "DECIMAL") || !strcasecmp(optarg, "DEC") || !strcasecmp(optarg, "d") || !strcasecmp(optarg, "10")) - modeId = CCanMessage::OptionDec; + fmtModeId = CCanMessage::OptionDec; else if (!strcasecmp(optarg, "OCTAL") || !strcasecmp(optarg, "OCT") || !strcasecmp(optarg, "o") || !strcasecmp(optarg, "8")) - modeId = CCanMessage::OptionOct; + fmtModeId = CCanMessage::OptionOct; else { fprintf(err, "%s: illegal argument for option /ID\n", m_szBasename); return 1; } - if (!CCanMessage::SetIdentifierFormat(modeId)) { + if (!CCanMessage::SetIdentifierFormat(fmtModeId)) { fprintf(err, "%s: illegal argument for option /ID\n", m_szBasename); return 1; } @@ -493,7 +620,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--data=(HEX|DEC|OCT)' (-d) */ case MODE_DATA_STR: case MODE_DATA_CHR: - if ((optData++)) { + if ((optFmtData++)) { fprintf(err, "%s: duplicated option /DATA\n", m_szBasename); return 1; } @@ -502,16 +629,16 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "HEXADECIMAL") || !strcasecmp(optarg, "HEX") || !strcasecmp(optarg, "h") || !strcasecmp(optarg, "16")) - modeData = CCanMessage::OptionHex; + fmtModeData = CCanMessage::OptionHex; else if (!strcasecmp(optarg, "DECIMAL") || !strcasecmp(optarg, "DEC") || !strcasecmp(optarg, "d") || !strcasecmp(optarg, "10")) - modeData = CCanMessage::OptionDec; + fmtModeData = CCanMessage::OptionDec; else if (!strcasecmp(optarg, "OCTAL") || !strcasecmp(optarg, "OCT") || !strcasecmp(optarg, "o") || !strcasecmp(optarg, "8")) - modeData = CCanMessage::OptionOct; + fmtModeData = CCanMessage::OptionOct; else { fprintf(err, "%s: illegal argument for option /DATA\n", m_szBasename); return 1; } - if (!CCanMessage::SetDataFormat(modeData)) { + if (!CCanMessage::SetDataFormat(fmtModeData)) { fprintf(err, "%s: illegal argument for option /DATA\n", m_szBasename); return 1; } @@ -519,7 +646,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--ascii=(ON|OFF)' (-a) */ case MODE_ASCII_STR: case MODE_ASCII_CHR: - if ((optAscii++)) { + if ((optFmtAscii++)) { fprintf(err, "%s: duplicated option /ASCII\n", m_szBasename); return 1; } @@ -528,14 +655,14 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) - modeAscii = CCanMessage::OptionOff; + fmtModeAscii = CCanMessage::OptionOff; else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) - modeAscii = CCanMessage::OptionOn; + fmtModeAscii = CCanMessage::OptionOn; else { fprintf(err, "%s: illegal argument for option /ASCII\n", m_szBasename); return 1; } - if (!CCanMessage::SetAsciiFormat(modeAscii)) { + if (!CCanMessage::SetAsciiFormat(fmtModeAscii)) { fprintf(err, "%s: illegal argument for option /ASCII\n", m_szBasename); return 1; } @@ -544,7 +671,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) /* option '--wrap=(No|8|10|16|32|64)' (-w) */ case WRAPAROUND_STR: case WRAPAROUND_CHR: - if ((optWrap++)) { + if ((optFmtWrap++)) { fprintf(err, "%s: duplicated option /WRAPAROUND\n", m_szBasename); return 1; } @@ -553,22 +680,22 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) return 1; } if (!strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) - wraparound = CCanMessage::OptionWraparoundNo; + fmtWraparound = CCanMessage::OptionWraparoundNo; else if (!strcasecmp(optarg, "8")) - wraparound = CCanMessage::OptionWraparound8; + fmtWraparound = CCanMessage::OptionWraparound8; else if (!strcasecmp(optarg, "10")) - wraparound = CCanMessage::OptionWraparound10; + fmtWraparound = CCanMessage::OptionWraparound10; else if (!strcasecmp(optarg, "16")) - wraparound = CCanMessage::OptionWraparound16; + fmtWraparound = CCanMessage::OptionWraparound16; else if (!strcasecmp(optarg, "32")) - wraparound = CCanMessage::OptionWraparound32; + fmtWraparound = CCanMessage::OptionWraparound32; else if (!strcasecmp(optarg, "64")) - wraparound = CCanMessage::OptionWraparound64; + fmtWraparound = CCanMessage::OptionWraparound64; else { fprintf(err, "%s: illegal argument for option /WRAPAROUND\n", m_szBasename); return 1; } - if (!CCanMessage::SetWraparound(wraparound)) { + if (!CCanMessage::SetWraparound(fmtWraparound)) { fprintf(err, "%s: illegal argument for option /WRAPAROUND\n", m_szBasename); return 1; } @@ -587,86 +714,6 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) } m_szExcludeList = optarg; break; - /* option '--code=<11-bit-code>' */ - case STD_CODE_STR: - if ((optCode++)) { - fprintf(err, "%s: duplicated option /CODE\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /CODE\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_STD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /CODE\n", m_szBasename); - return 1; - } - m_StdFilter.m_u32Code = (uint32_t)intarg; - break; - /* option '--mask=<11-bit-mask>' */ - case STD_MASK_CHR: - if ((optMask++)) { - fprintf(err, "%s: duplicated option /MASK\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /MASK\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_STD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /MASK\n", m_szBasename); - return 1; - } - m_StdFilter.m_u32Mask = (uint32_t)intarg; - break; - /* option '--xtd-code=<29-bit-code>' */ - case XTD_CODE_STR: - if ((optXtdCode++)) { - fprintf(err, "%s: duplicated option /XTD-CODE\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /XTD-CODE\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_XTD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /XTD-CODE\n", m_szBasename); - return 1; - } - m_XtdFilter.m_u32Code = (uint32_t)intarg; - break; - /* option '--xtd-mask=<29-bit-mask>' */ - case XTD_MASK_CHR: - if ((optXtdMask++)) { - fprintf(err, "%s: duplicated option /XTD-MASK\n", m_szBasename); - return 1; - } - if ((optarg = getOptionParameter()) == NULL) { - fprintf(err, "%s: missing argument for option /XTD-MASK\n", m_szBasename); - return 1; - } - if (sscanf_s(optarg, "%lli", &intarg) != 1) { - fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); - return 1; - } - if ((intarg & ~CAN_MAX_XTD_ID) != 0) { - fprintf(err, "%s: illegal argument for option /XTD-MASK\n", m_szBasename); - return 1; - } - m_XtdFilter.m_u32Mask = (uint32_t)intarg; - break; /* option '--list-bitrates[=(2.0|FDF[+BRS])]' */ case LISTBITRATES_STR: if ((optListBitrates++)) { @@ -708,7 +755,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: option /PATH already set\n", m_szBasename); return 1; } - m_szSearchPath = optarg; + m_szSearchPath = optarg; // option '--list-boards=' (-L) } #endif m_fListBoards = true; @@ -727,7 +774,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: option /PATH already set\n", m_szBasename); return 1; } - m_szSearchPath = optarg; + m_szSearchPath = optarg; // option '--test-boards=' (-L) } #endif m_fTestBoards = true; @@ -826,7 +873,10 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " /MASK: acceptance mask for 11-bit IDs (default=0x%03lx)\n", CANACC_MASK_11BIT); fprintf(stream, " /XTD-CODE: acceptance code for 29-bit IDs (default=0x%08lx)\n", CANACC_CODE_29BIT); fprintf(stream, " /XTD-MASK: acceptance mask for 29-bit IDs (default=0x%08lx)\n", CANACC_MASK_29BIT); - // fprintf(stream, " /Script: execute a script file\n"); // TODO: script engine +// fprintf(stream, " /Script: execute a script file\n"); // TODO: script engine +#if (OPTION_CANAPI_LIBRARY != 0) + fprintf(stream, " /Path: search path for JSON configuration files\n"); +#endif #if (CAN_FD_SUPPORTED != 0) fprintf(stream, " /Mode:(2.0|FDf[+BRS]) CAN operation mode: CAN 2.0 or CAN FD mode\n"); #else @@ -839,10 +889,10 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " /XTD:(Yes|No) allow extended frames (29-bit identifier)\n"); fprintf(stream, " /BauDrate: CAN bit-timing in kbps (default=250), or\n"); fprintf(stream, " /BitRate: CAN bit-rate settings (as key/value list)\n"); -#if (OPTION_CANAPI_LIBRARY != 0) - fprintf(stream, " /Path: search path for JSON configuration files\n"); -#endif fprintf(stream, " /Verbose show detailed bit-rate settings\n"); +#if (CAN_TRACE_SUPPORTED != 0) + fprintf(stream, " /TRaCe:(ON|OFF) write a trace file (default=OFF)\n"); +#endif #if (CAN_FD_SUPPORTED != 0) fprintf(stream, " /LIST-BITRATES[:(2.0|FDf[+BRS])] list standard bit-rate settings and exit\n"); #else diff --git a/Utilities/can_moni/Sources/main.cpp b/Utilities/can_moni/Sources/main.cpp index 92addd8..af6a759 100644 --- a/Utilities/can_moni/Sources/main.cpp +++ b/Utilities/can_moni/Sources/main.cpp @@ -85,7 +85,7 @@ int main(int argc, const char* argv[]) { CCanDevice::SLibraryInfo library = { (-1), "", "" }; #endif CANAPI_Return_t retVal = CANERR_FATAL; - char property[CANPROP_MAX_BUFFER_SIZE] = ""; + char property[CANPROP_MAX_BUFFER_SIZE + 1] = ""; char* string = NULL; /* device parameter */ @@ -313,9 +313,50 @@ int main(int argc, const char* argv[]) { fprintf(stderr, "+++ error: CAN Controller could not be started (%i)\n", retVal); goto teardown; } + /* - start trace session (if enabled) */ +#if (CAN_TRACE_SUPPORTED != 0) + if (opts.m_eTraceMode != SOptions::eTraceOff) { + /* -- set trace format */ + switch (opts.m_eTraceMode) { + case SOptions::eTraceVendor: + property[0] = CANPARA_TRACE_TYPE_VENDOR; + break; + case SOptions::eTraceLogger: + property[0] = CANPARA_TRACE_TYPE_LOGGER; + break; + case SOptions::eTraceBinary: + default: + property[0] = CANPARA_TRACE_TYPE_BINARY; + break; + } + (void)canDevice.SetProperty(CANPROP_SET_TRACE_TYPE, (void*)&property[0], sizeof(uint8_t)); + /* -- set trace active */ + property[0] = CANPARA_TRACE_ON; + retVal = canDevice.SetProperty(CANPROP_SET_TRACE_ACTIVE, (void*)&property[0], sizeof(uint8_t)); + if (retVal != CCanApi::NoError) { + fprintf(stdout, "FAILED!\n"); + fprintf(stderr, "+++ error: trace session could not be started (%i)\n", retVal); + goto teardown; + } + } +#endif fprintf(stdout, "OK!\n"); /* - reception loop */ canDevice.ReceptionLoop(); + /* - stop trace session (if enabled) */ +#if (CAN_TRACE_SUPPORTED != 0) + if (opts.m_eTraceMode != SOptions::eTraceOff) { + /* -- get trace file name */ + retVal = canDevice.GetProperty(CANPROP_GET_TRACE_FILE, (void*)property, CANPROP_MAX_BUFFER_SIZE); + if (retVal == CCanApi::NoError) { + property[CANPROP_MAX_BUFFER_SIZE] = '\0'; + fprintf(stdout, "Trace-file=%s\n", property); + } + /* -- set trace inactive */ + property[0] = CANPARA_TRACE_OFF; + (void)canDevice.SetProperty(CANPROP_SET_TRACE_ACTIVE, (void*)&property[0], sizeof(uint8_t)); + } +#endif /* - show interface information */ if ((string = canDevice.GetHardwareVersion()) != NULL) fprintf(stdout, "Hardware: %s\n", string); @@ -471,7 +512,6 @@ bool CCanDevice::IsBlacklisted(int32_t library, int32_t blacklist[]) { int CCanDevice::ListCanBitrates(CANAPI_OpMode_t opMode) { CANAPI_Bitrate_t bitrate[9]; CANAPI_BusSpeed_t speed; - CANAPI_Return_t retVal; char string[CANPROP_MAX_BUFFER_SIZE] = ""; bool hasDataPhase = false; @@ -519,7 +559,7 @@ int CCanDevice::ListCanBitrates(CANAPI_OpMode_t opMode) { hasNoSamp = true; } for (i = 0; i < n; i++) { - if ((retVal = CCanDevice::MapBitrate2Speed(bitrate[i], speed)) == CCanApi::NoError) { + if (CCanDevice::MapBitrate2Speed(bitrate[i], speed) == CCanApi::NoError) { fprintf(stdout, " %4.0fkbps@%.1f%%", speed.nominal.speed / 1000., speed.nominal.samplepoint * 100.); #if (CAN_FD_SUPPORTED != 0) if (opMode.brse) @@ -618,7 +658,7 @@ bool CCanDevice::WriteJsonFile(const char* filename) { " \"id\": %i,\n" " \"name\": \"%s%i\",\n" " \"alias\": \"%s%i\"\n", - CANDEV_SERIAL, + CANDEV_SERIAL, #if defined(_WIN32) || defined(_WIN64) MONITOR_TTYNAME, i + 1, #else @@ -647,7 +687,6 @@ bool CCanDevice::WriteJsonFile(const char* filename) { */ uint64_t CCanDevice::ReceptionLoop() { CANAPI_Message_t message; - CANAPI_Return_t retVal; uint64_t frames = 0U; char string[CANPROP_MAX_STRING_LENGTH+1]; @@ -655,7 +694,7 @@ uint64_t CCanDevice::ReceptionLoop() { fprintf(stderr, "\nPress ^C to abort.\n\n"); while(running) { - if ((retVal = ReadMessage(message)) == CCanApi::NoError) { + if (ReadMessage(message) == CCanApi::NoError) { if ((((message.id < MAX_ID) && can_id[message.id]) || ((message.id >= MAX_ID) && can_id_xtd))) { (void)CCanMessage::Format(message, ++frames, string, CANPROP_MAX_STRING_LENGTH); fprintf(stdout, "%s\n", string); @@ -729,9 +768,9 @@ static int get_exclusion(const char* arg) } if (inv) { for (i = 0; i < MAX_ID; i++) - can_id[i] = !can_id[i]; + can_id[i] = can_id[i] ? 0 : 1; } - can_id_xtd = !inv; + can_id_xtd = inv ? 0 : 1; return 1; } diff --git a/Utilities/can_test/Driver.h b/Utilities/can_test/Driver.h index 89f3475..0102c94 100644 --- a/Utilities/can_test/Driver.h +++ b/Utilities/can_test/Driver.h @@ -26,7 +26,8 @@ #if (OPTION_CAN_2_0_ONLY != 0) #error Compilation with legacy CAN 2.0 frame format! #else -#define CAN_FD_SUPPORTED 1 // don't touch that dial +#define CAN_FD_SUPPORTED 1 // don't touch that dial +#define CAN_TRACE_SUPPORTED 0 // write trace file (1=PCAN) #endif #define TESTER_INTERFACE "PEAK-System PCAN Interfaces" #define TESTER_COPYRIGHT "2005-2010,2012-2024 by Uwe Vogt, UV Software, Berlin" diff --git a/Utilities/can_test/README.md b/Utilities/can_test/README.md index 78baba1..fb4f724 100644 --- a/Utilities/can_test/README.md +++ b/Utilities/can_test/README.md @@ -1,4 +1,4 @@ -__CAN Tester for PEAK-System PCAN Interfaces, Version 0.5.1__ \ +__CAN Tester for PEAK-System PCAN Interfaces, Version 0.5.2__ \ Copyright © 2005-2010,2012-2024 by Uwe Vogt, UV Software, Berlin ``` @@ -28,6 +28,7 @@ Options for transmitter test: /Usec: cycle time in microseconds (default=0) /Dlc: send messages of given length (default=8) /can-Id: use given identifier (default=100h) + /EXTended use extended identifier (29-bit) /Number: set first up-counting number (default=0) /Mode:(2.0|FDf[+BRS]) CAN operation mode: CAN 2.0 or CAN FD mode /SHARED shared CAN controller access (if supported) diff --git a/Utilities/can_test/Sources/Options.h b/Utilities/can_test/Sources/Options.h index fdd0c73..7a63fb7 100644 --- a/Utilities/can_test/Sources/Options.h +++ b/Utilities/can_test/Sources/Options.h @@ -83,6 +83,15 @@ struct SOptions { uint64_t m_nTxDelay; uint32_t m_nTxCanId; uint8_t m_nTxCanDlc; + bool m_fTxXtdId; +#if (CAN_TRACE_SUPPORTED != 0) + enum { + eTraceOff, + eTraceBinary, + eTraceLogger, + eTraceVendor + } m_eTraceMode; +#endif bool m_fListBitrates; bool m_fListBoards; bool m_fTestBoards; diff --git a/Utilities/can_test/Sources/Options_p.cpp b/Utilities/can_test/Sources/Options_p.cpp index 44173c9..2da99fb 100644 --- a/Utilities/can_test/Sources/Options_p.cpp +++ b/Utilities/can_test/Sources/Options_p.cpp @@ -79,6 +79,9 @@ SOptions::SOptions() { m_StdFilter.m_u32Mask = CANACC_MASK_11BIT; m_XtdFilter.m_u32Code = CANACC_CODE_29BIT; m_XtdFilter.m_u32Mask = CANACC_MASK_29BIT; +#if (CAN_TRACE_SUPPORTED != 0) + m_eTraceMode = SOptions::eTraceOff; +#endif m_TestMode = SOptions::RxMODE; m_nStartNumber = (uint64_t)0; m_fCheckNumber = false; @@ -88,11 +91,11 @@ SOptions::SOptions() { m_nTxDelay = (uint64_t)0; m_nTxCanId = (uint32_t)DEFAULT_CAN_ID; m_nTxCanDlc = (uint8_t)DEFAULT_LENGTH; + m_fTxXtdId = false; m_fListBitrates = false; m_fListBoards = false; m_fTestBoards = false; m_fVerbose = false; - m_fVerbose = false; m_fExit = false; } @@ -121,6 +124,10 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) int optCycle = 0; int optDlc = 0; int optId = 0; + int optXtd = 0; +#if (CAN_TRACE_SUPPORTED != 0) + int optTraceMode = 0; +#endif int optListBitrates = 0; int optListBoards = 0; int optTestBoards = 0; @@ -156,6 +163,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) {"dlc", required_argument, 0, 'd'}, {"data", required_argument, 0, 'd'}, {"id", required_argument, 0, 'i'}, + {"xtd", no_argument, 0, 'e'}, + {"extended", no_argument, 0, 'e'}, + {"trace", required_argument, 0, 'y'}, {"list-bitrates", optional_argument, 0, 'l'}, #if (OPTION_CANAPI_LIBRARY != 0) {"list-boards", optional_argument, 0, 'L'}, @@ -181,9 +191,9 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) #endif // (2) scan command-line for options #if (OPTION_CANAPI_LIBRARY != 0) - while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:rn:st:f:R:c:u:d:i:lLaTh", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vp:m:rn:st:f:R:c:u:d:i:ey:lLaTh", long_options, NULL)) != -1) { #else - while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:rn:st:f:R:c:u:d:i:lLaTj:h", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, (char * const *)argv, "b:vm:rn:st:f:R:c:u:d:i:ey:lLaTj:h", long_options, NULL)) != -1) { #endif switch (opt) { /* option '--baudrate=' (-b) */ @@ -325,8 +335,8 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--error-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_ERR; - + m_OpMode.byte |= CANMODE_ERR; + break; /* option '--no-extended-frames' */ case 'X': @@ -338,7 +348,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: illegal argument for option `--no-extended-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NXTD; + m_OpMode.byte |= CANMODE_NXTD; break; /* option '--no-remote-frames' */ case 'R': @@ -350,7 +360,7 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) fprintf(err, "%s: missing argument for option `--no-remote-frames'\n", m_szBasename); return 1; } - m_OpMode.byte |= CANMODE_NRTR; + m_OpMode.byte |= CANMODE_NRTR; break; /* option '--code=<11-bit-code>' */ case '1': @@ -432,6 +442,36 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) } m_XtdFilter.m_u32Mask = (uint32_t)intarg; break; + /* option '--trace=(ON|OFF)' (-y) */ +#if (CAN_TRACE_SUPPORTED != 0) + case 'y': + if (optTraceMode++) { + fprintf(err, "%s: duplicated option `--trace'\n", m_szBasename); + return 1; + } + if (optarg == NULL) { + fprintf(err, "%s: missing argument for option `--trace'\n", m_szBasename); + return 1; + } +#if (CAN_TRACE_SUPPORTED == 1) + if (!strcasecmp(optarg, "OFF") || !strcasecmp(optarg, "NO") || !strcasecmp(optarg, "n") || !strcasecmp(optarg, "0")) + m_eTraceMode = SOptions::eTraceOff; + else if (!strcasecmp(optarg, "ON") || !strcasecmp(optarg, "YES") || !strcasecmp(optarg, "y") || !strcasecmp(optarg, "1")) + m_eTraceMode = SOptions::eTraceVendor; +#else + if (!strcasecmp(optarg, "BIN") || !strcasecmp(optarg, "BINARY") || !strcasecmp(optarg, "default")) + m_eTraceMode = SOptions::eTraceBinary; + else if (!strcasecmp(optarg, "CSV") || !strcasecmp(optarg, "logger") || !strcasecmp(optarg, "log")) + m_eTraceMode = SOptions::eTraceLogger; + else if (!strcasecmp(optarg, "TRC") || !strcasecmp(optarg, "vendor")) + m_eTraceMode = SOptions::eTraceVendor; +#endif + else { + fprintf(err, "%s: illegal argument for option `--trace'\n", m_szBasename); + return 1; + } + break; +#endif /* option '--receive' (-r) */ case 'r': if (optReceive++) { @@ -626,6 +666,18 @@ int SOptions::ScanCommanline(int argc, const char* argv[], FILE* err, FILE* out) } m_nTxCanId = (uint32_t)intarg; break; + /* option '--extended' (-e) */ + case 'e': + if (optXtd++) { + fprintf(err, "%s: duplicated option `--extended' (%c)\n", m_szBasename, opt); + return 1; + } + if (optarg != NULL) { + fprintf(err, "%s: illegal argument for option `--extended' (%c)\n", m_szBasename, opt); + return 1; + } + m_fTxXtdId = true; + break; /* option '--list-bitrates[=(2.0|FDF[+BRS])]' */ case 'l': if (optListBitrates++) { @@ -833,9 +885,16 @@ void SOptions::ShowUsage(FILE* stream, bool args) { fprintf(stream, " --error-frames allow reception of error frames\n"); fprintf(stream, " --no-remote-frames suppress remote frames (RTR frames)\n"); fprintf(stream, " --no-extended-frames suppress extended frames (29-bit identifier)\n"); + fprintf(stream, " --code= acceptance code for 11-bit IDs (default=0x%03x)\n", CANACC_CODE_11BIT); + fprintf(stream, " --mask= acceptance mask for 11-bit IDs (default=0x%03x)\n", CANACC_MASK_11BIT); + fprintf(stream, " --xtd-code= acceptance code for 29-bit IDs (default=0x%08x)\n", CANACC_CODE_29BIT); + fprintf(stream, " --xtd-mask= acceptance mask for 29-bit IDs (default=0x%08x)\n", CANACC_MASK_29BIT); fprintf(stream, " -b, --baudrate= CAN bit-timing in kbps (default=250), or\n"); fprintf(stream, " --bitrate= CAN bit-rate settings (as key/value list)\n"); fprintf(stream, " -v, --verbose show detailed bit-rate settings\n"); +#if (CAN_TRACE_SUPPORTED != 0) + fprintf(stream, " -y, --trace=(ON|OFF) write a trace file (default=OFF)\n"); +#endif fprintf(stream, "Options for transmitter test:\n"); fprintf(stream, " -t, --transmit=