From 27707431936cbac19dc47b5642bc2a606a16e3ef Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 13 Feb 2025 14:17:27 +0100 Subject: [PATCH] Added new 'ca_userdef' callback --- CHANGELOG.md | 8 +++++ lib/clixon/clixon_plugin.h | 22 ++++++++++++ lib/src/clixon_plugin.c | 68 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 451e3d3c..0a6964a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Clixon Changelog +* [7.4.0](#730) Planned: April 2025 * [7.3.0](#730) 30 January 2025 * [7.2.0](#720) 28 October 2024 * [7.1.0](#710) 3 July 2024 @@ -12,6 +13,13 @@ * [6.1.0](#610) 19 Feb 2023 * [6.0.0](#600) 29 Nov 2022 +## 7.4.0 +Planned: April 2025 + +### Features + +* Added new `ca_userdef` callback + ## 7.3.0 30 January 2025 diff --git a/lib/clixon/clixon_plugin.h b/lib/clixon/clixon_plugin.h index efeabea1..cf7f6054 100644 --- a/lib/clixon/clixon_plugin.h +++ b/lib/clixon/clixon_plugin.h @@ -355,6 +355,24 @@ typedef int (errmsg_t)(clixon_handle h, const char *fn, const int line, */ typedef int (plgversion_t)(clixon_handle, FILE*); +/* For 7.3 compatibility */ +#define CLIXON_PLUGIN_USERDEF + +/*! Callback for generic user-defined semantics + * + * An application may define a user-defined callback which is called from _within_ + * an application callback. That is, not from within the Clixon base code. + * This means that the application needs to define semantics based on where and when the + * callback is called, and also the semantics of the arguments to the callback. + * @param[in] h Clixon handle + * @param[in] type User-defined type + * @param[in] x XML tree + * @param[in] arg User-defined argument + * @retval 0 OK + * @retval -1 Error + */ +typedef int (plguserdef_t)(clixon_handle, int type, cxobj *xn, void *arg); + /*! Startup status for use in startup-callback * * Note that for STARTUP_ERR and STARTUP_INVALID, running runs in failsafe mode @@ -386,6 +404,7 @@ struct clixon_plugin_api{ yang_patch_t *ca_yang_patch; /* Patch yang after parse */ errmsg_t *ca_errmsg; /* Customize log/error/debug callback */ plgversion_t *ca_version; /* Output a customized version message */ + plguserdef_t *ca_userdef; /* User-defined plugin */ union { struct { /* cli-specific */ cli_prompthook_t *ci_prompt; /* Prompt hook */ @@ -535,6 +554,9 @@ int clixon_plugin_errmsg_all(clixon_handle h, int clixon_plugin_version_one(clixon_plugin_t *cp, clixon_handle h, FILE *f); int clixon_plugin_version_all(clixon_handle h, FILE *f); +int clixon_plugin_userdef_one(clixon_plugin_t *cp, clixon_handle h, int type, cxobj *xn, void *arg); +int clixon_plugin_userdef_all(clixon_handle h, int type, cxobj* xn, void *arg); + /* rpc callback API */ int rpc_callback_register(clixon_handle h, clicon_rpc_cb cb, void *arg, const char *ns, const char *name); int rpc_callback_call(clixon_handle h, cxobj *xe, void *arg, int *nrp, cbuf *cbret); diff --git a/lib/src/clixon_plugin.c b/lib/src/clixon_plugin.c index bdefbba2..4b4b7535 100644 --- a/lib/src/clixon_plugin.c +++ b/lib/src/clixon_plugin.c @@ -1307,6 +1307,74 @@ clixon_plugin_version_all(clixon_handle h, return retval; } +/*! Call user-defined callback in one plugin + * + * @param[in] cp Plugin handle + * @param[in] h Clixon handle + * @param[in] type User-defined type + * @param[in] xn XML tree + * @param[in] arg User-defined argument + * @retval 0 OK + * @retval -1 Error + */ +int +clixon_plugin_userdef_one(clixon_plugin_t *cp, + clixon_handle h, + int type, + cxobj *xn, + void *arg) +{ + int retval = -1; + plguserdef_t *fn; + void *wh = NULL; + + if ((fn = cp->cp_api.ca_userdef) != NULL){ + wh = NULL; + if (clixon_resource_check(h, &wh, cp->cp_name, __FUNCTION__) < 0) + goto done; + if (fn(h, type, xn, arg) < 0) { + if (clixon_err_category() < 0) + clixon_log(h, LOG_WARNING, "%s: Internal error: userdef callback in plugin: %s returned -1 but did not make a clixon_err call", + __FUNCTION__, cp->cp_name); + clixon_resource_check(h, &wh, cp->cp_name, __FUNCTION__); + goto done; + } + if (clixon_resource_check(h, &wh, cp->cp_name, __FUNCTION__) < 0) + goto done; + } + retval = 0; + done: + return retval; +} + +/*! Call user-defined callbacks in all plugins + * + * @param[in] h Clixon handle + * @param[in] type User-defined type + * @param[in] xn XML tree + * @param[in] arg User-defined argument + * @retval 0 OK + * @retval -1 Error + */ +int +clixon_plugin_userdef_all(clixon_handle h, + int type, + cxobj *xn, + void *arg) +{ + int retval = -1; + clixon_plugin_t *cp = NULL; + + cp = NULL; + while ((cp = clixon_plugin_each(h, cp)) != NULL) { + if (clixon_plugin_userdef_one(cp, h, type, xn, arg) < 0) + goto done; + } + retval = 0; + done: + return retval; +} + /*-------------------------------------------------------------------- * RPC callbacks for both client/frontend and backend plugins. */