commit 9ea3d1a: [Rework] Final efforts to make it compileable

Vsevolod Stakhov vsevolod at rspamd.com
Thu Aug 17 11:49:13 UTC 2023


Author: Vsevolod Stakhov
Date: 2023-08-16 14:57:26 +0100
URL: https://github.com/rspamd/rspamd/commit/9ea3d1aa7c44ded48e8f9db0b2e4219429b03bac

[Rework] Final efforts to make it compileable

---
 contrib/libucl/lua_ucl.h    |  44 ++++++++++++----
 src/libserver/cfg_file.h    |   6 +--
 src/libserver/cfg_rcl.cxx   |  39 ++++++++------
 src/libserver/cfg_utils.cxx |   7 +--
 src/libserver/protocol.c    | 123 ++++++++++++++++++++++----------------------
 src/lua/lua_util.c          |   4 +-
 src/rspamadm/confighelp.c   |   2 +-
 7 files changed, 130 insertions(+), 95 deletions(-)

diff --git a/contrib/libucl/lua_ucl.h b/contrib/libucl/lua_ucl.h
index 5b7f88e03..4a759e3b4 100644
--- a/contrib/libucl/lua_ucl.h
+++ b/contrib/libucl/lua_ucl.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2023 Vsevolod Stakhov
+ *
+ * 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.
+ */
+
 /* Copyright (c) 2014, Vsevolod Stakhov
  * All rights reserved.
  *
@@ -26,11 +42,16 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
+#include "ucl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+/* Include C++ guard as Lua headers miss one */
 #include <lua.h>
 #include <lauxlib.h>
 #include <lualib.h>
-#include "ucl.h"
 
 /**
  * Closure structure for lua function storing inside UCL
@@ -44,7 +65,7 @@ struct ucl_lua_funcdata {
 /**
  * Initialize lua UCL API
  */
-UCL_EXTERN int luaopen_ucl (lua_State *L);
+UCL_EXTERN int luaopen_ucl(lua_State *L);
 
 /**
  * Import UCL object from lua state
@@ -52,7 +73,7 @@ UCL_EXTERN int luaopen_ucl (lua_State *L);
  * @param idx index of object at the lua stack to convert to UCL
  * @return new UCL object or NULL, the caller should unref object after using
  */
-UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx);
+UCL_EXTERN ucl_object_t *ucl_object_lua_import(lua_State *L, int idx);
 
 /**
  * Import UCL object from lua state, escaping JSON strings
@@ -60,7 +81,7 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx);
  * @param idx index of object at the lua stack to convert to UCL
  * @return new UCL object or NULL, the caller should unref object after using
  */
-UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx);
+UCL_EXTERN ucl_object_t *ucl_object_lua_import_escape(lua_State *L, int idx);
 
 /**
  * Push an object to lua
@@ -68,18 +89,21 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx);
  * @param obj object to push
  * @param allow_array traverse over implicit arrays
  */
-UCL_EXTERN int ucl_object_push_lua (lua_State *L,
-		const ucl_object_t *obj, bool allow_array);
+UCL_EXTERN int ucl_object_push_lua(lua_State *L,
+								   const ucl_object_t *obj, bool allow_array);
 /**
  * Push an object to lua replacing all ucl.null with `false`
  * @param L lua state
  * @param obj object to push
  * @param allow_array traverse over implicit arrays
  */
-UCL_EXTERN int ucl_object_push_lua_filter_nil (lua_State *L,
-											   const ucl_object_t *obj,
-											   bool allow_array);
+UCL_EXTERN int ucl_object_push_lua_filter_nil(lua_State *L,
+											  const ucl_object_t *obj,
+											  bool allow_array);
 
-UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure (const ucl_object_t *obj);
+UCL_EXTERN struct ucl_lua_funcdata *ucl_object_toclosure(const ucl_object_t *obj);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
 
 #endif /* LUA_UCL_H_ */
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 0d85e5f5e..3f876ab23 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -856,9 +856,9 @@ gboolean rspamd_config_libs(struct rspamd_external_libs_ctx *ctx,
 														cfg->cfg_pool->tag.tagname, cfg->checksum, \
 														RSPAMD_LOG_FUNC,                           \
 														__VA_ARGS__)
