[syslog-ng] [PATCH] basicfuncs: Implement a few numeric template functions.
Gergely Nagy
algernon at balabit.hu
Tue May 3 22:19:40 CEST 2011
Implement addition, substraction, multiplication, division and modulus
template functions: $(+ N M), $(- N M), $(* N M), $(/ N M) and $(% N
M), respectively.
All of them take two numeric arguments, and log an error, if they
receive less or more, or in case the number cannot be fully parsed as
a number.
Signed-off-by: Gergely Nagy <algernon at balabit.hu>
---
modules/basicfuncs/basic-funcs.c | 120 +++++++++++++++++++++++++++++++++++++-
tests/unit/test_template.c | 9 +++
2 files changed, 126 insertions(+), 3 deletions(-)
diff --git a/modules/basicfuncs/basic-funcs.c b/modules/basicfuncs/basic-funcs.c
index a03e221..2cc1442 100644
--- a/modules/basicfuncs/basic-funcs.c
+++ b/modules/basicfuncs/basic-funcs.c
@@ -23,7 +23,7 @@ tf_echo(LogMessage *msg, gint argc, GString *argv[], GString *result)
TEMPLATE_FUNCTION_SIMPLE(tf_echo);
static gboolean
-tf_substr_parse_int(const gchar *s, long *d)
+tf_parse_int(const gchar *s, long *d)
{
gchar *endptr;
glong val;
@@ -42,6 +42,115 @@ tf_substr_parse_int(const gchar *s, long *d)
return TRUE;
}
+static gboolean
+tf_num_parse(gint argc, GString *argv[],
+ const gchar *func_name, glong *n, glong *m)
+{
+ if (argc != 2)
+ {
+ msg_error("Template function requires two arguments.",
+ evt_tag_str("function", func_name), NULL);
+ return FALSE;
+ }
+
+ if (!tf_parse_int(argv[0]->str, n))
+ {
+ msg_error("Parsing failed, template function's first argument is not a number",
+ evt_tag_str("function", func_name),
+ evt_tag_str("arg1", argv[0]->str), NULL);
+ return FALSE;
+ }
+
+ if (!tf_parse_int(argv[1]->str, m))
+ {
+ msg_error("Parsing failed, template function's first argument is not a number",
+ evt_tag_str("function", func_name),
+ evt_tag_str("arg1", argv[1]->str), NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+tf_num_plus(LogMessage *msg, gint argc, GString *argv[], GString *result)
+{
+ glong n, m;
+
+ if (!tf_num_parse(argc, argv, "+", &n, &m))
+ return;
+
+ g_string_append_printf(result, "%li", n + m);
+}
+
+TEMPLATE_FUNCTION_SIMPLE(tf_num_plus);
+
+static void
+tf_num_minus(LogMessage *msg, gint argc, GString *argv[], GString *result)
+{
+ glong n, m;
+
+ if (!tf_num_parse(argc, argv, "-", &n, &m))
+ return;
+
+ g_string_append_printf(result, "%li", n - m);
+}
+
+TEMPLATE_FUNCTION_SIMPLE(tf_num_minus);
+
+static void
+tf_num_multi(LogMessage *msg, gint argc, GString *argv[], GString *result)
+{
+ glong n, m;
+
+ if (!tf_num_parse(argc, argv, "*", &n, &m))
+ return;
+
+ g_string_append_printf(result, "%li", n * m);
+}
+
+TEMPLATE_FUNCTION_SIMPLE(tf_num_multi);
+
+static void
+tf_num_div(LogMessage *msg, gint argc, GString *argv[], GString *result)
+{
+ glong n, m;
+
+ if (!tf_num_parse(argc, argv, "/", &n, &m))
+ return;
+
+ if (m == 0)
+ {
+ msg_error ("$(/): Division by zero in the template function",
+ NULL);
+ return;
+ }
+
+ g_string_append_printf(result, "%li", (glong)(n / m));
+}
+
+TEMPLATE_FUNCTION_SIMPLE(tf_num_div);
+
+static void
+tf_num_mod(LogMessage *msg, gint argc, GString *argv[], GString *result)
+{
+ glong n, m;
+
+ if (!tf_num_parse(argc, argv, "%", &n, &m))
+ return;
+
+ if (m == 0)
+ {
+ msg_error ("$(%): Division by zero in the template function",
+ NULL);
+ return;
+ }
+
+ g_string_append_printf(result, "%li", n % m);
+}
+
+TEMPLATE_FUNCTION_SIMPLE(tf_num_mod);
+
static void
tf_substr(LogMessage *msg, gint argc, GString *argv[], GString *result)
{
@@ -64,14 +173,14 @@ tf_substr(LogMessage *msg, gint argc, GString *argv[], GString *result)
return;
/* get offset position from second argument */
- if (!tf_substr_parse_int(argv[1]->str, &start)) {
+ if (!tf_parse_int(argv[1]->str, &start)) {
msg_error("$(substr) parsing failed, start could not be parsed", evt_tag_str("start", argv[1]->str), NULL);
return;
}
/* if we were called with >2 arguments, third was desired length */
if (argc > 2) {
- if (!tf_substr_parse_int(argv[2]->str, &len)) {
+ if (!tf_parse_int(argv[2]->str, &len)) {
msg_error("$(substr) parsing failed, length could not be parsed", evt_tag_str("length", argv[2]->str), NULL);
return;
}
@@ -282,6 +391,11 @@ static Plugin basicfuncs_plugins[] =
TEMPLATE_FUNCTION_PLUGIN(tf_grep, "grep"),
TEMPLATE_FUNCTION_PLUGIN(tf_if, "if"),
TEMPLATE_FUNCTION_PLUGIN(tf_substr, "substr"),
+ TEMPLATE_FUNCTION_PLUGIN(tf_num_plus, "+"),
+ TEMPLATE_FUNCTION_PLUGIN(tf_num_minus, "-"),
+ TEMPLATE_FUNCTION_PLUGIN(tf_num_multi, "*"),
+ TEMPLATE_FUNCTION_PLUGIN(tf_num_div, "/"),
+ TEMPLATE_FUNCTION_PLUGIN(tf_num_mod, "%"),
};
gboolean
diff --git a/tests/unit/test_template.c b/tests/unit/test_template.c
index fca0076..aabc3db 100644
--- a/tests/unit/test_template.c
+++ b/tests/unit/test_template.c
@@ -246,6 +246,15 @@ main(int argc G_GNUC_UNUSED, char *argv[] G_GNUC_UNUSED)
testcase(msg, "$(substr $HOST -1)", "p");
testcase(msg, "$(substr $HOST -2 1)", "r");
+ testcase(msg, "$(+ $FACILITY_NUM 1)", "20");
+ testcase(msg, "$(- $FACILITY_NUM 1)", "18");
+ testcase(msg, "$(* $FACILITY_NUM 2)", "38");
+ testcase(msg, "$(/ $FACILITY_NUM 2)", "9");
+ testcase(msg, "$(% $FACILITY_NUM 3)", "1");
+ testcase(msg, "$(/ $FACILITY_NUM 0)", "");
+ testcase(msg, "$(% $FACILITY_NUM 0)", "");
+ testcase(msg, "$(+ foo bar)", "");
+
/* message refs */
testcase(msg, "$(echo ${HOST}@0 ${PID}@1)", "bzorp 23323");
testcase(msg, "$(echo $HOST $PID)@0", "bzorp 23323");
--
1.7.2.5
More information about the syslog-ng
mailing list