Thu Apr 28 2011 17:13:55

Asterisk developer's documentation


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/app.h"
#include "asterisk/config.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 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
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mathematical dialplan function" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_custom_function math_function

Detailed Description

Math related dialplan function.

Author:
Andy Powell
Mark Spencer <markster@digium.com>

Definition in file func_math.c.


Enumeration Type Documentation

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

Definition at line 71 of file func_math.c.

Enumerator:
FLOAT_RESULT 
INT_RESULT 
HEX_RESULT 
CHAR_RESULT 

Definition at line 90 of file func_math.c.


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 355 of file func_math.c.

static void __unreg_module ( void  ) [static]

Definition at line 355 of file func_math.c.

static int load_module ( void  ) [static]

Definition at line 350 of file func_math.c.

References ast_custom_function_register.

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

Definition at line 97 of file func_math.c.

References ADDFUNCTION, 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, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION, and SUBTRACTFUNCTION.

{
   double fnum1;
   double fnum2;
   double ftmp = 0;
   char *op;
   int iaction = -1;
   int type_of_result = FLOAT_RESULT;
   char *mvalue1, *mvalue2 = NULL, *mtype_of_result;
   int negvalue1 = 0;
   AST_DECLARE_APP_ARGS(args,
              AST_APP_ARG(argv0);
              AST_APP_ARG(argv1);
   );

   if (ast_strlen_zero(parse)) {
      ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
      return -1;
   }

   AST_STANDARD_APP_ARGS(args, parse);

   if (args.argc < 1) {
      ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
      return -1;
   }

   mvalue1 = args.argv0;

   if (mvalue1[0] == '-') {
      negvalue1 = 1;
      mvalue1++;
   }

   if ((op = strchr(mvalue1, '*'))) {
      iaction = MULTIPLYFUNCTION;
      *op = '\0';
   } else if ((op = strchr(mvalue1, '/'))) {
      iaction = DIVIDEFUNCTION;
      *op = '\0';
   } else if ((op = strchr(mvalue1, '%'))) {
      iaction = MODULUSFUNCTION;
      *op = '\0';
   } else if ((op = strchr(mvalue1, '^'))) {
      iaction = POWFUNCTION;
      *op = '\0';
   } else if ((op = strstr(mvalue1, "AND"))) {
      iaction = BITWISEANDFUNCTION;
      *op = '\0';
      op += 2;
   } else if ((op = strstr(mvalue1, "XOR"))) {
      iaction = BITWISEXORFUNCTION;
      *op = '\0';
      op += 2;
   } else if ((op = strstr(mvalue1, "OR"))) {
      iaction = BITWISEORFUNCTION;
      *op = '\0';
      ++op;
   } else if ((op = strchr(mvalue1, '>'))) {
      iaction = GTFUNCTION;
      *op = '\0';
      if (*(op + 1) == '=') {
         iaction = GTEFUNCTION;
         ++op;
      } else if (*(op + 1) == '>') {
         iaction = SHRIGHTFUNCTION;
         ++op;
      }
   } else if ((op = strchr(mvalue1, '<'))) {
      iaction = LTFUNCTION;
      *op = '\0';
      if (*(op + 1) == '=') {
         iaction = LTEFUNCTION;
         ++op;
      } else if (*(op + 1) == '<') {
         iaction = SHLEFTFUNCTION;
         ++op;
      }
   } else if ((op = strchr(mvalue1, '='))) {
      *op = '\0';
      if (*(op + 1) == '=') {
         iaction = EQFUNCTION;
         ++op;
      } else
         op = NULL;
   } else if ((op = strchr(mvalue1, '+'))) {
      iaction = ADDFUNCTION;
      *op = '\0';
   } else if ((op = strchr(mvalue1, '-'))) { /* subtraction MUST always be last, in case we have a negative second number */
      iaction = SUBTRACTFUNCTION;
      *op = '\0';
   }

   if (op)
      mvalue2 = op + 1;

   /* detect wanted type of result */
   mtype_of_result = args.argv1;
   if (mtype_of_result) {
      if (!strcasecmp(mtype_of_result, "float")
          || !strcasecmp(mtype_of_result, "f"))
         type_of_result = FLOAT_RESULT;
      else if (!strcasecmp(mtype_of_result, "int")
          || !strcasecmp(mtype_of_result, "i"))
         type_of_result = INT_RESULT;
      else if (!strcasecmp(mtype_of_result, "hex")
          || !strcasecmp(mtype_of_result, "h"))
         type_of_result = HEX_RESULT;
      else if (!strcasecmp(mtype_of_result, "char")
          || !strcasecmp(mtype_of_result, "c"))
         type_of_result = CHAR_RESULT;
      else {
         ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n",
               mtype_of_result);
         return -1;
      }
   }

   if (!mvalue1 || !mvalue2) {
      ast_log(LOG_WARNING,
            "Supply all the parameters - just this once, please\n");
      return -1;
   }

   if (sscanf(mvalue1, "%30lf", &fnum1) != 1) {
      ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
      return -1;
   }

   if (sscanf(mvalue2, "%30lf", &fnum2) != 1) {
      ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
      return -1;
   }

   if (negvalue1)
      fnum1 = 0 - fnum1;

   switch (iaction) {
   case ADDFUNCTION:
      ftmp = fnum1 + fnum2;
      break;
   case DIVIDEFUNCTION:
      if (fnum2 <= 0)
         ftmp = 0;         /* can't do a divide by 0 */
      else
         ftmp = (fnum1 / fnum2);
      break;
   case MULTIPLYFUNCTION:
      ftmp = (fnum1 * fnum2);
      break;
   case SUBTRACTFUNCTION:
      ftmp = (fnum1 - fnum2);
      break;
   case MODULUSFUNCTION:
      {
         int inum1 = fnum1;
         int inum2 = fnum2;

         if (inum2 == 0) {
            ftmp = 0;
         } else {
            ftmp = (inum1 % inum2);
         }

         break;
      }
   case POWFUNCTION:
      ftmp = pow(fnum1, fnum2);
      break;
   case SHLEFTFUNCTION:
      {
         int inum1 = fnum1;
         int inum2 = fnum2;

         ftmp = (inum1 << inum2);
         break;
      }
   case SHRIGHTFUNCTION:
      {
         int inum1 = fnum1;
         int inum2 = fnum2;

         ftmp = (inum1 >> inum2);
         break;
      }
   case BITWISEANDFUNCTION:
      {
         int inum1 = fnum1;
         int inum2 = fnum2;
         ftmp = (inum1 & inum2);
         break;
      }
   case BITWISEXORFUNCTION:
      {
         int inum1 = fnum1;
         int inum2 = fnum2;
         ftmp = (inum1 ^ inum2);
         break;
      }
   case BITWISEORFUNCTION:
      {
         int inum1 = fnum1;
         int inum2 = fnum2;
         ftmp = (inum1 | inum2);
         break;
      }
   case GTFUNCTION:
      ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len);
      break;
   case LTFUNCTION:
      ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len);
      break;
   case GTEFUNCTION:
      ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len);
      break;
   case LTEFUNCTION:
      ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len);
      break;
   case EQFUNCTION:
      ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len);
      break;
   default:
      ast_log(LOG_WARNING,
            "Something happened that neither of us should be proud of %d\n",
            iaction);
      return -1;
   }

   if (iaction < GTFUNCTION || iaction > EQFUNCTION) {
      if (type_of_result == FLOAT_RESULT)
         snprintf(buf, len, "%f", ftmp);
      else if (type_of_result == INT_RESULT)
         snprintf(buf, len, "%i", (int) ftmp);
      else if (type_of_result == HEX_RESULT)
         snprintf(buf, len, "%x", (unsigned int) ftmp);
      else if (type_of_result == CHAR_RESULT)
         snprintf(buf, len, "%c", (unsigned char) ftmp);
   }

   return 0;
}
static int unload_module ( void  ) [static]

Definition at line 345 of file func_math.c.

References ast_custom_function_unregister().


Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mathematical dialplan function" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 355 of file func_math.c.

Definition at line 355 of file func_math.c.

Initial value:
 {
   .name = "MATH",
   .read = math
}

Definition at line 340 of file func_math.c.