From cd306c7d2b534fc6b163d80ea9c09f50d21932e2 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 24 Jan 2020 12:18:25 +0100 Subject: [PATCH] DSL: add xrange() --- lib/base/CMakeLists.txt | 1 + lib/base/generator-range.cpp | 20 ++++++++++++++++++++ lib/base/generator-range.hpp | 33 +++++++++++++++++++++++++++++++++ lib/base/scriptutils.cpp | 30 ++++++++++++++++++++++++++++++ lib/base/scriptutils.hpp | 2 ++ 5 files changed, 86 insertions(+) create mode 100644 lib/base/generator-range.cpp create mode 100644 lib/base/generator-range.hpp diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 1cdf0a409..aefa1cd08 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -41,6 +41,7 @@ set(base_SOURCES generator-array.cpp generator-array.hpp generator-filter.cpp generator-filter.hpp generator-map.cpp generator-map.hpp + generator-range.cpp generator-map.hpp generator-unique.cpp generator-unique.hpp initialize.cpp initialize.hpp intrusive-ptr.hpp diff --git a/lib/base/generator-range.cpp b/lib/base/generator-range.cpp new file mode 100644 index 000000000..efb6c23aa --- /dev/null +++ b/lib/base/generator-range.cpp @@ -0,0 +1,20 @@ +/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */ + +#include "base/generator-range.hpp" +#include "base/objectlock.hpp" +#include "base/value.hpp" + +using namespace icinga; + +bool GeneratorRange::GetNext(Value& out) +{ + ObjectLock oLock (this); + + if (m_Current < m_Stop) { + out = m_Current; + m_Current += m_Step; + return true; + } + + return false; +} diff --git a/lib/base/generator-range.hpp b/lib/base/generator-range.hpp new file mode 100644 index 000000000..d2e5881b4 --- /dev/null +++ b/lib/base/generator-range.hpp @@ -0,0 +1,33 @@ +/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */ + +#ifndef GENERATOR_RANGE_H +#define GENERATOR_RANGE_H + +#include "base/generator.hpp" +#include "base/value.hpp" + +namespace icinga +{ + +/** + * Supplies items [start, stop), incrementing by step. + * + * @ingroup base + */ +class GeneratorRange final : public Generator +{ +public: + inline GeneratorRange(double start, double stop, double step) + : m_Current(start), m_Stop(stop), m_Step(step) + { + } + + bool GetNext(Value& out) override; + +private: + double m_Current, m_Stop, m_Step; +}; + +} + +#endif /* GENERATOR_RANGE_H */ diff --git a/lib/base/scriptutils.cpp b/lib/base/scriptutils.cpp index 3611799ff..c59b7bf03 100644 --- a/lib/base/scriptutils.cpp +++ b/lib/base/scriptutils.cpp @@ -2,6 +2,8 @@ #include "base/scriptutils.hpp" #include "base/function.hpp" +#include "base/generator.hpp" +#include "base/generator-range.hpp" #include "base/scriptframe.hpp" #include "base/exception.hpp" #include "base/utility.hpp" @@ -32,6 +34,7 @@ REGISTER_SAFE_FUNCTION(System, union, &ScriptUtils::Union, ""); REGISTER_SAFE_FUNCTION(System, intersection, &ScriptUtils::Intersection, ""); REGISTER_FUNCTION(System, log, &ScriptUtils::Log, "severity:facility:value"); REGISTER_FUNCTION(System, range, &ScriptUtils::Range, "start:end:increment"); +REGISTER_FUNCTION(System, xrange, &ScriptUtils::XRange, "start:end:increment"); REGISTER_FUNCTION(System, exit, &Application::Exit, "status"); REGISTER_SAFE_FUNCTION(System, typeof, &ScriptUtils::TypeOf, "value"); REGISTER_SAFE_FUNCTION(System, keys, &ScriptUtils::Keys, "value"); @@ -380,6 +383,33 @@ Array::Ptr ScriptUtils::Range(const std::vector& arguments) return new Array(std::move(result)); } +Generator::Ptr ScriptUtils::XRange(const std::vector& arguments) +{ + double start, end, increment; + + switch (arguments.size()) { + case 1: + start = 0; + end = arguments[0]; + increment = 1; + break; + case 2: + start = arguments[0]; + end = arguments[1]; + increment = 1; + break; + case 3: + start = arguments[0]; + end = arguments[1]; + increment = arguments[2]; + break; + default: + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid number of arguments for xrange()")); + } + + return new GeneratorRange(start, end, increment); +} + Type::Ptr ScriptUtils::TypeOf(const Value& value) { return value.GetReflectionType(); diff --git a/lib/base/scriptutils.hpp b/lib/base/scriptutils.hpp index 7bd3e8b9d..dc764dfcf 100644 --- a/lib/base/scriptutils.hpp +++ b/lib/base/scriptutils.hpp @@ -7,6 +7,7 @@ #include "base/string.hpp" #include "base/array.hpp" #include "base/dictionary.hpp" +#include "base/generator.hpp" #include "base/type.hpp" #include "base/configobject.hpp" @@ -31,6 +32,7 @@ public: static Array::Ptr Intersection(const std::vector& arguments); static void Log(const std::vector& arguments); static Array::Ptr Range(const std::vector& arguments); + static Generator::Ptr XRange(const std::vector& arguments); static Type::Ptr TypeOf(const Value& value); static Array::Ptr Keys(const Object::Ptr& obj); static Dictionary::Ptr GetTemplate(const Value& vtype, const String& name);