From 0262fa985bd6b9f26163379d2688831e06c45e46 Mon Sep 17 00:00:00 2001 From: Dmitry Borisenko <49808844+DmitryBorisenko33@users.noreply.github.com> Date: Wed, 22 Dec 2021 23:33:47 +0100 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20wi?= =?UTF-8?q?fi=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=BA=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=D1=8F=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=B8=D0=BB?= =?UTF-8?q?=D0=B8=D1=80=D1=83=D0=B5=D1=82=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_svelte/check.json | 0 data_svelte/config.json | 37 - data_svelte/settings.json | 11 + data_svelte/setup.json | 542 -- data_svelte/sync.ffs_db | Bin 188 -> 0 bytes include/Const.h | 15 + include/EspFileSystem.h | 6 - include/Global.h | 15 +- include/WebServer.h | 8 + include/utils/FileUtils.h | 9 + include/utils/JsonUtils.h | 24 + include/utils/WiFiUtils.h | 10 + lib/ArduinoStreamUtils/.clang-format | 5 - lib/ArduinoStreamUtils/.github/FUNDING.yml | 4 - .../.github/workflows/ci.yml | 121 - lib/ArduinoStreamUtils/.gitignore | 2 - lib/ArduinoStreamUtils/CHANGELOG.md | 79 - lib/ArduinoStreamUtils/CMakeLists.txt | 18 - lib/ArduinoStreamUtils/LICENSE.md | 10 - lib/ArduinoStreamUtils/README.md | 369 - .../examples/EepromRead/EepromRead.ino | 63 - .../examples/EepromWrite/EepromWrite.ino | 69 - .../HammingSerial1/HammingSerial1.ino | 68 - .../HammingSoftwareSerial.ino | 67 - .../examples/Logger/Logger.ino | 61 - .../examples/ReadBuffer/ReadBuffer.ino | 56 - .../examples/ReadLogger/ReadLogger.ino | 55 - .../examples/StringPrint/StringPrint.ino | 54 - .../examples/StringStream/StringStream.ino | 55 - .../examples/WriteBuffer/WriteBuffer.ino | 62 - .../examples/WriteLogger/WriteLogger.ino | 55 - .../extras/images/EepromStream.svg | 1 - .../extras/images/HammingDecodingStream.svg | 1 - .../extras/images/HammingEncodingStream.svg | 1 - .../extras/images/HammingStream.svg | 1 - .../extras/images/Logger.svg | 1 - .../extras/images/ReadBuffer.svg | 1 - .../extras/images/ReadLogger.svg | 1 - .../extras/images/StringPrint.svg | 1 - .../extras/images/StringStream.svg | 1 - .../extras/images/WriteBuffer.svg | 1 - .../extras/images/WriteLogger.svg | 1 - .../extras/images/WriteWaitingStream.svg | 1 - .../extras/test/BufferingPrintTest.cpp | 137 - .../extras/test/CMakeLists.txt | 104 - .../extras/test/EepromStreamTest.cpp | 57 - .../extras/test/FailingAllocator.hpp | 14 - .../extras/test/HammingClientTest.cpp | 30 - .../extras/test/HammingDecodingClientTest.cpp | 137 - .../extras/test/HammingDecodingStreamTest.cpp | 290 - .../extras/test/HammingEncodingClientTest.cpp | 30 - .../extras/test/HammingEncodingStreamTest.cpp | 30 - .../extras/test/HammingPrintTest.cpp | 202 - .../extras/test/HammingStreamTest.cpp | 30 - .../extras/test/LoggingClientTest.cpp | 138 - .../extras/test/LoggingPrintTest.cpp | 41 - .../extras/test/LoggingStreamTest.cpp | 93 - .../extras/test/MemoryStreamTest.cpp | 116 - .../extras/test/ReadBufferingClientTest.cpp | 337 - .../extras/test/ReadBufferingStreamTest.cpp | 318 - .../extras/test/ReadLoggingClientTest.cpp | 139 - .../extras/test/ReadLoggingStreamTest.cpp | 89 - .../extras/test/ReadThrottlingStreamTest.cpp | 89 - .../extras/test/SpyingAllocator.hpp | 36 - .../extras/test/StringPrintTest.cpp | 77 - .../extras/test/StringStreamTest.cpp | 116 - .../extras/test/WaitingPrintTest.cpp | 104 - .../extras/test/WriteBufferingClientTest.cpp | 203 - .../extras/test/WriteBufferingStreamTest.cpp | 166 - .../extras/test/WriteLoggingClientTest.cpp | 140 - .../extras/test/WriteLoggingStreamTest.cpp | 90 - .../extras/test/WriteWaitingClientTest.cpp | 104 - .../extras/test/WriteWaitingStreamTest.cpp | 104 - .../extras/test/cores/avr/Arduino.h | 18 - .../extras/test/cores/avr/CMakeLists.txt | 22 - .../extras/test/cores/avr/Client.h | 27 - .../extras/test/cores/avr/EEPROM.cpp | 12 - .../extras/test/cores/avr/EEPROM.h | 12 - .../extras/test/cores/avr/Print.h | 42 - .../extras/test/cores/avr/Stream.h | 41 - .../extras/test/cores/avr/WString.h | 43 - .../extras/test/cores/esp32/Arduino.h | 18 - .../extras/test/cores/esp32/CMakeLists.txt | 22 - .../extras/test/cores/esp32/Client.h | 26 - .../extras/test/cores/esp32/EEPROM.cpp | 20 - .../extras/test/cores/esp32/EEPROM.h | 12 - .../extras/test/cores/esp32/Print.h | 42 - .../extras/test/cores/esp32/Stream.h | 48 - .../extras/test/cores/esp32/WString.h | 5 - .../extras/test/cores/esp8266/Arduino.h | 18 - .../extras/test/cores/esp8266/CMakeLists.txt | 22 - .../extras/test/cores/esp8266/Client.h | 26 - .../extras/test/cores/esp8266/EEPROM.cpp | 19 - .../extras/test/cores/esp8266/EEPROM.h | 12 - .../extras/test/cores/esp8266/Print.h | 43 - .../extras/test/cores/esp8266/Stream.h | 45 - .../extras/test/cores/esp8266/WString.h | 5 - .../extras/test/cores/nrf52/Arduino.h | 18 - .../extras/test/cores/nrf52/CMakeLists.txt | 15 - .../extras/test/cores/nrf52/Client.h | 26 - .../extras/test/cores/nrf52/Print.h | 45 - .../extras/test/cores/nrf52/Stream.h | 45 - .../extras/test/cores/nrf52/WString.h | 5 - .../extras/test/cores/samd/Arduino.h | 18 - .../extras/test/cores/samd/CMakeLists.txt | 15 - .../extras/test/cores/samd/Client.h | 26 - .../extras/test/cores/samd/Print.h | 46 - .../extras/test/cores/samd/Stream.h | 44 - .../extras/test/cores/samd/WString.h | 5 - .../extras/test/cores/stm32/Arduino.h | 18 - .../extras/test/cores/stm32/CMakeLists.txt | 22 - .../extras/test/cores/stm32/Client.h | 28 - .../extras/test/cores/stm32/EEPROM.cpp | 12 - .../extras/test/cores/stm32/EEPROM.h | 11 - .../extras/test/cores/stm32/Print.h | 41 - .../extras/test/cores/stm32/Stream.h | 42 - .../extras/test/cores/stm32/WString.h | 43 - .../extras/test/cores/teensy/Arduino.h | 18 - .../extras/test/cores/teensy/CMakeLists.txt | 22 - .../extras/test/cores/teensy/Client.h | 31 - .../extras/test/cores/teensy/EEPROM.cpp | 12 - .../extras/test/cores/teensy/EEPROM.h | 12 - .../extras/test/cores/teensy/Print.h | 46 - .../extras/test/cores/teensy/Stream.h | 42 - .../extras/test/cores/teensy/WString.h | 7 - lib/ArduinoStreamUtils/extras/test/doctest.h | 6000 ----------------- lib/ArduinoStreamUtils/extras/test/main.cpp | 6 - lib/ArduinoStreamUtils/keywords.txt | 13 - lib/ArduinoStreamUtils/library.properties | 11 - lib/ArduinoStreamUtils/src/StreamUtils.h | 7 - lib/ArduinoStreamUtils/src/StreamUtils.hpp | 28 - .../src/StreamUtils/Buffers/CharArray.hpp | 57 - .../StreamUtils/Buffers/CircularBuffer.hpp | 101 - .../src/StreamUtils/Buffers/LinearBuffer.hpp | 111 - .../src/StreamUtils/Clients/ClientProxy.hpp | 105 - .../src/StreamUtils/Clients/HammingClient.hpp | 23 - .../Clients/HammingDecodingClient.hpp | 24 - .../Clients/HammingEncodingClient.hpp | 24 - .../src/StreamUtils/Clients/LoggingClient.hpp | 23 - .../src/StreamUtils/Clients/MemoryClient.hpp | 92 - .../Clients/ReadBufferingClient.hpp | 30 - .../StreamUtils/Clients/ReadLoggingClient.hpp | 23 - .../src/StreamUtils/Clients/SpyingClient.hpp | 21 - .../Clients/WriteBufferingClient.hpp | 29 - .../Clients/WriteLoggingClient.hpp | 24 - .../Clients/WriteWaitingClient.hpp | 30 - .../src/StreamUtils/Configuration.hpp | 53 - .../src/StreamUtils/Helpers.hpp | 17 - .../Policies/ConnectForwardingPolicy.hpp | 35 - .../Policies/ConnectSpyingPolicy.hpp | 68 - .../Policies/HammingDecodingPolicy.hpp | 137 - .../Policies/HammingEncodingPolicy.hpp | 116 - .../Policies/ReadBufferingPolicy.hpp | 97 - .../Policies/ReadForwardingPolicy.hpp | 33 - .../Policies/ReadLoggingPolicy.hpp | 46 - .../StreamUtils/Policies/ReadSpyingPolicy.hpp | 64 - .../Policies/ReadThrottlingPolicy.hpp | 47 - .../Policies/WriteBufferingPolicy.hpp | 78 - .../Policies/WriteForwardingPolicy.hpp | 27 - .../Policies/WriteLoggingPolicy.hpp | 39 - .../Policies/WriteSpyingPolicy.hpp | 55 - .../Policies/WriteWaitingPolicy.hpp | 63 - .../src/StreamUtils/Polyfills.hpp | 60 - .../StreamUtils/Ports/ArduinoThrottler.hpp | 29 - .../StreamUtils/Ports/DefaultAllocator.hpp | 21 - .../src/StreamUtils/Prints/BufferingPrint.hpp | 22 - .../src/StreamUtils/Prints/HammingPrint.hpp | 19 - .../src/StreamUtils/Prints/LoggingPrint.hpp | 17 - .../src/StreamUtils/Prints/PrintProxy.hpp | 50 - .../src/StreamUtils/Prints/SpyingPrint.hpp | 17 - .../src/StreamUtils/Prints/StringPrint.hpp | 52 - .../src/StreamUtils/Prints/WaitingPrint.hpp | 22 - .../src/StreamUtils/Streams/EepromStream.hpp | 76 - .../Streams/HammingDecodingStream.hpp | 22 - .../Streams/HammingEncodingStream.hpp | 22 - .../src/StreamUtils/Streams/HammingStream.hpp | 21 - .../src/StreamUtils/Streams/LoggingStream.hpp | 19 - .../src/StreamUtils/Streams/MemoryStream.hpp | 61 - .../Streams/ReadBufferingStream.hpp | 28 - .../StreamUtils/Streams/ReadLoggingStream.hpp | 19 - .../Streams/ReadThrottlingStream.hpp | 35 - .../src/StreamUtils/Streams/SpyingStream.hpp | 19 - .../src/StreamUtils/Streams/StreamProxy.hpp | 68 - .../src/StreamUtils/Streams/StringStream.hpp | 77 - .../Streams/WriteBufferingStream.hpp | 24 - .../Streams/WriteLoggingStream.hpp | 20 - .../Streams/WriteWaitingStream.hpp | 26 - lib/TickerScheduler/README.md | 81 + lib/TickerScheduler/TickerScheduler.cpp | 116 + lib/TickerScheduler/TickerScheduler.h | 91 + .../example/blink/blink/blink.ino | 29 + src/EspFileSystem.cpp | 65 - src/Global.cpp | 9 + src/WebServer.cpp | 213 + src/main.cpp | 3 +- src/utils/FileUtils.cpp | 66 + src/utils/JsonUtils.cpp | 176 + src/utils/WiFiUtils.cpp | 170 + 198 files changed, 1043 insertions(+), 15417 deletions(-) delete mode 100644 data_svelte/check.json delete mode 100644 data_svelte/config.json create mode 100644 data_svelte/settings.json delete mode 100644 data_svelte/setup.json delete mode 100644 data_svelte/sync.ffs_db create mode 100644 include/Const.h create mode 100644 include/WebServer.h create mode 100644 include/utils/FileUtils.h create mode 100644 include/utils/JsonUtils.h create mode 100644 include/utils/WiFiUtils.h delete mode 100644 lib/ArduinoStreamUtils/.clang-format delete mode 100644 lib/ArduinoStreamUtils/.github/FUNDING.yml delete mode 100644 lib/ArduinoStreamUtils/.github/workflows/ci.yml delete mode 100644 lib/ArduinoStreamUtils/.gitignore delete mode 100644 lib/ArduinoStreamUtils/CHANGELOG.md delete mode 100644 lib/ArduinoStreamUtils/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/LICENSE.md delete mode 100644 lib/ArduinoStreamUtils/README.md delete mode 100644 lib/ArduinoStreamUtils/examples/EepromRead/EepromRead.ino delete mode 100644 lib/ArduinoStreamUtils/examples/EepromWrite/EepromWrite.ino delete mode 100644 lib/ArduinoStreamUtils/examples/HammingSerial1/HammingSerial1.ino delete mode 100644 lib/ArduinoStreamUtils/examples/HammingSoftwareSerial/HammingSoftwareSerial.ino delete mode 100644 lib/ArduinoStreamUtils/examples/Logger/Logger.ino delete mode 100644 lib/ArduinoStreamUtils/examples/ReadBuffer/ReadBuffer.ino delete mode 100644 lib/ArduinoStreamUtils/examples/ReadLogger/ReadLogger.ino delete mode 100644 lib/ArduinoStreamUtils/examples/StringPrint/StringPrint.ino delete mode 100644 lib/ArduinoStreamUtils/examples/StringStream/StringStream.ino delete mode 100644 lib/ArduinoStreamUtils/examples/WriteBuffer/WriteBuffer.ino delete mode 100644 lib/ArduinoStreamUtils/examples/WriteLogger/WriteLogger.ino delete mode 100644 lib/ArduinoStreamUtils/extras/images/EepromStream.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/HammingDecodingStream.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/HammingEncodingStream.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/HammingStream.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/Logger.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/ReadBuffer.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/ReadLogger.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/StringPrint.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/StringStream.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/WriteBuffer.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/WriteLogger.svg delete mode 100644 lib/ArduinoStreamUtils/extras/images/WriteWaitingStream.svg delete mode 100644 lib/ArduinoStreamUtils/extras/test/BufferingPrintTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/EepromStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/FailingAllocator.hpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/HammingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/HammingDecodingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/HammingDecodingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/HammingEncodingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/HammingEncodingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/HammingPrintTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/HammingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/LoggingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/LoggingPrintTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/LoggingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/MemoryStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/ReadBufferingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/ReadBufferingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/ReadLoggingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/ReadLoggingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/ReadThrottlingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/SpyingAllocator.hpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/StringPrintTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/StringStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/WaitingPrintTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/WriteBufferingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/WriteBufferingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/WriteLoggingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/WriteLoggingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/WriteWaitingClientTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/WriteWaitingStreamTest.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/Arduino.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/Client.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/Print.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/Stream.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/avr/WString.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/Arduino.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/Client.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/Print.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/Stream.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp32/WString.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/Arduino.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/Client.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/Print.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/Stream.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/esp8266/WString.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/nrf52/Arduino.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/nrf52/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/nrf52/Client.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/nrf52/Print.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/nrf52/Stream.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/nrf52/WString.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/samd/Arduino.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/samd/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/samd/Client.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/samd/Print.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/samd/Stream.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/samd/WString.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/Arduino.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/Client.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/Print.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/Stream.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/stm32/WString.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/Arduino.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/CMakeLists.txt delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/Client.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.cpp delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/Print.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/Stream.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/cores/teensy/WString.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/doctest.h delete mode 100644 lib/ArduinoStreamUtils/extras/test/main.cpp delete mode 100644 lib/ArduinoStreamUtils/keywords.txt delete mode 100644 lib/ArduinoStreamUtils/library.properties delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils.h delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CharArray.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CircularBuffer.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Buffers/LinearBuffer.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/ClientProxy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingDecodingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingEncodingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/LoggingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/MemoryClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadBufferingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadLoggingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/SpyingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteBufferingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteLoggingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteWaitingClient.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Configuration.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Helpers.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectForwardingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectSpyingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingDecodingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingEncodingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadBufferingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadForwardingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadLoggingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadSpyingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadThrottlingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteBufferingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteForwardingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteLoggingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteSpyingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteWaitingPolicy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Polyfills.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Ports/ArduinoThrottler.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Ports/DefaultAllocator.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Prints/BufferingPrint.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Prints/HammingPrint.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Prints/LoggingPrint.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Prints/PrintProxy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Prints/SpyingPrint.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Prints/StringPrint.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Prints/WaitingPrint.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/EepromStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingDecodingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingEncodingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/LoggingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/MemoryStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadBufferingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadLoggingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadThrottlingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/SpyingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/StreamProxy.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/StringStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteBufferingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteLoggingStream.hpp delete mode 100644 lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteWaitingStream.hpp create mode 100644 lib/TickerScheduler/README.md create mode 100644 lib/TickerScheduler/TickerScheduler.cpp create mode 100644 lib/TickerScheduler/TickerScheduler.h create mode 100644 lib/TickerScheduler/example/blink/blink/blink.ino create mode 100644 src/Global.cpp create mode 100644 src/WebServer.cpp create mode 100644 src/utils/FileUtils.cpp create mode 100644 src/utils/JsonUtils.cpp create mode 100644 src/utils/WiFiUtils.cpp diff --git a/data_svelte/check.json b/data_svelte/check.json deleted file mode 100644 index e69de29b..00000000 diff --git a/data_svelte/config.json b/data_svelte/config.json deleted file mode 100644 index d8a730c6..00000000 --- a/data_svelte/config.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "IoTmanager", - "chipID": "", - "apssid": "IoTmanager", - "appass": "", - "routerssid": "dlink", - "routerpass": "", - "timezone": 1, - "ntp": "pool.ntp.org", - "mqttServer": "91.204.228.124", - "mqttPort": 1883, - "mqttPrefix": "/iotTest3", - "mqttUser": "rise", - "mqttPass": "23ri22se32", - "mqttServer2": "M2.WQTT.RU", - "mqttPort2": 8021, - "mqttPrefix2": "/iotTest3", - "mqttUser2": "rise", - "mqttPass2": "hostel3333", - "scen": "1", - "telegramApi": "1416711569:AAEI0j83GmXqwzb_gnK1B0Am0gDwZoJt5xo", - "telegonof": "0", - "teleginput": "0", - "autos": "1", - "weblogin": "admin", - "webpass": "admin", - "MqttIn": "0", - "MqttOut": "0", - "blink": "0", - "oneWirePin": "2", - "serverip": "http://206.189.49.244", - "uart": "0", - "uartS": "9600", - "uartTX": "12", - "uartRX": "13", - "grafmax": "0" -} \ No newline at end of file diff --git a/data_svelte/settings.json b/data_svelte/settings.json new file mode 100644 index 00000000..0f8b460a --- /dev/null +++ b/data_svelte/settings.json @@ -0,0 +1,11 @@ +{ + "name": "IoTmanager", + "apssid": "IoTmanager", + "appass": "", + "routerssid": "rise", + "routerpass": "hostel3333", + "timezone": 1, + "ntp": "pool.ntp.org", + "weblogin": "admin", + "webpass": "admin" +} \ No newline at end of file diff --git a/data_svelte/setup.json b/data_svelte/setup.json deleted file mode 100644 index 88a9ae69..00000000 --- a/data_svelte/setup.json +++ /dev/null @@ -1,542 +0,0 @@ -[ - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 1, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 2, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 3, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 4, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 5, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 6, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 7, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 8, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 9, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 10, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 11, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 12, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 13, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 14, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 15, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 16, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 17, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 18, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 19, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 20, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 21, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 22, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 23, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 24, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 25, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 26, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 27, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 28, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 29, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 30, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 31, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 32, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 33, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 34, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 1, - "topic": "/prefix/123456-123456/btn1" - }, - "set": { - "id": "btn1", - "gpio": 35, - "inv": false - } - }, - { - "type": "button-out", - "web": { - "widget": "toggle", - "page": "Кнопки", - "descr": "Освещение", - "order": 2, - "topic": "/prefix/123456-123456/btn2" - }, - "set": { - "id": "btn2", - "gpio": 36, - "inv": false - } - } -] \ No newline at end of file diff --git a/data_svelte/sync.ffs_db b/data_svelte/sync.ffs_db deleted file mode 100644 index cd5cdf88e9c6cf1c9b78c0920fe43edb193cb8fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmZ=ON=zrNUvL=f|K$b~NfuRd1$PC1FKnwzt zIkmn_lvg}Hq5BA%5#x%J%q|%~Q3a5GAgGAbwtGMK00WDS!=9gyYuf+0_Be=fI~&fb zFpros^x8fTIobUu;EuAja0;I= f^R6FDj@~#b-f;GKh`s14Ifg?lPS*V9|1JXnwpT$2 diff --git a/include/Const.h b/include/Const.h new file mode 100644 index 00000000..ef02d585 --- /dev/null +++ b/include/Const.h @@ -0,0 +1,15 @@ +#pragma once + +#define FIRMWARE_VERSION 400 + +#define JSON_BUFFER_SIZE 4096 + +//задачи таскера +enum TimerTask_t { WIFI_SCAN, + WIFI_MQTT_CONNECTION_CHECK, + TIME, + TIME_SYNC, + UPTIME, + SYGNAL, + TIMES, + MYTEST }; \ No newline at end of file diff --git a/include/EspFileSystem.h b/include/EspFileSystem.h index 1758bfcf..4438a8cd 100644 --- a/include/EspFileSystem.h +++ b/include/EspFileSystem.h @@ -10,9 +10,3 @@ extern FS* filesystem; #define FS_NAME "LittleFS" extern bool fileSystemInit(); - -extern File seekFile(const String& filename, size_t position = 0); -extern const String writeFile(const String& filename, const String& str); -extern const String readFile(const String& filename, size_t max_size); -extern const String filepath(const String& filename); -extern bool cutFile(const String& src, const String& dst); \ No newline at end of file diff --git a/include/Global.h b/include/Global.h index dadf273d..8f174c2e 100644 --- a/include/Global.h +++ b/include/Global.h @@ -3,8 +3,19 @@ //внешние глобальные директории #include #include +#include #include -#include +#include //внутренние глобальные директории проекта -#include "Utils\SerialPrint.h" \ No newline at end of file +#include "Const.h" +#include "Utils/JsonUtils.h" +#include "Utils\SerialPrint.h" + +//глобальные объекты классов +extern TickerScheduler ts; + +//глобальные переменные +extern String settingsFlashJson; +extern String paramsFlashJson; +extern String paramsHeapJson; \ No newline at end of file diff --git a/include/WebServer.h b/include/WebServer.h new file mode 100644 index 00000000..5818624b --- /dev/null +++ b/include/WebServer.h @@ -0,0 +1,8 @@ +//#pragma once +// +//#include "Global.h" +// +// +// +// void initWS(); +// void init(); diff --git a/include/utils/FileUtils.h b/include/utils/FileUtils.h new file mode 100644 index 00000000..274ba22a --- /dev/null +++ b/include/utils/FileUtils.h @@ -0,0 +1,9 @@ +#pragma once +#include "EspFileSystem.h" +#include "Global.h" + +extern File seekFile(const String& filename, size_t position = 0); +extern const String writeFile(const String& filename, const String& str); +extern const String readFile(const String& filename, size_t max_size); +extern const String filepath(const String& filename); +extern bool cutFile(const String& src, const String& dst); \ No newline at end of file diff --git a/include/utils/JsonUtils.h b/include/utils/JsonUtils.h new file mode 100644 index 00000000..105067b4 --- /dev/null +++ b/include/utils/JsonUtils.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Global.h" + +String jsonReadStr(String& json, String name); +int jsonReadInt(String& json, String name); +boolean jsonReadBool(String& json, String name); + +String jsonWriteStr(String& json, String name, String value); +String jsonWriteInt(String& json, String name, int value); +String jsonWriteFloat(String& json, String name, float value); +String jsonWriteBool(String& json, String name, boolean value); + +bool jsonRead(String& json, String key, String& value); +bool jsonRead(String& json, String key, bool& value); +bool jsonRead(String& json, String key, int& value); + +bool jsonWriteStr_(String& json, String name, String value); +bool jsonWriteBool_(String& json, String name, bool value); +bool jsonWriteInt_(String& json, String name, int value); +bool jsonWriteFloat_(String& json, String name, float value); + +void saveConfig(); +void saveStore(); \ No newline at end of file diff --git a/include/utils/WiFiUtils.h b/include/utils/WiFiUtils.h new file mode 100644 index 00000000..e6b6b3ff --- /dev/null +++ b/include/utils/WiFiUtils.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Global.h" + +boolean isNetworkActive(); +void routerConnect(); +bool startAPMode(); +boolean RouterFind(String ssid); +uint8_t RSSIquality(); +extern void wifiSignalInit(); diff --git a/lib/ArduinoStreamUtils/.clang-format b/lib/ArduinoStreamUtils/.clang-format deleted file mode 100644 index 76317270..00000000 --- a/lib/ArduinoStreamUtils/.clang-format +++ /dev/null @@ -1,5 +0,0 @@ -BasedOnStyle: Google -AllowShortFunctionsOnASingleLine: Empty -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -IncludeBlocks: Preserve \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/.github/FUNDING.yml b/lib/ArduinoStreamUtils/.github/FUNDING.yml deleted file mode 100644 index 0ec57d0a..00000000 --- a/lib/ArduinoStreamUtils/.github/FUNDING.yml +++ /dev/null @@ -1,4 +0,0 @@ -github: bblanchon -custom: - - https://arduinojson.org/book/ - - https://donate.benoitblanchon.fr/ diff --git a/lib/ArduinoStreamUtils/.github/workflows/ci.yml b/lib/ArduinoStreamUtils/.github/workflows/ci.yml deleted file mode 100644 index 4458bfe0..00000000 --- a/lib/ArduinoStreamUtils/.github/workflows/ci.yml +++ /dev/null @@ -1,121 +0,0 @@ -name: Continuous Integration - -on: [push, pull_request] - -jobs: - test: - name: Unit Test - runs-on: ubuntu-latest - steps: - - name: Install - run: sudo apt-get install -y lcov - - name: Checkout - uses: actions/checkout@v2 - - name: Configure - run: cmake -DCOVERAGE=true . - - name: Build - run: cmake --build . - - name: Run tests - run: ctest --output-on-failure . - - name: Capture coverage data - run: lcov --capture --no-external --directory . --output-file coverage.info - - name: Filter coverage data - run: lcov --remove coverage.info "$(pwd)/extras/*" --output-file coverage_filtered.info - - name: Generate coverage report - run: mkdir coverage && genhtml coverage_filtered.info -o coverage -t ArduinoJson - - name: Upload coverage report - uses: actions/upload-artifact@v2 - with: - name: coverage - path: coverage - - name: Upload to Coveralls - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: coverage_filtered.info - - platformio: - name: PlatformIO - needs: test - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - platform: atmelavr - board: leonardo - eeprom: true - softwareserial: true - - platform: espressif8266 - board: huzzah - eeprom: true - softwareserial: true - - platform: espressif32 - board: esp32dev - eeprom: true - softwareserial: false - - platform: atmelsam - board: mkr1000USB - eeprom: false - softwareserial: false - - platform: teensy - board: teensy31 - eeprom: true - softwareserial: true - - platform: ststm32 - board: nucleo_f031k6 - eeprom: true - softwareserial: true - - platform: nordicnrf52 - board: adafruit_feather_nrf52840 - eeprom: false - softwareserial: true - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Set up cache - uses: actions/cache@v2 - with: - path: | - ~/.platformio - ~/.cache/pip - key: ${{ runner.os }}-platformio - - name: Set up Python 3.x - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Install PlatformIO - run: pip install platformio - - name: Install platform "${{ matrix.platform }}" - run: platformio platform install ${{ matrix.platform }} - - name: Install adafruit-nrfutil - if: ${{ matrix.platform == 'nordicnrf52' }} - run: pip3 install adafruit-nrfutil - - name: Include Adafruit_TinyUSB.h # https://github.com/adafruit/Adafruit_nRF52_Arduino/issues/653 - if: ${{ matrix.platform == 'nordicnrf52' }} - run: find examples/ -name '*.ino' -exec sed -i 's/\(#include \)/\1\n#include /' {} + - - name: Build EepromRead - if: ${{ matrix.eeprom }} - run: platformio ci "examples/EepromRead/EepromRead.ino" -l '.' -b ${{ matrix.board }} - - name: Build EepromWrite - if: ${{ matrix.eeprom }} - run: platformio ci "examples/EepromWrite/EepromWrite.ino" -l '.' -b ${{ matrix.board }} - - name: Build HammingSerial1 - run: platformio ci "examples/HammingSerial1/HammingSerial1.ino" -l '.' -b ${{ matrix.board }} - - name: Build HammingSoftwareSerial - if: ${{ matrix.softwareserial }} - run: platformio ci "examples/HammingSoftwareSerial/HammingSoftwareSerial.ino" -l '.' -b ${{ matrix.board }} - - name: Build Logger - run: platformio ci "examples/Logger/Logger.ino" -l '.' -b ${{ matrix.board }} - - name: Build ReadBuffer - run: platformio ci "examples/ReadBuffer/ReadBuffer.ino" -l '.' -b ${{ matrix.board }} - - name: Build ReadLogger - run: platformio ci "examples/ReadLogger/ReadLogger.ino" -l '.' -b ${{ matrix.board }} - - name: Build StringPrint - run: platformio ci "examples/StringPrint/StringPrint.ino" -l '.' -b ${{ matrix.board }} - - name: Build StringStream - run: platformio ci "examples/StringStream/StringStream.ino" -l '.' -b ${{ matrix.board }} - - name: Build WriteBuffer - run: platformio ci "examples/WriteBuffer/WriteBuffer.ino" -l '.' -b ${{ matrix.board }} - - name: Build WriteLogger - run: platformio ci "examples/WriteLogger/WriteLogger.ino" -l '.' -b ${{ matrix.board }} diff --git a/lib/ArduinoStreamUtils/.gitignore b/lib/ArduinoStreamUtils/.gitignore deleted file mode 100644 index a7747886..00000000 --- a/lib/ArduinoStreamUtils/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build - diff --git a/lib/ArduinoStreamUtils/CHANGELOG.md b/lib/ArduinoStreamUtils/CHANGELOG.md deleted file mode 100644 index ae38a39c..00000000 --- a/lib/ArduinoStreamUtils/CHANGELOG.md +++ /dev/null @@ -1,79 +0,0 @@ -StreamUtils - Change log -======================== - -HEAD ----- - -* Support `Print::flush()` on AVR - -1.6.1 (2021/94/05) ------ - -* Add example `HammingSerial1.ino` -* Add support for STM32 (issue #11) - - -1.6.0 (2020/11/20) ------ - -* Add `HammingPrint<7, 4>` -* Add `HammingStream<7, 4>`, `HammingEncodingStream<7, 4>`, and `HammingDecodingStream<7, 4>` -* Add `HammingClient<7, 4>`, `HammingEncodingClient<7, 4>`, and `HammingDecodingClient<7, 4>` - -1.5.0 (2020/08/04) ------ - -* Add `WaitingPrint`, `WriteWaitingClient`, and `WriteWaitingStream`. - -1.4.1 (2020/07/01) ------ - -* Fix unwanted waits in `ReadBufferingClient` and `ReadBufferingStream`. -* Stop calling `Client::read()` in place of `Stream::readBytes()`, - because it doesn't honor the timeout. - -1.4.0 (2020/03/30) ------ - -* Add `EepromStream` -* Add support for ESP32 -* Add support for Teensy - -1.3.0 (2020/01/20) ------ - -* Move auxiliary content to `extras/` to comply with new library layout -* Add `StringPrint` and `StringStream` -* Extract `StreamUtils.hpp`, same as `StreamUtils.h` except it keeps everything in the `StreamUtils` namespace. - -1.2.2 (2019/07/18) ------ - -* Fix `BufferingPrint` taking `Stream` instead of `Print` (issue #3) -* Fix `LoggingPrint` not forwarding call to `Print::flush()` -* Fix missing `override` specifiers - -1.2.1 (2019/06/05) ------ - -* Remove workaround for ESP8266 core 2.5.0 -* Fix compatibility with ESP8266 core 2.5.1+ (issue #2) - -1.2.0 (2019/05/01) ------ - -* Add `LoggingPrint` -* Add `BufferingPrint` -* Add `WriteLoggingClient`, `ReadLoggingClient`, and `LoggingClient` -* Add `WriteBufferingClient` and `ReadBufferingClient` - -1.1.0 (2019/04/20) ------ - -* Add `LoggingStream` (=`ReadLoggingStream` + `WriteLoggingStream`) - -1.0.0 (2019/04/14) ------ - -* Add `ReadBufferingStream` and `WriteBufferingStream` -* Add `ReadLoggingStream` and `WriteLoggingStream` diff --git a/lib/ArduinoStreamUtils/CMakeLists.txt b/lib/ArduinoStreamUtils/CMakeLists.txt deleted file mode 100644 index 26061d64..00000000 --- a/lib/ArduinoStreamUtils/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -cmake_minimum_required(VERSION 3.0) -project(StreamUtils) - -enable_testing() - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -if(${COVERAGE}) - set(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage -g -O0") -endif() - -include_directories(${CMAKE_CURRENT_LIST_DIR}/src) -add_subdirectory(extras/test) diff --git a/lib/ArduinoStreamUtils/LICENSE.md b/lib/ArduinoStreamUtils/LICENSE.md deleted file mode 100644 index 4774d78c..00000000 --- a/lib/ArduinoStreamUtils/LICENSE.md +++ /dev/null @@ -1,10 +0,0 @@ -The MIT License (MIT) ---------------------- - -Copyright © 2019 Benoit BLANCHON - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/ArduinoStreamUtils/README.md b/lib/ArduinoStreamUtils/README.md deleted file mode 100644 index a03ffe9e..00000000 --- a/lib/ArduinoStreamUtils/README.md +++ /dev/null @@ -1,369 +0,0 @@ -StreamUtils: Power-ups for Arduino Streams -========================================== - -[![arduino-library-badge](https://www.ardu-badge.com/badge/StreamUtils.svg?version=1.6.1)](https://www.ardu-badge.com/StreamUtils/1.6.1) -[![Continuous Integration](https://github.com/bblanchon/ArduinoStreamUtils/workflows/Continuous%20Integration/badge.svg)](https://github.com/bblanchon/ArduinoStreamUtils/actions/workflows/ci.yml) -[![Coverage Status](https://coveralls.io/repos/github/bblanchon/ArduinoStreamUtils/badge.svg)](https://coveralls.io/github/bblanchon/ArduinoStreamUtils) - -The *stream* is an essential abstraction in Arduino; we find it in many places: - -* [`HardwareSerial`](https://www.arduino.cc/reference/en/language/functions/communication/serial/) -* [`SoftwareSerial`](https://www.arduino.cc/en/Reference/SoftwareSerial) -* [`File`](https://www.arduino.cc/en/Reference/SD) -* [`EthernetClient`](https://www.arduino.cc/en/Reference/EthernetClient) -* [`WiFiClient`](https://www.arduino.cc/en/Reference/WiFiClient) -* [`Wire`](https://www.arduino.cc/en/reference/wire) -* and many others... - -This library provides some helper classes and functions for dealing with streams. - -For example, with this library, you can: - -* speed of your program by buffering the data it reads from a file -* reduce the number of packets sent over WiFi by buffering the data you send -* improve the reliability of a serial connection by adding error correction codes -* debug your program more easily by logging what it sends to a Web service -* send large data with the [Wire library](https://www.arduino.cc/en/reference/wire) -* use a `String` or EEPROM with a stream interface - -Read on to see how StreamUtils can help you! - - -How to add buffering to a Stream? ---------------------------------- - -### Buffering read operations - -Sometimes, you can significantly improve performance by reading many bytes at once. -For example, [according to SPIFFS's wiki](https://github.com/pellepl/spiffs/wiki/Performance-and-Optimizing#reading-files), it's much faster to read files in chunks of 64 bytes than reading them one byte at a time. - -![ReadBufferingStream](extras/images/ReadBuffer.svg) - -To buffer the input, simply decorate the original `Stream` with `ReadBufferingStream`. For example, suppose your program reads a JSON document from SPIFFS, like that: - -```c++ -File file = SPIFFS.open("example.json", "r"); -deserializeJson(doc, file); -``` - -Then you simply need to insert one line to greatly improve the reading speed: - -```c++ -File file = SPIFFS.open("example.json", "r"); -ReadBufferingStream bufferedFile{file, 64}; // <- HERE -deserializeJson(doc, bufferedFile); -``` - -Unfortunately, this optimization is only possible if: - -1. `Stream.readBytes()` is declared `virtual` in your Arduino Code (as it's the case for ESP8266), and -2. the derived class has an optimized implementation of `readBytes()` (as it's the case for SPIFFS' `File`). - -When possible, prefer `ReadBufferingClient` to `ReadBufferingStream` because `Client` defines a `read()` method similar to `readBytes()`, except that this one is `virtual` on all platforms. - -If memory allocation fails, `ReadBufferingStream` behaves as if no buffer was used: it forwards all calls to the upstream `Stream`. - -Adding a buffer only makes sense for **unbuffered** streams. For example, there is **no benefit to adding a buffer to serial ports** because they already include an internal buffer. - -### Buffering write operations - -Similarly, you can improve performance significantly by writing many bytes at once. -For example, if you write to `WiFiClient` one bytes at a time, it will be very slow; it's much faster if you send large chunks. - -![WriteBufferingStream](extras/images/WriteBuffer.svg) - -To add a buffer, decorate the original `Stream` with `WriteBufferingStream`. For example, if your program sends a JSON document via `WiFiClient`, like that: - -```c++ -serializeJson(doc, wifiClient); -``` - -Then, you just need to add two lines: - -```c++ -WriteBufferingStream bufferedWifiClient{wifiClient, 64}; -serializeJson(doc, bufferedWifiClient); -bufferedWifiClient.flush(); -``` - -`flush()` sends the remaining data; if you forget to call it, the end of the message will be missing. The destructor of `WriteBufferingStream` calls `flush()`, so you can remove this line if you destroy the decorator immediately. - -If memory allocation fails, `WriteBufferingStream` behaves as if no buffer was used: it forwards all calls to the upstream `Stream`. - -Adding a buffer only makes sense for **unbuffered** streams. For example, there is **no benefit to adding a buffer to serial ports** because they already include an internal buffer. - -How to add logging to a stream? -------------------------------- - -### Logging write operations - -When debugging a program that makes HTTP requests, the first thing you want to check is that the request is correct. With this library, you can decorate the `EthernetClient` or the `WiFiClient` to log everything to the serial. - -![WriteLoggingStream](extras/images/WriteLogger.svg) - -For example, if you program is: - -```c++ -client.println("GET / HTTP/1.1"); -client.println("User-Agent: Arduino"); -// ... -``` - -Then, you just need to create the decorator, and update the calls to `println()`: - -```c++ -WriteLoggingStream loggingClient(client, Serial); -loggingClient.println("GET / HTTP/1.1"); -loggingClient.println("User-Agent: Arduino"); -// ... -``` - -Everything you write to `loggingClient` is written to `client` and logged to `Serial`. - - -### Logging read operations - -Similarly, you often want to see what the HTTP server sent back. With this library, you can decorate the `EthernetClient` or the `WiFiClient` to log everything to the serial. - -![ReadLoggingStream](extras/images/ReadLogger.svg) - -For example, if you program is: - -```c++ -char response[256]; -client.readBytes(response, 256); -``` - -Then, you just need to create the decorator, and update the calls to `readBytes()`: - -```c++ -ReadLoggingStream loggingClient(client, Serial); -char response[256]; -loggingClient.readBytes(response, 256); -// ... -``` - -`loggingClient` forwards all operations to `client` and logs read operation to `Serial`. - -⚠ **WARNING** ⚠ -If your program receives data from one serial port and logs to another one, **make sure the latter runs at a much higher speed**. Logging must be at least ten times faster, or it will slow down the receiving port, which may drop incoming bytes. - -### Logging read and write operations - -Of course, you could log read and write operations by combining `ReadLoggingStream` and `WriteLoggingStream`, but there is a simpler solution: `LoggingStream`. - -![LoggingStream](extras/images/Logger.svg) - -As usual, if your program is: - -```c++ -client.println("GET / HTTP/1.1"); -client.println("User-Agent: Arduino"); - -char response[256]; -client.readBytes(response, 256); -``` - -Then decorate `client` and replace the calls: - -```c++ -LoggingStream loggingClient(client, Serial); - -loggingClient.println("GET / HTTP/1.1"); -loggingClient.println("User-Agent: Arduino"); - -char response[256]; -loggingClient.readBytes(response, 256); -``` - -How to use error-correction codes (ECC)? ----------------------------------------- - -StreamUtils supports the [Hamming(7, 4)](https://en.wikipedia.org/wiki/Hamming(7,4)) error-correction code, which encodes 4 bits of data into 7 bits by adding three parity bits. -These extra bits increase the amount of traffic but allow correcting any one-bit error within the 7 bits. - -If you use this encoding on an 8-bit channel, it effectively doubles the amount of traffic. However, if you use an [`HardwareSerial`](https://www.arduino.cc/reference/en/language/functions/communication/serial/) instance (like `Serial`, `Serial1`...), you can slightly reduce the overhead by configuring the ports as a 7-bit channel, like so: - -```c++ -// Initialize serial port with 9600 bauds, 7-bits of data, no parity, and one stop bit -Serial1.begin(9600, SERIAL_7N1); -``` - -### Adding parity bits - -The class `HammingEncodingStream<7, 4>` decorates an existing `Stream` to include parity bits in every write operation. - -![HammingEncodingStream](extras/images/HammingEncodingStream.svg) - -You can use this class like so: - -```c++ -HammingEncodingStream<7, 4> eccSerial(Serial1); - -eccSerial.println("Hello world!"); -``` - -Like every `Stream` decorator in this library, `HammingEncodingStream<7, 4>` supports all `Stream` methods (like `print()`, `println()`, `read()`, `readBytes()`, and `available()`). - -### Correcting errors - -The class `HammingDecodingStream<7, 4>` decorates an existing `Stream` to decode parity bits in every read operation. - -![HammingDecodingStream](extras/images/HammingDecodingStream.svg) - -You can use this class like so: - -```c++ -HammingDecodingStream<7, 4> eccSerial(Serial1); - -char buffer[256]; -size_t n = eccSerial.readBytes(buffer, n); -``` - -Like every `Stream` decorator in this library, `HammingDecodingStream<7, 4>` supports all `Stream` methods (like `print()`, `println()`, `read()`, `readBytes()`, and `available()`). - -### Encoding and decoding in both directions - -The class `HammingStream<7, 4>` combines the features of `HammingEncodingStream<7, 4>` and `HammingDecodingStream<7, 4>`, which is very useful when you do a two-way communication. - -![HammingStream](extras/images/HammingStream.svg) - -You can use this class like so: - -```c++ -HammingStream<7, 4> eccSerial(Serial1); - -eccSerial.println("Hello world!"); - -char buffer[256]; -size_t n = eccSerial.readBytes(buffer, n); -``` - -Like every `Stream` decorator in this library, `HammingStream<7, 4>` supports all `Stream` methods (like `print()`, `println()`, `read()`, `readBytes()`, and `available()`). - - -How to retry write operations? ------------------------------- - -Sometimes, a stream is limited to the capacity of its internal buffer. In that case, you must wait before sending more data. -To solve this problem, StreamUtils provides the `WriteWaitingStream` decorator: - -![WriteWaitingStream](extras/images/WriteWaitingStream.svg) - -This function repeatedly waits and retries until it times out. -You can customize the `wait()` function; by default, it's [`yield()`](https://www.arduino.cc/en/Reference/SchedulerYield). - -For example, if you want to send more than 32 bytes with the [Wire library](https://www.arduino.cc/en/reference/wire), you can do: - -```c++ -WriteWaitingStream wireStream(Wire, [](){ - Wire.endTransmission(false); // <- don't forget this argument - Wire.beginTransmission(address); -}); - -Wire.beginTransmission(address); -wireStream.print("This is a very very long message that I'm sending!"); -Wire.endTransmission(); -``` - -As you can see, we use the `wait()` function as a hook to flush the Wire transmission buffer. Notice that we pass `false` to [`endTransmission()`](https://www.arduino.cc/en/Reference/WireEndTransmission) so that it sends the data but doesn't actually stop the transmission. - - -How to use a `String` as a stream? ---------------------- - -### Writing to a `String` - -Sometimes, you use a piece of code that expects a `Print` instance (like `ReadLoggingStream`), but you want the output in a `String` instead of a regular `Stream`. -In that case, use the `StringPrint` class. It wraps a `String` within a `Print` implementation. - -![StringPrint](extras/images/StringPrint.svg) - -Here is how you can use it: - -```c++ -StringPrint stream; - -stream.print("Temperature = "); -stream.print(22.3); -stream.print(" °C"); - -String result = stream.str(); -``` - -At the end of this snippet, the string `result` contains: - -``` -Temperature = 22.30 °C -``` - -### Reading from a `String` - -Similarly, there are cases where you have a `String`, but you need to pass a `Stream` to some other piece of code. In that case, use `StringStream`; it's similar to `StrintPrint`, except you can read as well. - -![StringStream](extras/images/StringStream.svg) - - -How to use EEPROM as a stream? ------------------------------- - -SteamUtils also allows using EEPROM as a stream. Simply create an instance of `EepromStream` and specify the start address and the size of the region you want to expose. - -![EepromStream](extras/images/EepromStream.svg) - -For example, it allows you to save a JSON document in EEPROM: - -```c++ -EepromStream eepromStream(0, 128); -serializeJson(doc, eepromStream); -eepromStream.flush(); // <- calls EEPROM.commit() on ESP (optional) -``` - -In the same way, you can read a JSON document from EEPROM: - -```c++ -EepromStream eepromStream(0, 128); -deserializeJson(doc, eepromStream); -``` - - -Summary -------- - -Some of the decorators are also available for the `Print` and `Client` classes. -See the equivalence table below. - -| Purpose | `Client` | `Stream` | `Print` | -|:-----------------------------------|:------------------------|:------------------------|:-----------------| -| Log *write* operations | `WriteLoggingClient` | `WriteLoggingStream` | `LoggingPrint` | -| Log *read* operations | `ReadLoggingClient` | `ReadLoggingStream` | | -| Log *read* and *write* op. | `LoggingClient` | `LoggingStream` | | -| Buffer *write* operations | `WriteBufferingClient` | `WriteBufferingStream` | `BufferingPrint` | -| Buffer *read* operations | `ReadBufferingClient` | `ReadBufferingStream` | | -| Repeat *write* operations | `WriteWaitingClient` | `WriteWaitingStream` | `WaitingPrint` | -| Use `String` as a stream | | `StringStream` | `StringPrint` | -| Use EEPROM as a stream | | `EepromStream` | | -| Error correction (decode only) | `HammingDecodingClient` | `HammingDecodingStream` | | -| Error correction (encode only) | `HammingEncodingClient` | `HammingEncodingStream` | `HammingPrint` | -| Error correction (encode & decode) | `HammingClient` | `HammingStream` | | - -When possible, prefer `ReadBufferingClient` to `ReadBufferingStream` because `Client::read()` often provides an optimized implementation. - - -Portability ------------ - -This library relies on the definitions of `Client`, `Print`, and `Stream`, which unfortunately differ from one core to another. - -It has been tested on the following cores: - -* [AVR](https://github.com/arduino/ArduinoCore-avr) -* [ESP32](https://github.com/espressif/arduino-esp32) -* [ESP8266](https://github.com/esp8266/Arduino) -* [nRF52](https://github.com/adafruit/Adafruit_nRF52_Arduino) -* [SAMD](https://github.com/arduino/ArduinoCore-samd) -* [STM32](https://github.com/stm32duino/Arduino_Core_STM32) -* [Teensy](https://github.com/PaulStoffregen/cores) - -If your core is not supported, please [open an issue](https://github.com/bblanchon/ArduinoStreamUtils/issues/new). -Thank you for your understanding. diff --git a/lib/ArduinoStreamUtils/examples/EepromRead/EepromRead.ino b/lib/ArduinoStreamUtils/examples/EepromRead/EepromRead.ino deleted file mode 100644 index fb5ed409..00000000 --- a/lib/ArduinoStreamUtils/examples/EepromRead/EepromRead.ino +++ /dev/null @@ -1,63 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to read from EEPROM - -#include - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; - -#if STREAMUTILS_ENABLE_EEPROM - -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) - Serial.println("Initializing EEPROM..."); - EEPROM.begin(512); -#endif - - Serial.println("Make sure to run the EepromWrite example first!"); - - Serial.println("Reading EEPROM... "); - EepromStream s(0, 12); - Serial.print(s.readString()); - -#else - Serial.println("EepromStream is not supported on this platform. Sorry"); -#endif -} - -void loop() { - // not used in this example -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/EepromWrite/EepromWrite.ino b/lib/ArduinoStreamUtils/examples/EepromWrite/EepromWrite.ino deleted file mode 100644 index 4e988268..00000000 --- a/lib/ArduinoStreamUtils/examples/EepromWrite/EepromWrite.ino +++ /dev/null @@ -1,69 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to read from EEPROM - -#include - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; - -#if STREAMUTILS_ENABLE_EEPROM - -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) - Serial.println("Initializing EEPROM..."); - EEPROM.begin(512); -#endif - - Serial.println("Writing to EEPROM..."); - EepromStream s(0, 12); - s.print("Hello World!"); - -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) - Serial.println("Saving..."); - s.flush(); // only required on ESP -#endif - - Serial.println("Done!"); - Serial.println("Now, run the EepromRead example."); - -#else - Serial.println("EepromStream is not supported on this platform. Sorry"); -#endif -} - -void loop() { - // not used in this example -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/HammingSerial1/HammingSerial1.ino b/lib/ArduinoStreamUtils/examples/HammingSerial1/HammingSerial1.ino deleted file mode 100644 index 16338a06..00000000 --- a/lib/ArduinoStreamUtils/examples/HammingSerial1/HammingSerial1.ino +++ /dev/null @@ -1,68 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to use Hamming codes for error correction -// -// To run this program, you need two boards that support Serial1 with the same -// voltage. For example: Arduino Mega, Leonardo, or Nano Every (all 5V boards) -// -// Connect the TX pin of one board to the RX pin of the other and vice-versa. - -#include - -HammingStream<7, 4> eccSerial1(Serial1); - -void setup() { - Serial.begin(115200); - while (!Serial) - continue; - - Serial1.begin(9600); - while (!Serial) - continue; - - // Discard any remaining data in the input buffer - while (Serial1.available()) - Serial1.read(); -} - -void loop() { - // Did we receive something? - if (eccSerial1.available()) - // Print it - Serial.write(eccSerial1.read()); - - // Do we have something to send? - if (Serial.available()) - // Sent it - eccSerial1.write(Serial.read()); -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/HammingSoftwareSerial/HammingSoftwareSerial.ino b/lib/ArduinoStreamUtils/examples/HammingSoftwareSerial/HammingSoftwareSerial.ino deleted file mode 100644 index bf63bde0..00000000 --- a/lib/ArduinoStreamUtils/examples/HammingSoftwareSerial/HammingSoftwareSerial.ino +++ /dev/null @@ -1,67 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to use Hamming codes for error correction -// -// To run this program, you need two boards connected like so: -// BOARD 1 - BOARD 2 -// pin 10 - pin 11 -// pin 11 - pin 10 -// -// SoftwareSerial is here for demonstration purposes; please don't use it in -// production, as it is notoriously unreliable. - -#include -#include - -SoftwareSerial linkSerial(10, 11); // RX, TX -HammingStream<7, 4> eccLinkSerial(linkSerial); - -void setup() { - Serial.begin(115200); - while (!Serial) - continue; - - linkSerial.begin(4800); -} - -void loop() { - // Did we receive something? - if (eccLinkSerial.available()) - // Print it - Serial.write(eccLinkSerial.read()); - - // Do we have something to send? - if (Serial.available()) - // Sent it - eccLinkSerial.write(Serial.read()); -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/Logger/Logger.ino b/lib/ArduinoStreamUtils/examples/Logger/Logger.ino deleted file mode 100644 index ccb483ed..00000000 --- a/lib/ArduinoStreamUtils/examples/Logger/Logger.ino +++ /dev/null @@ -1,61 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to log what goes through a Stream, both reads and -// writes operations. - -#include - -// Create a new stream that will forward all calls to Serial, and log to Serial. -// Everything will be written twice to the Serial! -LoggingStream loggingStream(Serial, Serial); - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; - - // Write to the serial port. - // Because loggingStream logs each write operation, the string will we written - // twice - loggingStream.println("Hello World!"); -} - -void loop() { - // Read from the serial port. - // Because loggingStream logs each read operation, everything we read is - // printed back to the serial port. - while (loggingStream.available()) { - loggingStream.read(); - } -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/ReadBuffer/ReadBuffer.ino b/lib/ArduinoStreamUtils/examples/ReadBuffer/ReadBuffer.ino deleted file mode 100644 index 62e1aa4d..00000000 --- a/lib/ArduinoStreamUtils/examples/ReadBuffer/ReadBuffer.ino +++ /dev/null @@ -1,56 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to buffer the read operations of a stream. -// -// Like "echo," it reads from the serial port and prints back the same thing. -// What's interesting with this program is that it reads the input in chunks of -// 64 bytes, even if it seems to read them one by one. - -#include - -ReadBufferingStream bufferedSerial{Serial, 64}; - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; -} - -void loop() { - // Even if it looks like the bytes are extracted one by one, they are actually - // read by chunks of 64 bytes and placed in a buffer. - while (bufferedSerial.available()) { - Serial.write(bufferedSerial.read()); - } -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/ReadLogger/ReadLogger.ino b/lib/ArduinoStreamUtils/examples/ReadLogger/ReadLogger.ino deleted file mode 100644 index 204ef9d3..00000000 --- a/lib/ArduinoStreamUtils/examples/ReadLogger/ReadLogger.ino +++ /dev/null @@ -1,55 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to log what read from a Stream - -#include - -// Create a new stream that will forward all calls to Serial, and log to Serial. -// It will write back everything it reads, just like "echo" -ReadLoggingStream loggingStream(Serial, Serial); - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; -} - -void loop() { - // Read the serial port. - // Because loggingStream write everything it read, the program will show what - // you sent. - while (Serial.available()) { - loggingStream.write(Serial.read()); - } -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/StringPrint/StringPrint.ino b/lib/ArduinoStreamUtils/examples/StringPrint/StringPrint.ino deleted file mode 100644 index 30b5eb46..00000000 --- a/lib/ArduinoStreamUtils/examples/StringPrint/StringPrint.ino +++ /dev/null @@ -1,54 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to use StringPrint - -#include - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; - - StringPrint stream; - - stream.print("Temperature = "); - stream.print(22.3); - stream.print(" °C"); - - Serial.print(stream.str()); -} - -void loop() { - // no used in this example -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/StringStream/StringStream.ino b/lib/ArduinoStreamUtils/examples/StringStream/StringStream.ino deleted file mode 100644 index 89d82c86..00000000 --- a/lib/ArduinoStreamUtils/examples/StringStream/StringStream.ino +++ /dev/null @@ -1,55 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to use StringStream - -#include - -StringStream stream; - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; - - stream.print("Temperature = "); - stream.print(22.3); - stream.print(" °C"); -} - -void loop() { - if (stream.available() > 0) { - Serial.print((char)stream.read()); - } - delay(250); -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/WriteBuffer/WriteBuffer.ino b/lib/ArduinoStreamUtils/examples/WriteBuffer/WriteBuffer.ino deleted file mode 100644 index 7e68487d..00000000 --- a/lib/ArduinoStreamUtils/examples/WriteBuffer/WriteBuffer.ino +++ /dev/null @@ -1,62 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to buffer writes to a stream. -// -// Like "echo," it reads from the serial port and prints back the same thing. -// What's interesting with this program is that it writes in chunks of -// 8 bytes, even if it seems to write them one by one. -// -// As you'll see, you need to type at least 8 bytes to see something. That's -// because it waits for the buffered to be full before sending it to the serial. - -#include - -// Create a new Stream that buffers all writes to Serial -WriteBufferingStream bufferedSerial{Serial, 8}; - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; - - Serial.println(F("Send at least 8 bytes to see the result")); -} - -void loop() { - // Even if it looks like the bytes are sent one by one, they are actual - // written in chunks of 8 bytes. - while (Serial.available()) { - bufferedSerial.write(Serial.read()); - } -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/examples/WriteLogger/WriteLogger.ino b/lib/ArduinoStreamUtils/examples/WriteLogger/WriteLogger.ino deleted file mode 100644 index f08e4e40..00000000 --- a/lib/ArduinoStreamUtils/examples/WriteLogger/WriteLogger.ino +++ /dev/null @@ -1,55 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License -// -// This example shows how to log what written to a Stream - -#include - -// Create a new stream that will forward all calls to Serial, and log to Serial. -// Everything will be written twice to the Serial! -WriteLoggingStream loggingStream(Serial, Serial); - -void setup() { - // Initialize serial port - Serial.begin(9600); - while (!Serial) - continue; - - // Write to the serial port. - // Because loggingStream logs each write operation, the string will we written - // twice - loggingStream.println("Hello World!"); -} - -void loop() { - // not used in this example -} - -/***************************************************** - * * - * Love this project? * - * Star it on GitHub! * - * * - * .,,. * - * ,,:1. * - * ,.,:;1 * - * .,,,::;: * - * ,,,,::;;. * - * .,,,:::;;; * - * .....,,,,...,.,,,,,,:::,,,,,,,,,,,,, * - * ,,,,,,,,,,,:,...,,,,,,:::,,,,:::;;;11l * - * .;::::::::,,,,,,,,,,:::::,,::;;;1lt * - * .;;;:::,,,,,,,,::::::;:::;;1t: * - * :;;:,,,,,,::::::;;;;;;l1 * - * ,,,,:::::::;;;;;;l * - * .,,,,::::;;;;;;;:::: * - * ,,,,,:::;;;;;::,:::1 * - * ,,,,,::;;;t1:,,:::::;l * - * .,,,,:;;ll ;::::::;;, * - * ,,,:;ll. .1:::;;l * - * .,:lt, .1;;l: * - * * - * https://github.com/bblanchon/ArduinoStreamUtils * - * * - *****************************************************/ \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/EepromStream.svg b/lib/ArduinoStreamUtils/extras/images/EepromStream.svg deleted file mode 100644 index efe2433e..00000000 --- a/lib/ArduinoStreamUtils/extras/images/EepromStream.svg +++ /dev/null @@ -1 +0,0 @@ -EEPROM \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/HammingDecodingStream.svg b/lib/ArduinoStreamUtils/extras/images/HammingDecodingStream.svg deleted file mode 100644 index 1330fde7..00000000 --- a/lib/ArduinoStreamUtils/extras/images/HammingDecodingStream.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginalparity bits \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/HammingEncodingStream.svg b/lib/ArduinoStreamUtils/extras/images/HammingEncodingStream.svg deleted file mode 100644 index a2129454..00000000 --- a/lib/ArduinoStreamUtils/extras/images/HammingEncodingStream.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginalparity bits \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/HammingStream.svg b/lib/ArduinoStreamUtils/extras/images/HammingStream.svg deleted file mode 100644 index 10471609..00000000 --- a/lib/ArduinoStreamUtils/extras/images/HammingStream.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginalparity bitsparity bits \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/Logger.svg b/lib/ArduinoStreamUtils/extras/images/Logger.svg deleted file mode 100644 index 6be65429..00000000 --- a/lib/ArduinoStreamUtils/extras/images/Logger.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginallog \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/ReadBuffer.svg b/lib/ArduinoStreamUtils/extras/images/ReadBuffer.svg deleted file mode 100644 index b0913bb7..00000000 --- a/lib/ArduinoStreamUtils/extras/images/ReadBuffer.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginalbuffer \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/ReadLogger.svg b/lib/ArduinoStreamUtils/extras/images/ReadLogger.svg deleted file mode 100644 index f7ed4bc1..00000000 --- a/lib/ArduinoStreamUtils/extras/images/ReadLogger.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginallog \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/StringPrint.svg b/lib/ArduinoStreamUtils/extras/images/StringPrint.svg deleted file mode 100644 index 345696b4..00000000 --- a/lib/ArduinoStreamUtils/extras/images/StringPrint.svg +++ /dev/null @@ -1 +0,0 @@ -String \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/StringStream.svg b/lib/ArduinoStreamUtils/extras/images/StringStream.svg deleted file mode 100644 index ecd0863a..00000000 --- a/lib/ArduinoStreamUtils/extras/images/StringStream.svg +++ /dev/null @@ -1 +0,0 @@ -String \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/WriteBuffer.svg b/lib/ArduinoStreamUtils/extras/images/WriteBuffer.svg deleted file mode 100644 index 5b25c9d7..00000000 --- a/lib/ArduinoStreamUtils/extras/images/WriteBuffer.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginalbuffer \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/WriteLogger.svg b/lib/ArduinoStreamUtils/extras/images/WriteLogger.svg deleted file mode 100644 index a5b27242..00000000 --- a/lib/ArduinoStreamUtils/extras/images/WriteLogger.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginallog \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/images/WriteWaitingStream.svg b/lib/ArduinoStreamUtils/extras/images/WriteWaitingStream.svg deleted file mode 100644 index ca916f70..00000000 --- a/lib/ArduinoStreamUtils/extras/images/WriteWaitingStream.svg +++ /dev/null @@ -1 +0,0 @@ -decoratedoriginalwait() \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/BufferingPrintTest.cpp b/lib/ArduinoStreamUtils/extras/test/BufferingPrintTest.cpp deleted file mode 100644 index b6ba96a5..00000000 --- a/lib/ArduinoStreamUtils/extras/test/BufferingPrintTest.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Prints/BufferingPrint.hpp" -#include "StreamUtils/Prints/SpyingPrint.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("BufferingPrint") { - StringPrint target; - - StringPrint log; - SpyingPrint spy{target, log}; - - GIVEN("capacity is 4") { - BufferingPrint bufferingPrint{spy, 4}; - - SUBCASE("flush() calls write()") { - bufferingPrint.write("ABC", 3); - bufferingPrint.flush(); - -#if STREAMUTILS_PRINT_FLUSH_EXISTS - CHECK(log.str() == - "write('ABC', 3) -> 3" - "flush()"); -#else - CHECK(log.str() == "write('ABC', 3) -> 3"); -#endif - } - - GIVEN("the buffer is empty") { - SUBCASE("write(uint8_t)") { - int n = bufferingPrint.write('A'); - - CHECK(n == 1); - CHECK(log.str() == ""); - } - - SUBCASE("write(uint8_t) should flush") { - bufferingPrint.write('A'); - bufferingPrint.write('B'); - bufferingPrint.write('C'); - bufferingPrint.write('D'); - bufferingPrint.write('E'); - - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - - SUBCASE("write(char*,3) goes in buffer") { - size_t n = bufferingPrint.write("ABC", 3); - - CHECK(n == 3); - CHECK(log.str() == ""); - } - - SUBCASE("write(char*,4) bypasses buffer") { - size_t n = bufferingPrint.write("ABCD", 4); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - SUBCASE("write(char*,2) bypasses buffer") { - size_t n = bufferingPrint.write("ABCD", 4); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - } - - GIVEN("one byte in the buffer") { - bufferingPrint.write('A'); - - SUBCASE("write(char*,3) goes in buffer and flush") { - size_t n = bufferingPrint.write("BCD", 3); - - CHECK(n == 3); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - - SUBCASE("write(char*,7) bypasses") { - size_t n = bufferingPrint.write("BCDEFGH", 7); - - CHECK(n == 7); - CHECK(log.str() == - "write('ABCD', 4) -> 4" - "write('EFGH', 4) -> 4"); - } - } - } - - GIVEN("capacity is 0") { - BufferingPrint bufferingPrint{spy, 0}; - - // SUBCASE("capacity()") { - // CHECK(bufferingPrint.capacity() == 0); - // } - - SUBCASE("write(uint8_t) forwards to target") { - int n = bufferingPrint.write('X'); - - CHECK(n == 1); - CHECK(log.str() == "write('X') -> 1"); - } - - SUBCASE("write(char*,1) forwards to target") { - int n = bufferingPrint.write("A", 1); - - CHECK(n == 1); - CHECK(log.str() == "write('A', 1) -> 1"); - } - - SUBCASE("flush()") { - bufferingPrint.flush(); - -#if STREAMUTILS_PRINT_FLUSH_EXISTS - CHECK(log.str() == "flush()"); -#else - CHECK(log.str() == ""); -#endif - } - } - - SUBCASE("Destructor should flush") { - { - BufferingPrint bufferingPrint{spy, 10}; - bufferingPrint.write("ABC", 3); - } - - CHECK(log.str() == "write('ABC', 3) -> 3"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/CMakeLists.txt deleted file mode 100644 index 3f49c108..00000000 --- a/lib/ArduinoStreamUtils/extras/test/CMakeLists.txt +++ /dev/null @@ -1,104 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") - add_compile_options(-Wall -Wextra -Werror -Wundef) -endif() - -set(SOURCES - BufferingPrintTest.cpp - EepromStreamTest.cpp - FailingAllocator.hpp - HammingClientTest.cpp - HammingDecodingClientTest.cpp - HammingDecodingStreamTest.cpp - HammingEncodingClientTest.cpp - HammingEncodingStreamTest.cpp - HammingPrintTest.cpp - HammingStreamTest.cpp - LoggingClientTest.cpp - LoggingPrintTest.cpp - LoggingStreamTest.cpp - MemoryStreamTest.cpp - ReadBufferingClientTest.cpp - ReadBufferingStreamTest.cpp - ReadLoggingClientTest.cpp - ReadLoggingStreamTest.cpp - ReadThrottlingStreamTest.cpp - StringPrintTest.cpp - StringStreamTest.cpp - WaitingPrintTest.cpp - WriteBufferingClientTest.cpp - WriteBufferingStreamTest.cpp - WriteLoggingClientTest.cpp - WriteLoggingStreamTest.cpp - WriteWaitingClientTest.cpp - WriteWaitingStreamTest.cpp - - doctest.h - main.cpp -) - -########## AVR ########## - -add_subdirectory(cores/avr) - -add_executable(StreamUtilsTestAvr ${SOURCES}) -target_link_libraries(StreamUtilsTestAvr AvrCore) - -add_test(Avr StreamUtilsTestAvr) - -########## ESP32 ########## - -add_subdirectory(cores/esp32) - -add_executable(StreamUtilsTestEsp32 ${SOURCES}) -target_link_libraries(StreamUtilsTestEsp32 Esp32Core) - -add_test(Esp32 StreamUtilsTestEsp32) - -########## ESP8266 ########## - -add_subdirectory(cores/esp8266) - -add_executable(StreamUtilsTestEsp8266 ${SOURCES}) -target_link_libraries(StreamUtilsTestEsp8266 Esp8266Core) - -add_test(Esp8266 StreamUtilsTestEsp8266) - -########## NRF52 ########## - -add_subdirectory(cores/nrf52) - -add_executable(StreamUtilsTestNrf52 ${SOURCES}) -target_link_libraries(StreamUtilsTestNrf52 Nrf52Core) - -add_test(Nrf52 StreamUtilsTestNrf52) - -########## SAMD ########## - -add_subdirectory(cores/samd) - -add_executable(StreamUtilsTestSamd ${SOURCES}) -target_link_libraries(StreamUtilsTestSamd SamdCore) - -add_test(Samd StreamUtilsTestSamd) - -########## STM32 ########## - -add_subdirectory(cores/stm32) - -add_executable(StreamUtilsTestStm32 ${SOURCES}) -target_link_libraries(StreamUtilsTestStm32 Stm32Core) - -add_test(Stm32 StreamUtilsTestStm32) - -########## Teensy ########## - -add_subdirectory(cores/teensy) - -add_executable(StreamUtilsTestTeensy ${SOURCES}) -target_link_libraries(StreamUtilsTestTeensy TeensyCore) - -add_test(Teensy StreamUtilsTestTeensy) \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/EepromStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/EepromStreamTest.cpp deleted file mode 100644 index 78e943f0..00000000 --- a/lib/ArduinoStreamUtils/extras/test/EepromStreamTest.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Streams/EepromStream.hpp" - -#if STREAMUTILS_ENABLE_EEPROM - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("EepromStream") { - SUBCASE("available()") { - EepromStream s(42, 84); - CHECK(s.available() == 84); - } - - SUBCASE("write(uint8_t)") { - EepromStream s(0, 2); - CHECK(s.write('a') == 1); - CHECK(s.write('b') == 1); - CHECK(s.write('c') == 0); - CHECK(s.write('d') == 0); - s.flush(); - CHECK(s.readString() == "ab"); - } - - SUBCASE("write(const uint8_t *, size_t)") { - EepromStream s(0, 5); - CHECK(s.write("abc", 3) == 3); - CHECK(s.write("def", 3) == 2); - CHECK(s.write("ghi", 3) == 0); - s.flush(); - CHECK(s.readString() == "abcde"); - } - - SUBCASE("read()") { - EepromStream s(0, 2); - s.write("ab", 2); - CHECK(s.read() == 'a'); - CHECK(s.read() == 'b'); - CHECK(s.read() == -1); - } - - SUBCASE("peek()") { - EepromStream s(0, 2); - s.write("ab", 2); - CHECK(s.peek() == 'a'); - CHECK(s.peek() == 'a'); - s.read(); - CHECK(s.peek() == 'b'); - s.read(); - CHECK(s.peek() == -1); - } -} -#endif \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/FailingAllocator.hpp b/lib/ArduinoStreamUtils/extras/test/FailingAllocator.hpp deleted file mode 100644 index 64debc62..00000000 --- a/lib/ArduinoStreamUtils/extras/test/FailingAllocator.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include // size_t - -struct FailingAllocator { - void* allocate(size_t) { - return nullptr; - } - void deallocate(void*) {} -}; diff --git a/lib/ArduinoStreamUtils/extras/test/HammingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/HammingClientTest.cpp deleted file mode 100644 index 5182956d..00000000 --- a/lib/ArduinoStreamUtils/extras/test/HammingClientTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "SpyingAllocator.hpp" - -#include "StreamUtils/Clients/HammingClient.hpp" -#include "StreamUtils/Clients/MemoryClient.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("HammingClient") { - MemoryClient upstream(64); - - HammingClient<7, 4> client{upstream}; - - SUBCASE("read() decodes") { - upstream.print("Tq"); - - CHECK(client.read() == 'A'); - } - - SUBCASE("write() encodes") { - client.write('A'); - - CHECK(upstream.readString() == "Tq"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/HammingDecodingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/HammingDecodingClientTest.cpp deleted file mode 100644 index 443bf7ae..00000000 --- a/lib/ArduinoStreamUtils/extras/test/HammingDecodingClientTest.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "SpyingAllocator.hpp" - -#include "StreamUtils/Clients/HammingDecodingClient.hpp" -#include "StreamUtils/Clients/MemoryClient.hpp" -#include "StreamUtils/Clients/SpyingClient.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("HammingDecodingClient") { - MemoryClient upstream(64); - StringPrint log; - SpyingClient spy{upstream, log}; - SpyingAllocator allocator{log}; - - BasicHammingDecodingClient<7, 4, SpyingAllocator&> client{spy, allocator}; - - SUBCASE("read() with small buffer") { - uint8_t buffer[8]; - - SUBCASE("empty input") { - size_t result = client.read(buffer, sizeof(buffer)); - - CHECK(result == 0); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "read(16) -> 0 [timeout]"); -#endif - } - - SUBCASE("decodes input") { - upstream.print("TqTb"); - - size_t result = client.read(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string((char*)buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "read(16) -> 4 [timeout]"); -#endif - } - - SUBCASE("includes byte loaded by peek()") { - upstream.print("TqTb"); - client.peek(); - log.clear(); - - size_t result = client.read(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string((char*)buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "read(15) -> 3 [timeout]"); -#endif - } - - SUBCASE("stores dangling byte") { - upstream.print("TqT"); - - size_t result = client.read(buffer, sizeof(buffer)); - - CHECK(result == 1); - CHECK(std::string((char*)buffer, result) == "A"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "read(16) -> 3 [timeout]"); -#endif - - log.clear(); - upstream.print("b"); - CHECK(client.peek() == 'B'); - CHECK(log.str() == "peek() -> 98"); - } - - SUBCASE("clears the byte loaded by peek") { - upstream.print("TqTb"); - client.peek(); - client.read(buffer, sizeof(buffer)); - client.peek(); - CHECK(log.str() == - "read() -> 84" - "peek() -> 113" - "read(15) -> 3 [timeout]" - "read() -> -1"); - } - } - - SUBCASE("read() with large buffer") { - uint8_t buffer[32]; - - SUBCASE("empty input") { - size_t result = client.read(buffer, sizeof(buffer)); - - CHECK(result == 0); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "allocate(64) -> ptr" - "read(64) -> 0 [timeout]" - "deallocate(ptr)"); -#endif - } - - SUBCASE("decodes input") { - upstream.print("TqTb"); - - size_t result = client.read(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string((char*)buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "allocate(64) -> ptr" - "read(64) -> 4 [timeout]" - "deallocate(ptr)"); -#endif - } - - SUBCASE("uses input buffer if allocation fails") { - upstream.print("TqTb"); - allocator.forceFail = true; - - size_t result = client.read(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string((char*)buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "allocate(64) -> null" - "read(32) -> 4 [timeout]"); -#endif - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/HammingDecodingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/HammingDecodingStreamTest.cpp deleted file mode 100644 index 0c60c0d3..00000000 --- a/lib/ArduinoStreamUtils/extras/test/HammingDecodingStreamTest.cpp +++ /dev/null @@ -1,290 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "SpyingAllocator.hpp" - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/HammingDecodingStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" -#include "StreamUtils/Streams/StringStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("HammingDecodingStream") { - StringStream upstream; - StringPrint log; - SpyingStream spy{upstream, log}; - SpyingAllocator allocator{log}; - - BasicHammingDecodingStream<7, 4, SpyingAllocator&> stream{spy, allocator}; - - SUBCASE("available()") { - SUBCASE("empty input") { - CHECK(stream.available() == 0); - CHECK(log.str() == "available() -> 0"); - } - - SUBCASE("even number of bytes") { - upstream.print("ABCDEFGH"); - - CHECK(stream.available() == 4); - CHECK(log.str() == "available() -> 8"); - } - - SUBCASE("odd number of bytes") { - upstream.print("ABCDEFGHI"); - - CHECK(stream.available() == 4); - CHECK(log.str() == "available() -> 9"); - } - - SUBCASE("even number of bytes after peek") { - upstream.print("ABCDEFGH"); - stream.peek(); - log.clear(); - CHECK(stream.available() == 4); - CHECK(log.str() == "available() -> 7"); - } - - SUBCASE("odd number of bytes after peek") { - upstream.print("ABCDEFGHI"); - stream.peek(); - log.clear(); - CHECK(stream.available() == 4); - CHECK(log.str() == "available() -> 8"); - } - } - - SUBCASE("peek()") { - SUBCASE("returns -1 when empty") { - int result = stream.peek(); - - CHECK(result == -1); - CHECK(log.str() == "read() -> -1"); - } - - SUBCASE("returns -1 when only one byte in input") { - upstream.print("A"); - - int result = stream.peek(); - - CHECK(result == -1); - CHECK(log.str() == - "read() -> 65" - "peek() -> -1"); - } - - SUBCASE("returns decoded value") { - upstream.print("Tq"); - - int result = stream.peek(); - - CHECK(result == 'A'); - CHECK(log.str() == - "read() -> 84" - "peek() -> 113"); - } - - SUBCASE("doesn't call read() the second time") { - upstream.print("A"); - stream.peek(); - log.clear(); - - int result = stream.peek(); - - CHECK(result == -1); - CHECK(log.str() == "peek() -> -1"); - } - } - - SUBCASE("read()") { - SUBCASE("returns -1 if empty") { - int result = stream.read(); - - CHECK(result == -1); - CHECK(log.str() == "read() -> -1"); - } - - SUBCASE("returns -1 if only one byte in input") { - upstream.print("A"); - - int result = stream.read(); - - CHECK(result == -1); - CHECK(log.str() == - "read() -> 65" - "read() -> -1"); - } - - SUBCASE("returns decoded value if two bytes in input") { - upstream.print("Tq"); - - int result = stream.read(); - - CHECK(result == 'A'); - CHECK(log.str() == - "read() -> 84" - "read() -> 113"); - } - - SUBCASE("reuses the byte read by peek()") { - upstream.print("Tq"); - stream.peek(); - log.clear(); - - int result = stream.read(); - - CHECK(result == 'A'); - CHECK(log.str() == "read() -> 113"); - } - - SUBCASE("reuses the byte read by previous call") { - upstream.print("T"); - stream.read(); - upstream.print("q"); - log.clear(); - - int result = stream.read(); - - CHECK(result == 'A'); - CHECK(log.str() == "read() -> 113"); - } - - SUBCASE("flushes the buffered byte") { - upstream.print("TqTb"); - - CHECK(stream.read() == 'A'); - CHECK(stream.read() == 'B'); - - CHECK(log.str() == - "read() -> 84" - "read() -> 113" - "read() -> 84" - "read() -> 98"); - } - } - - SUBCASE("readBytes() with small buffer") { - char buffer[8]; - - SUBCASE("empty input") { - size_t result = stream.readBytes(buffer, sizeof(buffer)); - - CHECK(result == 0); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(16) -> 0 [timeout]"); -#endif - } - - SUBCASE("decodes input") { - upstream.print("TqTb"); - - size_t result = stream.readBytes(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string(buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(16) -> 4 [timeout]"); -#endif - } - - SUBCASE("includes byte loaded by peek()") { - upstream.print("TqTb"); - stream.peek(); - log.clear(); - - size_t result = stream.readBytes(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string(buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(15) -> 3 [timeout]"); -#endif - } - - SUBCASE("stores dangling byte") { - upstream.print("TqT"); - - size_t result = stream.readBytes(buffer, sizeof(buffer)); - - CHECK(result == 1); - CHECK(std::string(buffer, result) == "A"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(16) -> 3 [timeout]"); -#endif - - log.clear(); - upstream.print("b"); - CHECK(stream.peek() == 'B'); - CHECK(log.str() == "peek() -> 98"); - } - - SUBCASE("clears the byte loaded by peek") { - upstream.print("TqTb"); - stream.peek(); - stream.readBytes(buffer, sizeof(buffer)); - CHECK(stream.peek() == -1); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "read() -> 84" - "peek() -> 113" - "readBytes(15) -> 3 [timeout]" - "read() -> -1"); -#endif - } - } - - SUBCASE("readBytes() with large buffer") { - char buffer[32]; - - SUBCASE("empty input") { - size_t result = stream.readBytes(buffer, sizeof(buffer)); - - CHECK(result == 0); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "allocate(64) -> ptr" - "readBytes(64) -> 0 [timeout]" - "deallocate(ptr)"); -#endif - } - - SUBCASE("decodes input") { - upstream.print("TqTb"); - - size_t result = stream.readBytes(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string(buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "allocate(64) -> ptr" - "readBytes(64) -> 4 [timeout]" - "deallocate(ptr)"); -#endif - } - - SUBCASE("uses input buffer if allocation fails") { - upstream.print("TqTb"); - allocator.forceFail = true; - - size_t result = stream.readBytes(buffer, sizeof(buffer)); - - CHECK(result == 2); - CHECK(std::string(buffer, result) == "AB"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "allocate(64) -> null" - "readBytes(32) -> 4 [timeout]"); -#endif - } - } - - SUBCASE("flush()") { - stream.flush(); - CHECK(log.str() == "flush()"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/HammingEncodingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/HammingEncodingClientTest.cpp deleted file mode 100644 index 1356d161..00000000 --- a/lib/ArduinoStreamUtils/extras/test/HammingEncodingClientTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "SpyingAllocator.hpp" - -#include "StreamUtils/Clients/HammingEncodingClient.hpp" -#include "StreamUtils/Clients/MemoryClient.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("HammingEncodingClient") { - MemoryClient upstream(64); - - HammingEncodingClient<7, 4> client{upstream}; - - SUBCASE("read() forwards upstream data") { - upstream.print("A"); - - CHECK(client.read() == 'A'); - } - - SUBCASE("write() encodes") { - client.write('A'); - - CHECK(upstream.readString() == "Tq"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/HammingEncodingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/HammingEncodingStreamTest.cpp deleted file mode 100644 index faa51dce..00000000 --- a/lib/ArduinoStreamUtils/extras/test/HammingEncodingStreamTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "SpyingAllocator.hpp" - -#include "StreamUtils/Streams/HammingEncodingStream.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("HammingEncodingStream") { - MemoryStream upstream(64); - - HammingEncodingStream<7, 4> stream{upstream}; - - SUBCASE("read() forwards upstream data") { - upstream.print("A"); - - CHECK(stream.read() == 'A'); - } - - SUBCASE("write() encodes") { - stream.write('A'); - - CHECK(upstream.readString() == "Tq"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/HammingPrintTest.cpp b/lib/ArduinoStreamUtils/extras/test/HammingPrintTest.cpp deleted file mode 100644 index 42d7556d..00000000 --- a/lib/ArduinoStreamUtils/extras/test/HammingPrintTest.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "SpyingAllocator.hpp" - -#include "StreamUtils/Prints/HammingPrint.hpp" -#include "StreamUtils/Prints/SpyingPrint.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("HammingPrint") { - MemoryStream upstream(4); - - StringPrint log; - SpyingPrint spy{upstream, log}; - SpyingAllocator allocator{log}; - - BasicHammingPrint<7, 4, SpyingAllocator&> print{spy, allocator}; - - SUBCASE("write(char*, size_t)") { - SUBCASE("stops if even byte fails") { - CHECK(print.print("ABA") == 2); - print.write('A'); // try to flush remainder - - CHECK(log.str() == - "write('TqTbTq', 6) -> 4" - "write('T') -> 0" // no remainder - ); - } - - SUBCASE("saves remainder if odd byte fails") { - upstream.print("?"); - - CHECK(print.print("ABA") == 2); - print.write('A'); // try to flush remainder - - CHECK(log.str() == - "write('TqTbTq', 6) -> 3" - "write('b') -> 0" // remainder!! - ); - } - - SUBCASE("writes remainder first") { - upstream.print("???"); - print.write('A'); // add remainder - log.clear(); - upstream.readString(); - - CHECK(print.print("ABA") == 2); - - CHECK(log.str() == - "write('q') -> 1" - "write('TqTbTq', 6) -> 3"); - } - - SUBCASE("stops if remainder fails") { - upstream.print("???"); - print.write('A'); // add remainder - log.clear(); - - CHECK(print.print("ABA") == 0); - - CHECK(log.str() == "write('q') -> 0"); - } - - SUBCASE("allocates in stack when buffer is small") { - print.write("ABABABABABABABAB", 16); - - CHECK(log.str() == "write('TqTbTqTbTqTbTqTbTqTbTqTbTqTbTqTb', 32) -> 4"); - } - - SUBCASE("allocates in heap when buffer is large") { - print.write("ABABABABABABABABA", 17); - - CHECK(log.str() == - "allocate(34) -> ptr" - "write('TqTbTqTbTqTbTqTbTqTbTqTbTqTbTqTbTq', 34) -> 4" - "deallocate(ptr)"); - } - - SUBCASE("falls back to stack if heap fails") { - allocator.forceFail = true; - print.write("ABABABABABABABABA", 17); - - CHECK(log.str() == - "allocate(34) -> null" - "write('TqTbTqTbTqTbTqTbTqTbTqTbTqTbTqTb', 32) -> 4"); - } - } - - SUBCASE("write(char)") { - SUBCASE("writes both bytes") { - CHECK(print.write('A') == 1); - - CHECK(upstream.readString() == "Tq"); - CHECK(log.str() == - "write('T') -> 1" - "write('q') -> 1"); - } - - SUBCASE("stops if first by fails") { - upstream.print("????"); - - CHECK(print.write('A') == 0); - print.write('A'); // try to flush remainder - - CHECK(log.str() == - "write('T') -> 0" - "write('T') -> 0" // no remainder - ); - } - - SUBCASE("saves remainder if second by fails") { - upstream.print("???"); - - CHECK(print.write('A') == 1); - print.write('A'); // try to flush remainder - - CHECK(log.str() == - "write('T') -> 1" - "write('q') -> 0" - "write('q') -> 0" // remainder!! - ); - } - - SUBCASE("writes remainder first") { - upstream.print("???"); - print.write('A'); // add remainder - log.clear(); - upstream.readString(); - - CHECK(print.write('A') == 1); - - CHECK(log.str() == - "write('q') -> 1" - "write('T') -> 1" - "write('q') -> 1"); - } - - SUBCASE("stops if remainder fails") { - upstream.print("???"); - print.write('A'); // add remainder - log.clear(); - - CHECK(print.write('A') == 0); - print.write('A'); // try to flush remainder - - CHECK(log.str() == - "write('q') -> 0" - "write('q') -> 0" // remainder!! - ); - } - - SUBCASE("resets remainder") { - upstream.print("???"); - print.write('A'); // add remainder - log.clear(); - upstream.read(); - - CHECK(print.write('A') == 0); - print.write('A'); // try to flush remainder - - CHECK(log.str() == - "write('q') -> 1" - "write('T') -> 0" - "write('T') -> 0" // no remainder - ); - } - } - -#if STREAMUTILS_PRINT_FLUSH_EXISTS - SUBCASE("flush() writes remainder") { - upstream.print("???"); - print.write('A'); // add remainder - log.clear(); - upstream.read(); - - print.flush(); - - CHECK(log.str() == - "write('q') -> 1" - "flush()" // no remainder - ); - } -#endif - - SUBCASE("destructor flushes remainder") { - { - BasicHammingPrint<7, 4, SpyingAllocator&> print{spy, allocator}; - upstream.print("???"); - print.write('A'); // add remainder - log.clear(); - } - - CHECK(log.str() == "write('q') -> 0"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/HammingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/HammingStreamTest.cpp deleted file mode 100644 index 551f5fc8..00000000 --- a/lib/ArduinoStreamUtils/extras/test/HammingStreamTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "SpyingAllocator.hpp" - -#include "StreamUtils/Streams/HammingStream.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("HammingStream") { - MemoryStream upstream(64); - - HammingStream<7, 4> stream{upstream}; - - SUBCASE("read() decodes") { - upstream.print("Tq"); - - CHECK(stream.read() == 'A'); - } - - SUBCASE("write() encodes") { - stream.write('A'); - - CHECK(upstream.readString() == "Tq"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/LoggingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/LoggingClientTest.cpp deleted file mode 100644 index f457abea..00000000 --- a/lib/ArduinoStreamUtils/extras/test/LoggingClientTest.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Clients/LoggingClient.hpp" -#include "StreamUtils/Clients/MemoryClient.hpp" -#include "StreamUtils/Clients/SpyingClient.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("LoggingClient") { - MemoryClient target(4); - - StringPrint log; - SpyingClient spy{target, log}; - - StringPrint output; - LoggingClient loggingClient{spy, output}; - - SUBCASE("available()") { - target.print("ABC"); - - size_t n = loggingClient.available(); - - CHECK(n == 3); - CHECK(log.str() == "available() -> 3"); - CHECK(output.str() == ""); - } - - SUBCASE("connect(IPAddress)") { - int n = loggingClient.connect(IPAddress("1.2.3.4"), 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("connect(const char*)") { - int n = loggingClient.connect("1.2.3.4", 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("connected()") { - uint8_t n = loggingClient.connected(); - - CHECK(n == false); - CHECK(log.str() == "connected() -> 0"); - CHECK(output.str() == ""); - } - - SUBCASE("stop()") { - loggingClient.stop(); - - CHECK(log.str() == "stop()"); - CHECK(output.str() == ""); - } - - SUBCASE("operator bool()") { - bool n = loggingClient.operator bool(); - - CHECK(n == true); - CHECK(log.str() == "operator bool() -> true"); - CHECK(output.str() == ""); - } - - SUBCASE("peek()") { - target.print("ABC"); - - int n = loggingClient.peek(); - - CHECK(n == 'A'); - CHECK(log.str() == "peek() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("read()") { - target.print("ABC"); - - int n = loggingClient.read(); - - CHECK(n == 'A'); - CHECK(log.str() == "read() -> 65"); - CHECK(output.str() == "A"); - } - - SUBCASE("read(uint8_t*,size_t)") { - target.print("ABC"); - - uint8_t s[4] = {0}; - size_t n = loggingClient.read(s, 4); - - CHECK(n == 3); - CHECK(log.str() == "read(4) -> 3 [timeout]"); - CHECK(output.str() == "ABC"); - } - - SUBCASE("readBytes()") { - target.print("ABC"); - - char s[4] = {0}; - size_t n = loggingClient.readBytes(s, 4); - - CHECK(n == 3); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(4) -> 3 [timeout]"); -#endif - CHECK(output.str() == "ABC"); - } - - SUBCASE("write(char)") { - int n = loggingClient.write('A'); - - CHECK(n == 1); - CHECK(log.str() == "write('A') -> 1"); - CHECK(output.str() == "A"); - } - - SUBCASE("write(char*,size_t)") { - int n = loggingClient.write("ABCDEF", 6); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCDEF', 6) -> 4"); - CHECK(output.str() == "ABCD"); - } - - SUBCASE("flush()") { - loggingClient.flush(); - - CHECK(output.str() == ""); - CHECK(log.str() == "flush()"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/LoggingPrintTest.cpp b/lib/ArduinoStreamUtils/extras/test/LoggingPrintTest.cpp deleted file mode 100644 index ca20c483..00000000 --- a/lib/ArduinoStreamUtils/extras/test/LoggingPrintTest.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Prints/LoggingPrint.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("LoggingPrint") { - MemoryStream primary(4); - MemoryStream secondary(64); - LoggingPrint loggingPrint{primary, secondary}; - - SUBCASE("write(char)") { - int n = loggingPrint.write('A'); - - CHECK(n == 1); - CHECK(primary.readString() == "A"); - CHECK(secondary.readString() == "A"); - } - - SUBCASE("write(char*,size_t)") { - int n = loggingPrint.write("ABCDEF", 6); - - CHECK(n == 4); - CHECK(primary.readString() == "ABCD"); - CHECK(secondary.readString() == "ABCD"); - } - -#if STREAMUTILS_PRINT_FLUSH_EXISTS - SUBCASE("flush()") { - loggingPrint.write("AB", 2); - REQUIRE(primary.available() == 2); - loggingPrint.flush(); - REQUIRE(primary.available() == 0); - } -#endif -} diff --git a/lib/ArduinoStreamUtils/extras/test/LoggingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/LoggingStreamTest.cpp deleted file mode 100644 index aab8537b..00000000 --- a/lib/ArduinoStreamUtils/extras/test/LoggingStreamTest.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/LoggingStream.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("LoggingStream") { - MemoryStream upstream{4}; - StringPrint output; - - StringPrint log; - SpyingStream upstreamSpy{upstream, log}; - - LoggingStream loggingStream{upstreamSpy, output}; - - // upstream -> upstreamSpy -> loggingStream -> output - // | - // v - // log - - SUBCASE("available()") { - upstream.print("ABC"); - - size_t n = loggingStream.available(); - - CHECK(n == 3); - CHECK(log.str() == "available() -> 3"); - CHECK(output.str() == ""); - } - - SUBCASE("peek()") { - upstream.print("ABC"); - - int n = loggingStream.peek(); - - CHECK(n == 'A'); - CHECK(log.str() == "peek() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("read()") { - upstream.print("ABC"); - - int n = loggingStream.read(); - - CHECK(n == 'A'); - CHECK(log.str() == "read() -> 65"); - CHECK(output.str() == "A"); - } - - SUBCASE("readBytes()") { - upstream.print("ABC"); - - char s[4] = {0}; - size_t n = loggingStream.readBytes(s, 4); - - CHECK(n == 3); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(4) -> 3 [timeout]"); -#endif - CHECK(output.str() == "ABC"); - } - - SUBCASE("write(char)") { - int n = loggingStream.write('A'); - - CHECK(n == 1); - CHECK(log.str() == "write('A') -> 1"); - CHECK(output.str() == "A"); - } - - SUBCASE("write(char*,size_t)") { - int n = loggingStream.write("ABCDEF", 6); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCDEF', 6) -> 4"); - CHECK(output.str() == "ABCD"); - } - - SUBCASE("flush()") { - loggingStream.flush(); - - CHECK(log.str() == "flush()"); - CHECK(output.str() == ""); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/MemoryStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/MemoryStreamTest.cpp deleted file mode 100644 index a649d1fc..00000000 --- a/lib/ArduinoStreamUtils/extras/test/MemoryStreamTest.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Streams/MemoryStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("MemoryStream") { - MemoryStream stream(4); - - WHEN("stream is empty") { - THEN("available() return 0") { - CHECK(stream.available() == 0); - } - - THEN("write(uint8) returns 1") { - CHECK(stream.write('A') == 1); - } - - THEN("write(\"ABCD\",4) returns 4") { - CHECK(stream.write("ABCD", 4) == 4); - } - - THEN("write(uint8*,8) returns 4") { - CHECK(stream.write("ABCDEFGH", 8) == 4); - } - - THEN("read() return -1") { - CHECK(stream.read() == -1); - } - - THEN("peek() return -1") { - CHECK(stream.peek() == -1); - } - } - - WHEN("stream is full") { - stream.print("ABCD"); - - THEN("available() return 4") { - CHECK(stream.available() == 4); - } - - THEN("write(uint8) returns 0") { - CHECK(stream.write('A') == 0); - } - - THEN("write(\"ABCD\",4) returns 0") { - CHECK(stream.write("ABCD", 4) == 0); - } - - THEN("read() returns the next value") { - CHECK(stream.read() == 'A'); - CHECK(stream.read() == 'B'); - } - - THEN("read(uint8_t*,size_t) extracts the next bytes") { - char data[5] = {0}; - CHECK(stream.readBytes(data, 4) == 4); - CHECK(data == std::string("ABCD")); - } - - THEN("peek() returns the first value") { - CHECK(stream.peek() == 'A'); - CHECK(stream.peek() == 'A'); - } - - SUBCASE("read() makes room for one byte") { - stream.read(); // make room - REQUIRE(stream.available() == 3); - - stream.write('E'); // write at the beginning - REQUIRE(stream.available() == 4); - - char data[5] = {0}; - stream.readBytes(data, 4); - CHECK(data == std::string("BCDE")); - } - } - - WHEN("lower half is filled") { - stream.print("AB"); - - THEN("available() return 2") { - CHECK(stream.available() == 2); - } - - THEN("write(uint8) returns 1") { - CHECK(stream.write('C') == 1); - } - - THEN("write(\"ABCD\",4) returns 2") { - CHECK(stream.write("ABCD", 4) == 2); - } - - THEN("read() returns the next value") { - CHECK(stream.read() == 'A'); - CHECK(stream.read() == 'B'); - } - - THEN("read(uint8_t*,size_t) extracts the next bytes") { - char data[5] = {0}; - CHECK(stream.readBytes(data, 4) == 2); - CHECK(data == std::string("AB")); - } - - THEN("peek() returns the first value") { - CHECK(stream.peek() == 'A'); - CHECK(stream.peek() == 'A'); - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/ReadBufferingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/ReadBufferingClientTest.cpp deleted file mode 100644 index 37d965ba..00000000 --- a/lib/ArduinoStreamUtils/extras/test/ReadBufferingClientTest.cpp +++ /dev/null @@ -1,337 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Clients/MemoryClient.hpp" -#include "StreamUtils/Clients/ReadBufferingClient.hpp" -#include "StreamUtils/Clients/SpyingClient.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("ReadBufferingClient") { - MemoryClient target(64); - StringPrint log; - SpyingClient spy{target, log}; - - SUBCASE("capacity = 4") { - ReadBufferingClient bufferedClient{spy, 4}; - Client& client = bufferedClient; - - SUBCASE("available()") { - target.print("ABCDEFGH"); - - SUBCASE("empty input") { - target.flush(); - CHECK(client.available() == 0); - CHECK(log.str() == "available() -> 0"); - } - - SUBCASE("read empty input") { - target.flush(); - - client.read(); - - CHECK(client.available() == 0); - CHECK(log.str() == - "available() -> 0" - "read() -> -1" - "available() -> 0"); - } - - SUBCASE("same a target") { - CHECK(client.available() == 8); - CHECK(log.str() == "available() -> 8"); - } - - SUBCASE("target + in buffer") { - client.read(); - - CHECK(client.available() == 7); - CHECK(log.str() == - "available() -> 8" - "read(4) -> 4" - "available() -> 4"); - } - } - - SUBCASE("peek()") { - SUBCASE("returns -1 when empty") { - target.flush(); - - int result = client.peek(); - - CHECK(result == -1); - CHECK(log.str() == "peek() -> -1"); - } - - SUBCASE("doesn't call readBytes() when buffer is empty") { - target.print("A"); - - int result = client.peek(); - - CHECK(result == 'A'); - CHECK(log.str() == "peek() -> 65"); - } - - SUBCASE("doesn't call peek() when buffer is full") { - target.print("AB"); - - client.read(); - int result = client.peek(); - - CHECK(result == 'B'); - CHECK(log.str() == - "available() -> 2" - "read(2) -> 2"); - } - } - - SUBCASE("read()") { - SUBCASE("reads 4 bytes at a time") { - target.print("ABCDEFG"); - std::string result; - - for (int i = 0; i < 7; i++) { - result += (char)client.read(); - } - - CHECK(result == "ABCDEFG"); - CHECK(log.str() == - "available() -> 7" - "read(4) -> 4" - "available() -> 3" - "read(3) -> 3"); - } - - SUBCASE("returns -1 when empty") { - target.flush(); - - int result = client.read(); - - CHECK(result == -1); - CHECK(log.str() == - "available() -> 0" - "read() -> -1"); - } - } - - SUBCASE("read()") { - SUBCASE("empty input") { - target.flush(); - - char c; - size_t result = client.readBytes(&c, 1); - - CHECK(result == 0); - -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 0" - "readBytes(1) -> 0 [timeout]"); -#else - CHECK(log.str() == - "available() -> 0" - "read() -> -1"); // [timeout] from timedRead() -#endif - } - - SUBCASE("reads 4 bytes when requested one") { - target.print("ABCDEFG"); - - char c; - size_t result = client.readBytes(&c, 1); - - CHECK(c == 'A'); - CHECK(result == 1); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 7" - "readBytes(4) -> 4"); -#else - CHECK(log.str() == - "available() -> 7" - "read(4) -> 4"); -#endif - } - - SUBCASE("copy one byte from buffer") { - target.print("ABCDEFGH"); - client.read(); // load buffer - - char c; - size_t result = client.readBytes(&c, 1); - - CHECK(c == 'B'); - CHECK(result == 1); - CHECK(log.str() == - "available() -> 8" - "read(4) -> 4"); - } - - SUBCASE("copy content from buffer then bypass buffer") { - target.print("ABCDEFGH"); - client.read(); // load buffer - - char c[8] = {0}; - size_t result = client.readBytes(c, 7); - - CHECK(c == std::string("BCDEFGH")); - CHECK(result == 7); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 8" - "read(4) -> 4" - "available() -> 4" - "readBytes(4) -> 4"); -#else - CHECK(log.str() == - "available() -> 8" - "read(4) -> 4" - "available() -> 4" - "read(4) -> 4"); -#endif - } - - SUBCASE("copy content from buffer twice") { - target.print("ABCDEFGH"); - client.read(); // load buffer - - char c[8] = {0}; - size_t result = client.readBytes(c, 4); - - CHECK(c == std::string("BCDE")); - CHECK(result == 4); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 8" - "read(4) -> 4" - "available() -> 4" - "readBytes(4) -> 4"); -#else - CHECK(log.str() == - "available() -> 8" - "read(4) -> 4" - "available() -> 4" - "read(4) -> 4"); -#endif - } - - SUBCASE("read past the end") { - target.print("A"); - - char c; - client.readBytes(&c, 1); - size_t result = client.readBytes(&c, 1); - - CHECK(result == 0); - -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 1" - "readBytes(1) -> 1" - "available() -> 0" - "readBytes(1) -> 0 [timeout]"); -#else - CHECK(log.str() == - "available() -> 1" - "read() -> 65" - "available() -> 0" - "read() -> -1"); // [timeout] from timedRead() -#endif - } - } - - SUBCASE("flush()") { - client.flush(); - CHECK(log.str() == "flush()"); - } - - SUBCASE("copy constructor") { - target.print("ABCDEFGH"); - bufferedClient.read(); - - auto dup = bufferedClient; - - int result = dup.read(); - - CHECK(result == 'B'); - CHECK(log.str() == - "available() -> 8" - "read(4) -> 4"); - } - } - - SUBCASE("No memory") { - BasicReadBufferingClient client(spy, 4); - - SUBCASE("available()") { - target.print("ABC"); - - CHECK(client.available() == 3); - } - - // SUBCASE("capacity()") { - // CHECK(client.capacity() == 0); - // } - - SUBCASE("peek()") { - target.print("ABC"); - - int c = client.peek(); - - CHECK(c == 'A'); - CHECK(log.str() == "peek() -> 65"); - } - - SUBCASE("read()") { - target.print("ABC"); - - int c = client.read(); - - CHECK(c == 'A'); - CHECK(log.str() == "read() -> 65"); - } - - SUBCASE("readBytes()") { - target.print("ABC"); - - char s[4] = {0}; - int n = client.readBytes(s, 3); - - CHECK(n == 3); - CHECK(s == std::string("ABC")); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(3) -> 3"); -#endif - } - } - - SUBCASE("Real example") { - ReadBufferingClient bufferedClient{spy, 64}; - Client& client = bufferedClient; - - target.print("{\"helloWorld\":\"Hello World\"}"); - - char c[] = "ABCDEFGH"; - CHECK(client.readBytes(&c[0], 1) == 1); - CHECK(client.readBytes(&c[1], 1) == 1); - CHECK(client.readBytes(&c[2], 1) == 1); - CHECK(client.readBytes(&c[3], 1) == 1); - - CHECK(c == std::string("{\"heEFGH")); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 28" - "readBytes(28) -> 28"); -#else - CHECK(log.str() == - "available() -> 28" - "read(28) -> 28"); -#endif - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/ReadBufferingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/ReadBufferingStreamTest.cpp deleted file mode 100644 index bbc13b73..00000000 --- a/lib/ArduinoStreamUtils/extras/test/ReadBufferingStreamTest.cpp +++ /dev/null @@ -1,318 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/ReadBufferingStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" -#include "StreamUtils/Streams/StringStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("ReadBufferingStream") { - StringStream upstream; - StringPrint log; - SpyingStream spy{upstream, log}; - - SUBCASE("capacity = 4") { - ReadBufferingStream bufferedStream{spy, 4}; - Stream& stream = bufferedStream; - - SUBCASE("available()") { - SUBCASE("empty input") { - CHECK(stream.available() == 0); - CHECK(log.str() == "available() -> 0"); - } - - SUBCASE("read empty input") { - int n = stream.read(); - - CHECK(n == -1); - CHECK(stream.available() == 0); - CHECK(log.str() == - "available() -> 0" - "read() -> -1" - "available() -> 0"); - } - - SUBCASE("same a upstream") { - upstream.print("ABCDEFGH"); - - CHECK(stream.available() == 8); - CHECK(log.str() == "available() -> 8"); - } - - SUBCASE("upstream + in buffer") { - upstream.print("ABCDEFGH"); - - int n = stream.read(); - - CHECK(n == 'A'); - CHECK(stream.available() == 7); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 8" - "readBytes(4) -> 4" - "available() -> 4"); -#endif - } - } - - SUBCASE("peek()") { - SUBCASE("returns -1 when empty") { - upstream.flush(); - - int result = stream.peek(); - - CHECK(result == -1); - CHECK(log.str() == "peek() -> -1"); - } - - SUBCASE("doesn't call readBytes() when buffer is empty") { - upstream.print("A"); - - int result = stream.peek(); - - CHECK(result == 'A'); - CHECK(log.str() == "peek() -> 65"); - } - - SUBCASE("doesn't call peek() when buffer is full") { - upstream.print("AB"); - - stream.read(); - int result = stream.peek(); - - CHECK(result == 'B'); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 2" - "readBytes(2) -> 2"); -#endif - } - } - - SUBCASE("read()") { - SUBCASE("reads 4 bytes at a time") { - upstream.print("ABCDEFG"); - std::string result; - - for (int i = 0; i < 7; i++) { - result += (char)stream.read(); - } - - CHECK(result == "ABCDEFG"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 7" - "readBytes(4) -> 4" - "available() -> 3" - "readBytes(3) -> 3"); -#endif - } - - SUBCASE("returns -1 when empty") { - upstream.flush(); - - int result = stream.read(); - - CHECK(result == -1); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 0" - "read() -> -1"); -#endif - } - } - - SUBCASE("readBytes()") { - SUBCASE("empty input") { - upstream.flush(); - - char c; - size_t result = stream.readBytes(&c, 1); - - CHECK(result == 0); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 0" - "readBytes(1) -> 0 [timeout]"); -#endif - } - - SUBCASE("reads 4 bytes when requested one") { - upstream.print("ABCDEFG"); - - char c; - size_t result = stream.readBytes(&c, 1); - - CHECK(c == 'A'); - CHECK(result == 1); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 7" - "readBytes(4) -> 4"); -#endif - } - - SUBCASE("copy one byte from buffer") { - upstream.print("ABCDEFGH"); - stream.read(); // load buffer - - char c; - size_t result = stream.readBytes(&c, 1); - - CHECK(c == 'B'); - CHECK(result == 1); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 8" - "readBytes(4) -> 4"); -#endif - } - - SUBCASE("copy content from buffer then bypass buffer") { - upstream.print("ABCDEFGH"); - stream.read(); // load buffer - - char c[8] = {0}; - size_t result = stream.readBytes(c, 7); - - CHECK(c == std::string("BCDEFGH")); - CHECK(result == 7); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 8" - "readBytes(4) -> 4" - "available() -> 4" - "readBytes(4) -> 4"); -#endif - } - - SUBCASE("copy content from buffer twice") { - upstream.print("ABCDEFGH"); - stream.read(); // load buffer - - char c[8] = {0}; - size_t result = stream.readBytes(c, 4); - - CHECK(c == std::string("BCDE")); - CHECK(result == 4); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 8" - "readBytes(4) -> 4" - "available() -> 4" - "readBytes(4) -> 4"); -#endif - } - - SUBCASE("read past the end") { - upstream.print("A"); - - char c; - stream.readBytes(&c, 1); - size_t result = stream.readBytes(&c, 1); - - CHECK(result == 0); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 1" - "readBytes(1) -> 1" - "available() -> 0" - "readBytes(1) -> 0 [timeout]"); -#endif - } - } - - SUBCASE("flush()") { - stream.flush(); - CHECK(log.str() == "flush()"); - } - - SUBCASE("copy constructor") { - upstream.print("ABCDEFGH"); - bufferedStream.read(); - - auto dup = bufferedStream; - - int result = dup.read(); - - CHECK(result == 'B'); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 8" - "readBytes(4) -> 4"); -#endif - } - } - - SUBCASE("No memory") { - BasicReadBufferingStream stream(spy, 4); - - SUBCASE("available()") { - upstream.print("ABC"); - - CHECK(stream.available() == 3); - } - - // SUBCASE("capacity()") { - // CHECK(stream.capacity() == 0); - // } - - SUBCASE("peek()") { - upstream.print("ABC"); - - int c = stream.peek(); - - CHECK(c == 'A'); - CHECK(log.str() == "peek() -> 65"); - } - - SUBCASE("read()") { - upstream.print("ABC"); - - int c = stream.read(); - - CHECK(c == 'A'); - CHECK(log.str() == "read() -> 65"); - } - - SUBCASE("readBytes()") { - upstream.print("ABC"); - - char s[4] = {0}; - int n = stream.readBytes(s, 3); - - CHECK(n == 3); - CHECK(s == std::string("ABC")); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(3) -> 3"); -#endif - } - } - - SUBCASE("Real example") { - ReadBufferingStream bufferedStream{spy, 64}; - Stream& stream = bufferedStream; - - upstream.print("{\"helloWorld\":\"Hello World\"}"); - - char c[] = "ABCDEFGH"; - CHECK(stream.readBytes(&c[0], 1) == 1); - CHECK(stream.readBytes(&c[1], 1) == 1); - CHECK(stream.readBytes(&c[2], 1) == 1); - CHECK(stream.readBytes(&c[3], 1) == 1); - - CHECK(c == std::string("{\"heEFGH")); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == - "available() -> 28" - "readBytes(28) -> 28"); -#endif - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/ReadLoggingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/ReadLoggingClientTest.cpp deleted file mode 100644 index bbd0128a..00000000 --- a/lib/ArduinoStreamUtils/extras/test/ReadLoggingClientTest.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Clients/MemoryClient.hpp" -#include "StreamUtils/Clients/ReadLoggingClient.hpp" -#include "StreamUtils/Clients/SpyingClient.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("ReadLoggingClient") { - MemoryClient target(4); - - StringPrint log; - SpyingClient upstreamSpy{target, log}; - - StringPrint output; - ReadLoggingClient loggingClient{upstreamSpy, output}; - - SUBCASE("available()") { - target.print("ABC"); - - size_t n = loggingClient.available(); - - CHECK(n == 3); - CHECK(log.str() == "available() -> 3"); - CHECK(output.str() == ""); - } - - SUBCASE("connect(IPAddress)") { - int n = loggingClient.connect(IPAddress("1.2.3.4"), 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("connect(const char*)") { - int n = loggingClient.connect("1.2.3.4", 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("connected()") { - uint8_t n = loggingClient.connected(); - - CHECK(n == false); - CHECK(log.str() == "connected() -> 0"); - CHECK(output.str() == ""); - } - - SUBCASE("stop()") { - loggingClient.stop(); - - CHECK(log.str() == "stop()"); - CHECK(output.str() == ""); - } - - SUBCASE("operator bool()") { - bool n = loggingClient.operator bool(); - - CHECK(n == true); - CHECK(log.str() == "operator bool() -> true"); - CHECK(output.str() == ""); - } - - SUBCASE("peek()") { - target.print("ABC"); - - int n = loggingClient.peek(); - - CHECK(n == 'A'); - CHECK(log.str() == "peek() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("read()") { - target.print("ABC"); - - int n = loggingClient.read(); - - CHECK(n == 'A'); - CHECK(log.str() == "read() -> 65"); - CHECK(output.str() == "A"); - } - - SUBCASE("read(uint8_t*,size_t)") { - target.print("ABC"); - - uint8_t s[4] = {0}; - size_t n = loggingClient.read(s, 4); - - CHECK(n == 3); - CHECK(log.str() == "read(4) -> 3 [timeout]"); - CHECK(output.str() == "ABC"); - } - - SUBCASE("readBytes()") { - target.print("ABC"); - - char s[4] = {0}; - size_t n = loggingClient.readBytes(s, 4); - - CHECK(n == 3); - CHECK(output.str() == "ABC"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(4) -> 3 [timeout]"); -#endif - } - - SUBCASE("write(char)") { - int n = loggingClient.write('A'); - - CHECK(n == 1); - CHECK(log.str() == "write('A') -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("write(char*,size_t)") { - int n = loggingClient.write("ABCDEF", 6); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCDEF', 6) -> 4"); - CHECK(output.str() == ""); - } - - SUBCASE("flush()") { - loggingClient.flush(); - - CHECK(log.str() == "flush()"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/ReadLoggingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/ReadLoggingStreamTest.cpp deleted file mode 100644 index aa2c5744..00000000 --- a/lib/ArduinoStreamUtils/extras/test/ReadLoggingStreamTest.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" -#include "StreamUtils/Streams/ReadLoggingStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("ReadLoggingStream") { - MemoryStream upstream(4); - - StringPrint log; - SpyingStream upstreamSpy{upstream, log}; - - StringPrint output; - ReadLoggingStream loggingStream{upstreamSpy, output}; - - SUBCASE("available()") { - upstream.print("ABC"); - - size_t n = loggingStream.available(); - - CHECK(n == 3); - CHECK(log.str() == "available() -> 3"); - CHECK(output.str() == ""); - } - - SUBCASE("peek()") { - upstream.print("ABC"); - - int n = loggingStream.peek(); - - CHECK(n == 'A'); - CHECK(log.str() == "peek() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("read()") { - upstream.print("ABC"); - - int n = loggingStream.read(); - - CHECK(n == 'A'); - CHECK(log.str() == "read() -> 65"); - CHECK(output.str() == "A"); - } - - SUBCASE("readBytes()") { - upstream.print("ABC"); - - char s[4] = {0}; - size_t n = loggingStream.readBytes(s, 4); - - CHECK(n == 3); - CHECK(output.str() == "ABC"); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(4) -> 3 [timeout]"); -#endif - } - - SUBCASE("write(char)") { - int n = loggingStream.write('A'); - - CHECK(n == 1); - CHECK(log.str() == "write('A') -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("write(char*,size_t)") { - int n = loggingStream.write("ABCDEF", 6); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCDEF', 6) -> 4"); - CHECK(output.str() == ""); - } - - SUBCASE("flush()") { - loggingStream.flush(); - - CHECK(log.str() == "flush()"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/ReadThrottlingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/ReadThrottlingStreamTest.cpp deleted file mode 100644 index bb87dc59..00000000 --- a/lib/ArduinoStreamUtils/extras/test/ReadThrottlingStreamTest.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Streams/ReadThrottlingStream.hpp" -#include "StreamUtils/Streams/StringStream.hpp" - -#include "doctest.h" - -#include - -using namespace StreamUtils; - -class SpyingThrottler { - public: - SpyingThrottler(uint32_t rate) { - _log << "C(" << rate << ")"; - } - - SpyingThrottler(const SpyingThrottler& src) { - _log << src._log.str(); - } - - void throttle() { - _log << "T"; - } - - std::string log() const { - return _log.str(); - } - - private: - std::stringstream _log; -}; - -using ReadThrottlingStream = BasicReadThrottlingStream; - -TEST_CASE("ReadThrottlingStream") { - StringStream upstream; - - ReadThrottlingStream throttledStream{upstream, 4}; - Stream& stream = throttledStream; - const SpyingThrottler& throttler = throttledStream.throttler(); - - SUBCASE("available()") { - upstream.print("ABCD"); - CHECK(stream.available() == 4); - CHECK(throttler.log() == "C(4)"); - } - - SUBCASE("read()") { - upstream.print("ABCD"); - int n = stream.read(); - - CHECK(n == 'A'); - CHECK(throttler.log() == "C(4)T"); - } - - SUBCASE("readBytes()") { - upstream.print("ABCD"); - char output[8] = {0}; - - SUBCASE("read more than available") { - size_t n = stream.readBytes(output, sizeof(output)); - - CHECK(n == 4); - CHECK(strcmp("ABCD", output) == 0); - CHECK(throttler.log() == "C(4)TTTTT"); - } - - SUBCASE("read less than available") { - size_t n = stream.readBytes(output, 2); - - CHECK(n == 2); - CHECK(strcmp("AB", output) == 0); - CHECK(throttler.log() == "C(4)TT"); - } - - SUBCASE("read as many as available") { - size_t n = stream.readBytes(output, 4); - - CHECK(n == 4); - CHECK(strcmp("ABCD", output) == 0); - CHECK(throttler.log() == "C(4)TTTT"); - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/SpyingAllocator.hpp b/lib/ArduinoStreamUtils/extras/test/SpyingAllocator.hpp deleted file mode 100644 index 89f5c087..00000000 --- a/lib/ArduinoStreamUtils/extras/test/SpyingAllocator.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "StreamUtils/Ports/DefaultAllocator.hpp" - -class SpyingAllocator { - public: - SpyingAllocator(Print& log) : _log(&log) {} - - bool forceFail = false; - - void* allocate(size_t n) { - void* ptr = forceFail ? 0 : _allocator.allocate(n); - _log->print("allocate("); - _log->print(n); - _log->print(") -> "); - _log->print(ptr ? "ptr" : "null"); - return ptr; - } - - void deallocate(void* ptr) { - _log->print("deallocate("); - _log->print(ptr ? "ptr" : "null"); - _log->print(")"); - _allocator.deallocate(ptr); - } - - private: - Print* _log; - StreamUtils::DefaultAllocator _allocator; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/StringPrintTest.cpp b/lib/ArduinoStreamUtils/extras/test/StringPrintTest.cpp deleted file mode 100644 index 24163bf7..00000000 --- a/lib/ArduinoStreamUtils/extras/test/StringPrintTest.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("StringPrint") { - WHEN("Constructed with no argument") { - StringPrint s; - - THEN("str() return an empty String") { - CHECK(s.str() == ""); - } - - THEN("write(uint8_t) appends the string") { - s.write('A'); - s.write('B'); - CHECK(s.str() == "AB"); - } - - THEN("write(uint8_t) return 1") { - CHECK(s.write('A') == 1); - CHECK(s.write('B') == 1); - } - - THEN("write(0) return 0") { - CHECK(s.write(0) == 0); - } - - THEN("write(uint8_t*, size_t) appends the string") { - s.write(reinterpret_cast("ABXXX"), 2); - s.write(reinterpret_cast("CDEXX"), 3); - CHECK(s.str() == "ABCDE"); - } - - THEN("write(uint8_t*, size_t) return number of chars written") { - uint8_t dummy[32] = {1, 2, 3, 0, 5, 6}; - CHECK(s.write(dummy, 2) == 2); - CHECK(s.write(dummy, 3) == 3); - CHECK(s.write(dummy, 4) == 3); - } - - THEN("str(String) sets the string") { - s.str("world!"); - CHECK(s.str() == "world!"); - } - } - - WHEN("Constructed with string") { - StringPrint s("hello"); - - THEN("str() return the stirng passed to contructor") { - CHECK(s.str() == "hello"); - } - - THEN("write(uint8_t) appends the string") { - s.write('A'); - s.write('B'); - CHECK(s.str() == "helloAB"); - } - - THEN("write(uint8_t*, size_t) appends the string") { - s.write(reinterpret_cast("ABXXX"), 2); - s.write(reinterpret_cast("CDEXX"), 3); - CHECK(s.str() == "helloABCDE"); - } - - THEN("str(String) replaces the string") { - s.str("world!"); - CHECK(s.str() == "world!"); - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/StringStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/StringStreamTest.cpp deleted file mode 100644 index cf0821c8..00000000 --- a/lib/ArduinoStreamUtils/extras/test/StringStreamTest.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Streams/StringStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("StringStream") { - WHEN("Constructed with no argument") { - StringStream s; - - THEN("str() return an empty String") { - CHECK(s.str() == ""); - } - - THEN("write(uint8_t) appends the string") { - s.write('A'); - s.write('B'); - CHECK(s.str() == "AB"); - } - - THEN("write(uint8_t) return 1") { - CHECK(s.write('A') == 1); - CHECK(s.write('B') == 1); - } - - THEN("write(0) return 0") { - CHECK(s.write(0) == 0); - } - - THEN("write(uint8_t*, size_t) appends the string") { - s.write(reinterpret_cast("ABXXX"), 2); - s.write(reinterpret_cast("CDEXX"), 3); - CHECK(s.str() == "ABCDE"); - } - - THEN("write(uint8_t*, size_t) return number of chars written") { - uint8_t dummy[32] = {1, 2, 3, 0, 5, 6}; - CHECK(s.write(dummy, 2) == 2); - CHECK(s.write(dummy, 3) == 3); - CHECK(s.write(dummy, 4) == 3); - } - - THEN("str(String) sets the string") { - s.str("world!"); - CHECK(s.str() == "world!"); - } - - THEN("available() returns 0") { - CHECK(s.available() == 0); - } - - THEN("peek() return -1") { - CHECK(s.peek() == -1); - } - - THEN("peek() return -1") { - CHECK(s.read() == -1); - } - } - - WHEN("Constructed with string") { - StringStream s("hello"); - - THEN("str() returns the string passed to contructor") { - CHECK(s.str() == "hello"); - } - - THEN("available() returns the length passed to the constructor") { - CHECK(s.available() == 5); - } - - THEN("write(uint8_t) appends the string") { - s.write('A'); - s.write('B'); - CHECK(s.str() == "helloAB"); - } - - THEN("write(uint8_t*, size_t) appends the string") { - s.write(reinterpret_cast("ABXXX"), 2); - s.write(reinterpret_cast("CDEXX"), 3); - CHECK(s.str() == "helloABCDE"); - } - - THEN("str(String) replaces the string") { - s.str("world!"); - CHECK(s.str() == "world!"); - } - - THEN("peek() return the first char") { - CHECK(s.peek() == 'h'); - } - - THEN("peek() return the next char") { - CHECK(s.read() == 'h'); - CHECK(s.read() == 'e'); - } - - THEN("readBytes() can return the begining of the string") { - char buffer[32] = {0}; - CHECK(s.readBytes(buffer, 3) == 3); - CHECK(buffer == std::string("hel")); - CHECK(s.available() == 2); - } - - THEN("readBytes() can return the whole string") { - char buffer[32] = {0}; - CHECK(s.readBytes(buffer, 32) == 5); - CHECK(buffer == std::string("hello")); - CHECK(s.available() == 0); - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/WaitingPrintTest.cpp b/lib/ArduinoStreamUtils/extras/test/WaitingPrintTest.cpp deleted file mode 100644 index 8a691204..00000000 --- a/lib/ArduinoStreamUtils/extras/test/WaitingPrintTest.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Prints/WaitingPrint.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("WaitingPrint") { - MemoryStream upstream(4); - - StringPrint log; - SpyingStream spy{upstream, log}; - WaitingPrint stream{static_cast(spy), [&spy]() { spy.flush(); }}; - - SUBCASE("write(char*, size_t)") { - SUBCASE("no need to wait") { - CHECK(stream.print("ABC") == 3); - - CHECK(log.str() == "write('ABC', 3) -> 3"); - } - - SUBCASE("need to wait") { - CHECK(stream.print("ABCDEFG") == 7); - - CHECK(log.str() == - "write('ABCDEFG', 7) -> 4" - "flush()" - "write('EFG', 3) -> 3"); - } - - SUBCASE("need to wait twice") { - CHECK(stream.print("ABCDEFGIJKL") == 11); - - CHECK(log.str() == - "write('ABCDEFGIJKL', 11) -> 4" - "flush()" - "write('EFGIJKL', 7) -> 4" - "flush()" - "write('JKL', 3) -> 3"); - } - - SUBCASE("doesn't wait when timeout is 0") { - stream.setTimeout(0); - - CHECK(stream.print("ABCDEFG") == 4); - - CHECK(log.str() == "write('ABCDEFG', 7) -> 4"); - } - } - - SUBCASE("write(char)") { - SUBCASE("no need to wait") { - CHECK(stream.write('A') == 1); - CHECK(stream.write('B') == 1); - CHECK(stream.write('C') == 1); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1"); - } - - SUBCASE("need to wait") { - for (int i = 0; i < 7; i++) - CHECK(stream.write("ABCDEFG"[i]) == 1); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1" - "write('D') -> 1" - "write('E') -> 0" - "flush()" - "write('E') -> 1" - "write('F') -> 1" - "write('G') -> 1"); - } - - SUBCASE("doesn't wait when timeout is 0") { - stream.setTimeout(0); - - CHECK(stream.write('A') == 1); - CHECK(stream.write('B') == 1); - CHECK(stream.write('C') == 1); - CHECK(stream.write('D') == 1); - CHECK(stream.write('E') == 0); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1" - "write('D') -> 1" - "write('E') -> 0"); - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/WriteBufferingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/WriteBufferingClientTest.cpp deleted file mode 100644 index e300a06f..00000000 --- a/lib/ArduinoStreamUtils/extras/test/WriteBufferingClientTest.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Clients/MemoryClient.hpp" -#include "StreamUtils/Clients/SpyingClient.hpp" -#include "StreamUtils/Clients/WriteBufferingClient.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("WriteBufferingClient") { - MemoryClient target(64); - - StringPrint log; - SpyingClient spy{target, log}; - - GIVEN("capacity is 4") { - WriteBufferingClient bufferingClient{spy, 4}; - - SUBCASE("available()") { - target.print("ABC"); - - CHECK(bufferingClient.available() == 3); - CHECK(log.str() == "available() -> 3"); - } - - SUBCASE("connect(IPAddress)") { - int n = bufferingClient.connect(IPAddress("1.2.3.4"), 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - } - - SUBCASE("connect(const char*)") { - int n = bufferingClient.connect("1.2.3.4", 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - } - - SUBCASE("connected()") { - uint8_t n = bufferingClient.connected(); - - CHECK(n == false); - CHECK(log.str() == "connected() -> 0"); - } - - SUBCASE("stop()") { - bufferingClient.write("ABC", 3); - bufferingClient.stop(); - - CHECK(log.str() == - "write('ABC', 3) -> 3" - "stop()"); - } - - SUBCASE("operator bool()") { - bool n = bufferingClient.operator bool(); - - CHECK(n == true); - CHECK(log.str() == "operator bool() -> true"); - } - - SUBCASE("flush() forwards to target)") { - bufferingClient.flush(); - - CHECK(log.str() == "flush()"); - } - - SUBCASE("flush() calls write() and flush()") { - bufferingClient.write("ABC", 3); - bufferingClient.flush(); - - CHECK(log.str() == - "write('ABC', 3) -> 3" - "flush()"); - } - - SUBCASE("peek()") { - target.print("ABC"); - - CHECK(bufferingClient.peek() == 'A'); - CHECK(log.str() == "peek() -> 65"); - } - - SUBCASE("read()") { - target.print("ABC"); - - CHECK(bufferingClient.read() == 'A'); - CHECK(log.str() == "read() -> 65"); - } - - SUBCASE("readBytes()") { - target.print("ABC"); - - char s[4] = {0}; - int n = bufferingClient.readBytes(s, 3); - - CHECK(n == 3); - CHECK(s == std::string("ABC")); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(3) -> 3"); -#endif - } - - GIVEN("the buffer is empty") { - SUBCASE("write(uint8_t)") { - int n = bufferingClient.write('A'); - - CHECK(n == 1); - CHECK(log.str() == ""); - } - - SUBCASE("write(uint8_t) should flush") { - bufferingClient.write('A'); - bufferingClient.write('B'); - bufferingClient.write('C'); - bufferingClient.write('D'); - bufferingClient.write('E'); - - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - - SUBCASE("write(char*,3) goes in buffer") { - size_t n = bufferingClient.write("ABC", 3); - - CHECK(n == 3); - CHECK(log.str() == ""); - } - - SUBCASE("write(char*,4) bypasses buffer") { - size_t n = bufferingClient.write("ABCD", 4); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - SUBCASE("write(char*,2) bypasses buffer") { - size_t n = bufferingClient.write("ABCD", 4); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - } - - GIVEN("one byte in the buffer") { - bufferingClient.write('A'); - - SUBCASE("write(char*,3) goes in buffer and flush") { - size_t n = bufferingClient.write("BCD", 3); - - CHECK(n == 3); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - - SUBCASE("write(char*,7) bypasses") { - size_t n = bufferingClient.write("BCDEFGH", 7); - - CHECK(n == 7); - CHECK(log.str() == - "write('ABCD', 4) -> 4" - "write('EFGH', 4) -> 4"); - } - } - } - - GIVEN("capacity is 0") { - WriteBufferingClient bufferingClient{spy, 0}; - - SUBCASE("write(uint8_t) forwards to target") { - int n = bufferingClient.write('X'); - - CHECK(n == 1); - CHECK(log.str() == "write('X') -> 1"); - } - - SUBCASE("write(char*,1) forwards to target") { - int n = bufferingClient.write("A", 1); - - CHECK(n == 1); - CHECK(log.str() == "write('A', 1) -> 1"); - } - - SUBCASE("flush() forwards to target") { - bufferingClient.flush(); - - CHECK(log.str() == "flush()"); - } - } - - SUBCASE("Destructor should flush") { - { - WriteBufferingClient bufferingClient{spy, 10}; - bufferingClient.write("ABC", 3); - } - - CHECK(log.str() == "write('ABC', 3) -> 3"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/WriteBufferingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/WriteBufferingStreamTest.cpp deleted file mode 100644 index 0dae701e..00000000 --- a/lib/ArduinoStreamUtils/extras/test/WriteBufferingStreamTest.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" -#include "StreamUtils/Streams/WriteBufferingStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("WriteBufferingStream") { - MemoryStream upstream(64); - - StringPrint log; - SpyingStream spy{upstream, log}; - - GIVEN("capacity is 4") { - WriteBufferingStream stream{spy, 4}; - - SUBCASE("available()") { - upstream.print("ABC"); - - CHECK(stream.available() == 3); - CHECK(log.str() == "available() -> 3"); - } - - SUBCASE("flush() forwards to upstream)") { - stream.flush(); - - CHECK(log.str() == "flush()"); - } - - SUBCASE("flush() calls write() and flush()") { - stream.write("ABC", 3); - stream.flush(); - - CHECK(log.str() == - "write('ABC', 3) -> 3" - "flush()"); - } - - SUBCASE("peek()") { - upstream.print("ABC"); - - CHECK(stream.peek() == 'A'); - CHECK(log.str() == "peek() -> 65"); - } - - SUBCASE("read()") { - upstream.print("ABC"); - - CHECK(stream.read() == 'A'); - CHECK(log.str() == "read() -> 65"); - } - - SUBCASE("readBytes()") { - upstream.print("ABC"); - - char s[4] = {0}; - int n = stream.readBytes(s, 3); - - CHECK(n == 3); - CHECK(s == std::string("ABC")); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(3) -> 3"); -#endif - } - - GIVEN("the buffer is empty") { - SUBCASE("write(uint8_t)") { - int n = stream.write('A'); - - CHECK(n == 1); - CHECK(log.str() == ""); - } - - SUBCASE("write(uint8_t) should flush") { - stream.write('A'); - stream.write('B'); - stream.write('C'); - stream.write('D'); - stream.write('E'); - - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - - SUBCASE("write(char*,3) goes in buffer") { - size_t n = stream.write("ABC", 3); - - CHECK(n == 3); - CHECK(log.str() == ""); - } - - SUBCASE("write(char*,4) bypasses buffer") { - size_t n = stream.write("ABCD", 4); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - SUBCASE("write(char*,2) bypasses buffer") { - size_t n = stream.write("ABCD", 4); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - } - - GIVEN("one byte in the buffer") { - stream.write('A'); - - SUBCASE("write(char*,3) goes in buffer and flush") { - size_t n = stream.write("BCD", 3); - - CHECK(n == 3); - CHECK(log.str() == "write('ABCD', 4) -> 4"); - } - - SUBCASE("write(char*,7) bypasses") { - size_t n = stream.write("BCDEFGH", 7); - - CHECK(n == 7); - CHECK(log.str() == - "write('ABCD', 4) -> 4" - "write('EFGH', 4) -> 4"); - } - } - } - - GIVEN("capacity is 0") { - WriteBufferingStream stream{spy, 0}; - - SUBCASE("write(uint8_t) forwards to upstream") { - int n = stream.write('X'); - - CHECK(n == 1); - CHECK(log.str() == "write('X') -> 1"); - } - - SUBCASE("write(char*,1) forwards to upstream") { - int n = stream.write("A", 1); - - CHECK(n == 1); - CHECK(log.str() == "write('A', 1) -> 1"); - } - - SUBCASE("flush() forwards to upstream") { - stream.flush(); - - CHECK(log.str() == "flush()"); - } - } - - SUBCASE("Destructor should flush") { - { - WriteBufferingStream stream{spy, 10}; - stream.write("ABC", 3); - } - - CHECK(log.str() == "write('ABC', 3) -> 3"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/WriteLoggingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/WriteLoggingClientTest.cpp deleted file mode 100644 index 3d5c6115..00000000 --- a/lib/ArduinoStreamUtils/extras/test/WriteLoggingClientTest.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Clients/MemoryClient.hpp" -#include "StreamUtils/Clients/SpyingClient.hpp" -#include "StreamUtils/Clients/WriteLoggingClient.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("WriteLoggingClient") { - MemoryClient target(4); - - StringPrint log; - SpyingClient spy{target, log}; - - StringPrint output; - WriteLoggingClient loggingClient{spy, output}; - - SUBCASE("available()") { - target.print("ABC"); - - size_t n = loggingClient.available(); - - CHECK(n == 3); - CHECK(log.str() == "available() -> 3"); - CHECK(output.str() == ""); - } - - SUBCASE("connect(IPAddress)") { - int n = loggingClient.connect(IPAddress("1.2.3.4"), 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("connect(const char*)") { - int n = loggingClient.connect("1.2.3.4", 80); - - CHECK(n == 1); - CHECK(log.str() == "connect('1.2.3.4', 80) -> 1"); - CHECK(output.str() == ""); - } - - SUBCASE("connected()") { - uint8_t n = loggingClient.connected(); - - CHECK(n == false); - CHECK(log.str() == "connected() -> 0"); - CHECK(output.str() == ""); - } - - SUBCASE("stop()") { - loggingClient.stop(); - - CHECK(log.str() == "stop()"); - CHECK(output.str() == ""); - } - - SUBCASE("operator bool()") { - bool n = loggingClient.operator bool(); - - CHECK(n == true); - CHECK(log.str() == "operator bool() -> true"); - CHECK(output.str() == ""); - } - - SUBCASE("peek()") { - target.print("ABC"); - - int n = loggingClient.peek(); - - CHECK(n == 'A'); - CHECK(log.str() == "peek() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("read()") { - target.print("ABC"); - - int n = loggingClient.read(); - - CHECK(n == 'A'); - CHECK(log.str() == "read() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("read(uint8_t*,size_t)") { - target.print("ABC"); - - uint8_t s[4] = {0}; - size_t n = loggingClient.read(s, 4); - - CHECK(n == 3); - CHECK(log.str() == "read(4) -> 3 [timeout]"); - CHECK(output.str() == ""); - } - - SUBCASE("readBytes()") { - target.print("ABC"); - - char s[4] = {0}; - size_t n = loggingClient.readBytes(s, 4); - - CHECK(n == 3); - CHECK(output.str() == ""); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(4) -> 3 [timeout]"); -#endif - } - - SUBCASE("write(char)") { - int n = loggingClient.write('A'); - - CHECK(n == 1); - CHECK(log.str() == "write('A') -> 1"); - CHECK(output.str() == "A"); - } - - SUBCASE("write(char*,size_t)") { - int n = loggingClient.write("ABCDEF", 6); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCDEF', 6) -> 4"); - CHECK(output.str() == "ABCD"); - } - - SUBCASE("flush()") { - loggingClient.flush(); - - CHECK(output.str() == ""); - CHECK(log.str() == "flush()"); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/WriteLoggingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/WriteLoggingStreamTest.cpp deleted file mode 100644 index e38ae525..00000000 --- a/lib/ArduinoStreamUtils/extras/test/WriteLoggingStreamTest.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" -#include "StreamUtils/Streams/WriteLoggingStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("WriteLoggingStream") { - MemoryStream upstream(4); - - StringPrint log; - SpyingStream upstreamSpy{upstream, log}; - - StringPrint output; - WriteLoggingStream loggingStream{upstreamSpy, output}; - - SUBCASE("available()") { - upstream.print("ABC"); - - size_t n = loggingStream.available(); - - CHECK(n == 3); - CHECK(log.str() == "available() -> 3"); - CHECK(output.str() == ""); - } - - SUBCASE("peek()") { - upstream.print("ABC"); - - int n = loggingStream.peek(); - - CHECK(n == 'A'); - CHECK(log.str() == "peek() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("read()") { - upstream.print("ABC"); - - int n = loggingStream.read(); - - CHECK(n == 'A'); - CHECK(log.str() == "read() -> 65"); - CHECK(output.str() == ""); - } - - SUBCASE("readBytes()") { - upstream.print("ABC"); - - char s[4] = {0}; - size_t n = loggingStream.readBytes(s, 4); - - CHECK(n == 3); - CHECK(output.str() == ""); -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - CHECK(log.str() == "readBytes(4) -> 3 [timeout]"); -#endif - } - - SUBCASE("write(char)") { - int n = loggingStream.write('A'); - - CHECK(n == 1); - CHECK(log.str() == "write('A') -> 1"); - CHECK(output.str() == "A"); - } - - SUBCASE("write(char*,size_t)") { - int n = loggingStream.write("ABCDEF", 6); - - CHECK(n == 4); - CHECK(log.str() == "write('ABCDEF', 6) -> 4"); - CHECK(output.str() == "ABCD"); - } - - SUBCASE("flush()") { - loggingStream.flush(); - - CHECK(log.str() == "flush()"); - CHECK(output.str() == ""); - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/WriteWaitingClientTest.cpp b/lib/ArduinoStreamUtils/extras/test/WriteWaitingClientTest.cpp deleted file mode 100644 index 20b2d901..00000000 --- a/lib/ArduinoStreamUtils/extras/test/WriteWaitingClientTest.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Clients/MemoryClient.hpp" -#include "StreamUtils/Clients/SpyingClient.hpp" -#include "StreamUtils/Clients/WriteWaitingClient.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("WriteWaitingClient") { - MemoryClient upstream(4); - - StringPrint log; - SpyingClient spy{upstream, log}; - WriteWaitingClient client{spy, [&spy]() { spy.flush(); }}; - - SUBCASE("write(char*, size_t)") { - SUBCASE("no need to wait") { - CHECK(client.print("ABC") == 3); - - CHECK(log.str() == "write('ABC', 3) -> 3"); - } - - SUBCASE("need to wait") { - CHECK(client.print("ABCDEFG") == 7); - - CHECK(log.str() == - "write('ABCDEFG', 7) -> 4" - "flush()" - "write('EFG', 3) -> 3"); - } - - SUBCASE("need to wait twice") { - CHECK(client.print("ABCDEFGIJKL") == 11); - - CHECK(log.str() == - "write('ABCDEFGIJKL', 11) -> 4" - "flush()" - "write('EFGIJKL', 7) -> 4" - "flush()" - "write('JKL', 3) -> 3"); - } - - SUBCASE("doesn't wait when timeout is 0") { - client.setTimeout(0); - - CHECK(client.print("ABCDEFG") == 4); - - CHECK(log.str() == "write('ABCDEFG', 7) -> 4"); - } - } - - SUBCASE("write(char)") { - SUBCASE("no need to wait") { - CHECK(client.write('A') == 1); - CHECK(client.write('B') == 1); - CHECK(client.write('C') == 1); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1"); - } - - SUBCASE("need to wait") { - for (int i = 0; i < 7; i++) - CHECK(client.write("ABCDEFG"[i]) == 1); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1" - "write('D') -> 1" - "write('E') -> 0" - "flush()" - "write('E') -> 1" - "write('F') -> 1" - "write('G') -> 1"); - } - - SUBCASE("doesn't wait when timeout is 0") { - client.setTimeout(0); - - CHECK(client.write('A') == 1); - CHECK(client.write('B') == 1); - CHECK(client.write('C') == 1); - CHECK(client.write('D') == 1); - CHECK(client.write('E') == 0); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1" - "write('D') -> 1" - "write('E') -> 0"); - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/WriteWaitingStreamTest.cpp b/lib/ArduinoStreamUtils/extras/test/WriteWaitingStreamTest.cpp deleted file mode 100644 index f071ea02..00000000 --- a/lib/ArduinoStreamUtils/extras/test/WriteWaitingStreamTest.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "FailingAllocator.hpp" - -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/MemoryStream.hpp" -#include "StreamUtils/Streams/SpyingStream.hpp" -#include "StreamUtils/Streams/WriteWaitingStream.hpp" - -#include "doctest.h" - -using namespace StreamUtils; - -TEST_CASE("WriteWaitingStream") { - MemoryStream upstream(4); - - StringPrint log; - SpyingStream spy{upstream, log}; - WriteWaitingStream stream{spy, [&spy]() { spy.flush(); }}; - - SUBCASE("write(char*, size_t)") { - SUBCASE("no need to wait") { - CHECK(stream.print("ABC") == 3); - - CHECK(log.str() == "write('ABC', 3) -> 3"); - } - - SUBCASE("need to wait") { - CHECK(stream.print("ABCDEFG") == 7); - - CHECK(log.str() == - "write('ABCDEFG', 7) -> 4" - "flush()" - "write('EFG', 3) -> 3"); - } - - SUBCASE("need to wait twice") { - CHECK(stream.print("ABCDEFGIJKL") == 11); - - CHECK(log.str() == - "write('ABCDEFGIJKL', 11) -> 4" - "flush()" - "write('EFGIJKL', 7) -> 4" - "flush()" - "write('JKL', 3) -> 3"); - } - - SUBCASE("doesn't wait when timeout is 0") { - stream.setTimeout(0); - - CHECK(stream.print("ABCDEFG") == 4); - - CHECK(log.str() == "write('ABCDEFG', 7) -> 4"); - } - } - - SUBCASE("write(char)") { - SUBCASE("no need to wait") { - CHECK(stream.write('A') == 1); - CHECK(stream.write('B') == 1); - CHECK(stream.write('C') == 1); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1"); - } - - SUBCASE("need to wait") { - for (int i = 0; i < 7; i++) - CHECK(stream.write("ABCDEFG"[i]) == 1); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1" - "write('D') -> 1" - "write('E') -> 0" - "flush()" - "write('E') -> 1" - "write('F') -> 1" - "write('G') -> 1"); - } - - SUBCASE("doesn't wait when timeout is 0") { - stream.setTimeout(0); - - CHECK(stream.write('A') == 1); - CHECK(stream.write('B') == 1); - CHECK(stream.write('C') == 1); - CHECK(stream.write('D') == 1); - CHECK(stream.write('E') == 0); - - CHECK(log.str() == - "write('A') -> 1" - "write('B') -> 1" - "write('C') -> 1" - "write('D') -> 1" - "write('E') -> 0"); - } - } -} diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/Arduino.h b/lib/ArduinoStreamUtils/extras/test/cores/avr/Arduino.h deleted file mode 100644 index e94f54ff..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/Arduino.h +++ /dev/null @@ -1,18 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include -#include -#include - -#include - -inline unsigned long millis() { - return static_cast(time(NULL)); -} - -inline void yield() {} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/cores/avr/CMakeLists.txt deleted file mode 100644 index 4cc892e0..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -add_library(AvrCore - Client.h - EEPROM.cpp - EEPROM.h - Print.h - Stream.h - WString.h -) - -target_include_directories(AvrCore - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(AvrCore - PUBLIC - ARDUINO_ARCH_AVR -) diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/Client.h b/lib/ArduinoStreamUtils/extras/test/cores/avr/Client.h deleted file mode 100644 index 79d7a5d1..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/Client.h +++ /dev/null @@ -1,27 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Stream.h" -#include "WString.h" - -using IPAddress = String; - -struct Client : Stream { - virtual int connect(IPAddress ip, uint16_t port) = 0; - virtual int connect(const char *host, uint16_t port) = 0; - virtual uint8_t connected() = 0; - virtual void stop() = 0; - virtual operator bool() = 0; - - // Already in Stream - virtual size_t write(uint8_t) = 0; - virtual size_t write(const uint8_t *buf, size_t size) = 0; - virtual int available() = 0; - virtual int read() = 0; - - // Curiously not in Stream - virtual int read(uint8_t *buf, size_t size) = 0; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.cpp b/lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.cpp deleted file mode 100644 index 2b2eb1a8..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "EEPROM.h" - -EEPROMClass EEPROM; -static uint8_t data[512]; - -uint8_t EEPROMClass::read(int address) { - return data[address]; -} - -void EEPROMClass::update(int address, uint8_t value) { - data[address] = value; -} diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.h b/lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.h deleted file mode 100644 index b5e3360c..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -class EEPROMClass { - public: - uint8_t read(int); - void update(int, uint8_t); - // void write(int, uint8_t); <- it exists but we want to use update() instead -}; - -extern EEPROMClass EEPROM; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/Print.h b/lib/ArduinoStreamUtils/extras/test/cores/avr/Print.h deleted file mode 100644 index 34b48916..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/Print.h +++ /dev/null @@ -1,42 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include - -#include - -struct Print { - virtual size_t write(const uint8_t *buffer, size_t size) = 0; - virtual size_t write(uint8_t data) = 0; - virtual void flush() {} - - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } - - size_t print(const String &s) { - return write(s.c_str(), s.length()); - } - - size_t print(const char *s) { - return write(s, std::strlen(s)); - } - - size_t println() { - return 0; - } - - template - size_t print(const T &value) { - return print(String(value)); - } - - template - size_t println(const T &value) { - return print(value); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/Stream.h b/lib/ArduinoStreamUtils/extras/test/cores/avr/Stream.h deleted file mode 100644 index 869b9d4c..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/Stream.h +++ /dev/null @@ -1,41 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Print.h" - -struct Stream : Print { - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - - size_t readBytes(char *buffer, size_t length) { - size_t count = 0; - while (count < length) { - int c = timedRead(); - if (c < 0) - break; - *buffer++ = (char)c; - count++; - } - return count; - } - - String readString() { - String result; - int c; - while ((c = timedRead()) >= 0) { - result += static_cast(c); - } - return result; - } - - void setTimeout(unsigned long) {} - - protected: - int timedRead() { - return read(); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/avr/WString.h b/lib/ArduinoStreamUtils/extras/test/cores/avr/WString.h deleted file mode 100644 index a4c911bd..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/avr/WString.h +++ /dev/null @@ -1,43 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -class String : private std::string { - public: - String() {} - String(const String& s) : std::string(s) {} - String(String&& s) : std::string(std::move(s)) {} - String(const char* s) : std::string(s) {} - String(int n) : std::string(std::to_string(n)) {} - - String& operator=(const String& rhs) { - std::string::operator=(rhs); - return *this; - } - - using std::string::c_str; - using std::string::length; - using std::string::operator+=; - using std::string::operator[]; - - void remove(unsigned int index, unsigned int count) { - erase(begin() + index, begin() + index + count); - } - - void toCharArray(char* buf, unsigned int bufsize, - unsigned int index = 0) const { - copy(buf, bufsize, index); - } - - friend bool operator==(const String& lhs, const char* rhs) { - return static_cast(lhs) == rhs; - } - - friend std::ostream& operator<<(std::ostream& lhs, const String& rhs) { - return lhs << static_cast(rhs); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Arduino.h b/lib/ArduinoStreamUtils/extras/test/cores/esp32/Arduino.h deleted file mode 100644 index e94f54ff..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Arduino.h +++ /dev/null @@ -1,18 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include -#include -#include - -#include - -inline unsigned long millis() { - return static_cast(time(NULL)); -} - -inline void yield() {} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/cores/esp32/CMakeLists.txt deleted file mode 100644 index cc3cd733..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -add_library(Esp32Core - Client.h - EEPROM.cpp - EEPROM.h - Print.h - Stream.h - WString.h -) - -target_include_directories(Esp32Core - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(Esp32Core - PUBLIC - ARDUINO_ARCH_ESP32 -) diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Client.h b/lib/ArduinoStreamUtils/extras/test/cores/esp32/Client.h deleted file mode 100644 index 1fc8d8f0..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Client.h +++ /dev/null @@ -1,26 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Stream.h" -#include "WString.h" - -using IPAddress = String; - -class Client : public Stream { - public: - virtual int connect(IPAddress ip, uint16_t port) = 0; - virtual int connect(const char *host, uint16_t port) = 0; - virtual size_t write(uint8_t) = 0; - virtual size_t write(const uint8_t *buf, size_t size) = 0; - virtual int available() = 0; - virtual int read() = 0; - virtual int read(uint8_t *buf, size_t size) = 0; - virtual int peek() = 0; - virtual void flush() = 0; - virtual void stop() = 0; - virtual uint8_t connected() = 0; - virtual operator bool() = 0; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.cpp b/lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.cpp deleted file mode 100644 index a47dd834..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "EEPROM.h" - -#include // memcpy - -EEPROMClass EEPROM; -static uint8_t commitedData[512]; -static uint8_t pendingData[512]; - -uint8_t EEPROMClass::read(int address) { - return commitedData[address]; -} - -void EEPROMClass::write(int address, uint8_t value) { - pendingData[address] = value; -} - -bool EEPROMClass::commit() { - memcpy(commitedData, pendingData, 512); - return true; -} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.h b/lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.h deleted file mode 100644 index cd9eb00c..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -class EEPROMClass { - public: - uint8_t read(int); - void write(int, uint8_t); - bool commit(); -}; - -extern EEPROMClass EEPROM; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Print.h b/lib/ArduinoStreamUtils/extras/test/cores/esp32/Print.h deleted file mode 100644 index 40ff3646..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Print.h +++ /dev/null @@ -1,42 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include -#include - -struct Print { - virtual ~Print() {} - virtual size_t write(const uint8_t *buffer, size_t size) = 0; - virtual size_t write(uint8_t data) = 0; - - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } - - size_t print(const String &s) { - return write(s.c_str(), s.length()); - } - - size_t print(const char *s) { - return write(s, std::strlen(s)); - } - - size_t println() { - return 0; - } - - template - size_t print(const T &value) { - return print(String(value)); - } - - template - size_t println(const T &value) { - return print(value); - } -}; \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Stream.h b/lib/ArduinoStreamUtils/extras/test/cores/esp32/Stream.h deleted file mode 100644 index dae174d3..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/Stream.h +++ /dev/null @@ -1,48 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Print.h" - -struct Stream : Print { - virtual ~Stream() {} - - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - virtual void flush() = 0; - - virtual size_t readBytes(char *buffer, size_t length) { - size_t count = 0; - while (count < length) { - int c = timedRead(); - if (c < 0) - break; - *buffer++ = (char)c; - count++; - } - return count; - } - - virtual size_t readBytes(uint8_t *buffer, size_t length) { - return readBytes((char *)buffer, length); - } - - virtual String readString() { - String result; - int c; - while ((c = timedRead()) >= 0) { - result += c; - } - return result; - } - - void setTimeout(unsigned long) {} - - protected: - int timedRead() { - return read(); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp32/WString.h b/lib/ArduinoStreamUtils/extras/test/cores/esp32/WString.h deleted file mode 100644 index 9023e414..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp32/WString.h +++ /dev/null @@ -1,5 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "../avr/WString.h" \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Arduino.h b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Arduino.h deleted file mode 100644 index e94f54ff..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Arduino.h +++ /dev/null @@ -1,18 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include -#include -#include - -#include - -inline unsigned long millis() { - return static_cast(time(NULL)); -} - -inline void yield() {} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/CMakeLists.txt deleted file mode 100644 index 94d385d5..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -add_library(Esp8266Core - Client.h - EEPROM.cpp - EEPROM.h - Print.h - Stream.h - WString.h -) - -target_include_directories(Esp8266Core - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(Esp8266Core - PUBLIC - ARDUINO_ARCH_ESP8266 -) diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Client.h b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Client.h deleted file mode 100644 index 1fc8d8f0..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Client.h +++ /dev/null @@ -1,26 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Stream.h" -#include "WString.h" - -using IPAddress = String; - -class Client : public Stream { - public: - virtual int connect(IPAddress ip, uint16_t port) = 0; - virtual int connect(const char *host, uint16_t port) = 0; - virtual size_t write(uint8_t) = 0; - virtual size_t write(const uint8_t *buf, size_t size) = 0; - virtual int available() = 0; - virtual int read() = 0; - virtual int read(uint8_t *buf, size_t size) = 0; - virtual int peek() = 0; - virtual void flush() = 0; - virtual void stop() = 0; - virtual uint8_t connected() = 0; - virtual operator bool() = 0; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.cpp b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.cpp deleted file mode 100644 index fd0ef682..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "EEPROM.h" - -#include // memcpy - -EEPROMClass EEPROM; -static uint8_t commitedData[512]; -static uint8_t pendingData[512]; - -uint8_t EEPROMClass::read(int address) { - return commitedData[address]; -} - -void EEPROMClass::write(int address, uint8_t value) { - pendingData[address] = value; -} - -void EEPROMClass::commit() { - memcpy(commitedData, pendingData, 512); -} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.h b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.h deleted file mode 100644 index 63da03ba..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -class EEPROMClass { - public: - uint8_t read(int); - void write(int, uint8_t); - void commit(); -}; - -extern EEPROMClass EEPROM; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Print.h b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Print.h deleted file mode 100644 index 2abf7369..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Print.h +++ /dev/null @@ -1,43 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include -#include - -struct Print { - virtual size_t write(const uint8_t *buffer, size_t size) = 0; - virtual size_t write(uint8_t data) = 0; - - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } - - size_t print(const String &s) { - return write(s.c_str(), s.length()); - } - - size_t print(const char *s) { - return write(s, std::strlen(s)); - } - - size_t println() { - return 0; - } - - template - size_t print(const T &value) { - return print(String(value)); - } - - template - size_t println(const T &value) { - return print(value); - } - - virtual void flush() {} -}; \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Stream.h b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Stream.h deleted file mode 100644 index 5dea8c51..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/Stream.h +++ /dev/null @@ -1,45 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Print.h" - -struct Stream : Print { - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - - virtual size_t readBytes(char *buffer, size_t length) { - size_t count = 0; - while (count < length) { - int c = timedRead(); - if (c < 0) - break; - *buffer++ = (char)c; - count++; - } - return count; - } - - virtual size_t readBytes(uint8_t *buffer, size_t length) { - return readBytes((char *)buffer, length); - } - - virtual String readString() { - String result; - int c; - while ((c = timedRead()) >= 0) { - result += c; - } - return result; - } - - void setTimeout(unsigned long) {} - - protected: - int timedRead() { - return read(); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/WString.h b/lib/ArduinoStreamUtils/extras/test/cores/esp8266/WString.h deleted file mode 100644 index 9023e414..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/esp8266/WString.h +++ /dev/null @@ -1,5 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "../avr/WString.h" \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Arduino.h b/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Arduino.h deleted file mode 100644 index e94f54ff..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Arduino.h +++ /dev/null @@ -1,18 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include -#include -#include - -#include - -inline unsigned long millis() { - return static_cast(time(NULL)); -} - -inline void yield() {} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/cores/nrf52/CMakeLists.txt deleted file mode 100644 index 85f8ae8c..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -add_library(Nrf52Core INTERFACE) - -target_include_directories(Nrf52Core - INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(Nrf52Core - INTERFACE - ARDUINO_ARCH_NRF52 -) diff --git a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Client.h b/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Client.h deleted file mode 100644 index 1fc8d8f0..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Client.h +++ /dev/null @@ -1,26 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Stream.h" -#include "WString.h" - -using IPAddress = String; - -class Client : public Stream { - public: - virtual int connect(IPAddress ip, uint16_t port) = 0; - virtual int connect(const char *host, uint16_t port) = 0; - virtual size_t write(uint8_t) = 0; - virtual size_t write(const uint8_t *buf, size_t size) = 0; - virtual int available() = 0; - virtual int read() = 0; - virtual int read(uint8_t *buf, size_t size) = 0; - virtual int peek() = 0; - virtual void flush() = 0; - virtual void stop() = 0; - virtual uint8_t connected() = 0; - virtual operator bool() = 0; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Print.h b/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Print.h deleted file mode 100644 index 2d02babf..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Print.h +++ /dev/null @@ -1,45 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include -#include - -struct Print { - virtual size_t write(const uint8_t *buffer, size_t size) = 0; - virtual size_t write(uint8_t data) = 0; - - virtual int availableForWrite() { - return 0; - } - - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } - - size_t print(const String &s) { - return write(s.c_str(), s.length()); - } - - size_t print(const char *s) { - return write(s, std::strlen(s)); - } - - size_t println() { - return 0; - } - - template - size_t print(const T &value) { - return print(String(value)); - } - - template - size_t println(const T &value) { - return print(value); - } -}; \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Stream.h b/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Stream.h deleted file mode 100644 index 884dbabd..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/Stream.h +++ /dev/null @@ -1,45 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Print.h" - -struct Stream : Print { - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - virtual void flush() {} - - size_t readBytes(char *buffer, size_t length) { - size_t count = 0; - while (count < length) { - int c = timedRead(); - if (c < 0) - break; - *buffer++ = (char)c; - count++; - } - return count; - } - - size_t readBytes(uint8_t *buffer, size_t length) { - return readBytes((char *)buffer, length); - } - - String readString() { - String result; - int c; - while ((c = timedRead()) >= 0) - result += c; - return result; - } - - void setTimeout(unsigned long) {} - - protected: - int timedRead() { - return read(); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/WString.h b/lib/ArduinoStreamUtils/extras/test/cores/nrf52/WString.h deleted file mode 100644 index 9023e414..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/nrf52/WString.h +++ /dev/null @@ -1,5 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "../avr/WString.h" \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/samd/Arduino.h b/lib/ArduinoStreamUtils/extras/test/cores/samd/Arduino.h deleted file mode 100644 index e94f54ff..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/samd/Arduino.h +++ /dev/null @@ -1,18 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include -#include -#include - -#include - -inline unsigned long millis() { - return static_cast(time(NULL)); -} - -inline void yield() {} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/samd/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/cores/samd/CMakeLists.txt deleted file mode 100644 index ffc774b1..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/samd/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -add_library(SamdCore INTERFACE) - -target_include_directories(SamdCore - INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(SamdCore - INTERFACE - ARDUINO_ARCH_SAMD -) diff --git a/lib/ArduinoStreamUtils/extras/test/cores/samd/Client.h b/lib/ArduinoStreamUtils/extras/test/cores/samd/Client.h deleted file mode 100644 index 1fc8d8f0..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/samd/Client.h +++ /dev/null @@ -1,26 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Stream.h" -#include "WString.h" - -using IPAddress = String; - -class Client : public Stream { - public: - virtual int connect(IPAddress ip, uint16_t port) = 0; - virtual int connect(const char *host, uint16_t port) = 0; - virtual size_t write(uint8_t) = 0; - virtual size_t write(const uint8_t *buf, size_t size) = 0; - virtual int available() = 0; - virtual int read() = 0; - virtual int read(uint8_t *buf, size_t size) = 0; - virtual int peek() = 0; - virtual void flush() = 0; - virtual void stop() = 0; - virtual uint8_t connected() = 0; - virtual operator bool() = 0; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/samd/Print.h b/lib/ArduinoStreamUtils/extras/test/cores/samd/Print.h deleted file mode 100644 index 7d2c8a0b..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/samd/Print.h +++ /dev/null @@ -1,46 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include -#include - -struct Print { - virtual size_t write(const uint8_t *buffer, size_t size) = 0; - virtual size_t write(uint8_t data) = 0; - virtual void flush() {} - - virtual int availableForWrite() { - return 0; - } - - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } - - size_t print(const String &s) { - return write(s.c_str(), s.length()); - } - - size_t print(const char *s) { - return write(s, std::strlen(s)); - } - - size_t println() { - return 0; - } - - template - size_t print(const T &value) { - return print(String(value)); - } - - template - size_t println(const T &value) { - return print(value); - } -}; \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/samd/Stream.h b/lib/ArduinoStreamUtils/extras/test/cores/samd/Stream.h deleted file mode 100644 index 458f9c3a..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/samd/Stream.h +++ /dev/null @@ -1,44 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Print.h" - -struct Stream : Print { - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - - size_t readBytes(char *buffer, size_t length) { - size_t count = 0; - while (count < length) { - int c = timedRead(); - if (c < 0) - break; - *buffer++ = (char)c; - count++; - } - return count; - } - - size_t readBytes(uint8_t *buffer, size_t length) { - return readBytes((char *)buffer, length); - } - - String readString() { - String result; - int c; - while ((c = timedRead()) >= 0) - result += c; - return result; - } - - void setTimeout(unsigned long) {} - - protected: - int timedRead() { - return read(); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/samd/WString.h b/lib/ArduinoStreamUtils/extras/test/cores/samd/WString.h deleted file mode 100644 index 9023e414..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/samd/WString.h +++ /dev/null @@ -1,5 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "../avr/WString.h" \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Arduino.h b/lib/ArduinoStreamUtils/extras/test/cores/stm32/Arduino.h deleted file mode 100644 index e94f54ff..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Arduino.h +++ /dev/null @@ -1,18 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include -#include -#include - -#include - -inline unsigned long millis() { - return static_cast(time(NULL)); -} - -inline void yield() {} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/cores/stm32/CMakeLists.txt deleted file mode 100644 index 092f6753..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -add_library(Stm32Core - Client.h - EEPROM.cpp - EEPROM.h - Print.h - Stream.h - WString.h -) - -target_include_directories(Stm32Core - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(Stm32Core - PUBLIC - ARDUINO_ARCH_STM32 -) diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Client.h b/lib/ArduinoStreamUtils/extras/test/cores/stm32/Client.h deleted file mode 100644 index 907948de..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Client.h +++ /dev/null @@ -1,28 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Stream.h" -#include "WString.h" - -using IPAddress = String; - -struct Client : Stream { - // Print - virtual size_t write(uint8_t) = 0; - virtual size_t write(const uint8_t *buf, size_t size) = 0; - - // Stream - virtual int available() = 0; - virtual int read() = 0; - virtual void flush() = 0; - - virtual int connect(IPAddress ip, uint16_t port) = 0; - virtual int connect(const char *host, uint16_t port) = 0; - virtual uint8_t connected() = 0; - virtual void stop() = 0; - virtual operator bool() = 0; - virtual int read(uint8_t *buf, size_t size) = 0; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.cpp b/lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.cpp deleted file mode 100644 index 83af6c18..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "EEPROM.h" - -EEPROMClass EEPROM; -static uint8_t data[512]; - -uint8_t EEPROMClass::read(int address) { - return data[address]; -} - -void EEPROMClass::write(int address, uint8_t value) { - data[address] = value; -} diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.h b/lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.h deleted file mode 100644 index 6da7e0c2..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -class EEPROMClass { - public: - uint8_t read(int); - void write(int, uint8_t); -}; - -extern EEPROMClass EEPROM; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Print.h b/lib/ArduinoStreamUtils/extras/test/cores/stm32/Print.h deleted file mode 100644 index e255ec63..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Print.h +++ /dev/null @@ -1,41 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include - -#include - -struct Print { - virtual size_t write(const uint8_t *buffer, size_t size) = 0; - virtual size_t write(uint8_t data) = 0; - - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } - - size_t print(const String &s) { - return write(s.c_str(), s.length()); - } - - size_t print(const char *s) { - return write(s, std::strlen(s)); - } - - size_t println() { - return 0; - } - - template - size_t print(const T &value) { - return print(String(value)); - } - - template - size_t println(const T &value) { - return print(value); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Stream.h b/lib/ArduinoStreamUtils/extras/test/cores/stm32/Stream.h deleted file mode 100644 index 441eb574..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/Stream.h +++ /dev/null @@ -1,42 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Print.h" - -struct Stream : Print { - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - virtual void flush() = 0; - - virtual size_t readBytes(char *buffer, size_t length) { - size_t count = 0; - while (count < length) { - int c = timedRead(); - if (c < 0) - break; - *buffer++ = (char)c; - count++; - } - return count; - } - - String readString() { - String result; - int c; - while ((c = timedRead()) >= 0) { - result += static_cast(c); - } - return result; - } - - void setTimeout(unsigned long) {} - - protected: - int timedRead() { - return read(); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/stm32/WString.h b/lib/ArduinoStreamUtils/extras/test/cores/stm32/WString.h deleted file mode 100644 index a4c911bd..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/stm32/WString.h +++ /dev/null @@ -1,43 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -class String : private std::string { - public: - String() {} - String(const String& s) : std::string(s) {} - String(String&& s) : std::string(std::move(s)) {} - String(const char* s) : std::string(s) {} - String(int n) : std::string(std::to_string(n)) {} - - String& operator=(const String& rhs) { - std::string::operator=(rhs); - return *this; - } - - using std::string::c_str; - using std::string::length; - using std::string::operator+=; - using std::string::operator[]; - - void remove(unsigned int index, unsigned int count) { - erase(begin() + index, begin() + index + count); - } - - void toCharArray(char* buf, unsigned int bufsize, - unsigned int index = 0) const { - copy(buf, bufsize, index); - } - - friend bool operator==(const String& lhs, const char* rhs) { - return static_cast(lhs) == rhs; - } - - friend std::ostream& operator<<(std::ostream& lhs, const String& rhs) { - return lhs << static_cast(rhs); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Arduino.h b/lib/ArduinoStreamUtils/extras/test/cores/teensy/Arduino.h deleted file mode 100644 index e94f54ff..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Arduino.h +++ /dev/null @@ -1,18 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include -#include -#include - -#include - -inline unsigned long millis() { - return static_cast(time(NULL)); -} - -inline void yield() {} \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/CMakeLists.txt b/lib/ArduinoStreamUtils/extras/test/cores/teensy/CMakeLists.txt deleted file mode 100644 index 2b8cb8be..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# StreamUtils - github.com/bblanchon/ArduinoStreamUtils -# Copyright Benoit Blanchon 2019-2021 -# MIT License - -add_library(TeensyCore - Client.h - EEPROM.cpp - EEPROM.h - Print.h - Stream.h - WString.h -) - -target_include_directories(TeensyCore - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(TeensyCore - PUBLIC - CORE_TEENSY -) diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Client.h b/lib/ArduinoStreamUtils/extras/test/cores/teensy/Client.h deleted file mode 100644 index 20dc08b6..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Client.h +++ /dev/null @@ -1,31 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Stream.h" -#include "WString.h" - -using IPAddress = String; - -struct Client : Stream { - virtual int connect(IPAddress ip, uint16_t port) = 0; - virtual int connect(const char *host, uint16_t port) = 0; - virtual uint8_t connected() = 0; - virtual void stop() = 0; - virtual operator bool() = 0; - - // Already in Print - virtual size_t write(uint8_t) = 0; - virtual size_t write(const uint8_t *buf, size_t size) = 0; - virtual void flush() = 0; - - // Already in Stream - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - - // Curiously not in Stream - virtual int read(uint8_t *buf, size_t size) = 0; -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.cpp b/lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.cpp deleted file mode 100644 index 2b2eb1a8..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "EEPROM.h" - -EEPROMClass EEPROM; -static uint8_t data[512]; - -uint8_t EEPROMClass::read(int address) { - return data[address]; -} - -void EEPROMClass::update(int address, uint8_t value) { - data[address] = value; -} diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.h b/lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.h deleted file mode 100644 index b5e3360c..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -class EEPROMClass { - public: - uint8_t read(int); - void update(int, uint8_t); - // void write(int, uint8_t); <- it exists but we want to use update() instead -}; - -extern EEPROMClass EEPROM; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Print.h b/lib/ArduinoStreamUtils/extras/test/cores/teensy/Print.h deleted file mode 100644 index 7d2c8a0b..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Print.h +++ /dev/null @@ -1,46 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include -#include - -struct Print { - virtual size_t write(const uint8_t *buffer, size_t size) = 0; - virtual size_t write(uint8_t data) = 0; - virtual void flush() {} - - virtual int availableForWrite() { - return 0; - } - - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } - - size_t print(const String &s) { - return write(s.c_str(), s.length()); - } - - size_t print(const char *s) { - return write(s, std::strlen(s)); - } - - size_t println() { - return 0; - } - - template - size_t print(const T &value) { - return print(String(value)); - } - - template - size_t println(const T &value) { - return print(value); - } -}; \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Stream.h b/lib/ArduinoStreamUtils/extras/test/cores/teensy/Stream.h deleted file mode 100644 index 6515a1e3..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/Stream.h +++ /dev/null @@ -1,42 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "Print.h" - -struct Stream : Print { - virtual int available() = 0; - virtual int read() = 0; - virtual int peek() = 0; - virtual void flush() = 0; - - size_t readBytes(char *buffer, size_t length) { - size_t count = 0; - while (count < length) { - int c = timedRead(); - if (c < 0) - break; - *buffer++ = (char)c; - count++; - } - return count; - } - - String readString() { - String result; - int c; - while ((c = timedRead()) >= 0) { - result += static_cast(c); - } - return result; - } - - void setTimeout(unsigned long) {} - - private: - int timedRead() { - return read(); - } -}; diff --git a/lib/ArduinoStreamUtils/extras/test/cores/teensy/WString.h b/lib/ArduinoStreamUtils/extras/test/cores/teensy/WString.h deleted file mode 100644 index f0b99e22..00000000 --- a/lib/ArduinoStreamUtils/extras/test/cores/teensy/WString.h +++ /dev/null @@ -1,7 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../avr/WString.h" \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/extras/test/doctest.h b/lib/ArduinoStreamUtils/extras/test/doctest.h deleted file mode 100644 index 9f004da5..00000000 --- a/lib/ArduinoStreamUtils/extras/test/doctest.h +++ /dev/null @@ -1,6000 +0,0 @@ -// ====================================================================== lgtm [cpp/missing-header-guard] -// == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! == -// ====================================================================== -// -// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD -// -// Copyright (c) 2016-2019 Viktor Kirilov -// -// Distributed under the MIT Software License -// See accompanying file LICENSE.txt or copy at -// https://opensource.org/licenses/MIT -// -// The documentation can be found at the library's page: -// https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= -// -// The library is heavily influenced by Catch - https://github.com/catchorg/Catch2 -// which uses the Boost Software License - Version 1.0 -// see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt -// -// The concept of subcases (sections in Catch) and expression decomposition are from there. -// Some parts of the code are taken directly: -// - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<> -// - the Approx() helper class for floating point comparison -// - colors in the console -// - breaking into a debugger -// - signal / SEH handling -// - timer -// - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste) -// -// The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest -// which uses the Boost Software License - Version 1.0 -// see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= - -#ifndef DOCTEST_LIBRARY_INCLUDED -#define DOCTEST_LIBRARY_INCLUDED - -// ================================================================================================= -// == VERSION ====================================================================================== -// ================================================================================================= - -#define DOCTEST_VERSION_MAJOR 2 -#define DOCTEST_VERSION_MINOR 3 -#define DOCTEST_VERSION_PATCH 1 -#define DOCTEST_VERSION_STR "2.3.1" - -#define DOCTEST_VERSION \ - (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) - -// ================================================================================================= -// == COMPILER VERSION ============================================================================= -// ================================================================================================= - -// ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect - -#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH)) - -// GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl... -#if defined(_MSC_VER) && defined(_MSC_FULL_VER) -#if _MSC_VER == _MSC_FULL_VER / 10000 -#define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000) -#else // MSVC -#define DOCTEST_MSVC \ - DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000) -#endif // MSVC -#endif // MSVC -#if defined(__clang__) && defined(__clang_minor__) -#define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__) -#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \ - !defined(__INTEL_COMPILER) -#define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#endif // GCC - -#ifndef DOCTEST_MSVC -#define DOCTEST_MSVC 0 -#endif // DOCTEST_MSVC -#ifndef DOCTEST_CLANG -#define DOCTEST_CLANG 0 -#endif // DOCTEST_CLANG -#ifndef DOCTEST_GCC -#define DOCTEST_GCC 0 -#endif // DOCTEST_GCC - -// ================================================================================================= -// == COMPILER WARNINGS HELPERS ==================================================================== -// ================================================================================================= - -#if DOCTEST_CLANG -#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) -#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push") -#define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w) -#define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop") -#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w) -#else // DOCTEST_CLANG -#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -#define DOCTEST_CLANG_SUPPRESS_WARNING(w) -#define DOCTEST_CLANG_SUPPRESS_WARNING_POP -#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_CLANG - -#if DOCTEST_GCC -#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) -#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push") -#define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w) -#define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop") -#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w) -#else // DOCTEST_GCC -#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH -#define DOCTEST_GCC_SUPPRESS_WARNING(w) -#define DOCTEST_GCC_SUPPRESS_WARNING_POP -#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_GCC - -#if DOCTEST_MSVC -#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push)) -#define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w)) -#define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop)) -#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w) -#else // DOCTEST_MSVC -#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -#define DOCTEST_MSVC_SUPPRESS_WARNING(w) -#define DOCTEST_MSVC_SUPPRESS_WARNING_POP -#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_MSVC - -// ================================================================================================= -// == COMPILER WARNINGS ============================================================================ -// ================================================================================================= - -DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-local-typedef") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") - -DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") -DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") -DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor") -DOCTEST_GCC_SUPPRESS_WARNING("-Winline") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs") -DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") - -DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -DOCTEST_MSVC_SUPPRESS_WARNING(4616) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4619) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4996) // The compiler encountered a deprecated declaration -DOCTEST_MSVC_SUPPRESS_WARNING(4706) // assignment within conditional expression -DOCTEST_MSVC_SUPPRESS_WARNING(4512) // 'class' : assignment operator could not be generated -DOCTEST_MSVC_SUPPRESS_WARNING(4127) // conditional expression is constant -DOCTEST_MSVC_SUPPRESS_WARNING(4820) // padding -DOCTEST_MSVC_SUPPRESS_WARNING(4625) // copy constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4640) // construction of local static object is not thread-safe -// static analysis -DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Declare it 'noexcept' -DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable -DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ... -DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtr... - -// 4548 - expression before comma has no effect; expected expression with side - effect -// 4265 - class has virtual functions, but destructor is not virtual -// 4986 - exception specification does not match previous declaration -// 4350 - behavior change: 'member1' called instead of 'member2' -// 4668 - 'x' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' -// 4365 - conversion from 'int' to 'unsigned long', signed/unsigned mismatch -// 4774 - format string expected in argument 'x' is not a string literal -// 4820 - padding in structs - -// only 4 should be disabled globally: -// - 4514 # unreferenced inline function has been removed -// - 4571 # SEH related -// - 4710 # function not inlined -// - 4711 # function 'x' selected for automatic inline expansion - -#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \ - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \ - DOCTEST_MSVC_SUPPRESS_WARNING(4548) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4265) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4986) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4350) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4668) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4365) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4774) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4820) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4625) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4626) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5027) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5026) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4623) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5039) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5045) - -#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP - -// ================================================================================================= -// == FEATURE DETECTION ============================================================================ -// ================================================================================================= - -// general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support -// MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx -// GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html -// MSVC version table: -// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering -// MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019) << NOT YET RELEASED - April 2 2019 -// MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017) -// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) -// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) -// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012) -// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010) -// MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008) -// MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005) - -#if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH) -#define DOCTEST_CONFIG_WINDOWS_SEH -#endif // MSVC -#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH) -#undef DOCTEST_CONFIG_WINDOWS_SEH -#endif // DOCTEST_CONFIG_NO_WINDOWS_SEH - -#if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \ - !defined(__EMSCRIPTEN__) -#define DOCTEST_CONFIG_POSIX_SIGNALS -#endif // _WIN32 -#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS) -#undef DOCTEST_CONFIG_POSIX_SIGNALS -#endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // no exceptions -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS) -#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT) -#define DOCTEST_CONFIG_IMPLEMENT -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -#if defined(_WIN32) || defined(__CYGWIN__) -#if DOCTEST_MSVC -#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport) -#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport) -#else // MSVC -#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport)) -#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport)) -#endif // MSVC -#else // _WIN32 -#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default"))) -#define DOCTEST_SYMBOL_IMPORT -#endif // _WIN32 - -#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#ifdef DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT -#else // DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT -#endif // DOCTEST_CONFIG_IMPLEMENT -#else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#define DOCTEST_INTERFACE -#endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL - -#define DOCTEST_EMPTY - -#if DOCTEST_MSVC -#define DOCTEST_NOINLINE __declspec(noinline) -#define DOCTEST_UNUSED -#define DOCTEST_ALIGNMENT(x) -#else // MSVC -#define DOCTEST_NOINLINE __attribute__((noinline)) -#define DOCTEST_UNUSED __attribute__((unused)) -#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x))) -#endif // MSVC - -#ifndef DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK -#define DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK 5 -#endif // DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK - -// ================================================================================================= -// == FEATURE DETECTION END ======================================================================== -// ================================================================================================= - -// internal macros for string concatenation and anonymous variable name generation -#define DOCTEST_CAT_IMPL(s1, s2) s1##s2 -#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2) -#ifdef __COUNTER__ // not standard and may be missing for some compilers -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__) -#else // __COUNTER__ -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__) -#endif // __COUNTER__ - -#define DOCTEST_TOSTR(x) #x - -#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x& -#else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x -#endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE - -// not using __APPLE__ because... this is how Catch does it -#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED -#define DOCTEST_PLATFORM_MAC -#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -#define DOCTEST_PLATFORM_IPHONE -#elif defined(_WIN32) -#define DOCTEST_PLATFORM_WINDOWS -#else // DOCTEST_PLATFORM -#define DOCTEST_PLATFORM_LINUX -#endif // DOCTEST_PLATFORM - -// clang-format off -#define DOCTEST_DELETE_COPIES(type) type(const type&) = delete; type& operator=(const type&) = delete -#define DOCTEST_DECLARE_COPIES(type) type(const type&); type& operator=(const type&) -#define DOCTEST_DEFINE_COPIES(type) type::type(const type&) = default; type& type::operator=(const type&) = default -#define DOCTEST_DECLARE_DEFAULTS(type) type(); ~type() -#define DOCTEST_DEFINE_DEFAULTS(type) type::type() = default; type::~type() = default -// clang-format on - -#define DOCTEST_GLOBAL_NO_WARNINGS(var) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \ - static int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) -#define DOCTEST_GLOBAL_NO_WARNINGS_END() DOCTEST_CLANG_SUPPRESS_WARNING_POP - -// should probably take a look at https://github.com/scottt/debugbreak -#ifdef DOCTEST_PLATFORM_MAC -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) -#elif DOCTEST_MSVC -#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() -#elif defined(__MINGW32__) -extern "C" __declspec(dllimport) void __stdcall DebugBreak(); -#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak() -#else // linux -#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0) -#endif // linux - -// this is kept here for backwards compatibility since the config option was changed -#ifdef DOCTEST_CONFIG_USE_IOSFWD -#define DOCTEST_CONFIG_USE_STD_HEADERS -#endif // DOCTEST_CONFIG_USE_IOSFWD - -#ifdef DOCTEST_CONFIG_USE_STD_HEADERS -#include -#include -#else // DOCTEST_CONFIG_USE_STD_HEADERS - -#if DOCTEST_CLANG -// to detect if libc++ is being used with clang (the _LIBCPP_VERSION identifier) -#include -#endif // clang - -#ifdef _LIBCPP_VERSION -#define DOCTEST_STD_NAMESPACE_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD -#define DOCTEST_STD_NAMESPACE_END _LIBCPP_END_NAMESPACE_STD -#else // _LIBCPP_VERSION -#define DOCTEST_STD_NAMESPACE_BEGIN namespace std { -#define DOCTEST_STD_NAMESPACE_END } -#endif // _LIBCPP_VERSION - -// Forward declaring 'X' in namespace std is not permitted by the C++ Standard. -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643) - -DOCTEST_STD_NAMESPACE_BEGIN -typedef decltype(nullptr) nullptr_t; -template -struct char_traits; -template <> -struct char_traits; -template -class basic_ostream; -typedef basic_ostream> ostream; -template -class tuple; -DOCTEST_STD_NAMESPACE_END - -DOCTEST_MSVC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_USE_STD_HEADERS - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#include -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - -namespace doctest { - -DOCTEST_INTERFACE extern bool is_running_in_test; - -// A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length -// of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for: -// - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128) -// - if small - capacity left before going on the heap - using the lowest 5 bits -// - if small - 2 bits are left unused - the second and third highest ones -// - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator) -// and the "is small" bit remains "0" ("as well as the capacity left") so its OK -// Idea taken from this lecture about the string implementation of facebook/folly - fbstring -// https://www.youtube.com/watch?v=kPR8h4-qZdk -// TODO: -// - optimizations - like not deleting memory unnecessarily in operator= and etc. -// - resize/reserve/clear -// - substr -// - replace -// - back/front -// - iterator stuff -// - find & friends -// - push_back/pop_back -// - assign/insert/erase -// - relational operators as free functions - taking const char* as one of the params -class DOCTEST_INTERFACE String -{ - static const unsigned len = 24; //!OCLINT avoid private static members - static const unsigned last = len - 1; //!OCLINT avoid private static members - - struct view // len should be more than sizeof(view) - because of the final byte for flags - { - char* ptr; - unsigned size; - unsigned capacity; - }; - - union - { - char buf[len]; - view data; - }; - - bool isOnStack() const { return (buf[last] & 128) == 0; } - void setOnHeap(); - void setLast(unsigned in = last); - - void copy(const String& other); - -public: - String(); - ~String(); - - // cppcheck-suppress noExplicitConstructor - String(const char* in); - String(const char* in, unsigned in_size); - - String(const String& other); - String& operator=(const String& other); - - String& operator+=(const String& other); - String operator+(const String& other) const; - - String(String&& other); - String& operator=(String&& other); - - char operator[](unsigned i) const; - char& operator[](unsigned i); - - // the only functions I'm willing to leave in the interface - available for inlining - const char* c_str() const { return const_cast(this)->c_str(); } // NOLINT - char* c_str() { - if(isOnStack()) - return reinterpret_cast(buf); - return data.ptr; - } - - unsigned size() const; - unsigned capacity() const; - - int compare(const char* other, bool no_case = false) const; - int compare(const String& other, bool no_case = false) const; -}; - -DOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs); - -DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, const String& in); - -namespace Color { - enum Enum - { - None = 0, - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White - }; - - DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, Color::Enum code); -} // namespace Color - -namespace assertType { - enum Enum - { - // macro traits - - is_warn = 1, - is_check = 2 * is_warn, - is_require = 2 * is_check, - - is_normal = 2 * is_require, - is_throws = 2 * is_normal, - is_throws_as = 2 * is_throws, - is_throws_with = 2 * is_throws_as, - is_nothrow = 2 * is_throws_with, - - is_false = 2 * is_nothrow, - is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types - - is_eq = 2 * is_unary, - is_ne = 2 * is_eq, - - is_lt = 2 * is_ne, - is_gt = 2 * is_lt, - - is_ge = 2 * is_gt, - is_le = 2 * is_ge, - - // macro types - - DT_WARN = is_normal | is_warn, - DT_CHECK = is_normal | is_check, - DT_REQUIRE = is_normal | is_require, - - DT_WARN_FALSE = is_normal | is_false | is_warn, - DT_CHECK_FALSE = is_normal | is_false | is_check, - DT_REQUIRE_FALSE = is_normal | is_false | is_require, - - DT_WARN_THROWS = is_throws | is_warn, - DT_CHECK_THROWS = is_throws | is_check, - DT_REQUIRE_THROWS = is_throws | is_require, - - DT_WARN_THROWS_AS = is_throws_as | is_warn, - DT_CHECK_THROWS_AS = is_throws_as | is_check, - DT_REQUIRE_THROWS_AS = is_throws_as | is_require, - - DT_WARN_THROWS_WITH = is_throws_with | is_warn, - DT_CHECK_THROWS_WITH = is_throws_with | is_check, - DT_REQUIRE_THROWS_WITH = is_throws_with | is_require, - - DT_WARN_NOTHROW = is_nothrow | is_warn, - DT_CHECK_NOTHROW = is_nothrow | is_check, - DT_REQUIRE_NOTHROW = is_nothrow | is_require, - - DT_WARN_EQ = is_normal | is_eq | is_warn, - DT_CHECK_EQ = is_normal | is_eq | is_check, - DT_REQUIRE_EQ = is_normal | is_eq | is_require, - - DT_WARN_NE = is_normal | is_ne | is_warn, - DT_CHECK_NE = is_normal | is_ne | is_check, - DT_REQUIRE_NE = is_normal | is_ne | is_require, - - DT_WARN_GT = is_normal | is_gt | is_warn, - DT_CHECK_GT = is_normal | is_gt | is_check, - DT_REQUIRE_GT = is_normal | is_gt | is_require, - - DT_WARN_LT = is_normal | is_lt | is_warn, - DT_CHECK_LT = is_normal | is_lt | is_check, - DT_REQUIRE_LT = is_normal | is_lt | is_require, - - DT_WARN_GE = is_normal | is_ge | is_warn, - DT_CHECK_GE = is_normal | is_ge | is_check, - DT_REQUIRE_GE = is_normal | is_ge | is_require, - - DT_WARN_LE = is_normal | is_le | is_warn, - DT_CHECK_LE = is_normal | is_le | is_check, - DT_REQUIRE_LE = is_normal | is_le | is_require, - - DT_WARN_UNARY = is_normal | is_unary | is_warn, - DT_CHECK_UNARY = is_normal | is_unary | is_check, - DT_REQUIRE_UNARY = is_normal | is_unary | is_require, - - DT_WARN_UNARY_FALSE = is_normal | is_false | is_unary | is_warn, - DT_CHECK_UNARY_FALSE = is_normal | is_false | is_unary | is_check, - DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require, - }; -} // namespace assertType - -DOCTEST_INTERFACE const char* assertString(assertType::Enum at); -DOCTEST_INTERFACE const char* failureString(assertType::Enum at); -DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file); - -struct DOCTEST_INTERFACE TestCaseData -{ - const char* m_file; // the file in which the test was registered - unsigned m_line; // the line where the test was registered - const char* m_name; // name of the test case - const char* m_test_suite; // the test suite in which the test was added - const char* m_description; - bool m_skip; - bool m_may_fail; - bool m_should_fail; - int m_expected_failures; - double m_timeout; - - DOCTEST_DECLARE_DEFAULTS(TestCaseData); - DOCTEST_DECLARE_COPIES(TestCaseData); -}; - -struct DOCTEST_INTERFACE AssertData -{ - // common - for all asserts - const TestCaseData* m_test_case; - assertType::Enum m_at; - const char* m_file; - int m_line; - const char* m_expr; - bool m_failed; - - // exception-related - for all asserts - bool m_threw; - String m_exception; - - // for normal asserts - String m_decomp; - - // for specific exception-related asserts - bool m_threw_as; - const char* m_exception_type; - - DOCTEST_DECLARE_DEFAULTS(AssertData); - DOCTEST_DELETE_COPIES(AssertData); -}; - -struct DOCTEST_INTERFACE MessageData -{ - String m_string; - const char* m_file; - int m_line; - assertType::Enum m_severity; - - DOCTEST_DECLARE_DEFAULTS(MessageData); - DOCTEST_DELETE_COPIES(MessageData); -}; - -struct DOCTEST_INTERFACE SubcaseSignature -{ - const char* m_name; - const char* m_file; - int m_line; - - SubcaseSignature(const char* name, const char* file, int line); - - bool operator<(const SubcaseSignature& other) const; - - DOCTEST_DECLARE_DEFAULTS(SubcaseSignature); - DOCTEST_DECLARE_COPIES(SubcaseSignature); -}; - -struct DOCTEST_INTERFACE IContextScope -{ - DOCTEST_DELETE_COPIES(IContextScope); - - IContextScope(); - virtual ~IContextScope(); - virtual void stringify(std::ostream*) const = 0; -}; - -struct ContextOptions //!OCLINT too many fields -{ - std::ostream* cout; // stdout stream - std::cout by default - std::ostream* cerr; // stderr stream - std::cerr by default - String binary_name; // the test binary name - - // == parameters from the command line - String out; // output filename - String order_by; // how tests should be ordered - unsigned rand_seed; // the seed for rand ordering - - unsigned first; // the first (matching) test to be executed - unsigned last; // the last (matching) test to be executed - - int abort_after; // stop tests after this many failed assertions - int subcase_filter_levels; // apply the subcase filters for the first N levels - - bool success; // include successful assertions in output - bool case_sensitive; // if filtering should be case sensitive - bool exit; // if the program should be exited after the tests are ran/whatever - bool duration; // print the time duration of each test case - bool no_throw; // to skip exceptions-related assertion macros - bool no_exitcode; // if the framework should return 0 as the exitcode - bool no_run; // to not run the tests at all (can be done with an "*" exclude) - bool no_version; // to not print the version of the framework - bool no_colors; // if output to the console should be colorized - bool force_colors; // forces the use of colors even when a tty cannot be detected - bool no_breaks; // to not break into the debugger - bool no_skip; // don't skip test cases which are marked to be skipped - bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x): - bool no_path_in_filenames; // if the path to files should be removed from the output - bool no_line_numbers; // if source code line numbers should be omitted from the output - bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!! - - bool help; // to print the help - bool version; // to print the version - bool count; // if only the count of matching tests is to be retreived - bool list_test_cases; // to list all tests matching the filters - bool list_test_suites; // to list all suites matching the filters - bool list_reporters; // lists all registered reporters - - DOCTEST_DECLARE_DEFAULTS(ContextOptions); - DOCTEST_DELETE_COPIES(ContextOptions); -}; - -namespace detail { -#if defined(DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || defined(DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS) - template - struct enable_if - {}; - - template - struct enable_if - { typedef TYPE type; }; -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - // clang-format off - template struct remove_reference { typedef T type; }; - template struct remove_reference { typedef T type; }; - template struct remove_reference { typedef T type; }; - - template struct remove_const { typedef T type; }; - template struct remove_const { typedef T type; }; - // clang-format on - - template - struct deferred_false - // cppcheck-suppress unusedStructMember - { static const bool value = false; }; - - namespace has_insertion_operator_impl { - typedef char no; - typedef char yes[2]; - - struct any_t - { - template - // cppcheck-suppress noExplicitConstructor - any_t(const DOCTEST_REF_WRAP(T)); - }; - - yes& testStreamable(std::ostream&); - no testStreamable(no); - - no operator<<(const std::ostream&, const any_t&); - - template - struct has_insertion_operator - { - static std::ostream& s; - static const DOCTEST_REF_WRAP(T) t; - static const bool value = sizeof(decltype(testStreamable(s << t))) == sizeof(yes); - }; - } // namespace has_insertion_operator_impl - - template - struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator - {}; - - DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num); - - DOCTEST_INTERFACE std::ostream* getTlsOss(); // returns a thread-local ostringstream - DOCTEST_INTERFACE String getTlsOssResult(); - - template - struct StringMakerBase - { - template - static String convert(const DOCTEST_REF_WRAP(T)) { - return "{?}"; - } - }; - - template <> - struct StringMakerBase - { - template - static String convert(const DOCTEST_REF_WRAP(T) in) { - *getTlsOss() << in; - return getTlsOssResult(); - } - }; - - DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size); - - template - String rawMemoryToString(const DOCTEST_REF_WRAP(T) object) { - return rawMemoryToString(&object, sizeof(object)); - } - - template - const char* type_to_string() { - return "<>"; - } -} // namespace detail - -template -struct StringMaker : public detail::StringMakerBase::value> -{}; - -template -struct StringMaker -{ - template - static String convert(U* p) { - if(p) - return detail::rawMemoryToString(p); - return "NULL"; - } -}; - -template -struct StringMaker -{ - static String convert(R C::*p) { - if(p) - return detail::rawMemoryToString(p); - return "NULL"; - } -}; - -template -String toString(const DOCTEST_REF_WRAP(T) value) { - return StringMaker::convert(value); -} - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -DOCTEST_INTERFACE String toString(char* in); -DOCTEST_INTERFACE String toString(const char* in); -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -DOCTEST_INTERFACE String toString(bool in); -DOCTEST_INTERFACE String toString(float in); -DOCTEST_INTERFACE String toString(double in); -DOCTEST_INTERFACE String toString(double long in); - -DOCTEST_INTERFACE String toString(char in); -DOCTEST_INTERFACE String toString(char signed in); -DOCTEST_INTERFACE String toString(char unsigned in); -DOCTEST_INTERFACE String toString(int short in); -DOCTEST_INTERFACE String toString(int short unsigned in); -DOCTEST_INTERFACE String toString(int in); -DOCTEST_INTERFACE String toString(int unsigned in); -DOCTEST_INTERFACE String toString(int long in); -DOCTEST_INTERFACE String toString(int long unsigned in); -DOCTEST_INTERFACE String toString(int long long in); -DOCTEST_INTERFACE String toString(int long long unsigned in); -DOCTEST_INTERFACE String toString(std::nullptr_t in); - -class DOCTEST_INTERFACE Approx -{ -public: - explicit Approx(double value); - - DOCTEST_DECLARE_COPIES(Approx); - - Approx operator()(double value) const; - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - explicit Approx(const T& value, - typename detail::enable_if::value>::type* = - static_cast(nullptr)) { - *this = Approx(static_cast(value)); - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - Approx& epsilon(double newEpsilon); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - typename detail::enable_if::value, Approx&>::type epsilon( - const T& newEpsilon) { - m_epsilon = static_cast(newEpsilon); - return *this; - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - Approx& scale(double newScale); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - typename detail::enable_if::value, Approx&>::type scale( - const T& newScale) { - m_scale = static_cast(newScale); - return *this; - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - // clang-format off - DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs); - - DOCTEST_INTERFACE friend String toString(const Approx& in); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#define DOCTEST_APPROX_PREFIX \ - template friend typename detail::enable_if::value, bool>::type - - DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); } - DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); } - DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; } -#undef DOCTEST_APPROX_PREFIX -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - // clang-format on - -private: - double m_epsilon; - double m_scale; - double m_value; -}; - -DOCTEST_INTERFACE String toString(const Approx& in); - -DOCTEST_INTERFACE const ContextOptions* getContextOptions(); - -#if !defined(DOCTEST_CONFIG_DISABLE) - -namespace detail { - // clang-format off -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - template struct decay_array { typedef T type; }; - template struct decay_array { typedef T* type; }; - template struct decay_array { typedef T* type; }; - - template struct not_char_pointer { enum { value = 1 }; }; - template<> struct not_char_pointer { enum { value = 0 }; }; - template<> struct not_char_pointer { enum { value = 0 }; }; - - template struct can_use_op : public not_char_pointer::type> {}; -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - // clang-format on - - struct DOCTEST_INTERFACE TestFailureException - { - DOCTEST_DECLARE_DEFAULTS(TestFailureException); - DOCTEST_DECLARE_COPIES(TestFailureException); - }; - - DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at); - DOCTEST_INTERFACE void throwException(); - - struct DOCTEST_INTERFACE Subcase - { - SubcaseSignature m_signature; - bool m_entered = false; - - Subcase(const char* name, const char* file, int line); - ~Subcase(); - - DOCTEST_DELETE_COPIES(Subcase); - - operator bool() const; - }; - - template - String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op, - const DOCTEST_REF_WRAP(R) rhs) { - return toString(lhs) + op + toString(rhs); - } - -#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \ - template \ - DOCTEST_NOINLINE Result operator op(const DOCTEST_REF_WRAP(R) rhs) { \ - bool res = op_macro(lhs, rhs); \ - if(m_at & assertType::is_false) \ - res = !res; \ - if(!res || doctest::getContextOptions()->success) \ - return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \ - return Result(res); \ - } - - // more checks could be added - like in Catch: - // https://github.com/catchorg/Catch2/pull/1480/files - // https://github.com/catchorg/Catch2/pull/1481/files -#define DOCTEST_FORBIT_EXPRESSION(rt, op) \ - template \ - rt& operator op(const R&) { \ - static_assert(deferred_false::value, \ - "Expression Too Complex Please Rewrite As Binary Comparison!"); \ - return *this; \ - } - - struct DOCTEST_INTERFACE Result - { - bool m_passed; - String m_decomp; - - Result(bool passed, const String& decomposition = String()); - - DOCTEST_DECLARE_DEFAULTS(Result); - DOCTEST_DECLARE_COPIES(Result); - - // forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence - DOCTEST_FORBIT_EXPRESSION(Result, &) - DOCTEST_FORBIT_EXPRESSION(Result, ^) - DOCTEST_FORBIT_EXPRESSION(Result, |) - DOCTEST_FORBIT_EXPRESSION(Result, &&) - DOCTEST_FORBIT_EXPRESSION(Result, ||) - DOCTEST_FORBIT_EXPRESSION(Result, ==) - DOCTEST_FORBIT_EXPRESSION(Result, !=) - DOCTEST_FORBIT_EXPRESSION(Result, <) - DOCTEST_FORBIT_EXPRESSION(Result, >) - DOCTEST_FORBIT_EXPRESSION(Result, <=) - DOCTEST_FORBIT_EXPRESSION(Result, >=) - DOCTEST_FORBIT_EXPRESSION(Result, =) - DOCTEST_FORBIT_EXPRESSION(Result, +=) - DOCTEST_FORBIT_EXPRESSION(Result, -=) - DOCTEST_FORBIT_EXPRESSION(Result, *=) - DOCTEST_FORBIT_EXPRESSION(Result, /=) - DOCTEST_FORBIT_EXPRESSION(Result, %=) - DOCTEST_FORBIT_EXPRESSION(Result, <<=) - DOCTEST_FORBIT_EXPRESSION(Result, >>=) - DOCTEST_FORBIT_EXPRESSION(Result, &=) - DOCTEST_FORBIT_EXPRESSION(Result, ^=) - DOCTEST_FORBIT_EXPRESSION(Result, |=) - }; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - DOCTEST_CLANG_SUPPRESS_WARNING_PUSH - DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") - DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare") - //DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion") - //DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion") - //DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal") - - DOCTEST_GCC_SUPPRESS_WARNING_PUSH - DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") - DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare") - //DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion") - //DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") - //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal") - - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH - // http://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389 - DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch - DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch - DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch - //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - // clang-format off -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE bool -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if::value || can_use_op::value, bool>::type - inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } - inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } - inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } - inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); } - inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); } - inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - // clang-format on - -#define DOCTEST_RELATIONAL_OP(name, op) \ - template \ - DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \ - const DOCTEST_REF_WRAP(R) rhs) { \ - return lhs op rhs; \ - } - - DOCTEST_RELATIONAL_OP(eq, ==) - DOCTEST_RELATIONAL_OP(ne, !=) - DOCTEST_RELATIONAL_OP(lt, <) - DOCTEST_RELATIONAL_OP(gt, >) - DOCTEST_RELATIONAL_OP(le, <=) - DOCTEST_RELATIONAL_OP(ge, >=) - -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) l == r -#define DOCTEST_CMP_NE(l, r) l != r -#define DOCTEST_CMP_GT(l, r) l > r -#define DOCTEST_CMP_LT(l, r) l < r -#define DOCTEST_CMP_GE(l, r) l >= r -#define DOCTEST_CMP_LE(l, r) l <= r -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) eq(l, r) -#define DOCTEST_CMP_NE(l, r) ne(l, r) -#define DOCTEST_CMP_GT(l, r) gt(l, r) -#define DOCTEST_CMP_LT(l, r) lt(l, r) -#define DOCTEST_CMP_GE(l, r) ge(l, r) -#define DOCTEST_CMP_LE(l, r) le(l, r) -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - - template - // cppcheck-suppress copyCtorAndEqOperator - struct Expression_lhs - { - L lhs; - assertType::Enum m_at; - - explicit Expression_lhs(L in, assertType::Enum at) - : lhs(in) - , m_at(at) {} - - DOCTEST_NOINLINE operator Result() { - bool res = !!lhs; - if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional - res = !res; - - if(!res || getContextOptions()->success) - return Result(res, toString(lhs)); - return Result(res); - } - - // clang-format off - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>, " > ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<, " < ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional - // clang-format on - - // forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=) - // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the - // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression... - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>) - }; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - DOCTEST_CLANG_SUPPRESS_WARNING_POP - DOCTEST_MSVC_SUPPRESS_WARNING_POP - DOCTEST_GCC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - struct DOCTEST_INTERFACE ExpressionDecomposer - { - assertType::Enum m_at; - - ExpressionDecomposer(assertType::Enum at); - - DOCTEST_DECLARE_DEFAULTS(ExpressionDecomposer); - DOCTEST_DELETE_COPIES(ExpressionDecomposer); - - // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table) - // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now... - // https://github.com/catchorg/Catch2/issues/870 - // https://github.com/catchorg/Catch2/issues/565 - template - Expression_lhs operator<<(const DOCTEST_REF_WRAP(L) operand) { - return Expression_lhs(operand, m_at); - } - }; - - struct DOCTEST_INTERFACE TestSuite - { - const char* m_test_suite; - const char* m_description; - bool m_skip; - bool m_may_fail; - bool m_should_fail; - int m_expected_failures; - double m_timeout; - - DOCTEST_DECLARE_DEFAULTS(TestSuite); - DOCTEST_DECLARE_COPIES(TestSuite); - - TestSuite& operator*(const char* in); - - template - TestSuite& operator*(const T& in) { - in.fill(*this); - return *this; - } - }; - - typedef void (*funcType)(); - - struct DOCTEST_INTERFACE TestCase : public TestCaseData - { - funcType m_test; // a function pointer to the test case - - const char* m_type; // for templated test cases - gets appended to the real name - int m_template_id; // an ID used to distinguish between the different versions of a templated test case - String m_full_name; // contains the name (only for templated test cases!) + the template type - - TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, - const char* type = "", int template_id = -1); - - DOCTEST_DECLARE_DEFAULTS(TestCase); - - TestCase(const TestCase& other); - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function - TestCase& operator=(const TestCase& other); - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - TestCase& operator*(const char* in); - - template - TestCase& operator*(const T& in) { - in.fill(*this); - return *this; - } - - bool operator<(const TestCase& other) const; - }; - - // forward declarations of functions used by the macros - DOCTEST_INTERFACE int regTest(const TestCase& tc); - DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts); - DOCTEST_INTERFACE bool isDebuggerActive(); - - namespace binaryAssertComparison { - enum Enum - { - eq = 0, - ne, - gt, - lt, - ge, - le - }; - } // namespace binaryAssertComparison - - // clang-format off - template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } }; - -#define DOCTEST_BINARY_RELATIONAL_OP(n, op) \ - template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } }; - // clang-format on - - DOCTEST_BINARY_RELATIONAL_OP(0, eq) - DOCTEST_BINARY_RELATIONAL_OP(1, ne) - DOCTEST_BINARY_RELATIONAL_OP(2, gt) - DOCTEST_BINARY_RELATIONAL_OP(3, lt) - DOCTEST_BINARY_RELATIONAL_OP(4, ge) - DOCTEST_BINARY_RELATIONAL_OP(5, le) - - struct DOCTEST_INTERFACE ResultBuilder : public AssertData - { - ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, - const char* exception_type = ""); - - DOCTEST_DECLARE_DEFAULTS(ResultBuilder); - DOCTEST_DELETE_COPIES(ResultBuilder); - - void setResult(const Result& res); - - template - DOCTEST_NOINLINE void binary_assert(const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) { - m_failed = !RelationalComparator()(lhs, rhs); - if(m_failed || getContextOptions()->success) - m_decomp = stringifyBinaryExpr(lhs, ", ", rhs); - } - - template - DOCTEST_NOINLINE void unary_assert(const DOCTEST_REF_WRAP(L) val) { - m_failed = !val; - - if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional - m_failed = !m_failed; - - if(m_failed || getContextOptions()->success) - m_decomp = toString(val); - } - - void translateException(); - - bool log(); - void react() const; - }; - - namespace assertAction { - enum Enum - { - nothing = 0, - dbgbreak = 1, - shouldthrow = 2 - }; - } // namespace assertAction - - DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData& ad); - - DOCTEST_INTERFACE void decomp_assert(assertType::Enum at, const char* file, int line, - const char* expr, Result result); - -#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \ - do { \ - if(!is_running_in_test) { \ - if(failed) { \ - ResultBuilder rb(at, file, line, expr); \ - rb.m_failed = failed; \ - rb.m_decomp = decomp; \ - failed_out_of_a_testing_context(rb); \ - if(isDebuggerActive() && !getContextOptions()->no_breaks) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - if(checkIfShouldThrow(at)) \ - throwException(); \ - } \ - return; \ - } \ - } while(false) - -#define DOCTEST_ASSERT_IN_TESTS(decomp) \ - ResultBuilder rb(at, file, line, expr); \ - rb.m_failed = failed; \ - if(rb.m_failed || getContextOptions()->success) \ - rb.m_decomp = decomp; \ - if(rb.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - if(rb.m_failed && checkIfShouldThrow(at)) \ - throwException() - - template - DOCTEST_NOINLINE void binary_assert(assertType::Enum at, const char* file, int line, - const char* expr, const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) { - bool failed = !RelationalComparator()(lhs, rhs); - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); - DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); - } - - template - DOCTEST_NOINLINE void unary_assert(assertType::Enum at, const char* file, int line, - const char* expr, const DOCTEST_REF_WRAP(L) val) { - bool failed = !val; - - if(at & assertType::is_false) //!OCLINT bitwise operator in conditional - failed = !failed; - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(toString(val)); - DOCTEST_ASSERT_IN_TESTS(toString(val)); - } - - struct DOCTEST_INTERFACE IExceptionTranslator - { - DOCTEST_DELETE_COPIES(IExceptionTranslator); - - IExceptionTranslator(); - virtual ~IExceptionTranslator(); - virtual bool translate(String&) const = 0; - }; - - template - class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class - { - public: - explicit ExceptionTranslator(String (*translateFunction)(T)) - : m_translateFunction(translateFunction) {} - - bool translate(String& res) const override { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { - throw; // lgtm [cpp/rethrow-no-exception] - // cppcheck-suppress catchExceptionByValue - } catch(T ex) { // NOLINT - res = m_translateFunction(ex); //!OCLINT parameter reassignment - return true; - } catch(...) {} //!OCLINT - empty catch statement -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - ((void)res); // to silence -Wunused-parameter - return false; - } - - private: - String (*m_translateFunction)(T); - }; - - DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et); - - template - struct StringStreamBase - { - template - static void convert(std::ostream* s, const T& in) { - *s << toString(in); - } - - // always treat char* as a string in this context - no matter - // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined - static void convert(std::ostream* s, const char* in) { *s << String(in); } - }; - - template <> - struct StringStreamBase - { - template - static void convert(std::ostream* s, const T& in) { - *s << in; - } - }; - - template - struct StringStream : public StringStreamBase::value> - {}; - - template - void toStream(std::ostream* s, const T& value) { - StringStream::convert(s, value); - } - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - DOCTEST_INTERFACE void toStream(std::ostream* s, char* in); - DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in); -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - DOCTEST_INTERFACE void toStream(std::ostream* s, bool in); - DOCTEST_INTERFACE void toStream(std::ostream* s, float in); - DOCTEST_INTERFACE void toStream(std::ostream* s, double in); - DOCTEST_INTERFACE void toStream(std::ostream* s, double long in); - - DOCTEST_INTERFACE void toStream(std::ostream* s, char in); - DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in); - DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int short in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in); - - class DOCTEST_INTERFACE ContextBuilder - { - friend class ContextScope; - - struct DOCTEST_INTERFACE ICapture - { - DOCTEST_DELETE_COPIES(ICapture); - ICapture(); - virtual ~ICapture(); - virtual void toStream(std::ostream*) const = 0; - }; - - template - struct Capture : public ICapture //!OCLINT destructor of virtual class - { - const T* capture; - - explicit Capture(const T* in) - : capture(in) {} - void toStream(std::ostream* s) const override { detail::toStream(s, *capture); } - }; - - struct DOCTEST_INTERFACE Chunk - { - char buf[sizeof(Capture)] DOCTEST_ALIGNMENT( - 2 * sizeof(void*)); // place to construct a Capture - - DOCTEST_DECLARE_DEFAULTS(Chunk); - DOCTEST_DELETE_COPIES(Chunk); - }; - - struct DOCTEST_INTERFACE Node - { - Chunk chunk; - Node* next; - - DOCTEST_DECLARE_DEFAULTS(Node); - DOCTEST_DELETE_COPIES(Node); - }; - - Chunk stackChunks[DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK]; - int numCaptures = 0; - Node* head = nullptr; - Node* tail = nullptr; - - ContextBuilder(ContextBuilder& other); - - ContextBuilder& operator=(const ContextBuilder&) = delete; - - void stringify(std::ostream* s) const; - - public: - ContextBuilder(); - ~ContextBuilder(); - - template - DOCTEST_NOINLINE ContextBuilder& operator<<(T& in) { - Capture temp(&in); - - // construct either on stack or on heap - // copy the bytes for the whole object - including the vtable because we cant construct - // the object directly in the buffer using placement new - need the header... - if(numCaptures < DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK) { - my_memcpy(stackChunks[numCaptures].buf, &temp, sizeof(Chunk)); - } else { - auto curr = new Node; - curr->next = nullptr; - if(tail) { - tail->next = curr; - tail = curr; - } else { - head = tail = curr; - } - - my_memcpy(tail->chunk.buf, &temp, sizeof(Chunk)); - } - ++numCaptures; - return *this; - } - - template - ContextBuilder& operator<<(const T&&) { - static_assert(deferred_false::value, - "Cannot pass temporaries or rvalues to the streaming operator because it " - "caches pointers to the passed objects for lazy evaluation!"); - return *this; - } - }; - - class DOCTEST_INTERFACE ContextScope : public IContextScope - { - ContextBuilder contextBuilder; - - public: - explicit ContextScope(ContextBuilder& temp); - - DOCTEST_DELETE_COPIES(ContextScope); - - ~ContextScope(); - - void stringify(std::ostream* s) const; - }; - - struct DOCTEST_INTERFACE MessageBuilder : public MessageData - { - std::ostream* m_stream; - - MessageBuilder(const char* file, int line, assertType::Enum severity); - MessageBuilder() = delete; - ~MessageBuilder(); - - DOCTEST_DELETE_COPIES(MessageBuilder); - - template - MessageBuilder& operator<<(const T& in) { - toStream(m_stream, in); - return *this; - } - - bool log(); - void react(); - }; -} // namespace detail - -#define DOCTEST_DEFINE_DECORATOR(name, type, def) \ - struct name \ - { \ - type data; \ - name(type in = def) \ - : data(in) {} \ - void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; } \ - void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; } \ - } - -DOCTEST_DEFINE_DECORATOR(test_suite, const char*, ""); -DOCTEST_DEFINE_DECORATOR(description, const char*, ""); -DOCTEST_DEFINE_DECORATOR(skip, bool, true); -DOCTEST_DEFINE_DECORATOR(timeout, double, 0); -DOCTEST_DEFINE_DECORATOR(may_fail, bool, true); -DOCTEST_DEFINE_DECORATOR(should_fail, bool, true); -DOCTEST_DEFINE_DECORATOR(expected_failures, int, 0); - -template -int registerExceptionTranslator(String (*translateFunction)(T)) { - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") - static detail::ExceptionTranslator exceptionTranslator(translateFunction); - DOCTEST_CLANG_SUPPRESS_WARNING_POP - detail::registerExceptionTranslatorImpl(&exceptionTranslator); - return 0; -} - -} // namespace doctest - -// in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro -// introduces an anonymous namespace in which getCurrentTestSuite gets overridden -namespace doctest_detail_test_suite_ns { -DOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite(); -} // namespace doctest_detail_test_suite_ns - -namespace doctest { -#else // DOCTEST_CONFIG_DISABLE -template -int registerExceptionTranslator(String (*)(T)) { - return 0; -} -#endif // DOCTEST_CONFIG_DISABLE - -namespace detail { - typedef void (*assert_handler)(const AssertData&); - struct ContextState; -} // namespace detail - -class DOCTEST_INTERFACE Context -{ - detail::ContextState* p; - - void parseArgs(int argc, const char* const* argv, bool withDefaults = false); - -public: - explicit Context(int argc = 0, const char* const* argv = nullptr); - - DOCTEST_DELETE_COPIES(Context); - - ~Context(); - - void applyCommandLine(int argc, const char* const* argv); - - void addFilter(const char* filter, const char* value); - void clearFilters(); - void setOption(const char* option, int value); - void setOption(const char* option, const char* value); - - bool shouldExit(); - - void setAsDefaultForAssertsOutOfTestCases(); - - void setAssertHandler(detail::assert_handler ah); - - int run(); -}; - -namespace TestCaseFailureReason { - enum Enum - { - None = 0, - AssertFailure = 1, // an assertion has failed in the test case - Exception = 2, // test case threw an exception - Crash = 4, // a crash... - TooManyFailedAsserts = 8, // the abort-after option - Timeout = 16, // see the timeout decorator - ShouldHaveFailedButDidnt = 32, // see the should_fail decorator - ShouldHaveFailedAndDid = 64, // see the should_fail decorator - DidntFailExactlyNumTimes = 128, // see the expected_failures decorator - FailedExactlyNumTimes = 256, // see the expected_failures decorator - CouldHaveFailedAndDid = 512 // see the may_fail decorator - }; -} // namespace TestCaseFailureReason - -struct DOCTEST_INTERFACE CurrentTestCaseStats -{ - int numAssertsCurrentTest; - int numAssertsFailedCurrentTest; - double seconds; - int failure_flags; // use TestCaseFailureReason::Enum - - DOCTEST_DECLARE_DEFAULTS(CurrentTestCaseStats); - DOCTEST_DELETE_COPIES(CurrentTestCaseStats); -}; - -struct DOCTEST_INTERFACE TestCaseException -{ - String error_string; - bool is_crash; -}; - -struct DOCTEST_INTERFACE TestRunStats -{ - unsigned numTestCases; - unsigned numTestCasesPassingFilters; - unsigned numTestSuitesPassingFilters; - unsigned numTestCasesFailed; - int numAsserts; - int numAssertsFailed; - - DOCTEST_DECLARE_DEFAULTS(TestRunStats); - DOCTEST_DELETE_COPIES(TestRunStats); -}; - -struct QueryData -{ - const TestRunStats* run_stats = nullptr; - String* data = nullptr; - unsigned num_data = 0; -}; - -struct DOCTEST_INTERFACE IReporter -{ - // The constructor has to accept "const ContextOptions&" as a single argument - // which has most of the options for the run + a pointer to the stdout stream - // Reporter(const ContextOptions& in) - - // called when a query should be reported (listing test cases, printing the version, etc.) - virtual void report_query(const QueryData&) = 0; - - // called when the whole test run starts - virtual void test_run_start() = 0; - // called when the whole test run ends (caching a pointer to the input doesn't make sense here) - virtual void test_run_end(const TestRunStats&) = 0; - - // called when a test case is started (safe to cache a pointer to the input) - virtual void test_case_start(const TestCaseData&) = 0; - // called when a test case has ended - virtual void test_case_end(const CurrentTestCaseStats&) = 0; - - // called when an exception is thrown from the test case (or it crashes) - virtual void test_case_exception(const TestCaseException&) = 0; - - // called whenever a subcase is entered (don't cache pointers to the input) - virtual void subcase_start(const SubcaseSignature&) = 0; - // called whenever a subcase is exited (don't cache pointers to the input) - virtual void subcase_end() = 0; - - // called for each assert (don't cache pointers to the input) - virtual void log_assert(const AssertData&) = 0; - // called for each message (don't cache pointers to the input) - virtual void log_message(const MessageData&) = 0; - - // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator - // or isn't in the execution range (between first and last) (safe to cache a pointer to the input) - virtual void test_case_skipped(const TestCaseData&) = 0; - - // doctest will not be managing the lifetimes of reporters given to it but this would still be nice to have - virtual ~IReporter(); - - // can obtain all currently active contexts and stringify them if one wishes to do so - static int get_num_active_contexts(); - static const IContextScope* const* get_active_contexts(); - - // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown - static int get_num_stringified_contexts(); - static const String* get_stringified_contexts(); -}; - -namespace detail { - typedef IReporter* (*reporterCreatorFunc)(const ContextOptions&); - - DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c); - - template - IReporter* reporterCreator(const ContextOptions& o) { - return new Reporter(o); - } -} // namespace detail - -template -int registerReporter(const char* name, int priority) { - detail::registerReporterImpl(name, priority, detail::reporterCreator); - return 0; -} -} // namespace doctest - -// if registering is not disabled -#if !defined(DOCTEST_CONFIG_DISABLE) - -// common code in asserts - for convenience -#define DOCTEST_ASSERT_LOG_AND_REACT(b) \ - if(b.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - b.react() - -#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) x; -#else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) \ - try { \ - x; \ - } catch(...) { _DOCTEST_RB.translateException(); } -#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -// registers the test by initializing a dummy var with a function -#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \ - global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::regTest( \ - doctest::detail::TestCase( \ - f, __FILE__, __LINE__, \ - doctest_detail_test_suite_ns::getCurrentTestSuite()) * \ - decorators); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \ - namespace { \ - struct der : public base \ - { \ - void f(); \ - }; \ - static void func() { \ - der v; \ - v.f(); \ - } \ - DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \ - } \ - inline DOCTEST_NOINLINE void der::f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \ - static void f(); \ - DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \ - static void f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \ - static doctest::detail::funcType proxy() { return f; } \ - DOCTEST_REGISTER_FUNCTION(inline const, proxy(), decorators) \ - static void f() - -// for registering tests -#define DOCTEST_TEST_CASE(decorators) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators) - -// for registering tests in classes - requires C++17 for inline variables! -#if __cplusplus >= 201703L || (DOCTEST_MSVC >= DOCTEST_COMPILER(19, 12, 0) && _MSVC_LANG >= 201703L) -#define DOCTEST_TEST_CASE_CLASS(decorators) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_PROXY_), \ - decorators) -#else // DOCTEST_TEST_CASE_CLASS -#define DOCTEST_TEST_CASE_CLASS(...) \ - TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER -#endif // DOCTEST_TEST_CASE_CLASS - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), c, \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators) - -// for converting types to strings without the header and demangling -#define DOCTEST_TYPE_TO_STRING_IMPL(...) \ - template <> \ - inline const char* type_to_string<__VA_ARGS__>() { \ - return "<" #__VA_ARGS__ ">"; \ - } -#define DOCTEST_TYPE_TO_STRING(...) \ - namespace doctest { namespace detail { \ - DOCTEST_TYPE_TO_STRING_IMPL(__VA_ARGS__) \ - } \ - } \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for typed tests -#define DOCTEST_REGISTER_TYPED_TEST_CASE_IMPL(func, type, decorators, idx) \ - doctest::detail::regTest( \ - doctest::detail::TestCase(func, __FILE__, __LINE__, \ - doctest_detail_test_suite_ns::getCurrentTestSuite(), \ - doctest::detail::type_to_string(), idx) * \ - decorators) - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \ - template \ - inline void func(); \ - template \ - struct iter; \ - template \ - struct iter> \ - { \ - iter(int line, int index) { \ - DOCTEST_REGISTER_TYPED_TEST_CASE_IMPL(func, Type, dec, line * 1000 + index); \ - iter>(line, index + 1); \ - } \ - }; \ - template <> \ - struct iter> \ - { \ - iter(int, int) {} \ - }; \ - template \ - inline void func() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)) - -#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(id, anon, ...) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = [] { \ - DOCTEST_CAT(id, ITERATOR)> DOCTEST_UNUSED DOCTEST_CAT( \ - anon, inner_dummy)(__LINE__, 0); \ - return 0; \ - }(); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() - -#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_TEST_CASE_TEMPLATE_APPLY_IMPL(id, anon, ...) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = [] { \ - DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__> DOCTEST_UNUSED DOCTEST_CAT(anon, inner_dummy)( \ - __LINE__, 0); \ - return 0; \ - }(); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() - -#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_APPLY_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \ - DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(anon, anon, __VA_ARGS__) \ - template \ - inline void anon() - -#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) - -// for subcases -#define DOCTEST_SUBCASE(name) \ - if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \ - doctest::detail::Subcase(name, __FILE__, __LINE__)) - -// for grouping tests in test suites by using code blocks -#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \ - namespace ns_name { namespace doctest_detail_test_suite_ns { \ - static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() { \ - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \ - static doctest::detail::TestSuite data; \ - static bool inited = false; \ - DOCTEST_MSVC_SUPPRESS_WARNING_POP \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP \ - if(!inited) { \ - data* decorators; \ - inited = true; \ - } \ - return data; \ - } \ - } \ - } \ - namespace ns_name - -#define DOCTEST_TEST_SUITE(decorators) \ - DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUITE_)) - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(decorators) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * ""); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for registering exception translators -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \ - inline doctest::String translatorName(signature); \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)) = \ - doctest::registerExceptionTranslator(translatorName); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - doctest::String translatorName(signature) - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_), \ - signature) - -// for registering -#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_REPORTER_)) = \ - doctest::registerReporter(name, priority); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for logging -#define DOCTEST_INFO(x) \ - doctest::detail::ContextScope DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_)( \ - doctest::detail::ContextBuilder() << x) -#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := " << x) - -#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, x) \ - do { \ - doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \ - mb << x; \ - DOCTEST_ASSERT_LOG_AND_REACT(mb); \ - } while((void)0, 0) - -// clang-format off -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -// clang-format on - -#define DOCTEST_MESSAGE(x) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL_CHECK(x) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL(x) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, x) - -// hack for macros like INFO() that require lvalues -#if __cplusplus >= 201402L || (DOCTEST_MSVC >= DOCTEST_COMPILER(19, 10, 0)) -template -constexpr T to_lvalue = x; -#define DOCTEST_TO_LVALUE(...) to_lvalue -#else // TO_LVALUE -#define DOCTEST_TO_LVALUE(...) TO_LVALUE_CAN_BE_USED_ONLY_IN_CPP14_MODE_OR_WITH_VS_2017_OR_NEWER -#endif // TO_LVALUE - -#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.setResult( \ - doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ - << __VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB) \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ - do { \ - DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \ - } while((void)0, 0) - -#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \ - doctest::detail::decomp_assert( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, \ - doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ - << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__) -#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__) -#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__) -#define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__) -#define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__) -#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__) - -// clang-format off -#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while((void)0, 0) -#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while((void)0, 0) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while((void)0, 0) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while((void)0, 0) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while((void)0, 0) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while((void)0, 0) -// clang-format on - -#define DOCTEST_ASSERT_THROWS(expr, assert_type) DOCTEST_ASSERT_THROWS_WITH(expr, assert_type, "") - -#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, ...) \ - do { \ - if(!doctest::getContextOptions()->no_throw) { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #expr, #__VA_ARGS__); \ - try { \ - expr; \ - } catch(const doctest::detail::remove_const< \ - doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \ - _DOCTEST_RB.translateException(); \ - _DOCTEST_RB.m_threw_as = true; \ - } catch(...) { _DOCTEST_RB.translateException(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } \ - } while((void)0, 0) - -#define DOCTEST_ASSERT_THROWS_WITH(expr, assert_type, ...) \ - do { \ - if(!doctest::getContextOptions()->no_throw) { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #expr, __VA_ARGS__); \ - try { \ - expr; \ - } catch(...) { _DOCTEST_RB.translateException(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } \ - } while((void)0, 0) - -#define DOCTEST_ASSERT_NOTHROW(expr, assert_type) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #expr); \ - try { \ - expr; \ - } catch(...) { _DOCTEST_RB.translateException(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while((void)0, 0) - -// clang-format off -#define DOCTEST_WARN_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_WARN_THROWS) -#define DOCTEST_CHECK_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_CHECK_THROWS) -#define DOCTEST_REQUIRE_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_REQUIRE_THROWS) - -#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, __VA_ARGS__) - -#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, DT_WARN_THROWS_WITH, __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, DT_CHECK_THROWS_WITH, __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__) - -#define DOCTEST_WARN_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_WARN_NOTHROW) -#define DOCTEST_CHECK_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_CHECK_NOTHROW) -#define DOCTEST_REQUIRE_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_REQUIRE_NOTHROW) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while((void)0, 0) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while((void)0, 0) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while((void)0, 0) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while((void)0, 0) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while((void)0, 0) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while((void)0, 0) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH(expr, ex); } while((void)0, 0) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH(expr, ex); } while((void)0, 0) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH(expr, ex); } while((void)0, 0) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while((void)0, 0) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while((void)0, 0) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while((void)0, 0) -// clang-format on - -#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY( \ - _DOCTEST_RB.binary_assert( \ - __VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while((void)0, 0) - -#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(__VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while((void)0, 0) - -#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \ - doctest::detail::binary_assert( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__) - -#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ - doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__, \ - #__VA_ARGS__, __VA_ARGS__) - -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__) -#define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__) -#define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__) -#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__) -#define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__) -#define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__) -#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__) -#define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__) -#define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__) -#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__) -#define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__) -#define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__) -#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__) -#define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__) -#define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__) -#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__) -#define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__) -#define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__) - -#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__) -#define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__) -#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__) -#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__) -#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__) -#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__) - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS - -#undef DOCTEST_WARN_THROWS -#undef DOCTEST_CHECK_THROWS -#undef DOCTEST_REQUIRE_THROWS -#undef DOCTEST_WARN_THROWS_AS -#undef DOCTEST_CHECK_THROWS_AS -#undef DOCTEST_REQUIRE_THROWS_AS -#undef DOCTEST_WARN_THROWS_WITH -#undef DOCTEST_CHECK_THROWS_WITH -#undef DOCTEST_REQUIRE_THROWS_WITH -#undef DOCTEST_WARN_NOTHROW -#undef DOCTEST_CHECK_NOTHROW -#undef DOCTEST_REQUIRE_NOTHROW - -#undef DOCTEST_WARN_THROWS_MESSAGE -#undef DOCTEST_CHECK_THROWS_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_MESSAGE -#undef DOCTEST_WARN_THROWS_AS_MESSAGE -#undef DOCTEST_CHECK_THROWS_AS_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_AS_MESSAGE -#undef DOCTEST_WARN_THROWS_WITH_MESSAGE -#undef DOCTEST_CHECK_THROWS_WITH_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_WITH_MESSAGE -#undef DOCTEST_WARN_NOTHROW_MESSAGE -#undef DOCTEST_CHECK_NOTHROW_MESSAGE -#undef DOCTEST_REQUIRE_NOTHROW_MESSAGE - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#define DOCTEST_WARN_THROWS(expr) ((void)0) -#define DOCTEST_CHECK_THROWS(expr) ((void)0) -#define DOCTEST_REQUIRE_THROWS(expr) ((void)0) -#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0) -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0) -#define DOCTEST_WARN_NOTHROW(expr) ((void)0) -#define DOCTEST_CHECK_NOTHROW(expr) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0) - -#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#undef DOCTEST_REQUIRE -#undef DOCTEST_REQUIRE_FALSE -#undef DOCTEST_REQUIRE_MESSAGE -#undef DOCTEST_REQUIRE_FALSE_MESSAGE -#undef DOCTEST_REQUIRE_EQ -#undef DOCTEST_REQUIRE_NE -#undef DOCTEST_REQUIRE_GT -#undef DOCTEST_REQUIRE_LT -#undef DOCTEST_REQUIRE_GE -#undef DOCTEST_REQUIRE_LE -#undef DOCTEST_REQUIRE_UNARY -#undef DOCTEST_REQUIRE_UNARY_FALSE - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -// ================================================================================================= -// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! == -// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! == -// ================================================================================================= -#else // DOCTEST_CONFIG_DISABLE - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \ - namespace { \ - template \ - struct der : public base \ - { void f(); }; \ - } \ - template \ - inline void der::f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \ - template \ - static inline void f() - -// for registering tests -#define DOCTEST_TEST_CASE(name) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for registering tests in classes -#define DOCTEST_TEST_CASE_CLASS(name) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(x, name) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), x, \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for converting types to strings without the header and demangling -#define DOCTEST_TYPE_TO_STRING(...) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) -#define DOCTEST_TYPE_TO_STRING_IMPL(...) - -// for typed tests -#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \ - template \ - inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \ - template \ - inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for subcases -#define DOCTEST_SUBCASE(name) - -// for a testsuite block -#define DOCTEST_TEST_SUITE(name) namespace - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(name) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - template \ - static inline doctest::String DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)(signature) - -#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) - -#define DOCTEST_INFO(x) ((void)0) -#define DOCTEST_CAPTURE(x) ((void)0) -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) ((void)0) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) ((void)0) -#define DOCTEST_ADD_FAIL_AT(file, line, x) ((void)0) -#define DOCTEST_MESSAGE(x) ((void)0) -#define DOCTEST_FAIL_CHECK(x) ((void)0) -#define DOCTEST_FAIL(x) ((void)0) - -#define DOCTEST_WARN(...) ((void)0) -#define DOCTEST_CHECK(...) ((void)0) -#define DOCTEST_REQUIRE(...) ((void)0) -#define DOCTEST_WARN_FALSE(...) ((void)0) -#define DOCTEST_CHECK_FALSE(...) ((void)0) -#define DOCTEST_REQUIRE_FALSE(...) ((void)0) - -#define DOCTEST_WARN_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_CHECK_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) ((void)0) - -#define DOCTEST_WARN_THROWS(expr) ((void)0) -#define DOCTEST_CHECK_THROWS(expr) ((void)0) -#define DOCTEST_REQUIRE_THROWS(expr) ((void)0) -#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0) -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0) -#define DOCTEST_WARN_NOTHROW(expr) ((void)0) -#define DOCTEST_CHECK_NOTHROW(expr) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0) - -#define DOCTEST_WARN_EQ(...) ((void)0) -#define DOCTEST_CHECK_EQ(...) ((void)0) -#define DOCTEST_REQUIRE_EQ(...) ((void)0) -#define DOCTEST_WARN_NE(...) ((void)0) -#define DOCTEST_CHECK_NE(...) ((void)0) -#define DOCTEST_REQUIRE_NE(...) ((void)0) -#define DOCTEST_WARN_GT(...) ((void)0) -#define DOCTEST_CHECK_GT(...) ((void)0) -#define DOCTEST_REQUIRE_GT(...) ((void)0) -#define DOCTEST_WARN_LT(...) ((void)0) -#define DOCTEST_CHECK_LT(...) ((void)0) -#define DOCTEST_REQUIRE_LT(...) ((void)0) -#define DOCTEST_WARN_GE(...) ((void)0) -#define DOCTEST_CHECK_GE(...) ((void)0) -#define DOCTEST_REQUIRE_GE(...) ((void)0) -#define DOCTEST_WARN_LE(...) ((void)0) -#define DOCTEST_CHECK_LE(...) ((void)0) -#define DOCTEST_REQUIRE_LE(...) ((void)0) - -#define DOCTEST_WARN_UNARY(...) ((void)0) -#define DOCTEST_CHECK_UNARY(...) ((void)0) -#define DOCTEST_REQUIRE_UNARY(...) ((void)0) -#define DOCTEST_WARN_UNARY_FALSE(...) ((void)0) -#define DOCTEST_CHECK_UNARY_FALSE(...) ((void)0) -#define DOCTEST_REQUIRE_UNARY_FALSE(...) ((void)0) - -#endif // DOCTEST_CONFIG_DISABLE - -// clang-format off -// KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS -#define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ -#define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ -#define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ -#define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE -#define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE -#define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE -#define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT -#define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT -#define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT -#define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT -#define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT -#define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT -#define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE -#define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE -#define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE -#define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE -#define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE -#define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE - -#define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY -#define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY -#define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY -#define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE -#define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE -#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE - -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE DOCTEST_TEST_CASE_TEMPLATE_INVOKE -// clang-format on - -// BDD style macros -// clang-format off -#define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name) -#define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name) -#define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__) -#define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id) - -#define DOCTEST_GIVEN(name) SUBCASE(" Given: " name) -#define DOCTEST_WHEN(name) SUBCASE(" When: " name) -#define DOCTEST_AND_WHEN(name) SUBCASE("And when: " name) -#define DOCTEST_THEN(name) SUBCASE(" Then: " name) -#define DOCTEST_AND_THEN(name) SUBCASE(" And: " name) -// clang-format on - -// == SHORT VERSIONS OF THE MACROS -#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES) - -#define TEST_CASE DOCTEST_TEST_CASE -#define TEST_CASE_CLASS DOCTEST_TEST_CASE_CLASS -#define TEST_CASE_FIXTURE DOCTEST_TEST_CASE_FIXTURE -#define TYPE_TO_STRING DOCTEST_TYPE_TO_STRING -#define TEST_CASE_TEMPLATE DOCTEST_TEST_CASE_TEMPLATE -#define TEST_CASE_TEMPLATE_DEFINE DOCTEST_TEST_CASE_TEMPLATE_DEFINE -#define TEST_CASE_TEMPLATE_INVOKE DOCTEST_TEST_CASE_TEMPLATE_INVOKE -#define TEST_CASE_TEMPLATE_APPLY DOCTEST_TEST_CASE_TEMPLATE_APPLY -#define SUBCASE DOCTEST_SUBCASE -#define TEST_SUITE DOCTEST_TEST_SUITE -#define TEST_SUITE_BEGIN DOCTEST_TEST_SUITE_BEGIN -#define TEST_SUITE_END DOCTEST_TEST_SUITE_END -#define REGISTER_EXCEPTION_TRANSLATOR DOCTEST_REGISTER_EXCEPTION_TRANSLATOR -#define REGISTER_REPORTER DOCTEST_REGISTER_REPORTER -#define INFO DOCTEST_INFO -#define CAPTURE DOCTEST_CAPTURE -#define ADD_MESSAGE_AT DOCTEST_ADD_MESSAGE_AT -#define ADD_FAIL_CHECK_AT DOCTEST_ADD_FAIL_CHECK_AT -#define ADD_FAIL_AT DOCTEST_ADD_FAIL_AT -#define MESSAGE DOCTEST_MESSAGE -#define FAIL_CHECK DOCTEST_FAIL_CHECK -#define FAIL DOCTEST_FAIL -#define TO_LVALUE DOCTEST_TO_LVALUE - -#define WARN DOCTEST_WARN -#define WARN_FALSE DOCTEST_WARN_FALSE -#define WARN_THROWS DOCTEST_WARN_THROWS -#define WARN_THROWS_AS DOCTEST_WARN_THROWS_AS -#define WARN_THROWS_WITH DOCTEST_WARN_THROWS_WITH -#define WARN_NOTHROW DOCTEST_WARN_NOTHROW -#define CHECK DOCTEST_CHECK -#define CHECK_FALSE DOCTEST_CHECK_FALSE -#define CHECK_THROWS DOCTEST_CHECK_THROWS -#define CHECK_THROWS_AS DOCTEST_CHECK_THROWS_AS -#define CHECK_THROWS_WITH DOCTEST_CHECK_THROWS_WITH -#define CHECK_NOTHROW DOCTEST_CHECK_NOTHROW -#define REQUIRE DOCTEST_REQUIRE -#define REQUIRE_FALSE DOCTEST_REQUIRE_FALSE -#define REQUIRE_THROWS DOCTEST_REQUIRE_THROWS -#define REQUIRE_THROWS_AS DOCTEST_REQUIRE_THROWS_AS -#define REQUIRE_THROWS_WITH DOCTEST_REQUIRE_THROWS_WITH -#define REQUIRE_NOTHROW DOCTEST_REQUIRE_NOTHROW - -#define WARN_MESSAGE DOCTEST_WARN_MESSAGE -#define WARN_FALSE_MESSAGE DOCTEST_WARN_FALSE_MESSAGE -#define WARN_THROWS_MESSAGE DOCTEST_WARN_THROWS_MESSAGE -#define WARN_THROWS_AS_MESSAGE DOCTEST_WARN_THROWS_AS_MESSAGE -#define WARN_THROWS_WITH_MESSAGE DOCTEST_WARN_THROWS_WITH_MESSAGE -#define WARN_NOTHROW_MESSAGE DOCTEST_WARN_NOTHROW_MESSAGE -#define CHECK_MESSAGE DOCTEST_CHECK_MESSAGE -#define CHECK_FALSE_MESSAGE DOCTEST_CHECK_FALSE_MESSAGE -#define CHECK_THROWS_MESSAGE DOCTEST_CHECK_THROWS_MESSAGE -#define CHECK_THROWS_AS_MESSAGE DOCTEST_CHECK_THROWS_AS_MESSAGE -#define CHECK_THROWS_WITH_MESSAGE DOCTEST_CHECK_THROWS_WITH_MESSAGE -#define CHECK_NOTHROW_MESSAGE DOCTEST_CHECK_NOTHROW_MESSAGE -#define REQUIRE_MESSAGE DOCTEST_REQUIRE_MESSAGE -#define REQUIRE_FALSE_MESSAGE DOCTEST_REQUIRE_FALSE_MESSAGE -#define REQUIRE_THROWS_MESSAGE DOCTEST_REQUIRE_THROWS_MESSAGE -#define REQUIRE_THROWS_AS_MESSAGE DOCTEST_REQUIRE_THROWS_AS_MESSAGE -#define REQUIRE_THROWS_WITH_MESSAGE DOCTEST_REQUIRE_THROWS_WITH_MESSAGE -#define REQUIRE_NOTHROW_MESSAGE DOCTEST_REQUIRE_NOTHROW_MESSAGE - -#define SCENARIO DOCTEST_SCENARIO -#define SCENARIO_CLASS DOCTEST_SCENARIO_CLASS -#define SCENARIO_TEMPLATE DOCTEST_SCENARIO_TEMPLATE -#define SCENARIO_TEMPLATE_DEFINE DOCTEST_SCENARIO_TEMPLATE_DEFINE -#define GIVEN DOCTEST_GIVEN -#define WHEN DOCTEST_WHEN -#define AND_WHEN DOCTEST_AND_WHEN -#define THEN DOCTEST_THEN -#define AND_THEN DOCTEST_AND_THEN - -#define WARN_EQ DOCTEST_WARN_EQ -#define CHECK_EQ DOCTEST_CHECK_EQ -#define REQUIRE_EQ DOCTEST_REQUIRE_EQ -#define WARN_NE DOCTEST_WARN_NE -#define CHECK_NE DOCTEST_CHECK_NE -#define REQUIRE_NE DOCTEST_REQUIRE_NE -#define WARN_GT DOCTEST_WARN_GT -#define CHECK_GT DOCTEST_CHECK_GT -#define REQUIRE_GT DOCTEST_REQUIRE_GT -#define WARN_LT DOCTEST_WARN_LT -#define CHECK_LT DOCTEST_CHECK_LT -#define REQUIRE_LT DOCTEST_REQUIRE_LT -#define WARN_GE DOCTEST_WARN_GE -#define CHECK_GE DOCTEST_CHECK_GE -#define REQUIRE_GE DOCTEST_REQUIRE_GE -#define WARN_LE DOCTEST_WARN_LE -#define CHECK_LE DOCTEST_CHECK_LE -#define REQUIRE_LE DOCTEST_REQUIRE_LE -#define WARN_UNARY DOCTEST_WARN_UNARY -#define CHECK_UNARY DOCTEST_CHECK_UNARY -#define REQUIRE_UNARY DOCTEST_REQUIRE_UNARY -#define WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE -#define CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE -#define REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE - -// KEPT FOR BACKWARDS COMPATIBILITY -#define FAST_WARN_EQ DOCTEST_FAST_WARN_EQ -#define FAST_CHECK_EQ DOCTEST_FAST_CHECK_EQ -#define FAST_REQUIRE_EQ DOCTEST_FAST_REQUIRE_EQ -#define FAST_WARN_NE DOCTEST_FAST_WARN_NE -#define FAST_CHECK_NE DOCTEST_FAST_CHECK_NE -#define FAST_REQUIRE_NE DOCTEST_FAST_REQUIRE_NE -#define FAST_WARN_GT DOCTEST_FAST_WARN_GT -#define FAST_CHECK_GT DOCTEST_FAST_CHECK_GT -#define FAST_REQUIRE_GT DOCTEST_FAST_REQUIRE_GT -#define FAST_WARN_LT DOCTEST_FAST_WARN_LT -#define FAST_CHECK_LT DOCTEST_FAST_CHECK_LT -#define FAST_REQUIRE_LT DOCTEST_FAST_REQUIRE_LT -#define FAST_WARN_GE DOCTEST_FAST_WARN_GE -#define FAST_CHECK_GE DOCTEST_FAST_CHECK_GE -#define FAST_REQUIRE_GE DOCTEST_FAST_REQUIRE_GE -#define FAST_WARN_LE DOCTEST_FAST_WARN_LE -#define FAST_CHECK_LE DOCTEST_FAST_CHECK_LE -#define FAST_REQUIRE_LE DOCTEST_FAST_REQUIRE_LE - -#define FAST_WARN_UNARY DOCTEST_FAST_WARN_UNARY -#define FAST_CHECK_UNARY DOCTEST_FAST_CHECK_UNARY -#define FAST_REQUIRE_UNARY DOCTEST_FAST_REQUIRE_UNARY -#define FAST_WARN_UNARY_FALSE DOCTEST_FAST_WARN_UNARY_FALSE -#define FAST_CHECK_UNARY_FALSE DOCTEST_FAST_CHECK_UNARY_FALSE -#define FAST_REQUIRE_UNARY_FALSE DOCTEST_FAST_REQUIRE_UNARY_FALSE - -#define TEST_CASE_TEMPLATE_INSTANTIATE DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE - -#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES - -#if !defined(DOCTEST_CONFIG_DISABLE) - -// this is here to clear the 'current test suite' for the current translation unit - at the top -DOCTEST_TEST_SUITE_END(); - -// add stringification for primitive/fundamental types -namespace doctest { namespace detail { - DOCTEST_TYPE_TO_STRING_IMPL(bool) - DOCTEST_TYPE_TO_STRING_IMPL(float) - DOCTEST_TYPE_TO_STRING_IMPL(double) - DOCTEST_TYPE_TO_STRING_IMPL(long double) - DOCTEST_TYPE_TO_STRING_IMPL(char) - DOCTEST_TYPE_TO_STRING_IMPL(signed char) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned char) -#if !DOCTEST_MSVC || defined(_NATIVE_WCHAR_T_DEFINED) - DOCTEST_TYPE_TO_STRING_IMPL(wchar_t) -#endif // not MSVC or wchar_t support enabled - DOCTEST_TYPE_TO_STRING_IMPL(short int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned short int) - DOCTEST_TYPE_TO_STRING_IMPL(int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned int) - DOCTEST_TYPE_TO_STRING_IMPL(long int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned long int) - DOCTEST_TYPE_TO_STRING_IMPL(long long int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned long long int) -}} // namespace doctest::detail - -#endif // DOCTEST_CONFIG_DISABLE - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_LIBRARY_INCLUDED - -#ifndef DOCTEST_SINGLE_HEADER -#define DOCTEST_SINGLE_HEADER -#endif // DOCTEST_SINGLE_HEADER - -#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER) -#ifndef DOCTEST_LIBRARY_IMPLEMENTATION -#define DOCTEST_LIBRARY_IMPLEMENTATION - -#ifndef DOCTEST_SINGLE_HEADER -#include "doctest_fwd.h" -#endif // DOCTEST_SINGLE_HEADER - -DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-local-typedef") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function") - -DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") -DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") -DOCTEST_GCC_SUPPRESS_WARNING("-Winline") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations") -DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs") -DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function") - -DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -DOCTEST_MSVC_SUPPRESS_WARNING(4616) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4619) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4996) // The compiler encountered a deprecated declaration -DOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data -DOCTEST_MSVC_SUPPRESS_WARNING(4706) // assignment within conditional expression -DOCTEST_MSVC_SUPPRESS_WARNING(4512) // 'class' : assignment operator could not be generated -DOCTEST_MSVC_SUPPRESS_WARNING(4127) // conditional expression is constant -DOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled -DOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified -DOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal -DOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch -DOCTEST_MSVC_SUPPRESS_WARNING(4820) // padding in structs -DOCTEST_MSVC_SUPPRESS_WARNING(4640) // construction of local static object is not thread-safe -DOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C -DOCTEST_MSVC_SUPPRESS_WARNING(5045) // Spectre mitigation stuff -DOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4625) // copy constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning) -// static analysis -DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Declare it 'noexcept' -DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable -DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ... -DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtor... - -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN - -// required includes - will go only in one translation unit! -#include -#include -#include -// borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/onqtam/doctest/pull/37 -#ifdef __BORLANDC__ -#include -#endif // __BORLANDC__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef DOCTEST_CONFIG_POSIX_SIGNALS -#include -#endif // DOCTEST_CONFIG_POSIX_SIGNALS -#include -#include -#include - -#ifdef DOCTEST_PLATFORM_MAC -#include -#include -#include -#endif // DOCTEST_PLATFORM_MAC - -#ifdef DOCTEST_PLATFORM_WINDOWS - -// defines for a leaner windows.h -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif // WIN32_LEAN_AND_MEAN -#ifndef VC_EXTRA_LEAN -#define VC_EXTRA_LEAN -#endif // VC_EXTRA_LEAN -#ifndef NOMINMAX -#define NOMINMAX -#endif // NOMINMAX - -// not sure what AfxWin.h is for - here I do what Catch does -#ifdef __AFXDLL -#include -#else -#include -#endif -#include - -#else // DOCTEST_PLATFORM_WINDOWS - -#include -#include - -#endif // DOCTEST_PLATFORM_WINDOWS - -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END - -// counts the number of elements in a C array -#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0])) - -#ifdef DOCTEST_CONFIG_DISABLE -#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled -#else // DOCTEST_CONFIG_DISABLE -#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled -#endif // DOCTEST_CONFIG_DISABLE - -#ifndef DOCTEST_CONFIG_OPTIONS_PREFIX -#define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-" -#endif - -#ifndef DOCTEST_THREAD_LOCAL -#define DOCTEST_THREAD_LOCAL thread_local -#endif - -#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS -#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX -#else -#define DOCTEST_OPTIONS_PREFIX_DISPLAY "" -#endif - -namespace doctest { - -bool is_running_in_test = false; - -namespace { - using namespace detail; - // case insensitive strcmp - int stricmp(const char* a, const char* b) { - for(;; a++, b++) { - const int d = tolower(*a) - tolower(*b); - if(d != 0 || !*a) - return d; - } - } - - template - String fpToString(T value, int precision) { - std::ostringstream oss; - oss << std::setprecision(precision) << std::fixed << value; - std::string d = oss.str(); - size_t i = d.find_last_not_of('0'); - if(i != std::string::npos && i != d.size() - 1) { - if(d[i] == '.') - i++; - d = d.substr(0, i + 1); - } - return d.c_str(); - } - - struct Endianness - { - enum Arch - { - Big, - Little - }; - - static Arch which() { - int x = 1; - // casting any data pointer to char* is allowed - auto ptr = reinterpret_cast(&x); - if(*ptr) - return Little; - return Big; - } - }; -} // namespace - -namespace detail { - void my_memcpy(void* dest, const void* src, unsigned num) { memcpy(dest, src, num); } - - String rawMemoryToString(const void* object, unsigned size) { - // Reverse order for little endian architectures - int i = 0, end = static_cast(size), inc = 1; - if(Endianness::which() == Endianness::Little) { - i = end - 1; - end = inc = -1; - } - - unsigned const char* bytes = static_cast(object); - std::ostringstream oss; - oss << "0x" << std::setfill('0') << std::hex; - for(; i != end; i += inc) - oss << std::setw(2) << static_cast(bytes[i]); - return oss.str().c_str(); - } - - DOCTEST_THREAD_LOCAL std::ostringstream g_oss; - - std::ostream* getTlsOss() { - g_oss.clear(); // there shouldn't be anything worth clearing in the flags - g_oss.str(""); // the slow way of resetting a string stream - //g_oss.seekp(0); // optimal reset - as seen here: https://stackoverflow.com/a/624291/3162383 - return &g_oss; - } - - String getTlsOssResult() { - //g_oss << std::ends; // needed - as shown here: https://stackoverflow.com/a/624291/3162383 - return g_oss.str().c_str(); - } - -#ifndef DOCTEST_CONFIG_DISABLE - - typedef uint64_t UInt64; - -#ifdef DOCTEST_CONFIG_GETCURRENTTICKS - UInt64 getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); } -#elif defined(DOCTEST_PLATFORM_WINDOWS) - UInt64 getCurrentTicks() { - static UInt64 hz = 0, hzo = 0; - if(!hz) { - QueryPerformanceFrequency(reinterpret_cast(&hz)); - QueryPerformanceCounter(reinterpret_cast(&hzo)); - } - UInt64 t; - QueryPerformanceCounter(reinterpret_cast(&t)); - return ((t - hzo) * 1000000) / hz; - } -#else // DOCTEST_PLATFORM_WINDOWS - UInt64 getCurrentTicks() { - timeval t; - gettimeofday(&t, nullptr); - return static_cast(t.tv_sec) * 1000000 + static_cast(t.tv_usec); - } -#endif // DOCTEST_PLATFORM_WINDOWS - - struct Timer - { - void start() { m_ticks = getCurrentTicks(); } - unsigned int getElapsedMicroseconds() const { - return static_cast(getCurrentTicks() - m_ticks); - } - //unsigned int getElapsedMilliseconds() const { - // return static_cast(getElapsedMicroseconds() / 1000); - //} - double getElapsedSeconds() const { return getElapsedMicroseconds() / 1000000.0; } - - private: - UInt64 m_ticks = 0; - }; - - // this holds both parameters from the command line and runtime data for tests - struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats - { - std::atomic numAssertsCurrentTest_atomic; - std::atomic numAssertsFailedCurrentTest_atomic; - - std::vector> filters = decltype(filters)(9); // 9 different filters - - std::vector reporters_currently_used; - - const TestCase* currentTest = nullptr; - - assert_handler ah = nullptr; - - Timer timer; - - std::vector stringifiedContexts; // logging from INFO() due to an exception - - // stuff for subcases - std::set subcasesPassed; - std::set subcasesEnteredLevels; - int subcasesCurrentLevel; - bool should_reenter; - - void resetRunData() { - numTestCases = 0; - numTestCasesPassingFilters = 0; - numTestSuitesPassingFilters = 0; - numTestCasesFailed = 0; - numAsserts = 0; - numAssertsFailed = 0; - numAssertsCurrentTest = 0; - numAssertsFailedCurrentTest = 0; - } - - void finalizeTestCaseData() { - seconds = timer.getElapsedSeconds(); - - // update the non-atomic counters - numAsserts += numAssertsCurrentTest_atomic; - numAssertsFailed += numAssertsFailedCurrentTest_atomic; - numAssertsCurrentTest = numAssertsCurrentTest_atomic; - numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic; - - if(numAssertsFailedCurrentTest) - failure_flags |= TestCaseFailureReason::AssertFailure; - - if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 && - Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout) - failure_flags |= TestCaseFailureReason::Timeout; - - if(currentTest->m_should_fail) { - if(failure_flags) { - failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid; - } else { - failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt; - } - } else if(failure_flags && currentTest->m_may_fail) { - failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid; - } else if(currentTest->m_expected_failures > 0) { - if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) { - failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes; - } else { - failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes; - } - } - - bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) || - (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) || - (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags); - - // if any subcase has failed - the whole test case has failed - if(failure_flags && !ok_to_fail) - numTestCasesFailed++; - } - }; - - ContextState* g_cs = nullptr; - - // used to avoid locks for the debug output - // TODO: figure out if this is indeed necessary/correct - seems like either there still - // could be a race or that there wouldn't be a race even if using the context directly - DOCTEST_THREAD_LOCAL bool g_no_colors; - -#endif // DOCTEST_CONFIG_DISABLE -} // namespace detail - -void String::setOnHeap() { *reinterpret_cast(&buf[last]) = 128; } -void String::setLast(unsigned in) { buf[last] = char(in); } - -void String::copy(const String& other) { - if(other.isOnStack()) { - memcpy(buf, other.buf, len); - } else { - setOnHeap(); - data.size = other.data.size; - data.capacity = data.size + 1; - data.ptr = new char[data.capacity]; - memcpy(data.ptr, other.data.ptr, data.size + 1); - } -} - -String::String() { - buf[0] = '\0'; - setLast(); -} - -String::~String() { - if(!isOnStack()) - delete[] data.ptr; -} - -String::String(const char* in) - : String(in, strlen(in)) {} - -String::String(const char* in, unsigned in_size) { - if(in_size <= last) { - memcpy(buf, in, in_size + 1); - setLast(last - in_size); - } else { - setOnHeap(); - data.size = in_size; - data.capacity = data.size + 1; - data.ptr = new char[data.capacity]; - memcpy(data.ptr, in, in_size + 1); - } -} - -String::String(const String& other) { copy(other); } - -String& String::operator=(const String& other) { - if(this != &other) { - if(!isOnStack()) - delete[] data.ptr; - - copy(other); - } - - return *this; -} - -String& String::operator+=(const String& other) { - const unsigned my_old_size = size(); - const unsigned other_size = other.size(); - const unsigned total_size = my_old_size + other_size; - if(isOnStack()) { - if(total_size < len) { - // append to the current stack space - memcpy(buf + my_old_size, other.c_str(), other_size + 1); - setLast(last - total_size); - } else { - // alloc new chunk - char* temp = new char[total_size + 1]; - // copy current data to new location before writing in the union - memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed - // update data in union - setOnHeap(); - data.size = total_size; - data.capacity = data.size + 1; - data.ptr = temp; - // transfer the rest of the data - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } else { - if(data.capacity > total_size) { - // append to the current heap block - data.size = total_size; - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } else { - // resize - data.capacity *= 2; - if(data.capacity <= total_size) - data.capacity = total_size + 1; - // alloc new chunk - char* temp = new char[data.capacity]; - // copy current data to new location before releasing it - memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed - // release old chunk - delete[] data.ptr; - // update the rest of the union members - data.size = total_size; - data.ptr = temp; - // transfer the rest of the data - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } - - return *this; -} - -String String::operator+(const String& other) const { return String(*this) += other; } - -String::String(String&& other) { - memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); -} - -String& String::operator=(String&& other) { - if(this != &other) { - if(!isOnStack()) - delete[] data.ptr; - memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); - } - return *this; -} - -char String::operator[](unsigned i) const { - return const_cast(this)->operator[](i); // NOLINT -} - -char& String::operator[](unsigned i) { - if(isOnStack()) - return reinterpret_cast(buf)[i]; - return data.ptr[i]; -} - -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized") -unsigned String::size() const { - if(isOnStack()) - return last - (unsigned(buf[last]) & 31); // using "last" would work only if "len" is 32 - return data.size; -} -DOCTEST_GCC_SUPPRESS_WARNING_POP - -unsigned String::capacity() const { - if(isOnStack()) - return len; - return data.capacity; -} - -int String::compare(const char* other, bool no_case) const { - if(no_case) - return stricmp(c_str(), other); - return std::strcmp(c_str(), other); -} - -int String::compare(const String& other, bool no_case) const { - return compare(other.c_str(), no_case); -} - -// clang-format off -bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; } -bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; } -bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; } -bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; } -bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; } -bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; } -// clang-format on - -std::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); } - -namespace { - void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;) -} // namespace - -namespace Color { - std::ostream& operator<<(std::ostream& s, Color::Enum code) { - color_to_stream(s, code); - return s; - } -} // namespace Color - -// clang-format off -const char* assertString(assertType::Enum at) { - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4062) // enum 'x' in switch of enum 'y' is not handled - switch(at) { //!OCLINT missing default in switch statements - case assertType::DT_WARN : return "WARN"; - case assertType::DT_CHECK : return "CHECK"; - case assertType::DT_REQUIRE : return "REQUIRE"; - - case assertType::DT_WARN_FALSE : return "WARN_FALSE"; - case assertType::DT_CHECK_FALSE : return "CHECK_FALSE"; - case assertType::DT_REQUIRE_FALSE : return "REQUIRE_FALSE"; - - case assertType::DT_WARN_THROWS : return "WARN_THROWS"; - case assertType::DT_CHECK_THROWS : return "CHECK_THROWS"; - case assertType::DT_REQUIRE_THROWS : return "REQUIRE_THROWS"; - - case assertType::DT_WARN_THROWS_AS : return "WARN_THROWS_AS"; - case assertType::DT_CHECK_THROWS_AS : return "CHECK_THROWS_AS"; - case assertType::DT_REQUIRE_THROWS_AS : return "REQUIRE_THROWS_AS"; - - case assertType::DT_WARN_THROWS_WITH : return "WARN_THROWS_WITH"; - case assertType::DT_CHECK_THROWS_WITH : return "CHECK_THROWS_WITH"; - case assertType::DT_REQUIRE_THROWS_WITH : return "REQUIRE_THROWS_WITH"; - - case assertType::DT_WARN_NOTHROW : return "WARN_NOTHROW"; - case assertType::DT_CHECK_NOTHROW : return "CHECK_NOTHROW"; - case assertType::DT_REQUIRE_NOTHROW : return "REQUIRE_NOTHROW"; - - case assertType::DT_WARN_EQ : return "WARN_EQ"; - case assertType::DT_CHECK_EQ : return "CHECK_EQ"; - case assertType::DT_REQUIRE_EQ : return "REQUIRE_EQ"; - case assertType::DT_WARN_NE : return "WARN_NE"; - case assertType::DT_CHECK_NE : return "CHECK_NE"; - case assertType::DT_REQUIRE_NE : return "REQUIRE_NE"; - case assertType::DT_WARN_GT : return "WARN_GT"; - case assertType::DT_CHECK_GT : return "CHECK_GT"; - case assertType::DT_REQUIRE_GT : return "REQUIRE_GT"; - case assertType::DT_WARN_LT : return "WARN_LT"; - case assertType::DT_CHECK_LT : return "CHECK_LT"; - case assertType::DT_REQUIRE_LT : return "REQUIRE_LT"; - case assertType::DT_WARN_GE : return "WARN_GE"; - case assertType::DT_CHECK_GE : return "CHECK_GE"; - case assertType::DT_REQUIRE_GE : return "REQUIRE_GE"; - case assertType::DT_WARN_LE : return "WARN_LE"; - case assertType::DT_CHECK_LE : return "CHECK_LE"; - case assertType::DT_REQUIRE_LE : return "REQUIRE_LE"; - - case assertType::DT_WARN_UNARY : return "WARN_UNARY"; - case assertType::DT_CHECK_UNARY : return "CHECK_UNARY"; - case assertType::DT_REQUIRE_UNARY : return "REQUIRE_UNARY"; - case assertType::DT_WARN_UNARY_FALSE : return "WARN_UNARY_FALSE"; - case assertType::DT_CHECK_UNARY_FALSE : return "CHECK_UNARY_FALSE"; - case assertType::DT_REQUIRE_UNARY_FALSE : return "REQUIRE_UNARY_FALSE"; - } - DOCTEST_MSVC_SUPPRESS_WARNING_POP - return ""; -} -// clang-format on - -const char* failureString(assertType::Enum at) { - if(at & assertType::is_warn) //!OCLINT bitwise operator in conditional - return "WARNING"; - if(at & assertType::is_check) //!OCLINT bitwise operator in conditional - return "ERROR"; - if(at & assertType::is_require) //!OCLINT bitwise operator in conditional - return "FATAL ERROR"; - return ""; -} - -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") -// depending on the current options this will remove the path of filenames -const char* skipPathFromFilename(const char* file) { - if(getContextOptions()->no_path_in_filenames) { - auto back = std::strrchr(file, '\\'); - auto forward = std::strrchr(file, '/'); - if(back || forward) { - if(back > forward) - forward = back; - return forward + 1; - } - } - return file; -} -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -DOCTEST_DEFINE_DEFAULTS(TestCaseData); -DOCTEST_DEFINE_COPIES(TestCaseData); - -DOCTEST_DEFINE_DEFAULTS(AssertData); - -DOCTEST_DEFINE_DEFAULTS(MessageData); - -SubcaseSignature::SubcaseSignature(const char* name, const char* file, int line) - : m_name(name) - , m_file(file) - , m_line(line) {} - -DOCTEST_DEFINE_DEFAULTS(SubcaseSignature); -DOCTEST_DEFINE_COPIES(SubcaseSignature); - -bool SubcaseSignature::operator<(const SubcaseSignature& other) const { - if(m_line != other.m_line) - return m_line < other.m_line; - if(std::strcmp(m_file, other.m_file) != 0) - return std::strcmp(m_file, other.m_file) < 0; - return std::strcmp(m_name, other.m_name) < 0; -} - -IContextScope::IContextScope() = default; -IContextScope::~IContextScope() = default; - -DOCTEST_DEFINE_DEFAULTS(ContextOptions); - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -String toString(char* in) { return toString(static_cast(in)); } -String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -String toString(bool in) { return in ? "true" : "false"; } -String toString(float in) { return fpToString(in, 5) + "f"; } -String toString(double in) { return fpToString(in, 10); } -String toString(double long in) { return fpToString(in, 15); } - -#define DOCTEST_TO_STRING_OVERLOAD(type, fmt) \ - String toString(type in) { \ - char buf[64]; \ - std::sprintf(buf, fmt, in); \ - return buf; \ - } - -DOCTEST_TO_STRING_OVERLOAD(char, "%d") -DOCTEST_TO_STRING_OVERLOAD(char signed, "%d") -DOCTEST_TO_STRING_OVERLOAD(char unsigned, "%u") -DOCTEST_TO_STRING_OVERLOAD(int short, "%d") -DOCTEST_TO_STRING_OVERLOAD(int short unsigned, "%u") -DOCTEST_TO_STRING_OVERLOAD(int, "%d") -DOCTEST_TO_STRING_OVERLOAD(unsigned, "%u") -DOCTEST_TO_STRING_OVERLOAD(int long, "%ld") -DOCTEST_TO_STRING_OVERLOAD(int long unsigned, "%lu") -DOCTEST_TO_STRING_OVERLOAD(int long long, "%lld") -DOCTEST_TO_STRING_OVERLOAD(int long long unsigned, "%llu") - -String toString(std::nullptr_t) { return "NULL"; } - -Approx::Approx(double value) - : m_epsilon(static_cast(std::numeric_limits::epsilon()) * 100) - , m_scale(1.0) - , m_value(value) {} - -DOCTEST_DEFINE_COPIES(Approx); - -Approx Approx::operator()(double value) const { - Approx approx(value); - approx.epsilon(m_epsilon); - approx.scale(m_scale); - return approx; -} - -Approx& Approx::epsilon(double newEpsilon) { - m_epsilon = newEpsilon; - return *this; -} -Approx& Approx::scale(double newScale) { - m_scale = newScale; - return *this; -} - -bool operator==(double lhs, const Approx& rhs) { - // Thanks to Richard Harris for his help refining this formula - return std::fabs(lhs - rhs.m_value) < - rhs.m_epsilon * (rhs.m_scale + std::max(std::fabs(lhs), std::fabs(rhs.m_value))); -} -bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); } -bool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); } -bool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); } -bool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; } -bool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; } -bool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; } -bool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; } -bool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; } -bool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; } -bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; } -bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; } - -String toString(const Approx& in) { - return String("Approx( ") + doctest::toString(in.m_value) + " )"; -} -const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); } - -} // namespace doctest - -#ifdef DOCTEST_CONFIG_DISABLE -namespace doctest { -Context::Context(int, const char* const*) {} -Context::~Context() = default; -void Context::applyCommandLine(int, const char* const*) {} -void Context::addFilter(const char*, const char*) {} -void Context::clearFilters() {} -void Context::setOption(const char*, int) {} -void Context::setOption(const char*, const char*) {} -bool Context::shouldExit() { return false; } -void Context::setAsDefaultForAssertsOutOfTestCases() {} -void Context::setAssertHandler(detail::assert_handler) {} -int Context::run() { return 0; } - -DOCTEST_DEFINE_DEFAULTS(CurrentTestCaseStats); - -DOCTEST_DEFINE_DEFAULTS(TestRunStats); - -IReporter::~IReporter() = default; - -int IReporter::get_num_active_contexts() { return 0; } -const IContextScope* const* IReporter::get_active_contexts() { return nullptr; } -int IReporter::get_num_stringified_contexts() { return 0; } -const String* IReporter::get_stringified_contexts() { return nullptr; } - -int registerReporter(const char*, int, IReporter*) { return 0; } - -} // namespace doctest -#else // DOCTEST_CONFIG_DISABLE - -#if !defined(DOCTEST_CONFIG_COLORS_NONE) -#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI) -#ifdef DOCTEST_PLATFORM_WINDOWS -#define DOCTEST_CONFIG_COLORS_WINDOWS -#else // linux -#define DOCTEST_CONFIG_COLORS_ANSI -#endif // platform -#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI -#endif // DOCTEST_CONFIG_COLORS_NONE - -namespace doctest_detail_test_suite_ns { -// holds the current test suite -doctest::detail::TestSuite& getCurrentTestSuite() { - static doctest::detail::TestSuite data; - return data; -} -} // namespace doctest_detail_test_suite_ns - -namespace doctest { -namespace { - // the int (priority) is part of the key for automatic sorting - sadly one can register a - // reporter with a duplicate name and a different priority but hopefully that won't happen often :| - typedef std::map, reporterCreatorFunc> reporterMap; - reporterMap& getReporters() { - static reporterMap data; - return data; - } -} // namespace -namespace detail { -#define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \ - for(auto& curr_rep : g_cs->reporters_currently_used) \ - curr_rep->function(__VA_ARGS__) - - DOCTEST_DEFINE_DEFAULTS(TestFailureException); - DOCTEST_DEFINE_COPIES(TestFailureException); - bool checkIfShouldThrow(assertType::Enum at) { - if(at & assertType::is_require) //!OCLINT bitwise operator in conditional - return true; - - if((at & assertType::is_check) //!OCLINT bitwise operator in conditional - && getContextOptions()->abort_after > 0 && - (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >= - getContextOptions()->abort_after) - return true; - - return false; - } - - void throwException() { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - throw TestFailureException(); -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - } -} // namespace detail - -namespace { - using namespace detail; - // matching of a string against a wildcard mask (case sensitivity configurable) taken from - // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing - int wildcmp(const char* str, const char* wild, bool caseSensitive) { - const char* cp = nullptr; - const char* mp = nullptr; - - while((*str) && (*wild != '*')) { - if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) && - (*wild != '?')) { - return 0; - } - wild++; - str++; - } - - while(*str) { - if(*wild == '*') { - if(!*++wild) { - return 1; - } - mp = wild; - cp = str + 1; - } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) || - (*wild == '?')) { - wild++; - str++; - } else { - wild = mp; //!OCLINT parameter reassignment - str = cp++; //!OCLINT parameter reassignment - } - } - - while(*wild == '*') { - wild++; - } - return !*wild; - } - - //// C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html - //unsigned hashStr(unsigned const char* str) { - // unsigned long hash = 5381; - // char c; - // while((c = *str++)) - // hash = ((hash << 5) + hash) + c; // hash * 33 + c - // return hash; - //} - - // checks if the name matches any of the filters (and can be configured what to do when empty) - bool matchesAny(const char* name, const std::vector& filters, bool matchEmpty, - bool caseSensitive) { - if(filters.empty() && matchEmpty) - return true; - for(auto& curr : filters) - if(wildcmp(name, curr.c_str(), caseSensitive)) - return true; - return false; - } -} // namespace -namespace detail { - - Subcase::Subcase(const char* name, const char* file, int line) - : m_signature(name, file, line) { - ContextState* s = g_cs; - - // if we have already completed it - if(s->subcasesPassed.count(m_signature) != 0) - return; - - // check subcase filters - if(s->subcasesCurrentLevel < s->subcase_filter_levels) { - if(!matchesAny(m_signature.m_name, s->filters[6], true, s->case_sensitive)) - return; - if(matchesAny(m_signature.m_name, s->filters[7], false, s->case_sensitive)) - return; - } - - // if a Subcase on the same level has already been entered - if(s->subcasesEnteredLevels.count(s->subcasesCurrentLevel) != 0) { - s->should_reenter = true; - return; - } - - s->subcasesEnteredLevels.insert(s->subcasesCurrentLevel++); - m_entered = true; - - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); - } - - Subcase::~Subcase() { - if(m_entered) { - ContextState* s = g_cs; - - s->subcasesCurrentLevel--; - // only mark the subcase as passed if no subcases have been skipped - if(s->should_reenter == false) - s->subcasesPassed.insert(m_signature); - - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); - } - } - - Subcase::operator bool() const { return m_entered; } - - Result::Result(bool passed, const String& decomposition) - : m_passed(passed) - , m_decomp(decomposition) {} - - DOCTEST_DEFINE_DEFAULTS(Result); - DOCTEST_DEFINE_COPIES(Result); - - ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at) - : m_at(at) {} - - DOCTEST_DEFINE_DEFAULTS(ExpressionDecomposer); - - DOCTEST_DEFINE_DEFAULTS(TestSuite); - DOCTEST_DEFINE_COPIES(TestSuite); - - TestSuite& TestSuite::operator*(const char* in) { - m_test_suite = in; - // clear state - m_description = nullptr; - m_skip = false; - m_may_fail = false; - m_should_fail = false; - m_expected_failures = 0; - m_timeout = 0; - return *this; - } - - TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, - const char* type, int template_id) { - m_file = file; - m_line = line; - m_name = nullptr; - m_test_suite = test_suite.m_test_suite; - m_description = test_suite.m_description; - m_skip = test_suite.m_skip; - m_may_fail = test_suite.m_may_fail; - m_should_fail = test_suite.m_should_fail; - m_expected_failures = test_suite.m_expected_failures; - m_timeout = test_suite.m_timeout; - - m_test = test; - m_type = type; - m_template_id = template_id; - } - - DOCTEST_DEFINE_DEFAULTS(TestCase); - - TestCase::TestCase(const TestCase& other) - : TestCaseData() { - *this = other; - } - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function - DOCTEST_MSVC_SUPPRESS_WARNING(26437) // Do not slice - TestCase& TestCase::operator=(const TestCase& other) { - static_cast(*this) = static_cast(other); - - m_test = other.m_test; - m_type = other.m_type; - m_template_id = other.m_template_id; - m_full_name = other.m_full_name; - - if(m_template_id != -1) - m_name = m_full_name.c_str(); - return *this; - } - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - TestCase& TestCase::operator*(const char* in) { - m_name = in; - // make a new name with an appended type for templated test case - if(m_template_id != -1) { - m_full_name = String(m_name) + m_type; - // redirect the name to point to the newly constructed full name - m_name = m_full_name.c_str(); - } - return *this; - } - - bool TestCase::operator<(const TestCase& other) const { - if(m_line != other.m_line) - return m_line < other.m_line; - const int file_cmp = std::strcmp(m_file, other.m_file); - if(file_cmp != 0) - return file_cmp < 0; - return m_template_id < other.m_template_id; - } -} // namespace detail -namespace { - using namespace detail; - // for sorting tests by file/line - bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) { -#if DOCTEST_MSVC - // this is needed because MSVC gives different case for drive letters - // for __FILE__ when evaluated in a header and a source file - const int res = stricmp(lhs->m_file, rhs->m_file); -#else // MSVC - const int res = std::strcmp(lhs->m_file, rhs->m_file); -#endif // MSVC - if(res != 0) - return res < 0; - if(lhs->m_line != rhs->m_line) - return lhs->m_line < rhs->m_line; - return lhs->m_template_id < rhs->m_template_id; - } - - // for sorting tests by suite/file/line - bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) { - const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite); - if(res != 0) - return res < 0; - return fileOrderComparator(lhs, rhs); - } - - // for sorting tests by name/suite/file/line - bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) { - const int res = std::strcmp(lhs->m_name, rhs->m_name); - if(res != 0) - return res < 0; - return suiteOrderComparator(lhs, rhs); - } - - // all the registered tests - std::set& getRegisteredTests() { - static std::set data; - return data; - } - -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - HANDLE g_stdoutHandle; - WORD g_origFgAttrs; - WORD g_origBgAttrs; - bool g_attrsInitted = false; - - int colors_init() { - if(!g_attrsInitted) { - g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); - g_attrsInitted = true; - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo(g_stdoutHandle, &csbiInfo); - g_origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | - BACKGROUND_BLUE | BACKGROUND_INTENSITY); - g_origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | - FOREGROUND_BLUE | FOREGROUND_INTENSITY); - } - return 0; - } - - int dumy_init_console_colors = colors_init(); -#endif // DOCTEST_CONFIG_COLORS_WINDOWS - - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - void color_to_stream(std::ostream& s, Color::Enum code) { - ((void)s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS - ((void)code); // for DOCTEST_CONFIG_COLORS_NONE -#ifdef DOCTEST_CONFIG_COLORS_ANSI - if(g_no_colors || - (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false)) - return; - - auto col = ""; - // clang-format off - switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement - case Color::Red: col = "[0;31m"; break; - case Color::Green: col = "[0;32m"; break; - case Color::Blue: col = "[0;34m"; break; - case Color::Cyan: col = "[0;36m"; break; - case Color::Yellow: col = "[0;33m"; break; - case Color::Grey: col = "[1;30m"; break; - case Color::LightGrey: col = "[0;37m"; break; - case Color::BrightRed: col = "[1;31m"; break; - case Color::BrightGreen: col = "[1;32m"; break; - case Color::BrightWhite: col = "[1;37m"; break; - case Color::Bright: // invalid - case Color::None: - case Color::White: - default: col = "[0m"; - } - // clang-format on - s << "\033" << col; -#endif // DOCTEST_CONFIG_COLORS_ANSI - -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - if(g_no_colors || - (isatty(fileno(stdout)) == false && getContextOptions()->force_colors == false)) - return; - -#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(g_stdoutHandle, x | g_origBgAttrs) - - // clang-format off - switch (code) { - case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break; - case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break; - case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break; - case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break; - case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break; - case Color::Grey: DOCTEST_SET_ATTR(0); break; - case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break; - case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break; - case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; - case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::None: - case Color::Bright: // invalid - default: DOCTEST_SET_ATTR(g_origFgAttrs); - } - // clang-format on -#endif // DOCTEST_CONFIG_COLORS_WINDOWS - } - DOCTEST_CLANG_SUPPRESS_WARNING_POP - - std::vector& getExceptionTranslators() { - static std::vector data; - return data; - } - - String translateActiveException() { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - String res; - auto& translators = getExceptionTranslators(); - for(auto& curr : translators) - if(curr->translate(res)) - return res; - // clang-format off - try { - throw; - } catch(std::exception& ex) { - return ex.what(); - } catch(std::string& msg) { - return msg.c_str(); - } catch(const char* msg) { - return msg; - } catch(...) { - return "unknown exception"; - } -// clang-format on -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - return ""; -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - } -} // namespace - -namespace detail { - // used by the macros for registering tests - int regTest(const TestCase& tc) { - getRegisteredTests().insert(tc); - return 0; - } - - // sets the current test suite - int setTestSuite(const TestSuite& ts) { - doctest_detail_test_suite_ns::getCurrentTestSuite() = ts; - return 0; - } - -#ifdef DOCTEST_PLATFORM_MAC - // The following function is taken directly from the following technical note: - // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). - bool isDebuggerActive() { - int mib[4]; - kinfo_proc info; - size_t size; - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - info.kp_proc.p_flag = 0; - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - // Call sysctl. - size = sizeof(info); - if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) { - std::cerr << "\nCall to sysctl failed - unable to determine if debugger is active **\n"; - return false; - } - // We're being debugged if the P_TRACED flag is set. - return ((info.kp_proc.p_flag & P_TRACED) != 0); - } -#elif DOCTEST_MSVC || defined(__MINGW32__) - bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; } -#else - bool isDebuggerActive() { return false; } -#endif // Platform - - void registerExceptionTranslatorImpl(const IExceptionTranslator* et) { - if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) == - getExceptionTranslators().end()) - getExceptionTranslators().push_back(et); - } - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - void toStream(std::ostream* s, char* in) { *s << in; } - void toStream(std::ostream* s, const char* in) { *s << in; } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - void toStream(std::ostream* s, bool in) { *s << std::boolalpha << in << std::noboolalpha; } - void toStream(std::ostream* s, float in) { *s << in; } - void toStream(std::ostream* s, double in) { *s << in; } - void toStream(std::ostream* s, double long in) { *s << in; } - - void toStream(std::ostream* s, char in) { *s << in; } - void toStream(std::ostream* s, char signed in) { *s << in; } - void toStream(std::ostream* s, char unsigned in) { *s << in; } - void toStream(std::ostream* s, int short in) { *s << in; } - void toStream(std::ostream* s, int short unsigned in) { *s << in; } - void toStream(std::ostream* s, int in) { *s << in; } - void toStream(std::ostream* s, int unsigned in) { *s << in; } - void toStream(std::ostream* s, int long in) { *s << in; } - void toStream(std::ostream* s, int long unsigned in) { *s << in; } - void toStream(std::ostream* s, int long long in) { *s << in; } - void toStream(std::ostream* s, int long long unsigned in) { *s << in; } - - DOCTEST_THREAD_LOCAL std::vector g_infoContexts; // for logging with INFO() - - ContextBuilder::ICapture::ICapture() = default; - ContextBuilder::ICapture::~ICapture() = default; - - ContextBuilder::Chunk::Chunk() = default; - ContextBuilder::Chunk::~Chunk() = default; - - ContextBuilder::Node::Node() = default; - ContextBuilder::Node::~Node() = default; - - // steal the contents of the other - acting as a move constructor... - ContextBuilder::ContextBuilder(ContextBuilder& other) - : numCaptures(other.numCaptures) - , head(other.head) - , tail(other.tail) { - other.numCaptures = 0; - other.head = nullptr; - other.tail = nullptr; - memcpy(stackChunks, other.stackChunks, - unsigned(int(sizeof(Chunk)) * DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK)); - } - - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wcast-align") - void ContextBuilder::stringify(std::ostream* s) const { - int curr = 0; - // iterate over small buffer - while(curr < numCaptures && curr < DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK) - reinterpret_cast(stackChunks[curr++].buf)->toStream(s); - // iterate over list - auto curr_elem = head; - while(curr < numCaptures) { - reinterpret_cast(curr_elem->chunk.buf)->toStream(s); - curr_elem = curr_elem->next; - ++curr; - } - } - DOCTEST_GCC_SUPPRESS_WARNING_POP - - ContextBuilder::ContextBuilder() = default; - - ContextBuilder::~ContextBuilder() { - // free the linked list - the ones on the stack are left as-is - // no destructors are called at all - there is no need - while(head) { - auto next = head->next; - delete head; - head = next; - } - } - - ContextScope::ContextScope(ContextBuilder& temp) - : contextBuilder(temp) { - g_infoContexts.push_back(this); - } - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17 - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - ContextScope::~ContextScope() { - if(std::uncaught_exception()) { - std::ostringstream s; - this->stringify(&s); - g_cs->stringifiedContexts.push_back(s.str().c_str()); - } - g_infoContexts.pop_back(); - } - DOCTEST_CLANG_SUPPRESS_WARNING_POP - DOCTEST_GCC_SUPPRESS_WARNING_POP - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - void ContextScope::stringify(std::ostream* s) const { contextBuilder.stringify(s); } -} // namespace detail -namespace { - using namespace detail; - - std::ostream& file_line_to_stream(std::ostream& s, const char* file, int line, - const char* tail = "") { - const auto opt = getContextOptions(); - s << Color::LightGrey << skipPathFromFilename(file) << (opt->gnu_file_line ? ":" : "(") - << (opt->no_line_numbers ? 0 : line) // 0 or the real num depending on the option - << (opt->gnu_file_line ? ":" : "):") << tail; - return s; - } - -#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH) - struct FatalConditionHandler - { - void reset() {} - }; -#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - - void reportFatal(const std::string&); - -#ifdef DOCTEST_PLATFORM_WINDOWS - - struct SignalDefs - { - DWORD id; - const char* name; - }; - // There is no 1-1 mapping between signals and windows exceptions. - // Windows can easily distinguish between SO and SigSegV, - // but SigInt, SigTerm, etc are handled differently. - SignalDefs signalDefs[] = { - {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"}, - {EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"}, - {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"}, - {EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"}, - }; - - struct FatalConditionHandler - { - static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { - for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { - reportFatal(signalDefs[i].name); - } - } - // If its not an exception we care about, pass it along. - // This stops us from eating debugger breaks etc. - return EXCEPTION_CONTINUE_SEARCH; - } - - FatalConditionHandler() { - isSet = true; - // 32k seems enough for doctest to handle stack overflow, - // but the value was found experimentally, so there is no strong guarantee - guaranteeSize = 32 * 1024; - exceptionHandlerHandle = nullptr; - // Register as first handler in current chain - exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - } - - static void reset() { - if(isSet) { - // Unregister handler and restore the old guarantee - RemoveVectoredExceptionHandler(exceptionHandlerHandle); - SetThreadStackGuarantee(&guaranteeSize); - exceptionHandlerHandle = nullptr; - isSet = false; - } - } - - ~FatalConditionHandler() { reset(); } - - private: - static bool isSet; - static ULONG guaranteeSize; - static PVOID exceptionHandlerHandle; - }; - - bool FatalConditionHandler::isSet = false; - ULONG FatalConditionHandler::guaranteeSize = 0; - PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; - -#else // DOCTEST_PLATFORM_WINDOWS - - struct SignalDefs - { - int id; - const char* name; - }; - SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"}, - {SIGILL, "SIGILL - Illegal instruction signal"}, - {SIGFPE, "SIGFPE - Floating point error signal"}, - {SIGSEGV, "SIGSEGV - Segmentation violation signal"}, - {SIGTERM, "SIGTERM - Termination request signal"}, - {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}}; - - struct FatalConditionHandler - { - static bool isSet; - static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)]; - static stack_t oldSigStack; - static char altStackMem[4 * SIGSTKSZ]; - - static void handleSignal(int sig) { - const char* name = ""; - for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - SignalDefs& def = signalDefs[i]; - if(sig == def.id) { - name = def.name; - break; - } - } - reset(); - reportFatal(name); - raise(sig); - } - - FatalConditionHandler() { - isSet = true; - stack_t sigStack; - sigStack.ss_sp = altStackMem; - sigStack.ss_size = sizeof(altStackMem); - sigStack.ss_flags = 0; - sigaltstack(&sigStack, &oldSigStack); - struct sigaction sa = {}; - sa.sa_handler = handleSignal; // NOLINT - sa.sa_flags = SA_ONSTACK; - for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); - } - } - - ~FatalConditionHandler() { reset(); } - static void reset() { - if(isSet) { - // Set signals back to previous values -- hopefully nobody overwrote them in the meantime - for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); - } - // Return the old stack - sigaltstack(&oldSigStack, nullptr); - isSet = false; - } - } - }; - - bool FatalConditionHandler::isSet = false; - struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {}; - stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[] = {}; - -#endif // DOCTEST_PLATFORM_WINDOWS -#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - -} // namespace - -namespace { - using namespace detail; - -#ifdef DOCTEST_PLATFORM_WINDOWS -#define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text) -#else - // TODO: integration with XCode and other IDEs -#define DOCTEST_OUTPUT_DEBUG_STRING(text) -#endif // Platform - - void addAssert(assertType::Enum at) { - if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional - g_cs->numAssertsCurrentTest_atomic++; - } - - void addFailedAssert(assertType::Enum at) { - if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional - g_cs->numAssertsFailedCurrentTest_atomic++; - } - -#if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH) - void reportFatal(const std::string& message) { - g_cs->failure_flags |= TestCaseFailureReason::Crash; - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true}); - - while(g_cs->subcasesCurrentLevel--) - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); - - g_cs->finalizeTestCaseData(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); - } -#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH -} // namespace -namespace detail { - - ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, - const char* exception_type) { - m_test_case = g_cs->currentTest; - m_at = at; - m_file = file; - m_line = line; - m_expr = expr; - m_failed = true; - m_threw = false; - m_threw_as = false; - m_exception_type = exception_type; -#if DOCTEST_MSVC - if(m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC - ++m_expr; -#endif // MSVC - } - - DOCTEST_DEFINE_DEFAULTS(ResultBuilder); - - void ResultBuilder::setResult(const Result& res) { - m_decomp = res.m_decomp; - m_failed = !res.m_passed; - } - - void ResultBuilder::translateException() { - m_threw = true; - m_exception = translateActiveException(); - } - - bool ResultBuilder::log() { - if(m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional - m_failed = !m_threw; - } else if(m_at & assertType::is_throws_as) { //!OCLINT bitwise operator in conditional - m_failed = !m_threw_as; - } else if(m_at & assertType::is_throws_with) { //!OCLINT bitwise operator in conditional - m_failed = m_exception != m_exception_type; - } else if(m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional - m_failed = m_threw; - } - - if(m_exception.size()) - m_exception = String("\"") + m_exception + "\""; - - if(is_running_in_test) { - addAssert(m_at); - DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this); - - if(m_failed) - addFailedAssert(m_at); - } else if(m_failed) { - failed_out_of_a_testing_context(*this); - } - - return m_failed && isDebuggerActive() && - !getContextOptions()->no_breaks; // break into debugger - } - - void ResultBuilder::react() const { - if(m_failed && checkIfShouldThrow(m_at)) - throwException(); - } - - void failed_out_of_a_testing_context(const AssertData& ad) { - if(g_cs->ah) - g_cs->ah(ad); - else - std::abort(); - } - - void decomp_assert(assertType::Enum at, const char* file, int line, const char* expr, - Result result) { - bool failed = !result.m_passed; - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp); - DOCTEST_ASSERT_IN_TESTS(result.m_decomp); - } - - MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) { - m_stream = getTlsOss(); - m_file = file; - m_line = line; - m_severity = severity; - } - - IExceptionTranslator::IExceptionTranslator() = default; - IExceptionTranslator::~IExceptionTranslator() = default; - - bool MessageBuilder::log() { - m_string = getTlsOssResult(); - DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this); - - const bool isWarn = m_severity & assertType::is_warn; - - // warn is just a message in this context so we dont treat it as an assert - if(!isWarn) { - addAssert(m_severity); - addFailedAssert(m_severity); - } - - return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn; // break - } - - void MessageBuilder::react() { - if(m_severity & assertType::is_require) //!OCLINT bitwise operator in conditional - throwException(); - } - - MessageBuilder::~MessageBuilder() = default; -} // namespace detail -namespace { - using namespace detail; - - template - [[noreturn]] void throw_exception(Ex const& e) { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - throw e; -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - std::cerr << "doctest will terminate because it needed to throw an exception.\n" - << "The message was: " << e.what() << '\n'; - std::terminate(); -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - } - -#define DOCTEST_INTERNAL_ERROR(msg) \ - throw_exception(std::logic_error( \ - __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg)) - - // clang-format off - -// ================================================================================================= -// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp -// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. -// ================================================================================================= - - class XmlEncode { - public: - enum ForWhat { ForTextNodes, ForAttributes }; - - XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); - - void encodeTo( std::ostream& os ) const; - - friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); - - private: - std::string m_str; - ForWhat m_forWhat; - }; - - class XmlWriter { - public: - - class ScopedElement { - public: - ScopedElement( XmlWriter* writer ); - - ScopedElement( ScopedElement&& other ) noexcept; - ScopedElement& operator=( ScopedElement&& other ) noexcept; - - ~ScopedElement(); - - ScopedElement& writeText( std::string const& text, bool indent = true ); - - template - ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { - m_writer->writeAttribute( name, attribute ); - return *this; - } - - private: - mutable XmlWriter* m_writer = nullptr; - }; - - XmlWriter( std::ostream& os = std::cout ); - ~XmlWriter(); - - XmlWriter( XmlWriter const& ) = delete; - XmlWriter& operator=( XmlWriter const& ) = delete; - - XmlWriter& startElement( std::string const& name ); - - ScopedElement scopedElement( std::string const& name ); - - XmlWriter& endElement(); - - XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); - - XmlWriter& writeAttribute( std::string const& name, const char* attribute ); - - XmlWriter& writeAttribute( std::string const& name, bool attribute ); - - template - XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { - std::stringstream rss; - rss << attribute; - return writeAttribute( name, rss.str() ); - } - - XmlWriter& writeText( std::string const& text, bool indent = true ); - - //XmlWriter& writeComment( std::string const& text ); - - //void writeStylesheetRef( std::string const& url ); - - //XmlWriter& writeBlankLine(); - - void ensureTagClosed(); - - private: - - void writeDeclaration(); - - void newlineIfNecessary(); - - bool m_tagIsOpen = false; - bool m_needsNewline = false; - std::vector m_tags; - std::string m_indent; - std::ostream& m_os; - }; - -// ================================================================================================= -// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp -// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. -// ================================================================================================= - -using uchar = unsigned char; - -namespace { - - size_t trailingBytes(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return 2; - } - if ((c & 0xF0) == 0xE0) { - return 3; - } - if ((c & 0xF8) == 0xF0) { - return 4; - } - DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - uint32_t headerValue(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return c & 0x1F; - } - if ((c & 0xF0) == 0xE0) { - return c & 0x0F; - } - if ((c & 0xF8) == 0xF0) { - return c & 0x07; - } - DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - void hexEscapeChar(std::ostream& os, unsigned char c) { - std::ios_base::fmtflags f(os.flags()); - os << "\\x" - << std::uppercase << std::hex << std::setfill('0') << std::setw(2) - << static_cast(c); - os.flags(f); - } - -} // anonymous namespace - - XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) - : m_str( str ), - m_forWhat( forWhat ) - {} - - void XmlEncode::encodeTo( std::ostream& os ) const { - // Apostrophe escaping not necessary if we always use " to write attributes - // (see: http://www.w3.org/TR/xml/#syntax) - - for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { - uchar c = m_str[idx]; - switch (c) { - case '<': os << "<"; break; - case '&': os << "&"; break; - - case '>': - // See: http://www.w3.org/TR/xml/#syntax - if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') - os << ">"; - else - os << c; - break; - - case '\"': - if (m_forWhat == ForAttributes) - os << """; - else - os << c; - break; - - default: - // Check for control characters and invalid utf-8 - - // Escape control characters in standard ascii - // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 - if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { - hexEscapeChar(os, c); - break; - } - - // Plain ASCII: Write it to stream - if (c < 0x7F) { - os << c; - break; - } - - // UTF-8 territory - // Check if the encoding is valid and if it is not, hex escape bytes. - // Important: We do not check the exact decoded values for validity, only the encoding format - // First check that this bytes is a valid lead byte: - // This means that it is not encoded as 1111 1XXX - // Or as 10XX XXXX - if (c < 0xC0 || - c >= 0xF8) { - hexEscapeChar(os, c); - break; - } - - auto encBytes = trailingBytes(c); - // Are there enough bytes left to avoid accessing out-of-bounds memory? - if (idx + encBytes - 1 >= m_str.size()) { - hexEscapeChar(os, c); - break; - } - // The header is valid, check data - // The next encBytes bytes must together be a valid utf-8 - // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) - bool valid = true; - uint32_t value = headerValue(c); - for (std::size_t n = 1; n < encBytes; ++n) { - uchar nc = m_str[idx + n]; - valid &= ((nc & 0xC0) == 0x80); - value = (value << 6) | (nc & 0x3F); - } - - if ( - // Wrong bit pattern of following bytes - (!valid) || - // Overlong encodings - (value < 0x80) || - ( value < 0x800 && encBytes > 2) || // removed "0x80 <= value &&" because redundant - (0x800 < value && value < 0x10000 && encBytes > 3) || - // Encoded value out of range - (value >= 0x110000) - ) { - hexEscapeChar(os, c); - break; - } - - // If we got here, this is in fact a valid(ish) utf-8 sequence - for (std::size_t n = 0; n < encBytes; ++n) { - os << m_str[idx + n]; - } - idx += encBytes - 1; - break; - } - } - } - - std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { - xmlEncode.encodeTo( os ); - return os; - } - - XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer ) - : m_writer( writer ) - {} - - XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept - : m_writer( other.m_writer ){ - other.m_writer = nullptr; - } - XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept { - if ( m_writer ) { - m_writer->endElement(); - } - m_writer = other.m_writer; - other.m_writer = nullptr; - return *this; - } - - - XmlWriter::ScopedElement::~ScopedElement() { - if( m_writer ) - m_writer->endElement(); - } - - XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) { - m_writer->writeText( text, indent ); - return *this; - } - - XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) - { - writeDeclaration(); - } - - XmlWriter::~XmlWriter() { - while( !m_tags.empty() ) - endElement(); - } - - XmlWriter& XmlWriter::startElement( std::string const& name ) { - ensureTagClosed(); - newlineIfNecessary(); - m_os << m_indent << '<' << name; - m_tags.push_back( name ); - m_indent += " "; - m_tagIsOpen = true; - return *this; - } - - XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) { - ScopedElement scoped( this ); - startElement( name ); - return scoped; - } - - XmlWriter& XmlWriter::endElement() { - newlineIfNecessary(); - m_indent = m_indent.substr( 0, m_indent.size()-2 ); - if( m_tagIsOpen ) { - m_os << "/>"; - m_tagIsOpen = false; - } - else { - m_os << m_indent << ""; - } - m_os << std::endl; - m_tags.pop_back(); - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { - if( !name.empty() && !attribute.empty() ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) { - if( !name.empty() && attribute && attribute[0] != '\0' ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { - m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) { - if( !text.empty() ){ - bool tagWasOpen = m_tagIsOpen; - ensureTagClosed(); - if( tagWasOpen && indent ) - m_os << m_indent; - m_os << XmlEncode( text ); - m_needsNewline = true; - } - return *this; - } - - //XmlWriter& XmlWriter::writeComment( std::string const& text ) { - // ensureTagClosed(); - // m_os << m_indent << ""; - // m_needsNewline = true; - // return *this; - //} - - //void XmlWriter::writeStylesheetRef( std::string const& url ) { - // m_os << "\n"; - //} - - //XmlWriter& XmlWriter::writeBlankLine() { - // ensureTagClosed(); - // m_os << '\n'; - // return *this; - //} - - void XmlWriter::ensureTagClosed() { - if( m_tagIsOpen ) { - m_os << ">" << std::endl; - m_tagIsOpen = false; - } - } - - void XmlWriter::writeDeclaration() { - m_os << "\n"; - } - - void XmlWriter::newlineIfNecessary() { - if( m_needsNewline ) { - m_os << std::endl; - m_needsNewline = false; - } - } - -// ================================================================================================= -// End of copy-pasted code from Catch -// ================================================================================================= - - // clang-format on - - struct XmlReporter : public IReporter - { - XmlWriter xml; - std::mutex mutex; - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc = nullptr; - - XmlReporter(const ContextOptions& co) - : xml(*co.cout) - , opt(co) {} - - void log_contexts() { - int num_contexts = get_num_active_contexts(); - if(num_contexts) { - auto contexts = get_active_contexts(); - std::stringstream ss; - for(int i = 0; i < num_contexts; ++i) { - contexts[i]->stringify(&ss); - xml.scopedElement("Info").writeText(ss.str()); - ss.str(""); - } - } - } - - unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; } - - void test_case_start_impl(const TestCaseData& in) { - bool open_ts_tag = false; - if(tc != nullptr) { // we have already opened a test suite - if(strcmp(tc->m_test_suite, in.m_test_suite) != 0) { - xml.endElement(); - open_ts_tag = true; - } - } - else { - open_ts_tag = true; // first test case ==> first test suite - } - - if(open_ts_tag) { - xml.startElement("TestSuite"); - xml.writeAttribute("name", in.m_test_suite); - } - - tc = ∈ - xml.startElement("TestCase") - .writeAttribute("name", in.m_name) - .writeAttribute("filename", skipPathFromFilename(in.m_file)) - .writeAttribute("line", line(in.m_line)) - .writeAttribute("description", in.m_description); - - if(Approx(in.m_timeout) != 0) - xml.writeAttribute("timeout", in.m_timeout); - if(in.m_may_fail) - xml.writeAttribute("may_fail", true); - if(in.m_should_fail) - xml.writeAttribute("should_fail", true); - } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData& in) override { - test_run_start(); - if(opt.list_reporters) { - for(auto& curr : getReporters()) - xml.scopedElement("Reporter") - .writeAttribute("priority", curr.first.first) - .writeAttribute("name", curr.first.second); - } else if(opt.count || opt.list_test_cases) { - for(unsigned i = 0; i < in.num_data; ++i) - xml.scopedElement("TestCase").writeAttribute("name", in.data[i]); - xml.scopedElement("OverallResultsTestCases") - .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); - } else if(opt.list_test_suites) { - for(unsigned i = 0; i < in.num_data; ++i) - xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]); - xml.scopedElement("OverallResultsTestCases") - .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); - xml.scopedElement("OverallResultsTestSuites") - .writeAttribute("unskipped", in.run_stats->numTestSuitesPassingFilters); - } - xml.endElement(); - } - - void test_run_start() override { - // remove .exe extension - mainly to have the same output on UNIX and Windows - std::string binary_name = skipPathFromFilename(opt.binary_name.c_str()); -#ifdef DOCTEST_PLATFORM_WINDOWS - if(binary_name.rfind(".exe") != std::string::npos) - binary_name = binary_name.substr(0, binary_name.length() - 4); -#endif // DOCTEST_PLATFORM_WINDOWS - - xml.startElement("doctest").writeAttribute("binary", binary_name); - if(opt.no_version == false) - xml.writeAttribute("version", DOCTEST_VERSION_STR); - - // only the consequential ones (TODO: filters) - xml.scopedElement("Options") - .writeAttribute("order_by", opt.order_by.c_str()) - .writeAttribute("rand_seed", opt.rand_seed) - .writeAttribute("first", opt.first) - .writeAttribute("last", opt.last) - .writeAttribute("abort_after", opt.abort_after) - .writeAttribute("subcase_filter_levels", opt.subcase_filter_levels) - .writeAttribute("case_sensitive", opt.case_sensitive) - .writeAttribute("no_throw", opt.no_throw) - .writeAttribute("no_skip", opt.no_skip); - } - - void test_run_end(const TestRunStats& p) override { - if(tc) // the TestSuite tag - only if there has been at least 1 test case - xml.endElement(); - - xml.scopedElement("OverallResultsAsserts") - .writeAttribute("successes", p.numAsserts - p.numAssertsFailed) - .writeAttribute("failures", p.numAssertsFailed); - - xml.startElement("OverallResultsTestCases") - .writeAttribute("successes", - p.numTestCasesPassingFilters - p.numTestCasesFailed) - .writeAttribute("failures", p.numTestCasesFailed); - if(opt.no_skipped_summary == false) - xml.writeAttribute("skipped", p.numTestCases - p.numTestCasesPassingFilters); - xml.endElement(); - - xml.endElement(); - } - - void test_case_start(const TestCaseData& in) override { - test_case_start_impl(in); - xml.ensureTagClosed(); - } - - void test_case_end(const CurrentTestCaseStats& st) override { - xml.startElement("OverallResultsAsserts") - .writeAttribute("successes", - st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest) - .writeAttribute("failures", st.numAssertsFailedCurrentTest); - if(opt.duration) - xml.writeAttribute("duration", st.seconds); - if(tc->m_expected_failures) - xml.writeAttribute("expected_failures", tc->m_expected_failures); - xml.endElement(); - - xml.endElement(); - } - - void test_case_exception(const TestCaseException& e) override { - xml.scopedElement("Exception") - .writeAttribute("crash", e.is_crash) - .writeText(e.error_string.c_str()); - } - - void subcase_start(const SubcaseSignature& in) override { - xml.startElement("SubCase") - .writeAttribute("name", in.m_name) - .writeAttribute("filename", skipPathFromFilename(in.m_file)) - .writeAttribute("line", line(in.m_line)); - } - - void subcase_end() override { xml.endElement(); } - - void log_assert(const AssertData& rb) override { - if(!rb.m_failed && !opt.success) - return; - - std::lock_guard lock(mutex); - - xml.startElement("Expression") - .writeAttribute("success", !rb.m_failed) - .writeAttribute("type", assertString(rb.m_at)) - .writeAttribute("filename", skipPathFromFilename(rb.m_file)) - .writeAttribute("line", line(rb.m_line)); - - xml.scopedElement("Original").writeText(rb.m_expr); - - if(rb.m_threw) - xml.scopedElement("Exception").writeText(rb.m_exception.c_str()); - - if(rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) { - xml.scopedElement("ExpectedException").writeText(rb.m_exception_type); - } else if((rb.m_at & assertType::is_normal) && !rb.m_threw) { - xml.scopedElement("Expanded").writeText(rb.m_decomp.c_str()); - } - - log_contexts(); - - xml.endElement(); - } - - void log_message(const MessageData& mb) override { - std::lock_guard lock(mutex); - - xml.startElement("Message") - .writeAttribute("type", failureString(mb.m_severity)) - .writeAttribute("filename", skipPathFromFilename(mb.m_file)) - .writeAttribute("line", line(mb.m_line)); - - xml.scopedElement("Text").writeText(mb.m_string.c_str()); - - log_contexts(); - - xml.endElement(); - } - - void test_case_skipped(const TestCaseData& in) override { - if(opt.no_skipped_summary == false) { - test_case_start_impl(in); - xml.writeAttribute("skipped", "true"); - xml.endElement(); - } - } - }; - - DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter); - - struct Whitespace - { - int nrSpaces; - explicit Whitespace(int nr) - : nrSpaces(nr) {} - }; - - std::ostream& operator<<(std::ostream& out, const Whitespace& ws) { - if(ws.nrSpaces != 0) - out << std::setw(ws.nrSpaces) << ' '; - return out; - } - - struct ConsoleReporter : public IReporter - { - std::ostream& s; - bool hasLoggedCurrentTestStart; - std::vector subcasesStack; - std::mutex mutex; - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc; - - ConsoleReporter(const ContextOptions& co) - : s(*co.cout) - , opt(co) {} - - ConsoleReporter(const ContextOptions& co, std::ostream& ostr) - : s(ostr) - , opt(co) {} - - // ========================================================================================= - // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF THE INTERFACE - // ========================================================================================= - - void separator_to_stream() { - s << Color::Yellow - << "===============================================================================" - "\n"; - } - - const char* getSuccessOrFailString(bool success, assertType::Enum at, - const char* success_str) { - if(success) - return success_str; - return failureString(at); - } - - Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) { - return success ? Color::BrightGreen : - (at & assertType::is_warn) ? Color::Yellow : Color::Red; - } - - void successOrFailColoredStringToStream(bool success, assertType::Enum at, - const char* success_str = "SUCCESS") { - s << getSuccessOrFailColor(success, at) - << getSuccessOrFailString(success, at, success_str) << ": "; - } - - void log_contexts() { - int num_contexts = get_num_active_contexts(); - if(num_contexts) { - auto contexts = get_active_contexts(); - - s << Color::None << " logged: "; - for(int i = 0; i < num_contexts; ++i) { - s << (i == 0 ? "" : " "); - contexts[i]->stringify(&s); - s << "\n"; - } - } - - s << "\n"; - } - - void logTestStart() { - if(hasLoggedCurrentTestStart) - return; - - separator_to_stream(); - file_line_to_stream(s, tc->m_file, tc->m_line, "\n"); - if(tc->m_description) - s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n"; - if(tc->m_test_suite && tc->m_test_suite[0] != '\0') - s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n"; - if(strncmp(tc->m_name, " Scenario:", 11) != 0) - s << Color::None << "TEST CASE: "; - s << Color::None << tc->m_name << "\n"; - - for(auto& curr : subcasesStack) - if(curr.m_name[0] != '\0') - s << " " << curr.m_name << "\n"; - - s << "\n"; - - hasLoggedCurrentTestStart = true; - } - - void printVersion() { - if(opt.no_version == false) - s << Color::Cyan << "[doctest] " << Color::None << "doctest version is \"" - << DOCTEST_VERSION_STR << "\"\n"; - } - - void printIntro() { - printVersion(); - s << Color::Cyan << "[doctest] " << Color::None - << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\" for options\n"; - } - - void printHelp() { - int sizePrefixDisplay = static_cast(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY)); - printVersion(); - // clang-format off - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n"; - s << Color::Cyan << "[doctest] " << Color::None; - s << "filter values: \"str1,str2,str3\" (comma separated strings)\n"; - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "filters use wildcards for matching strings\n"; - s << Color::Cyan << "[doctest] " << Color::None; - s << "something passes a filter if any of the strings in a filter matches\n"; -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX "\" PREFIX!!!\n"; -#endif - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "Query flags - the program quits after them. Available:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY "h " - << Whitespace(sizePrefixDisplay*0) << "prints this message\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "version " - << Whitespace(sizePrefixDisplay*1) << "prints the version\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "count " - << Whitespace(sizePrefixDisplay*1) << "prints the number of matching tests\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-cases " - << Whitespace(sizePrefixDisplay*1) << "lists all matching tests by name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-suites " - << Whitespace(sizePrefixDisplay*1) << "lists all matching test suites\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-reporters " - << Whitespace(sizePrefixDisplay*1) << "lists all registered reporters\n\n"; - // ================================================================================== << 79 - s << Color::Cyan << "[doctest] " << Color::None; - s << "The available / options/filters are:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their file\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their file\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their test suite\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their test suite\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase= " - << Whitespace(sizePrefixDisplay*1) << "filters subcases by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT subcases by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "reporters= " - << Whitespace(sizePrefixDisplay*1) << "reporters to use (console is default)\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "out= " - << Whitespace(sizePrefixDisplay*1) << "output filename\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by= " - << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n"; - s << Whitespace(sizePrefixDisplay*3) << " - by [file/suite/name/rand]\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed= " - << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first= " - << Whitespace(sizePrefixDisplay*1) << "the first test passing the filters to\n"; - s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "last= " - << Whitespace(sizePrefixDisplay*1) << "the last test passing the filters to\n"; - s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "abort-after= " - << Whitespace(sizePrefixDisplay*1) << "stop after failed assertions\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-filter-levels= " - << Whitespace(sizePrefixDisplay*1) << "apply filters for the first levels\n"; - s << Color::Cyan << "\n[doctest] " << Color::None; - s << "Bool options - can be used like flags and true is assumed. Available:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "success= " - << Whitespace(sizePrefixDisplay*1) << "include successful assertions in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "case-sensitive= " - << Whitespace(sizePrefixDisplay*1) << "filters being treated as case sensitive\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "exit= " - << Whitespace(sizePrefixDisplay*1) << "exits after the tests finish\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "duration= " - << Whitespace(sizePrefixDisplay*1) << "prints the time duration of each test\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw= " - << Whitespace(sizePrefixDisplay*1) << "skips exceptions-related assert checks\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode= " - << Whitespace(sizePrefixDisplay*1) << "returns (or exits) always with success\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run= " - << Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest operations\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version= " - << Whitespace(sizePrefixDisplay*1) << "omit the framework version in the output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors= " - << Whitespace(sizePrefixDisplay*1) << "disables colors in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "force-colors= " - << Whitespace(sizePrefixDisplay*1) << "use colors even when not in a tty\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-breaks= " - << Whitespace(sizePrefixDisplay*1) << "disables breakpoints in debuggers\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-skip= " - << Whitespace(sizePrefixDisplay*1) << "don't skip test cases marked as skip\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "gnu-file-line= " - << Whitespace(sizePrefixDisplay*1) << ":n: vs (n): for line numbers in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-path-filenames= " - << Whitespace(sizePrefixDisplay*1) << "only filenames and no paths in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-line-numbers= " - << Whitespace(sizePrefixDisplay*1) << "0 instead of real line numbers in output\n"; - // ================================================================================== << 79 - // clang-format on - - s << Color::Cyan << "\n[doctest] " << Color::None; - s << "for more information visit the project documentation\n\n"; - } - - void printRegisteredReporters() { - printVersion(); - s << Color::Cyan << "[doctest] " << Color::None << "listing all registered reporters\n"; - for(auto& curr : getReporters()) - s << "priority: " << std::setw(5) << curr.first.first - << " name: " << curr.first.second << "\n"; - } - - void list_query_results() { - separator_to_stream(); - if(opt.count || opt.list_test_cases) { - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - } else if(opt.list_test_suites) { - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "test suites with unskipped test cases passing the current filters: " - << g_cs->numTestSuitesPassingFilters << "\n"; - } - } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData& in) override { - if(opt.version) { - printVersion(); - } else if(opt.help) { - printHelp(); - } else if(opt.list_reporters) { - printRegisteredReporters(); - } else if(opt.count || opt.list_test_cases) { - if(opt.list_test_cases) { - s << Color::Cyan << "[doctest] " << Color::None - << "listing all test case names\n"; - separator_to_stream(); - } - - for(unsigned i = 0; i < in.num_data; ++i) - s << Color::None << in.data[i] << "\n"; - - separator_to_stream(); - - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - - } else if(opt.list_test_suites) { - s << Color::Cyan << "[doctest] " << Color::None << "listing all test suites\n"; - separator_to_stream(); - - for(unsigned i = 0; i < in.num_data; ++i) - s << Color::None << in.data[i] << "\n"; - - separator_to_stream(); - - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "test suites with unskipped test cases passing the current filters: " - << g_cs->numTestSuitesPassingFilters << "\n"; - } - } - - void test_run_start() override { printIntro(); } - - void test_run_end(const TestRunStats& p) override { - separator_to_stream(); - - const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0; - s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(6) - << p.numTestCasesPassingFilters << " | " - << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None : - Color::Green) - << std::setw(6) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed" - << Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None) - << std::setw(6) << p.numTestCasesFailed << " failed" << Color::None << " | "; - if(opt.no_skipped_summary == false) { - const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters; - s << (numSkipped == 0 ? Color::None : Color::Yellow) << std::setw(6) << numSkipped - << " skipped" << Color::None; - } - s << "\n"; - s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(6) - << p.numAsserts << " | " - << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green) - << std::setw(6) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None - << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(6) - << p.numAssertsFailed << " failed" << Color::None << " |\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green) - << ((p.numTestCasesFailed > 0) ? "FAILURE!" : "SUCCESS!") << Color::None << std::endl; - } - - void test_case_start(const TestCaseData& in) override { - hasLoggedCurrentTestStart = false; - tc = ∈ - } - - void test_case_end(const CurrentTestCaseStats& st) override { - // log the preamble of the test case only if there is something - // else to print - something other than that an assert has failed - if(opt.duration || - (st.failure_flags && st.failure_flags != TestCaseFailureReason::AssertFailure)) - logTestStart(); - - if(opt.duration) - s << Color::None << std::setprecision(6) << std::fixed << st.seconds - << " s: " << tc->m_name << "\n"; - - if(st.failure_flags & TestCaseFailureReason::Timeout) - s << Color::Red << "Test case exceeded time limit of " << std::setprecision(6) - << std::fixed << tc->m_timeout << "!\n"; - - if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) { - s << Color::Red << "Should have failed but didn't! Marking it as failed!\n"; - } else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) { - s << Color::Yellow << "Failed as expected so marking it as not failed\n"; - } else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) { - s << Color::Yellow << "Allowed to fail so marking it as not failed\n"; - } else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) { - s << Color::Red << "Didn't fail exactly " << tc->m_expected_failures - << " times so marking it as failed!\n"; - } else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) { - s << Color::Yellow << "Failed exactly " << tc->m_expected_failures - << " times as expected so marking it as not failed!\n"; - } - if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) { - s << Color::Red << "Aborting - too many failed asserts!\n"; - } - s << Color::None; - } - - void test_case_exception(const TestCaseException& e) override { - logTestStart(); - - file_line_to_stream(s, tc->m_file, tc->m_line, " "); - successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require : - assertType::is_check); - s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ") - << Color::Cyan << e.error_string << "\n"; - - int num_stringified_contexts = get_num_stringified_contexts(); - if(num_stringified_contexts) { - auto stringified_contexts = get_stringified_contexts(); - s << Color::None << " logged: "; - for(int i = num_stringified_contexts - 1; i >= 0; --i) { - s << (i == num_stringified_contexts - 1 ? "" : " ") - << stringified_contexts[i] << "\n"; - } - } - s << "\n" << Color::None; - } - - void subcase_start(const SubcaseSignature& subc) override { - subcasesStack.push_back(subc); - hasLoggedCurrentTestStart = false; - } - - void subcase_end() override { - subcasesStack.pop_back(); - hasLoggedCurrentTestStart = false; - } - - void log_assert(const AssertData& rb) override { - if(!rb.m_failed && !opt.success) - return; - - std::lock_guard lock(mutex); - - logTestStart(); - - file_line_to_stream(s, rb.m_file, rb.m_line, " "); - successOrFailColoredStringToStream(!rb.m_failed, rb.m_at); - if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) == - 0) //!OCLINT bitwise operator in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) " - << Color::None; - - if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional - s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n"; - } else if(rb.m_at & - assertType::is_throws_as) { //!OCLINT bitwise operator in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", " - << rb.m_exception_type << " ) " << Color::None - << (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" : - "threw a DIFFERENT exception: ") : - "did NOT throw at all!") - << Color::Cyan << rb.m_exception << "\n"; - } else if(rb.m_at & - assertType::is_throws_with) { //!OCLINT bitwise operator in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \"" - << rb.m_exception_type << "\" ) " << Color::None - << (rb.m_threw ? (!rb.m_failed ? "threw as expected!" : - "threw a DIFFERENT exception: ") : - "did NOT throw at all!") - << Color::Cyan << rb.m_exception << "\n"; - } else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional - s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan - << rb.m_exception << "\n"; - } else { - s << (rb.m_threw ? "THREW exception: " : - (!rb.m_failed ? "is correct!\n" : "is NOT correct!\n")); - if(rb.m_threw) - s << rb.m_exception << "\n"; - else - s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n"; - } - - log_contexts(); - } - - void log_message(const MessageData& mb) override { - std::lock_guard lock(mutex); - - logTestStart(); - - file_line_to_stream(s, mb.m_file, mb.m_line, " "); - s << getSuccessOrFailColor(false, mb.m_severity) - << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity, - "MESSAGE") << ": "; - s << Color::None << mb.m_string << "\n"; - log_contexts(); - } - - void test_case_skipped(const TestCaseData&) override {} - }; - - DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter); - -#ifdef DOCTEST_PLATFORM_WINDOWS - struct DebugOutputWindowReporter : public ConsoleReporter - { - DOCTEST_THREAD_LOCAL static std::ostringstream oss; - - DebugOutputWindowReporter(const ContextOptions& co) - : ConsoleReporter(co, oss) {} - -#define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \ - void func(type arg) override { \ - bool with_col = g_no_colors; \ - g_no_colors = false; \ - ConsoleReporter::func(arg); \ - DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \ - oss.str(""); \ - g_no_colors = with_col; \ - } - - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, DOCTEST_EMPTY, DOCTEST_EMPTY) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, const TestCaseData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, const CurrentTestCaseStats&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, const TestCaseException&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, const SubcaseSignature&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, DOCTEST_EMPTY, DOCTEST_EMPTY) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, const TestCaseData&, in) - }; - - DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss; -#endif // DOCTEST_PLATFORM_WINDOWS - - // the implementation of parseFlag() - bool parseFlagImpl(int argc, const char* const* argv, const char* pattern) { - for(int i = argc - 1; i >= 0; --i) { - auto temp = std::strstr(argv[i], pattern); - if(temp && strlen(temp) == strlen(pattern)) { - // eliminate strings in which the chars before the option are not '-' - bool noBadCharsFound = true; //!OCLINT prefer early exits and continue - while(temp != argv[i]) { - if(*--temp != '-') { - noBadCharsFound = false; - break; - } - } - if(noBadCharsFound && argv[i][0] == '-') - return true; - } - } - return false; - } - - // locates a flag on the command line - bool parseFlag(int argc, const char* const* argv, const char* pattern) { -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - // offset (normally 3 for "dt-") to skip prefix - if(parseFlagImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX))) - return true; -#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - return parseFlagImpl(argc, argv, pattern); - } - - // the implementation of parseOption() - bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String& res) { - for(int i = argc - 1; i >= 0; --i) { - auto temp = std::strstr(argv[i], pattern); - if(temp) { //!OCLINT prefer early exits and continue - // eliminate matches in which the chars before the option are not '-' - bool noBadCharsFound = true; - auto curr = argv[i]; - while(curr != temp) { - if(*curr++ != '-') { - noBadCharsFound = false; - break; - } - } - if(noBadCharsFound && argv[i][0] == '-') { - temp += strlen(pattern); - const unsigned len = strlen(temp); - if(len) { - res = temp; - return true; - } - } - } - } - return false; - } - - // parses an option and returns the string after the '=' character - bool parseOption(int argc, const char* const* argv, const char* pattern, String& res, - const String& defaultVal = String()) { - res = defaultVal; -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - // offset (normally 3 for "dt-") to skip prefix - if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), res)) - return true; -#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - return parseOptionImpl(argc, argv, pattern, res); - } - - // parses a comma separated list of words after a pattern in one of the arguments in argv - bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern, - std::vector& res) { - String filtersString; - if(parseOption(argc, argv, pattern, filtersString)) { - // tokenize with "," as a separator - // cppcheck-suppress strtokCalled - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - auto pch = std::strtok(filtersString.c_str(), ","); // modifies the string - while(pch != nullptr) { - if(strlen(pch)) - res.push_back(pch); - // uses the strtok() internal state to go to the next token - // cppcheck-suppress strtokCalled - pch = std::strtok(nullptr, ","); - } - DOCTEST_CLANG_SUPPRESS_WARNING_POP - return true; - } - return false; - } - - enum optionType - { - option_bool, - option_int - }; - - // parses an int/bool option from the command line - bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type, - int& res) { - String parsedValue; - if(!parseOption(argc, argv, pattern, parsedValue)) - return false; - - if(type == 0) { - // boolean - const char positive[][5] = {"1", "true", "on", "yes"}; // 5 - strlen("true") + 1 - const char negative[][6] = {"0", "false", "off", "no"}; // 6 - strlen("false") + 1 - - // if the value matches any of the positive/negative possibilities - for(unsigned i = 0; i < 4; i++) { - if(parsedValue.compare(positive[i], true) == 0) { - res = 1; //!OCLINT parameter reassignment - return true; - } - if(parsedValue.compare(negative[i], true) == 0) { - res = 0; //!OCLINT parameter reassignment - return true; - } - } - } else { - // integer - // TODO: change this to use std::stoi or something else! currently it uses undefined behavior - assumes '0' on failed parse... - int theInt = std::atoi(parsedValue.c_str()); // NOLINT - if(theInt != 0) { - res = theInt; //!OCLINT parameter reassignment - return true; - } - } - return false; - } -} // namespace - -Context::Context(int argc, const char* const* argv) - : p(new detail::ContextState) { - parseArgs(argc, argv, true); - if(argc) - p->binary_name = argv[0]; -} - -Context::~Context() { - if(g_cs == p) - g_cs = nullptr; - delete p; -} - -void Context::applyCommandLine(int argc, const char* const* argv) { - parseArgs(argc, argv); - if(argc) - p->binary_name = argv[0]; -} - -// parses args -void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { - using namespace detail; - - // clang-format off - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file=", p->filters[0]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sf=", p->filters[0]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file-exclude=",p->filters[1]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sfe=", p->filters[1]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite=", p->filters[2]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ts=", p->filters[2]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite-exclude=", p->filters[3]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tse=", p->filters[3]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case=", p->filters[4]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tc=", p->filters[4]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case-exclude=", p->filters[5]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tce=", p->filters[5]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase=", p->filters[6]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sc=", p->filters[6]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase-exclude=", p->filters[7]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sce=", p->filters[7]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "reporters=", p->filters[8]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "r=", p->filters[8]); - // clang-format on - - int intRes = 0; - String strRes; - -#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \ - if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \ - parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \ - p->var = !!intRes; \ - else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \ - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \ - p->var = true; \ - else if(withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \ - if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_int, intRes) || \ - parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_int, intRes)) \ - p->var = intRes; \ - else if(withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \ - if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", strRes, default) || \ - parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", strRes, default) || \ - withDefaults) \ - p->var = strRes - - // clang-format off - DOCTEST_PARSE_STR_OPTION("out", "o", out, ""); - DOCTEST_PARSE_STR_OPTION("order-by", "ob", order_by, "file"); - DOCTEST_PARSE_INT_OPTION("rand-seed", "rs", rand_seed, 0); - - DOCTEST_PARSE_INT_OPTION("first", "f", first, 0); - DOCTEST_PARSE_INT_OPTION("last", "l", last, UINT_MAX); - - DOCTEST_PARSE_INT_OPTION("abort-after", "aa", abort_after, 0); - DOCTEST_PARSE_INT_OPTION("subcase-filter-levels", "scfl", subcase_filter_levels, INT_MAX); - - DOCTEST_PARSE_AS_BOOL_OR_FLAG("success", "s", success, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-breaks", "nb", no_breaks, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skip", "ns", no_skip, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC)); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false); - // clang-format on - - if(withDefaults) { - p->help = false; - p->version = false; - p->count = false; - p->list_test_cases = false; - p->list_test_suites = false; - p->list_reporters = false; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "help") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "h") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "?")) { - p->help = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "version") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "v")) { - p->version = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "count") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "c")) { - p->count = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-cases") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ltc")) { - p->list_test_cases = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-suites") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lts")) { - p->list_test_suites = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-reporters") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lr")) { - p->list_reporters = true; - p->exit = true; - } -} - -// allows the user to add procedurally to the filters from the command line -void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); } - -// allows the user to clear all filters from the command line -void Context::clearFilters() { - for(auto& curr : p->filters) - curr.clear(); -} - -// allows the user to override procedurally the int/bool options from the command line -void Context::setOption(const char* option, int value) { - setOption(option, toString(value).c_str()); -} - -// allows the user to override procedurally the string options from the command line -void Context::setOption(const char* option, const char* value) { - auto argv = String("-") + option + "=" + value; - auto lvalue = argv.c_str(); - parseArgs(1, &lvalue); -} - -// users should query this in their main() and exit the program if true -bool Context::shouldExit() { return p->exit; } - -void Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; } - -void Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; } - -// the main function that does all the filtering and test running -int Context::run() { - using namespace detail; - - // save the old context state in case such was setup - for using asserts out of a testing context - auto old_cs = g_cs; - // this is the current contest - g_cs = p; - is_running_in_test = true; - - g_no_colors = p->no_colors; - p->resetRunData(); - - // stdout by default - p->cout = &std::cout; - p->cerr = &std::cerr; - - // or to a file if specified - std::fstream fstr; - if(p->out.size()) { - fstr.open(p->out.c_str(), std::fstream::out); - p->cout = &fstr; - } - - auto cleanup_and_return = [&]() { - if(fstr.is_open()) - fstr.close(); - - // restore context - g_cs = old_cs; - is_running_in_test = false; - - // we have to free the reporters which were allocated when the run started - for(auto& curr : p->reporters_currently_used) - delete curr; - p->reporters_currently_used.clear(); - - if(p->numTestCasesFailed && !p->no_exitcode) - return EXIT_FAILURE; - return EXIT_SUCCESS; - }; - - DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter); - - // setup default reporter if none is given through the command line - if(p->filters[8].empty()) - p->filters[8].push_back("console"); - - // check to see if any of the registered reporters has been selected - for(auto& curr : getReporters()) { - if(matchesAny(curr.first.second.c_str(), p->filters[8], false, p->case_sensitive)) - p->reporters_currently_used.push_back(curr.second(*g_cs)); - } - -#ifdef DOCTEST_PLATFORM_WINDOWS - if(isDebuggerActive()) - p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs)); -#endif // DOCTEST_PLATFORM_WINDOWS - - // handle version, help and no_run - if(p->no_run || p->version || p->help || p->list_reporters) { - DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData()); - - return cleanup_and_return(); - } - - std::vector testArray; - for(auto& curr : getRegisteredTests()) - testArray.push_back(&curr); - p->numTestCases = testArray.size(); - - // sort the collected records - if(!testArray.empty()) { - if(p->order_by.compare("file", true) == 0) { - std::sort(testArray.begin(), testArray.end(), fileOrderComparator); - } else if(p->order_by.compare("suite", true) == 0) { - std::sort(testArray.begin(), testArray.end(), suiteOrderComparator); - } else if(p->order_by.compare("name", true) == 0) { - std::sort(testArray.begin(), testArray.end(), nameOrderComparator); - } else if(p->order_by.compare("rand", true) == 0) { - std::srand(p->rand_seed); - - // random_shuffle implementation - const auto first = &testArray[0]; - for(size_t i = testArray.size() - 1; i > 0; --i) { - int idxToSwap = std::rand() % (i + 1); // NOLINT - - const auto temp = first[i]; - - first[i] = first[idxToSwap]; - first[idxToSwap] = temp; - } - } - } - - std::set testSuitesPassingFilt; - - bool query_mode = p->count || p->list_test_cases || p->list_test_suites; - std::vector queryResults; - - if(!query_mode) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY); - - // invoke the registered functions if they match the filter criteria (or just count them) - for(auto& curr : testArray) { - const auto& tc = *curr; - - bool skip_me = false; - if(tc.m_skip && !p->no_skip) - skip_me = true; - - if(!matchesAny(tc.m_file, p->filters[0], true, p->case_sensitive)) - skip_me = true; - if(matchesAny(tc.m_file, p->filters[1], false, p->case_sensitive)) - skip_me = true; - if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive)) - skip_me = true; - if(matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive)) - skip_me = true; - if(!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive)) - skip_me = true; - if(matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive)) - skip_me = true; - - if(!skip_me) - p->numTestCasesPassingFilters++; - - // skip the test if it is not in the execution range - if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) || - (p->first > p->numTestCasesPassingFilters)) - skip_me = true; - - if(skip_me) { - if(!query_mode) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc); - continue; - } - - // do not execute the test if we are to only count the number of filter passing tests - if(p->count) - continue; - - // print the name of the test and don't execute it - if(p->list_test_cases) { - queryResults.push_back(tc.m_name); - continue; - } - - // print the name of the test suite if not done already and don't execute it - if(p->list_test_suites) { - if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') { - queryResults.push_back(tc.m_test_suite); - testSuitesPassingFilt.insert(tc.m_test_suite); - p->numTestSuitesPassingFilters++; - } - continue; - } - - // execute the test if it passes all the filtering - { - p->currentTest = &tc; - - p->failure_flags = TestCaseFailureReason::None; - p->seconds = 0; - - // reset atomic counters - p->numAssertsFailedCurrentTest_atomic = 0; - p->numAssertsCurrentTest_atomic = 0; - - p->subcasesPassed.clear(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc); - - p->timer.start(); - - do { - // reset some of the fields for subcases (except for the set of fully passed ones) - p->should_reenter = false; - p->subcasesCurrentLevel = 0; - p->subcasesEnteredLevels.clear(); - - // reset stuff for logging with INFO() - p->stringifiedContexts.clear(); - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - FatalConditionHandler fatalConditionHandler; // Handle signals - // execute the test - tc.m_test(); - fatalConditionHandler.reset(); -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - } catch(const TestFailureException&) { - p->failure_flags |= TestCaseFailureReason::AssertFailure; - } catch(...) { - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, - {translateActiveException(), false}); - p->failure_flags |= TestCaseFailureReason::Exception; - } -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - - // exit this loop if enough assertions have failed - even if there are more subcases - if(p->abort_after > 0 && - p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) { - p->should_reenter = false; - p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts; - } - } while(p->should_reenter == true); - - p->finalizeTestCaseData(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); - - p->currentTest = nullptr; - - // stop executing tests if enough assertions have failed - if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after) - break; - } - } - - if(!query_mode) { - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); - } else { - QueryData qdata; - qdata.run_stats = g_cs; - qdata.data = queryResults.data(); - qdata.num_data = unsigned(queryResults.size()); - DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata); - } - - return cleanup_and_return(); -} - -DOCTEST_DEFINE_DEFAULTS(CurrentTestCaseStats); - -DOCTEST_DEFINE_DEFAULTS(TestRunStats); - -IReporter::~IReporter() = default; - -int IReporter::get_num_active_contexts() { return detail::g_infoContexts.size(); } -const IContextScope* const* IReporter::get_active_contexts() { - return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr; -} - -int IReporter::get_num_stringified_contexts() { return detail::g_cs->stringifiedContexts.size(); } -const String* IReporter::get_stringified_contexts() { - return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] : nullptr; -} - -namespace detail { - void registerReporterImpl(const char* name, int priority, reporterCreatorFunc c) { - getReporters().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c)); - } -} // namespace detail - -// see these issues on the reasoning for this: -// - https://github.com/onqtam/doctest/issues/143#issuecomment-414418903 -// - https://github.com/onqtam/doctest/issues/126 -void DOCTEST_FIX_FOR_MACOS_LIBCPP_IOSFWD_STRING_LINK_ERRORS() { std::cout << std::string(); } - -} // namespace doctest - -#endif // DOCTEST_CONFIG_DISABLE - -#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) // 'function' : must be 'attribute' - see issue #182 -int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); } -DOCTEST_MSVC_SUPPRESS_WARNING_POP -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_LIBRARY_IMPLEMENTATION -#endif // DOCTEST_CONFIG_IMPLEMENT diff --git a/lib/ArduinoStreamUtils/extras/test/main.cpp b/lib/ArduinoStreamUtils/extras/test/main.cpp deleted file mode 100644 index dcfcaba1..00000000 --- a/lib/ArduinoStreamUtils/extras/test/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "doctest.h" diff --git a/lib/ArduinoStreamUtils/keywords.txt b/lib/ArduinoStreamUtils/keywords.txt deleted file mode 100644 index 9f91ccef..00000000 --- a/lib/ArduinoStreamUtils/keywords.txt +++ /dev/null @@ -1,13 +0,0 @@ -BufferingPrint KEYWORD1 -LoggingClient KEYWORD1 -LoggingPrint KEYWORD1 -LoggingStream KEYWORD1 -ReadBufferingClient KEYWORD1 -ReadBufferingStream KEYWORD1 -ReadLoggingClient KEYWORD1 -ReadLoggingStream KEYWORD1 -ReadThrottlingStream KEYWORD1 -WriteBufferingClient KEYWORD1 -WriteBufferingStream KEYWORD1 -WriteLoggingClient KEYWORD1 -WriteLoggingStream KEYWORD1 \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/library.properties b/lib/ArduinoStreamUtils/library.properties deleted file mode 100644 index 00cb5887..00000000 --- a/lib/ArduinoStreamUtils/library.properties +++ /dev/null @@ -1,11 +0,0 @@ -name=StreamUtils -version=1.6.1 -author=Benoit Blanchon -maintainer=Benoit Blanchon -sentence=💪 Power-ups for Arduino streams -paragraph=Enhances existing streams with logging, buffering, error correction, and more! Works with Serial, SoftwareSerial, WiFiClient... -category=Other -url=https://github.com/bblanchon/ArduinoStreamUtils -architectures=* -repository=https://github.com/bblanchon/ArduinoStreamUtils.git -license=MIT diff --git a/lib/ArduinoStreamUtils/src/StreamUtils.h b/lib/ArduinoStreamUtils/src/StreamUtils.h deleted file mode 100644 index 39637e3a..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils.h +++ /dev/null @@ -1,7 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils.hpp" - -using namespace StreamUtils; \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils.hpp b/lib/ArduinoStreamUtils/src/StreamUtils.hpp deleted file mode 100644 index f24f78e9..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#include "StreamUtils/Clients/HammingClient.hpp" -#include "StreamUtils/Clients/HammingDecodingClient.hpp" -#include "StreamUtils/Clients/HammingEncodingClient.hpp" -#include "StreamUtils/Clients/LoggingClient.hpp" -#include "StreamUtils/Clients/ReadBufferingClient.hpp" -#include "StreamUtils/Clients/ReadLoggingClient.hpp" -#include "StreamUtils/Clients/WriteBufferingClient.hpp" -#include "StreamUtils/Clients/WriteLoggingClient.hpp" -#include "StreamUtils/Prints/BufferingPrint.hpp" -#include "StreamUtils/Prints/HammingPrint.hpp" -#include "StreamUtils/Prints/LoggingPrint.hpp" -#include "StreamUtils/Prints/StringPrint.hpp" -#include "StreamUtils/Streams/EepromStream.hpp" -#include "StreamUtils/Streams/HammingDecodingStream.hpp" -#include "StreamUtils/Streams/HammingEncodingStream.hpp" -#include "StreamUtils/Streams/HammingStream.hpp" -#include "StreamUtils/Streams/LoggingStream.hpp" -#include "StreamUtils/Streams/ReadBufferingStream.hpp" -#include "StreamUtils/Streams/ReadLoggingStream.hpp" -#include "StreamUtils/Streams/ReadThrottlingStream.hpp" -#include "StreamUtils/Streams/StringStream.hpp" -#include "StreamUtils/Streams/WriteBufferingStream.hpp" -#include "StreamUtils/Streams/WriteLoggingStream.hpp" -#include "StreamUtils/Streams/WriteWaitingStream.hpp" diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CharArray.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CharArray.hpp deleted file mode 100644 index c16f4548..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CharArray.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include // size_t -#include // memcpy - -namespace StreamUtils { - -template -class CharArray { - public: - CharArray(size_t size, TAllocator allocator = TAllocator()) - : _allocator(allocator) { - _data = reinterpret_cast(_allocator.allocate(size)); - _size = _data ? size : 0; - } - - CharArray(const CharArray &src) : CharArray(src._size, src._allocator) { - if (_data != nullptr) - memcpy(_data, src._data, _size); - } - - ~CharArray() { - _allocator.deallocate(_data); - } - - size_t size() const { - return _size; - } - - operator bool() const { - return _size > 0; - } - - char *operator&() { - return _data; - } - - char &operator[](size_t i) { - return _data[i]; - } - - char operator[](size_t i) const { - return _data[i]; - } - - protected: - TAllocator _allocator; - char *_data; - size_t _size; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CircularBuffer.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CircularBuffer.hpp deleted file mode 100644 index c2f210af..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CircularBuffer.hpp +++ /dev/null @@ -1,101 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "CharArray.hpp" - -namespace StreamUtils { - -template -class CircularBuffer { - public: - CircularBuffer(size_t capacity, TAllocator allocator = TAllocator()) - : _data(capacity, allocator) { - _begin = _end = _size = 0; - } - - CircularBuffer(const CircularBuffer &src) - : CircularBuffer(src._data.size(), src._allocator) { - if (_data) { - _begin = src._begin; - _end = src._end; - _size = src._size; - } - } - - size_t available() const { - return _size; - } - - size_t capacity() const { - return _data.size(); - } - - void clear() { - _begin = _end = _size = 0; - } - - bool isEmpty() const { - return _size == 0; - } - - bool isFull() const { - return _size == _data.size(); - } - - char peek() const { - assert(_size > 0); - return _data[_begin]; - } - - char read() { - assert(_size > 0); - char result = _data[_begin]; - _begin = (_begin + 1) % _data.size(); - _size--; - return result; - } - - size_t readBytes(char *data, size_t size) { - // don't read more that available - if (size > _size) - size = _size; - - for (size_t i = 0; i < size; i++) - data[i] = read(); - - return size; - } - - size_t write(uint8_t data) { - assert(_size < _data.size()); - _data[_end] = data; - _end = (_end + 1) % _data.size(); - _size++; - return 1; - } - - size_t write(const uint8_t *data, size_t size) { - // don't read more that available - size_t roomLeft = _data.size() - _size; - if (size > roomLeft) - size = roomLeft; - - for (size_t i = 0; i < size; i++) - write(data[i]); - - return size; - } - - private: - CharArray _data; - size_t _size; - size_t _begin; - size_t _end; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/LinearBuffer.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/LinearBuffer.hpp deleted file mode 100644 index 10c108f6..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Buffers/LinearBuffer.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include - -#include "../Helpers.hpp" -#include "CharArray.hpp" - -namespace StreamUtils { - -template -class LinearBuffer { - public: - LinearBuffer(size_t capacity, TAllocator allocator = TAllocator()) - : _data(capacity, allocator) { - _begin = _data ? &_data : nullptr; - _end = _begin; - } - - LinearBuffer(const LinearBuffer &src) : _data(src._data) { - if (_data) { - memcpy(&_data, src._begin, src.available()); - _begin = &_data; - _end = &_data + src.available(); - } else { - _begin = nullptr; - _end = nullptr; - } - } - - size_t available() const { - return _end - _begin; - } - - size_t capacity() const { - return _data.size(); - } - - void clear() { - _begin = _end = _data; - } - - bool isEmpty() const { - return available() == 0; - } - - bool isFull() const { - return available() == capacity(); - } - - operator bool() const { - return _data; - } - - char peek() const { - return *_begin; - } - - char read() { - return *_begin++; - } - - size_t readBytes(char *dstPtr, size_t dstSize) { - size_t srcSize = available(); - size_t n = srcSize < dstSize ? srcSize : dstSize; - memcpy(dstPtr, _begin, n); - _begin += n; - return n; - } - - size_t write(uint8_t data) { - assert(!isFull()); - *_end++ = data; - return 1; - } - - size_t write(const uint8_t *data, size_t size) { - size_t roomLeft = capacity() - available(); - if (size > roomLeft) - size = roomLeft; - memcpy(_end, data, size); - _end += size; - return size; - } - - template // Stream or Client - void reloadFrom(TTarget &source, size_t size) { - if (size > _data.size()) - size = _data.size(); - size_t n = readOrReadBytes(source, &_data, size); - _begin = &_data; - _end = &_data + n; - } - - void flushInto(Print &destination) { - if (_begin != _end) - destination.write(_begin, _end - _begin); - _begin = _end = &_data; - } - - private: - CharArray _data; - char *_begin; - char *_end; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ClientProxy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ClientProxy.hpp deleted file mode 100644 index 23a9cc09..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ClientProxy.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Configuration.hpp" -#include "../Streams/StreamProxy.hpp" - -namespace StreamUtils { - -template -class ClientProxy : public Client { - public: - explicit ClientProxy(Client &upstream, ReadPolicy reader = ReadPolicy(), - WritePolicy writer = WritePolicy(), - ConnectPolicy connection = ConnectPolicy()) - : _target(upstream), - _reader(reader), - _writer(Polyfills::move(writer)), - _connection(connection) {} - - ClientProxy(const ClientProxy &other) - : _target(other._target), - _reader(other._reader), - _writer(other._writer), - _connection(other._connection) {} - - ~ClientProxy() { - _writer.implicitFlush(_target); - } - - // --- Print --- - - size_t write(const uint8_t *buffer, size_t size) override { - return _writer.write(_target, buffer, size); - } - - size_t write(uint8_t data) override { - return _writer.write(_target, data); - } - - using Print::write; - - // --- Stream --- - - int available() override { - return _reader.available(_target); - } - - int read() override { - return _reader.read(_target); - } - - int peek() override { - return _reader.peek(_target); - } - -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - size_t readBytes(char *buffer, size_t size) override { - return _reader.readBytes(_target, buffer, size); - } -#endif - - // --- Client --- - - int connect(IPAddress ip, uint16_t port) override { - return _connection.connect(_target, ip, port); - } - - int connect(const char *ip, uint16_t port) override { - return _connection.connect(_target, ip, port); - } - - uint8_t connected() override { - return _connection.connected(_target); - } - - void stop() override { - _writer.implicitFlush(_target); - _connection.stop(_target); - } - - operator bool() override { - return _connection.operator_bool(_target); - } - - int read(uint8_t *buf, size_t size) override { - return _reader.read(_target, buf, size); - } - - void flush() override { - _writer.flush(_target); - } - - protected: - Client &_target; - ReadPolicy _reader; - WritePolicy _writer; - ConnectPolicy _connection; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingClient.hpp deleted file mode 100644 index 99442397..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingClient.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/HammingDecodingPolicy.hpp" -#include "../Policies/HammingEncodingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -template -using BasicHammingClient = ClientProxy, - HammingEncodingPolicy, - ConnectForwardingPolicy>; - -template -using HammingClient = BasicHammingClient; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingDecodingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingDecodingClient.hpp deleted file mode 100644 index ab4de20a..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingDecodingClient.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/HammingDecodingPolicy.hpp" -#include "../Policies/WriteForwardingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -template -using BasicHammingDecodingClient = - ClientProxy, WriteForwardingPolicy, - ConnectForwardingPolicy>; - -template -using HammingDecodingClient = - BasicHammingDecodingClient; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingEncodingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingEncodingClient.hpp deleted file mode 100644 index d341b060..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/HammingEncodingClient.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/HammingEncodingPolicy.hpp" -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -template -using BasicHammingEncodingClient = - ClientProxy, - ConnectForwardingPolicy>; - -template -using HammingEncodingClient = - BasicHammingEncodingClient; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/LoggingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/LoggingClient.hpp deleted file mode 100644 index c3c8bcbe..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/LoggingClient.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/ReadLoggingPolicy.hpp" -#include "../Policies/WriteLoggingPolicy.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -struct LoggingClient : ClientProxy { - LoggingClient(Client &target, Print &log) - : ClientProxy(target, ReadLoggingPolicy{log}, - WriteLoggingPolicy{log}, - ConnectForwardingPolicy{}) {} -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/MemoryClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/MemoryClient.hpp deleted file mode 100644 index 2e2447dd..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/MemoryClient.hpp +++ /dev/null @@ -1,92 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Buffers/CircularBuffer.hpp" -#include "../Configuration.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "../Streams/MemoryStream.hpp" - -namespace StreamUtils { - -template -class BasicMemoryClient : public Client { - public: - BasicMemoryClient(size_t capacity, TAllocator allocator = TAllocator()) - : _stream(capacity, allocator), _connected(false) {} - - BasicMemoryClient(const BasicMemoryClient &src) : _stream(src._stream) {} - - // --- Print --- - - size_t write(uint8_t data) override { - return _stream.write(data); - } - - size_t write(const uint8_t *data, size_t size) override { - return _stream.write(data, size); - } - - // --- Stream --- - - int available() override { - return _stream.available(); - } - - int peek() override { - return _stream.peek(); - } - - int read() override { - return _stream.read(); - } - -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - size_t readBytes(char *data, size_t size) override { - return _stream.readBytes(data, size); - } -#endif - - void flush() override { - _stream.flush(); - } - - // --- Client --- - - int connect(IPAddress, uint16_t) override { - _connected = true; - return 1; - } - - int connect(const char *, uint16_t) override { - _connected = true; - return 1; - } - - uint8_t connected() override { - return _connected; - } - - void stop() override { - _connected = false; - } - - operator bool() override { - return true; - } - - int read(uint8_t *buf, size_t size) override { - return _stream.readBytes(reinterpret_cast(buf), size); - } - - private: - BasicMemoryStream _stream; - bool _connected; -}; -using MemoryClient = BasicMemoryClient; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadBufferingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadBufferingClient.hpp deleted file mode 100644 index b3b864eb..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadBufferingClient.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/ReadBufferingPolicy.hpp" -#include "../Policies/WriteForwardingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -template -class BasicReadBufferingClient - : public ClientProxy, WriteForwardingPolicy, - ConnectForwardingPolicy> { - using base_type = ClientProxy, - WriteForwardingPolicy, ConnectForwardingPolicy>; - - public: - explicit BasicReadBufferingClient(Client &target, size_t capacity, - TAllocator allocator = TAllocator()) - : base_type(target, ReadBufferingPolicy{capacity, allocator}, - WriteForwardingPolicy{}, ConnectForwardingPolicy{}) {} -}; - -using ReadBufferingClient = BasicReadBufferingClient; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadLoggingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadLoggingClient.hpp deleted file mode 100644 index 627af07b..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/ReadLoggingClient.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/ReadLoggingPolicy.hpp" -#include "../Policies/WriteForwardingPolicy.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -struct ReadLoggingClient : ClientProxy { - ReadLoggingClient(Client &target, Print &log) - : ClientProxy(target, ReadLoggingPolicy{log}, - WriteForwardingPolicy{}, - ConnectForwardingPolicy{}) {} -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/SpyingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/SpyingClient.hpp deleted file mode 100644 index eaba9af5..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/SpyingClient.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectSpyingPolicy.hpp" -#include "../Policies/ReadSpyingPolicy.hpp" -#include "../Policies/WriteSpyingPolicy.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -struct SpyingClient - : ClientProxy { - SpyingClient(Client &target, Print &log) - : ClientProxy( - target, {log}, {log}, {log}) {} -}; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteBufferingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteBufferingClient.hpp deleted file mode 100644 index 4f207cb9..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteBufferingClient.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Policies/WriteBufferingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -template -struct BasicWriteBufferingClient - : ClientProxy, - ConnectForwardingPolicy> { - explicit BasicWriteBufferingClient(Client &target, size_t capacity, - TAllocator allocator = TAllocator()) - : ClientProxy, - ConnectForwardingPolicy>( - target, ReadForwardingPolicy{}, - WriteBufferingPolicy{capacity, allocator}, - ConnectForwardingPolicy{}) {} -}; - -using WriteBufferingClient = BasicWriteBufferingClient; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteLoggingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteLoggingClient.hpp deleted file mode 100644 index 5b07a179..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteLoggingClient.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Policies/WriteLoggingPolicy.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -struct WriteLoggingClient - : ClientProxy { - WriteLoggingClient(Client &target, Print &log) - : ClientProxy(target, ReadForwardingPolicy{}, - WriteLoggingPolicy{log}, - ConnectForwardingPolicy{}) {} -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteWaitingClient.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteWaitingClient.hpp deleted file mode 100644 index 3e1894ca..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Clients/WriteWaitingClient.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ConnectForwardingPolicy.hpp" -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Policies/WriteWaitingPolicy.hpp" -#include "ClientProxy.hpp" - -namespace StreamUtils { - -struct WriteWaitingClient - : ClientProxy { - WriteWaitingClient(Client &target, Polyfills::function wait = yield) - : ClientProxy( - target, ReadForwardingPolicy{}, - WriteWaitingPolicy{Polyfills::move(wait)}, - ConnectForwardingPolicy{}) {} - - void setTimeout(unsigned long timeout) { - Client::setTimeout(timeout); - _writer.setTimeout(timeout); - } -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Configuration.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Configuration.hpp deleted file mode 100644 index ec149566..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Configuration.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#ifndef STREAMUTILS_PRINT_FLUSH_EXISTS -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD) || \ - defined(ARDUINO_ARCH_AVR) -#define STREAMUTILS_PRINT_FLUSH_EXISTS 1 -#else -#define STREAMUTILS_PRINT_FLUSH_EXISTS 0 -#endif -#endif - -#ifndef STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || \ - defined(ARDUINO_ARCH_STM32) -#define STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL 1 -#else -#define STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL 0 -#endif -#endif - -#ifndef STREAMUTILS_ENABLE_EEPROM -#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP8266) || \ - defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_STM32) || \ - defined(CORE_TEENSY) -#define STREAMUTILS_ENABLE_EEPROM 1 -#else -#define STREAMUTILS_ENABLE_EEPROM 0 -#endif -#endif - -#ifndef STREAMUTILS_USE_EEPROM_COMMIT -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) -#define STREAMUTILS_USE_EEPROM_COMMIT 1 -#else -#define STREAMUTILS_USE_EEPROM_COMMIT 0 -#endif -#endif - -#ifndef STREAMUTILS_USE_EEPROM_UPDATE -#if defined(ARDUINO_ARCH_AVR) || defined(CORE_TEENSY) -#define STREAMUTILS_USE_EEPROM_UPDATE 1 -#else -#define STREAMUTILS_USE_EEPROM_UPDATE 0 -#endif -#endif - -#ifndef STREAMUTILS_STACK_BUFFER_MAX_SIZE -#define STREAMUTILS_STACK_BUFFER_MAX_SIZE 32 -#endif \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Helpers.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Helpers.hpp deleted file mode 100644 index 9bd219c7..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Helpers.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -namespace StreamUtils { - -inline size_t readOrReadBytes(Stream &stream, char *buffer, size_t size) { - return stream.readBytes(buffer, size); -} - -inline size_t readOrReadBytes(Client &client, char *buffer, size_t size) { - return client.read(reinterpret_cast(buffer), size); -} - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectForwardingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectForwardingPolicy.hpp deleted file mode 100644 index 1580eee4..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectForwardingPolicy.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Configuration.hpp" - -namespace StreamUtils { - -struct ConnectForwardingPolicy { - int connect(Client& target, const IPAddress& ip, uint16_t port) { - return target.connect(ip, port); - } - - int connect(Client& target, const char* ip, uint16_t port) { - return target.connect(ip, port); - } - - uint8_t connected(Client& target) { - return target.connected(); - } - - void stop(Client& target) { - target.stop(); - } - - bool operator_bool(Client& target) { - return target.operator bool(); - } -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectSpyingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectSpyingPolicy.hpp deleted file mode 100644 index c004ba02..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ConnectSpyingPolicy.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -namespace StreamUtils { - -class ConnectSpyingPolicy { - public: - ConnectSpyingPolicy(Print& log) : _log(log) {} - - int connect(Client& target, const IPAddress& ip, uint16_t port) { - _log.print("connect('"); - _log.print(ip); - _log.print("', "); - _log.print(port); - _log.print(") -> "); - - int result = target.connect(ip, port); - _log.println(result); - - return result; - } - - int connect(Client& target, const char* ip, uint16_t port) { - _log.print("connect('"); - _log.print(ip); - _log.print("', "); - _log.print(port); - _log.print(") -> "); - - int result = target.connect(ip, port); - _log.println(result); - - return result; - } - - uint8_t connected(Client& target) { - _log.print("connected() -> "); - - uint8_t result = target.connected(); - _log.println(result); - - return result; - } - - void stop(Client& target) { - _log.print("stop()"); - target.stop(); - } - - bool operator_bool(Client& target) { - _log.print("operator bool() -> "); - - bool result = target.operator bool(); - _log.println(result ? "true" : "false"); - - return result; - } - - private: - Print& _log; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingDecodingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingDecodingPolicy.hpp deleted file mode 100644 index 37bb2ffe..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingDecodingPolicy.hpp +++ /dev/null @@ -1,137 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__) -#include -#else -#include -#endif - -#include -#include - -#include "../Configuration.hpp" -#include "../Helpers.hpp" - -namespace StreamUtils { - -template -class HammingDecodingPolicy; - -template -class HammingDecodingPolicy<7, 4, TAllocator> { - const static size_t sizeAllowedOnStack = STREAMUTILS_STACK_BUFFER_MAX_SIZE; - - public: - HammingDecodingPolicy(TAllocator allocator = TAllocator()) - : _allocator(allocator) {} - - int available(Stream &stream) { - int n = stream.available(); - if (_remainder >= 0) - n++; - return n / 2; - } - - template // Stream or Client - int read(TTarget &target) { - if (_remainder < 0) { - _remainder = target.read(); - if (_remainder < 0) - return -1; - } - int c = target.read(); - if (c < 0) - return -1; - int result = decode(_remainder, c); - _remainder = -1; - return result; - } - - int peek(Stream &stream) { - if (_remainder < 0) { - _remainder = stream.read(); - if (_remainder < 0) - return -1; - } - int c = stream.peek(); - if (c < 0) - return -1; - return decode(_remainder, c); - } - - size_t readBytes(Stream &stream, char *buffer, size_t size) { - return doReadBytes(stream, buffer, size); - } - - int read(Client &client, uint8_t *buffer, size_t size) { - return doReadBytes(client, reinterpret_cast(buffer), size); - } - - private: - // Decode 7-bits to 4-bits using Hamming(7,4) - uint8_t decode(uint8_t input) { - // table is packed: each element contains two 4-bits values - static uint8_t table[] = { - 0x00, 0x03, 0x05, 0xE7, 0x09, 0xEB, 0xED, 0xEE, 0x03, 0x33, 0x4D, - 0x63, 0x8D, 0xA3, 0xDD, 0xED, 0x05, 0x2B, 0x55, 0x65, 0x8B, 0xBB, - 0xC5, 0xEB, 0x81, 0x63, 0x65, 0x66, 0x88, 0x8B, 0x8D, 0x6F, 0x09, - 0x27, 0x47, 0x77, 0x99, 0xA9, 0xC9, 0xE7, 0x41, 0xA3, 0x44, 0x47, - 0xA9, 0xAA, 0x4D, 0xAF, 0x21, 0x22, 0xC5, 0x27, 0xC9, 0x2B, 0xCC, - 0xCF, 0x11, 0x21, 0x41, 0x6F, 0x81, 0xAF, 0xCF, 0xFF}; - uint8_t elem = table[input / 2]; - if (input % 2) - return elem & 0x0f; - - else - return elem >> 4; - } - - uint8_t decode(uint8_t first, uint8_t second) { - return decode(first) << 4 | decode(second); - } - - template // Stream or Client - size_t doReadBytes(TTarget &target, char *output, size_t outputSize) { - char *buffer; - size_t bufferSize = outputSize * 2; - - if (bufferSize > sizeAllowedOnStack) { - buffer = static_cast(_allocator.allocate(bufferSize)); - if (!buffer) { - // allocation failed => use the input buffer - bufferSize = outputSize; - buffer = output; - } - } else { - buffer = static_cast(alloca(bufferSize)); - } - - size_t loadedSize = 0; - if (_remainder >= 0) - buffer[loadedSize++] = _remainder; - - loadedSize += - readOrReadBytes(target, buffer + loadedSize, bufferSize - loadedSize); - for (size_t i = 0; i < loadedSize / 2; i++) - output[i] = decode(buffer[2 * i], buffer[2 * i + 1]); - - if (loadedSize % 2) - _remainder = buffer[loadedSize - 1]; - else - _remainder = -1; - - if (bufferSize > sizeAllowedOnStack) - _allocator.deallocate(buffer); - - return loadedSize / 2; - } - - TAllocator _allocator; - char _remainder = -1; -}; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingEncodingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingEncodingPolicy.hpp deleted file mode 100644 index f7d281ec..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/HammingEncodingPolicy.hpp +++ /dev/null @@ -1,116 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__) -#include -#else -#include -#endif - -#include "../Configuration.hpp" - -namespace StreamUtils { - -template -class HammingEncodingPolicy; - -template -class HammingEncodingPolicy<7, 4, TAllocator> { - const static size_t sizeAllowedOnStack = STREAMUTILS_STACK_BUFFER_MAX_SIZE; - - public: - HammingEncodingPolicy(TAllocator allocator = TAllocator()) - : _allocator(allocator) {} - - size_t write(Print &target, const uint8_t *data, size_t size) { - if (!flushRemainder(target)) - return 0; - - size_t bufferSize = size * 2; - uint8_t *buffer; - if (bufferSize > sizeAllowedOnStack) { - buffer = static_cast(_allocator.allocate(bufferSize)); - if (!buffer) { - bufferSize = sizeAllowedOnStack; - buffer = static_cast(alloca(bufferSize)); - } - } else { - buffer = static_cast(alloca(bufferSize)); - } - - for (size_t i = 0, j = 0; j < bufferSize; i++) { - buffer[j++] = encode(data[i] >> 4); - buffer[j++] = encode(data[i] & 0x0f); - } - size_t n = target.write(buffer, bufferSize); - if (n & 1) { - _remainder = buffer[n]; - ++n; - } - - if (bufferSize > sizeAllowedOnStack) - _allocator.deallocate(buffer); - - return n / 2; - } - - size_t write(Print &target, uint8_t data) { - uint8_t first = encode(data >> 4); - uint8_t second = encode(data & 0x0f); - - if (!flushRemainder(target)) - return 0; - - if (!target.write(first)) - return 0; - - if (!target.write(second)) - _remainder = second; - - return 1; - } - - void flush(Stream &target) { - flushRemainder(target); - target.flush(); - } - - void flush(Print &target) { - flushRemainder(target); -#if STREAMUTILS_PRINT_FLUSH_EXISTS - target.flush(); -#endif - } - - void implicitFlush(Print &target) { - flushRemainder(target); - } - - private: - // Encode 4-bits to 7-bits using Hamming(7,4) - uint8_t encode(uint8_t input) { - static uint8_t table[] = {0x00, 0x71, 0x62, 0x13, 0x54, 0x25, 0x36, 0x47, - 0x38, 0x49, 0x5A, 0x2B, 0x6C, 0x1D, 0x0E, 0x7F}; - return table[input]; - } - - template - bool flushRemainder(TTarget &target) { - if (_remainder < 0) - return true; - - if (!target.write(_remainder)) - return false; - - _remainder = -1; - return true; - } - - TAllocator _allocator; - int16_t _remainder = -1; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadBufferingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadBufferingPolicy.hpp deleted file mode 100644 index 10bc3305..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadBufferingPolicy.hpp +++ /dev/null @@ -1,97 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Buffers/LinearBuffer.hpp" -#include "../Helpers.hpp" - -namespace StreamUtils { - -template -struct ReadBufferingPolicy { - ReadBufferingPolicy(size_t capacity, TAllocator allocator = TAllocator()) - : _buffer(capacity, allocator) {} - - ReadBufferingPolicy(const ReadBufferingPolicy &other) - : _buffer(other._buffer) {} - - int available(Stream &stream) { - return stream.available() + _buffer.available(); - } - - template // Stream or Client - int read(TTarget &target) { - if (!_buffer) - return target.read(); - - if (_buffer.available() > 0) - return _buffer.read(); - - size_t avail = static_cast(target.available()); - if (avail <= 1) - return target.read(); - - _buffer.reloadFrom(target, avail); - return _buffer.read(); - } - - int peek(Stream &stream) { - return isEmpty() ? stream.peek() : _buffer.peek(); - } - - size_t readBytes(Stream &stream, char *buffer, size_t size) { - return doReadBytes(stream, buffer, size); - } - - int read(Client &client, uint8_t *buffer, size_t size) { - return doReadBytes(client, reinterpret_cast(buffer), size); - } - - private: - bool isEmpty() const { - return _buffer.available() == 0; - } - - LinearBuffer _buffer; - - template // Stream or Client - size_t doReadBytes(TTarget &target, char *buffer, size_t size) { - if (!_buffer) - return readOrReadBytes(target, buffer, size); - - size_t result = 0; - - // can we read from buffer? - if (_buffer.available() > 0) { - size_t bytesRead = _buffer.readBytes(buffer, size); - result += bytesRead; - buffer += bytesRead; - size -= bytesRead; - } - - // still something to read? - if (size > 0) { - // (at this point, the buffer is empty) - - size_t avail = static_cast(target.available()); - - // should we use the buffer? - if (avail > size && size < _buffer.capacity()) { - _buffer.reloadFrom(target, avail); - size_t bytesRead = _buffer.readBytes(buffer, size); - result += bytesRead; - } else { - // we can bypass the buffer - result += readOrReadBytes(target, buffer, size); - } - } - - return result; - } -}; // namespace StreamUtils - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadForwardingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadForwardingPolicy.hpp deleted file mode 100644 index 02138aba..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadForwardingPolicy.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -namespace StreamUtils { - -struct ReadForwardingPolicy { - int available(Stream &target) { - return target.available(); - } - - int read(Stream &target) { - return target.read(); - } - - int peek(Stream &target) { - return target.peek(); - } - - size_t readBytes(Stream &target, char *buffer, size_t size) { - return target.readBytes(buffer, size); - } - - int read(Client &target, uint8_t *buffer, size_t size) { - return target.read(buffer, size); - } -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadLoggingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadLoggingPolicy.hpp deleted file mode 100644 index ce614c34..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadLoggingPolicy.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -namespace StreamUtils { - -class ReadLoggingPolicy { - public: - ReadLoggingPolicy(Print &log) : _log(log) {} - - int available(Stream &stream) { - return stream.available(); - } - - int read(Stream &stream) { - int result = stream.read(); - if (result >= 0) - _log.write(result); - return result; - } - - int peek(Stream &stream) { - return stream.peek(); - } - - size_t readBytes(Stream &stream, char *buffer, size_t size) { - size_t result = stream.readBytes(buffer, size); - _log.write(buffer, result); - return result; - } - - int read(Client &client, uint8_t *buffer, size_t size) { - int result = client.read(buffer, size); - _log.write(buffer, result); - return result; - } - - private: - Print &_log; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadSpyingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadSpyingPolicy.hpp deleted file mode 100644 index 0cfb6ac2..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadSpyingPolicy.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -namespace StreamUtils { - -class ReadSpyingPolicy { - public: - ReadSpyingPolicy(Print &log) : _log(log) {} - - int available(Stream &target) { - int result = target.available(); - _log.print("available() -> "); - _log.println(result); - return result; - } - - int read(Stream &target) { - int result = target.read(); - _log.print("read() -> "); - _log.println(result); - return result; - } - - int peek(Stream &target) { - int result = target.peek(); - _log.print("peek() -> "); - _log.println(result); - return result; - } - - size_t readBytes(Stream &target, char *buffer, size_t size) { - size_t result = target.readBytes(buffer, size); - _log.print("readBytes("); - _log.print(size); - _log.print(") -> "); - _log.print(result); - if (size > result) - _log.print(" [timeout]"); - _log.println(); - return result; - } - - int read(Client &target, uint8_t *buffer, size_t size) { - int result = target.read(buffer, size); - _log.print("read("); - _log.print(size); - _log.print(") -> "); - _log.print(result); - if (static_cast(size) > result) - _log.print(" [timeout]"); - _log.println(); - return result; - } - - private: - Print &_log; -}; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadThrottlingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadThrottlingPolicy.hpp deleted file mode 100644 index 51e01a81..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/ReadThrottlingPolicy.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -namespace StreamUtils { - -template -struct ReadThrottlingPolicy { - ReadThrottlingPolicy(TThrottler throttler) : _throttler(throttler) {} - - int available(Stream &stream) { - return stream.available(); - } - - int read(Stream &stream) { - _throttler.throttle(); - return stream.read(); - } - - int peek(Stream &stream) { - _throttler.throttle(); - return stream.peek(); - } - - size_t readBytes(Stream &stream, char *buffer, size_t size) { - for (size_t i = 0; i < size; i++) { - int c = read(stream); - if (c < 0) - return i; - buffer[i] = c; - } - return size; - } - - const TThrottler &throttler() const { - return _throttler; - } - - private: - TThrottler _throttler; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteBufferingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteBufferingPolicy.hpp deleted file mode 100644 index 53a2b974..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteBufferingPolicy.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Buffers/LinearBuffer.hpp" -#include "../Configuration.hpp" - -namespace StreamUtils { - -template -struct WriteBufferingPolicy { - public: - WriteBufferingPolicy(size_t capacity, TAllocator allocator) - : _buffer(capacity, allocator) {} - - size_t write(Print &target, const uint8_t *data, size_t size) { - size_t result = 0; - - // continue to fill the buffer? - if (!_buffer.isEmpty()) { - size_t n = _buffer.write(data, size); - data += n; - size -= n; - result += n; - - // time to flush? - if (_buffer.isFull()) { - _buffer.flushInto(target); - } - } - - // something left to write? - if (size > 0) { - // can we bypass the buffer? - if (size >= _buffer.capacity()) { - result += target.write(data, size); - } else { - result += _buffer.write(data, size); - } - } - return result; - } - - size_t write(Print &target, uint8_t data) { - if (!_buffer) - return target.write(data); - - _buffer.write(data); - if (_buffer.isFull()) - _buffer.flushInto(target); - return 1; - } - - void flush(Stream &target) { - _buffer.flushInto(target); - target.flush(); - } - - void flush(Print &target) { - _buffer.flushInto(target); -#if STREAMUTILS_PRINT_FLUSH_EXISTS - target.flush(); -#endif - } - - void implicitFlush(Print &target) { - _buffer.flushInto(target); - } - - private: - LinearBuffer _buffer; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteForwardingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteForwardingPolicy.hpp deleted file mode 100644 index fac36cce..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteForwardingPolicy.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include - -#include "../Configuration.hpp" - -namespace StreamUtils { - -struct WriteForwardingPolicy { - template - size_t write(Stream &stream, Args... args) { - return stream.write(args...); - } - - void flush(Stream &stream) { - stream.flush(); - } - - void implicitFlush(Stream &) {} -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteLoggingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteLoggingPolicy.hpp deleted file mode 100644 index c4378af3..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteLoggingPolicy.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include "../Configuration.hpp" - -namespace StreamUtils { - -class WriteLoggingPolicy { - public: - WriteLoggingPolicy(Print &log) : _log(log) {} - - size_t write(Print &target, const uint8_t *buffer, size_t size) { - size_t result = target.write(buffer, size); - _log.write(buffer, result); - return result; - } - - size_t write(Print &target, uint8_t c) { - size_t result = target.write(c); - _log.write(c); - return result; - } - - template - void flush(TTarget &target) { - target.flush(); - } - - void implicitFlush(Print &) {} - - private: - Print &_log; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteSpyingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteSpyingPolicy.hpp deleted file mode 100644 index 24ee2f3e..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteSpyingPolicy.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Configuration.hpp" - -namespace StreamUtils { - -class WriteSpyingPolicy { - public: - WriteSpyingPolicy(Print &log) : _log(log) {} - - size_t write(Print &stream, const uint8_t *buffer, size_t size) { - _log.print("write('"); - for (size_t i = 0; i < size; i++) { - _log.write(buffer[i]); - } - _log.print("', "); - _log.print(size); - _log.print(") -> "); - - size_t result = stream.write(buffer, size); - _log.println(result); - - return result; - } - - size_t write(Print &stream, uint8_t data) { - _log.print("write('"); - _log.write(data); - _log.print("') -> "); - - size_t result = stream.write(data); - _log.println(result); - - return result; - } - - template - void flush(TTarget &target) { - _log.println("flush()"); - target.flush(); - } - - void implicitFlush(Print &) {} - - private: - Print &_log; -}; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteWaitingPolicy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteWaitingPolicy.hpp deleted file mode 100644 index 744fb80c..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Policies/WriteWaitingPolicy.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Buffers/LinearBuffer.hpp" -#include "../Configuration.hpp" -#include "../Polyfills.hpp" - -namespace StreamUtils { - -struct WriteWaitingPolicy { - public: - WriteWaitingPolicy(Polyfills::function wait) - : _wait(Polyfills::move(wait)), _timeout(1000) {} - - size_t write(Print &target, const uint8_t *data, size_t size) { - unsigned long startTime = millis(); - size_t totalWritten = 0; - - for (;;) { - size_t n = target.write(data, size); - size -= n; - data += n; - totalWritten += n; - if (size == 0 || millis() - startTime >= _timeout) - return totalWritten; - _wait(); - } - } - - size_t write(Print &target, uint8_t data) { - unsigned long startTime = millis(); - - for (;;) { - if (target.write(data)) - return 1; - if (millis() - startTime >= _timeout) - return 0; - _wait(); - } - } - - template - void flush(TTarget &target) { - target.flush(); - } - - void implicitFlush(Print &) {} - - void setTimeout(unsigned long timeout) { - _timeout = timeout; - } - - private: - Polyfills::function _wait; - unsigned long _timeout; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Polyfills.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Polyfills.hpp deleted file mode 100644 index aa4b50bc..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Polyfills.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -namespace StreamUtils { -namespace Polyfills { - -template -struct remove_reference { - using type = T; -}; - -template -struct remove_reference { - using type = T; -}; - -template -typename remove_reference::type &&move(T &&t) { - return static_cast::type &&>(t); -} - -// poor man's std::function -class function { - struct callable_base { - virtual void operator()() = 0; - virtual ~callable_base() {} - }; - - template - struct callable : callable_base { - Functor functor; - callable(Functor functor) : functor(functor) {} - virtual void operator()() { - functor(); - } - }; - - callable_base *_callable; - - public: - template - function(Functor f) { - _callable = new callable(f); - } - function(function &&src) { - _callable = src._callable, src._callable = 0; - } - ~function() { - delete _callable; - } - void operator()() const { - (*_callable)(); - } -}; - -} // namespace Polyfills -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Ports/ArduinoThrottler.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Ports/ArduinoThrottler.hpp deleted file mode 100644 index 0efda001..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Ports/ArduinoThrottler.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -namespace StreamUtils { - -class ArduinoThrottler { - public: - ArduinoThrottler(uint32_t rate) : _interval(1000000 / rate), _last(0) {} - - void throttle() { - auto now = micros(); - auto elapsed = now - _last; - - if (elapsed < _interval) { - delayMicroseconds(_interval - elapsed); - } - - _last = now; - } - - private: - unsigned long _interval; - unsigned long _last; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Ports/DefaultAllocator.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Ports/DefaultAllocator.hpp deleted file mode 100644 index e3bf1541..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Ports/DefaultAllocator.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -namespace StreamUtils { - -#include // malloc, free, size_t - -struct DefaultAllocator { - void* allocate(size_t n) { - return malloc(n); - } - - void deallocate(void* p) { - free(p); - } -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/BufferingPrint.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Prints/BufferingPrint.hpp deleted file mode 100644 index 904ba219..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/BufferingPrint.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/WriteBufferingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "PrintProxy.hpp" - -namespace StreamUtils { - -template -struct BasicBufferingPrint : PrintProxy> { - explicit BasicBufferingPrint(Print &upstream, size_t capacity, - TAllocator allocator = TAllocator()) - : PrintProxy>(upstream, - {capacity, allocator}) {} -}; - -using BufferingPrint = BasicBufferingPrint; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/HammingPrint.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Prints/HammingPrint.hpp deleted file mode 100644 index 9d0236ab..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/HammingPrint.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/HammingEncodingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "PrintProxy.hpp" - -namespace StreamUtils { - -template -using BasicHammingPrint = PrintProxy>; - -template -using HammingPrint = BasicHammingPrint; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/LoggingPrint.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Prints/LoggingPrint.hpp deleted file mode 100644 index cfd33741..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/LoggingPrint.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/WriteLoggingPolicy.hpp" -#include "PrintProxy.hpp" - -namespace StreamUtils { - -struct LoggingPrint : PrintProxy { - LoggingPrint(Print &upstream, Print &log) - : PrintProxy(upstream, {log}) {} -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/PrintProxy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Prints/PrintProxy.hpp deleted file mode 100644 index fcb6860e..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/PrintProxy.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Configuration.hpp" -#include "../Polyfills.hpp" - -namespace StreamUtils { - -template -class PrintProxy : public Print { - public: - explicit PrintProxy(Print &upstream, WritePolicy writer = WritePolicy{}) - : _target(upstream), _writer(Polyfills::move(writer)) {} - - PrintProxy(const PrintProxy &other) - : _target(other._target), _writer(other._writer) {} - - ~PrintProxy() { - _writer.implicitFlush(_target); - } - - size_t write(const uint8_t *buffer, size_t size) override { - return _writer.write(_target, buffer, size); - } - - size_t write(uint8_t data) override { - return _writer.write(_target, data); - } - -#if STREAMUTILS_PRINT_FLUSH_EXISTS - void flush() override { -#else - void flush() { -#endif - _writer.flush(_target); - } - - using Print::write; - - protected: - Print &_target; - WritePolicy _writer; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/SpyingPrint.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Prints/SpyingPrint.hpp deleted file mode 100644 index c8262ef1..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/SpyingPrint.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/WriteSpyingPolicy.hpp" -#include "PrintProxy.hpp" - -namespace StreamUtils { - -struct SpyingPrint : PrintProxy { - SpyingPrint(Print &target, Print &log) - : PrintProxy(target, WriteSpyingPolicy{log}) {} -}; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/StringPrint.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Prints/StringPrint.hpp deleted file mode 100644 index 0f344980..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/StringPrint.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include - -#include "../Polyfills.hpp" - -namespace StreamUtils { - -class StringPrint : public Print { - public: - StringPrint() {} - - explicit StringPrint(String str) : _str(Polyfills::move(str)) {} - - size_t write(const uint8_t* p, size_t n) override { - for (size_t i = 0; i < n; i++) { - uint8_t c = p[i]; - if (c == 0) - return i; - write(c); - } - return n; - } - - size_t write(uint8_t c) override { - if (c == 0) - return 0; - _str += static_cast(c); - return 1; - } - - const String& str() const { - return _str; - } - - void str(String str) { - _str = Polyfills::move(str); - } - - void clear() { - _str = ""; - } - - private: - String _str; -}; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/WaitingPrint.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Prints/WaitingPrint.hpp deleted file mode 100644 index 05d05b47..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Prints/WaitingPrint.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/WriteWaitingPolicy.hpp" -#include "PrintProxy.hpp" - -namespace StreamUtils { - -struct WaitingPrint : PrintProxy { - WaitingPrint(Print &target, Polyfills::function wait = yield) - : PrintProxy( - target, WriteWaitingPolicy{Polyfills::move(wait)}) {} - - void setTimeout(unsigned long timeout) { - _writer.setTimeout(timeout); - } -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/EepromStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/EepromStream.hpp deleted file mode 100644 index d28bccbd..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/EepromStream.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Configuration.hpp" - -#if STREAMUTILS_ENABLE_EEPROM - -#include -#include - -namespace StreamUtils { - -class EepromStream : public Stream { - public: - EepromStream(size_t address, size_t size) - : _readAddress(address), _writeAddress(address), _end(address + size) {} - - int available() override { - return _end - _readAddress; - } - - int read() override { - if (_readAddress >= _end) - return -1; - return EEPROM.read(_readAddress++); - } - - int peek() override { - if (_readAddress >= _end) - return -1; - return EEPROM.read(_readAddress); - } - - void flush() override { -#if STREAMUTILS_USE_EEPROM_COMMIT - EEPROM.commit(); -#endif - } - - using Print::write; - - size_t write(const uint8_t *buffer, size_t size) override { - size_t remaining = _end - _writeAddress; - if (size > remaining) - size = remaining; - for (size_t i = 0; i < size; i++) { -#if STREAMUTILS_USE_EEPROM_UPDATE - EEPROM.update(_writeAddress++, buffer[i]); -#else - EEPROM.write(_writeAddress++, buffer[i]); -#endif - } - return size; - } - - size_t write(uint8_t data) override { - if (_writeAddress >= _end) - return 0; -#if STREAMUTILS_USE_EEPROM_UPDATE - EEPROM.update(_writeAddress++, data); -#else - EEPROM.write(_writeAddress++, data); -#endif - return 1; - } - - private: - size_t _readAddress, _writeAddress, _end; -}; - -} // namespace StreamUtils - -#endif diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingDecodingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingDecodingStream.hpp deleted file mode 100644 index 4003eee0..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingDecodingStream.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/HammingDecodingPolicy.hpp" -#include "../Policies/WriteForwardingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -template -using BasicHammingDecodingStream = - StreamProxy, WriteForwardingPolicy>; - -template -using HammingDecodingStream = - BasicHammingDecodingStream; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingEncodingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingEncodingStream.hpp deleted file mode 100644 index 59a80934..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingEncodingStream.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/HammingEncodingPolicy.hpp" -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -template -using BasicHammingEncodingStream = - StreamProxy>; - -template -using HammingEncodingStream = - BasicHammingEncodingStream; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingStream.hpp deleted file mode 100644 index 68e8f70d..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/HammingStream.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/HammingDecodingPolicy.hpp" -#include "../Policies/HammingEncodingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -template -using BasicHammingStream = StreamProxy, - HammingEncodingPolicy>; - -template -using HammingStream = BasicHammingStream; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/LoggingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/LoggingStream.hpp deleted file mode 100644 index 3e7e789a..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/LoggingStream.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadLoggingPolicy.hpp" -#include "../Policies/WriteLoggingPolicy.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -struct LoggingStream : StreamProxy { - LoggingStream(Stream& target, Print& log) - : StreamProxy( - target, ReadLoggingPolicy{log}, WriteLoggingPolicy{log}) {} -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/MemoryStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/MemoryStream.hpp deleted file mode 100644 index 1b027e4f..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/MemoryStream.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include - -#include "../Buffers/CircularBuffer.hpp" -#include "../Configuration.hpp" -#include "../Ports/DefaultAllocator.hpp" - -namespace StreamUtils { - -template -class BasicMemoryStream : public Stream { - public: - BasicMemoryStream(size_t capacity, TAllocator allocator = TAllocator()) - : _buffer(capacity, allocator) {} - - BasicMemoryStream(const BasicMemoryStream &src) : _buffer(src._buffer) {} - - int available() override { - return static_cast(_buffer.available()); - } - - int peek() override { - return _buffer.isEmpty() ? -1 : _buffer.peek(); - } - - int read() override { - return _buffer.isEmpty() ? -1 : _buffer.read(); - } - -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - size_t readBytes(char *data, size_t size) override { - return _buffer.readBytes(data, size); - } -#endif - - size_t write(uint8_t data) override { - return _buffer.isFull() ? 0 : _buffer.write(data); - } - - size_t write(const uint8_t *data, size_t size) override { - return _buffer.write(data, size); - } - - using Stream::write; - - void flush() override { - _buffer.clear(); - } - - private: - CircularBuffer _buffer; -}; - -using MemoryStream = BasicMemoryStream; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadBufferingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadBufferingStream.hpp deleted file mode 100644 index 11805937..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadBufferingStream.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadBufferingPolicy.hpp" -#include "../Policies/WriteForwardingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -template -class BasicReadBufferingStream - : public StreamProxy, - WriteForwardingPolicy> { - using base_type = - StreamProxy, WriteForwardingPolicy>; - - public: - explicit BasicReadBufferingStream(Stream &upstream, size_t capacity, - TAllocator allocator = TAllocator()) - : base_type(upstream, {capacity, allocator}, {}) {} -}; - -using ReadBufferingStream = BasicReadBufferingStream; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadLoggingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadLoggingStream.hpp deleted file mode 100644 index 50f92b01..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadLoggingStream.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadLoggingPolicy.hpp" -#include "../Policies/WriteForwardingPolicy.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -struct ReadLoggingStream - : StreamProxy { - ReadLoggingStream(Stream &target, Print &log) - : StreamProxy( - target, ReadLoggingPolicy{log}, WriteForwardingPolicy{}) {} -}; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadThrottlingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadThrottlingStream.hpp deleted file mode 100644 index edafd085..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/ReadThrottlingStream.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadThrottlingPolicy.hpp" -#include "../Policies/WriteForwardingPolicy.hpp" -#include "StreamProxy.hpp" - -#ifdef ARDUINO -#include "../Ports/ArduinoThrottler.hpp" -#endif - -namespace StreamUtils { - -template -class BasicReadThrottlingStream - : public StreamProxy, - WriteForwardingPolicy> { - public: - BasicReadThrottlingStream(Stream& upstream, - TThrottler throttler = TThrottler()) - : StreamProxy, WriteForwardingPolicy>( - upstream, ReadThrottlingPolicy(throttler), {}) {} - - const TThrottler& throttler() const { - return this->_reader.throttler(); - } -}; - -#ifdef ARDUINO -using ReadThrottlingStream = BasicReadThrottlingStream; -#endif -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/SpyingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/SpyingStream.hpp deleted file mode 100644 index c323a543..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/SpyingStream.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadSpyingPolicy.hpp" -#include "../Policies/WriteSpyingPolicy.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -struct SpyingStream : StreamProxy { - SpyingStream(Stream &target, Print &log) - : StreamProxy( - target, ReadSpyingPolicy{log}, WriteSpyingPolicy{log}) {} -}; - -} // namespace StreamUtils diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/StreamProxy.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/StreamProxy.hpp deleted file mode 100644 index c2c95226..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/StreamProxy.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include "../Polyfills.hpp" - -namespace StreamUtils { - -template -class StreamProxy : public Stream { - public: - explicit StreamProxy(Stream &upstream, ReadPolicy reader = ReadPolicy{}, - WritePolicy writer = WritePolicy{}) - : _upstream(upstream), - _reader(reader), - _writer(Polyfills::move(writer)) {} - - StreamProxy(const StreamProxy &other) - : _upstream(other._upstream), - _reader(other._reader), - _writer(other._writer) {} - - ~StreamProxy() { - _writer.implicitFlush(_upstream); - } - - size_t write(const uint8_t *buffer, size_t size) override { - return _writer.write(_upstream, buffer, size); - } - - size_t write(uint8_t data) override { - return _writer.write(_upstream, data); - } - - using Stream::write; - - int available() override { - return _reader.available(_upstream); - } - - int read() override { - return _reader.read(_upstream); - } - - int peek() override { - return _reader.peek(_upstream); - } - - void flush() override { - _writer.flush(_upstream); - } - -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - size_t readBytes(char *buffer, size_t size) override { - return _reader.readBytes(_upstream, buffer, size); - } -#endif - - protected: - Stream &_upstream; - ReadPolicy _reader; - WritePolicy _writer; -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/StringStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/StringStream.hpp deleted file mode 100644 index fa89ecf6..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/StringStream.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include -#include - -#include "../Configuration.hpp" -#include "../Polyfills.hpp" - -namespace StreamUtils { - -class StringStream : public Stream { - public: - StringStream() {} - - explicit StringStream(String str) : _str(Polyfills::move(str)) {} - - size_t write(const uint8_t* p, size_t n) override { - for (size_t i = 0; i < n; i++) { - uint8_t c = p[i]; - if (c == 0) - return i; - write(c); - } - return n; - } - - size_t write(uint8_t c) override { - if (c == 0) - return 0; - _str += static_cast(c); - return 1; - } - - const String& str() const { - return _str; - } - - void str(String str) { - _str = Polyfills::move(str); - } - - int available() override { - return _str.length(); - } - - int read() override { - if (_str.length() == 0) - return -1; - char c = _str[0]; - _str.remove(0, 1); - return c; - } - -#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL - size_t readBytes(char* buffer, size_t length) override { - if (length > _str.length()) - length = _str.length(); - _str.toCharArray(buffer, length); - _str.remove(0, length); - return length; - } -#endif - - int peek() override { - return _str.length() > 0 ? _str[0] : -1; - } - - void flush() override {} - - private: - String _str; -}; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteBufferingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteBufferingStream.hpp deleted file mode 100644 index 92dda084..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteBufferingStream.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Policies/WriteBufferingPolicy.hpp" -#include "../Ports/DefaultAllocator.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -template -struct BasicWriteBufferingStream - : StreamProxy> { - explicit BasicWriteBufferingStream(Stream &upstream, size_t capacity, - TAllocator allocator = TAllocator()) - : StreamProxy>( - upstream, {}, {capacity, allocator}) {} -}; - -using WriteBufferingStream = BasicWriteBufferingStream; -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteLoggingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteLoggingStream.hpp deleted file mode 100644 index 13275aa4..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteLoggingStream.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Policies/WriteLoggingPolicy.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -struct WriteLoggingStream - : StreamProxy { - WriteLoggingStream(Stream &target, Print &log) - : StreamProxy( - target, ReadForwardingPolicy{}, WriteLoggingPolicy{log}) {} -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteWaitingStream.hpp b/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteWaitingStream.hpp deleted file mode 100644 index f8c8d5f8..00000000 --- a/lib/ArduinoStreamUtils/src/StreamUtils/Streams/WriteWaitingStream.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// StreamUtils - github.com/bblanchon/ArduinoStreamUtils -// Copyright Benoit Blanchon 2019-2021 -// MIT License - -#pragma once - -#include "../Policies/ReadForwardingPolicy.hpp" -#include "../Policies/WriteWaitingPolicy.hpp" -#include "StreamProxy.hpp" - -namespace StreamUtils { - -struct WriteWaitingStream - : StreamProxy { - WriteWaitingStream(Stream &target, Polyfills::function wait = yield) - : StreamProxy( - target, ReadForwardingPolicy{}, - WriteWaitingPolicy{Polyfills::move(wait)}) {} - - void setTimeout(unsigned long timeout) { - Stream::setTimeout(timeout); - _writer.setTimeout(timeout); - } -}; - -} // namespace StreamUtils \ No newline at end of file diff --git a/lib/TickerScheduler/README.md b/lib/TickerScheduler/README.md new file mode 100644 index 00000000..33f0182e --- /dev/null +++ b/lib/TickerScheduler/README.md @@ -0,0 +1,81 @@ +# TickerScheduler +Simple scheduler for ESP8266 Arduino based on Ticker + +### Initialization + +`TickerScheduler(uint size);` + +| Param | Description | +| --- | --- | +| size | Amount of task Tickers to initialize | + +**Example**: + +`TickerScheduler ts(5)` + + +### Add task + +`boolean add(uint i, uint32_t period, tscallback_t f, boolean shouldFireNow = false); ` + +| Param | Description | +| --- | --- | +| i | Task ID | +| period | Task execution period in ms | +| f | Task callback | +| shouldFireNow| `true` if you want to execute task right after first scheduler update or wait next scheduled start | + +**Returns**: + +`true` - task added sucessfully + +`false` - task was not added + +**Example**: + +`ts.add(0, 3000, sendData)` + +### Execute scheduler in `loop()` + +`ts.update()` + +### Remove task + +`boolean remove(uint i)` + +**Returns**: + +`true` - task removed sucessfully + +`false` - task was not removed + +| Param | Description | +| --- | --- | +| i | Task ID | + +### Enable/Disable task + +`boolean enable(uint i)` + +`boolean disable(uint i)` + +**Returns**: + +`true` - task enabled/disabled sucessfully + +`false` - task was not enabled/disabled + +| Param | Description | +| --- | --- | +| i | Task ID | + +### Enable / disable all tasks + +`void enableAll()` + +`void disableAll()` + +### TODO + +* Task callback parameters support +* ... diff --git a/lib/TickerScheduler/TickerScheduler.cpp b/lib/TickerScheduler/TickerScheduler.cpp new file mode 100644 index 00000000..af47ffa1 --- /dev/null +++ b/lib/TickerScheduler/TickerScheduler.cpp @@ -0,0 +1,116 @@ +#include "TickerScheduler.h" + +TickerScheduler::TickerScheduler(uint8_t size) +{ + this->items = new TickerSchedulerItem[size]; + this->size = size; +} + +TickerScheduler::~TickerScheduler() +{ + for (uint8_t i = 0; i < this->size; i++) + { + this->remove(i); + yield(); + } + + delete[] this->items; + this->items = NULL; + this->size = 0; +} + +void TickerScheduler::handleTickerFlag(bool * flag) +{ + if (!*flag) + *flag = true; +} + +void TickerScheduler::handleTicker(tscallback_t f, void * arg, bool * flag) +{ + if (*flag) + { + yield(); + *flag = false; + yield(); + f(arg); + yield(); + } +} + +bool TickerScheduler::add(uint8_t i, uint32_t period, tscallback_t f, void* arg, boolean shouldFireNow) +{ + if (i >= this->size || this->items[i].is_used) + return false; + + this->items[i].cb = f; + this->items[i].cb_arg = arg; + this->items[i].flag = shouldFireNow; + this->items[i].period = period; + this->items[i].is_used = true; + + enable(i); + + return true; +} + +bool TickerScheduler::remove(uint8_t i) +{ + if (i >= this->size || !this->items[i].is_used) + return false; + + this->items[i].is_used = false; + this->items[i].t.detach(); + this->items[i].flag = false; + this->items[i].cb = NULL; + + return true; +} + +bool TickerScheduler::disable(uint8_t i) +{ + if (i >= this->size || !this->items[i].is_used) + return false; + + this->items[i].t.detach(); + + return true; +} + +bool TickerScheduler::enable(uint8_t i) +{ + if (i >= this->size || !this->items[i].is_used) + return false; + + bool * flag = &this->items[i].flag; + this->items[i].t.attach_ms(this->items[i].period, TickerScheduler::handleTickerFlag, flag); + + return true; +} + +void TickerScheduler::disableAll() +{ + for (uint8_t i = 0; i < this->size; i++) + disable(i); +} + +void TickerScheduler::enableAll() +{ + for (uint8_t i = 0; i < this->size; i++) + enable(i); +} + +void TickerScheduler::update() +{ + for (uint8_t i = 0; i < this->size; i++) + { + if (this->items[i].is_used) + { + #ifdef ARDUINO_ARCH_AVR + this->items[i].t.Tick(); + #endif + + handleTicker(this->items[i].cb, this->items[i].cb_arg, &this->items[i].flag); + } + yield(); + } +} diff --git a/lib/TickerScheduler/TickerScheduler.h b/lib/TickerScheduler/TickerScheduler.h new file mode 100644 index 00000000..98ae1f05 --- /dev/null +++ b/lib/TickerScheduler/TickerScheduler.h @@ -0,0 +1,91 @@ +#ifndef TICKERSCHEDULER_H +#define TICKERSCHEDULER_H + +#if defined(ARDUINO) && ARDUINO >= 100 + #include "Arduino.h" +#endif +#include + + +#ifdef ARDUINO_ARCH_AVR +class Ticker +{ + typedef void(*ticker_callback_t)(bool*); + +private: + bool is_attached = false; + uint32_t period = 0; + uint32_t last_tick = 0; + ticker_callback_t callback; + bool *callback_argument; +public: + void Tick() + { + if (is_attached && millis() - last_tick >= period) + { + callback(callback_argument); + last_tick = millis(); + } + } + + void detach() + { + this->is_attached = true; + } + + template void attach_ms(uint32_t milliseconds, void(*callback)(TArg), TArg arg) + { + this->period = milliseconds; + this->callback = callback; + this->callback_argument = arg; + this->is_attached = true; + } +}; +#endif + +//#ifdef ARDUINO_ARCH_ESP8266 +#include +#include +//#endif + +void tickerFlagHandle(volatile bool * flag); + +#ifdef _GLIBCXX_FUNCTIONAL +typedef std::function tscallback_t; +#else +typedef void(*tscallback_t)(void*); +#endif + +struct TickerSchedulerItem +{ + Ticker t; + bool flag = false; + tscallback_t cb; + void * cb_arg; + uint32_t period; + volatile bool is_used = false; +}; + +class TickerScheduler +{ +private: + uint8_t size; + TickerSchedulerItem *items = NULL; + + void handleTicker(tscallback_t, void *, bool * flag); + static void handleTickerFlag(bool * flag); + +public: + TickerScheduler(uint8_t size); + ~TickerScheduler(); + + bool add(uint8_t i, uint32_t period, tscallback_t, void *, boolean shouldFireNow = false); + bool remove(uint8_t i); + bool enable(uint8_t i); + bool disable(uint8_t i); + void enableAll(); + void disableAll(); + void update(); +}; + +#endif diff --git a/lib/TickerScheduler/example/blink/blink/blink.ino b/lib/TickerScheduler/example/blink/blink/blink.ino new file mode 100644 index 00000000..49afc470 --- /dev/null +++ b/lib/TickerScheduler/example/blink/blink/blink.ino @@ -0,0 +1,29 @@ +#include + +#define LED1 4 +#define LED2 5 + +TickerScheduler ts(2); + +void blink1() { + digitalWrite(LED1, !digitalRead(LED1)); +} + +void blink2() { + digitalWrite(LED2, !digitalRead(LED2)); +} + +void setup() { + pinMode(LED1, OUTPUT); + digitalWrite(LED1, LOW); + + pinMode(LED2, OUTPUT); + digitalWrite(LED2, LOW); + + ts.add(0, 1000, [&](void *) { blink1(); }, nullptr, true); + ts.add(1, 3000, [&](void *) { blink2(); }, nullptr, true); +} + +void loop() { + ts.update(); +} diff --git a/src/EspFileSystem.cpp b/src/EspFileSystem.cpp index 0087f9fe..0f71a935 100644 --- a/src/EspFileSystem.cpp +++ b/src/EspFileSystem.cpp @@ -8,68 +8,3 @@ bool fileSystemInit() { SerialPrint(F("i"), F("FS"), F("Init completed")); return true; } - -File seekFile(const String& filename, size_t position) { - String path = filepath(filename); - auto file = FileFS.open(path, "r"); - if (!file) { - SerialPrint(F("E"), F("FS"), F("seek file error")); - } - file.seek(position, SeekSet); - return file; -} - -const String writeFile(const String& filename, const String& str) { - String path = filepath(filename); - auto file = FileFS.open(path, "w"); - if (!file) { - return "failed"; - } - file.print(str); - file.close(); - return "sucсess"; -} - -const String readFile(const String& filename, size_t max_size) { - String path = filepath(filename); - auto file = FileFS.open(path, "r"); - if (!file) { - return "failed"; - } - size_t size = file.size(); - if (size > max_size) { - file.close(); - return "large"; - } - String temp = file.readString(); - file.close(); - return temp; -} - -const String filepath(const String& filename) { - return filename.startsWith("/") ? filename : "/" + filename; -} - -bool cutFile(const String& src, const String& dst) { - String srcPath = filepath(src); - String dstPath = filepath(dst); - SerialPrint(F("i"), F("FS"), "cut " + srcPath + " to " + dstPath); - if (!FileFS.exists(srcPath)) { - SerialPrint(F("E"), F("FS"), "not exist: " + srcPath); - return false; - } - if (FileFS.exists(dstPath)) { - FileFS.remove(dstPath); - } - auto srcFile = FileFS.open(srcPath, "r"); - auto dstFile = FileFS.open(dstPath, "w"); - uint8_t buf[512]; - while (srcFile.available()) { - size_t len = srcFile.read(buf, 512); - dstFile.write(buf, len); - } - srcFile.close(); - dstFile.close(); - FileFS.remove(srcPath); - return true; -} \ No newline at end of file diff --git a/src/Global.cpp b/src/Global.cpp new file mode 100644 index 00000000..967eeb71 --- /dev/null +++ b/src/Global.cpp @@ -0,0 +1,9 @@ +#include "Global.h" + +//глобальные объекты классов +TickerScheduler ts(MYTEST + 1); + +//глобальные переменные +String settingsFlashJson = "{}"; //переменная в которой хранятся все настройки, синхронизированна с flash памятью +String paramsFlashJson = "{}"; //переменная в которой хранятся все параметры, синхронизированна с flash памятью +String paramsHeapJson = "{}"; //переменная в которой хранятся все параметры, находится в оперативной памяти только \ No newline at end of file diff --git a/src/WebServer.cpp b/src/WebServer.cpp new file mode 100644 index 00000000..a690cf9c --- /dev/null +++ b/src/WebServer.cpp @@ -0,0 +1,213 @@ +// +// +// +// AsyncWebSocket ws("/ws"); +// AsyncEventSource events("/events"); +// +// +// +// +// +// void init() { +// String login = jsonReadStr(settingsFlashJson, "weblogin"); +// String pass = jsonReadStr(settingsFlashJson, "webpass"); +//#ifdef ESP32 +// server.addHandler(new FSEditor(FileFS, login, pass)); +//#else +// server.addHandler(new FSEditor(login, pass)); +//#endif +// +// server.serveStatic("/css/", FileFS, "/css/").setCacheControl("max-age=600"); +// server.serveStatic("/js/", FileFS, "/js/").setCacheControl("max-age=600"); +// server.serveStatic("/favicon.ico", FileFS, "/favicon.ico").setCacheControl("max-age=600"); +// server.serveStatic("/icon.jpeg", FileFS, "/icon.jpeg").setCacheControl("max-age=600"); +// server.serveStatic("/edit", FileFS, "/edit").setCacheControl("max-age=600"); +// +//#ifdef svelte +// server.serveStatic("/", FileFS, "/").setDefaultFile("index.html").setAuthentication(login.c_str(), pass.c_str()); +//#else +// server.serveStatic("/", FileFS, "/").setDefaultFile("index.htm").setAuthentication(login.c_str(), pass.c_str()); +//#endif +// +// server.onNotFound([](AsyncWebServerRequest *request) { +// SerialPrint("[E]", "WebServer", "not found:\n" + getRequestInfo(request)); +// request->send(404); +// }); +// +// server.onFileUpload([](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) { +// // TODO +// if (!index) { +// SerialPrint("I", "WebServer", "start upload " + filename); +// } +// if (final) { +// SerialPrint("I", "WebServer", "finish upload: " + prettyBytes(index + len)); +// } +// }); +// +// // динамические данные +// server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest *request) { +// request->send(200, "application/json", configLiveJson); +// }); +// +// server.on("/config.store.json", HTTP_GET, [](AsyncWebServerRequest *request) { +// request->send(200, "application/json", paramsFlashJson); +// }); +// +// // данные не являющиеся событиями +// server.on("/config.option.json", HTTP_GET, [](AsyncWebServerRequest *request) { +// request->send(200, "application/json", paramsHeapJson); +// }); +// +// // для хранения постоянных данных +// server.on("/config.setup.json", HTTP_GET, [](AsyncWebServerRequest *request) { +// request->send(200, "application/json", settingsFlashJson); +// }); +// +// server.on("/cmd", HTTP_GET, [](AsyncWebServerRequest *request) { +// String cmdStr = request->getParam("command")->value(); +// SerialPrint("I", "WebServer", "do: " + cmdStr); +// loopCmdAdd(cmdStr); +// request->send(200, "text/html", "OK"); +// }); +// +// server.begin(); +// +// initOta(); +// initMDNS(); +// initWS(); +// +// SerialPrint("I", F("HTTP"), F("HttpServer Init")); +//} +// +// void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { +//#ifdef WEBSOCKET_ENABLED +// if (type == WS_EVT_CONNECT) { +// SerialPrint("I", F("WS"), F("CONNECTED")); +// Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); +// // client->printf(json.c_str(), client->id()); +// // client->ping(); +// } else if (type == WS_EVT_DISCONNECT) { +// Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); +// } else if (type == WS_EVT_ERROR) { +// Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t *)arg), (char *)data); +// } else if (type == WS_EVT_PONG) { +// Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char *)data : ""); +// } else if (type == WS_EVT_DATA) { +// AwsFrameInfo *info = (AwsFrameInfo *)arg; +// String msg = ""; +// if (info->final && info->index == 0 && info->len == len) { +// // the whole message is in a single frame and we got all of it's data +// Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT) ? "text" : "binary", info->len); +// +// if (info->opcode == WS_TEXT) { +// for (size_t i = 0; i < info->len; i++) { +// msg += (char)data[i]; +// } +// } else { +// char buff[3]; +// for (size_t i = 0; i < info->len; i++) { +// sprintf(buff, "%02x ", (uint8_t)data[i]); +// msg += buff; +// } +// } +// Serial.printf("%s\n", msg.c_str()); +// +// if (msg.startsWith("HELLO")) { +// SerialPrint("I", F("WS"), F("Full update")); +// // publishWidgetsWS(); +// // publishStateWS(); +// // choose_log_date_and_send(); // функцию выгрузки архива с графиком я не сделал. Забираю при выгрузке по MQTT +// } +// +// if (info->opcode == WS_TEXT) +// client->text("{}"); +// else +// client->binary("{}"); +// } else { +// // message is comprised of multiple frames or the frame is split into multiple packets +// if (info->index == 0) { +// if (info->num == 0) +// Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary"); +// Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); +// } +// +// Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len); +// +// if (info->opcode == WS_TEXT) { +// for (size_t i = 0; i < len; i++) { +// msg += (char)data[i]; +// } +// } else { +// char buff[3]; +// for (size_t i = 0; i < len; i++) { +// sprintf(buff, "%02x ", (uint8_t)data[i]); +// msg += buff; +// } +// } +// Serial.printf("%s\n", msg.c_str()); +// +// if ((info->index + len) == info->len) { +// Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); +// if (info->final) { +// Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary"); +// if (info->message_opcode == WS_TEXT) +// client->text("I got your text message"); +// else +// client->binary("I got your binary message"); +// } +// } +// } +// } +//#endif +// ; +//} +// +// void initMDNS() { +//#ifdef MDNS_ENABLED +// MDNS.addService("http", "tcp", 80); +// // TODO Add Adduino OTA +//#endif +// ; +//} +// +// void initOta() { +//#ifdef OTA_UPDATES_ENABLED +// ArduinoOTA.onStart([]() { +// events.send("Update Start", "ota"); +// }); +// ArduinoOTA.onEnd([]() { +// events.send("Update End", "ota"); +// }); +// ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { +// char p[32]; +// sprintf(p, "Progress: %u%%\n", (progress / (total / 100))); +// events.send(p, "ota"); +// }); +// ArduinoOTA.onError([](ota_error_t error) { +// if (error == OTA_AUTH_ERROR) +// events.send("Auth Failed", "ota"); +// else if (error == OTA_BEGIN_ERROR) +// events.send("Begin Failed", "ota"); +// else if (error == OTA_CONNECT_ERROR) +// events.send("Connect Failed", "ota"); +// else if (error == OTA_RECEIVE_ERROR) +// events.send("Recieve Failed", "ota"); +// else if (error == OTA_END_ERROR) +// events.send("End Failed", "ota"); +// }); +// ArduinoOTA.setHostname(hostName); +// ArduinoOTA.begin(); +//#endif +// ; +//} +// +// void initWS() { +//#ifdef WEBSOCKET_ENABLED +// ws.onEvent(onWsEvent); +// server.addHandler(&ws); +// events.onConnect([](AsyncEventSourceClient *client) { +// client->send("", NULL, millis(), 1000); +// }); +// server.addHandler(&events); +//#endif +//} diff --git a/src/main.cpp b/src/main.cpp index 2baafd48..ca40b9ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,8 @@ void setup() { //инициализация файловой системы fileSystemInit(); - //выводим остаток оперативной памяти после старта (пустой код без wifi остаток = 50.28 kB) + //выводим остаток оперативной памяти после старта + // 22.12.21 пустой код без wifi остаток = 50.28 kB SerialPrint(F("i"), F("HEAP"), prettyBytes(ESP.getFreeHeap())); } diff --git a/src/utils/FileUtils.cpp b/src/utils/FileUtils.cpp new file mode 100644 index 00000000..9b0970ba --- /dev/null +++ b/src/utils/FileUtils.cpp @@ -0,0 +1,66 @@ +#include "Utils/FileUtils.h" + +File seekFile(const String& filename, size_t position) { + String path = filepath(filename); + auto file = FileFS.open(path, "r"); + if (!file) { + SerialPrint(F("E"), F("FS"), F("seek file error")); + } + file.seek(position, SeekSet); + return file; +} + +const String writeFile(const String& filename, const String& str) { + String path = filepath(filename); + auto file = FileFS.open(path, "w"); + if (!file) { + return "failed"; + } + file.print(str); + file.close(); + return "sucсess"; +} + +const String readFile(const String& filename, size_t max_size) { + String path = filepath(filename); + auto file = FileFS.open(path, "r"); + if (!file) { + return "failed"; + } + size_t size = file.size(); + if (size > max_size) { + file.close(); + return "large"; + } + String temp = file.readString(); + file.close(); + return temp; +} + +const String filepath(const String& filename) { + return filename.startsWith("/") ? filename : "/" + filename; +} + +bool cutFile(const String& src, const String& dst) { + String srcPath = filepath(src); + String dstPath = filepath(dst); + SerialPrint(F("i"), F("FS"), "cut " + srcPath + " to " + dstPath); + if (!FileFS.exists(srcPath)) { + SerialPrint(F("E"), F("FS"), "not exist: " + srcPath); + return false; + } + if (FileFS.exists(dstPath)) { + FileFS.remove(dstPath); + } + auto srcFile = FileFS.open(srcPath, "r"); + auto dstFile = FileFS.open(dstPath, "w"); + uint8_t buf[512]; + while (srcFile.available()) { + size_t len = srcFile.read(buf, 512); + dstFile.write(buf, len); + } + srcFile.close(); + dstFile.close(); + FileFS.remove(srcPath); + return true; +} \ No newline at end of file diff --git a/src/utils/JsonUtils.cpp b/src/utils/JsonUtils.cpp new file mode 100644 index 00000000..b47a9d72 --- /dev/null +++ b/src/utils/JsonUtils.cpp @@ -0,0 +1,176 @@ +#include "Utils/JsonUtils.h" + +#include "Utils/FileUtils.h" + +// depricated====================================================================== +String jsonReadStr(String& json, String name) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) SerialPrint("EE", F("jsonRead"), error.f_str()); + return doc[name].as(); +} + +boolean jsonReadBool(String& json, String name) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) SerialPrint("EE", F("jsonRead"), error.f_str()); + return doc[name].as(); +} + +int jsonReadInt(String& json, String name) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) SerialPrint("EE", F("jsonRead"), error.f_str()); + return doc[name].as(); +} + +// new============================================================================== +bool jsonRead(String& json, String key, String& value) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + SerialPrint("EE", F("jsonRead"), error.f_str()); + ret = false; + } else if (!doc.containsKey(key)) { + SerialPrint("EE", F("jsonRead"), key + " missing"); + ret = false; + } + value = doc[key].as(); + return ret; +} + +bool jsonRead(String& json, String key, bool& value) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + SerialPrint("EE", F("jsonRead"), error.f_str()); + ret = false; + } else if (!doc.containsKey(key)) { + SerialPrint("EE", F("jsonRead"), key + " missing"); + ret = false; + } + value = doc[key].as(); + return ret; +} + +bool jsonRead(String& json, String key, int& value) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + SerialPrint("EE", F("jsonRead"), error.f_str()); + ret = false; + } else if (!doc.containsKey(key)) { + SerialPrint("EE", F("jsonRead"), key + " missing"); + ret = false; + } + value = doc[key].as(); + return ret; +} +// depricated======================================================================== +String jsonWriteStr(String& json, String name, String value) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) SerialPrint("EE", F("jsonWrite"), error.f_str()); + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +String jsonWriteBool(String& json, String name, boolean value) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) SerialPrint("EE", F("jsonWrite"), error.f_str()); + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +String jsonWriteInt(String& json, String name, int value) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) SerialPrint("EE", F("jsonWrite"), error.f_str()); + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +String jsonWriteFloat(String& json, String name, float value) { + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) SerialPrint("EE", F("jsonWrite"), error.f_str()); + doc[name] = value; + json = ""; + serializeJson(doc, json); + return json; +} + +// new============================================================================== +bool jsonWriteStr_(String& json, String key, String value) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + SerialPrint("EE", F("jsonWrite"), error.f_str()); + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} + +bool jsonWriteBool_(String& json, String key, bool value) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + SerialPrint("EE", F("jsonWrite"), error.f_str()); + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} + +bool jsonWriteInt_(String& json, String key, int value) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + SerialPrint("EE", F("jsonWrite"), error.f_str()); + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} + +bool jsonWriteFloat_(String& json, String key, float value) { + bool ret = true; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); + DeserializationError error = deserializeJson(doc, json); + if (error) { + SerialPrint("EE", F("jsonWrite"), error.f_str()); + ret = false; + } + doc[key] = value; + json = ""; + serializeJson(doc, json); + return ret; +} +//================================================================================= +void saveConfig() { + writeFile(String("config.json"), settingsFlashJson); +} + +void saveStore() { + writeFile(String("store.json"), paramsFlashJson); +} \ No newline at end of file diff --git a/src/utils/WiFiUtils.cpp b/src/utils/WiFiUtils.cpp new file mode 100644 index 00000000..5e57d25c --- /dev/null +++ b/src/utils/WiFiUtils.cpp @@ -0,0 +1,170 @@ +#include "Utils/WiFiUtils.h" + +void routerConnect() { + WiFi.setAutoConnect(false); + WiFi.persistent(false); + + WiFi.mode(WIFI_STA); + byte tries = 40; + + String _ssid = jsonReadStr(settingsFlashJson, "routerssid"); + String _password = jsonReadStr(settingsFlashJson, "routerpass"); + + if (_ssid == "" && _password == "") { + WiFi.begin(); + } else { + WiFi.begin(_ssid.c_str(), _password.c_str()); +#ifdef ESP32 + WiFi.setTxPower(WIFI_POWER_19_5dBm); +#else + WiFi.setOutputPower(20.5); +#endif + SerialPrint("I", "WIFI", "ssid: " + _ssid); + SerialPrint("I", "WIFI", "pass: " + _password); + } + + while (--tries && WiFi.status() != WL_CONNECTED) { + if (WiFi.status() == WL_CONNECT_FAILED) { + SerialPrint("E", "WIFI", "password is not correct"); + tries = 1; + jsonWriteInt(paramsHeapJson, "pass_status", 1); + } + Serial.print("."); + delay(1000); + } + + if (WiFi.status() != WL_CONNECTED) { + Serial.println(""); + startAPMode(); + } else { + Serial.println(""); + SerialPrint("I", "WIFI", "http://" + WiFi.localIP().toString()); + jsonWriteStr(settingsFlashJson, "ip", WiFi.localIP().toString()); + + //mqttInit(); + } + SerialPrint("I", F("WIFI"), F("Network Init")); +} + +bool startAPMode() { + SerialPrint("I", "WIFI", "AP Mode"); + + WiFi.disconnect(); + WiFi.mode(WIFI_AP); + + String _ssidAP = jsonReadStr(settingsFlashJson, "apssid"); + String _passwordAP = jsonReadStr(settingsFlashJson, "appass"); + + WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); + IPAddress myIP = WiFi.softAPIP(); + + SerialPrint("I", "WIFI", "AP IP: " + myIP.toString()); + jsonWriteStr(settingsFlashJson, "ip", myIP.toString()); + + // if (jsonReadInt(paramsHeapJson, "pass_status") != 1) { + ts.add( + WIFI_SCAN, 10 * 1000, [&](void*) { + String sta_ssid = jsonReadStr(settingsFlashJson, "routerssid"); + + SerialPrint("I", "WIFI", "scanning for " + sta_ssid); + + if (RouterFind(sta_ssid)) { + ts.remove(WIFI_SCAN); + WiFi.scanDelete(); + routerConnect(); + } + }, + nullptr, true); + //} + return true; +} + +boolean RouterFind(String ssid) { + bool res = false; + int n = WiFi.scanComplete(); + SerialPrint("I", "WIFI", "scan result: " + String(n, DEC)); + + if (n == -2) { //Сканирование не было запущено, запускаем + SerialPrint("I", "WIFI", "start scanning"); + WiFi.scanNetworks(true, false); // async, show_hidden + } + + else if (n == -1) { //Сканирование все еще выполняется + SerialPrint("I", "WIFI", "scanning in progress"); + } + + else if (n == 0) { //ни одна сеть не найдена + SerialPrint("I", "WIFI", "no networks found"); + WiFi.scanNetworks(true, false); + } + + else if (n > 0) { + for (int8_t i = 0; i < n; i++) { + if (WiFi.SSID(i) == ssid) { + res = true; + } + SerialPrint("I", "WIFI", (res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); + } + } + WiFi.scanDelete(); + return res; +} + +boolean isNetworkActive() { + return WiFi.status() == WL_CONNECTED; +} + +uint8_t RSSIquality() { + uint8_t res = 0; + if (WiFi.status() == WL_CONNECTED) { + int rssi = WiFi.RSSI(); + if (rssi >= -50) { + res = 6; //"Excellent"; + } else if (rssi < -50 && rssi >= -60) { + res = 5; //"Very good"; + } else if (rssi < -60 && rssi >= -70) { + res = 4; //"Good"; + } else if (rssi < -70 && rssi >= -80) { + res = 3; //"Low"; + } else if (rssi < -80 && rssi > -100) { + res = 2; //"Very low"; + } else if (rssi <= -100) { + res = 1; //"No signal"; + } + } + return res; +} + +void wifiSignalInit() { + ts.add( + SYGNAL, 1000 * 60, [&](void*) { + //SerialPrint("I", "System", printMemoryStatus()); + + //getFSInfo(); + + switch (RSSIquality()) { + case 0: + jsonWriteStr(settingsFlashJson, F("signal"), F("Уровень WiFi сигнала: не подключено к роутеру")); + break; + case 1: + jsonWriteStr(settingsFlashJson, F("signal"), F("Уровень WiFi сигнала: нет сигнала")); + break; + case 2: + jsonWriteStr(settingsFlashJson, F("signal"), F("Уровень WiFi сигнала: очень низкий")); + break; + case 3: + jsonWriteStr(settingsFlashJson, F("signal"), F("Уровень WiFi сигнала: низкий")); + break; + case 4: + jsonWriteStr(settingsFlashJson, F("signal"), F("Уровень WiFi сигнала: хороший")); + break; + case 5: + jsonWriteStr(settingsFlashJson, F("signal"), F("Уровень WiFi сигнала: очень хороший")); + break; + case 6: + jsonWriteStr(settingsFlashJson, F("signal"), F("Уровень WiFi сигнала: отличный")); + break; + } + }, + nullptr, true); +}