From 1e0631d7e14b2880b6290952444f7412ec6c8214 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 30 Jan 2021 12:27:48 +0100 Subject: [PATCH] Refactor command line arguments --- tasmota/support.ino | 48 +++++++++++++++++--------------------- tasmota/xdrv_10_rules.ino | 14 +++++------ tasmota/xsns_02_analog.ino | 31 +++++++++++------------- 3 files changed, 41 insertions(+), 52 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index c2381f289..a302b4fb2 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -252,39 +252,33 @@ uint32_t ChrCount(const char *str, const char *delim) { return count; } +uint32_t ArgC(void) { + return ChrCount(XdrvMailbox.data, ",") +1; +} + // Function to return a substring defined by a delimiter at an index char* subStr(char* dest, char* str, const char *delim, int index) { -/* - // Exceptions on empty fields - char *act; - char *sub = nullptr; - char *ptr; - int i; + char* write = dest; + char* read = str; + char ch = '.'; - // Since strtok consumes the first arg, make a copy - strncpy(dest, str, strlen(str)+1); - for (i = 1, act = dest; i <= index; i++, act = nullptr) { - sub = strtok_r(act, delim, &ptr); - if (sub == nullptr) break; + while (index && (ch != '\0')) { + ch = *read++; + if (strchr(delim, ch)) { + index--; + if (index) { write = dest; } + } else { + *write++ = ch; + } } - return sub; -*/ - uint32_t len = strlen(str) -1; - // Since strtok consumes the first arg, make a copy - strncpy(dest, str, len +2); - // Since strtok_r will exception if last char is delim change to space - if (strchr(delim, dest[len]) != nullptr) { dest[len] = ' '; } + *write = '\0'; + dest = Trim(dest); + return dest; +} - char *ptr = dest; - char *sub; - int i = index; - while ( ptr && ((sub = strtok_r(ptr, delim, &ptr))) && (--i) ) { -// Serial.printf("%s|", sub); - } -// Serial.printf("%s|=\n|", sub); - sub = Trim(sub); - return sub; +char* ArgV(char* dest, int index) { + return subStr(dest, XdrvMailbox.data, ",", index); } float CharToFloat(const char *str) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 80bdd95df..c1dfa277e 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -2283,14 +2283,14 @@ void CmndScale(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_RULE_VARS)) { if (XdrvMailbox.data_len > 0) { - if (strchr(XdrvMailbox.data, ',') != nullptr) { // Process parameter entry - char sub_string[XdrvMailbox.data_len +1]; + if (ArgC() > 1) { // Process parameter entry + char argument[XdrvMailbox.data_len]; - float valueIN = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 1)); - float fromLow = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 2)); - float fromHigh = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 3)); - float toLow = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 4)); - float toHigh = CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 5)); + float valueIN = CharToFloat(ArgV(argument, 1)); + float fromLow = CharToFloat(ArgV(argument, 2)); + float fromHigh = CharToFloat(ArgV(argument, 3)); + float toLow = CharToFloat(ArgV(argument, 4)); + float toHigh = CharToFloat(ArgV(argument, 5)); float value = map_double(valueIN, fromLow, fromHigh, toLow, toHigh); dtostrfd(value, Settings.flag2.calc_resolution, rules_vars[XdrvMailbox.index -1]); bitSet(Rules.vars_event, XdrvMailbox.index -1); diff --git a/tasmota/xsns_02_analog.ino b/tasmota/xsns_02_analog.ino index 2c8c4a4fa..f939c8d9e 100644 --- a/tasmota/xsns_02_analog.ino +++ b/tasmota/xsns_02_analog.ino @@ -591,8 +591,8 @@ void CmndAdcParam(void) { if (XdrvMailbox.data_len) { if (XdrvMailbox.payload > ADC_INPUT) { AdcGetSettings(idx); - if (ChrCount(XdrvMailbox.data, ",") > 2) { // Process parameter entry - char sub_string[XdrvMailbox.data_len +1]; + if (ArgC() > 3) { // Process parameter entry + char argument[XdrvMailbox.data_len]; // AdcParam 2, 32000, 10000, 3350 // AdcParam 3, 10000, 12518931, -1.405 // AdcParam 4, 128, 0, 0 @@ -601,29 +601,24 @@ void CmndAdcParam(void) { // AdcParam 7, 0, 2146, 0.23 // AdcParam 8, 1000, 0, 0 Adc[idx].type = XdrvMailbox.payload; - Adc[idx].param1 = strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), nullptr, 10); - Adc[idx].param2 = strtol(subStr(sub_string, XdrvMailbox.data, ",", 3), nullptr, 10); + Adc[idx].param1 = strtol(ArgV(argument, 2), nullptr, 10); + Adc[idx].param2 = strtol(ArgV(argument, 3), nullptr, 10); if (ADC_RANGE == XdrvMailbox.payload) { - Adc[idx].param3 = abs(strtol(subStr(sub_string, XdrvMailbox.data, ",", 4), nullptr, 10)); - Adc[idx].param4 = abs(strtol(subStr(sub_string, XdrvMailbox.data, ",", 5), nullptr, 10)); + Adc[idx].param3 = abs(strtol(ArgV(argument, 4), nullptr, 10)); + Adc[idx].param4 = abs(strtol(ArgV(argument, 5), nullptr, 10)); } else { - Adc[idx].param3 = (int)(CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 4)) * 10000); + Adc[idx].param3 = (int)(CharToFloat(ArgV(argument, 4)) * 10000); } - if (ADC_PH == XdrvMailbox.payload) { - char *phLow_chr = subStr(sub_string, XdrvMailbox.data, ",", 2); - char *phHigh_chr = subStr(sub_string, XdrvMailbox.data, ",", 4); - float phLow = CharToFloat(phLow_chr); - float phHigh = CharToFloat(phHigh_chr); - + float phLow = CharToFloat(ArgV(argument, 2)); + float phHigh = CharToFloat(ArgV(argument, 4)); Adc[idx].param1 = phLow * ANALOG_PH_DECIMAL_MULTIPLIER; - Adc[idx].param2 = strtol(subStr(sub_string, XdrvMailbox.data, ",", 3), nullptr, 10); + Adc[idx].param2 = strtol(ArgV(argument, 3), nullptr, 10); Adc[idx].param3 = phHigh * ANALOG_PH_DECIMAL_MULTIPLIER; - Adc[idx].param4 = strtol(subStr(sub_string, XdrvMailbox.data, ",", 5), nullptr, 10); - - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Analog pH probe calibrated. cal-low(pH=ADC): %s=%d, cal-high(pH=ADC): %s=%d"), phLow_chr, Adc[idx].param2, phHigh_chr, Adc[idx].param4); + Adc[idx].param4 = strtol(ArgV(argument, 5), nullptr, 10); + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Analog pH probe calibrated. cal-low(pH=ADC) %2_f=%d, cal-high(pH=ADC) %2_f=%d"), + &phLow, Adc[idx].param2, &phHigh, Adc[idx].param4); } - if (ADC_CT_POWER == XdrvMailbox.payload) { if (((1 == Adc[idx].param1) & CT_FLAG_ENERGY_RESET) > 0) { for (uint32_t idx = 0; idx < MAX_ADCS; idx++) {