Asterisk - The Open Source Telephony Project  18.5.0
Enumerations | Functions | Variables
func_math.c File Reference

Math related dialplan function. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/module.h"
#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"
Include dependency graph for func_math.c:

Go to the source code of this file.

Enumerations

enum  TypeOfFunctions {
  ADDFUNCTION, DIVIDEFUNCTION, MULTIPLYFUNCTION, SUBTRACTFUNCTION,
  MODULUSFUNCTION, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION,
  BITWISEANDFUNCTION, BITWISEXORFUNCTION, BITWISEORFUNCTION, GTFUNCTION,
  LTFUNCTION, GTEFUNCTION, LTEFUNCTION, EQFUNCTION
}
 
enum  TypeOfResult { FLOAT_RESULT, INT_RESULT, HEX_RESULT, CHAR_RESULT }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int acf_abs_exec (struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
 
static int acf_max_exec (struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
 
static int acf_min_exec (struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_MATH_function)
 
static int crement_function_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int load_module (void)
 
static int math (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Mathematical dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static struct ast_custom_function acf_abs
 
static struct ast_custom_function acf_max
 
static struct ast_custom_function acf_min
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_custom_function decrement_function
 
static struct ast_custom_function increment_function
 
static struct ast_custom_function math_function
 

Detailed Description

Math related dialplan function.

Author
Andy Powell
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Nir Simionovich nirs@.nosp@m.gree.nosp@m.nfiel.nosp@m.dtec.nosp@m.h.net
Naveen Albert aster.nosp@m.isk@.nosp@m.phrea.nosp@m.knet.nosp@m..org

Definition in file func_math.c.

Enumeration Type Documentation

◆ TypeOfFunctions

Enumerator
ADDFUNCTION 
DIVIDEFUNCTION 
MULTIPLYFUNCTION 
SUBTRACTFUNCTION 
MODULUSFUNCTION 
POWFUNCTION 
SHLEFTFUNCTION 
SHRIGHTFUNCTION 
BITWISEANDFUNCTION 
BITWISEXORFUNCTION 
BITWISEORFUNCTION 
GTFUNCTION 
LTFUNCTION 
GTEFUNCTION 
LTEFUNCTION 
EQFUNCTION 

Definition at line 154 of file func_math.c.

◆ TypeOfResult

Enumerator
FLOAT_RESULT 
INT_RESULT 
HEX_RESULT 
CHAR_RESULT 

Definition at line 173 of file func_math.c.

173  {
174  FLOAT_RESULT,
175  INT_RESULT,
176  HEX_RESULT,
178 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 723 of file func_math.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 723 of file func_math.c.

◆ acf_abs_exec()

static int acf_abs_exec ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buffer,
size_t  buflen 
)
static

Definition at line 583 of file func_math.c.

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero, and LOG_WARNING.

585 {
586  double num1, response_num;
588  AST_APP_ARG(num1);
589  );
590 
592 
593  if (ast_strlen_zero(args.num1) || sscanf(args.num1, "%30lf", &num1) != 1) {
594  ast_log(LOG_WARNING, "Bad or missing argument for number: %s", args.num1);
595  return -1;
596  }
597 
598  response_num = fabs(num1);
599  ast_debug(1, "%f is the absolute value of %f\n", response_num, num1);
600  if ((int) response_num == response_num) {
601  snprintf(buffer, buflen, "%d", (int) response_num);
602  } else {
603  snprintf(buffer, buflen, "%f", response_num);
604  }
605 
606  return 0;
607 }
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ acf_max_exec()

static int acf_max_exec ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buffer,
size_t  buflen 
)
static

Definition at line 537 of file func_math.c.

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero, LOG_ERROR, and LOG_WARNING.

539 {
540  double num1, num2, response_num = 0;
542  AST_APP_ARG(num1);
543  AST_APP_ARG(num2);
544  );
545 
547 
548  if (ast_strlen_zero(args.num1) && ast_strlen_zero(args.num2)) {
549  ast_log(LOG_ERROR, "Missing argument for number(s).");
550  return -1;
551  }
552 
553  if (ast_strlen_zero(args.num1)) {
554  response_num = -1; /* couldn't read num1 successfully */
555  } else if (sscanf(args.num1, "%30lf", &num1) != 1) {
556  ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num1);
557  return -1;
558  }
559 
560  if (ast_strlen_zero(args.num2)) {
561  num2 = num1; /* num1 must be a valid integer here */
562  } else if (sscanf(args.num2, "%30lf", &num2) != 1) {
563  ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num2);
564  return -1;
565  }
566 
567  if (response_num == -1) { /* could only read num2 */
568  response_num = num2;
569  } else {
570  response_num = (num1 < num2) ? num2 : num1;
571  }
572 
573  ast_debug(1, "%f is the maximum of [%f,%f]\n", response_num, num1, num2);
574  if ((int) response_num == response_num) {
575  snprintf(buffer, buflen, "%d", (int) response_num);
576  } else {
577  snprintf(buffer, buflen, "%f", response_num);
578  }
579 
580  return 0;
581 }
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ acf_min_exec()

