From fa67b926b47620d1b14b9696294f22cf3af081ae Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 14 Aug 2018 23:20:34 +0300 Subject: [PATCH 1/4] add stubs for more exception throw calls Fixes https://github.com/esp8266/Arduino/issues/3358 --- cores/esp8266/abi.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cores/esp8266/abi.cpp b/cores/esp8266/abi.cpp index 8001c185a5..aa4d29f990 100644 --- a/cores/esp8266/abi.cpp +++ b/cores/esp8266/abi.cpp @@ -127,7 +127,24 @@ void __throw_out_of_range(const char* str) (void) str; panic(); } + +void __throw_bad_cast(void) +{ + panic(); +} + +void __throw_ios_failure(const char* str) +{ + (void) str; + panic(); +} + +void __throw_runtime_error(const char* str) +{ + (void) str; + panic(); } +} // namespace std // TODO: rebuild windows toolchain to make this unnecessary: void* __dso_handle; From 97d08065f9ee2f195756efde554497a5e449c2f0 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 14 Aug 2018 23:22:24 +0300 Subject: [PATCH 2/4] libc: make putc_r implementation weak newlib provides its own implementation of _putc_r, which will call _write_r (possibly after buffering). Make our implementation weak to allow using the one from newlib. Fixes https://github.com/esp8266/Arduino/issues/4630 --- cores/esp8266/libc_replacements.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cores/esp8266/libc_replacements.c b/cores/esp8266/libc_replacements.c index fe111ba4cb..50bb246062 100644 --- a/cores/esp8266/libc_replacements.c +++ b/cores/esp8266/libc_replacements.c @@ -93,6 +93,8 @@ int ICACHE_RAM_ATTR _write_r(struct _reent* r, int file, char *ptr, int len) { return len; } +int ICACHE_RAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) __attribute__((weak)); + int ICACHE_RAM_ATTR _putc_r(struct _reent* r, int c, FILE* file) { (void) r; if (file->_file == STDOUT_FILENO) { From 074dff7fdcd70918e93958d0d7f06651bb854888 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 14 Aug 2018 23:23:49 +0300 Subject: [PATCH 3/4] libc: fix incorrect return value of _write_r call Should return number of bytes written, actually returned zero. This resulted in std::cout going into failed state after the first write. --- cores/esp8266/libc_replacements.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cores/esp8266/libc_replacements.c b/cores/esp8266/libc_replacements.c index 50bb246062..fc6c2f142d 100644 --- a/cores/esp8266/libc_replacements.c +++ b/cores/esp8266/libc_replacements.c @@ -84,8 +84,9 @@ int ICACHE_RAM_ATTR _read_r(struct _reent* unused, int file, char *ptr, int len) int ICACHE_RAM_ATTR _write_r(struct _reent* r, int file, char *ptr, int len) { (void) r; + int pos = len; if (file == STDOUT_FILENO) { - while(len--) { + while(pos--) { ets_putc(*ptr); ++ptr; } From 6e906b2d9deacf8015097cfce580444e8b97db66 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 14 Aug 2018 23:40:48 +0300 Subject: [PATCH 4/4] tests: add test for output to std::cout --- tests/device/test_iostream/test_iostream.ino | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/device/test_iostream/test_iostream.ino diff --git a/tests/device/test_iostream/test_iostream.ino b/tests/device/test_iostream/test_iostream.ino new file mode 100644 index 0000000000..b644882bf2 --- /dev/null +++ b/tests/device/test_iostream/test_iostream.ino @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +BS_ENV_DECLARE(); + +void setup() +{ + Serial.begin(115200); + BS_RUN(Serial); +} + +TEST_CASE("can print to std::cout", "[iostream]") +{ + std::stringstream test_stream(""); + test_stream << "hello stream"; + + // empty the RX buffer, just in case + Serial.readString(); + + USC0(0) |= (1 << UCLBE); // enable loopback + std::cout << test_stream.str().c_str() << std::endl; + delay(100); + USC0(0) &= ~(1 << UCLBE); // disable loopback + + String result = Serial.readStringUntil('\n'); + + Serial.printf("result: '%s'\n", result.c_str()); + + CHECK(result == test_stream.str().c_str()); +} + +void loop() { }