From 98f33e9b58c40174ff6974120694053bac59b57b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 5 Jul 2022 12:45:04 -0400 Subject: [PATCH] convert std::string std::string_view and cast to std::string for debug logging --- src/zm_monitorlink_expression.cpp | 89 ++++++++++++++++++++++++------- src/zm_monitorlink_expression.h | 2 +- src/zm_monitorlink_token.h | 3 ++ 3 files changed, 74 insertions(+), 20 deletions(-) diff --git a/src/zm_monitorlink_expression.cpp b/src/zm_monitorlink_expression.cpp index 1f9986a7d..de8938b3a 100644 --- a/src/zm_monitorlink_expression.cpp +++ b/src/zm_monitorlink_expression.cpp @@ -7,7 +7,7 @@ bool MonitorLinkExpression::parse() { Tokens tokens; auto first = std::begin(expression_); - Debug(1, "Parsing %s", expression_.c_str()); + Debug(1, "Parsing %s", std::string(expression_).c_str()); // First we tokenize while (first != std::end(expression_)) { auto const second = std::find_first_of( @@ -16,11 +16,11 @@ bool MonitorLinkExpression::parse() { ); if (first != second) { - std::string t = expression_.substr( + std::string_view t = expression_.substr( std::distance(std::begin(expression_), first), std::distance(first, second) ); - Debug(1, "Have a token %s", t.c_str()); + Debug(1, "Have a token %s", std::string(t).c_str()); tokens.emplace_back(t); } @@ -30,15 +30,18 @@ bool MonitorLinkExpression::parse() { break; } - std::string delim { second, 1 }; + std::string_view delim { second, 1 }; if (!delim.empty()) { - Debug(1, "Have delim %s", delim.c_str()); + Debug(1, "Have delim %s", std::string(delim).c_str()); tokens.emplace_back(delim); } first = std::next(second); } - if (tokens.empty()) return false; + if (tokens.empty()) { + Debug(1, "No tokens?"); + return false; + } std::size_t current{ 0u }; @@ -48,9 +51,13 @@ bool MonitorLinkExpression::parse() { } bool MonitorLinkExpression::evaluate() { + if (!tree_) { + Debug(1, "No tree"); + return false; + } MonitorLinkExpression::result result = this->visit(*tree_); if (!result.success) { - Warning("%s", result.message.c_str()); + Warning("%s", std::string(result.message).c_str()); return false; } return true; @@ -58,15 +65,23 @@ bool MonitorLinkExpression::evaluate() { MonitorLinkExpression::result MonitorLinkExpression::visit(Node const & node) { - if ( nullptr == node.left || nullptr == node.right ) { + Debug(1, "visit: Node: %p", &node); + //Debug(1, "visit: Node: left %p right: %p", node.left, node.right); + if (node.token.type() == Token::TokenType::monitorlink) { + return { true, node.token.value() }; + } else if (nullptr == node.left || nullptr == node.right) { return { false, "Missing operand" }; } + Debug(1, "Token: %d", static_cast(node.token.type())); + Debug(1, "Token: value %s", std::string(node.token.value()).c_str()); switch ( node.token.type() ) { case Token::TokenType::logical_and: return visit_logical_and(node); case Token::TokenType::logical_or : + Debug(1, "or"); case Token::TokenType::logical_comma : + Debug(1, "comma"); return visit_logical_or(node); default: return { false, "Unknown token type" }; @@ -103,26 +118,51 @@ MonitorLinkExpression::visit_logical_or(MonitorLinkExpression::Node const & node std::unique_ptr MonitorLinkExpression::parse_expression( Tokens const & tokens, std::size_t & current ) { - auto left{ parse_and_operation(tokens, current) }; + if (tokens.size() == 1) { + Debug(1, "Special case monitorlink"); + // Special case, must be a monitorlink + return std::make_unique(tokens[0]); + } + // First token could me a parenthesis or monitorlink. Otherwise invalid. + + //auto left{ std::make_unique(tokens[current]) }; + //if ( tokens[current].is( + + //parse_and_operation(tokens, current) }; + + /* if ( has_unused(tokens, current) and tokens[current].is_not(Token::TokenType::logical_or) + and + tokens[current].is_not(Token::TokenType::logical_comma) ) { + Debug(1, "parse_expression: not or, Returning left %s", std::string(left->token.value()).c_str()); return left; } + */ - while ( - has_unused(tokens, current) - and - tokens[current].is(Token::TokenType::logical_or) - ) { - ++current; - auto logical_or{ std::make_unique(Token::TokenType::logical_or) }; + std::unique_ptr left; + if (tokens[current].is(Token::TokenType::monitorlink)) { + left = std::make_unique(tokens[current]); + current++; + } else { + left = parse_and_operation(tokens, current); + // invalid + //return nullptr; + } + + while (has_unused(tokens, current) && tokens[ current ].is( Token::TokenType::logical_or )) { + + auto logical_or{ std::make_unique( Token::TokenType::logical_or ) }; auto right{ parse_and_operation( tokens, current ) }; - if ( right == nullptr ) { return nullptr; } + if ( right == nullptr ) { + Debug(1, "null from right side"); + return nullptr; + } logical_or->left = std::move( left ); logical_or->right = std::move( right ); @@ -136,7 +176,11 @@ std::unique_ptr MonitorLinkExpression::parse_and_operation( Tokens const & tokens, std::size_t & current ) { auto left{ parse_parentheses( tokens, current ) }; - if (left == nullptr) return nullptr; + if (left == nullptr) { + Debug(1, "null from parse_parenteses, adding a left."); + //left = std::make_unique< Node >(Token::TokenType::lp); + return nullptr; + } while ( has_unused(tokens, current) @@ -148,7 +192,12 @@ MonitorLinkExpression::parse_and_operation( Tokens const & tokens, std::size_t & auto logical_and{ std::make_unique< Node >(Token::TokenType::logical_and) }; auto right{parse_parentheses(tokens, current) }; - if (right == nullptr) return nullptr; + if (right == nullptr) { + // No right parentheses. Add it? + Debug(1, "No right parenthesis, adding it"); + //right = std::make_unique< Node >(Token::TokenType::rp); + return nullptr; + } logical_and->left = std::move(left); logical_and->right = std::move(right); @@ -165,6 +214,8 @@ MonitorLinkExpression::parse_parentheses(Tokens const & tokens, std::size_t & cu if (tokens[current].is(Token::TokenType::lp)) { ++current; auto expression{ parse_expression(tokens, current) }; + + // Because we are parsing a left, there SHOULD be a remaining right. If not, invalid. if (!has_unused(tokens, current)) return nullptr; if (tokens[ current++ ].is(Token::TokenType::rp)) { diff --git a/src/zm_monitorlink_expression.h b/src/zm_monitorlink_expression.h index 177fdeed7..692766722 100644 --- a/src/zm_monitorlink_expression.h +++ b/src/zm_monitorlink_expression.h @@ -65,7 +65,7 @@ class MonitorLinkExpression { /** * Message in case of the fault. */ - std::string message{}; + std::string_view message{}; }; public: diff --git a/src/zm_monitorlink_token.h b/src/zm_monitorlink_token.h index 353382e17..11fe98146 100644 --- a/src/zm_monitorlink_token.h +++ b/src/zm_monitorlink_token.h @@ -85,6 +85,7 @@ class Token { Token(TokenType const type, std::string_view const value) : type_(type) , value_(value) + , monitor_link_(nullptr) { if (type_ == TokenType::monitorlink) { auto colon_position = value_.find(':'); @@ -110,6 +111,7 @@ class Token { constexpr Token() noexcept : type_(TokenType::unknown), + value_(""), monitor_link_(nullptr) { } @@ -120,6 +122,7 @@ class Token { constexpr Token( TokenType const type ) noexcept : type_ ( type ) + , value_("") , monitor_link_(nullptr) {}