239 char *mvalue1, *mvalue2 =
NULL, *mtype_of_result;
247 ast_log(
LOG_WARNING,
"Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
254 ast_log(
LOG_WARNING,
"Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
258 mvalue1 =
args.argv0;
260 if (mvalue1[0] ==
'-') {
265 if ((op = strchr(mvalue1,
'*'))) {
268 }
else if ((op = strchr(mvalue1,
'/'))) {
271 }
else if ((op = strchr(mvalue1,
'%'))) {
274 }
else if ((op = strchr(mvalue1,
'^'))) {
277 }
else if ((op = strstr(mvalue1,
"AND"))) {
281 }
else if ((op = strstr(mvalue1,
"XOR"))) {
285 }
else if ((op = strstr(mvalue1,
"OR"))) {
289 }
else if ((op = strchr(mvalue1,
'>'))) {
292 if (*(op + 1) ==
'=') {
295 }
else if (*(op + 1) ==
'>') {
299 }
else if ((op = strchr(mvalue1,
'<'))) {
302 if (*(op + 1) ==
'=') {
305 }
else if (*(op + 1) ==
'<') {
309 }
else if ((op = strchr(mvalue1,
'='))) {
311 if (*(op + 1) ==
'=') {
316 }
else if ((op = strchr(mvalue1,
'+'))) {
319 }
else if ((op = strchr(mvalue1,
'-'))) {
328 mtype_of_result =
args.argv1;
329 if (mtype_of_result) {
330 if (!strcasecmp(mtype_of_result,
"float")
331 || !strcasecmp(mtype_of_result,
"f"))
333 else if (!strcasecmp(mtype_of_result,
"int")
334 || !strcasecmp(mtype_of_result,
"i"))
336 else if (!strcasecmp(mtype_of_result,
"hex")
337 || !strcasecmp(mtype_of_result,
"h"))
339 else if (!strcasecmp(mtype_of_result,
"char")
340 || !strcasecmp(mtype_of_result,
"c"))
351 "Supply all the parameters - just this once, please\n");
355 if (sscanf(mvalue1,
"%30lf", &fnum1) != 1) {
360 if (sscanf(mvalue2,
"%30lf", &fnum2) != 1) {
370 ftmp = fnum1 + fnum2;
376 ftmp = (fnum1 / fnum2);
379 ftmp = (fnum1 * fnum2);
382 ftmp = (fnum1 - fnum2);
392 ftmp = (inum1 % inum2);
398 ftmp = pow(fnum1, fnum2);
405 ftmp = (inum1 << inum2);
413 ftmp = (inum1 >> inum2);
420 ftmp = (inum1 & inum2);
427 ftmp = (inum1 ^ inum2);
434 ftmp = (inum1 | inum2);
454 "Something happened that neither of us should be proud of %d\n",
459 if (iaction < GTFUNCTION || iaction >
EQFUNCTION) {
461 snprintf(
buf,
len,
"%f", ftmp);
463 snprintf(
buf,
len,
"%i", (
int) ftmp);
465 snprintf(
buf,
len,
"%x", (
unsigned int) ftmp);
467 snprintf(
buf,
len,
"%c", (
unsigned char) ftmp);
474 char *data,
char *
buf,
size_t len)
480 char endchar = 0, returnvar[12];
501 ast_log(
LOG_NOTICE,
"Variable %s doesn't exist - are you sure you wrote it correctly?\n", data);
506 if (sscanf(
var,
"%30d%1c", &int_value, &endchar) == 0 || endchar != 0) {
507 ast_log(
LOG_NOTICE,
"The content of ${%s} is not a numeric value - bailing out!\n", data);
513 if (!strcasecmp(cmd,
"INC")) {
516 }
else if (!strcasecmp(cmd,
"DEC")) {
521 if (snprintf(returnvar,
sizeof(returnvar),
"%d", int_value) > 0) {
532 ast_log(
LOG_NOTICE,
"Variable %s refused to be %sREMENTED, setting value to 0", data, cmd);
542 char *parse,
char *buffer,
size_t buflen)
544 double num1, num2, response_num = 0;
559 }
else if (sscanf(
args.num1,
"%30lf", &num1) != 1) {
566 }
else if (sscanf(
args.num2,
"%30lf", &num2) != 1) {
571 if (response_num == -1) {
574 response_num = (num1 > num2) ? num2 : num1;
577 ast_debug(1,
"%f is the minimum of [%f,%f]\n", response_num, num1, num2);
578 if ((
int) response_num == response_num) {
579 snprintf(buffer, buflen,
"%d", (
int) response_num);
581 snprintf(buffer, buflen,
"%f", response_num);
588 char *parse,
char *buffer,
size_t buflen)
590 double num1, num2, response_num = 0;
605 }
else if (sscanf(
args.num1,
"%30lf", &num1) != 1) {
612 }
else if (sscanf(
args.num2,
"%30lf", &num2) != 1) {
617 if (response_num == -1) {
620 response_num = (num1 < num2) ? num2 : num1;
623 ast_debug(1,
"%f is the maximum of [%f,%f]\n", response_num, num1, num2);
624 if ((
int) response_num == response_num) {
625 snprintf(buffer, buflen,
"%d", (
int) response_num);
627 snprintf(buffer, buflen,
"%f", response_num);
634 char *parse,
char *buffer,
size_t buflen)
636 double num1, response_num;
648 response_num = fabs(num1);
649 ast_debug(1,
"%f is the absolute value of %f\n", response_num, num1);
650 if ((
int) response_num == response_num) {
651 snprintf(buffer, buflen,
"%d", (
int) response_num);
653 snprintf(buffer, buflen,
"%f", response_num);
660 char *parse,
char *buffer,
size_t buflen)
669 for (; *parse; parse++) {
670 if (*parse <
'0' || *parse >
'9') {
673 sum += (*parse -
'0');
676 snprintf(buffer, buflen,
"%d", sum);
726 info->name =
"test_MATH_function";
727 info->category =
"/main/pbx/";
728 info->summary =
"Test MATH function substitution";
730 "Executes a series of variable substitutions using the MATH function and ensures that the expected results are received.";
Asterisk main include file. File version handling, generic pbx functions.
General Asterisk PBX channel definitions.
#define ast_channel_lock(chan)
#define ast_channel_unlock(chan)
Conversion utility functions.
static int acf_abs_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
static struct ast_custom_function increment_function
static int math(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static int acf_digit_sum_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
static struct ast_custom_function math_function
static int acf_max_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
static struct ast_custom_function decrement_function
static struct ast_custom_function acf_min
static int acf_min_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
static struct ast_custom_function acf_abs
static int load_module(void)
static struct ast_custom_function acf_max
static int unload_module(void)
static struct ast_custom_function acf_digit_sum
static int crement_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
Configuration File Parser.
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
#define ast_custom_function_register(acf)
Register a custom function.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Main Channel structure associated with a channel.
Data structure associated with a custom dialplan function.
Support for dynamic strings.
#define AST_TEST_REGISTER(cb)
#define ast_test_status_update(a, b, c...)
#define AST_TEST_UNREGISTER(cb)
#define AST_TEST_DEFINE(hdr)