static int acf_min_exec ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buffer,
size_t  buflen 
)
static

Definition at line 491 of file func_math.c.

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero, LOG_ERROR, and LOG_WARNING.

493 {
494  double num1, num2, response_num = 0;
496  AST_APP_ARG(num1);
497  AST_APP_ARG(num2);
498  );
499 
501 
502  if (ast_strlen_zero(args.num1) && ast_strlen_zero(args.num2)) {
503  ast_log(LOG_ERROR, "Missing argument for number(s).");
504  return -1;
505  }
506 
507  if (ast_strlen_zero(args.num1)) {
508  response_num = -1; /* couldn't read num1 successfully */
509  } else if (sscanf(args.num1, "%30lf", &num1) != 1) {
510  ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num1);
511  return -1;
512  }
513 
514  if (ast_strlen_zero(args.num2)) {
515  num2 = num1; /* num1 must be a valid integer here */
516  } else if (sscanf(args.num2, "%30lf", &num2) != 1) {
517  ast_log(LOG_WARNING, "'%s' is not a valid number\n", args.num2);
518  return -1;
519  }
520 
521  if (response_num == -1) { /* could only read num2 */
522  response_num = num2;
523  } else {
524  response_num = (num1 > num2) ? num2 : num1;
525  }
526 
527  ast_debug(1, "%f is the minimum of [%f,%f]\n", response_num, num1, num2);
528  if ((int) response_num == response_num) {
529  snprintf(buffer, buflen, "%d", (int) response_num);
530  } else {
531  snprintf(buffer, buflen, "%f", response_num);
532  }
533 
534  return 0;
535 }
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 723 of file func_math.c.

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( test_MATH_function  )

Definition at line 643 of file func_math.c.

