Utils: Break out expression parsing and evaluation
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I16101a37220be56722cedd273d5788393aa860fa
diff --git a/include/Expression.hpp b/include/Expression.hpp
new file mode 100644
index 0000000..b832e72
--- /dev/null
+++ b/include/Expression.hpp
@@ -0,0 +1,36 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+// Copyright (c) 2022 IBM Corp.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+
+#include <optional>
+#include <string>
+
+namespace expression
+{
+enum class Operation
+{
+ addition,
+ division,
+ multiplication,
+ subtraction,
+ modulo,
+};
+
+std::optional<Operation> parseOperation(std::string& op);
+int evaluate(int a, Operation op, int b);
+} // namespace expression
diff --git a/include/Utils.hpp b/include/Utils.hpp
index 13c199c..c54559a 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -40,15 +40,6 @@
using MapperGetSubTreeResponse =
boost::container::flat_map<std::string, DBusObject>;
-enum class TemplateOperation
-{
- addition,
- division,
- multiplication,
- subtraction,
- modulo,
-};
-
namespace properties
{
constexpr const char* interface = "org.freedesktop.DBus.Properties";
diff --git a/meson.build b/meson.build
index 80893ab..5f733af 100644
--- a/meson.build
+++ b/meson.build
@@ -210,6 +210,7 @@
executable(
'test_entity_manager',
'test/test_entity-manager.cpp',
+ 'src/Expression.cpp',
'src/Utils.cpp',
cpp_args: test_boost_args,
dependencies: [
diff --git a/src/Expression.cpp b/src/Expression.cpp
new file mode 100644
index 0000000..43fcaf7
--- /dev/null
+++ b/src/Expression.cpp
@@ -0,0 +1,79 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+// Copyright (c) 2022 IBM Corp.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "Expression.hpp"
+
+#include <stdexcept>
+
+namespace expression
+{
+std::optional<Operation> parseOperation(std::string& op)
+{
+ if (op == "+")
+ {
+ return Operation::addition;
+ }
+ if (op == "-")
+ {
+ return Operation::subtraction;
+ }
+ if (op == "*")
+ {
+ return Operation::multiplication;
+ }
+ if (op == R"(%)")
+ {
+ return Operation::modulo;
+ }
+ if (op == R"(/)")
+ {
+ return Operation::division;
+ }
+
+ return std::nullopt;
+}
+
+int evaluate(int a, Operation op, int b)
+{
+ switch (op)
+ {
+ case Operation::addition:
+ {
+ return a + b;
+ }
+ case Operation::subtraction:
+ {
+ return a - b;
+ }
+ case Operation::multiplication:
+ {
+ return a * b;
+ }
+ case Operation::division:
+ {
+ return a / b;
+ }
+ case Operation::modulo:
+ {
+ return a % b;
+ }
+
+ default:
+ throw std::invalid_argument("Unrecognised operation");
+ }
+}
+} // namespace expression
diff --git a/src/Utils.cpp b/src/Utils.cpp
index dd13113..b73e469 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -17,6 +17,7 @@
#include "Utils.hpp"
+#include "Expression.hpp"
#include "VariantVisitors.hpp"
#include <boost/algorithm/string/classification.hpp>
@@ -297,7 +298,8 @@
int number = std::visit(VariantToIntVisitor(), propValue);
bool isOperator = true;
- TemplateOperation next = TemplateOperation::addition;
+ std::optional<expression::Operation> next =
+ expression::Operation::addition;
auto it = split.begin();
@@ -305,37 +307,18 @@
{
if (isOperator)
{
- if (*it == "+")
- {
- next = TemplateOperation::addition;
- }
- else if (*it == "-")
- {
- next = TemplateOperation::subtraction;
- }
- else if (*it == "*")
- {
- next = TemplateOperation::multiplication;
- }
- else if (*it == R"(%)")
- {
- next = TemplateOperation::modulo;
- }
- else if (*it == R"(/)")
- {
- next = TemplateOperation::division;
- }
- else
+ next = expression::parseOperation(*it);
+ if (!next)
{
break;
}
}
else
{
- int constant = 0;
try
{
- constant = std::stoi(*it);
+ int constant = std::stoi(*it);
+ number = expression::evaluate(number, *next, constant);
}
catch (const std::invalid_argument&)
{
@@ -343,37 +326,6 @@
<< "\n";
continue;
}
- switch (next)
- {
- case TemplateOperation::addition:
- {
- number += constant;
- break;
- }
- case TemplateOperation::subtraction:
- {
- number -= constant;
- break;
- }
- case TemplateOperation::multiplication:
- {
- number *= constant;
- break;
- }
- case TemplateOperation::division:
- {
- number /= constant;
- break;
- }
- case TemplateOperation::modulo:
- {
- number = number % constant;
- break;
- }
-
- default:
- break;
- }
}
isOperator = !isOperator;
}
diff --git a/src/meson.build b/src/meson.build
index d1112cc..939574e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -4,6 +4,7 @@
executable(
'entity-manager',
'EntityManager.cpp',
+ 'Expression.cpp',
'PerformScan.cpp',
'PerformProbe.cpp',
'Overlay.cpp',
@@ -27,6 +28,7 @@
endif
executable(
'fru-device',
+ 'Expression.cpp',
'FruDevice.cpp',
'Utils.cpp',
'FruUtils.cpp',