[Asterisk-code-review] func_math: Three new dialplan functions (asterisk[18])

Friendly Automation asteriskteam at digium.com
Wed May 26 13:48:08 CDT 2021


Friendly Automation has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/15905 )

Change subject: func_math: Three new dialplan functions
......................................................................

func_math: Three new dialplan functions

Introduces three new dialplan functions, MIN and MAX,
which can be used to calculate the minimum or
maximum of up to two numbers, and ABS, an absolute
value function.

ASTERISK-29431

Change-Id: I2bda9269d18f9d54833c85e48e41fce0e0ce4d8d
---
A doc/CHANGES-staging/func_min_max.txt
M funcs/func_math.c
2 files changed, 177 insertions(+), 0 deletions(-)

Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  Benjamin Keith Ford: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, but someone else must approve
  Friendly Automation: Approved for Submit



diff --git a/doc/CHANGES-staging/func_min_max.txt b/doc/CHANGES-staging/func_min_max.txt
new file mode 100644
index 0000000..df2b665
--- /dev/null
+++ b/doc/CHANGES-staging/func_min_max.txt
@@ -0,0 +1,4 @@
+Subject: func_math: Three new dialplan functions
+
+Introduce three new functions, MIN, MAX, and ABS, which can be used to
+obtain the minimum or maximum of up to two integers or absolute value.
diff --git a/funcs/func_math.c b/funcs/func_math.c
index 6fc7255..b8a6eb6 100644
--- a/funcs/func_math.c
+++ b/funcs/func_math.c
@@ -5,6 +5,7 @@
  *
  * Updated by Mark Spencer <markster at digium.com>
  * Updated by Nir Simionovich <nirs at greenfieldtech.net>
+ * Updated by Naveen Albert <asterisk at phreaknet.org>
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -24,6 +25,7 @@
  * \author Andy Powell
  * \author Mark Spencer <markster at digium.com>
  * \author Nir Simionovich <nirs at greenfieldtech.net>
+ * \author Naveen Albert <asterisk at phreaknet.org>
  *
  * \ingroup functions
  */
@@ -40,6 +42,7 @@
 #include "asterisk/channel.h"
 #include "asterisk/pbx.h"
 #include "asterisk/utils.h"
+#include "asterisk/conversions.h"
 #include "asterisk/app.h"
 #include "asterisk/config.h"
 #include "asterisk/test.h"
@@ -105,6 +108,47 @@
 			<para>Note: DEC(${MyVAR}) - Is wrong, as DEC expects the variable name, not its value</para>
 		</description>
 	</function>
+	<function name="MIN" language="en_US">
+		<synopsis>
+			Returns the minimum of two numbers.
+		</synopsis>
+		<syntax>
+			<parameter name="num1" />
+			<parameter name="num2" />
+		</syntax>
+		<description>
+			<para>Returns the minimum of two numbers <replaceable>num1</replaceable> and <replaceable>num2</replaceable>.</para>
+			<para>Example:  Set(min=${MIN(7,4)});
+			Sets the min variable equal to 4.</para>
+		</description>
+	</function>
+	<function name="MAX" language="en_US">
+		<synopsis>
+			Returns the maximum of two numbers.
+		</synopsis>
+		<syntax>
+			<parameter name="num1" />
+			<parameter name="num2" />
+		</syntax>
+		<description>
+			<para>Returns the maximum of two numbers <replaceable>num1</replaceable> and <replaceable>num2</replaceable>.</para>
+			<para>Example:  Set(max=${MAX(4,7)});
+			Sets the max variable equal to 7.</para>
+		</description>
+	</function>
+	<function name="ABS" language="en_US">
+		<synopsis>
+			Returns absolute value of a number.
+		</synopsis>
+		<syntax>
+			<parameter name="num" />
+		</syntax>
+		<description>
+			<para>Returns the absolute value of a number <replaceable>num</replaceable>.</para>
+			<para>Example:  Set(absval=${ABS(-13)});
+			Sets the absval variable equal to 13.</para>
+		</description>
+	</function>
  ***/
 
 enum TypeOfFunctions {
@@ -444,6 +488,111 @@
 	return ret;
 }
 
