Fri Aug 24 02:25:38 2007

Asterisk developer's documentation


func_math.c File Reference

Math related dialplan function. More...

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.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,
  GTFUNCTION, LTFUNCTION, GTEFUNCTION, LTEFUNCTION,
  EQFUNCTION
}
enum  TypeOfResult { FLOAT_RESULT, INT_RESULT, HEX_RESULT, CHAR_RESULT }

Functions

 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Mathematical dialplan function")
static int load_module (void)
static int math (struct ast_channel *chan, char *cmd, char *parse, char *buf, size_t len)
static int unload_module (void)

Variables

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

enum TypeOfFunctions

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

Definition at line 47 of file func_math.c.

00047                      {
00048    ADDFUNCTION,
00049    DIVIDEFUNCTION,
00050    MULTIPLYFUNCTION,
00051    SUBTRACTFUNCTION,
00052    MODULUSFUNCTION,
00053    POWFUNCTION,
00054    SHLEFTFUNCTION,
00055    SHRIGHTFUNCTION,
00056    GTFUNCTION,
00057    LTFUNCTION,
00058    GTEFUNCTION,
00059    LTEFUNCTION,
00060    EQFUNCTION
00061 };

enum TypeOfResult

Enumerator:
FLOAT_RESULT 
INT_RESULT 
HEX_RESULT 
CHAR_RESULT 

Definition at line 63 of file func_math.c.

00063                   {
00064    FLOAT_RESULT,
00065    INT_RESULT,
00066    HEX_RESULT,
00067    CHAR_RESULT
00068 };


Function Documentation

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Mathematical dialplan function"   
)

static int load_module ( void   )  [static]

Definition at line 297 of file func_math.c.

References ast_custom_function_register(), and math_function.

00298 {
00299    return ast_custom_function_register(&math_function);
00300 }

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

Definition at line 70 of file func_math.c.

References ADDFUNCTION, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), DIVIDEFUNCTION, FLOAT_RESULT, GTEFUNCTION, GTFUNCTION, HEX_RESULT, INT_RESULT, LOG_WARNING, LTEFUNCTION, LTFUNCTION, MODULUSFUNCTION, MULTIPLYFUNCTION, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION, and SUBTRACTFUNCTION.