-#define msg_err_config_forced(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL | RSPAMD_LOG_FORCED,  \
-															   cfg->cfg_pool->tag.tagname, cfg->checksum, \
-															   RSPAMD_LOG_FUNC,                           \
+#define msg_err_config_forced(...) rspamd_default_log_function((gint) G_LOG_LEVEL_CRITICAL | (gint) RSPAMD_LOG_FORCED, \
+															   cfg->cfg_pool->tag.tagname, cfg->checksum,              \
+															   RSPAMD_LOG_FUNC,                                        \
 															   __VA_ARGS__)
 #define msg_warn_config(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING,                       \
 														 cfg->cfg_pool->tag.tagname, cfg->checksum, \
diff --git a/src/libserver/cfg_rcl.cxx b/src/libserver/cfg_rcl.cxx
index 5234e4fa3..1ca9e5b69 100644
--- a/src/libserver/cfg_rcl.cxx
+++ b/src/libserver/cfg_rcl.cxx
@@ -13,12 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#include "lua/lua_common.h"
 #include "cfg_rcl.h"
 #include "rspamd.h"
 #include "cfg_file_private.h"
 #include "utlist.h"
 #include "cfg_file.h"
-#include "lua/lua_common.h"
 #include "expression.h"
 #include "src/libserver/composites/composites.h"
 #include "libserver/worker_util.h"
@@ -31,7 +32,6 @@
 #include <string>
 #include <filesystem>
 #include <memory>
-#include <algorithm>
 #include "contrib/ankerl/unordered_dense.h"
 #include "fmt/core.h"
 #include "libutil/cxx/util.hxx"
