container: root: common: utility: add PluggableSpace entrypoint

This commit is contained in:
2026-01-08 14:21:26 -08:00
parent 1f0b8e914e
commit cf5c2c4baa

View File

@@ -1,6 +1,6 @@
// docker-finance | modern accounting for the power-user // docker-finance | modern accounting for the power-user
// //
// Copyright (C) 2021-2025 Aaron Fiore (Founder, Evergreen Crypto LLC) // Copyright (C) 2021-2026 Aaron Fiore (Founder, Evergreen Crypto LLC)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@@ -412,10 +412,10 @@ class PluggablePath
bool m_is_repo, m_is_custom; bool m_is_repo, m_is_custom;
}; };
//! \brief Base namespace handler for various pluggables (plugins and macros) //! \brief Base pluggable space handler for various pluggables (plugins and macros)
//! //!
//! \details Handles pluggable namespace, typically used by pluggable //! \details Handles pluggable namespace and entrypoint class name,
//! implementations when auto-(un|re)loading. //! typically used by pluggable implementations when auto-(un|re)loading.
//! //!
//! \ingroup cpp_plugin_impl cpp_macro_impl //! \ingroup cpp_plugin_impl cpp_macro_impl
//! \since docker-finance 1.1.0 //! \since docker-finance 1.1.0
@@ -437,8 +437,8 @@ class PluggableSpace
!std::regex_match( !std::regex_match(
parsed, parsed,
std::regex{ std::regex{
"[a-zA-Z0-9:/_\\-]+"} /* TODO(unassigned): refine */), "[a-zA-Z0-9:/_\\-\\.]+"} /* TODO(unassigned): refine */),
"invalid characters in namespace"); "invalid characters in pluggable space");
if (parsed.find('/')) if (parsed.find('/'))
{ {
@@ -448,6 +448,10 @@ class PluggableSpace
{ {
parsed = std::regex_replace(parsed, std::regex{"-"}, "_"); parsed = std::regex_replace(parsed, std::regex{"-"}, "_");
} }
if (parsed.find('.'))
{
parsed = std::regex_replace(parsed, std::regex{"\\."}, "_");
}
} }
return parsed; return parsed;
@@ -455,6 +459,7 @@ class PluggableSpace
m_space.outer(parser(m_space.outer())); m_space.outer(parser(m_space.outer()));
m_space.inner(parser(m_space.inner())); m_space.inner(parser(m_space.inner()));
m_space.entry(parser(m_space.entry()));
return *this; return *this;
} }
@@ -462,7 +467,7 @@ class PluggableSpace
protected: protected:
// \note Since the current presumption is that a PluggableSpace is likely // \note Since the current presumption is that a PluggableSpace is likely
// to be derived from an operating system path (via PluggablePath), // to be derived from an operating system path (via PluggablePath),
// there's leeway for path-to-namespace conversions to be done here. // there's leeway for path-to-space conversions to be done here.
explicit PluggableSpace(const type::PluggableSpace& space) : m_space(space) explicit PluggableSpace(const type::PluggableSpace& space) : m_space(space)
{ {
parse(); parse();
@@ -491,12 +496,18 @@ class PluggableSpace
//! \return The pluggable's inner namespace //! \return The pluggable's inner namespace
const std::string& inner() const { return m_space.inner(); } const std::string& inner() const { return m_space.inner(); }
//! \return The pluggable's entrypoint class name
const std::string& entry() const { return m_space.entry(); }
//! \return true if the outer namespace was set //! \return true if the outer namespace was set
bool has_outer() const { return !m_space.outer().empty(); } bool has_outer() const { return !m_space.outer().empty(); }
//! \return true if the inner namespace was set //! \return true if the inner namespace was set
bool has_inner() const { return !m_space.inner().empty(); } bool has_inner() const { return !m_space.inner().empty(); }
//! \return true if the entrypoint class name was set
bool has_entry() const { return !m_space.entry().empty(); }
private: private:
type::PluggableSpace m_space; type::PluggableSpace m_space;
}; };
@@ -610,7 +621,8 @@ class Pluggable
// Execute pluggable's loader // Execute pluggable's loader
const std::string s{ const std::string s{
"dfi::" + m_plug.space().outer() + "::" + m_plug.space().inner()}; "dfi::" + m_plug.space().outer() + "::" + m_plug.space().inner()
+ "::" + m_plug.space().entry()};
::dfi::common::line(s + "::load(\"" + m_plug.args().load() + "\")"); ::dfi::common::line(s + "::load(\"" + m_plug.args().load() + "\")");
return *this; return *this;
@@ -624,7 +636,8 @@ class Pluggable
{ {
// Execute pluggable's unloader // Execute pluggable's unloader
const std::string s{ const std::string s{
"dfi::" + m_plug.space().outer() + "::" + m_plug.space().inner()}; "dfi::" + m_plug.space().outer() + "::" + m_plug.space().inner()
+ "::" + m_plug.space().entry()};
::dfi::common::line(s + "::unload(\"" + m_plug.args().unload() + "\")"); ::dfi::common::line(s + "::unload(\"" + m_plug.args().unload() + "\")");
// Unload pluggable file // Unload pluggable file