From 82adc95d6456828e256145615e1dd4bf8d921e15 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sat, 18 May 2019 14:07:13 -0700 Subject: [PATCH] Add explicit Print::write(char) (#6101) W/o this change, file::write('a'); tries to use the template and fails since char is a basic type. The reason it is needed is due to pre 2.5.x behavior, File::write(char) silently was cast to File::write(uint8_t). With the template write, though, this is not performed. * Add Print::write tests and add'l overrides Ensure that print::write does something sane and doesn't cause a compile time error about templates when used for Files. Test using SPIFFS file since Print is an abstract type. --- cores/esp8266/Print.h | 15 ++++--- libraries/Wire/Wire.h | 4 -- tests/host/Makefile | 3 +- tests/host/core/test_Print.cpp | 80 ++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 tests/host/core/test_Print.cpp diff --git a/cores/esp8266/Print.h b/cores/esp8266/Print.h index b92bcc6e7..fdd20fda3 100644 --- a/cores/esp8266/Print.h +++ b/cores/esp8266/Print.h @@ -63,12 +63,15 @@ class Print { return write((const uint8_t *) buffer, size); } // These handle ambiguity for write(0) case, because (0) can be a pointer or an integer - size_t write(short t) { return write((uint8_t)t); } - size_t write(unsigned short t) { return write((uint8_t)t); } - size_t write(int t) { return write((uint8_t)t); } - size_t write(unsigned int t) { return write((uint8_t)t); } - size_t write(long t) { return write((uint8_t)t); } - size_t write(unsigned long t) { return write((uint8_t)t); } + inline size_t write(short t) { return write((uint8_t)t); } + inline size_t write(unsigned short t) { return write((uint8_t)t); } + inline size_t write(int t) { return write((uint8_t)t); } + inline size_t write(unsigned int t) { return write((uint8_t)t); } + inline size_t write(long t) { return write((uint8_t)t); } + inline size_t write(unsigned long t) { return write((uint8_t)t); } + // Enable write(char) to fall through to write(uint8_t) + inline size_t write(char c) { return write((uint8_t) c); } + inline size_t write(int8_t c) { return write((uint8_t) c); } size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3))); size_t printf_P(PGM_P format, ...) __attribute__((format(printf, 2, 3))); diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 8f2a37394..d396f4a84 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -80,10 +80,6 @@ class TwoWire : public Stream void onReceive( void (*)(size_t) ); // legacy esp8266 backward compatibility void onRequest( void (*)(void) ); - inline size_t write(unsigned long n) { return write((uint8_t)n); } - inline size_t write(long n) { return write((uint8_t)n); } - inline size_t write(unsigned int n) { return write((uint8_t)n); } - inline size_t write(int n) { return write((uint8_t)n); } using Print::write; }; diff --git a/tests/host/Makefile b/tests/host/Makefile index 1602eed79..f4d6d9321 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -127,7 +127,8 @@ TEST_CPP_FILES := \ core/test_pgmspace.cpp \ core/test_md5builder.cpp \ core/test_string.cpp \ - core/test_PolledTimeout.cpp + core/test_PolledTimeout.cpp \ + core/test_Print.cpp PREINCLUDES := \ -include common/mock.h \ diff --git a/tests/host/core/test_Print.cpp b/tests/host/core/test_Print.cpp new file mode 100644 index 000000000..c3cb2f5cd --- /dev/null +++ b/tests/host/core/test_Print.cpp @@ -0,0 +1,80 @@ +/* + test_pgmspace.cpp - pgmspace tests + Copyright © 2016 Ivan Grokhotkov + + 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. + */ + +#include +#include +#include +#include "../common/spiffs_mock.h" +#include + +// Use a SPIFFS file because we can't instantiate a virtual class like Print +TEST_CASE("Print::write overrides all compile properly", "[core][Print]") +{ + SPIFFS_MOCK_DECLARE(64, 8, 512, ""); + REQUIRE(SPIFFS.begin()); + auto p = SPIFFS.open("test.bin", "w"); + REQUIRE(p); + uint8_t uint8 = 1; + uint16_t uint16 = 2; + uint32_t uint32 = 3; + size_t size = 4; + int8_t int8 = 1; + int16_t int16 = 2; + int32_t int32 = 3; + char c = 'h'; + int i = 10; + long l = 11; + unsigned char uc = 20; + unsigned int ui = 21; + unsigned long ul = 22; + p.write(uint8); + p.write(uint16); + p.write(uint32); + p.write(size); + p.write(int8); + p.write(int16); + p.write(int32); + p.write(c); + p.write(i); + p.write(l); + p.write(uc); + p.write(ui); + p.write(ul); + p.write(0); + p.write(1); + p.close(); + + p = SPIFFS.open("test.bin", "r"); + REQUIRE(p); + uint8_t buff[16]; + int len = p.read(buff, 16); + p.close(); + REQUIRE(len == 15); + REQUIRE(buff[0] == 1); + REQUIRE(buff[1] == 2); + REQUIRE(buff[2] == 3); + REQUIRE(buff[3] == 4); + REQUIRE(buff[4] == 1); + REQUIRE(buff[5] == 2); + REQUIRE(buff[6] == 3); + REQUIRE(buff[7] == 'h'); + REQUIRE(buff[8] == 10); + REQUIRE(buff[9] == 11); + REQUIRE(buff[10] == 20); + REQUIRE(buff[11] == 21); + REQUIRE(buff[12] == 22); + REQUIRE(buff[13] == 0); + REQUIRE(buff[14] == 1); +}