00072 {
00073    double fnum1;
00074    double fnum2;
00075    double ftmp = 0;
00076    char *op;
00077    int iaction = -1;
00078    int type_of_result = FLOAT_RESULT;
00079    char *mvalue1, *mvalue2 = NULL, *mtype_of_result;
00080    int negvalue1 = 0;
00081    AST_DECLARE_APP_ARGS(args,
00082               AST_APP_ARG(argv0);
00083               AST_APP_ARG(argv1);
00084    );
00085 
00086    if (ast_strlen_zero(parse)) {
00087       ast_log(LOG_WARNING, "Syntax: Math(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
00088       return -1;
00089    }
00090 
00091    AST_STANDARD_APP_ARGS(args, parse);
00092 
00093    if (args.argc < 1) {
00094       ast_log(LOG_WARNING, "Syntax: Math(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
00095       return -1;
00096    }
00097 
00098    mvalue1 = args.argv0;
00099 
00100    if (mvalue1[0] == '-') {
00101       negvalue1 = 1;
00102       mvalue1++;
00103    }
00104 
00105    if ((op = strchr(mvalue1, '*'))) {
00106       iaction = MULTIPLYFUNCTION;
00107       *op = '\0';
00108    } else if ((op = strchr(mvalue1, '/'))) {
00109       iaction = DIVIDEFUNCTION;
00110       *op = '\0';
00111    } else if ((op = strchr(mvalue1, '%'))) {
00112       iaction = MODULUSFUNCTION;
00113       *op = '\0';
00114    } else if ((op = strchr(mvalue1, '^'))) {
00115       iaction = POWFUNCTION;
00116       *op = '\0';
00117    } else if ((op = strchr(mvalue1, '>'))) {
00118       iaction = GTFUNCTION;
00119       *op = '\0';
00120       if (*(op + 1) == '=') {
00121          *++op = '\0';
00122          iaction = GTEFUNCTION;
00123       } else if (*(op + 1) == '>') {
00124          *++op = '\0';
00125          iaction = SHRIGHTFUNCTION;
00126       }
00127    } else if ((op = strchr(mvalue1, '<'))) {
00128       iaction = LTFUNCTION;
00129       *op = '\0';
00130       if (*(op + 1) == '=') {
00131          *++op = '\0';
00132          iaction = LTEFUNCTION;
00133       } else if (*(op + 1) == '<') {
00134          *++op = '\0';
00135          iaction = SHLEFTFUNCTION;
00136       }
00137    } else if ((op = strchr(mvalue1, '='))) {
00138       *op = '\0';
00139       if (*(op + 1) == '=') {
00140          *++op = '\0';
00141          iaction = EQFUNCTION;
00142       } else
00143          op = NULL;
00144    } else if ((op = strchr(mvalue1, '+'))) {
00145       iaction = ADDFUNCTION;
00146       *op = '\0';
00147    } else if ((op = strchr(mvalue1, '-'))) { /* subtraction MUST always be last, in case we have a negative first number */
00148       iaction = SUBTRACTFUNCTION;
00149       *op = '\0';
00150    }
00151 
00152    if (op)
00153       mvalue2 = op + 1;
00154 
00155    /* detect wanted type of result */
00156    mtype_of_result = args.argv1;
00157    if (mtype_of_result) {
00158       if (!strcasecmp(mtype_of_result, "float")
00159           || !strcasecmp(mtype_of_result, "f"))
00160          type_of_result = FLOAT_RESULT;
00161       else if (!strcasecmp(mtype_of_result, "int")
00162           || !strcasecmp(mtype_of_result, "i"))
00163          type_of_result = INT_RESULT;
00164       else if (!strcasecmp(mtype_of_result, "hex")
00165           || !strcasecmp(mtype_of_result, "h"))
00166          type_of_result = HEX_RESULT;
00167       else if (!strcasecmp(mtype_of_result, "char")
00168           || !strcasecmp(mtype_of_result, "c"))
00169          type_of_result = CHAR_RESULT;
00170       else {
00171          ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n",
00172                mtype_of_result);
00173          return -1;
00174       }
00175    }
00176 
00177    if (!mvalue1 || !mvalue2) {
00178       ast_log(LOG_WARNING,
00179             "Supply all the parameters - just this once, please\n");
00180       return -1;
00181    }
00182 
00183    if (sscanf(mvalue1, "%lf", &fnum1) != 1) {
00184       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
00185       return -1;
00186    }
00187 
00188    if (sscanf(mvalue2, "%lf", &fnum2) != 1) {
00189       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
00190       return -1;
00191    }
00192 
00193    if (negvalue1)
00194       fnum1 = 0 - fnum1;
00195 
00196    switch (iaction) {
00197    case ADDFUNCTION:
00198       ftmp = fnum1 + fnum2;
00199       break;
00200    case DIVIDEFUNCTION:
00201       if (fnum2 <= 0)
00202          ftmp = 0;         /* can't do a divide by 0 */
00203       else
00204          ftmp = (fnum1 / fnum2);
00205       break;
00206    case MULTIPLYFUNCTION:
00207       ftmp = (fnum1 * fnum2);
00208       break;
00209    case SUBTRACTFUNCTION:
00210       ftmp = (fnum1 - fnum2);
00211       break;
00212    case MODULUSFUNCTION:
00213       {
00214          int inum1 = fnum1;
00215          int inum2 = fnum2;
00216 
00217          ftmp = (inum1 % inum2);
00218 
00219          break;
00220       }
00221    case POWFUNCTION:
00222       ftmp = pow(fnum1, fnum2);
00223       break;
00224    case SHLEFTFUNCTION:
00225       {
00226          int inum1 = fnum1;
00227          int inum2 = fnum2;
00228 
00229          ftmp = (inum1 << inum2);
00230          break;
00231       }
00232    case SHRIGHTFUNCTION:
00233       {
00234          int inum1 = fnum1;
00235          int inum2 = fnum2;
00236 
00237          ftmp = (inum1 >> inum2);
00238          break;
00239       }
00240    case GTFUNCTION:
00241       ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len);
00242       break;
00243    case LTFUNCTION:
00244       ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len);
00245       break;
00246    case GTEFUNCTION:
00247       ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len);
00248       break;
00249    case LTEFUNCTION:
00250       ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len);
00251       break;
00252    case EQFUNCTION:
00253       ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len);
00254       break;
00255    default:
00256       ast_log(LOG_WARNING,
00257             "Something happened that neither of us should be proud of %d\n",
00258             iaction);
00259       return -1;
00260    }
00261 
00262    if (iaction < GTFUNCTION || iaction > EQFUNCTION) {
00263       if (type_of_result == FLOAT_RESULT)
00264          snprintf(buf, len, "%f", ftmp);
00265       else if (type_of_result == INT_RESULT)
00266          snprintf(buf, len, "%i", (int) ftmp);
00267       else if (type_of_result == HEX_RESULT)
00268          snprintf(buf, len, "%x", (unsigned int) ftmp);
00269       else if (type_of_result == CHAR_RESULT)
00270          snprintf(buf, len, "%c", (unsigned char) ftmp);
00271    }
00272 
00273    return 0;
00274 }

static int unload_module ( void   )  [static]

Definition at line 292 of file func_math.c.

References ast_custom_function_unregister(), and math_function.

00293 {
00294    return ast_custom_function_unregister(&math_function);
00295 }


Variable Documentation

struct ast_custom_function math_function [static]

Definition at line 276 of file func_math.c.

Referenced by load_module(), and unload_module().


Generated on Fri Aug 24 02:25:38 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1