diff --git a/code/espurna/button.cpp b/code/espurna/button.cpp index bfa2c39a..8021ca58 100644 --- a/code/espurna/button.cpp +++ b/code/espurna/button.cpp @@ -832,13 +832,14 @@ void buttonSetup() { terminalRegisterCommand(F("BUTTON"), [](const terminal::CommandContext& ctx) { unsigned index { 0u }; for (auto& button : _buttons) { - ctx.output.printf("%u - ", index++); + ctx.output.printf_P(PSTR("%u - "), index++); if (button.event_emitter) { auto& pin = button.event_emitter->pin(); - ctx.output.println(pin->description()); + ctx.output.print(pin->description()); } else { - ctx.output.println(F("Virtual")); + ctx.output.print(F("Virtual")); } + ctx.output.print('\n'); } terminalOK(ctx); diff --git a/code/espurna/ifan.cpp b/code/espurna/ifan.cpp index f1563af8..ed8a0ba0 100644 --- a/code/espurna/ifan.cpp +++ b/code/espurna/ifan.cpp @@ -351,7 +351,9 @@ void setup() { updateSpeedFromPayload(ctx.argv[1]); } - ctx.output.println(speedToPayload(config.speed)); + ctx.output.printf_P(PSTR("%s %s\n"), + (config.speed != FanSpeed::Off) ? "speed" : "fan is", + speedToPayload(config.speed)); terminalOK(ctx); }); #endif diff --git a/code/espurna/light.cpp b/code/espurna/light.cpp index c3ff380c..7167a94e 100644 --- a/code/espurna/light.cpp +++ b/code/espurna/light.cpp @@ -1834,7 +1834,7 @@ void _lightInitCommands() { _lightFromRgbPayload(ctx.argv[1].c_str()); lightUpdate(); } - ctx.output.println(lightRgbPayload()); + ctx.output.printf_P(PSTR("rgb %s\n"), lightRgbPayload().c_str()); terminalOK(ctx); }); @@ -1843,7 +1843,7 @@ void _lightInitCommands() { _lightFromHsvPayload(ctx.argv[1].c_str()); lightUpdate(); } - ctx.output.println(lightHsvPayload()); + ctx.output.printf_P(PSTR("hsv %s\n"), lightHsvPayload().c_str()); terminalOK(ctx); }); @@ -1852,7 +1852,7 @@ void _lightInitCommands() { _lightAdjustKelvin(ctx.argv[1].c_str()); lightUpdate(); } - ctx.output.printf("%ld\n", _toKelvin(_light_mireds)); + ctx.output.printf_P(PSTR("kelvin %ld\n"), _toKelvin(_light_mireds)); terminalOK(ctx); }); @@ -1861,7 +1861,7 @@ void _lightInitCommands() { _lightAdjustMireds(ctx.argv[1]); lightUpdate(); } - ctx.output.printf("%ld\n", _light_mireds); + ctx.output.printf_P(PSTR("mireds %ld\n"), _light_mireds); terminalOK(ctx); }); diff --git a/code/espurna/rpnrules.cpp b/code/espurna/rpnrules.cpp index 2a70cc41..707d47f9 100644 --- a/code/espurna/rpnrules.cpp +++ b/code/espurna/rpnrules.cpp @@ -553,14 +553,12 @@ void _rpnRfbSetup() { for (auto& code : _rfb_codes) { char buffer[128] = {0}; snprintf_P(buffer, sizeof(buffer), - PSTR("proto=%u raw=\"%s\" count=%u last=%u"), - code.protocol, - code.raw.c_str(), - code.count, - code.last - ); - ctx.output.println(buffer); + PSTR("proto=%u raw=\"%s\" count=%u last=%u\n"), + code.protocol, code.raw.c_str(), code.count, code.last); + ctx.output.print(buffer); } + + terminalOK(ctx); }); #endif @@ -589,20 +587,19 @@ void _rpnDeepSleep(uint64_t duration, RFMode mode) { } void _rpnShowStack(Print& print) { - print.println(F("Stack:")); + print.print(F("Stack:\n")); auto index = rpn_stack_size(_rpn_ctxt); - if (!index) { - print.println(F(" (empty)")); + if (index) { + rpn_stack_foreach(_rpn_ctxt, [&index, &print](rpn_stack_value::Type type, const rpn_value& value) { + print.printf_P(PSTR("%c %02u: %s\n"), + _rpnStackTypeTag(type), index--, + _rpnValueToString(value).c_str()); + }); return; } - rpn_stack_foreach(_rpn_ctxt, [&index, &print](rpn_stack_value::Type type, const rpn_value& value) { - print.printf("%c %02u: %s\n", - _rpnStackTypeTag(type), index--, - _rpnValueToString(value).c_str() - ); - }); + print.print(F(" (empty)\n")); } void _rpnInit() { @@ -872,11 +869,10 @@ void _rpnInitCommands() { for (auto& runner : _rpn_runners) { char buffer[128] = {0}; - snprintf_P(buffer, sizeof(buffer), PSTR("%p %s %u ms, last %u ms"), + snprintf_P(buffer, sizeof(buffer), PSTR("%p %s %u ms, last %u ms\n"), &runner, (RpnRunner::Policy::Periodic == runner.policy) ? "every" : "one-shot", - runner.period, runner.last - ); - ctx.output.println(buffer); + runner.period, runner.last); + ctx.output.print(buffer); } terminalOK(ctx); @@ -885,8 +881,8 @@ void _rpnInitCommands() { terminalRegisterCommand(F("RPN.VARS"), [](const terminal::CommandContext& ctx) { rpn_variables_foreach(_rpn_ctxt, [&ctx](const String& name, const rpn_value& value) { char buffer[256] = {0}; - snprintf_P(buffer, sizeof(buffer), PSTR(" %s: %s"), name.c_str(), _rpnValueToString(value).c_str()); - ctx.output.println(buffer); + snprintf_P(buffer, sizeof(buffer), PSTR(" %s: %s\n"), name.c_str(), _rpnValueToString(value).c_str()); + ctx.output.print(buffer); }); terminalOK(ctx); }); @@ -894,8 +890,8 @@ void _rpnInitCommands() { terminalRegisterCommand(F("RPN.OPS"), [](const terminal::CommandContext& ctx) { rpn_operators_foreach(_rpn_ctxt, [&ctx](const String& name, size_t argc, rpn_operator::callback_type) { char buffer[128] = {0}; - snprintf_P(buffer, sizeof(buffer), PSTR(" %s (%d)"), name.c_str(), argc); - ctx.output.println(buffer); + snprintf_P(buffer, sizeof(buffer), PSTR(" %s (%d)\n"), name.c_str(), argc); + ctx.output.print(buffer); }); terminalOK(ctx); }); @@ -906,10 +902,10 @@ void _rpnInitCommands() { return; } - ctx.output.print(F("Running RPN expression: ")); - ctx.output.println(ctx.argv[1].c_str()); + const char* ptr = ctx.argv[1].c_str(); + ctx.output.printf_P(PSTR("Expression: \"%s\"\n"), ctx.argv[1].c_str()); - if (!rpn_process(_rpn_ctxt, ctx.argv[1].c_str())) { + if (!rpn_process(_rpn_ctxt, ptr)) { rpn_stack_clear(_rpn_ctxt); char buffer[64] = {0}; snprintf_P(buffer, sizeof(buffer), PSTR("position=%u category=%d code=%d"), diff --git a/code/espurna/settings.cpp b/code/espurna/settings.cpp index fd42dcd0..8af979d3 100644 --- a/code/espurna/settings.cpp +++ b/code/espurna/settings.cpp @@ -458,15 +458,18 @@ void _settingsInitCommands() { terminalRegisterCommand(F("KEYS"), [](const terminal::CommandContext& ctx) { auto keys = settingsKeys(); - ctx.output.println(F("Current settings:")); + ctx.output.printf_P(PSTR("Current settings:")); + + String value; for (unsigned int i=0; i %s => \"%s\"\n", (keys[i]).c_str(), value.c_str()); + value = getSetting(keys[i]); + ctx.output.printf_P(PSTR("> %s => \"%s\"\n"), (keys[i]).c_str(), value.c_str()); } auto available [[gnu::unused]] = settings::kv_store.available(); - ctx.output.printf("Number of keys: %u\n", keys.size()); - ctx.output.printf("Available: %u bytes (%u%%)\n", available, (100 * available) / settings::kv_store.size()); + ctx.output.printf_P(PSTR("Number of keys: %u\n"), keys.size()); + ctx.output.printf_P(PSTR("Available: %u bytes (%u%%)\n"), + available, (100 * available) / settings::kv_store.size()); terminalOK(ctx); }); @@ -515,14 +518,14 @@ void _settingsInitCommands() { if (!result) { const auto maybeDefault = settingsQueryDefaults(key); if (maybeDefault.length()) { - ctx.output.printf("> %s => %s (default)\n", key.c_str(), maybeDefault.c_str()); + ctx.output.printf_P(PSTR("> %s => %s (default)\n"), key.c_str(), maybeDefault.c_str()); } else { - ctx.output.printf("> %s =>\n", key.c_str()); + ctx.output.printf_P(PSTR("> %s =>\n"), key.c_str()); } continue; } - ctx.output.printf("> %s => \"%s\"\n", key.c_str(), result.c_str()); + ctx.output.printf_P(PSTR("> %s => \"%s\"\n"), key.c_str(), result.c_str()); } terminalOK(ctx); diff --git a/code/espurna/terminal.cpp b/code/espurna/terminal.cpp index 326d4712..459d3fcd 100644 --- a/code/espurna/terminal.cpp +++ b/code/espurna/terminal.cpp @@ -128,8 +128,10 @@ struct TerminalIO final : public Stream { // Buffer data until we encounter line break, then flush via Raw debug method // (which is supposed to 1-to-1 copy the data, without adding the timestamp) #if DEBUG_SUPPORT - if (!size) return 0; - if (buffer[size-1] == '\0') return 0; + if (!size || ((size > 0) && buffer[size - 1] == '\0')) { + return 0; + } + if (_output.capacity() < (size + 2)) { _output.reserve(_output.size() + size + 2); } @@ -137,6 +139,7 @@ struct TerminalIO final : public Stream { reinterpret_cast(buffer), reinterpret_cast(buffer) + size ); + if (_output.end() != std::find(_output.begin(), _output.end(), '\n')) { _output.push_back('\0'); debugSendRaw(_output.data()); @@ -283,7 +286,7 @@ void _terminalInitCommands() { ? ctx.argv[1].toInt() : A0; - ctx.output.println(analogRead(pin)); + ctx.output.printf_P(PSTR("value %d\n"), analogRead(pin)); terminalOK(ctx); }); @@ -361,7 +364,7 @@ void _terminalInitCommands() { }); terminalRegisterCommand(F("UPTIME"), [](const terminal::CommandContext& ctx) { - ctx.output.println(getUptime()); + ctx.output.printf_P(PSTR("uptime %s\n"), getUptime().c_str()); terminalOK(ctx); }); @@ -641,11 +644,11 @@ void terminalRegisterCommand(const __FlashStringHelper* name, terminal::Terminal }; void terminalOK(Print& print) { - print.print(F("+OK\n")); + print.printf_P(PSTR("+%s\n"), "OK"); } void terminalError(Print& print, const String& error) { - print.printf("-ERROR: %s\n", error.c_str()); + print.printf_P(PSTR("-ERROR: %s\n"), error.c_str()); } void terminalOK(const terminal::CommandContext& ctx) { diff --git a/code/espurna/tuya.cpp b/code/espurna/tuya.cpp index 4990153f..4f476e73 100644 --- a/code/espurna/tuya.cpp +++ b/code/espurna/tuya.cpp @@ -613,12 +613,13 @@ error: terminalRegisterCommand(F("TUYA.SHOW"), [](const terminal::CommandContext& ctx) { ctx.output.printf_P(PSTR("Product: %s\n"), product.length() ? product.c_str() : "(unknown)"); - ctx.output.println(F("\nConfig:")); + + ctx.output.print(F("\nConfig:\n")); for (auto& kv : config) { ctx.output.printf_P(PSTR("\"%s\" => \"%s\"\n"), kv.key.c_str(), kv.value.c_str()); } - ctx.output.println(F("\nKnown DP(s):")); + ctx.output.print(F("\nKnown DP(s):\n")); #if LIGHT_PROVIDER == LIGHT_PROVIDER_CUSTOM if (channelStateId) { ctx.output.printf_P(PSTR("%u (bool) => lights state\n"), channelStateId.id()); diff --git a/code/espurna/wifi.cpp b/code/espurna/wifi.cpp index ada6cf63..bde2c46d 100644 --- a/code/espurna/wifi.cpp +++ b/code/espurna/wifi.cpp @@ -1784,7 +1784,7 @@ void init() { wifi::debug::mac(network.bssid).c_str(), network.rssi, network.channel, network.ssid.c_str()); } else { - ctx.output.println(F("STA: disconnected")); + ctx.output.print(F("STA: disconnected\n")); } }