References ast_free, ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_substitute_variables(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, result, TEST_EXECUTE, and TEST_INIT.

644 {
646  struct ast_str *expr, *result;
647 
648  switch (cmd) {
649  case TEST_INIT:
650  info->name = "test_MATH_function";
651  info->category = "/main/pbx/";
652  info->summary = "Test MATH function substitution";
653  info->description =
654  "Executes a series of variable substitutions using the MATH function and ensures that the expected results are received.";
655  return AST_TEST_NOT_RUN;
656  case TEST_EXECUTE:
657  break;
658  }
659 
660  ast_test_status_update(test, "Testing MATH() substitution ...\n");
661 
662  if (!(expr = ast_str_create(16))) {
663  return AST_TEST_FAIL;
664  }
665  if (!(result = ast_str_create(16))) {
666  ast_free(expr);
667  return AST_TEST_FAIL;
668  }
669 
670  ast_str_set(&expr, 0, "${MATH(170 AND 63,i)}");
672  if (strcmp(ast_str_buffer(result), "42") != 0) {
673  ast_test_status_update(test, "Expected result '42' not returned! ('%s')\n",
674  ast_str_buffer(result));
675  res = AST_TEST_FAIL;
676  }
677 
678  ast_str_set(&expr, 0, "${MATH(170AND63,i)}");
680  if (strcmp(ast_str_buffer(result), "42") != 0) {
681  ast_test_status_update(test, "Expected result '42' not returned! ('%s')\n",
682  ast_str_buffer(result));
683  res = AST_TEST_FAIL;
684  }
685 
686  ast_free(expr);
687  ast_free(result);
688 
689  return res;
690 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
#define NULL
Definition: resample.c:96
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
def info(msg)
#define ast_free(a)
Definition: astmm.h:182
static PGresult * result
Definition: cel_pgsql.c:88
ast_test_result_state
Definition: test.h:200
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ crement_function_read()

static int crement_function_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 423 of file func_math.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log, ast_strlen_zero, LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and var.

425 {
426  int ret = -1;
427  int int_value = 0;
428  int modify_orig = 0;
429  const char *var;
430  char endchar = 0, returnvar[12]; /* If you need a variable longer than 11 digits - something is way wrong */
431 
432  if (ast_strlen_zero(data)) {
433  ast_log(LOG_WARNING, "Syntax: %s(<data>) - missing argument!\n", cmd);
434  return -1;
435  }
436 
437  if (!chan) {
438  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
439  return -1;
440  }
441 
442  ast_channel_lock(chan);
443 
444  if (!(var = pbx_builtin_getvar_helper(chan, data))) {
445  ast_log(LOG_NOTICE, "Failed to obtain variable %s, bailing out\n", data);
446  ast_channel_unlock(chan);
447  return -1;
448  }
449 
450  if (ast_strlen_zero(var)) {
451  ast_log(LOG_NOTICE, "Variable %s doesn't exist - are you sure you wrote it correctly?\n", data);
452  ast_channel_unlock(chan);
453  return -1;
454  }
455 
456  if (sscanf(var, "%30d%1c", &int_value, &endchar) == 0 || endchar != 0) {
457  ast_log(LOG_NOTICE, "The content of ${%s} is not a numeric value - bailing out!\n", data);
458  ast_channel_unlock(chan);
459  return -1;
460  }
461 
462  /* now we'll actually do something useful */
463  if (!strcasecmp(cmd, "INC")) { /* Increment variable */
464  int_value++;
465  modify_orig = 1;
466  } else if (!strcasecmp(cmd, "DEC")) { /* Decrement variable */
467  int_value--;
468  modify_orig = 1;
469  }
470 
471  if (snprintf(returnvar, sizeof(returnvar), "%d", int_value) > 0) {
472  pbx_builtin_setvar_helper(chan, data, returnvar);
473  if (modify_orig) {
474  ast_copy_string(buf, returnvar, len);
475  }
476  ret = 0;
477  } else {
478  pbx_builtin_setvar_helper(chan, data, "0");
479  if (modify_orig) {
480  ast_copy_string(buf, "0", len);
481  }
482  ast_log(LOG_NOTICE, "Variable %s refused to be %sREMENTED, setting value to 0", data, cmd);
483  ret = 0;
484  }
485 
486  ast_channel_unlock(chan);
487 
488  return ret;
489 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define var
Definition: ast_expr2f.c:614
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
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...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ load_module()

static int load_module ( void  )
static

Definition at line 708 of file func_math.c.

References ast_custom_function_register, and AST_TEST_REGISTER.

709 {
710  int res = 0;
711 
718  AST_TEST_REGISTER(test_MATH_function);
719 
720  return res;
721 }
static struct ast_custom_function math_function
Definition: func_math.c:609
static struct ast_custom_function acf_max
Definition: func_math.c:630
static struct ast_custom_function decrement_function
Definition: func_math.c:619
static struct ast_custom_function acf_abs
Definition: func_math.c:636
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static struct ast_custom_function acf_min
Definition: func_math.c:624
static struct ast_custom_function increment_function
Definition: func_math.c:614
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508

◆ math()

static int math ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
size_t  len 
)
static

Definition at line 180 of file func_math.c.

References ADDFUNCTION, args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero, BITWISEANDFUNCTION, BITWISEORFUNCTION, BITWISEXORFUNCTION, CHAR_RESULT, DIVIDEFUNCTION, EQFUNCTION, FLOAT_RESULT, GTEFUNCTION, GTFUNCTION, HEX_RESULT, INT_RESULT, LOG_WARNING, LTEFUNCTION, LTFUNCTION, MODULUSFUNCTION, MULTIPLYFUNCTION, NULL, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION, and SUBTRACTFUNCTION.

182 {
183  double fnum1;
184  double fnum2;
185  double ftmp = 0;
186  char *op;
187  int iaction = -1;
188  int type_of_result = FLOAT_RESULT;
189  char *mvalue1, *mvalue2 = NULL, *mtype_of_result;
190  int negvalue1 = 0;
192  AST_APP_ARG(argv0);
193  AST_APP_ARG(argv1);
194  );
195 
196  if (ast_strlen_zero(parse)) {
197  ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
198  return -1;
199  }
200 
202 
203  if (args.argc < 1) {
204  ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
205  return -1;
206  }
207 
208  mvalue1 = args.argv0;
209 
210  if (mvalue1[0] == '-') {
211  negvalue1 = 1;
212  mvalue1++;
213  }
214 
215  if ((op = strchr(mvalue1, '*'))) {
216  iaction = MULTIPLYFUNCTION;
217  *op = '\0';
218  } else if ((op = strchr(mvalue1, '/'))) {
219  iaction = DIVIDEFUNCTION;
220  *op = '\0';
221  } else if ((op = strchr(mvalue1, '%'))) {
222  iaction = MODULUSFUNCTION;
223  *op = '\0';
224  } else if ((op = strchr(mvalue1, '^'))) {
225  iaction = POWFUNCTION;
226  *op = '\0';
227  } else if ((op = strstr(mvalue1, "AND"))) {
228  iaction = BITWISEANDFUNCTION;
229  *op = '\0';
230  op += 2;
231  } else if ((op = strstr(mvalue1, "XOR"))) {
232  iaction = BITWISEXORFUNCTION;
233  *op = '\0';
234  op += 2;
235  } else if ((op = strstr(mvalue1, "OR"))) {
236  iaction = BITWISEORFUNCTION;
237  *op = '\0';
238  ++op;
239  } else if ((op = strchr(mvalue1, '>'))) {
240  iaction = GTFUNCTION;
241  *op = '\0';
242  if (*(op + 1) == '=') {
243  iaction = GTEFUNCTION;
244  ++op;
245  } else if (*(op + 1) == '>') {
246  iaction = SHRIGHTFUNCTION;
247  ++op;
248  }
249  } else if ((op = strchr(mvalue1, '<'))) {
250  iaction = LTFUNCTION;
251  *op = '\0';
252  if (*(op + 1) == '=') {
253  iaction = LTEFUNCTION;
254  ++op;
255  } else if (*(op + 1) == '<') {
256  iaction = SHLEFTFUNCTION;
257  ++op;
258  }
259  } else if ((op = strchr(mvalue1, '='))) {
260  *op = '\0';
261  if (*(op + 1) == '=') {
262  iaction = EQFUNCTION;
263  ++op;
264  } else
265  op = NULL;
266  } else if ((op = strchr(mvalue1, '+'))) {
267  iaction = ADDFUNCTION;
268  *op = '\0';
269  } else if ((op = strchr(mvalue1, '-'))) { /* subtraction MUST always be last, in case we have a negative second number */
270  iaction = SUBTRACTFUNCTION;
271  *op = '\0';
272  }
273 
274  if (op)
275  mvalue2 = op + 1;
276 
277  /* detect wanted type of result */
278  mtype_of_result = args.argv1;
279  if (mtype_of_result) {
280  if (!strcasecmp(mtype_of_result, "float")
281  || !strcasecmp(mtype_of_result, "f"))
282  type_of_result = FLOAT_RESULT;
283  else if (!strcasecmp(mtype_of_result, "int")
284  || !strcasecmp(mtype_of_result, "i"))
285  type_of_result = INT_RESULT;
286  else if (!strcasecmp(mtype_of_result, "hex")
287  || !strcasecmp(mtype_of_result, "h"))
288  type_of_result = HEX_RESULT;
289  else if (!strcasecmp(mtype_of_result, "char")
290  || !strcasecmp(mtype_of_result, "c"))
291  type_of_result = CHAR_RESULT;
292  else {
293  ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n",
294  mtype_of_result);
295  return -1;
296  }
297  }
298 
299  if (!mvalue2) {
301  "Supply all the parameters - just this once, please\n");
302  return -1;
303  }
304 
305  if (sscanf(mvalue1, "%30lf", &fnum1) != 1) {
306  ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
307  return -1;
308  }
309 
310  if (sscanf(mvalue2, "%30lf", &fnum2) != 1) {
311  ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
312  return -1;
313  }
314 
315  if (negvalue1)
316  fnum1 = 0 - fnum1;
317 
318  switch (iaction) {
319  case ADDFUNCTION:
320  ftmp = fnum1 + fnum2;
321  break;
322  case DIVIDEFUNCTION:
323  if (fnum2 <= 0)
324  ftmp = 0; /* can't do a divide by 0 */
325  else
326  ftmp = (fnum1 / fnum2);
327  break;
328  case MULTIPLYFUNCTION:
329  ftmp = (fnum1 * fnum2);
330  break;
331  case SUBTRACTFUNCTION:
332  ftmp = (fnum1 - fnum2);
333  break;
334  case MODULUSFUNCTION:
335  {
336  int inum1 = fnum1;
337  int inum2 = fnum2;
338 
339  if (inum2 == 0) {
340  ftmp = 0;
341  } else {
342  ftmp = (inum1 % inum2);
343  }
344 
345  break;
346  }
347  case POWFUNCTION:
348  ftmp = pow(fnum1, fnum2);
349  break;
350  case SHLEFTFUNCTION:
351  {
352  int inum1 = fnum1;
353  int inum2 = fnum2;
354 
355  ftmp = (inum1 << inum2);
356  break;
357  }
358  case SHRIGHTFUNCTION:
359  {
360  int inum1 = fnum1;
361  int inum2 = fnum2;
362 
363  ftmp = (inum1 >> inum2);
364  break;
365  }
366  case BITWISEANDFUNCTION:
367  {
368  int inum1 = fnum1;
369  int inum2 = fnum2;
370  ftmp = (inum1 & inum2);
371  break;
372  }
373  case BITWISEXORFUNCTION:
374  {
375  int inum1 = fnum1;
376  int inum2 = fnum2;
377  ftmp = (inum1 ^ inum2);
378  break;
379  }
380  case BITWISEORFUNCTION:
381  {
382  int inum1 = fnum1;
383  int inum2 = fnum2;
384  ftmp = (inum1 | inum2);
385  break;
386  }
387  case GTFUNCTION:
388  ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len);
389  break;
390  case LTFUNCTION:
391  ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len);
392  break;
393  case GTEFUNCTION:
394  ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len);
395  break;
396  case LTEFUNCTION:
397  ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len);
398  break;
399  case EQFUNCTION:
400  ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len);
401  break;
402  default:
404  "Something happened that neither of us should be proud of %d\n",
405  iaction);
406  return -1;
407  }
408 
409  if (iaction < GTFUNCTION || iaction > EQFUNCTION) {
410  if (type_of_result == FLOAT_RESULT)
411  snprintf(buf, len, "%f", ftmp);
412  else if (type_of_result == INT_RESULT)
413  snprintf(buf, len, "%i", (int) ftmp);
414  else if (type_of_result == HEX_RESULT)
415  snprintf(buf, len, "%x", (unsigned int) ftmp);
416  else if (type_of_result == CHAR_RESULT)
417  snprintf(buf, len, "%c", (unsigned char) ftmp);
418  }
419 
420  return 0;
421 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 693 of file func_math.c.

