From 5e548ce3abadd7b84eca9dad3c4f87839e11c07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Tue, 18 Apr 2023 16:47:42 +0200 Subject: [PATCH] Properly handle m3 unit in calculations. --- src/formula.cc | 19 ++++++++++++------- tests/test_formula_errors.sh | 23 ++++++++++++++++++++--- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/formula.cc b/src/formula.cc index b252f3c..f6c90cf 100644 --- a/src/formula.cc +++ b/src/formula.cc @@ -490,14 +490,17 @@ size_t FormulaImplementation::findUnit(size_t i) // All units start with a lower case a-z, followed by more letters and _ underscores. if (!is_letter(c)) return 0; + size_t longest_unit = 0; + #define X(cname,lcname,hrname,quantity,explanation) \ if ( (i+sizeof(#lcname)-1 <= len) && \ - !is_letter_or_underscore(formula_[i+sizeof(#lcname)-1]) && \ - !strncmp(#lcname, formula_.c_str()+i, sizeof(#lcname)-1)) return sizeof(#lcname)-1; + !is_letter_digit_or_underscore(formula_[i+sizeof(#lcname)-1]) && \ + !strncmp(#lcname, formula_.c_str()+i, sizeof(#lcname)-1) && \ + longest_unit < (sizeof(#lcname)-1)) { longest_unit = (sizeof(#lcname)-1); } LIST_OF_UNITS #undef X - return 0; + return longest_unit; } size_t FormulaImplementation::findField(size_t i) @@ -672,7 +675,9 @@ size_t FormulaImplementation::parseOps(size_t i) { if (next == NULL || next->type != TokenType::UNIT) { - errors_.push_back(tostrprintf("Constant number %s lacks a unit!\n", tok->vals(formula_).c_str())); + errors_.push_back(tostrprintf("Constant number %s lacks a valid unit!\n%s", + tok->vals(formula_).c_str(), + tok->withMarker(formula_).c_str())); valid_ = false; return i; } @@ -699,14 +704,14 @@ size_t FormulaImplementation::parsePar(size_t i) i = next; } - if (tok == NULL) + if (valid_ && tok == NULL) { - errors_.push_back(tostrprintf("Missing closing parenthesis at end of formula!\n")); + errors_.push_back("Missing closing parenthesis at end of formula!\n"); valid_ = false; return i; } - if (tok->type != TokenType::RPAR) + if (valid_ && tok->type != TokenType::RPAR) { errors_.push_back("Expected closing parenthesis!\n"+tok->withMarker(formula_)); valid_ = false; diff --git a/tests/test_formula_errors.sh b/tests/test_formula_errors.sh index bd710b5..1ec5048 100755 --- a/tests/test_formula_errors.sh +++ b/tests/test_formula_errors.sh @@ -11,16 +11,33 @@ TESTRESULT="ERROR" $PROG --format=json \ --calculate_sumtemp_c='external_temperature_c*198' \ - --calculate_addtemp_c='external_temperature_c + 1100' \ + --calculate_addtemp_c='32+external_temperature_c' \ + --calculate_tjo_m3='99m3+12' \ + --calculate_bar_m3='99m3+12m' \ + --calculate_barr_m3='(123kw' \ --format=fields --selectfields=name \ 23442D2C998734761B168D2087D19EAD217F1779EDA86AB6_710008190000081900007F13 \ MyTapWater multical21 76348799 "" > $TEST/test_output.txt 2>&1 cat < $TEST/test_expected.txt Warning! Ignoring calculated field sumtemp because parse failed: -Constant number 198 lacks a unit! +Constant number 198 lacks a valid unit! +external_temperature_c*198 + ^~~~~ Warning! Ignoring calculated field addtemp because parse failed: -Constant number 1100 lacks a unit! +Constant number 32 lacks a valid unit! +32+external_temperature_c +^~~~~ +Warning! Ignoring calculated field tjo because parse failed: +Constant number 12 lacks a valid unit! +99m3+12 + ^~~~~ +Warning! Ignoring calculated field bar because parse failed: +Cannot add [m3|Volume|1m³] to [m|Length|1m]! +99m3+12m + ^~~~~ +Warning! Ignoring calculated field barr because parse failed: +Missing closing parenthesis at end of formula! MyTapWater EOF