+static int acf_min_exec(struct ast_channel *chan, const char *cmd,
+			 char *parse, char *buffer, size_t buflen)
+{
+	double num1, num2, response_num = 0;
+	AST_DECLARE_APP_ARGS(args,
+			     AST_APP_ARG(num1);
+			     AST_APP_ARG(num2);
+	);
+
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (ast_strlen_zero(args.num1) && ast_strlen_zero(args.num2)) {
+		ast_log(LOG_ERROR, "Missing argument for number(s).");
+		return -1;
+	}
+
+	if (ast_strlen_zero(args.num1)) {
+		response_num = -1; /* couldn't read num1 successfully */
+	} else if (sscanf(args.num1, "%30lf", &num1) != 1) {
+		ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num1);
+		return -1;
+	}
+
+	if (ast_strlen_zero(args.num2)) {
+		num2 = num1; /* num1 must be a valid integer here */
+	} else if (sscanf(args.num2, "%30lf", &num2) != 1) {
+		ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num2);
+		return -1;
+	}
+
+	if (response_num == -1) { /* could only read num2 */
+		response_num = num2;
+	} else {
+		response_num = (num1 > num2) ? num2 : num1;
+	}
+
+	ast_debug(1, "%f is the minimum of [%f,%f]\n", response_num, num1, num2);
+	snprintf(buffer, buflen, "%f", response_num);
+
+	return 0;
+}
+
+static int acf_max_exec(struct ast_channel *chan, const char *cmd,
+			 char *parse, char *buffer, size_t buflen)
+{
+	double num1, num2, response_num = 0;
+	AST_DECLARE_APP_ARGS(args,
+			     AST_APP_ARG(num1);
+			     AST_APP_ARG(num2);
+	);
+
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (ast_strlen_zero(args.num1) && ast_strlen_zero(args.num2)) {
+		ast_log(LOG_ERROR, "Missing argument for number(s).");
+		return -1;
+	}
+
+	if (ast_strlen_zero(args.num1)) {
+		response_num = -1; /* couldn't read num1 successfully */
+	} else if (sscanf(args.num1, "%30lf", &num1) != 1) {
+		ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num1);
+		return -1;
+	}
+
+	if (ast_strlen_zero(args.num2)) {
+		num2 = num1; /* num1 must be a valid integer here */
+	} else if (sscanf(args.num2, "%30lf", &num2) != 1) {
+		ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num2);
+		return -1;
+	}
+
+	if (response_num == -1) { /* could only read num2 */
+		response_num = num2;
+	} else {
+		response_num = (num1 < num2) ? num2 : num1;
+	}
+
+	ast_debug(1, "%f is the maximum of [%f,%f]\n", response_num, num1, num2);
+	snprintf(buffer, buflen, "%f", response_num);
+
+	return 0;
+}
+
+static int acf_abs_exec(struct ast_channel *chan, const char *cmd,
+			 char *parse, char *buffer, size_t buflen)
+{
+	double num1, response_num;
+	AST_DECLARE_APP_ARGS(args,
+			     AST_APP_ARG(num1);
+	);
+
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (ast_strlen_zero(args.num1) || sscanf(args.num1, "%30lf", &num1) != 1) {
+		ast_log(LOG_WARNING, "Bad or missing argument for number: %s", args.num1);
+		return -1;
+	}
+
+	response_num = fabs(num1);
+	ast_debug(1, "%f is the absolute value of %f\n", response_num, num1);
+	snprintf(buffer, buflen, "%f", response_num);
+
+	return 0;
+}
 
 static struct ast_custom_function math_function = {
 	.name = "MATH",
@@ -460,6 +609,24 @@
 	.read = crement_function_read,
 };
 
+static struct ast_custom_function acf_min = {
+	.name = "MIN",
+	.read = acf_min_exec,
+	.read_max = 12,
+};
+
+static struct ast_custom_function acf_max = {
+	.name = "MAX",
+	.read = acf_max_exec,
+	.read_max = 12,
+};
+
+static struct ast_custom_function acf_abs = {
+	.name = "ABS",
+	.read = acf_abs_exec,
+	.read_max = 12,
+};
+
 #ifdef TEST_FRAMEWORK
 AST_TEST_DEFINE(test_MATH_function)
 {
@@ -518,6 +685,9 @@
 	res |= ast_custom_function_unregister(&math_function);
 	res |= ast_custom_function_unregister(&increment_function);
 	res |= ast_custom_function_unregister(&decrement_function);
+	res |= ast_custom_function_unregister(&acf_min);
+	res |= ast_custom_function_unregister(&acf_max);
+	res |= ast_custom_function_unregister(&acf_abs);
 	AST_TEST_UNREGISTER(test_MATH_function);
 
 	return res;
@@ -530,6 +700,9 @@
 	res |= ast_custom_function_register(&math_function);
 	res |= ast_custom_function_register(&increment_function);
 	res |= ast_custom_function_register(&decrement_function);
+	res |= ast_custom_function_register(&acf_min);
+	res |= ast_custom_function_register(&acf_max);
+	res |= ast_custom_function_register(&acf_abs);
 	AST_TEST_REGISTER(test_MATH_function);
 
 	return res;

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/15905
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 18
Gerrit-Change-Id: I2bda9269d18f9d54833c85e48e41fce0e0ce4d8d
Gerrit-Change-Number: 15905
Gerrit-PatchSet: 10
Gerrit-Owner: N A <mail at interlinked.x10host.com>
Gerrit-Reviewer: Benjamin Keith Ford <bford at digium.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at sangoma.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210526/e46cd940/attachment-0001.html>


More information about the asterisk-code-review mailing list