From b239dd5fd109a03a8b2feb4263801df3040fe7da Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Mon, 7 Mar 2016 22:37:20 -0500 Subject: [PATCH] Formula engine: New string functions find_string and replace --- src/formula_function.cpp | 72 +++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/src/formula_function.cpp b/src/formula_function.cpp index f821af7296c5..2b222015fddf 100644 --- a/src/formula_function.cpp +++ b/src/formula_function.cpp @@ -414,6 +414,42 @@ class substring_function : public function_expression { } }; +class replace_function : public function_expression { +public: + explicit replace_function(const args_list& args) + : function_expression("replace", args, 3, 4) + {} +private: + variant execute(const formula_callable& variables, formula_debugger *fdb) const { + + std::string result = args()[0]->evaluate(variables, fdb).as_string(); + std::string replacement = args().back()->evaluate(variables, fdb).as_string(); + + int offset = args()[1]->evaluate(variables, fdb).as_int(); + if(offset < 0) { + offset += result.size(); + if(offset < 0) { + offset = 0; + } + } else { + if(static_cast(offset) >= result.size()) { + return variant(result); + } + } + + if(args().size() > 2) { + int size = args()[2]->evaluate(variables, fdb).as_int(); + if(size < 0) { + size = -size; + offset = std::max(0, offset - size + 1); + } + return variant(result.replace(offset, size, replacement)); + } else { + return variant(result.replace(offset, std::string::npos, replacement)); + } + } +}; + class length_function : public function_expression { public: explicit length_function(const args_list& args) @@ -813,29 +849,23 @@ class contains_string_function : public function_expression { std::string str = args()[0]->evaluate(variables,fdb).as_string(); std::string key = args()[1]->evaluate(variables,fdb).as_string(); - if (key.size() > str.size()) - return variant(0); - - std::string::iterator str_it, key_it, tmp_it; + return variant(str.find(key) != std::string::npos); + } +}; - for(str_it = str.begin(); str_it != str.end() - (key.size()-1); ++str_it) - { - key_it = key.begin(); - if((key_it) == key.end()) { - return variant(1); - } - tmp_it = str_it; +class find_string_function : public function_expression { +public: + explicit find_string_function(const args_list& args) + : function_expression("find_string", args, 2, 2) + {} - while( *tmp_it == *key_it) - { - if( ++key_it == key.end()) - return variant(1); - if( ++tmp_it == str.end()) - return variant(0); - } - } +private: + variant execute(const formula_callable& variables, formula_debugger *fdb) const { + const std::string str = args()[0]->evaluate(variables,fdb).as_string(); + const std::string key = args()[1]->evaluate(variables,fdb).as_string(); - return variant(0); + size_t pos = str.find(key); + return variant(static_cast(pos)); } }; @@ -1434,6 +1464,7 @@ functions_map& get_functions_map() { FUNCTION(wave); FUNCTION(sort); FUNCTION(contains_string); + FUNCTION(find_string); FUNCTION(reverse); FUNCTION(filter); FUNCTION(find); @@ -1458,6 +1489,7 @@ functions_map& get_functions_map() { FUNCTION(tolist); FUNCTION(tomap); FUNCTION(substring); + FUNCTION(replace); FUNCTION(length); FUNCTION(concatenate); FUNCTION(sin);