diff --git a/examples/debug/debug.ino b/examples/debug/debug.ino index 4bef794..ad7a95b 100644 --- a/examples/debug/debug.ino +++ b/examples/debug/debug.ino @@ -39,8 +39,8 @@ void dump_stack(rpn_context & ctxt) { void dump_variables(rpn_context & ctxt) { Serial.printf("Variables\n--------------------\n"); - rpn_variables_foreach(ctxt, [](const String& name, const rpn_value& value) { - Serial.printf("$%s = %.2f\n", name.c_str(), value.toFloat()); + rpn_variables_foreach(ctxt, [](const char* name, const rpn_value& value) { + Serial.printf("$%s = %.2f\n", name, value.toFloat()); }); Serial.println(); @@ -85,7 +85,7 @@ void setup() { // Last parameter in rpn_process forces variable check, // the execution will fail if the variable does not exist if (!rpn_process(ctxt, "$temperatue 18 21 cmp3 1 + 1 $relay 0 3 index", true)) { - rpn_handle_error(ctxt.error, rpn_decode_errors([](const String& decoded) { + rpn_handle_error(ctxt.error, rpn_decode_errors([](const char* decoded) { Serial.println("rpn_process stopped after an error: "); Serial.println(decoded); })); diff --git a/examples/host/repl.cpp b/examples/host/repl.cpp index b1cedb1..68337bc 100644 --- a/examples/host/repl.cpp +++ b/examples/host/repl.cpp @@ -19,37 +19,10 @@ const char* stack_type(rpn_stack_value::Type type) { } } -void dump_value(const rpn_value& val) { - switch (val.type) { - case rpn_value::Type::Boolean: - std::cout << (val.toBoolean() ? "true" : "false") << " (Boolean) "; - break; - case rpn_value::Type::Integer: - std::cout << val.toInt() << " (Integer) "; - break; - case rpn_value::Type::Unsigned: - std::cout << val.toUint() << " (Unsigned) "; - break; - case rpn_value::Type::Float: - std::cout << val.toFloat() << " (Float) "; - break; - case rpn_value::Type::String: - std::cout << val.toString().c_str() << " (String) "; - break; - case rpn_value::Type::Error: - std::cout << "error "; - break; - case rpn_value::Type::Null: - std::cout << "null "; - break; - } -} - void dump_variables(rpn_context & ctxt) { - rpn_variables_foreach(ctxt, [](const String& name, rpn_value& value) { - std::cout << "$" << name.c_str() << " is "; - dump_value(value); - std::cout << std::endl; + rpn_variables_foreach(ctxt, [](const char* name, rpn_value& value) { + std::cout << "$" << name << " is "; + std::cout << value.toString() << std::endl; }); } @@ -57,7 +30,7 @@ void dump_stack(rpn_context & ctxt) { size_t index = rpn_stack_size(ctxt); rpn_stack_foreach(ctxt, [&index](rpn_stack_value::Type type, const rpn_value& value) { std::cout << std::setfill('0') << std::setw(3) << --index << ": "; - dump_value(value); + std::cout << value.toString(); std::cout << " (" << stack_type(type) << ")" << std::endl; }); std::cout << std::endl; @@ -65,9 +38,9 @@ void dump_stack(rpn_context & ctxt) { void dump_operators(rpn_context & ctxt) { size_t index = 0; - rpn_operators_foreach(ctxt, [&index](const String& name, size_t argc, rpn_operator::callback_type) { + rpn_operators_foreach(ctxt, [&index](const char* name, size_t argc, rpn_operator::callback_type) { std::cout << std::setfill('0') << std::setw(3) << ++index << ": "; - std::cout << name.c_str() << "(...), " << argc << std::endl; + std::cout << name << "(...), " << argc << std::endl; }); } @@ -151,14 +124,14 @@ int main(int argc, char** argv) { break; } if (!rpn_process(ctxt, input.c_str())) { - auto handler = [&ctxt](const String& decoded) { + auto handler = [&ctxt](const char* decoded) { auto pos = ctxt.error.position; std::cout << " "; while (--pos) { std::cout << ' '; } std::cout << "^\n"; - std::cout << "ERR: " << decoded.c_str() << std::endl; + std::cout << "ERR: " << decoded << std::endl; }; rpn_handle_error(ctxt.error, rpn_decode_errors(handler)); } diff --git a/examples/time/time.ino b/examples/time/time.ino index 1d85758..a5bf0ff 100644 --- a/examples/time/time.ino +++ b/examples/time/time.ino @@ -26,6 +26,10 @@ along with the rpnlib library. If not, see . #include #include +// time_t value on ESP8266 could be either 4 or 8 bytes, but it might not always be able to fit into rpn_int +// (but, it is possible to tweak time funcs to accept time_t as LOW and HIGH parts, requiring special operators to handle such values) +static_assert(sizeof(rpn_int) >= sizeof(time_t), "time_t should be able to fit into a single rpn_value"); + void dump_stack(rpn_context & ctxt) { rpn_value value; auto index = rpn_stack_size(ctxt) - 1; @@ -115,11 +119,11 @@ void setup() { return 0; }); - rpn_variable_set(ctxt, F("time"), + rpn_variable_set(ctxt, "time", rpn_value(static_cast(time(nullptr))) ); - rpn_variables_foreach(ctxt, [](const String& name, const rpn_value& value) { + rpn_variables_foreach(ctxt, [](const char* name, const rpn_value& value) { Serial.println(name); Serial.println(value.toInt()); }); diff --git a/src/rpnlib.cpp b/src/rpnlib.cpp index 02a5909..153c186 100644 --- a/src/rpnlib.cpp +++ b/src/rpnlib.cpp @@ -127,8 +127,8 @@ rpn_input_buffer& rpn_input_buffer::write(const char* data, size_t data_length) return *this; } -bool rpn_input_buffer::operator==(const String& other) const { - return other.equals(_buffer); +bool rpn_input_buffer::operator==(const std::string& other) const { + return other == _buffer; } void rpn_input_buffer::reset() { diff --git a/src/rpnlib.h b/src/rpnlib.h index f0ea870..700d266 100644 --- a/src/rpnlib.h +++ b/src/rpnlib.h @@ -23,8 +23,6 @@ along with the rpnlib library. If not, see . #ifndef rpnlib_h #define rpnlib_h -#include - #include "rpnlib_config.h" #include "rpnlib_error.h" @@ -62,7 +60,7 @@ struct rpn_input_buffer { const char* c_str() const; size_t length() const; - bool operator==(const String& other) const; + bool operator==(const std::string& other) const; rpn_input_buffer& operator+=(char c); rpn_input_buffer& write(const char* data, size_t data_length); diff --git a/src/rpnlib_config.h b/src/rpnlib_config.h index 296089e..4baa3de 100644 --- a/src/rpnlib_config.h +++ b/src/rpnlib_config.h @@ -21,6 +21,8 @@ along with the rpnlib library. If not, see . #pragma once +#include + #ifndef RPNLIB_INT_TYPE #define RPNLIB_INT_TYPE int32_t #endif diff --git a/src/rpnlib_error.h b/src/rpnlib_error.h index 729226e..e4738b2 100644 --- a/src/rpnlib_error.h +++ b/src/rpnlib_error.h @@ -22,6 +22,8 @@ along with the rpnlib library. If not, see . #pragma once +#include + enum class rpn_error_category { Unknown, Processing, diff --git a/src/rpnlib_operators.cpp b/src/rpnlib_operators.cpp index de3ae26..5a26612 100644 --- a/src/rpnlib_operators.cpp +++ b/src/rpnlib_operators.cpp @@ -28,8 +28,6 @@ extern "C" { #include "fs_math.h" } -#include "rpnlib_compat.h" - #include #include #include @@ -239,8 +237,8 @@ rpn_error _rpn_abs(rpn_context & ctxt) { } rpn_value result = - (top.isFloat()) ? rpn_value(rpnlib_abs(top.toFloat())) : - (top.isInt()) ? rpn_value(rpnlib_abs(top.toInt())) : + (top.isFloat()) ? rpn_value(std::abs(top.toFloat())) : + (top.isInt()) ? rpn_value(std::abs(top.toInt())) : (rpn_value{}); _rpn_stack_eat(ctxt, 1); @@ -392,7 +390,7 @@ rpn_error _rpn_index(rpn_context & ctxt) { return conversion.error(); } - auto offset = rpnlib_round(conversion.value()); + auto offset = std::round(conversion.value()); if (offset >= 0.) { if ((offset + 1) > size) { return rpn_operator_error::InvalidArgument; @@ -539,7 +537,7 @@ rpn_error _rpn_round(rpn_context & ctxt) { return conversion.error(); } - rpn_float limit = rpnlib_round(conversion.value()); + rpn_float limit = std::round(conversion.value()); rpn_float multiplier = 1.0; for (int i = 0; i < limit; ++i) { multiplier *= 10.0; @@ -742,12 +740,6 @@ rpn_error _rpn_assign(rpn_context & ctxt) { // Functions methods // ---------------------------------------------------------------------------- -rpn_operator::rpn_operator(const char* name, unsigned char argc, callback_type callback) : - name(name), - argc(argc), - callback(callback) -{} - bool rpn_operator_set(rpn_context & ctxt, const char * name, unsigned char argc, rpn_operator::callback_type callback) { ctxt.operators.emplace_front(name, argc, callback); return true; diff --git a/src/rpnlib_operators.h b/src/rpnlib_operators.h index a435f28..2962570 100644 --- a/src/rpnlib_operators.h +++ b/src/rpnlib_operators.h @@ -28,16 +28,18 @@ struct rpn_operator { using callback_type = rpn_error(*)(rpn_context &); rpn_operator() = delete; - rpn_operator(const char*, unsigned char, callback_type); - rpn_operator(const rpn_operator&) = default; - rpn_operator(rpn_operator&& other) noexcept : - name(std::move(other.name)), - argc(other.argc), - callback(other.callback) + template + rpn_operator(T&& name_, unsigned char argc_, callback_type callback_) : + name(std::forward(name_)), + argc(argc_), + callback(callback_) {} - String name; + rpn_operator(const rpn_operator&) = default; + rpn_operator(rpn_operator&& other) noexcept = default; + + std::string name; unsigned char argc; callback_type callback; }; diff --git a/src/rpnlib_util.h b/src/rpnlib_util.h index c6d6ac8..bb5a6f4 100644 --- a/src/rpnlib_util.h +++ b/src/rpnlib_util.h @@ -22,6 +22,8 @@ along with the rpnlib library. If not, see . #pragma once #include "rpnlib.h" + +#include #include template @@ -35,14 +37,14 @@ void rpn_stack_foreach(rpn_context & ctxt, Callback callback) { template void rpn_variables_foreach(rpn_context & ctxt, Callback callback) { for (auto& var : ctxt.variables) { - callback(var.name, *(var.value.get())); + callback(var.name.c_str(), *(var.value.get())); } } template void rpn_operators_foreach(rpn_context & ctxt, Callback callback) { for (auto& op : ctxt.operators) { - callback(op.name, op.argc, op.callback); + callback(op.name.c_str(), op.argc, op.callback); } } @@ -65,7 +67,6 @@ void rpn_handle_error(const rpn_error& error, Visitor&& visitor) { template struct rpn_error_decoder { - rpn_error_decoder(Callback&& callback) : callback(callback) {} @@ -152,11 +153,12 @@ struct rpn_error_decoder { } void operator()(int code) { - callback(String("Unknown error #") + String(code)); + char buffer[33]; + snprintf(buffer, sizeof(buffer), "Unknown error #%d", code); + callback(buffer); } Callback callback; - }; template diff --git a/src/rpnlib_value.cpp b/src/rpnlib_value.cpp index 3734290..c8e1c29 100644 --- a/src/rpnlib_value.cpp +++ b/src/rpnlib_value.cpp @@ -25,12 +25,11 @@ along with the rpnlib library. If not, see . #include +#include #include #include #include -#include "rpnlib_compat.h" - // TODO: implement fs_math operations namespace { @@ -144,7 +143,7 @@ rpn_value::rpn_value() : rpn_value::rpn_value(const rpn_value& other) { if (other.type == rpn_value::Type::String) { - new (&as_string) String(other.as_string); + new (&as_string) std::string(other.as_string); type = Type::String; } else { assignPrimitive(other); @@ -158,8 +157,8 @@ rpn_value::rpn_value(const rpn_value& other) { rpn_value::rpn_value(rpn_value&& other) noexcept { if (other.type == rpn_value::Type::String) { type = Type::String; - new (&as_string) String(std::move(other.as_string)); - other.as_string.~String(); + new (&as_string) std::string(std::move(other.as_string)); + other.as_string.~basic_string(); } else { assignPrimitive(other); } @@ -194,24 +193,24 @@ rpn_value::rpn_value(rpn_float value) : rpn_value::rpn_value(const char* value) : type(rpn_value::Type::String) { - new (&as_string) String(value); + new (&as_string) std::string(value); } -rpn_value::rpn_value(const String& value) : +rpn_value::rpn_value(const std::string& value) : type(rpn_value::Type::String) { - new (&as_string) String(value); + new (&as_string) std::string(value); } -rpn_value::rpn_value(String&& value) : +rpn_value::rpn_value(std::string&& value) : type(rpn_value::Type::String) { - new (&as_string) String(std::move(value)); + new (&as_string) std::string(std::move(value)); } rpn_value::~rpn_value() { if (type == rpn_value::Type::String) { - as_string.~String(); + as_string.~basic_string(); } } @@ -245,7 +244,7 @@ void rpn_value::assign(const rpn_value& other) noexcept { if (type == rpn_value::Type::String) { as_string = other.as_string; } else { - new (&as_string) String(other.as_string); + new (&as_string) std::string(other.as_string); } } else { assignPrimitive(other); @@ -289,7 +288,7 @@ bool rpn_value::toBoolean() const { result = static_cast(0.0) != as_float; break; case rpn_value::Type::String: { - using size_type = decltype(std::declval().length()); + using size_type = decltype(std::declval().length()); result = static_cast(0ul) < as_string.length(); break; } @@ -331,7 +330,7 @@ rpn_optional rpn_value::checkedToInt() const { constexpr rpn_float upper = std::numeric_limits::max(); constexpr rpn_float lower = std::numeric_limits::min(); if ((lower <= as_float) && (as_float <= upper)) { - result = rpnlib_round(as_float); + result = std::round(as_float); break; } result = rpn_value_error::OutOfRangeConversion; @@ -382,7 +381,7 @@ rpn_optional rpn_value::checkedToUint() const { constexpr rpn_float upper = std::numeric_limits::max(); constexpr rpn_float lower = std::numeric_limits::min(); if ((as_float >= lower) && (as_float <= upper)) { - result = rpnlib_round(as_float); + result = std::round(as_float); break; } result = rpn_value_error::OutOfRangeConversion; @@ -435,29 +434,100 @@ rpn_float rpn_value::toFloat() const { return isFloat() ? as_float : checkedToFloat().value(); } -String rpn_value::toString() const { - String result(""); +namespace { + +inline std::string _rpn_value_to_string(int value) { + char buffer[4 * sizeof(int)]; + snprintf(buffer, sizeof(buffer), "%d", value); + return buffer; +} + +inline std::string _rpn_value_to_string(unsigned int value) { + char buffer[4 * sizeof(unsigned int)]; + snprintf(buffer, sizeof(buffer), "%u", value); + return buffer; +} + +inline std::string _rpn_value_to_string(unsigned long value) { + char buffer[4 * sizeof(unsigned long)]; + snprintf(buffer, sizeof(buffer), "%lu", value); + return buffer; +} + +inline std::string _rpn_value_to_string(unsigned long long value) { + char buffer[4 * sizeof(unsigned long long)]; + snprintf(buffer, sizeof(buffer), "%llu", value); + return buffer; +} + +inline std::string _rpn_value_to_string(long value) { + char buffer[4 * sizeof(long)]; + snprintf(buffer, sizeof(buffer), "%ld", value); + return buffer; +} + +inline std::string _rpn_value_to_string(long long value) { + char buffer[4 * sizeof(long long)]; + snprintf(buffer, sizeof(buffer), "%lld", value); + return buffer; +} + +inline std::string _rpn_value_to_string(double value) { + asm(".global _printf_float"); + + constexpr int StackSize { 64 }; + constexpr int HeapSize { 20 + std::numeric_limits::max_exponent10 }; + + char buffer[StackSize]; + auto len = snprintf(buffer, StackSize, "%g", value); + if (len < 0) { + return {}; + } + + if (len <= StackSize) { + return buffer; + } + + std::string string(HeapSize, '\0'); + len = snprintf(&string.front(), HeapSize, "%g", value); + string.resize(len); + return string; +} + +inline std::string _rpn_value_to_string(rpn_value_error value) { + static_assert(sizeof(int) >= sizeof(std::underlying_type::type), ""); + char buffer[10 + (4 * sizeof(int))]; + snprintf(buffer, sizeof(buffer), "error %d", static_cast(value)); + return buffer; +} + +std::string _rpn_value_to_string(bool value) { + return value ? "true" : "false"; +} + +} // namespace + +std::string rpn_value::toString() const { + std::string result; switch (type) { case rpn_value::Type::Null: - result = F("null"); + result = "null"; break; case rpn_value::Type::Error: - result = F("(as_error)); - result += F(">"); + result = _rpn_value_to_string(as_error); break; case rpn_value::Type::Boolean: - result = as_boolean ? F("true") : F("false"); + result = _rpn_value_to_string(as_boolean); break; case rpn_value::Type::Integer: - result = String(as_integer); + result = _rpn_value_to_string(as_integer); break; case rpn_value::Type::Unsigned: - result = String(as_unsigned); + result = _rpn_value_to_string(as_unsigned); break; case rpn_value::Type::Float: - result = String(as_float); + result = _rpn_value_to_string(as_float); break; case rpn_value::Type::String: result = as_string; @@ -595,13 +665,13 @@ bool rpn_value::operator==(const rpn_value& other) const { // - https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/ constexpr auto epsilon = std::numeric_limits::epsilon(); if (other.isFloat()) { - result = rpnlib_abs(as_float - other.as_float) <= epsilon; + result = std::abs(as_float - other.as_float) <= epsilon; break; } auto conversion = other.checkedToFloat(); if (conversion.ok()) { - result = rpnlib_abs(as_float - conversion.value()) <= epsilon; + result = std::abs(as_float - conversion.value()) <= epsilon; break; } @@ -649,7 +719,7 @@ rpn_value rpn_value::operator+(const rpn_value& other) { const auto our_size = as_string.length(); const auto other_size = other.as_string.length(); - new (&val.as_string) String(); + new (&val.as_string) std::string(); val.as_string.reserve(our_size + other_size + 1); val.as_string += as_string; val.as_string += other.as_string; diff --git a/src/rpnlib_value.h b/src/rpnlib_value.h index 3059002..d27f71d 100644 --- a/src/rpnlib_value.h +++ b/src/rpnlib_value.h @@ -22,17 +22,21 @@ along with the rpnlib library. If not, see . #pragma once -#include + #include +#include #include - -#include #include +#include +#include +#include #include "rpnlib_error.h" template struct rpn_optional { + //static_assert(std::is_trivially_constructible::value, ""); + rpn_optional() = delete; rpn_optional(T default_value, rpn_value_error default_error) : _value(default_value), @@ -97,8 +101,8 @@ struct rpn_value { explicit rpn_value(rpn_uint); explicit rpn_value(rpn_float); explicit rpn_value(const char*); - explicit rpn_value(const String&); - explicit rpn_value(String&&); + explicit rpn_value(const std::string&); + explicit rpn_value(std::string&&); template explicit rpn_value(rpn_optional value) : @@ -136,7 +140,7 @@ struct rpn_value { rpn_int toInt() const; rpn_uint toUint() const; rpn_float toFloat() const; - String toString() const; + std::string toString() const; // Optional result when we need to ensure that target // value did convert without any issues @@ -166,7 +170,7 @@ struct rpn_value { rpn_int as_integer; rpn_uint as_unsigned; rpn_float as_float; - String as_string; + std::string as_string; }; }; diff --git a/src/rpnlib_variable.cpp b/src/rpnlib_variable.cpp index 1d97d39..6208a3d 100644 --- a/src/rpnlib_variable.cpp +++ b/src/rpnlib_variable.cpp @@ -49,8 +49,8 @@ bool rpn_variables_unref(rpn_context& ctxt) { namespace { template -bool _rpn_variable_set(rpn_context & ctxt, const String& name, Value&& value) { - if (!name.length() || (name.indexOf(' ') >= 0)) { +bool _rpn_variable_set(rpn_context & ctxt, const std::string& name, Value&& value) { + if (!name.length() || (name.find(' ') != std::string::npos)) { return false; } @@ -66,15 +66,15 @@ bool _rpn_variable_set(rpn_context & ctxt, const String& name, Value&& value) { } -bool rpn_variable_set(rpn_context & ctxt, const String& name, const rpn_value& value) { +bool rpn_variable_set(rpn_context & ctxt, const std::string& name, const rpn_value& value) { return _rpn_variable_set(ctxt, name, value); } -bool rpn_variable_set(rpn_context & ctxt, const String& name, rpn_value&& value) { +bool rpn_variable_set(rpn_context & ctxt, const std::string& name, rpn_value&& value) { return _rpn_variable_set(ctxt, name, std::move(value)); } -bool rpn_variable_get(rpn_context & ctxt, const String& name, rpn_value& value) { +bool rpn_variable_get(rpn_context & ctxt, const std::string& name, rpn_value& value) { for (auto& v : ctxt.variables) { if (v.name != name) continue; value = *v.value.get(); @@ -83,13 +83,13 @@ bool rpn_variable_get(rpn_context & ctxt, const String& name, rpn_value& value) return false; } -rpn_value rpn_variable_get(rpn_context & ctxt, const String& name) { +rpn_value rpn_variable_get(rpn_context & ctxt, const std::string& name) { rpn_value value; rpn_variable_get(ctxt, name, value); return value; } -bool rpn_variable_del(rpn_context & ctxt, const String& name) { +bool rpn_variable_del(rpn_context & ctxt, const std::string& name) { auto end = ctxt.variables.end(); auto prev = ctxt.variables.before_begin(); auto v = prev; diff --git a/src/rpnlib_variable.h b/src/rpnlib_variable.h index a1eb985..11fb146 100644 --- a/src/rpnlib_variable.h +++ b/src/rpnlib_variable.h @@ -31,10 +31,7 @@ along with the rpnlib library. If not, see . struct rpn_variable { rpn_variable(const rpn_variable&) = default; - rpn_variable(rpn_variable&& other) noexcept : - name(std::move(other.name)), - value(std::move(other.value)) - {} + rpn_variable(rpn_variable&& other) noexcept = default; template rpn_variable(Name&& name, std::shared_ptr value) : @@ -48,18 +45,18 @@ struct rpn_variable { value(std::make_shared(std::forward(value))) {} - String name; + std::string name; std::shared_ptr value; }; -bool rpn_variable_set(rpn_context &, const String& name, const rpn_value& value); -bool rpn_variable_set(rpn_context &, const String& name, rpn_value&& value); +bool rpn_variable_set(rpn_context &, const std::string& name, const rpn_value& value); +bool rpn_variable_set(rpn_context &, const std::string& name, rpn_value&& value); -bool rpn_variable_get(rpn_context &, const String& name, rpn_value& value); -rpn_value rpn_variable_get(rpn_context &, const String& name); +bool rpn_variable_get(rpn_context &, const std::string& name, rpn_value& value); +rpn_value rpn_variable_get(rpn_context &, const std::string& name); -bool rpn_variable_del(rpn_context &, const String& name); +bool rpn_variable_del(rpn_context &, const std::string& name); size_t rpn_variables_size(rpn_context &); bool rpn_variables_clear(rpn_context &); diff --git a/test/piotest/main.cpp b/test/piotest/main.cpp index eca8550..94ca619 100644 --- a/test/piotest/main.cpp +++ b/test/piotest/main.cpp @@ -22,7 +22,6 @@ along with the rpnlib library. If not, see . */ -#include #include #include @@ -161,8 +160,8 @@ void _run_and_compare(rpn_context & ctxt, const char* command, T expected, int l UnityMessage(command, line); if (!rpn_process(ctxt, command)) { - String message("rpn_process() failed with \""); - rpn_handle_error(ctxt.error, rpn_decode_errors([&message](const String& decoded) { + std::string message("rpn_process() failed with \""); + rpn_handle_error(ctxt.error, rpn_decode_errors([&message](const std::string& decoded) { message += decoded; })); message += "\" at position "; @@ -726,7 +725,7 @@ void test_strings() { rpn_context ctxt; TEST_ASSERT_TRUE(rpn_init(ctxt)); - rpn_value original { String("12345") }; + rpn_value original { std::string("12345") }; TEST_ASSERT_TRUE(rpn_variable_set(ctxt, "value", original)); run_and_compare_ctx(ctxt, "&value &value +", rpn_values("1234512345")); @@ -934,7 +933,7 @@ void test_overflow() { rpn_context ctxt; TEST_ASSERT_TRUE(rpn_init(ctxt)); - String a; + std::string a; auto size = ctxt.input_buffer.Size + 1; while (size--) { a += 'x'; @@ -944,8 +943,8 @@ void test_overflow() { return 0; }; - String b(a.substring(1)); - String c(a.substring(2)); + std::string b(a.substr(1)); + std::string c(a.substr(2)); TEST_ASSERT_TRUE(rpn_operator_set(ctxt, a.c_str(), 0, callback)); TEST_ASSERT_TRUE(rpn_operator_set(ctxt, b.c_str(), 0, callback));