@@ -52,20 +52,20 @@ struct rspamd_rcl_default_handler_data {
 struct rspamd_rcl_sections_map;
 
 struct rspamd_rcl_section {
-	struct rspamd_rcl_sections_map *top;
+	struct rspamd_rcl_sections_map *top{};
 	std::string name; /**< name of section */
 	std::optional<std::string> key_attr;
 	std::optional<std::string> default_key;
-	rspamd_rcl_handler_t handler; /**< handler of section attributes */
-	enum ucl_type type;           /**< type of attribute */
-	bool required;                /**< whether this param is required */
-	bool strict_type;             /**< whether we need strict type */
-	mutable bool processed;       /**< whether this section was processed */
+	rspamd_rcl_handler_t handler{}; /**< handler of section attributes */
+	enum ucl_type type;             /**< type of attribute */
+	bool required{};                /**< whether this param is required */
+	bool strict_type{};             /**< whether we need strict type */
+	mutable bool processed{};       /**< whether this section was processed */
 	ankerl::unordered_dense::map<std::string, std::shared_ptr<struct rspamd_rcl_section>> subsections;
 	ankerl::unordered_dense::map<std::string, struct rspamd_rcl_default_handler_data> default_parser; /**< generic parsing fields */
-	rspamd_rcl_section_fin_t fin;                                                                     /** called at the end of section parsing */
-	gpointer fin_ud;
-	ucl_object_t *doc_ref; /**< reference to the section's documentation */
+	rspamd_rcl_section_fin_t fin{};                                                                   /** called at the end of section parsing */
+	gpointer fin_ud{};
+	ucl_object_t *doc_ref{}; /**< reference to the section's documentation */
 };
 
 struct rspamd_worker_param_parser {
@@ -74,10 +74,19 @@ struct rspamd_worker_param_parser {
 };
 
 struct rspamd_worker_cfg_parser {
-	ankerl::unordered_dense::map<std::pair<std::string, gpointer>, rspamd_worker_param_parser> parsers; /**< parsers hash										*/
-	gint type;                                                                                          /**< workers quark										*/
-	gboolean (*def_obj_parser)(ucl_object_t *obj, gpointer ud);                                         /**<
- 														 default object parser								*/
+	struct pair_hash {
+		using is_avalanching = void;
+		template<class T1, class T2>
+		std::size_t operator()(const std::pair<T1, T2> &pair) const
+		{
+			return ankerl::unordered_dense::hash<T1>()(pair.first) ^ ankerl::unordered_dense::hash<T2>()(pair.second);
+		}
+	};
+	ankerl::unordered_dense::map<std::pair<std::string, gpointer>,
+								 rspamd_worker_param_parser, pair_hash>
+		parsers;                                                /**< parsers hash										*/
+	gint type;                                                  /**< workers quark										*/
+	gboolean (*def_obj_parser)(ucl_object_t *obj, gpointer ud); /**< default object parser								*/
 	gpointer def_ud;
 };
 
diff --git a/src/libserver/cfg_utils.cxx b/src/libserver/cfg_utils.cxx
index 2c820bfa4..a088559f1 100644
--- a/src/libserver/cfg_utils.cxx
+++ b/src/libserver/cfg_utils.cxx
@@ -15,12 +15,13 @@
  */
 #include "config.h"
 
+#include "lua/lua_common.h"
+#include "lua/lua_thread_pool.h"
+
 #include "cfg_file.h"
 #include "rspamd.h"
 #include "cfg_file_private.h"
-#include "scan_result.h"
-#include "lua/lua_common.h"
-#include "lua/lua_thread_pool.h"
+
 #include "maps/map.h"
 #include "maps/map_helpers.h"
 #include "maps/map_private.h"
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c
index c8e3fe441..867455754 100644
--- a/src/libserver/protocol.c
+++ b/src/libserver/protocol.c
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2016 Vsevolod Stakhov
+/*
+ * Copyright 2023 Vsevolod Stakhov
  *
  * 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
+ *    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,
@@ -793,65 +793,66 @@ rspamd_protocol_parse_task_flags(rspamd_mempool_t *pool,
 	return TRUE;
 }
 
-static struct rspamd_rcl_section *control_parser = NULL;
+static struct rspamd_rcl_sections_map *control_parser = NULL;
 
-static void
-rspamd_protocol_control_parser_init(void)
+RSPAMD_CONSTRUCTOR(rspamd_protocol_control_parser_ctor)
 {
-	struct rspamd_rcl_section *sub;
-
-	if (control_parser == NULL) {
-		sub = rspamd_rcl_add_section(&control_parser,
-									 "*",
-									 NULL,
-									 NULL,
-									 UCL_OBJECT,
-									 FALSE,
-									 TRUE);
-		/* Default handlers */
-		rspamd_rcl_add_default_handler(sub,
-									   "ip",
-									   rspamd_rcl_parse_struct_addr,
-									   G_STRUCT_OFFSET(struct rspamd_task, from_addr),
-									   0,
-									   NULL);
-		rspamd_rcl_add_default_handler(sub,
-									   "from",
-									   rspamd_rcl_parse_struct_mime_addr,
-									   G_STRUCT_OFFSET(struct rspamd_task, from_envelope),
-									   0,
-									   NULL);
-		rspamd_rcl_add_default_handler(sub,
-									   "rcpt",
-									   rspamd_rcl_parse_struct_mime_addr,
-									   G_STRUCT_OFFSET(struct rspamd_task, rcpt_envelope),
-									   0,
-									   NULL);
-		rspamd_rcl_add_default_handler(sub,
-									   "helo",
-									   rspamd_rcl_parse_struct_string,
-									   G_STRUCT_OFFSET(struct rspamd_task, helo),
-									   0,
-									   NULL);
-		rspamd_rcl_add_default_handler(sub,
-									   "user",
-									   rspamd_rcl_parse_struct_string,
-									   G_STRUCT_OFFSET(struct rspamd_task, auth_user),
-									   0,
-									   NULL);
-		rspamd_rcl_add_default_handler(sub,
-									   "pass_all",
-									   rspamd_protocol_parse_task_flags,
-									   G_STRUCT_OFFSET(struct rspamd_task, flags),
-									   0,
-									   NULL);
-		rspamd_rcl_add_default_handler(sub,
-									   "json",
-									   rspamd_protocol_parse_task_flags,
-									   G_STRUCT_OFFSET(struct rspamd_task, flags),
-									   0,
-									   NULL);
-	}
+
+	struct rspamd_rcl_section *sub = rspamd_rcl_add_section(&control_parser, NULL,
+															"*",
+															NULL,
+															NULL,
+															UCL_OBJECT,
+															FALSE,
+															TRUE);
+	/* Default handlers */
+	rspamd_rcl_add_default_handler(sub,
+								   "ip",
+								   rspamd_rcl_parse_struct_addr,
+								   G_STRUCT_OFFSET(struct rspamd_task, from_addr),
+								   0,
+								   NULL);
+	rspamd_rcl_add_default_handler(sub,
+								   "from",
+								   rspamd_rcl_parse_struct_mime_addr,
+								   G_STRUCT_OFFSET(struct rspamd_task, from_envelope),
+								   0,
+								   NULL);
+	rspamd_rcl_add_default_handler(sub,
+								   "rcpt",
+								   rspamd_rcl_parse_struct_mime_addr,
+								   G_STRUCT_OFFSET(struct rspamd_task, rcpt_envelope),
+								   0,
+								   NULL);
+	rspamd_rcl_add_default_handler(sub,
+								   "helo",
+								   rspamd_rcl_parse_struct_string,
+								   G_STRUCT_OFFSET(struct rspamd_task, helo),
+								   0,
+								   NULL);
+	rspamd_rcl_add_default_handler(sub,
+								   "user",
+								   rspamd_rcl_parse_struct_string,
+								   G_STRUCT_OFFSET(struct rspamd_task, auth_user),
+								   0,
+								   NULL);
+	rspamd_rcl_add_default_handler(sub,
+								   "pass_all",
+								   rspamd_protocol_parse_task_flags,
+								   G_STRUCT_OFFSET(struct rspamd_task, flags),
+								   0,
+								   NULL);
+	rspamd_rcl_add_default_handler(sub,
+								   "json",
+								   rspamd_protocol_parse_task_flags,
+								   G_STRUCT_OFFSET(struct rspamd_task, flags),
+								   0,
+								   NULL);
+}
+
+RSPAMD_DESTRUCTOR(rspamd_protocol_control_parser_dtor)
+{
+	rspamd_rcl_sections_free(control_parser);
 }
 
 gboolean
