From 00af66378c5ddbccbee28cedaf274b9164881ff0 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 27 May 2025 15:48:37 +0200 Subject: [PATCH 01/11] Import unit-test from ArduinoCore-API --- extras/test/.gitignore | 1 + extras/test/ArduinoCore-api/Arduino.h | 1 + extras/test/ArduinoCore-api/api/ArduinoAPI.h | 57 + extras/test/ArduinoCore-api/api/Binary.h | 552 + extras/test/ArduinoCore-api/api/Common.cpp | 29 + extras/test/ArduinoCore-api/api/Common.h | 190 + extras/test/ArduinoCore-api/api/Compat.h | 35 + extras/test/ArduinoCore-api/api/IPAddress.h | 122 + extras/test/ArduinoCore-api/api/Interrupts.h | 63 + .../test/ArduinoCore-api/api/PluggableUSB.h | 78 + extras/test/ArduinoCore-api/api/Print.cpp | 388 + extras/test/ArduinoCore-api/api/Print.h | 97 + extras/test/ArduinoCore-api/api/Printable.h | 40 + extras/test/ArduinoCore-api/api/Server.h | 31 + extras/test/ArduinoCore-api/api/Stream.cpp | 321 + extras/test/ArduinoCore-api/api/Stream.h | 133 + extras/test/ArduinoCore-api/api/String.cpp | 750 + extras/test/ArduinoCore-api/api/String.h | 255 + extras/test/ArduinoCore-api/api/USBAPI.h | 64 + extras/test/ArduinoCore-api/api/Udp.h | 92 + extras/test/ArduinoCore-api/api/WCharacter.h | 171 + .../deprecated-avr-comp/avr/dtostrf.c.impl | 40 + .../api/deprecated-avr-comp/avr/dtostrf.h | 34 + .../api/deprecated-avr-comp/avr/interrupt.h | 23 + .../api/deprecated-avr-comp/avr/pgmspace.h | 124 + extras/test/ArduinoCore-api/api/itoa.h | 38 + extras/test/CMakeLists.txt | 109 + .../test/external/ArxContainer/ArxContainer.h | 884 + .../ArxContainer/ArxContainer/has_include.h | 30 + .../ArxContainer/has_libstdcplusplus.h | 35 + .../ArxContainer/initializer_list.h | 32 + .../ArxContainer/replace_minmax_macros.h | 35 + extras/test/external/ArxContainer/LICENSE | 21 + extras/test/external/ArxContainer/README.md | 197 + .../test/external/ArxContainer/library.json | 18 + .../external/ArxContainer/library.properties | 9 + .../external/ArxTypeTraits/ArxTypeTraits.h | 38 + .../ArxTypeTraits/ArxTypeTraits/functional.h | 165 + .../ArxTypeTraits/ArxTypeTraits/has_include.h | 30 + .../ArxTypeTraits/has_libstdcplusplus.h | 35 + .../ArxTypeTraits/initializer_list.h | 30 + .../ArxTypeTraits/replace_minmax_macros.h | 35 + .../ArxTypeTraits/ArxTypeTraits/tuple.h | 82 + .../ArxTypeTraits/ArxTypeTraits/type_traits.h | 983 + extras/test/external/ArxTypeTraits/LICENSE | 21 + extras/test/external/ArxTypeTraits/README.md | 180 + .../test/external/ArxTypeTraits/library.json | 18 + .../external/ArxTypeTraits/library.properties | 9 + extras/test/external/DebugLog/DebugLog.h | 56 + .../external/DebugLog/DebugLog/FileLogger.h | 95 + .../test/external/DebugLog/DebugLog/Manager.h | 402 + .../test/external/DebugLog/DebugLog/Types.h | 135 + .../test/external/DebugLog/DebugLogDisable.h | 15 + .../test/external/DebugLog/DebugLogEnable.h | 65 + .../external/DebugLog/DebugLogRestoreState.h | 5 + extras/test/external/DebugLog/LICENSE | 21 + extras/test/external/DebugLog/README.md | 593 + extras/test/external/DebugLog/library.json | 22 + .../test/external/DebugLog/library.properties | 10 + .../external/catch/v2.13.9/include/catch.hpp | 17970 ++++++++++++++++ extras/test/include/MillisFake.h | 32 + extras/test/include/PrintMock.h | 31 + extras/test/include/PrintableMock.h | 35 + extras/test/include/StreamMock.h | 38 + extras/test/src/Common/test_makeWord.cpp | 34 + extras/test/src/Common/test_map.cpp | 48 + extras/test/src/Common/test_max.cpp | 78 + extras/test/src/Common/test_min.cpp | 78 + extras/test/src/MillisFake.cpp | 65 + .../test/src/Print/test_availableForWrite.cpp | 25 + .../test/src/Print/test_clearWriteError.cpp | 27 + extras/test/src/Print/test_getWriteError.cpp | 32 + extras/test/src/Print/test_print.cpp | 197 + extras/test/src/Print/test_println.cpp | 150 + extras/test/src/PrintMock.cpp | 21 + extras/test/src/RPC/test_RPCClient.cpp | 82 + extras/test/src/Stream/test_find.cpp | 80 + extras/test/src/Stream/test_findUntil.cpp | 51 + extras/test/src/Stream/test_getTimeout.cpp | 23 + extras/test/src/Stream/test_parseFloat.cpp | 123 + extras/test/src/Stream/test_parseInt.cpp | 105 + extras/test/src/Stream/test_readBytes.cpp | 51 + .../test/src/Stream/test_readBytesUntil.cpp | 52 + extras/test/src/Stream/test_readString.cpp | 28 + .../test/src/Stream/test_readStringUntil.cpp | 38 + extras/test/src/Stream/test_setTimeout.cpp | 26 + extras/test/src/StreamMock.cpp | 53 + extras/test/src/String/StringPrinter.h | 30 + extras/test/src/String/test_String.cpp | 164 + .../src/String/test_characterAccessFunc.cpp | 71 + extras/test/src/String/test_compareTo.cpp | 104 + .../test/src/String/test_comparisonFunc.cpp | 159 + extras/test/src/String/test_concat.cpp | 106 + extras/test/src/String/test_indexOf.cpp | 104 + extras/test/src/String/test_isEmpty.cpp | 31 + extras/test/src/String/test_lastIndexOf.cpp | 104 + extras/test/src/String/test_length.cpp | 31 + extras/test/src/String/test_move.cpp | 46 + extras/test/src/String/test_operators.cpp | 168 + extras/test/src/String/test_remove.cpp | 68 + extras/test/src/String/test_replace.cpp | 91 + extras/test/src/String/test_substring.cpp | 42 + extras/test/src/String/test_toDouble.cpp | 47 + extras/test/src/String/test_toFloat.cpp | 40 + extras/test/src/String/test_toInt.cpp | 47 + extras/test/src/String/test_toLowerCase.cpp | 26 + extras/test/src/String/test_toUpperCase.cpp | 26 + extras/test/src/String/test_trim.cpp | 47 + extras/test/src/delay.c | 21 + extras/test/src/dtostrf.cpp | 43 + extras/test/src/itoa.cpp | 64 + extras/test/src/main.cpp | 12 + 112 files changed, 29409 insertions(+) create mode 100644 extras/test/.gitignore create mode 100644 extras/test/ArduinoCore-api/Arduino.h create mode 100644 extras/test/ArduinoCore-api/api/ArduinoAPI.h create mode 100644 extras/test/ArduinoCore-api/api/Binary.h create mode 100644 extras/test/ArduinoCore-api/api/Common.cpp create mode 100644 extras/test/ArduinoCore-api/api/Common.h create mode 100644 extras/test/ArduinoCore-api/api/Compat.h create mode 100644 extras/test/ArduinoCore-api/api/IPAddress.h create mode 100644 extras/test/ArduinoCore-api/api/Interrupts.h create mode 100644 extras/test/ArduinoCore-api/api/PluggableUSB.h create mode 100644 extras/test/ArduinoCore-api/api/Print.cpp create mode 100644 extras/test/ArduinoCore-api/api/Print.h create mode 100644 extras/test/ArduinoCore-api/api/Printable.h create mode 100644 extras/test/ArduinoCore-api/api/Server.h create mode 100644 extras/test/ArduinoCore-api/api/Stream.cpp create mode 100644 extras/test/ArduinoCore-api/api/Stream.h create mode 100644 extras/test/ArduinoCore-api/api/String.cpp create mode 100644 extras/test/ArduinoCore-api/api/String.h create mode 100644 extras/test/ArduinoCore-api/api/USBAPI.h create mode 100644 extras/test/ArduinoCore-api/api/Udp.h create mode 100644 extras/test/ArduinoCore-api/api/WCharacter.h create mode 100644 extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.c.impl create mode 100644 extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.h create mode 100644 extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/interrupt.h create mode 100644 extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/pgmspace.h create mode 100644 extras/test/ArduinoCore-api/api/itoa.h create mode 100644 extras/test/CMakeLists.txt create mode 100644 extras/test/external/ArxContainer/ArxContainer.h create mode 100644 extras/test/external/ArxContainer/ArxContainer/has_include.h create mode 100644 extras/test/external/ArxContainer/ArxContainer/has_libstdcplusplus.h create mode 100644 extras/test/external/ArxContainer/ArxContainer/initializer_list.h create mode 100644 extras/test/external/ArxContainer/ArxContainer/replace_minmax_macros.h create mode 100644 extras/test/external/ArxContainer/LICENSE create mode 100644 extras/test/external/ArxContainer/README.md create mode 100644 extras/test/external/ArxContainer/library.json create mode 100644 extras/test/external/ArxContainer/library.properties create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits.h create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits/functional.h create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits/has_include.h create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits/has_libstdcplusplus.h create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits/initializer_list.h create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits/replace_minmax_macros.h create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits/tuple.h create mode 100644 extras/test/external/ArxTypeTraits/ArxTypeTraits/type_traits.h create mode 100644 extras/test/external/ArxTypeTraits/LICENSE create mode 100644 extras/test/external/ArxTypeTraits/README.md create mode 100644 extras/test/external/ArxTypeTraits/library.json create mode 100644 extras/test/external/ArxTypeTraits/library.properties create mode 100644 extras/test/external/DebugLog/DebugLog.h create mode 100644 extras/test/external/DebugLog/DebugLog/FileLogger.h create mode 100644 extras/test/external/DebugLog/DebugLog/Manager.h create mode 100644 extras/test/external/DebugLog/DebugLog/Types.h create mode 100644 extras/test/external/DebugLog/DebugLogDisable.h create mode 100644 extras/test/external/DebugLog/DebugLogEnable.h create mode 100644 extras/test/external/DebugLog/DebugLogRestoreState.h create mode 100644 extras/test/external/DebugLog/LICENSE create mode 100644 extras/test/external/DebugLog/README.md create mode 100644 extras/test/external/DebugLog/library.json create mode 100644 extras/test/external/DebugLog/library.properties create mode 100644 extras/test/external/catch/v2.13.9/include/catch.hpp create mode 100644 extras/test/include/MillisFake.h create mode 100644 extras/test/include/PrintMock.h create mode 100644 extras/test/include/PrintableMock.h create mode 100644 extras/test/include/StreamMock.h create mode 100644 extras/test/src/Common/test_makeWord.cpp create mode 100644 extras/test/src/Common/test_map.cpp create mode 100644 extras/test/src/Common/test_max.cpp create mode 100644 extras/test/src/Common/test_min.cpp create mode 100644 extras/test/src/MillisFake.cpp create mode 100644 extras/test/src/Print/test_availableForWrite.cpp create mode 100644 extras/test/src/Print/test_clearWriteError.cpp create mode 100644 extras/test/src/Print/test_getWriteError.cpp create mode 100644 extras/test/src/Print/test_print.cpp create mode 100644 extras/test/src/Print/test_println.cpp create mode 100644 extras/test/src/PrintMock.cpp create mode 100644 extras/test/src/RPC/test_RPCClient.cpp create mode 100644 extras/test/src/Stream/test_find.cpp create mode 100644 extras/test/src/Stream/test_findUntil.cpp create mode 100644 extras/test/src/Stream/test_getTimeout.cpp create mode 100644 extras/test/src/Stream/test_parseFloat.cpp create mode 100644 extras/test/src/Stream/test_parseInt.cpp create mode 100644 extras/test/src/Stream/test_readBytes.cpp create mode 100644 extras/test/src/Stream/test_readBytesUntil.cpp create mode 100644 extras/test/src/Stream/test_readString.cpp create mode 100644 extras/test/src/Stream/test_readStringUntil.cpp create mode 100644 extras/test/src/Stream/test_setTimeout.cpp create mode 100644 extras/test/src/StreamMock.cpp create mode 100644 extras/test/src/String/StringPrinter.h create mode 100644 extras/test/src/String/test_String.cpp create mode 100644 extras/test/src/String/test_characterAccessFunc.cpp create mode 100644 extras/test/src/String/test_compareTo.cpp create mode 100644 extras/test/src/String/test_comparisonFunc.cpp create mode 100644 extras/test/src/String/test_concat.cpp create mode 100644 extras/test/src/String/test_indexOf.cpp create mode 100644 extras/test/src/String/test_isEmpty.cpp create mode 100644 extras/test/src/String/test_lastIndexOf.cpp create mode 100644 extras/test/src/String/test_length.cpp create mode 100644 extras/test/src/String/test_move.cpp create mode 100644 extras/test/src/String/test_operators.cpp create mode 100644 extras/test/src/String/test_remove.cpp create mode 100644 extras/test/src/String/test_replace.cpp create mode 100644 extras/test/src/String/test_substring.cpp create mode 100644 extras/test/src/String/test_toDouble.cpp create mode 100644 extras/test/src/String/test_toFloat.cpp create mode 100644 extras/test/src/String/test_toInt.cpp create mode 100644 extras/test/src/String/test_toLowerCase.cpp create mode 100644 extras/test/src/String/test_toUpperCase.cpp create mode 100644 extras/test/src/String/test_trim.cpp create mode 100644 extras/test/src/delay.c create mode 100644 extras/test/src/dtostrf.cpp create mode 100644 extras/test/src/itoa.cpp create mode 100644 extras/test/src/main.cpp diff --git a/extras/test/.gitignore b/extras/test/.gitignore new file mode 100644 index 0000000..c795b05 --- /dev/null +++ b/extras/test/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/Arduino.h b/extras/test/ArduinoCore-api/Arduino.h new file mode 100644 index 0000000..ea1d87d --- /dev/null +++ b/extras/test/ArduinoCore-api/Arduino.h @@ -0,0 +1 @@ +#include "api/ArduinoAPI.h" diff --git a/extras/test/ArduinoCore-api/api/ArduinoAPI.h b/extras/test/ArduinoCore-api/api/ArduinoAPI.h new file mode 100644 index 0000000..3d53085 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/ArduinoAPI.h @@ -0,0 +1,57 @@ +/* + Arduino API main include + Copyright (c) 2016 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef ARDUINO_API_H +#define ARDUINO_API_H + +// version 1.5.1 +#define ARDUINO_API_VERSION 10501 + +#include "Binary.h" + +#ifdef __cplusplus +#include "Interrupts.h" +#include "IPAddress.h" +#include "Print.h" +#include "Printable.h" +#include "PluggableUSB.h" +#include "Server.h" +#include "String.h" +#include "Stream.h" +#include "Udp.h" +#include "USBAPI.h" +#include "WCharacter.h" +#endif + +/* Standard C library includes */ +#include +#include +#include +#include +#include + +// Misc Arduino core functions +#include "Common.h" + +#ifdef __cplusplus +// Compatibility layer for older code +#include "Compat.h" +#endif + +#endif diff --git a/extras/test/ArduinoCore-api/api/Binary.h b/extras/test/ArduinoCore-api/api/Binary.h new file mode 100644 index 0000000..947542e --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Binary.h @@ -0,0 +1,552 @@ +/* + binary.h - Definitions for binary constants + Deprecated -- use 0b binary literals instead + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +/* If supported, 0b binary literals are preferable to these constants. + * In that case, warn the user about these being deprecated (if possible). */ +#if __cplusplus >= 201402L + /* C++14 introduces binary literals; C++11 introduces [[deprecated()]] */ + #define DEPRECATED(x) [[deprecated("use " #x " instead")]] +#elif __GNUC__ >= 6 + /* GCC 4.3 supports binary literals; GCC 6 supports __deprecated__ on enums*/ + #define DEPRECATED(x) __attribute__ ((__deprecated__ ("use " #x " instead"))) +#else + /* binary literals not supported, or "deprecated" warning not displayable */ + #define DEPRECATED(x) +#endif + +enum { + B0 DEPRECATED(0b0 ) = 0, + B00 DEPRECATED(0b00 ) = 0, + B000 DEPRECATED(0b000 ) = 0, + B0000 DEPRECATED(0b0000 ) = 0, + B00000 DEPRECATED(0b00000 ) = 0, + B000000 DEPRECATED(0b000000 ) = 0, + B0000000 DEPRECATED(0b0000000 ) = 0, + B00000000 DEPRECATED(0b00000000) = 0, + B1 DEPRECATED(0b1 ) = 1, + B01 DEPRECATED(0b01 ) = 1, + B001 DEPRECATED(0b001 ) = 1, + B0001 DEPRECATED(0b0001 ) = 1, + B00001 DEPRECATED(0b00001 ) = 1, + B000001 DEPRECATED(0b000001 ) = 1, + B0000001 DEPRECATED(0b0000001 ) = 1, + B00000001 DEPRECATED(0b00000001) = 1, + B10 DEPRECATED(0b10 ) = 2, + B010 DEPRECATED(0b010 ) = 2, + B0010 DEPRECATED(0b0010 ) = 2, + B00010 DEPRECATED(0b00010 ) = 2, + B000010 DEPRECATED(0b000010 ) = 2, + B0000010 DEPRECATED(0b0000010 ) = 2, + B00000010 DEPRECATED(0b00000010) = 2, + B11 DEPRECATED(0b11 ) = 3, + B011 DEPRECATED(0b011 ) = 3, + B0011 DEPRECATED(0b0011 ) = 3, + B00011 DEPRECATED(0b00011 ) = 3, + B000011 DEPRECATED(0b000011 ) = 3, + B0000011 DEPRECATED(0b0000011 ) = 3, + B00000011 DEPRECATED(0b00000011) = 3, + B100 DEPRECATED(0b100 ) = 4, + B0100 DEPRECATED(0b0100 ) = 4, + B00100 DEPRECATED(0b00100 ) = 4, + B000100 DEPRECATED(0b000100 ) = 4, + B0000100 DEPRECATED(0b0000100 ) = 4, + B00000100 DEPRECATED(0b00000100) = 4, + B101 DEPRECATED(0b101 ) = 5, + B0101 DEPRECATED(0b0101 ) = 5, + B00101 DEPRECATED(0b00101 ) = 5, + B000101 DEPRECATED(0b000101 ) = 5, + B0000101 DEPRECATED(0b0000101 ) = 5, + B00000101 DEPRECATED(0b00000101) = 5, + B110 DEPRECATED(0b110 ) = 6, + B0110 DEPRECATED(0b0110 ) = 6, + B00110 DEPRECATED(0b00110 ) = 6, + B000110 DEPRECATED(0b000110 ) = 6, + B0000110 DEPRECATED(0b0000110 ) = 6, + B00000110 DEPRECATED(0b00000110) = 6, + B111 DEPRECATED(0b111 ) = 7, + B0111 DEPRECATED(0b0111 ) = 7, + B00111 DEPRECATED(0b00111 ) = 7, + B000111 DEPRECATED(0b000111 ) = 7, + B0000111 DEPRECATED(0b0000111 ) = 7, + B00000111 DEPRECATED(0b00000111) = 7, + B1000 DEPRECATED(0b1000 ) = 8, + B01000 DEPRECATED(0b01000 ) = 8, + B001000 DEPRECATED(0b001000 ) = 8, + B0001000 DEPRECATED(0b0001000 ) = 8, + B00001000 DEPRECATED(0b00001000) = 8, + B1001 DEPRECATED(0b1001 ) = 9, + B01001 DEPRECATED(0b01001 ) = 9, + B001001 DEPRECATED(0b001001 ) = 9, + B0001001 DEPRECATED(0b0001001 ) = 9, + B00001001 DEPRECATED(0b00001001) = 9, + B1010 DEPRECATED(0b1010 ) = 10, + B01010 DEPRECATED(0b01010 ) = 10, + B001010 DEPRECATED(0b001010 ) = 10, + B0001010 DEPRECATED(0b0001010 ) = 10, + B00001010 DEPRECATED(0b00001010) = 10, + B1011 DEPRECATED(0b1011 ) = 11, + B01011 DEPRECATED(0b01011 ) = 11, + B001011 DEPRECATED(0b001011 ) = 11, + B0001011 DEPRECATED(0b0001011 ) = 11, + B00001011 DEPRECATED(0b00001011) = 11, + B1100 DEPRECATED(0b1100 ) = 12, + B01100 DEPRECATED(0b01100 ) = 12, + B001100 DEPRECATED(0b001100 ) = 12, + B0001100 DEPRECATED(0b0001100 ) = 12, + B00001100 DEPRECATED(0b00001100) = 12, + B1101 DEPRECATED(0b1101 ) = 13, + B01101 DEPRECATED(0b01101 ) = 13, + B001101 DEPRECATED(0b001101 ) = 13, + B0001101 DEPRECATED(0b0001101 ) = 13, + B00001101 DEPRECATED(0b00001101) = 13, + B1110 DEPRECATED(0b1110 ) = 14, + B01110 DEPRECATED(0b01110 ) = 14, + B001110 DEPRECATED(0b001110 ) = 14, + B0001110 DEPRECATED(0b0001110 ) = 14, + B00001110 DEPRECATED(0b00001110) = 14, + B1111 DEPRECATED(0b1111 ) = 15, + B01111 DEPRECATED(0b01111 ) = 15, + B001111 DEPRECATED(0b001111 ) = 15, + B0001111 DEPRECATED(0b0001111 ) = 15, + B00001111 DEPRECATED(0b00001111) = 15, + B10000 DEPRECATED(0b10000 ) = 16, + B010000 DEPRECATED(0b010000 ) = 16, + B0010000 DEPRECATED(0b0010000 ) = 16, + B00010000 DEPRECATED(0b00010000) = 16, + B10001 DEPRECATED(0b10001 ) = 17, + B010001 DEPRECATED(0b010001 ) = 17, + B0010001 DEPRECATED(0b0010001 ) = 17, + B00010001 DEPRECATED(0b00010001) = 17, + B10010 DEPRECATED(0b10010 ) = 18, + B010010 DEPRECATED(0b010010 ) = 18, + B0010010 DEPRECATED(0b0010010 ) = 18, + B00010010 DEPRECATED(0b00010010) = 18, + B10011 DEPRECATED(0b10011 ) = 19, + B010011 DEPRECATED(0b010011 ) = 19, + B0010011 DEPRECATED(0b0010011 ) = 19, + B00010011 DEPRECATED(0b00010011) = 19, + B10100 DEPRECATED(0b10100 ) = 20, + B010100 DEPRECATED(0b010100 ) = 20, + B0010100 DEPRECATED(0b0010100 ) = 20, + B00010100 DEPRECATED(0b00010100) = 20, + B10101 DEPRECATED(0b10101 ) = 21, + B010101 DEPRECATED(0b010101 ) = 21, + B0010101 DEPRECATED(0b0010101 ) = 21, + B00010101 DEPRECATED(0b00010101) = 21, + B10110 DEPRECATED(0b10110 ) = 22, + B010110 DEPRECATED(0b010110 ) = 22, + B0010110 DEPRECATED(0b0010110 ) = 22, + B00010110 DEPRECATED(0b00010110) = 22, + B10111 DEPRECATED(0b10111 ) = 23, + B010111 DEPRECATED(0b010111 ) = 23, + B0010111 DEPRECATED(0b0010111 ) = 23, + B00010111 DEPRECATED(0b00010111) = 23, + B11000 DEPRECATED(0b11000 ) = 24, + B011000 DEPRECATED(0b011000 ) = 24, + B0011000 DEPRECATED(0b0011000 ) = 24, + B00011000 DEPRECATED(0b00011000) = 24, + B11001 DEPRECATED(0b11001 ) = 25, + B011001 DEPRECATED(0b011001 ) = 25, + B0011001 DEPRECATED(0b0011001 ) = 25, + B00011001 DEPRECATED(0b00011001) = 25, + B11010 DEPRECATED(0b11010 ) = 26, + B011010 DEPRECATED(0b011010 ) = 26, + B0011010 DEPRECATED(0b0011010 ) = 26, + B00011010 DEPRECATED(0b00011010) = 26, + B11011 DEPRECATED(0b11011 ) = 27, + B011011 DEPRECATED(0b011011 ) = 27, + B0011011 DEPRECATED(0b0011011 ) = 27, + B00011011 DEPRECATED(0b00011011) = 27, + B11100 DEPRECATED(0b11100 ) = 28, + B011100 DEPRECATED(0b011100 ) = 28, + B0011100 DEPRECATED(0b0011100 ) = 28, + B00011100 DEPRECATED(0b00011100) = 28, + B11101 DEPRECATED(0b11101 ) = 29, + B011101 DEPRECATED(0b011101 ) = 29, + B0011101 DEPRECATED(0b0011101 ) = 29, + B00011101 DEPRECATED(0b00011101) = 29, + B11110 DEPRECATED(0b11110 ) = 30, + B011110 DEPRECATED(0b011110 ) = 30, + B0011110 DEPRECATED(0b0011110 ) = 30, + B00011110 DEPRECATED(0b00011110) = 30, + B11111 DEPRECATED(0b11111 ) = 31, + B011111 DEPRECATED(0b011111 ) = 31, + B0011111 DEPRECATED(0b0011111 ) = 31, + B00011111 DEPRECATED(0b00011111) = 31, + B100000 DEPRECATED(0b100000 ) = 32, + B0100000 DEPRECATED(0b0100000 ) = 32, + B00100000 DEPRECATED(0b00100000) = 32, + B100001 DEPRECATED(0b100001 ) = 33, + B0100001 DEPRECATED(0b0100001 ) = 33, + B00100001 DEPRECATED(0b00100001) = 33, + B100010 DEPRECATED(0b100010 ) = 34, + B0100010 DEPRECATED(0b0100010 ) = 34, + B00100010 DEPRECATED(0b00100010) = 34, + B100011 DEPRECATED(0b100011 ) = 35, + B0100011 DEPRECATED(0b0100011 ) = 35, + B00100011 DEPRECATED(0b00100011) = 35, + B100100 DEPRECATED(0b100100 ) = 36, + B0100100 DEPRECATED(0b0100100 ) = 36, + B00100100 DEPRECATED(0b00100100) = 36, + B100101 DEPRECATED(0b100101 ) = 37, + B0100101 DEPRECATED(0b0100101 ) = 37, + B00100101 DEPRECATED(0b00100101) = 37, + B100110 DEPRECATED(0b100110 ) = 38, + B0100110 DEPRECATED(0b0100110 ) = 38, + B00100110 DEPRECATED(0b00100110) = 38, + B100111 DEPRECATED(0b100111 ) = 39, + B0100111 DEPRECATED(0b0100111 ) = 39, + B00100111 DEPRECATED(0b00100111) = 39, + B101000 DEPRECATED(0b101000 ) = 40, + B0101000 DEPRECATED(0b0101000 ) = 40, + B00101000 DEPRECATED(0b00101000) = 40, + B101001 DEPRECATED(0b101001 ) = 41, + B0101001 DEPRECATED(0b0101001 ) = 41, + B00101001 DEPRECATED(0b00101001) = 41, + B101010 DEPRECATED(0b101010 ) = 42, + B0101010 DEPRECATED(0b0101010 ) = 42, + B00101010 DEPRECATED(0b00101010) = 42, + B101011 DEPRECATED(0b101011 ) = 43, + B0101011 DEPRECATED(0b0101011 ) = 43, + B00101011 DEPRECATED(0b00101011) = 43, + B101100 DEPRECATED(0b101100 ) = 44, + B0101100 DEPRECATED(0b0101100 ) = 44, + B00101100 DEPRECATED(0b00101100) = 44, + B101101 DEPRECATED(0b101101 ) = 45, + B0101101 DEPRECATED(0b0101101 ) = 45, + B00101101 DEPRECATED(0b00101101) = 45, + B101110 DEPRECATED(0b101110 ) = 46, + B0101110 DEPRECATED(0b0101110 ) = 46, + B00101110 DEPRECATED(0b00101110) = 46, + B101111 DEPRECATED(0b101111 ) = 47, + B0101111 DEPRECATED(0b0101111 ) = 47, + B00101111 DEPRECATED(0b00101111) = 47, + B110000 DEPRECATED(0b110000 ) = 48, + B0110000 DEPRECATED(0b0110000 ) = 48, + B00110000 DEPRECATED(0b00110000) = 48, + B110001 DEPRECATED(0b110001 ) = 49, + B0110001 DEPRECATED(0b0110001 ) = 49, + B00110001 DEPRECATED(0b00110001) = 49, + B110010 DEPRECATED(0b110010 ) = 50, + B0110010 DEPRECATED(0b0110010 ) = 50, + B00110010 DEPRECATED(0b00110010) = 50, + B110011 DEPRECATED(0b110011 ) = 51, + B0110011 DEPRECATED(0b0110011 ) = 51, + B00110011 DEPRECATED(0b00110011) = 51, + B110100 DEPRECATED(0b110100 ) = 52, + B0110100 DEPRECATED(0b0110100 ) = 52, + B00110100 DEPRECATED(0b00110100) = 52, + B110101 DEPRECATED(0b110101 ) = 53, + B0110101 DEPRECATED(0b0110101 ) = 53, + B00110101 DEPRECATED(0b00110101) = 53, + B110110 DEPRECATED(0b110110 ) = 54, + B0110110 DEPRECATED(0b0110110 ) = 54, + B00110110 DEPRECATED(0b00110110) = 54, + B110111 DEPRECATED(0b110111 ) = 55, + B0110111 DEPRECATED(0b0110111 ) = 55, + B00110111 DEPRECATED(0b00110111) = 55, + B111000 DEPRECATED(0b111000 ) = 56, + B0111000 DEPRECATED(0b0111000 ) = 56, + B00111000 DEPRECATED(0b00111000) = 56, + B111001 DEPRECATED(0b111001 ) = 57, + B0111001 DEPRECATED(0b0111001 ) = 57, + B00111001 DEPRECATED(0b00111001) = 57, + B111010 DEPRECATED(0b111010 ) = 58, + B0111010 DEPRECATED(0b0111010 ) = 58, + B00111010 DEPRECATED(0b00111010) = 58, + B111011 DEPRECATED(0b111011 ) = 59, + B0111011 DEPRECATED(0b0111011 ) = 59, + B00111011 DEPRECATED(0b00111011) = 59, + B111100 DEPRECATED(0b111100 ) = 60, + B0111100 DEPRECATED(0b0111100 ) = 60, + B00111100 DEPRECATED(0b00111100) = 60, + B111101 DEPRECATED(0b111101 ) = 61, + B0111101 DEPRECATED(0b0111101 ) = 61, + B00111101 DEPRECATED(0b00111101) = 61, + B111110 DEPRECATED(0b111110 ) = 62, + B0111110 DEPRECATED(0b0111110 ) = 62, + B00111110 DEPRECATED(0b00111110) = 62, + B111111 DEPRECATED(0b111111 ) = 63, + B0111111 DEPRECATED(0b0111111 ) = 63, + B00111111 DEPRECATED(0b00111111) = 63, + B1000000 DEPRECATED(0b1000000 ) = 64, + B01000000 DEPRECATED(0b01000000) = 64, + B1000001 DEPRECATED(0b1000001 ) = 65, + B01000001 DEPRECATED(0b01000001) = 65, + B1000010 DEPRECATED(0b1000010 ) = 66, + B01000010 DEPRECATED(0b01000010) = 66, + B1000011 DEPRECATED(0b1000011 ) = 67, + B01000011 DEPRECATED(0b01000011) = 67, + B1000100 DEPRECATED(0b1000100 ) = 68, + B01000100 DEPRECATED(0b01000100) = 68, + B1000101 DEPRECATED(0b1000101 ) = 69, + B01000101 DEPRECATED(0b01000101) = 69, + B1000110 DEPRECATED(0b1000110 ) = 70, + B01000110 DEPRECATED(0b01000110) = 70, + B1000111 DEPRECATED(0b1000111 ) = 71, + B01000111 DEPRECATED(0b01000111) = 71, + B1001000 DEPRECATED(0b1001000 ) = 72, + B01001000 DEPRECATED(0b01001000) = 72, + B1001001 DEPRECATED(0b1001001 ) = 73, + B01001001 DEPRECATED(0b01001001) = 73, + B1001010 DEPRECATED(0b1001010 ) = 74, + B01001010 DEPRECATED(0b01001010) = 74, + B1001011 DEPRECATED(0b1001011 ) = 75, + B01001011 DEPRECATED(0b01001011) = 75, + B1001100 DEPRECATED(0b1001100 ) = 76, + B01001100 DEPRECATED(0b01001100) = 76, + B1001101 DEPRECATED(0b1001101 ) = 77, + B01001101 DEPRECATED(0b01001101) = 77, + B1001110 DEPRECATED(0b1001110 ) = 78, + B01001110 DEPRECATED(0b01001110) = 78, + B1001111 DEPRECATED(0b1001111 ) = 79, + B01001111 DEPRECATED(0b01001111) = 79, + B1010000 DEPRECATED(0b1010000 ) = 80, + B01010000 DEPRECATED(0b01010000) = 80, + B1010001 DEPRECATED(0b1010001 ) = 81, + B01010001 DEPRECATED(0b01010001) = 81, + B1010010 DEPRECATED(0b1010010 ) = 82, + B01010010 DEPRECATED(0b01010010) = 82, + B1010011 DEPRECATED(0b1010011 ) = 83, + B01010011 DEPRECATED(0b01010011) = 83, + B1010100 DEPRECATED(0b1010100 ) = 84, + B01010100 DEPRECATED(0b01010100) = 84, + B1010101 DEPRECATED(0b1010101 ) = 85, + B01010101 DEPRECATED(0b01010101) = 85, + B1010110 DEPRECATED(0b1010110 ) = 86, + B01010110 DEPRECATED(0b01010110) = 86, + B1010111 DEPRECATED(0b1010111 ) = 87, + B01010111 DEPRECATED(0b01010111) = 87, + B1011000 DEPRECATED(0b1011000 ) = 88, + B01011000 DEPRECATED(0b01011000) = 88, + B1011001 DEPRECATED(0b1011001 ) = 89, + B01011001 DEPRECATED(0b01011001) = 89, + B1011010 DEPRECATED(0b1011010 ) = 90, + B01011010 DEPRECATED(0b01011010) = 90, + B1011011 DEPRECATED(0b1011011 ) = 91, + B01011011 DEPRECATED(0b01011011) = 91, + B1011100 DEPRECATED(0b1011100 ) = 92, + B01011100 DEPRECATED(0b01011100) = 92, + B1011101 DEPRECATED(0b1011101 ) = 93, + B01011101 DEPRECATED(0b01011101) = 93, + B1011110 DEPRECATED(0b1011110 ) = 94, + B01011110 DEPRECATED(0b01011110) = 94, + B1011111 DEPRECATED(0b1011111 ) = 95, + B01011111 DEPRECATED(0b01011111) = 95, + B1100000 DEPRECATED(0b1100000 ) = 96, + B01100000 DEPRECATED(0b01100000) = 96, + B1100001 DEPRECATED(0b1100001 ) = 97, + B01100001 DEPRECATED(0b01100001) = 97, + B1100010 DEPRECATED(0b1100010 ) = 98, + B01100010 DEPRECATED(0b01100010) = 98, + B1100011 DEPRECATED(0b1100011 ) = 99, + B01100011 DEPRECATED(0b01100011) = 99, + B1100100 DEPRECATED(0b1100100 ) = 100, + B01100100 DEPRECATED(0b01100100) = 100, + B1100101 DEPRECATED(0b1100101 ) = 101, + B01100101 DEPRECATED(0b01100101) = 101, + B1100110 DEPRECATED(0b1100110 ) = 102, + B01100110 DEPRECATED(0b01100110) = 102, + B1100111 DEPRECATED(0b1100111 ) = 103, + B01100111 DEPRECATED(0b01100111) = 103, + B1101000 DEPRECATED(0b1101000 ) = 104, + B01101000 DEPRECATED(0b01101000) = 104, + B1101001 DEPRECATED(0b1101001 ) = 105, + B01101001 DEPRECATED(0b01101001) = 105, + B1101010 DEPRECATED(0b1101010 ) = 106, + B01101010 DEPRECATED(0b01101010) = 106, + B1101011 DEPRECATED(0b1101011 ) = 107, + B01101011 DEPRECATED(0b01101011) = 107, + B1101100 DEPRECATED(0b1101100 ) = 108, + B01101100 DEPRECATED(0b01101100) = 108, + B1101101 DEPRECATED(0b1101101 ) = 109, + B01101101 DEPRECATED(0b01101101) = 109, + B1101110 DEPRECATED(0b1101110 ) = 110, + B01101110 DEPRECATED(0b01101110) = 110, + B1101111 DEPRECATED(0b1101111 ) = 111, + B01101111 DEPRECATED(0b01101111) = 111, + B1110000 DEPRECATED(0b1110000 ) = 112, + B01110000 DEPRECATED(0b01110000) = 112, + B1110001 DEPRECATED(0b1110001 ) = 113, + B01110001 DEPRECATED(0b01110001) = 113, + B1110010 DEPRECATED(0b1110010 ) = 114, + B01110010 DEPRECATED(0b01110010) = 114, + B1110011 DEPRECATED(0b1110011 ) = 115, + B01110011 DEPRECATED(0b01110011) = 115, + B1110100 DEPRECATED(0b1110100 ) = 116, + B01110100 DEPRECATED(0b01110100) = 116, + B1110101 DEPRECATED(0b1110101 ) = 117, + B01110101 DEPRECATED(0b01110101) = 117, + B1110110 DEPRECATED(0b1110110 ) = 118, + B01110110 DEPRECATED(0b01110110) = 118, + B1110111 DEPRECATED(0b1110111 ) = 119, + B01110111 DEPRECATED(0b01110111) = 119, + B1111000 DEPRECATED(0b1111000 ) = 120, + B01111000 DEPRECATED(0b01111000) = 120, + B1111001 DEPRECATED(0b1111001 ) = 121, + B01111001 DEPRECATED(0b01111001) = 121, + B1111010 DEPRECATED(0b1111010 ) = 122, + B01111010 DEPRECATED(0b01111010) = 122, + B1111011 DEPRECATED(0b1111011 ) = 123, + B01111011 DEPRECATED(0b01111011) = 123, + B1111100 DEPRECATED(0b1111100 ) = 124, + B01111100 DEPRECATED(0b01111100) = 124, + B1111101 DEPRECATED(0b1111101 ) = 125, + B01111101 DEPRECATED(0b01111101) = 125, + B1111110 DEPRECATED(0b1111110 ) = 126, + B01111110 DEPRECATED(0b01111110) = 126, + B1111111 DEPRECATED(0b1111111 ) = 127, + B01111111 DEPRECATED(0b01111111) = 127, + B10000000 DEPRECATED(0b10000000) = 128, + B10000001 DEPRECATED(0b10000001) = 129, + B10000010 DEPRECATED(0b10000010) = 130, + B10000011 DEPRECATED(0b10000011) = 131, + B10000100 DEPRECATED(0b10000100) = 132, + B10000101 DEPRECATED(0b10000101) = 133, + B10000110 DEPRECATED(0b10000110) = 134, + B10000111 DEPRECATED(0b10000111) = 135, + B10001000 DEPRECATED(0b10001000) = 136, + B10001001 DEPRECATED(0b10001001) = 137, + B10001010 DEPRECATED(0b10001010) = 138, + B10001011 DEPRECATED(0b10001011) = 139, + B10001100 DEPRECATED(0b10001100) = 140, + B10001101 DEPRECATED(0b10001101) = 141, + B10001110 DEPRECATED(0b10001110) = 142, + B10001111 DEPRECATED(0b10001111) = 143, + B10010000 DEPRECATED(0b10010000) = 144, + B10010001 DEPRECATED(0b10010001) = 145, + B10010010 DEPRECATED(0b10010010) = 146, + B10010011 DEPRECATED(0b10010011) = 147, + B10010100 DEPRECATED(0b10010100) = 148, + B10010101 DEPRECATED(0b10010101) = 149, + B10010110 DEPRECATED(0b10010110) = 150, + B10010111 DEPRECATED(0b10010111) = 151, + B10011000 DEPRECATED(0b10011000) = 152, + B10011001 DEPRECATED(0b10011001) = 153, + B10011010 DEPRECATED(0b10011010) = 154, + B10011011 DEPRECATED(0b10011011) = 155, + B10011100 DEPRECATED(0b10011100) = 156, + B10011101 DEPRECATED(0b10011101) = 157, + B10011110 DEPRECATED(0b10011110) = 158, + B10011111 DEPRECATED(0b10011111) = 159, + B10100000 DEPRECATED(0b10100000) = 160, + B10100001 DEPRECATED(0b10100001) = 161, + B10100010 DEPRECATED(0b10100010) = 162, + B10100011 DEPRECATED(0b10100011) = 163, + B10100100 DEPRECATED(0b10100100) = 164, + B10100101 DEPRECATED(0b10100101) = 165, + B10100110 DEPRECATED(0b10100110) = 166, + B10100111 DEPRECATED(0b10100111) = 167, + B10101000 DEPRECATED(0b10101000) = 168, + B10101001 DEPRECATED(0b10101001) = 169, + B10101010 DEPRECATED(0b10101010) = 170, + B10101011 DEPRECATED(0b10101011) = 171, + B10101100 DEPRECATED(0b10101100) = 172, + B10101101 DEPRECATED(0b10101101) = 173, + B10101110 DEPRECATED(0b10101110) = 174, + B10101111 DEPRECATED(0b10101111) = 175, + B10110000 DEPRECATED(0b10110000) = 176, + B10110001 DEPRECATED(0b10110001) = 177, + B10110010 DEPRECATED(0b10110010) = 178, + B10110011 DEPRECATED(0b10110011) = 179, + B10110100 DEPRECATED(0b10110100) = 180, + B10110101 DEPRECATED(0b10110101) = 181, + B10110110 DEPRECATED(0b10110110) = 182, + B10110111 DEPRECATED(0b10110111) = 183, + B10111000 DEPRECATED(0b10111000) = 184, + B10111001 DEPRECATED(0b10111001) = 185, + B10111010 DEPRECATED(0b10111010) = 186, + B10111011 DEPRECATED(0b10111011) = 187, + B10111100 DEPRECATED(0b10111100) = 188, + B10111101 DEPRECATED(0b10111101) = 189, + B10111110 DEPRECATED(0b10111110) = 190, + B10111111 DEPRECATED(0b10111111) = 191, + B11000000 DEPRECATED(0b11000000) = 192, + B11000001 DEPRECATED(0b11000001) = 193, + B11000010 DEPRECATED(0b11000010) = 194, + B11000011 DEPRECATED(0b11000011) = 195, + B11000100 DEPRECATED(0b11000100) = 196, + B11000101 DEPRECATED(0b11000101) = 197, + B11000110 DEPRECATED(0b11000110) = 198, + B11000111 DEPRECATED(0b11000111) = 199, + B11001000 DEPRECATED(0b11001000) = 200, + B11001001 DEPRECATED(0b11001001) = 201, + B11001010 DEPRECATED(0b11001010) = 202, + B11001011 DEPRECATED(0b11001011) = 203, + B11001100 DEPRECATED(0b11001100) = 204, + B11001101 DEPRECATED(0b11001101) = 205, + B11001110 DEPRECATED(0b11001110) = 206, + B11001111 DEPRECATED(0b11001111) = 207, + B11010000 DEPRECATED(0b11010000) = 208, + B11010001 DEPRECATED(0b11010001) = 209, + B11010010 DEPRECATED(0b11010010) = 210, + B11010011 DEPRECATED(0b11010011) = 211, + B11010100 DEPRECATED(0b11010100) = 212, + B11010101 DEPRECATED(0b11010101) = 213, + B11010110 DEPRECATED(0b11010110) = 214, + B11010111 DEPRECATED(0b11010111) = 215, + B11011000 DEPRECATED(0b11011000) = 216, + B11011001 DEPRECATED(0b11011001) = 217, + B11011010 DEPRECATED(0b11011010) = 218, + B11011011 DEPRECATED(0b11011011) = 219, + B11011100 DEPRECATED(0b11011100) = 220, + B11011101 DEPRECATED(0b11011101) = 221, + B11011110 DEPRECATED(0b11011110) = 222, + B11011111 DEPRECATED(0b11011111) = 223, + B11100000 DEPRECATED(0b11100000) = 224, + B11100001 DEPRECATED(0b11100001) = 225, + B11100010 DEPRECATED(0b11100010) = 226, + B11100011 DEPRECATED(0b11100011) = 227, + B11100100 DEPRECATED(0b11100100) = 228, + B11100101 DEPRECATED(0b11100101) = 229, + B11100110 DEPRECATED(0b11100110) = 230, + B11100111 DEPRECATED(0b11100111) = 231, + B11101000 DEPRECATED(0b11101000) = 232, + B11101001 DEPRECATED(0b11101001) = 233, + B11101010 DEPRECATED(0b11101010) = 234, + B11101011 DEPRECATED(0b11101011) = 235, + B11101100 DEPRECATED(0b11101100) = 236, + B11101101 DEPRECATED(0b11101101) = 237, + B11101110 DEPRECATED(0b11101110) = 238, + B11101111 DEPRECATED(0b11101111) = 239, + B11110000 DEPRECATED(0b11110000) = 240, + B11110001 DEPRECATED(0b11110001) = 241, + B11110010 DEPRECATED(0b11110010) = 242, + B11110011 DEPRECATED(0b11110011) = 243, + B11110100 DEPRECATED(0b11110100) = 244, + B11110101 DEPRECATED(0b11110101) = 245, + B11110110 DEPRECATED(0b11110110) = 246, + B11110111 DEPRECATED(0b11110111) = 247, + B11111000 DEPRECATED(0b11111000) = 248, + B11111001 DEPRECATED(0b11111001) = 249, + B11111010 DEPRECATED(0b11111010) = 250, + B11111011 DEPRECATED(0b11111011) = 251, + B11111100 DEPRECATED(0b11111100) = 252, + B11111101 DEPRECATED(0b11111101) = 253, + B11111110 DEPRECATED(0b11111110) = 254, + B11111111 DEPRECATED(0b11111111) = 255 +}; + +#undef DEPRECATED + +#endif diff --git a/extras/test/ArduinoCore-api/api/Common.cpp b/extras/test/ArduinoCore-api/api/Common.cpp new file mode 100644 index 0000000..8299247 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Common.cpp @@ -0,0 +1,29 @@ +/* + Common.cpp - Common function implementations + Copyright (c) 2017 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Common.h" + +/* C++ prototypes */ +long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +uint16_t makeWord(uint16_t w) { return w; } +uint16_t makeWord(uint8_t h, uint8_t l) { return (h << 8) | l; } \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/Common.h b/extras/test/ArduinoCore-api/api/Common.h new file mode 100644 index 0000000..9b28f40 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Common.h @@ -0,0 +1,190 @@ +/* + Common.h - Common definitions for Arduino core + Copyright (c) 2017 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +void yield(void); + +typedef enum { + LOW = 0, + HIGH = 1, + CHANGE = 2, + FALLING = 3, + RISING = 4, +} PinStatus; + +typedef enum { + INPUT = 0x0, + OUTPUT = 0x1, + INPUT_PULLUP = 0x2, + INPUT_PULLDOWN = 0x3, + OUTPUT_OPENDRAIN = 0x4, +} PinMode; + +typedef enum { + LSBFIRST = 0, + MSBFIRST = 1, +} BitOrder; + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#ifndef constrain +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#endif + +#ifndef radians +#define radians(deg) ((deg)*DEG_TO_RAD) +#endif + +#ifndef degrees +#define degrees(rad) ((rad)*RAD_TO_DEG) +#endif + +#ifndef sq +#define sq(x) ((x)*(x)) +#endif + +typedef void (*voidFuncPtr)(void); +typedef void (*voidFuncPtrParam)(void*); + +// interrupts() / noInterrupts() must be defined by the core + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitToggle(value, bit) ((value) ^= (1UL << (bit))) +#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet((value), (bit)) : bitClear((value), (bit))) + +#ifndef bit +#define bit(b) (1UL << (b)) +#endif + +/* TODO: request for removal */ +typedef bool boolean; +typedef uint8_t byte; +typedef uint16_t word; + +void init(void); +void initVariant(void); + +#ifndef HOST +int atexit(void (*func)()) __attribute__((weak)); +#endif +int main() __attribute__((weak)); + +#ifdef EXTENDED_PIN_MODE +// Platforms who want to declare more than 256 pins need to define EXTENDED_PIN_MODE globally +typedef uint32_t pin_size_t; +#else +typedef uint8_t pin_size_t; +#endif + +void pinMode(pin_size_t pinNumber, PinMode pinMode); +void digitalWrite(pin_size_t pinNumber, PinStatus status); +PinStatus digitalRead(pin_size_t pinNumber); +int analogRead(pin_size_t pinNumber); +void analogReference(uint8_t mode); +void analogWrite(pin_size_t pinNumber, int value); + +unsigned long millis(void); +unsigned long micros(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int us); +unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout); +unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout); + +void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val); +uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder); + +void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode); +void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void* param); +void detachInterrupt(pin_size_t interruptNumber); + +void setup(void); +void loop(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#ifdef __cplusplus + template + auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) + { + return (b < a) ? b : a; + } + + template + auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) + { + return (a < b) ? b : a; + } +#else +#ifndef min +#define min(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) +#endif +#ifndef max +#define max(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; }) +#endif +#endif + +#ifdef __cplusplus + +/* C++ prototypes */ +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); +unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); +void noTone(uint8_t _pin); + +// WMath prototypes +long random(long); +long random(long, long); +void randomSeed(unsigned long); +long map(long, long, long, long, long); + +#endif // __cplusplus diff --git a/extras/test/ArduinoCore-api/api/Compat.h b/extras/test/ArduinoCore-api/api/Compat.h new file mode 100644 index 0000000..564170c --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Compat.h @@ -0,0 +1,35 @@ +/* + Compat.h - Compatibility layer for Arduino API + Copyright (c) 2018 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __COMPAT_H__ +#define __COMPAT_H__ + +namespace arduino { + +inline void pinMode(pin_size_t pinNumber, int mode) { + pinMode(pinNumber, (PinMode)mode); +}; + +inline void digitalWrite(pin_size_t pinNumber, int status) { + digitalWrite(pinNumber, (PinStatus)status); +}; + +} + +#endif \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/IPAddress.h b/extras/test/ArduinoCore-api/api/IPAddress.h new file mode 100644 index 0000000..31a2d06 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/IPAddress.h @@ -0,0 +1,122 @@ +/* + IPAddress.h - Base class that provides IPAddress + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include "Printable.h" +#include "String.h" + +#define IPADDRESS_V4_BYTES_INDEX 12 +#define IPADDRESS_V4_DWORD_INDEX 3 + +// forward declarations of global name space friend classes +class EthernetClass; +class DhcpClass; +class DNSClient; + +namespace arduino { + +// A class to make it easier to handle and pass around IP addresses + +enum IPType { + IPv4, + IPv6 +}; + +class IPAddress : public Printable { +private: + union { + uint8_t bytes[16]; + uint32_t dword[4]; + } _address; + IPType _type; + + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { return _type == IPv4 ? &_address.bytes[IPADDRESS_V4_BYTES_INDEX] : _address.bytes; } + +public: + // Constructors + + // Default IPv4 + IPAddress(); + IPAddress(IPType ip_type); + IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16); + // IPv4; see implementation note + IPAddress(uint32_t address); + // Default IPv4 + IPAddress(const uint8_t *address); + IPAddress(IPType ip_type, const uint8_t *address); + // If IPv4 fails tries IPv6 see fromString function + IPAddress(const char *address); + + bool fromString(const char *address); + bool fromString(const String &address) { return fromString(address.c_str()); } + + // Overloaded cast operator to allow IPAddress objects to be used where a uint32_t is expected + // NOTE: IPv4 only; see implementation note + operator uint32_t() const { return _type == IPv4 ? _address.dword[IPADDRESS_V4_DWORD_INDEX] : 0; }; + + bool operator==(const IPAddress& addr) const; + bool operator!=(const IPAddress& addr) const { return !(*this == addr); }; + + // NOTE: IPv4 only; we don't know the length of the pointer + bool operator==(const uint8_t* addr) const; + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const; + uint8_t& operator[](int index); + + // Overloaded copy operators to allow initialisation of IPAddress objects from other types + // NOTE: IPv4 only + IPAddress& operator=(const uint8_t *address); + // NOTE: IPv4 only; see implementation note + IPAddress& operator=(uint32_t address); + // If IPv4 fails tries IPv6 see fromString function + IPAddress& operator=(const char *address); + + virtual size_t printTo(Print& p) const; + String toString() const; + + IPType type() const { return _type; } + + friend class UDP; + friend class Client; + friend class Server; + + friend ::EthernetClass; + friend ::DhcpClass; + friend ::DNSClient; + +protected: + bool fromString4(const char *address); + bool fromString6(const char *address); + String toString4() const; + String toString6() const; +}; + +extern const IPAddress IN6ADDR_ANY; +extern const IPAddress INADDR_NONE; +} + +using arduino::IPAddress; \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/Interrupts.h b/extras/test/ArduinoCore-api/api/Interrupts.h new file mode 100644 index 0000000..c3e37ad --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Interrupts.h @@ -0,0 +1,63 @@ +/* + Interrupts.h - Arduino interrupt management functions + Copyright (c) 2018 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef W_INTERRUPTS_CPP +#define W_INTERRUPTS_CPP +#ifdef __cplusplus + +#include +#include +#include +#include "Common.h" + +namespace arduino { + +template +using voidTemplateFuncPtrParam = void (*)(T param); + +template struct __container__ { + void* param; + voidTemplateFuncPtrParam function; +}; + +// C++ only overloaded version of attachInterrupt function +template void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam userFunc, PinStatus mode, T& param) { + + struct __container__ *cont = new __container__(); + cont->param = ¶m; + cont->function = userFunc; + + // TODO: check lambda scope + // TODO: add structure to delete(__container__) when detachInterrupt() is called + auto f = [](void* a) -> void + { + T param = *(T*)((struct __container__*)a)->param; + (((struct __container__*)a)->function)(param); + }; + + attachInterruptParam(interruptNum, f, mode, cont); +} + +template void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam userFunc, PinStatus mode, T* param) { + attachInterruptParam(interruptNum, (voidFuncPtrParam)userFunc, mode, (void*)param); +} + +} +#endif +#endif diff --git a/extras/test/ArduinoCore-api/api/PluggableUSB.h b/extras/test/ArduinoCore-api/api/PluggableUSB.h new file mode 100644 index 0000000..9018f6c --- /dev/null +++ b/extras/test/ArduinoCore-api/api/PluggableUSB.h @@ -0,0 +1,78 @@ +/* + PluggableUSB.h + Copyright (c) 2015 Arduino LLC + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef PUSB_h +#define PUSB_h + +#include "USBAPI.h" +#include +#include + +namespace arduino { + +class PluggableUSBModule { +public: + PluggableUSBModule(uint8_t numEps, uint8_t numIfs, unsigned int *epType) : + numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType) + { } + +protected: + virtual bool setup(USBSetup& setup) = 0; + virtual int getInterface(uint8_t* interfaceCount) = 0; + virtual int getDescriptor(USBSetup& setup) = 0; + virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; } + + uint8_t pluggedInterface; + uint8_t pluggedEndpoint; + + const uint8_t numEndpoints; + const uint8_t numInterfaces; + const unsigned int *endpointType; + + PluggableUSBModule *next = NULL; + + friend class PluggableUSB_; +}; + +class PluggableUSB_ { +public: + PluggableUSB_(); + bool plug(PluggableUSBModule *node); + int getInterface(uint8_t* interfaceCount); + int getDescriptor(USBSetup& setup); + bool setup(USBSetup& setup); + void getShortName(char *iSerialNum); + +private: + uint8_t lastIf; + uint8_t lastEp; + PluggableUSBModule* rootNode; + uint8_t totalEP; +}; +} + +// core need to define +void* epBuffer(unsigned int n); // -> returns a pointer to the Nth element of the EP buffer structure + +// Replacement for global singleton. +// This function prevents static-initialization-order-fiasco +// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use +arduino::PluggableUSB_& PluggableUSB(); + +#endif \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/Print.cpp b/extras/test/ArduinoCore-api/api/Print.cpp new file mode 100644 index 0000000..4a6e942 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Print.cpp @@ -0,0 +1,388 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include + +#include "Print.h" + +using namespace arduino; + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + if (write(*buffer++)) n++; + else break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ +#if defined(__AVR__) + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + if (write(c)) n++; + else break; + } + return n; +#else + return print(reinterpret_cast(ifsh)); +#endif +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(long long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printULLNumber(n, 10) + t; + } + return printULLNumber(n, 10); + } else { + return printULLNumber(n, base); + } +} + +size_t Print::print(unsigned long long n, int base) +{ + if (base == 0) return write(n); + else return printULLNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + return write("\r\n"); +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) +{ + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +// REFERENCE IMPLEMENTATION FOR ULL +// size_t Print::printULLNumber(unsigned long long n, uint8_t base) +// { + // // if limited to base 10 and 16 the bufsize can be smaller + // char buf[65]; + // char *str = &buf[64]; + + // *str = '\0'; + + // // prevent crash if called with base == 1 + // if (base < 2) base = 10; + + // do { + // unsigned long long t = n / base; + // char c = n - t * base; // faster than c = n%base; + // n = t; + // *--str = c < 10 ? c + '0' : c + 'A' - 10; + // } while(n); + + // return write(str); +// } + +// FAST IMPLEMENTATION FOR ULL +size_t Print::printULLNumber(unsigned long long n64, uint8_t base) +{ + // if limited to base 10 and 16 the bufsize can be 20 + char buf[64]; + uint8_t i = 0; + uint8_t innerLoops = 0; + + // Special case workaround https://github.com/arduino/ArduinoCore-API/issues/178 + if (n64 == 0) { + write('0'); + return 1; + } + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + // process chunks that fit in "16 bit math". + uint16_t top = 0xFFFF / base; + uint16_t th16 = 1; + while (th16 < top) + { + th16 *= base; + innerLoops++; + } + + while (n64 > th16) + { + // 64 bit math part + uint64_t q = n64 / th16; + uint16_t r = n64 - q*th16; + n64 = q; + + // 16 bit math loop to do remainder. (note buffer is filled reverse) + for (uint8_t j=0; j < innerLoops; j++) + { + uint16_t qq = r/base; + buf[i++] = r - qq*base; + r = qq; + } + } + + uint16_t n16 = n64; + while (n16 > 0) + { + uint16_t qq = n16/base; + buf[i++] = n16 - qq*base; + n16 = qq; + } + + size_t bytes = i; + for (; i > 0; i--) + write((char) (buf[i - 1] < 10 ? + '0' + buf[i - 1] : + 'A' + buf[i - 1] - 10)); + + return bytes; +} + +size_t Print::printFloat(double number, int digits) +{ + if (digits < 0) + digits = 2; + + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + unsigned int toPrint = (unsigned int)remainder; + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/extras/test/ArduinoCore-api/api/Print.h b/extras/test/ArduinoCore-api/api/Print.h new file mode 100644 index 0000000..6ed4509 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Print.h @@ -0,0 +1,97 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2016 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include // for size_t + +#include "String.h" +#include "Printable.h" + +const int DEC = 10; +const int HEX = 16; +const int OCT = 8; +const int BIN = 2; + +namespace arduino { + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printULLNumber(unsigned long long, uint8_t); + size_t printFloat(double, int); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + // default to zero, meaning "a single write may block" + // should be overridden by subclasses with buffering + virtual int availableForWrite() { return 0; } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(long long, int = DEC); + size_t print(unsigned long long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(long long, int = DEC); + size_t println(unsigned long long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); + + virtual void flush() { /* Empty implementation for backward compatibility */ } +}; + +} +using arduino::Print; \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/Printable.h b/extras/test/ArduinoCore-api/api/Printable.h new file mode 100644 index 0000000..850c8d2 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface for classes that can be printed via Print + Copyright (c) 2016 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include + +namespace arduino { + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +} \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/Server.h b/extras/test/ArduinoCore-api/api/Server.h new file mode 100644 index 0000000..83d0cd3 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Server.h @@ -0,0 +1,31 @@ +/* + Server.h - Base class that provides Server + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include "Print.h" + +namespace arduino { + +class Server : public Print { + public: + virtual void begin() = 0; +}; + +} \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/Stream.cpp b/extras/test/ArduinoCore-api/api/Stream.cpp new file mode 100644 index 0000000..f6f9bda --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Stream.cpp @@ -0,0 +1,321 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Common.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait + +using namespace arduino; + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) +{ + int c; + while (1) { + c = timedPeek(); + + if( c < 0 || + c == '-' || + (c >= '0' && c <= '9') || + (detectDecimal && c == '.')) return c; + + switch( lookahead ){ + case SKIP_NONE: return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ){ + case ' ': + case '\t': + case '\r': + case '\n': break; + default: return -1; // Fail code. + } + case SKIP_ALL: + break; + } + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(const char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(const char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(const char *target, const char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0; + } +} + +// returns the first valid (long) integer value from the current position. +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. +long Stream::parseInt(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(lookahead, false); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if((char)c == ignore) + ; // ignore this character + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || (char)c == ignore ); + + if(isNegative) + value = -value; + return value; +} + +// as parseInt but returns a floating point value +float Stream::parseFloat(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + bool isFraction = false; + double value = 0.0; + int c; + double fraction = 1.0; + + c = peekNextDigit(lookahead, true); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if((char)c == ignore) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + if(isFraction) { + fraction *= 0.1; + value = value + fraction * (c - '0'); + } else { + value = value * 10 + c - '0'; + } + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || (char)c == ignore ); + + if(isNegative) + value = -value; + + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::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; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || (char)c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && (char)c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if ((char)c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if ((char)c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} diff --git a/extras/test/ArduinoCore-api/api/Stream.h b/extras/test/ArduinoCore-api/api/Stream.h new file mode 100644 index 0000000..e81c71b --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Stream.h @@ -0,0 +1,133 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#pragma once + +#include +#include "Print.h" + +// compatibility macros for testing +/* +#define getInt() parseInt() +#define getInt(ignore) parseInt(ignore) +#define getFloat() parseFloat() +#define getFloat(ignore) parseFloat(ignore) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +namespace arduino { + +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + +class Stream : public Print +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + unsigned long getTimeout(void) { return _timeout; } + + bool find(const char *target); // reads data from the stream until the target string is found + bool find(const uint8_t *target) { return find ((const char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(const char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(const uint8_t *target, size_t length) { return find ((const char *)target, length); } + // returns true if target string is found, false if timed out + + bool find(char target) { return find (&target, 1); } + + bool findUntil(const char *target, const char *terminator); // as find but search ends if the terminator string is found + bool findUntil(const uint8_t *target, const char *terminator) { return findUntil((const char *)target, terminator); } + + bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen) {return findUntil((const char *)target, targetLen, terminate, termLen); } + + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. + + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#undef NO_IGNORE_CHAR + +} + +using arduino::Stream; \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/String.cpp b/extras/test/ArduinoCore-api/api/String.cpp new file mode 100644 index 0000000..4f17637 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/String.cpp @@ -0,0 +1,750 @@ +/* + String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "String.h" +#include "Common.h" +#include "itoa.h" +#include "deprecated-avr-comp/avr/dtostrf.h" + +#include + +namespace arduino { + +/*********************************************/ +/* Static Member Initialisation */ +/*********************************************/ + +size_t const String::FLT_MAX_DECIMAL_PLACES; +size_t const String::DBL_MAX_DECIMAL_PLACES; + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const char *cstr, unsigned int length) +{ + init(); + if (cstr) copy(cstr, length); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +String::String(String &&rval) + : buffer(rval.buffer) + , capacity(rval.capacity) + , len(rval.len) +{ + rval.buffer = NULL; + rval.capacity = 0; + rval.len = 0; +} + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + static size_t const FLOAT_BUF_SIZE = FLT_MAX_10_EXP + FLT_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */; + init(); + char buf[FLOAT_BUF_SIZE]; + decimalPlaces = min(decimalPlaces, FLT_MAX_DECIMAL_PLACES); + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + static size_t const DOUBLE_BUF_SIZE = DBL_MAX_10_EXP + DBL_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */; + init(); + char buf[DOUBLE_BUF_SIZE]; + decimalPlaces = min(decimalPlaces, DBL_MAX_DECIMAL_PLACES); + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + if (buffer) free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +bool String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return true; + } + return false; +} + +bool String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return true; + } + return false; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + memcpy(buffer, cstr, length); + buffer[len] = '\0'; + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +void String::move(String &rhs) +{ + if (this != &rhs) + { + free(buffer); + + buffer = rhs.buffer; + len = rhs.len; + capacity = rhs.capacity; + + rhs.buffer = NULL; + rhs.len = 0; + rhs.capacity = 0; + } +} + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +String & String::operator = (String &&rval) +{ + move(rval); + return *this; +} + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +bool String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +bool String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return false; + if (length == 0) return true; + if (!reserve(newlen)) return false; + memcpy(buffer + len, cstr, length); + len = newlen; + buffer[len] = '\0'; + return true; +} + +bool String::concat(const char *cstr) +{ + if (!cstr) return false; + return concat(cstr, strlen(cstr)); +} + +bool String::concat(char c) +{ + return concat(&c, 1); +} + +bool String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf); +} + +bool String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf); +} + +bool String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf); +} + +bool String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf); +} + +bool String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf); +} + +bool String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string); +} + +bool String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string); +} + +bool String::concat(const __FlashStringHelper * str) +{ + if (!str) return false; + int length = strlen_P((const char *) str); + if (length == 0) return true; + unsigned int newlen = len + length; + if (!reserve(newlen)) return false; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return true; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +int String::compareTo(const char *cstr) const +{ + if (!buffer || !cstr) { + if (cstr && *cstr) return 0 - *(unsigned char *)cstr; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, cstr); +} + +bool String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +bool String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +bool String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return true; + if (len != s2.len) return false; + if (len == 0) return true; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return false; + } + return true; +} + +bool String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return false; + return startsWith(s2, 0); +} + +bool String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return false; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +bool String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return false; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + out.copy(buffer + left, right - left); + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + unsigned int size = len; // compute size needed for result + diff = 0 - diff; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size -= diff; + } + if (size == len) return; + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom - diff, readFrom, len - (readFrom - buffer)); + len -= diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index){ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int)-1); +} + +void String::remove(unsigned int index, unsigned int count){ + if (index >= len) { return; } + if (count <= 0) { return; } + if (count > len - index) { count = len - index; } + char *writeTo = buffer + index; + len = len - count; + memmove(writeTo, buffer + index + count,len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memmove(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + return float(toDouble()); +} + +double String::toDouble(void) const +{ + if (buffer) return atof(buffer); + return 0; +} + +} // namespace arduino diff --git a/extras/test/ArduinoCore-api/api/String.h b/extras/test/ArduinoCore-api/api/String.h new file mode 100644 index 0000000..0bafd35 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/String.h @@ -0,0 +1,255 @@ +/* + String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef __cplusplus + +#ifndef __ARDUINO_STRINGS__ +#define __ARDUINO_STRINGS__ + +#include +#include +#include +#if defined(__AVR__) +#include "avr/pgmspace.h" +#else +#include "deprecated-avr-comp/avr/pgmspace.h" +#endif + +namespace arduino { + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + friend class StringSumHelper; + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + + static size_t const FLT_MAX_DECIMAL_PLACES = 10; + static size_t const DBL_MAX_DECIMAL_PLACES = FLT_MAX_DECIMAL_PLACES; + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const char *cstr, unsigned int length); + String(const uint8_t *cstr, unsigned int length) : String((const char*)cstr, length) {} + String(const String &str); + String(const __FlashStringHelper *str); + String(String &&rval); + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + bool reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + inline bool isEmpty(void) const { return length() == 0; } + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + String & operator = (String &&rval); + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsuccessful. + bool concat(const String &str); + bool concat(const char *cstr); + bool concat(const char *cstr, unsigned int length); + bool concat(const uint8_t *cstr, unsigned int length) {return concat((const char*)cstr, length);} + bool concat(char c); + bool concat(unsigned char num); + bool concat(int num); + bool concat(unsigned int num); + bool concat(long num); + bool concat(unsigned long num); + bool concat(float num); + bool concat(double num); + bool concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + int compareTo(const char *cstr) const; + bool equals(const String &s) const; + bool equals(const char *cstr) const; + + friend bool operator == (const String &a, const String &b) { return a.equals(b); } + friend bool operator == (const String &a, const char *b) { return a.equals(b); } + friend bool operator == (const char *a, const String &b) { return b == a; } + friend bool operator < (const String &a, const String &b) { return a.compareTo(b) < 0; } + friend bool operator < (const String &a, const char *b) { return a.compareTo(b) < 0; } + friend bool operator < (const char *a, const String &b) { return b.compareTo(a) > 0; } + + friend bool operator != (const String &a, const String &b) { return !(a == b); } + friend bool operator != (const String &a, const char *b) { return !(a == b); } + friend bool operator != (const char *a, const String &b) { return !(a == b); } + friend bool operator > (const String &a, const String &b) { return b < a; } + friend bool operator > (const String &a, const char *b) { return b < a; } + friend bool operator > (const char *a, const String &b) { return b < a; } + friend bool operator <= (const String &a, const String &b) { return !(b < a); } + friend bool operator <= (const String &a, const char *b) { return !(b < a); } + friend bool operator <= (const char *a, const String &b) { return !(b < a); } + friend bool operator >= (const String &a, const String &b) { return !(a < b); } + friend bool operator >= (const String &a, const char *b) { return !(a < b); } + friend bool operator >= (const char *a, const String &b) { return !(a < b); } + + bool equalsIgnoreCase(const String &s) const; + bool startsWith( const String &prefix) const; + bool startsWith(const String &prefix, unsigned int offset) const; + bool endsWith(const String &suffix) const; + + // character access + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + { getBytes((unsigned char *)buf, bufsize, index); } + const char* c_str() const { return buffer; } + char* begin() { return buffer; } + char* end() { return buffer + length(); } + const char* begin() const { return c_str(); } + const char* end() const { return c_str() + length(); } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + double toDouble(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + bool changeBuffer(unsigned int maxStrLen); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + void move(String &rhs); +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +} // namespace arduino + +using arduino::__FlashStringHelper; +using arduino::String; + +#endif // __cplusplus +#endif // __ARDUINO_STRINGS__ diff --git a/extras/test/ArduinoCore-api/api/USBAPI.h b/extras/test/ArduinoCore-api/api/USBAPI.h new file mode 100644 index 0000000..ba5e87c --- /dev/null +++ b/extras/test/ArduinoCore-api/api/USBAPI.h @@ -0,0 +1,64 @@ +/* + USBAPI.h + Copyright (c) 2005-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __USBAPI__ +#define __USBAPI__ + +#include + +namespace arduino { +//================================================================================ +//================================================================================ +// Low level API + +typedef struct __attribute__((packed)) +{ + union { + uint8_t bmRequestType; + struct { + uint8_t direction : 5; + uint8_t type : 2; + uint8_t transferDirection : 1; + }; + }; + uint8_t bRequest; + uint8_t wValueL; + uint8_t wValueH; + uint16_t wIndex; + uint16_t wLength; +} USBSetup; + +} + +//================================================================================ +// USB APIs (C scope) +//================================================================================ + +int USB_SendControl(uint8_t flags, const void* d, int len); +int USB_RecvControl(void* d, int len); +int USB_RecvControlLong(void* d, int len); + +uint8_t USB_Available(uint8_t ep); +uint8_t USB_SendSpace(uint8_t ep); +int USB_Send(uint8_t ep, const void* data, int len); // blocking +int USB_Recv(uint8_t ep, void* data, int len); // non-blocking +int USB_Recv(uint8_t ep); // non-blocking +void USB_Flush(uint8_t ep); + +#endif \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/Udp.h b/extras/test/ArduinoCore-api/api/Udp.h new file mode 100644 index 0000000..20117a6 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/Udp.h @@ -0,0 +1,92 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * 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. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#pragma once + +#include "Stream.h" +#include "IPAddress.h" + +namespace arduino { + +class UDP : public Stream { + +public: + virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure + virtual void stop() =0; // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specified in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port) =0; + // Start building up a packet to send to the remote host specified in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port) =0; + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket() =0; + // Write a single byte into the packet + virtual size_t write(uint8_t) =0; + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size) =0; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket() =0; + // Number of bytes remaining in the current packet + virtual int available() =0; + // Read a single byte from the current packet + virtual int read() =0; + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len) =0; + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) =0; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek() =0; + virtual void flush() =0; // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() =0; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() =0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +} + +using arduino::UDP; \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/WCharacter.h b/extras/test/ArduinoCore-api/api/WCharacter.h new file mode 100644 index 0000000..d050842 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/WCharacter.h @@ -0,0 +1,171 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include + +namespace arduino { + +// WCharacter.h prototypes +inline bool isAlphaNumeric(int c) __attribute__((always_inline)); +inline bool isAlpha(int c) __attribute__((always_inline)); +inline bool isAscii(int c) __attribute__((always_inline)); +inline bool isWhitespace(int c) __attribute__((always_inline)); +inline bool isControl(int c) __attribute__((always_inline)); +inline bool isDigit(int c) __attribute__((always_inline)); +inline bool isGraph(int c) __attribute__((always_inline)); +inline bool isLowerCase(int c) __attribute__((always_inline)); +inline bool isPrintable(int c) __attribute__((always_inline)); +inline bool isPunct(int c) __attribute__((always_inline)); +inline bool isSpace(int c) __attribute__((always_inline)); +inline bool isUpperCase(int c) __attribute__((always_inline)); +inline bool isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline bool isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline bool isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline bool isAscii(int c) +{ + return ((c & ~0x7f) != 0 ? false : true ); +} + + +// Checks for a blank character, that is, a space or a tab. +inline bool isWhitespace(int c) +{ + return ( c == '\t' || c == ' '); +} + + +// Checks for a control character. +inline bool isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline bool isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline bool isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline bool isLowerCase(int c) +{ + return ( c >= 'a' && c <= 'z' ); +} + + +// Checks for any printable character including space. +inline bool isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline bool isPunct(int c) +{ + return ( isPrintable(c) && !isSpace(c) && !isAlphaNumeric(c) ); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline bool isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline bool isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline bool isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ + return (c & 0x7f); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +} +#endif \ No newline at end of file diff --git a/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.c.impl b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.c.impl new file mode 100644 index 0000000..f410886 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.c.impl @@ -0,0 +1,40 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2016 Arduino LLC. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// This is a default implementation for dtostrf function. +// This file should be used if the standard lib doesn't provide an +// implementation of dtostrf. + +// Create a file called "dtostrf.c" with the following include: +// #include "api/deprecated-avr-comp/avr/dtostrf.c.impl" + +#include + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { + asm(".global _printf_float"); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + char fmt[20]; + sprintf(fmt, "%%%d.%df", width, prec); + sprintf(sout, fmt, val); + return sout; +#pragma GCC diagnostic pop +} + diff --git a/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.h b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.h new file mode 100644 index 0000000..2d287ca --- /dev/null +++ b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/dtostrf.h @@ -0,0 +1,34 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2015 Arduino LLC. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#if !defined(ARDUINO_ARCH_AVR) + +#ifdef __cplusplus +extern "C" { +#endif + +char *dtostrf(double val, signed char width, unsigned char prec, char *sout); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/interrupt.h b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/interrupt.h new file mode 100644 index 0000000..a2873cf --- /dev/null +++ b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/interrupt.h @@ -0,0 +1,23 @@ +/* + Copyright (c) 2015 Arduino LCC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + Empty file. + This file is here to allow compatibility with sketches (made for AVR) + that include +*/ diff --git a/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/pgmspace.h b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/pgmspace.h new file mode 100644 index 0000000..a80e4a5 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/deprecated-avr-comp/avr/pgmspace.h @@ -0,0 +1,124 @@ +/* + pgmspace.h - Definitions for compatibility with AVR pgmspace macros + + Copyright (c) 2015 Arduino LLC + + Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) + + 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 +*/ + +#ifndef __PGMSPACE_H_ +#define __PGMSPACE_H_ 1 + +#include + +#define PROGMEM +#define __ATTR_PROGMEM__ +#define PGM_P const char * +#define PGM_VOID_P const void * +#define PSTR(str) (str) + +#define _SFR_BYTE(n) (n) + +typedef void prog_void; +typedef char prog_char; +typedef unsigned char prog_uchar; +typedef int8_t prog_int8_t; +typedef uint8_t prog_uint8_t; +typedef int16_t prog_int16_t; +typedef uint16_t prog_uint16_t; +typedef int32_t prog_int32_t; +typedef uint32_t prog_uint32_t; +typedef int64_t prog_int64_t; +typedef uint64_t prog_uint64_t; + +typedef const void* int_farptr_t; +typedef const void* uint_farptr_t; + +#define memchr_P(s, c, n) memchr((s), (c), (n)) +#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) +#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) +#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) +#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) +#define memrchr_P(s, c, n) memrchr((s), (c), (n)) +#define strcat_P(dest, src) strcat((dest), (src)) +#define strchr_P(s, c) strchr((s), (c)) +#define strchrnul_P(s, c) strchrnul((s), (c)) +#define strcmp_P(a, b) strcmp((a), (b)) +#define strcpy_P(dest, src) strcpy((dest), (src)) +#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) +#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) +#define strcspn_P(s, accept) strcspn((s), (accept)) +#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) +#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) +#define strlen_P(a) strlen((a)) +#define strnlen_P(s, n) strnlen((s), (n)) +#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) +#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) +#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) +#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) +#define strpbrk_P(s, accept) strpbrk((s), (accept)) +#define strrchr_P(s, c) strrchr((s), (c)) +#define strsep_P(sp, delim) strsep((sp), (delim)) +#define strspn_P(s, accept) strspn((s), (accept)) +#define strstr_P(a, b) strstr((a), (b)) +#define strtok_P(s, delim) strtok((s), (delim)) +#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) + +#define strlen_PF(a) strlen((a)) +#define strnlen_PF(src, len) strnlen((src), (len)) +#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) +#define strcpy_PF(dest, src) strcpy((dest), (src)) +#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) +#define strcat_PF(dest, src) strcat((dest), (src)) +#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) +#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) +#define strcmp_PF(s1, s2) strcmp((s1), (s2)) +#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) +#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) +#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) +#define strstr_PF(s1, s2) strstr((s1), (s2)) +#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) +#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) + +#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) +#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) + +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_float(addr) (*(const float *)(addr)) +#define pgm_read_ptr(addr) (*(void *const *)(addr)) + +#define pgm_read_byte_near(addr) pgm_read_byte(addr) +#define pgm_read_word_near(addr) pgm_read_word(addr) +#define pgm_read_dword_near(addr) pgm_read_dword(addr) +#define pgm_read_float_near(addr) pgm_read_float(addr) +#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) + +#define pgm_read_byte_far(addr) pgm_read_byte(addr) +#define pgm_read_word_far(addr) pgm_read_word(addr) +#define pgm_read_dword_far(addr) pgm_read_dword(addr) +#define pgm_read_float_far(addr) pgm_read_float(addr) +#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) + +#define pgm_get_far_address(addr) (&(addr)) + +#endif diff --git a/extras/test/ArduinoCore-api/api/itoa.h b/extras/test/ArduinoCore-api/api/itoa.h new file mode 100644 index 0000000..c207783 --- /dev/null +++ b/extras/test/ArduinoCore-api/api/itoa.h @@ -0,0 +1,38 @@ +/* + itoa.h - Integer to ASCII conversion + Copyright (c) 2016 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +// Standard C functions required in Arduino API +// If these functions are not provided by the standard library, the +// core should supply an implementation of them. + +#ifdef __cplusplus +extern "C" { +#endif + +extern char* itoa(int value, char *string, int radix); +extern char* ltoa(long value, char *string, int radix); +extern char* utoa(unsigned value, char *string, int radix); +extern char* ultoa(unsigned long value, char *string, int radix); + +#ifdef __cplusplus +} // extern "C" +#endif + diff --git a/extras/test/CMakeLists.txt b/extras/test/CMakeLists.txt new file mode 100644 index 0000000..990d223 --- /dev/null +++ b/extras/test/CMakeLists.txt @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +########################################################################## + +cmake_minimum_required(VERSION 2.8) + +########################################################################## + +project(test-Arduino_RPClite) + +########################################################################## + +include_directories(../../src) +include_directories(ArduinoCore-api) +include_directories(include) +include_directories(external/catch/v2.13.9/include) +include_directories(external/DebugLog) +include_directories(external/ArxTypeTraits) +include_directories(external/ArxContainer) + +########################################################################## + +set(CMAKE_CXX_STANDARD 23) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +########################################################################## + +set(TEST_TARGET ${CMAKE_PROJECT_NAME}) + +########################################################################## + +set(TEST_SRCS + src/RPC/test_RPCClient.cpp + src/Print/test_clearWriteError.cpp + src/Print/test_getWriteError.cpp + src/Print/test_print.cpp + src/Print/test_println.cpp + src/Print/test_availableForWrite.cpp + src/Stream/test_find.cpp + src/Stream/test_findUntil.cpp + src/Stream/test_getTimeout.cpp + src/Stream/test_parseFloat.cpp + src/Stream/test_parseInt.cpp + src/Stream/test_readBytes.cpp + src/Stream/test_readBytesUntil.cpp + src/Stream/test_readString.cpp + src/Stream/test_readStringUntil.cpp + src/Stream/test_setTimeout.cpp + src/String/test_concat.cpp + src/String/test_operators.cpp + src/String/test_compareTo.cpp + src/String/test_comparisonFunc.cpp + src/String/test_characterAccessFunc.cpp + src/String/test_substring.cpp + src/String/test_indexOf.cpp + src/String/test_lastIndexOf.cpp + src/String/test_length.cpp + src/String/test_move.cpp + src/String/test_remove.cpp + src/String/test_replace.cpp + src/String/test_String.cpp + src/String/test_toDouble.cpp + src/String/test_toFloat.cpp + src/String/test_toInt.cpp + src/String/test_toLowerCase.cpp + src/String/test_toUpperCase.cpp + src/String/test_trim.cpp +) + +set(TEST_DUT_SRCS + ArduinoCore-api/api/Common.cpp + ArduinoCore-api/api/String.cpp + ArduinoCore-api/api/Stream.cpp + ArduinoCore-api/api/Print.cpp +) + +########################################################################## + +set(TEST_TARGET_SRCS + src/main.cpp + src/delay.c + src/dtostrf.cpp + src/itoa.cpp + src/MillisFake.cpp + src/PrintMock.cpp + src/StreamMock.cpp + ${TEST_SRCS} + ${TEST_DUT_SRCS} +) + +########################################################################## + +add_compile_definitions(HOST) +add_compile_options(-Wall -Wextra -Wpedantic -Werror) +add_compile_options(-Wno-cast-function-type) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -Wno-deprecated-copy") + +########################################################################## + +add_executable( + ${TEST_TARGET} + ${TEST_TARGET_SRCS} +) + +########################################################################## + diff --git a/extras/test/external/ArxContainer/ArxContainer.h b/extras/test/external/ArxContainer/ArxContainer.h new file mode 100644 index 0000000..b0582b1 --- /dev/null +++ b/extras/test/external/ArxContainer/ArxContainer.h @@ -0,0 +1,884 @@ +#pragma once + +#ifndef ARX_RINGBUFFER_H +#define ARX_RINGBUFFER_H + +#include "ArxContainer/has_include.h" +#include "ArxContainer/has_libstdcplusplus.h" + +#ifdef ARDUINO +#include +#endif + +// Make sure std namespace exists +namespace std { } + +// Import everything from the std namespace into arx::std, so that +// anything we import rather than define is also available through +// arx::stdx. +// This includes everything yet to be defined, so we can do this early +// (and must do so, to allow e.g. the C++14 additions in the arx::std +// namespace to reference the C++11 stuff from the system headers. +namespace arx { + namespace stdx { + using namespace ::std; + } +} + +// Import everything from arx::std back into the normal std namespace. +// This ensures that you can just use `std::foo` everywhere and you get +// the standard library version if it is available, falling back to arx +// versions for things not supplied by the standard library. Only when +// you really need the arx version (e.g. for constexpr numeric_limits +// when also using ArduinoSTL), you need to qualify with arx::stdx:: +namespace std { + using namespace ::arx::stdx; +} + +#include "ArxContainer/replace_minmax_macros.h" +#include "ArxContainer/initializer_list.h" + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 201103L // Have libstdc++11 + +#include +#include +#include +#include + +#endif + +#include + +#ifndef ARX_VECTOR_DEFAULT_SIZE +#define ARX_VECTOR_DEFAULT_SIZE 16 +#endif // ARX_VECTOR_DEFAULT_SIZE + +#ifndef ARX_DEQUE_DEFAULT_SIZE +#define ARX_DEQUE_DEFAULT_SIZE 16 +#endif // ARX_DEQUE_DEFAULT_SIZE + +#ifndef ARX_MAP_DEFAULT_SIZE +#define ARX_MAP_DEFAULT_SIZE 16 +#endif // ARX_MAP_DEFAULT_SIZE + +namespace arx { + +namespace container { + namespace detail { + template + inline T&& move(T& t) { return static_cast(t); } + } // namespace detail +} // namespace container + +template +class RingBuffer { + class Iterator; + class ConstIterator { + friend RingBuffer; + + const T* ptr {nullptr}; // pointer to the first element + int pos {0}; + + ConstIterator(const T* ptr, int pos) + : ptr(ptr), pos(pos) {} + + public: + ConstIterator() {} + ConstIterator(const ConstIterator& it) { + this->ptr = it.ptr; + this->pos = it.pos; + } + + ConstIterator(ConstIterator&& it) { + this->ptr = container::detail::move(it.ptr); + this->pos = container::detail::move(it.pos); + } + + ConstIterator& operator=(const ConstIterator& rhs) { + this->ptr = rhs.ptr; + this->pos = rhs.pos; + return *this; + } + ConstIterator& operator=(ConstIterator&& rhs) { + this->ptr = container::detail::move(rhs.ptr); + this->pos = container::detail::move(rhs.pos); + return *this; + } + + // const-like conversion ConstIterator => Iterator + Iterator to_iterator() const { + return Iterator(this->ptr, this->pos); + } + + private: + static int pos_wrap_around(const int pos) { + if (pos >= 0) + return pos % N; + else + return (N - 1) - (abs(pos + 1) % N); + } + + public: + int index() const { + return pos_wrap_around(pos); + } + int index_with_offset(const int i) const { + return pos_wrap_around(pos + i); + } + + const T& operator*() const { + return *(ptr + index()); + } + const T* operator->() const { + return ptr + index(); + } + + ConstIterator operator+(const int n) const { + return ConstIterator(this->ptr, this->pos + n); + } + int operator-(const ConstIterator& rhs) const { + return this->pos - rhs.pos; + } + ConstIterator operator-(const int n) const { + return ConstIterator(this->ptr, this->pos - n); + } + ConstIterator& operator+=(const int n) { + this->pos += n; + return *this; + } + ConstIterator& operator-=(const int n) { + this->pos -= n; + return *this; + } + + // prefix increment/decrement + ConstIterator& operator++() { + ++pos; + return *this; + } + ConstIterator& operator--() { + --pos; + return *this; + } + // postfix increment/decrement + ConstIterator operator++(int) { + ConstIterator it = *this; + ++pos; + return it; + } + ConstIterator operator--(int) { + ConstIterator it = *this; + --pos; + return it; + } + + bool operator==(const ConstIterator& rhs) const { + return (rhs.ptr == ptr) && (rhs.pos == pos); + } + bool operator!=(const ConstIterator& rhs) const { + return !(*this == rhs); + } + bool operator<(const ConstIterator& rhs) const { + return pos < rhs.pos; + } + bool operator<=(const ConstIterator& rhs) const { + return pos <= rhs.pos; + } + bool operator>(const ConstIterator& rhs) const { + return pos > rhs.pos; + } + bool operator>=(const ConstIterator& rhs) const { + return pos >= rhs.pos; + } + + private: + int raw_pos() const { + return pos; + } + + void set(const int i) { + pos = i; + } + + void reset() { + pos = 0; + } + }; + + class Iterator : public ConstIterator { + friend RingBuffer; + + Iterator(const T* ptr, int pos) { + this->ptr = ptr; + this->pos = pos; + } + + public: + Iterator() = default; + Iterator(const Iterator&) = default; + Iterator(Iterator&&) = default; + Iterator& operator=(const Iterator&) = default; + Iterator& operator=(Iterator&&) = default; + + T& operator*() { + return *(const_cast(this->ptr) + this->index()); + } + T* operator->() { + return const_cast(this->ptr) + this->index(); + } + + // all inherited methods that return ConstIterator must be reimplemented + Iterator operator+(const int n) const { + return Iterator(this->ptr, this->pos + n); + } + Iterator operator-(const int n) const { + return Iterator(this->ptr, this->pos - n); + } + Iterator& operator+=(const int n) { + this->pos += n; + return *this; + } + Iterator& operator-=(const int n) { + this->pos -= n; + return *this; + } + + // prefix increment/decrement + Iterator& operator++() { + ++(this->pos); + return *this; + } + Iterator& operator--() { + --(this->pos); + return *this; + } + // postfix increment/decrement + Iterator operator++(int) { + Iterator it = *this; + ++(this->pos); + return it; + } + Iterator operator--(int) { + Iterator it = *this; + --(this->pos); + return it; + } + }; + +protected: + friend class Iterator; + friend class ConstIterator; + + T queue_[N]; + int head_; + int tail_; + +public: + using iterator = Iterator; + using const_iterator = ConstIterator; + + RingBuffer() + : queue_() + , head_(0) + , tail_(0) { + } + + RingBuffer(std::initializer_list lst) + : queue_() + , head_(0) + , tail_(0) { + for (auto it = lst.begin(); it != lst.end(); ++it) { + push_back(*it); + } + } + + // copy + explicit RingBuffer(const RingBuffer& r) + : queue_() + , head_(r.head_) + , tail_(r.tail_) { + const_iterator it = r.begin(); + for (size_t i = 0; i < r.size(); ++i) { + int pos = it.index_with_offset(i); + queue_[pos] = r.queue_[pos]; + } + } + RingBuffer& operator=(const RingBuffer& r) { + head_ = r.head_; + tail_ = r.tail_; + const_iterator it = r.begin(); + for (size_t i = 0; i < r.size(); ++i) { + int pos = it.index_with_offset(i); + queue_[pos] = r.queue_[pos]; + } + return *this; + } + + // move + RingBuffer(RingBuffer&& r) { + head_ = container::detail::move(r.head_); + tail_ = container::detail::move(r.tail_); + const_iterator it = r.begin(); + for (size_t i = 0; i < r.size(); ++i) { + int pos = it.index_with_offset(i); + queue_[pos] = container::detail::move(r.queue_[pos]); + } + } + + RingBuffer& operator=(RingBuffer&& r) { + head_ = container::detail::move(r.head_); + tail_ = container::detail::move(r.tail_); + const_iterator it = r.begin(); + for (size_t i = 0; i < r.size(); ++i) { + int pos = it.index_with_offset(i); + queue_[pos] = container::detail::move(r.queue_[pos]); + } + return *this; + } + + size_t capacity() const { return N; }; + size_t size() const { return tail_ - head_; } + // data() method better not to use :-( + // it should point to the 1st item and have enough space for size() readings of items + // impossible with ringbuffer - either points to the 1st item or has enough space + // only exception when it works is when head_ pos == 0 + const T* data() const { return reinterpret_cast(&(queue_)); } + T* data() { return reinterpret_cast(&(queue_)); } + bool empty() const { return tail_ == head_; } + void clear() { head_ = tail_ = 0; } + + void pop() { + pop_front(); + } + void pop_front() { + if (size() == 0) return; + if (size() == 1) + clear(); + else + increment_head(); + } + void pop_back() { + if (size() == 0) return; + if (size() == 1) + clear(); + else + decrement_tail(); + } + + void push(const T& data) { + push_back(data); + } + void push(T&& data) { + push_back(data); + } + void push_back(const T& data) { + get(size()) = data; + increment_tail(); + } + void push_back(T&& data) { + get(size()) = data; + increment_tail(); + } + void push_front(const T& data) { + decrement_head(); + get(0) = data; + } + void push_front(T&& data) { + decrement_head(); + get(0) = data; + } + void emplace(const T& data) { push(data); } + void emplace(T&& data) { push(data); } + void emplace_back(const T& data) { push_back(data); } + void emplace_back(T&& data) { push_back(data); } + + const T& front() const { return get(0); } + T& front() { return get(0); } + + const T& back() const { return get(static_cast(size()) - 1); } + T& back() { return get(static_cast(size()) - 1); } + + const T& operator[](size_t index) const { return get(static_cast(index)); } + T& operator[](size_t index) { return get(static_cast(index)); } + + iterator begin() { return empty() ? Iterator() : Iterator(queue_, head_); } + iterator end() { return empty() ? Iterator() : Iterator(queue_, tail_); } + const_iterator begin() const { return empty() ? ConstIterator() : ConstIterator(queue_, head_); } + const_iterator end() const { return empty() ? ConstIterator() : ConstIterator(queue_, tail_); } + + // https://en.cppreference.com/w/cpp/container/vector/erase + iterator erase(const const_iterator& p) { + if (!is_valid(p)) return end(); + + iterator it_last = end() - 1; + for (iterator it = p.to_iterator(); it != it_last; ++it) + *it = *(it + 1); + *it_last = T(); + decrement_tail(); + return empty() ? end() : p.to_iterator(); + } + + void resize(size_t sz) { + size_t s = size(); + if (sz > s) { + for (size_t i = 0; i < sz - s; ++i) push(T()); + } else if (sz < s) { + for (size_t i = 0; i < s - sz; ++i) pop(); + } + } + + void assign(const_iterator first, const_iterator end) { + clear(); + while (first != end) push(*(first++)); + } + + void assign(const T* first, const T* end) { + clear(); + while (first != end) push(*(first++)); + } + + void shrink_to_fit() { + // dummy + } + + void reserve(size_t n) { + (void)n; + // dummy + } + + void fill(const T& v) { + for (iterator it = begin(); it != end(); ++it) + *it = v; + } + + // https://en.cppreference.com/w/cpp/container/vector/insert + void insert(const const_iterator& pos, const const_iterator& first, const const_iterator& last) { + if (!is_valid(pos) && pos != end()) + return; + + size_t sz = last - first; + + size_t new_sz = size() + sz; + if (new_sz > capacity()) + new_sz = capacity(); + + iterator it = begin() + new_sz - 1; + while (it != pos) { + *it = *(it - sz); + --it; + } + for (size_t i = 0; i < sz; ++i) { + *(it + i) = *(first + i); + if (size() < capacity() || (it + i) == end()) + increment_tail(); + } + } + + void insert(const const_iterator& pos, const T* first, const T* last) { + if (!is_valid(pos) && pos != end()) + return; + + size_t sz = last - first; + + size_t new_sz = size() + sz; + if (new_sz > capacity()) + new_sz = capacity(); + + iterator it = begin() + new_sz - 1; + while (it != pos) { + *it = *(it - sz); + --it; + } + for (size_t i = 0; i < sz; ++i) { + *(it + i) = *(first + i); + if (size() < capacity() || (it + i) == end()) + increment_tail(); + } + } + + void insert(const const_iterator& pos, const T& val) { + const T* ptr = &val; + insert(pos, ptr, ptr + 1); + } + +private: + T& get(const iterator& it) { + return queue_[it.index()]; + } + const T& get(const const_iterator& it) const { + return queue_[it.index()]; + } + T& get(const int index) { + return queue_[begin().index_with_offset(index)]; + } + const T& get(const int index) const { + return queue_[begin().index_with_offset(index)]; + } + + T* ptr(const iterator& it) { + return queue_ + it.index(); + } + const T* ptr(const const_iterator& it) const { + return queue_ + it.index(); + } + T* ptr(const int index) { + return queue_ + begin().index_with_offset(index); + } + const T* ptr(const int index) const { + return queue_ + begin().index_with_offset(index); + } + + void increment_head() { + ++head_; + resolve_overflow(); + } + void increment_tail() { + ++tail_; + resolve_overflow(); + if (size() > N) + increment_head(); + } + void decrement_head() { + --head_; + resolve_overflow(); + if (size() > N) + decrement_tail(); + } + void decrement_tail() { + --tail_; + resolve_overflow(); + } + + void resolve_overflow() { + if (empty()) + clear(); + else if (head_ <= (static_cast(INT_MIN) + static_cast(capacity())) \ + || tail_ >= (static_cast(INT_MAX) - static_cast(capacity()))) { + // +/- capacity(): reserve some space for pointer/iterator arithmetics + // head_/tail_ pointers are re-set N+1 steps before the overflow occurs + int len = size(); + head_ = begin().index(); + tail_ = head_ + len; + } + } + + bool is_valid(const const_iterator& it) const { + if (it.ptr != queue_) + return false; // iterator to a different object + return (it.raw_pos() >= head_) && (it.raw_pos() < tail_); + } +}; + +} // namespace arx + +template +inline bool operator==(const arx::RingBuffer& x, const arx::RingBuffer& y) { + if (x.size() != y.size()) return false; + for (size_t i = 0; i < x.size(); ++i) + if (x[i] != y[i]) return false; + return true; +} + +template +inline bool operator!=(const arx::RingBuffer& x, const arx::RingBuffer& y) { + return !(x == y); +} + +namespace arx { +namespace stdx { + +template +struct vector : public RingBuffer { + using iterator = typename RingBuffer::iterator; + using const_iterator = typename RingBuffer::const_iterator; + + vector() + : RingBuffer() {} + vector(std::initializer_list lst) + : RingBuffer(lst) {} + + // copy + vector(const vector& r) + : RingBuffer(r) {} + + vector& operator=(const vector& r) { + RingBuffer::operator=(r); + return *this; + } + + // move + vector(vector&& r) + : RingBuffer(r) {} + + vector& operator=(vector&& r) { + RingBuffer::operator=(r); + return *this; + } + +private: + using RingBuffer::pop; + using RingBuffer::pop_front; + using RingBuffer::push; + using RingBuffer::push_front; + using RingBuffer::emplace; + using RingBuffer::fill; +}; + +} // namespace arx +} // namespace stdx + +namespace arx { +namespace stdx { + +template +struct array : public RingBuffer { + using iterator = typename RingBuffer::iterator; + using const_iterator = typename RingBuffer::const_iterator; + + array() + : RingBuffer() {} + array(std::initializer_list lst) + : RingBuffer(lst) {} + + // copy + array(const array& r) + : RingBuffer(r) {} + + array& operator=(const array& r) { + RingBuffer::operator=(r); + return *this; + } + + // move + array(array&& r) + : RingBuffer(r) {} + + array& operator=(array&& r) { + RingBuffer::operator=(r); + return *this; + } + +private: + using RingBuffer::pop; + using RingBuffer::pop_front; + using RingBuffer::push; + using RingBuffer::push_front; + using RingBuffer::emplace; +}; + +} // namespace arx +} // namespace stdx + +namespace arx { +namespace stdx { + +template +struct deque : public RingBuffer { + using iterator = typename RingBuffer::iterator; + using const_iterator = typename RingBuffer::const_iterator; + + deque() + : RingBuffer() {} + deque(std::initializer_list lst) + : RingBuffer(lst) {} + + // copy + deque(const deque& r) + : RingBuffer(r) {} + + deque& operator=(const deque& r) { + RingBuffer::operator=(r); + return *this; + } + + // move + deque(deque&& r) + : RingBuffer(r) {} + + deque& operator=(deque&& r) { + RingBuffer::operator=(r); + return *this; + } + +private: + using RingBuffer::capacity; + using RingBuffer::pop; + using RingBuffer::push; + using RingBuffer::fill; +}; + +} // namespace arx +} // namespace stdx + +namespace arx { +namespace stdx { + +template +struct pair { + T1 first; + T2 second; +}; + +template +inline pair make_pair(const T1& t1, const T2& t2) { + return {t1, t2}; +}; + +} // namespace arx +} // namespace stdx + +template +inline bool operator==(const arx::stdx::pair& x, const arx::stdx::pair& y) { + return (x.first == y.first) && (x.second == y.second); +} + +template +inline bool operator!=(const arx::stdx::pair& x, const arx::stdx::pair& y) { + return !(x == y); +} + +namespace arx { +namespace stdx { + +template +struct map : public RingBuffer, N> { + using base = RingBuffer, N>; + using iterator = typename base::iterator; + using const_iterator = typename base::const_iterator; + + map() + : base() {} + map(std::initializer_list > lst) + : base(lst) {} + + // copy + map(const map& r) + : base(r) {} + + map& operator=(const map& r) { + base::operator=(r); + return *this; + } + + // move + map(map&& r) + : base(r) {} + + map& operator=(map&& r) { + base::operator=(r); + return *this; + } + + const_iterator find(const Key& key) const { + for (const_iterator it = this->begin(); it != this->end(); ++it) { + if (key == it->first) + return it; + } + return this->end(); + } + + iterator find(const Key& key) { + for (iterator it = this->begin(); it != this->end(); ++it) { + if (key == it->first) + return it; + } + return this->end(); + } + + pair insert(const Key& key, const T& t) { + return insert(::arx::stdx::make_pair(key, t)); + } + + pair insert(const pair& p) { + bool b {false}; + iterator it = find(p.first); + if (it == this->end()) { + this->push(p); + b = true; + it = this->begin() + this->size() - 1; + } + return {it, b}; + } + + pair emplace(const Key& key, const T& t) { + return insert(key, t); + } + + pair emplace(const pair& p) { + return insert(p); + } + +private: + T& empty_value() const { + static T val; + val = T(); // fresh empty value every time + return val; + } +public: + const T& at(const Key& key) const { + const_iterator it = find(key); + if (it != this->end()) return it->second; + return empty_value(); + //return find(key)->second; + } + + T& at(const Key& key) { + iterator it = find(key); + if (it != this->end()) return it->second; + return empty_value(); + //return find(key)->second; + } + + iterator erase(const const_iterator& it) { + iterator i = find(it->first); + return base::erase(i); + } + + iterator erase(const Key& key) { + iterator i = find(key); + return base::erase(i); + } + + // erase() will cause compile error if map's Key is 'unsigned int' + // => collision of this method with erase(const Key&) + iterator erase(const size_t index) { + if (index < this->size()) { + iterator it = this->begin() + index; + return erase(it); + } + return this->end(); + } + + T& operator[](const Key& key) { + iterator it = find(key); + if (it != this->end()) return it->second; + + insert(::arx::stdx::make_pair(key, T())); + return this->back().second; + } + +private: + using base::assign; + using base::back; + using base::capacity; + using base::data; + using base::emplace_back; + using base::front; + using base::pop; + using base::pop_back; + using base::pop_front; + using base::push; + using base::push_back; + using base::push_front; + using base::resize; + using base::shrink_to_fit; + using base::fill; +}; + +} // namespace stdx +} // namespace arx + +template +using ArxRingBuffer = arx::RingBuffer; + +#endif // ARX_RINGBUFFER_H diff --git a/extras/test/external/ArxContainer/ArxContainer/has_include.h b/extras/test/external/ArxContainer/ArxContainer/has_include.h new file mode 100644 index 0000000..d605d71 --- /dev/null +++ b/extras/test/external/ArxContainer/ArxContainer/has_include.h @@ -0,0 +1,30 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_HAS_INCLUDE_H +#define ARX_TYPE_TRAITS_HAS_INCLUDE_H + + // Check whether __has_include is available, but also check the GCC + // version (__has_include was introduced in gcc 5) to catch + // environments (such as ESP8266) where gcc is old, but some system + // header provides a fake __has_include. We also need to check + // against __clang__ here, since clang pretends to be GCC + // 4.something and would otherwise be detected incorrectly here... + #if !defined(__has_include) || defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__) + #if defined(ARDUINO_ARCH_ESP8266) + // ESP8266 does not have a working __has_include, but we + // know it does have a working libstdc++ with all the + // headers we care about, so provide a fake has_include + #define ARX_SYSTEM_HAS_INCLUDE(x) 1 + #elif defined(ARDUINO_SAM_DUE) + // Arduino DUE's GCC version is 4.8.3 (GCC < 5.0). + // If libstdc++ is used, std::function causes error + // so currently we disable libstdc++ and use ArxTypeTraits + #define ARX_SYSTEM_HAS_INCLUDE(x) 0 + #else + #error "Compiler does not support __has_include, please report a bug against the ArxTypeTraits library about this." + #endif + #else + #define ARX_SYSTEM_HAS_INCLUDE(x) __has_include(x) + #endif + +#endif // ARX_TYPE_TRAITS_HAS_INCLUDE_H diff --git a/extras/test/external/ArxContainer/ArxContainer/has_libstdcplusplus.h b/extras/test/external/ArxContainer/ArxContainer/has_libstdcplusplus.h new file mode 100644 index 0000000..23f2b26 --- /dev/null +++ b/extras/test/external/ArxContainer/ArxContainer/has_libstdcplusplus.h @@ -0,0 +1,35 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_HAS_LIBSTDCPLUSPLUS_H +#define ARX_TYPE_TRAITS_HAS_LIBSTDCPLUSPLUS_H + +#if !defined(ARX_HAVE_LIBSTDCPLUSPLUS) + #if ARX_SYSTEM_HAS_INCLUDE() && !defined(ARDUINO_spresense_ast) + #include + #if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) + // For gcc's libstdc++ and clang's libc++, assume that + // __cplusplus tells us what the standard includes support + #define ARX_HAVE_LIBSTDCPLUSPLUS __cplusplus + #elif defined(_CPPLIB_VER) + #if _CPPLIB_VER > 650 + #define ARX_HAVE_LIBSTDCPLUSPLUS 201703L // C++17 + #elif _CPPLIB_VER == 650 + #define ARX_HAVE_LIBSTDCPLUSPLUS 201402L // C++14 + #elif _CPPLIB_VER >= 610 + #define ARX_HAVE_LIBSTDCPLUSPLUS 201103L // C++11 + #else + #define ARX_HAVE_LIBSTDCPLUSPLUS 199711L // C++98 + #endif + #elif defined(__UCLIBCXX_MAJOR__) + // For uclibc++, assume C++98 support only. + #define ARX_HAVE_LIBSTDCPLUSPLUS 199711L + #else + #error "Unknown C++ library found, please report a bug against the ArxTypeTraits library about this." + #endif + #else + // Assume no standard library is available at all (e.g. on AVR) + #define ARX_HAVE_LIBSTDCPLUSPLUS 0 + #endif +#endif + +#endif // ARX_TYPE_TRAITS_HAS_LIBSTDCPLUSPLUS_H diff --git a/extras/test/external/ArxContainer/ArxContainer/initializer_list.h b/extras/test/external/ArxContainer/ArxContainer/initializer_list.h new file mode 100644 index 0000000..374aa27 --- /dev/null +++ b/extras/test/external/ArxContainer/ArxContainer/initializer_list.h @@ -0,0 +1,32 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_INITIALIZER_H +#define ARX_TYPE_TRAITS_INITIALIZER_H + +// Initializer_list *must* be defined in std, so take extra care to only +// define it when is really not available (e.g. +// ArduinoSTL is C++98 but *does* define ) and not +// already defined (e.g. by ArxContainer). +#if ARX_SYSTEM_HAS_INCLUDE() +#include +#else +namespace std { +template +class initializer_list { +private: + const T* array; + size_t len; + initializer_list(const T* a, size_t l) + : array(a), len(l) {} + +public: + initializer_list() + : array(nullptr), len(0) {} + size_t size() const { return len; } + const T* begin() const { return array; } + const T* end() const { return array + len; } +}; +} // namespace std +#endif + +#endif // ARX_TYPE_TRAITS_INITIALIZER_LIST_H diff --git a/extras/test/external/ArxContainer/ArxContainer/replace_minmax_macros.h b/extras/test/external/ArxContainer/ArxContainer/replace_minmax_macros.h new file mode 100644 index 0000000..f8ff86e --- /dev/null +++ b/extras/test/external/ArxContainer/ArxContainer/replace_minmax_macros.h @@ -0,0 +1,35 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_REPLACE_MINMAX_MACROS_H +#define ARX_TYPE_TRAITS_REPLACE_MINMAX_MACROS_H + +// Make sure Arduino.h is actually included, since otherwise it might be +// included later and break *uses* of the min/max methods, rather than +// the declarations of it. +#ifdef ARDUINO + #include +#endif + +// These macros are defined by Arduino.h on some platforms, and conflict +// with min/max methods defined or included by ArxTypeTraits, so replace +// them with macros here. +#ifdef max + #undef max + template + constexpr auto max(T1 x, T2 y) + -> decltype(x + y) + { + return (x > y) ? x : y; + } +#endif +#ifdef min + #undef min + template + constexpr auto min(T1 x, T2 y) + -> decltype(x + y) + { + return (x < y) ? x : y; + } +#endif + +#endif // ARX_TYPE_TRAITS_REPLACE_MINMAX_MACROS_H diff --git a/extras/test/external/ArxContainer/LICENSE b/extras/test/external/ArxContainer/LICENSE new file mode 100644 index 0000000..8c86460 --- /dev/null +++ b/extras/test/external/ArxContainer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Hideaki Tai + +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/extras/test/external/ArxContainer/README.md b/extras/test/external/ArxContainer/README.md new file mode 100644 index 0000000..99c1721 --- /dev/null +++ b/extras/test/external/ArxContainer/README.md @@ -0,0 +1,197 @@ +# ArxContainer + +C++ container-like classes (`vector`, `array`, `deque`, `map` etc.) for Arduino which cannot use STL + +## Note + +- `ArxContainer` is C++ container-**like** classes for Arduino + - Containers in this library is defined inside namespace `arx::stdx` instad of `std` (e.g. `arx::stdx::vector`) + - All of the functions is not supported currently +- If standard libraries are available, automatically use `std` version instead of `arx::stdx` version + +## Supported Container Types + +- `vector` +- `array` +- `map` (`pair`) +- `deque` + +## Supported Boards + +`arx::stdx` version of containers are enabled only if you use following architecture. +In other borads, `arx::stdx` version is disabled and standard libraries (`std` version) will be imported (because they can use them). + +- AVR (Uno, Nano, Mega, etc.) +- MEGAAVR (Uno WiFi, Nano Ecery, etc.) +- SAM (Due) + +## Usage + +### vector + +```C++ +// initialize with initializer_list +std::vector vs {1, 2, 3}; +// this is same as +// arx::stdx::vector vs {1, 2, 3}; + +// add contents +for (size_t i = 4; i <= 5; ++i) + vs.push_back(i); + +// index access +for (size_t i = 0; i < vs.size(); ++i) + Serial.println(vs[i]); + +// range-based access +for (const auto& v : vs) + Serial.println(v); +``` + +### array + +```C++ +// initialize with initializer_list +std::array arr {1, 2, 3}; +// this is same as +// arx::stdx::array arr {1, 2, 3}; + +// fill +arr.fill(123); + +// index access +for (size_t i = 0; i < arr.size(); ++i) + Serial.println(arr[i]); + +// range-based access +for (const auto& a : arr) + Serial.println(a); +``` + +### map + +```C++ +// initialize with initializer_list +std::map mp {{"one", 1}, {"two", 2}}; +// this is same as +// arx::stdx::map mp {{"one", 1}, {"two", 2}}; + +// add contents +mp.insert("three", 3); +mp["four"] = 4; + +// range based access +for (const auto& m : mp) +{ + Serial.print("{"); + Serial.print(m.first); Serial.print(","); + Serial.print(m.second); + Serial.println("}"); +} + +// key access +Serial.print("one = "); Serial.println(mp["one"]); +Serial.print("two = "); Serial.println(mp["two"]); +Serial.print("three = "); Serial.println(mp["three"]); +Serial.print("four = "); Serial.println(mp["four"]); +``` + +### deque + +```C++ +// initialize with initializer_list +std::deque dq {1, 2, 3}; +// this is same as +// arx::stdx::deque dq {1, 2, 3}; + +// add contents +for (int i = 4; i <= 5; ++i) + dq.push_back(i); + +// index access +for (int i = 0; i < dq.size(); ++i) + Serial.print(dq[i]); +``` + +## Detail + +`ArxContainer` is C++ container-**like** classes for Arduino. +This library is based on `arx::RingBuffer` and `arx::stdx::xxxx` is limited-size container. +`arx::RingBuffer` can be used as: + +```C++ +ArxRingBuffer buffer; + +buffer.push(1); +buffer.push(2); +buffer.push(3); + +for(size_t i = 0; i < buffer.size(); ++i) + Serial.println(buffer[i]); + +buffer.pop(); + +for(auto& b : buffer) + Serial.println(b); +``` + +`arx::stdx::xxxx` are derived from `RingBuffer` and defined as: + +```C++ +namespace arx { +namespace stdx { + template + struct vector : public RingBuffer + + template + struct array : public RingBuffer + + template + struct map : public RingBuffer, N> + + template + struct deque : public RingBuffer +} +} +``` + +So range-based loop cannot be applyed to `arx::stdx::deque` (iterator is not continuous because it is based on `RingBuffer`). + +### Manage Size Limit of Container + +Global default size of container can be changed by defining these macros before `#include `. + +```C++ +#define ARX_VECTOR_DEFAULT_SIZE XX // default: 16 +#define ARX_MAP_DEFAULT_SIZE XX // default: 16 +#define ARX_DEQUE_DEFAULT_SIZE XX // default: 16 +``` + +Or you can change each container size by template argument. + +```C++ +arx::stdx::vector vs; +arx::stdx::map ms; +arx::stdx::deque ds; +``` + +## Roadmap + +This library will be updated if I want to use more container interfaces on supported boards shown above. +PRs are welcome! + +## Used Inside of + +- [Packetizer](https://github.com/hideakitai/Packetizer) +- [MsgPack](https://github.com/hideakitai/MsgPack) +- [ArduinoOSC](https://github.com/hideakitai/ArduinoOSC) +- [ArtNet](https://github.com/hideakitai/ArtNet) +- [Tween](https://github.com/hideakitai/Tween) +- [TimeProfiler](https://github.com/hideakitai/TimeProfiler) +- [TaskManager](https://github.com/hideakitai/TaskManager) +- [ArxStringUtils](https://github.com/hideakitai/ArxStringUtils) +- [Debouncer](https://github.com/hideakitai/Debouncer) + +## License + +MIT diff --git a/extras/test/external/ArxContainer/library.json b/extras/test/external/ArxContainer/library.json new file mode 100644 index 0000000..7b4d886 --- /dev/null +++ b/extras/test/external/ArxContainer/library.json @@ -0,0 +1,18 @@ +{ + "name": "ArxContainer", + "keywords": "ringbuffer, vector, deque, map", + "description": "C++ container-like classes (vector, map, etc.) for Arduino which cannot use STL", + "repository": { + "type": "git", + "url": "https://github.com/hideakitai/ArxContainer.git" + }, + "authors": { + "name": "Hideaki Tai", + "url": "https://github.com/hideakitai", + "maintainer": true + }, + "version": "0.7.0", + "license": "MIT", + "frameworks": "arduino", + "platforms": "*" +} diff --git a/extras/test/external/ArxContainer/library.properties b/extras/test/external/ArxContainer/library.properties new file mode 100644 index 0000000..e711ce3 --- /dev/null +++ b/extras/test/external/ArxContainer/library.properties @@ -0,0 +1,9 @@ +name=ArxContainer +version=0.7.0 +author=hideakitai +maintainer=hideakitai +sentence=C++ container-like classes (vector, map, etc.) for Arduino which cannot use STL +paragraph=C++ container-like classes (vector, map, etc.) for Arduino which cannot use STL +category=Data Storage +url=https://github.com/hideakitai/ArxContainer +architectures=* diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits.h new file mode 100644 index 0000000..f963316 --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits.h @@ -0,0 +1,38 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_H +#define ARX_TYPE_TRAITS_H + +#include "ArxTypeTraits/has_include.h" +#include "ArxTypeTraits/has_libstdcplusplus.h" + +// Make sure std namespace exists +namespace std { } + +// Import everything from the std namespace into arx::std, so that +// anything we import rather than define is also available through +// arx::stdx. +// This includes everything yet to be defined, so we can do this early +// (and must do so, to allow e.g. the C++14 additions in the arx::std +// namespace to reference the C++11 stuff from the system headers. +namespace arx { + namespace stdx { + using namespace ::std; + } +} + +// Import everything from arx::std back into the normal std namespace. +// This ensures that you can just use `std::foo` everywhere and you get +// the standard library version if it is available, falling back to arx +// versions for things not supplied by the standard library. Only when +// you really need the arx version (e.g. for constexpr numeric_limits +// when also using ArduinoSTL), you need to qualify with arx::stdx:: +namespace std { + using namespace ::arx::stdx; +} + +#include "ArxTypeTraits/replace_minmax_macros.h" + +#include "ArxTypeTraits/type_traits.h" + +#endif // ARX_TYPE_TRAITS_H diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits/functional.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits/functional.h new file mode 100644 index 0000000..1d6e74c --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits/functional.h @@ -0,0 +1,165 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_FUNCTIONAL_H +#define ARX_TYPE_TRAITS_FUNCTIONAL_H + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 201103L // Have libstdc++11 + +#include + +#else // Do not have libstdc++11 + +// If we have a header, include it and assume it has placement new +// (for AVR this has always been true, MEGAAVR does not have placement +// new now, but will probably get it before is added). +// This also handles the case where ArduinoSTL is used, which defines an +// inline placement new which would conflict with the below definition. +#if ARX_SYSTEM_HAS_INCLUDE() +#include +#else +// When there is no header, there might be a header, but +// not all Arduino platform (versions) define a placement new operator +// in there. +// However, it is hard to detect whether it is or is not defined, but +// the versions that do define it, do not define it inline in the +// header, so we can just define it inline here without conflicts. +// Note that there is no need to include anything to declare the +// non-placement new operators, since those are implicit. +inline void* operator new (const size_t size, void* ptr) noexcept { (void)size; return ptr; } +#endif + +namespace arx { namespace stdx { + + // reference: + // stack overflow https://stackoverflow.com/questions/32074410/stdfunction-bind-like-type-erasure-without-standard-c-library + + template + class function; + + template + class function + { + struct vtable_t + { + void (*mover)(void* src, void* dest); + void (*destroyer)(void*); + R (*invoke)(void const* t, Args&&... args); + + template + static vtable_t const* get() + { + static const vtable_t table = + { + // mover + [] (void* src, void* dest) + { + new(dest) T(move(*static_cast(src))); + }, + // destroyer + [] (void* t) + { + static_cast(t)->~T(); + }, + // invoke + [] (void const* t, Args&&... args) -> R + { + return (*static_cast(t))(std::forward(args)...); + } + }; + return &table; + } + }; + + vtable_t const* table {nullptr}; + void* data {nullptr}; + + public: + + template < + class Func, + class dF = typename std::decay::type, + typename enable_if {}>::type* = nullptr, + typename enable_if ::type, R>{}>::type* = nullptr + > + function(const Func& f) + : table(vtable_t::template get()) + { + data = reinterpret_cast(new Func(f)); + } + function(const function& o) + : table(o.table) + { + data = o.data; + } + function(function&& o) + : table(o.table) + { + if (table) table->mover(o.data, data); + } + function() + { + } + ~function() + { + if (table) table->destroyer(data); + } + + function& operator= (const function& o) + { + this->~function(); + new(this) function(move(o)); + return *this; + } + function& operator= (function&& o) + { + this->~function(); + new(this) function(move(o)); + return *this; + } + function& operator= (std::nullptr_t p) + { + (void)p; + this->~function(); + return *this; + } + + explicit operator bool() const + { + return table; + } + + R operator()(Args...args) const + { + return table->invoke(data, std::forward(args)...); + } + }; + + template + inline bool operator== (const function& f, std::nullptr_t) + { + return !static_cast(f); + } + + template + inline bool operator== (std::nullptr_t, const function& f) + { + return !static_cast(f); + } + + template + inline bool operator!= (const function& f, std::nullptr_t) + { + return static_cast(f); + } + + template + inline bool operator!= (std::nullptr_t, const function& f) + { + return static_cast(f); + } + +} } // namespace arx::std + +#endif // Do not have libstdc++11 + +#endif // ARX_TYPE_TRAITS_FUNCTIONAL_H diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits/has_include.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits/has_include.h new file mode 100644 index 0000000..d605d71 --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits/has_include.h @@ -0,0 +1,30 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_HAS_INCLUDE_H +#define ARX_TYPE_TRAITS_HAS_INCLUDE_H + + // Check whether __has_include is available, but also check the GCC + // version (__has_include was introduced in gcc 5) to catch + // environments (such as ESP8266) where gcc is old, but some system + // header provides a fake __has_include. We also need to check + // against __clang__ here, since clang pretends to be GCC + // 4.something and would otherwise be detected incorrectly here... + #if !defined(__has_include) || defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__) + #if defined(ARDUINO_ARCH_ESP8266) + // ESP8266 does not have a working __has_include, but we + // know it does have a working libstdc++ with all the + // headers we care about, so provide a fake has_include + #define ARX_SYSTEM_HAS_INCLUDE(x) 1 + #elif defined(ARDUINO_SAM_DUE) + // Arduino DUE's GCC version is 4.8.3 (GCC < 5.0). + // If libstdc++ is used, std::function causes error + // so currently we disable libstdc++ and use ArxTypeTraits + #define ARX_SYSTEM_HAS_INCLUDE(x) 0 + #else + #error "Compiler does not support __has_include, please report a bug against the ArxTypeTraits library about this." + #endif + #else + #define ARX_SYSTEM_HAS_INCLUDE(x) __has_include(x) + #endif + +#endif // ARX_TYPE_TRAITS_HAS_INCLUDE_H diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits/has_libstdcplusplus.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits/has_libstdcplusplus.h new file mode 100644 index 0000000..23f2b26 --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits/has_libstdcplusplus.h @@ -0,0 +1,35 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_HAS_LIBSTDCPLUSPLUS_H +#define ARX_TYPE_TRAITS_HAS_LIBSTDCPLUSPLUS_H + +#if !defined(ARX_HAVE_LIBSTDCPLUSPLUS) + #if ARX_SYSTEM_HAS_INCLUDE() && !defined(ARDUINO_spresense_ast) + #include + #if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) + // For gcc's libstdc++ and clang's libc++, assume that + // __cplusplus tells us what the standard includes support + #define ARX_HAVE_LIBSTDCPLUSPLUS __cplusplus + #elif defined(_CPPLIB_VER) + #if _CPPLIB_VER > 650 + #define ARX_HAVE_LIBSTDCPLUSPLUS 201703L // C++17 + #elif _CPPLIB_VER == 650 + #define ARX_HAVE_LIBSTDCPLUSPLUS 201402L // C++14 + #elif _CPPLIB_VER >= 610 + #define ARX_HAVE_LIBSTDCPLUSPLUS 201103L // C++11 + #else + #define ARX_HAVE_LIBSTDCPLUSPLUS 199711L // C++98 + #endif + #elif defined(__UCLIBCXX_MAJOR__) + // For uclibc++, assume C++98 support only. + #define ARX_HAVE_LIBSTDCPLUSPLUS 199711L + #else + #error "Unknown C++ library found, please report a bug against the ArxTypeTraits library about this." + #endif + #else + // Assume no standard library is available at all (e.g. on AVR) + #define ARX_HAVE_LIBSTDCPLUSPLUS 0 + #endif +#endif + +#endif // ARX_TYPE_TRAITS_HAS_LIBSTDCPLUSPLUS_H diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits/initializer_list.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits/initializer_list.h new file mode 100644 index 0000000..b1cd74f --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits/initializer_list.h @@ -0,0 +1,30 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_INITIALIZER_H +#define ARX_TYPE_TRAITS_INITIALIZER_H + +// Initializer_list *must* be defined in std, so take extra care to only +// define it when is really not available (e.g. +// ArduinoSTL is C++98 but *does* define ) and not +// already defined (e.g. by ArxContainer). +#if ARX_SYSTEM_HAS_INCLUDE() +#include +#else +namespace std { + template + class initializer_list + { + private: + const T* array; + size_t len; + initializer_list(const T* a, size_t l) : array(a), len(l) {} + public: + initializer_list() : array(nullptr), len(0) {} + size_t size() const { return len; } + const T *begin() const { return array; } + const T *end() const { return array + len; } + }; +} // namespace std +#endif + +#endif // ARX_TYPE_TRAITS_INITIALIZER_LIST_H diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits/replace_minmax_macros.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits/replace_minmax_macros.h new file mode 100644 index 0000000..f8ff86e --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits/replace_minmax_macros.h @@ -0,0 +1,35 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_REPLACE_MINMAX_MACROS_H +#define ARX_TYPE_TRAITS_REPLACE_MINMAX_MACROS_H + +// Make sure Arduino.h is actually included, since otherwise it might be +// included later and break *uses* of the min/max methods, rather than +// the declarations of it. +#ifdef ARDUINO + #include +#endif + +// These macros are defined by Arduino.h on some platforms, and conflict +// with min/max methods defined or included by ArxTypeTraits, so replace +// them with macros here. +#ifdef max + #undef max + template + constexpr auto max(T1 x, T2 y) + -> decltype(x + y) + { + return (x > y) ? x : y; + } +#endif +#ifdef min + #undef min + template + constexpr auto min(T1 x, T2 y) + -> decltype(x + y) + { + return (x < y) ? x : y; + } +#endif + +#endif // ARX_TYPE_TRAITS_REPLACE_MINMAX_MACROS_H diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits/tuple.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits/tuple.h new file mode 100644 index 0000000..2c13d95 --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits/tuple.h @@ -0,0 +1,82 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_TUPLE_H +#define ARX_TYPE_TRAITS_TUPLE_H + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 201103L // Have libstdc++11 + +#include + +#else // Do not have libstdc++11 + +namespace arx { namespace stdx { + + // https://theolizer.com/cpp-school2/cpp-school2-15/ + // https://wandbox.org/permlink/C0BWIzjqg4iO3kKZ + + template + struct tuple + { + tuple() {} + }; + + template + class tuple : public tuple + { + template friend struct get_helper; + tFirst mMember; + public: + tuple(tFirst const& iFirst, tRest const&... iRest) + : tuple(iRest...) + , mMember(iFirst) + { } + constexpr tuple() {} + }; + + template + struct get_helper { }; + template + struct get_helper<0, tFirst, tRest...> + { + typedef tFirst type; + static type& get(tuple& iTuple) + { + return iTuple.mMember; + } + }; + template + struct get_helper + { + typedef typename get_helper::type type; + static type& get(tuple& iTuple) + { + return get_helper::get(iTuple); + } + }; + + template + typename get_helper::type& get(tuple& iTuple) + { + return get_helper::get(iTuple); + } + + template class tuple_size; + template class tuple_size; + template class tuple_size; + template class tuple_size; + template + class tuple_size > + : public integral_constant {}; + + template + auto make_tuple(Types&&... args) + -> std::tuple::type...> + { + return std::tuple::type...>(std::forward::type>(args)...); + } + +} } // namespace arx::std + +#endif // Do not have libstdc++11 + +#endif // ARX_TYPE_TRAITS_TUPLE_H diff --git a/extras/test/external/ArxTypeTraits/ArxTypeTraits/type_traits.h b/extras/test/external/ArxTypeTraits/ArxTypeTraits/type_traits.h new file mode 100644 index 0000000..df7ac5d --- /dev/null +++ b/extras/test/external/ArxTypeTraits/ArxTypeTraits/type_traits.h @@ -0,0 +1,983 @@ +#pragma once + +#ifndef ARX_TYPE_TRAITS_TYPE_TRAITS_H +#define ARX_TYPE_TRAITS_TYPE_TRAITS_H + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 199711L // Have libstdc++98 + +#include + +#else // Do not have libstdc++98 + +namespace arx { namespace stdx { + + template + void swap(T& a, T& b) + { + T t = move(a); + a = move(b); + b = move(t); + } +} } // namespace arx::stdx + +#endif // Do not have libstdc++98 + + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 201103L // Have libstdc++11 + +#include +#include + +#else // Do not have libstdc++11 + +#include +#include +#include + +namespace arx { namespace stdx { + + using nullptr_t = decltype(nullptr); + + // numeric_limits + + template + struct numeric_limits + { + static constexpr T max() { return T(); } + static constexpr T min() { return T(); } + }; + template <> constexpr bool numeric_limits::max() { return true; } + template <> constexpr char numeric_limits::max() { return CHAR_MAX; } + template <> constexpr signed char numeric_limits::max() { return SCHAR_MAX; } + template <> constexpr unsigned char numeric_limits::max() { return UCHAR_MAX; } +#ifndef ARDUINO_spresense_ast + template <> constexpr wchar_t numeric_limits::max() { return WCHAR_MAX; } + // template <> constexpr char8_t numeric_limits::max() { return UCHAR_MAX; } +#endif + template <> constexpr char16_t numeric_limits::max() { return UINT_LEAST16_MAX; } + template <> constexpr char32_t numeric_limits::max() { return UINT_LEAST32_MAX; } + template <> constexpr short numeric_limits::max() { return SHRT_MAX; } + template <> constexpr unsigned short numeric_limits::max() { return USHRT_MAX; } + template <> constexpr int numeric_limits::max() { return INT_MAX; } + template <> constexpr unsigned int numeric_limits::max() { return UINT_MAX; } + template <> constexpr long numeric_limits::max() { return LONG_MAX; } + template <> constexpr unsigned long numeric_limits::max() { return ULONG_MAX; } + // template <> constexpr long long numeric_limits::max() { return LLONG_MAX; } + // template <> constexpr unsigned long long numeric_limits::max() { return ULLONG_MAX; } + template <> constexpr float numeric_limits::max() { return FLT_MAX; } + template <> constexpr double numeric_limits::max() { return DBL_MAX; } + template <> constexpr long double numeric_limits::max() { return LDBL_MAX; } + + template <> constexpr bool numeric_limits::min() { return false; } + template <> constexpr char numeric_limits::min() { return CHAR_MIN; } + template <> constexpr signed char numeric_limits::min() { return SCHAR_MIN; } + template <> constexpr unsigned char numeric_limits::min() { return 0; } +#ifndef ARDUINO_spresense_ast + template <> constexpr wchar_t numeric_limits::min() { return WCHAR_MIN; } + // template <> constexpr char8_t numeric_limits::min() { return 0; } +#endif + template <> constexpr char16_t numeric_limits::min() { return 0; } + template <> constexpr char32_t numeric_limits::min() { return 0; } + template <> constexpr short numeric_limits::min() { return SHRT_MIN; } + template <> constexpr unsigned short numeric_limits::min() { return 0; } + template <> constexpr int numeric_limits::min() { return INT_MIN; } + template <> constexpr unsigned int numeric_limits::min() { return 0; } + template <> constexpr long numeric_limits::min() { return LONG_MIN; } + template <> constexpr unsigned long numeric_limits::min() { return 0; } + // template <> constexpr long long numeric_limits::min() { return LLONG_MIN; } + // template <> constexpr unsigned long long numeric_limits::min() { return 0; } + template <> constexpr float numeric_limits::min() { return FLT_MIN; } + template <> constexpr double numeric_limits::min() { return DBL_MIN; } + template <> constexpr long double numeric_limits::min() { return LDBL_MIN; } + + + // integral_constant + + template + struct integral_constant + { + static constexpr T value = v; + using value_type = T; + using type = integral_constant; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } + }; + + using true_type = integral_constant; + using false_type = integral_constant; + + + template + T declval(); // no implementation + + + template + struct enable_if; + template + struct enable_if { using type = T; }; + + + template + struct conditional { using type = T; }; + template + struct conditional { using type = F; }; + + + template struct remove_cv { using type = T; }; + template struct remove_cv { using type = T; }; + template struct remove_cv { using type = T; }; + template struct remove_cv { using type = T; }; + + template struct remove_const { using type = T; }; + template struct remove_const { using type = T; }; + + template struct remove_volatile { using type = T; }; + template struct remove_volatile { using type = T; }; + + template struct remove_pointer { using type = T; }; + template struct remove_pointer { using type = T; }; + template struct remove_pointer { using type = T; }; + template struct remove_pointer { using type = T; }; + template struct remove_pointer { using type = T; }; + + template struct remove_reference { using type = T; }; + template struct remove_reference { using type = T; }; + template struct remove_reference { using type = T; }; + + template struct remove_extent { typedef T type; }; + template struct remove_extent { typedef T type; }; + template struct remove_extent { typedef T type; }; + + + template + constexpr T&& forward(typename remove_reference::type& t) noexcept + { + return static_cast(t); + } + template + constexpr T&& forward(typename remove_reference::type&& t) noexcept + { + return static_cast(t); + } + + template struct remove_all_extents { using type = T; }; + template struct remove_all_extents { using type = typename remove_all_extents::type; }; + template struct remove_all_extents { using type = typename remove_all_extents::type; }; + + + template struct add_cv { using type = const volatile T; }; + template struct add_const { using type = const T; }; + template struct add_volatile { using type = volatile T; }; + + namespace detail + { + template + struct type_identity { using type = T; }; + template + auto try_add_pointer(int) -> type_identity::type*>; + template + auto try_add_pointer(...) -> type_identity; + } + template + struct add_pointer : decltype(detail::try_add_pointer(0)) {}; + + namespace detail + { + template + auto try_add_lvalue_reference(int) -> type_identity; + template + auto try_add_lvalue_reference(...) -> type_identity; + + template + auto try_add_rvalue_reference(int) -> type_identity; + template + auto try_add_rvalue_reference(...) -> type_identity; + } + + template + struct add_lvalue_reference : decltype(detail::try_add_lvalue_reference(0)) {}; + + template + struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference(0)) {}; + + + template + struct is_same : false_type {}; + template + struct is_same : true_type {}; + + + template + struct is_integral : false_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + template <> struct is_integral : true_type {}; + + + template + struct is_floating_point : false_type {}; + template <> struct is_floating_point : true_type {}; + template <> struct is_floating_point : true_type {}; + template <> struct is_floating_point : true_type {}; + + + template + struct is_arithmetic + : conditional< + is_integral::value || is_floating_point::value, + true_type, + false_type + >::type + {}; + + + namespace detail + { + template ::value> + struct is_signed : integral_constant {}; + template + struct is_signed : false_type {}; + } + template + struct is_signed : detail::is_signed::type {}; + + + namespace detail + { + template::value> + struct is_unsigned : integral_constant {}; + template + struct is_unsigned : false_type {}; + } + template + struct is_unsigned : detail::is_unsigned::type {}; + + + template struct is_const : false_type {}; + template struct is_const : true_type {}; + + template struct is_volatile : false_type {}; + template struct is_volatile : true_type {}; + + template struct is_reference : false_type {}; + template struct is_reference : true_type {}; + template struct is_reference : true_type {}; + + template struct is_lvalue_reference : false_type {}; + template struct is_lvalue_reference : true_type {}; + + template struct is_rvalue_reference : false_type {}; + template struct is_rvalue_reference : true_type {}; + + template struct is_pointer_helper : false_type {}; + template struct is_pointer_helper : true_type {}; + template struct is_pointer : is_pointer_helper::type> {}; + + + namespace detail + { + template + struct is_member_pointer_helper : false_type {}; + + template + struct is_member_pointer_helper : true_type {}; + } + + template + struct is_member_pointer : detail::is_member_pointer_helper::type> {}; + + + template + struct is_array : false_type {}; + template + struct is_array : true_type {}; + template + struct is_array : true_type {}; + + + namespace details + { + template + struct Tester { using type = void; }; + template + using void_t = typename Tester::type; + templateclass Z, class, class...Ts> + struct can_apply : false_type{}; + templateclass Z, class...Ts> + struct can_apply>, Ts...> : true_type{}; + + template + using try_convert = decltype(To{declval()}); + } + templateclass Z, class...Ts> + using can_apply = details::can_apply; + + template + struct is_convertible + : conditional < + can_apply ::value + , true_type + , typename conditional < + is_arithmetic::value && is_arithmetic::value, + true_type, + false_type + >::type + >::type + {}; + + template<> + struct is_convertible : true_type{}; + + + // primary template + template + struct is_function : false_type { }; + // specialization for regular functions + template + struct is_function : true_type {}; + // specialization for variadic functions such as printf + template + struct is_function : true_type {}; + // specialization for function types that have cv-qualifiers + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + // specialization for function types that have ref-qualifiers + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + template + struct is_function : true_type {}; + + + template + struct is_empty : public integral_constant { }; + + + template + struct is_void : is_same::type> {}; + + + namespace detail + { + // is_union implementation needs compiler hooks + // https://github.com/Quuxplusone/from-scratch/blob/master/include/scratch/bits/type-traits/compiler-magic.md + + //template + //integral_constant::value> test(int T::*); + + template + integral_constant test(int T::*); + + template + false_type test(...); + } + + template + struct is_class : decltype(detail::test(nullptr)) {}; + + + template + struct is_scalar : integral_constant::value || + /*is_enum::value || // is_enum implementation needs compiler hooks*/ + is_pointer::value || + is_member_pointer::value || + is_same::type>::value> {}; + + + template + struct is_object : integral_constant::value || + is_array::value || + /*is_union::value || // is_union implementation needs compiler hooks*/ + is_class::value> {}; + + + namespace detail + { + template + true_type test_pre_ptr_convertible(const volatile B*); + + template + false_type test_pre_ptr_convertible(const volatile void*); + + template + auto test_pre_is_base_of(...) -> true_type; + + template + auto test_pre_is_base_of(int) -> + decltype(test_pre_ptr_convertible(static_cast(nullptr))); + } + + template + struct is_base_of : integral_constant::value && + is_class::value && + decltype(detail::test_pre_is_base_of(0))::value> {}; + + + template + class decay + { + typedef typename remove_reference::type U; + public: + typedef typename conditional< + is_array::value, + typename remove_extent::type*, + typename conditional< + is_function::value, + typename add_pointer::type, + typename remove_cv::type + >::type + >::type type; + }; + + + namespace details + { + template struct tag { using type=T; }; + template using type_t = typename Tag::type; + + template + using invoke_t = decltype( declval()(declval()...) ); + + template + struct result_of {}; + template + struct result_of>> + : tag > + {}; + } + template + using result_of = details::result_of; + + + template + struct rank : integral_constant {}; + template + struct rank : integral_constant::value + 1> {}; + template + struct rank : integral_constant::value + 1> {}; + + template + struct extent : integral_constant {}; + template + struct extent : integral_constant {}; + template + struct extent : extent {}; + template + struct extent : integral_constant {}; + template + struct extent : extent {}; + + + template + auto addressof(T& arg) noexcept + -> typename enable_if::value, T*>::type + { + return reinterpret_cast(&const_cast(reinterpret_cast(arg))); + } + + template + auto addressof(T& arg) noexcept + -> typename enable_if::value, T*>::type + { + return &arg; + } + + + template + class reference_wrapper + { + public: + using type = T; + + reference_wrapper(T& ref) noexcept : m_ptr(addressof(ref)) {} + reference_wrapper(T&&) = delete; // as prior to LWG2993 + reference_wrapper(const reference_wrapper&) noexcept = default; + + reference_wrapper& operator= (const reference_wrapper& x) noexcept = default; + + constexpr operator T& () const noexcept { return *m_ptr; } + constexpr T& get() const noexcept { return *m_ptr; } + + // call-wrapping operator() omitted + + private: + T* m_ptr; + }; + + template reference_wrapper ref(T& t) noexcept { return reference_wrapper(t); } + template reference_wrapper ref(reference_wrapper t) noexcept { return ref(t.get()); } + template void ref(const T&&) = delete; + + template reference_wrapper cref(const T& t) noexcept { return reference_wrapper(t); } + template reference_wrapper cref(reference_wrapper t) noexcept { return cref(t.get()); } + template void cref(const T&&) = delete; + +} } // namespace arx::stdx + +#endif // Do not have libstdc++11 + + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 201402L // Have libstdc++14 + +#else // Do not have libstdc++14 + +namespace arx { namespace stdx { + + // `move` must be declared before including `functional.h` + // C++14 constexpr version should be inside of C++14, + // but moved before `functional.h` + template + constexpr typename remove_reference::type&& move(T&& t) noexcept + { + return static_cast::type&&>(t); + } + +} } // namespace arx::stdx + +#endif // Do not have libstdc++14 + + +#include "initializer_list.h" +#include "tuple.h" +#include "functional.h" + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 201402L // Have libstdc++14 + // Nothing to include here, relevant header files were already included + // for C++11 above. +#else // Do not have libstdc++14 + +namespace arx { namespace stdx { + + template + using enable_if_t = typename enable_if::type; + + template + using decay_t = typename decay::type; + + template + using remove_cv_t = typename remove_cv::type; + template + using remove_const_t = typename remove_const::type; + template + using remove_volatile_t = typename remove_volatile::type; + template + using remove_reference_t = typename remove_reference::type; + template + using remove_pointer_t = typename remove_pointer::type; + template + using remove_extent_t = typename remove_extent::type; + template + using remove_all_extents_t = typename remove_all_extents::type; + + template + using add_cv_t = typename add_cv::type; + template + using add_const_t = typename add_const::type; + template + using add_volatile_t = typename add_volatile::type; + template + using add_pointer_t = typename add_pointer::type; + template + using add_lvalue_reference_t = typename add_lvalue_reference::type; + template + using add_rvalue_reference_t = typename add_rvalue_reference::type; + + template + struct integer_sequence + { + using type = integer_sequence; + using value_type = T; + static constexpr size_t size() noexcept { return sizeof...(Ts); } + }; + template + using index_sequence = integer_sequence; + + // https://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence + + template + struct concat_impl; + template + using concat = typename concat_impl::type; + + template + struct concat_impl , index_sequence> + : index_sequence {}; + template + struct make_index_sequence_impl; + template + using make_index_sequence = typename make_index_sequence_impl::type; + template + struct make_index_sequence_impl + : concat, make_index_sequence > {}; + template<> + struct make_index_sequence_impl <0> : index_sequence<>{}; + template<> + struct make_index_sequence_impl <1> : index_sequence<0>{}; + + template + using index_sequence_for = make_index_sequence; + + template + struct is_null_pointer : is_same> {}; + +} } // namespace arx::stdx + +#endif // Do not have libstdc++14 + + +#if ARX_HAVE_LIBSTDCPLUSPLUS >= 201703L // Have libstdc++17 + // Nothing to include here, relevant header files were already included + // for C++11 above. +#else // Do not have libstdc++17 + +namespace arx { namespace stdx { + + template + using bool_constant = integral_constant; + +#if __cplusplus >= 201703L + template + inline constexpr bool is_same_v = is_same::value; + template + inline constexpr bool is_void_v = is_void::value; + template + inline constexpr bool is_class_v = is_class::value; + template + inline constexpr bool is_arithmetic_v = is_arithmetic::value; + template + inline constexpr bool is_const_v = is_const::value; + template + inline constexpr bool is_volatile_v = is_volatile::value; + template + inline constexpr bool is_reference_v = is_reference::value; + template + inline constexpr bool is_lvalue_reference_v = is_lvalue_reference::value; + template + inline constexpr bool is_rvalue_reference_v = is_rvalue_reference::value; + template + inline constexpr bool is_pointer_v = is_pointer::value; + template + inline constexpr bool is_member_pointer_v = is_member_pointer::value; + template + inline constexpr bool is_null_pointer_v = is_null_pointer::value; + template + inline constexpr bool is_scalar_v = is_scalar::value; + template + inline constexpr bool is_array_v = is_array::value; + template + inline constexpr bool is_object_v = is_object::value; + template + inline constexpr bool is_function_v = is_function::value; + template + inline constexpr bool is_base_of_v = is_base_of::value; + template + inline constexpr size_t rank_v = rank::value; + template + inline constexpr size_t extent_v = extent::value; +#endif // C++17 supported + + template + struct Tester { using type = void; }; + template + using void_t = typename Tester::type; + + template + struct disjunction : false_type {}; + template + struct disjunction : Arg::type {}; + template + struct disjunction : conditional>::type {}; + + template + struct conjunction : true_type {}; + template + struct conjunction : Arg::type {}; + template + struct conjunction : conditional, Arg>::type {}; + + template + struct negation : bool_constant {}; + + // https://qiita.com/_EnumHack/items/92e6e135174f1f781dbb + // without decltype(auto) + + template + constexpr auto apply_impl(F&& f, Tuple&& t, index_sequence) + -> decltype(f(get(forward(t))...)) + { + return f(get(forward(t))...); + } + template + constexpr auto apply(F&& f, Tuple&& t) + -> decltype(apply_impl( + forward(f), + forward(t), + make_index_sequence>::value>{} + )) + { + return apply_impl( + forward(f), + forward(t), + make_index_sequence>::value>() + ); + } + + namespace detail + { + template + struct is_reference_wrapper : false_type {}; + + template + struct is_reference_wrapper> : true_type {}; + + template + struct invoke_impl + { + template + static auto call(F&& f, Args&&... args) + -> decltype(forward(f)(forward(args)...)); + }; + + template + struct invoke_impl + { + template, + typename = enable_if_t::value> + > + static auto get(T&& t) -> T&&; + + template, + typename = enable_if_t::value> + > + static auto get(T&& t) -> decltype(t.get()); + + template, + typename = enable_if_t::value>, + typename = enable_if_t::value> + > + static auto get(T&& t) -> decltype(*forward(t)); + + template::value> + > + static auto call(MT1 B::* pmf, T&& t, Args&&... args) + -> decltype((invoke_impl::get(forward(t)).*pmf)(forward(args)...)); + + template + static auto call(MT B::* pmd, T&& t) + -> decltype(invoke_impl::get(forward(t)).*pmd); + }; + + template> + auto INVOKE(F&& f, Args&&... args) + -> decltype(invoke_impl::call(forward(f), forward(args)...)); + + template + struct invoke_result { }; + + template + struct invoke_result(), declval()...))), F, Args...> + { + using type = decltype(INVOKE(declval(), declval()...)); + }; + } + + template + struct invoke_result : detail::invoke_result {}; + + template + using invoke_result_t = typename invoke_result::type; + + template + constexpr add_const_t& as_const(T& val) noexcept + { + return val; + } + + template + void as_const(const T&&) = delete; + +} } // namespace arx::stdx + +#endif // Do not have libstdc++17 + + +#if ARX_HAVE_LIBSTDCPLUSPLUS > 201703L // Have libstdc++2a + // Nothing to include here, relevant header files were already included + // for C++11 above. +#else // Do not have libstdc++2a + +namespace arx { namespace stdx { + + template + struct type_identity { using type = T; }; + + template + using type_identity_t = typename type_identity::type; + + template + struct remove_cvref + { + typedef remove_cv_t> type; + }; + + template< class T > + using remove_cvref_t = typename remove_cvref::type; + + template + struct is_bounded_array : false_type {}; + template + struct is_bounded_array : true_type {}; + + template + struct is_unbounded_array : false_type {}; + template + struct is_unbounded_array : true_type {}; + +#if __cplusplus >= 201703L + template + inline constexpr bool is_bounded_array_v = is_bounded_array::value; + template + inline constexpr bool is_unbounded_array_v = is_unbounded_array::value; +#endif // C++17 supported + +} } // namespace arx::stdx +#endif // Do not have libstdc++2a + + +namespace arx { // others + + template class Check, class... T> + struct is_detected_impl : std::false_type {}; + template