References ast_custom_function_unregister(), and AST_TEST_UNREGISTER.

694 {
695  int res = 0;
696 
703  AST_TEST_UNREGISTER(test_MATH_function);
704 
705  return res;
706 }
static struct ast_custom_function math_function
Definition: func_math.c:609
static struct ast_custom_function acf_max
Definition: func_math.c:630
static struct ast_custom_function decrement_function
Definition: func_math.c:619
static struct ast_custom_function acf_abs
Definition: func_math.c:636
static struct ast_custom_function acf_min
Definition: func_math.c:624
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static struct ast_custom_function increment_function
Definition: func_math.c:614
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Mathematical dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 723 of file func_math.c.

◆ acf_abs

struct ast_custom_function acf_abs
static
Initial value:
= {
.name = "ABS",
.read = acf_abs_exec,
.read_max = 12,
}
static int acf_abs_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
Definition: func_math.c:583

Definition at line 636 of file func_math.c.

◆ acf_max

struct ast_custom_function acf_max
static
Initial value:
= {
.name = "MAX",
.read = acf_max_exec,
.read_max = 12,
}
static int acf_max_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
Definition: func_math.c:537

Definition at line 630 of file func_math.c.

◆ acf_min

struct ast_custom_function acf_min
static
Initial value:
= {
.name = "MIN",
.read = acf_min_exec,
.read_max = 12,
}
static int acf_min_exec(struct ast_channel *chan, const char *cmd, char *parse, char *buffer, size_t buflen)
Definition: func_math.c:491

Definition at line 624 of file func_math.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 723 of file func_math.c.

◆ decrement_function

struct ast_custom_function decrement_function
static
Initial value:
= {
.name = "DEC",
}
static int crement_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_math.c:423

Definition at line 619 of file func_math.c.

◆ increment_function

struct ast_custom_function increment_function
static
Initial value:
= {
.name = "INC",
}
static int crement_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_math.c:423

Definition at line 614 of file func_math.c.

◆ math_function

struct ast_custom_function math_function
static
Initial value:
= {
.name = "MATH",
.read = math
}
static int math(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_math.c:180

Definition at line 609 of file func_math.c.