@@ -860,8 +861,6 @@ rspamd_protocol_handle_control(struct rspamd_task *task,
 {
 	GError *err = NULL;
 
-	rspamd_protocol_control_parser_init();
-
 	if (!rspamd_rcl_parse(control_parser, task->cfg, task, task->task_pool,
 						  control, &err)) {
 		msg_warn_protocol("cannot parse control block: %e", err);
diff --git a/src/lua/lua_util.c b/src/lua/lua_util.c
index 550e0a9ee..40f6f6c48 100644
--- a/src/lua/lua_util.c
+++ b/src/lua/lua_util.c
@@ -858,7 +858,7 @@ lua_util_config_from_ucl(lua_State *L)
 {
 	LUA_TRACE_POINT;
 	struct rspamd_config *cfg = NULL, **pcfg;
-	struct rspamd_rcl_section *top;
+	struct rspamd_rcl_sections_map *top;
 	GError *err = NULL;
 	ucl_object_t *obj;
 	const char *str_options = NULL;
@@ -901,6 +901,8 @@ lua_util_config_from_ucl(lua_State *L)
 			rspamd_lua_setclass(L, "rspamd{config}", -1);
 			*pcfg = cfg;
 		}
+
+		rspamd_rcl_sections_free(top);
 	}
 
 	return 1;
diff --git a/src/rspamadm/confighelp.c b/src/rspamadm/confighelp.c
index 4c035ac94..2ad07c0a6 100644
--- a/src/rspamadm/confighelp.c
+++ b/src/rspamadm/confighelp.c
@@ -233,7 +233,7 @@ rspamadm_confighelp(gint argc, gchar **argv, const struct rspamadm_command *cmd)
 	rspamd_rcl_config_init(cfg, NULL);
 	lua_pushboolean(cfg->lua_state, true);
 	lua_setglobal(cfg->lua_state, "confighelp");
-	rspamd_rcl_add_lua_plugins_path(cfg, plugins_path, FALSE, NULL, NULL);
+	rspamd_rcl_add_lua_plugins_path(cfg->rcl_top_section, cfg, plugins_path, FALSE, NULL);
 
 	/* Init modules to get documentation strings */
 	i = 0;


More information about the Commits mailing list