#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 "asterisk/test.h"
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 | 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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static struct ast_module_info * | ast_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 |
Mark Spencer <markster@digium.com>
Nir Simionovich <nirs@greenfieldtech.net>
Definition in file func_math.c.
enum TypeOfFunctions |
Definition at line 108 of file func_math.c.
00108 { 00109 ADDFUNCTION, 00110 DIVIDEFUNCTION, 00111 MULTIPLYFUNCTION, 00112 SUBTRACTFUNCTION, 00113 MODULUSFUNCTION, 00114 POWFUNCTION, 00115 SHLEFTFUNCTION, 00116 SHRIGHTFUNCTION, 00117 BITWISEANDFUNCTION, 00118 BITWISEXORFUNCTION, 00119 BITWISEORFUNCTION, 00120 GTFUNCTION, 00121 LTFUNCTION, 00122 GTEFUNCTION, 00123 LTEFUNCTION, 00124 EQFUNCTION 00125 };
enum TypeOfResult |
Definition at line 127 of file func_math.c.
00127 { 00128 FLOAT_RESULT, 00129 INT_RESULT, 00130 HEX_RESULT, 00131 CHAR_RESULT 00132 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 532 of file func_math.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 532 of file func_math.c.
static int crement_function_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 377 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.
00379 { 00380 int ret = -1; 00381 int int_value = 0; 00382 int modify_orig = 0; 00383 const char *var; 00384 char endchar = 0, returnvar[12]; /* If you need a variable longer than 11 digits - something is way wrong */ 00385 00386 if (ast_strlen_zero(data)) { 00387 ast_log(LOG_WARNING, "Syntax: %s(<data>) - missing argument!\n", cmd); 00388 return -1; 00389 } 00390 00391 ast_channel_lock(chan); 00392 00393 if (!(var = pbx_builtin_getvar_helper(chan, data))) { 00394 ast_log(LOG_NOTICE, "Failed to obtain variable %s, bailing out\n", data); 00395 ast_channel_unlock(chan); 00396 return -1; 00397 } 00398 00399 if (ast_strlen_zero(var)) { 00400 ast_log(LOG_NOTICE, "Variable %s doesn't exist - are you sure you wrote it correctly?\n", data); 00401 ast_channel_unlock(chan); 00402 return -1; 00403 } 00404 00405 if (sscanf(var, "%30d%1c", &int_value, &endchar) == 0 || endchar != 0) { 00406 ast_log(LOG_NOTICE, "The content of ${%s} is not a numeric value - bailing out!\n", data); 00407 ast_channel_unlock(chan); 00408 return -1; 00409 } 00410 00411 /* now we'll actually do something useful */ 00412 if (!strcasecmp(cmd, "INC")) { /* Increment variable */ 00413 int_value++; 00414 modify_orig = 1; 00415 } else if (!strcasecmp(cmd, "DEC")) { /* Decrement variable */ 00416 int_value--; 00417 modify_orig = 1; 00418 } 00419 00420 ast_log(LOG_NOTICE, "The value is now: %d\n", int_value); 00421 00422 if (snprintf(returnvar, sizeof(returnvar), "%d", int_value) > 0) { 00423 pbx_builtin_setvar_helper(chan, data, returnvar); 00424 if (modify_orig) { 00425 ast_copy_string(buf, returnvar, len); 00426 } 00427 ret = 0; 00428 } else { 00429 pbx_builtin_setvar_helper(chan, data, "0"); 00430 if (modify_orig) { 00431 ast_copy_string(buf, "0", len); 00432 } 00433 ast_log(LOG_NOTICE, "Variable %s refused to be %sREMENTED, setting value to 0", data, cmd); 00434 ret = 0; 00435 } 00436 00437 ast_channel_unlock(chan); 00438 00439 return ret; 00440 }
static int load_module | ( | void | ) | [static] |
Definition at line 520 of file func_math.c.
References ast_custom_function_register, AST_TEST_REGISTER, decrement_function, increment_function, and math_function.
00521 { 00522 int res = 0; 00523 00524 res |= ast_custom_function_register(&math_function); 00525 res |= ast_custom_function_register(&increment_function); 00526 res |= ast_custom_function_register(&decrement_function); 00527 AST_TEST_REGISTER(test_MATH_function); 00528 00529 return res; 00530 }
static int math | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 134 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, DIVIDEFUNCTION, FLOAT_RESULT, GTEFUNCTION, GTFUNCTION, HEX_RESULT, INT_RESULT, LOG_WARNING, LTEFUNCTION, LTFUNCTION, MODULUSFUNCTION, MULTIPLYFUNCTION, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION, and SUBTRACTFUNCTION.
00136 { 00137 double fnum1; 00138 double fnum2; 00139 double ftmp = 0; 00140 char *op; 00141 int iaction = -1; 00142 int type_of_result = FLOAT_RESULT; 00143 char *mvalue1, *mvalue2 = NULL, *mtype_of_result; 00144 int negvalue1 = 0; 00145 AST_DECLARE_APP_ARGS(args, 00146 AST_APP_ARG(argv0); 00147 AST_APP_ARG(argv1); 00148 ); 00149 00150 if (ast_strlen_zero(parse)) { 00151 ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n"); 00152 return -1; 00153 } 00154 00155 AST_STANDARD_APP_ARGS(args, parse); 00156 00157 if (args.argc < 1) { 00158 ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n"); 00159 return -1; 00160 } 00161 00162 mvalue1 = args.argv0; 00163 00164 if (mvalue1[0] == '-') { 00165 negvalue1 = 1; 00166 mvalue1++; 00167 } 00168 00169 if ((op = strchr(mvalue1, '*'))) { 00170 iaction = MULTIPLYFUNCTION; 00171 *op = '\0'; 00172 } else if ((op = strchr(mvalue1, '/'))) { 00173 iaction = DIVIDEFUNCTION; 00174 *op = '\0'; 00175 } else if ((op = strchr(mvalue1, '%'))) { 00176 iaction = MODULUSFUNCTION; 00177 *op = '\0'; 00178 } else if ((op = strchr(mvalue1, '^'))) { 00179 iaction = POWFUNCTION; 00180 *op = '\0'; 00181 } else if ((op = strstr(mvalue1, "AND"))) { 00182 iaction = BITWISEANDFUNCTION; 00183 *op = '\0'; 00184 op += 2; 00185 } else if ((op = strstr(mvalue1, "XOR"))) { 00186 iaction = BITWISEXORFUNCTION; 00187 *op = '\0'; 00188 op += 2; 00189 } else if ((op = strstr(mvalue1, "OR"))) { 00190 iaction = BITWISEORFUNCTION; 00191 *op = '\0'; 00192 ++op; 00193 } else if ((op = strchr(mvalue1, '>'))) { 00194 iaction = GTFUNCTION; 00195 *op = '\0'; 00196 if (*(op + 1) == '=') { 00197 iaction = GTEFUNCTION; 00198 ++op; 00199 } else if (*(op + 1) == '>') { 00200 iaction = SHRIGHTFUNCTION; 00201 ++op; 00202 } 00203 } else if ((op = strchr(mvalue1, '<'))) { 00204 iaction = LTFUNCTION; 00205 *op = '\0'; 00206 if (*(op + 1) == '=') { 00207 iaction = LTEFUNCTION; 00208 ++op; 00209 } else if (*(op + 1) == '<') { 00210 iaction = SHLEFTFUNCTION; 00211 ++op; 00212 } 00213 } else if ((op = strchr(mvalue1, '='))) { 00214 *op = '\0'; 00215 if (*(op + 1) == '=') { 00216 iaction = EQFUNCTION; 00217 ++op; 00218 } else 00219 op = NULL; 00220 } else if ((op = strchr(mvalue1, '+'))) { 00221 iaction = ADDFUNCTION; 00222 *op = '\0'; 00223 } else if ((op = strchr(mvalue1, '-'))) { /* subtraction MUST always be last, in case we have a negative second number */ 00224 iaction = SUBTRACTFUNCTION; 00225 *op = '\0'; 00226 } 00227 00228 if (op) 00229 mvalue2 = op + 1; 00230 00231 /* detect wanted type of result */ 00232 mtype_of_result = args.argv1; 00233 if (mtype_of_result) { 00234 if (!strcasecmp(mtype_of_result, "float") 00235 || !strcasecmp(mtype_of_result, "f")) 00236 type_of_result = FLOAT_RESULT; 00237 else if (!strcasecmp(mtype_of_result, "int") 00238 || !strcasecmp(mtype_of_result, "i")) 00239 type_of_result = INT_RESULT; 00240 else if (!strcasecmp(mtype_of_result, "hex") 00241 || !strcasecmp(mtype_of_result, "h")) 00242 type_of_result = HEX_RESULT; 00243 else if (!strcasecmp(mtype_of_result, "char") 00244 || !strcasecmp(mtype_of_result, "c")) 00245 type_of_result = CHAR_RESULT; 00246 else { 00247 ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n", 00248 mtype_of_result); 00249 return -1; 00250 } 00251 } 00252 00253 if (!mvalue1 || !mvalue2) { 00254 ast_log(LOG_WARNING, 00255 "Supply all the parameters - just this once, please\n"); 00256 return -1; 00257 } 00258 00259 if (sscanf(mvalue1, "%30lf", &fnum1) != 1) { 00260 ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1); 00261 return -1; 00262 } 00263 00264 if (sscanf(mvalue2, "%30lf", &fnum2) != 1) { 00265 ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2); 00266 return -1; 00267 } 00268 00269 if (negvalue1) 00270 fnum1 = 0 - fnum1; 00271 00272 switch (iaction) { 00273 case ADDFUNCTION: 00274 ftmp = fnum1 + fnum2; 00275 break; 00276 case DIVIDEFUNCTION: 00277 if (fnum2 <= 0) 00278 ftmp = 0; /* can't do a divide by 0 */ 00279 else 00280 ftmp = (fnum1 / fnum2); 00281 break; 00282 case MULTIPLYFUNCTION: 00283 ftmp = (fnum1 * fnum2); 00284 break; 00285 case SUBTRACTFUNCTION: 00286 ftmp = (fnum1 - fnum2); 00287 break; 00288 case MODULUSFUNCTION: 00289 { 00290 int inum1 = fnum1; 00291 int inum2 = fnum2; 00292 00293 if (inum2 == 0) { 00294 ftmp = 0; 00295 } else { 00296 ftmp = (inum1 % inum2); 00297 } 00298 00299 break; 00300 } 00301 case POWFUNCTION: 00302 ftmp = pow(fnum1, fnum2); 00303 break; 00304 case SHLEFTFUNCTION: 00305 { 00306 int inum1 = fnum1; 00307 int inum2 = fnum2; 00308 00309 ftmp = (inum1 << inum2); 00310 break; 00311 } 00312 case SHRIGHTFUNCTION: 00313 { 00314 int inum1 = fnum1; 00315 int inum2 = fnum2; 00316 00317 ftmp = (inum1 >> inum2); 00318 break; 00319 } 00320 case BITWISEANDFUNCTION: 00321 { 00322 int inum1 = fnum1; 00323 int inum2 = fnum2; 00324 ftmp = (inum1 & inum2); 00325 break; 00326 } 00327 case BITWISEXORFUNCTION: 00328 { 00329 int inum1 = fnum1; 00330 int inum2 = fnum2; 00331 ftmp = (inum1 ^ inum2); 00332 break; 00333 } 00334 case BITWISEORFUNCTION: 00335 { 00336 int inum1 = fnum1; 00337 int inum2 = fnum2; 00338 ftmp = (inum1 | inum2); 00339 break; 00340 } 00341 case GTFUNCTION: 00342 ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len); 00343 break; 00344 case LTFUNCTION: 00345 ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len); 00346 break; 00347 case GTEFUNCTION: 00348 ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len); 00349 break; 00350 case LTEFUNCTION: 00351 ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len); 00352 break; 00353 case EQFUNCTION: 00354 ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len); 00355 break; 00356 default: 00357 ast_log(LOG_WARNING, 00358 "Something happened that neither of us should be proud of %d\n", 00359 iaction); 00360 return -1; 00361 } 00362 00363 if (iaction < GTFUNCTION || iaction > EQFUNCTION) { 00364 if (type_of_result == FLOAT_RESULT) 00365 snprintf(buf, len, "%f", ftmp); 00366 else if (type_of_result == INT_RESULT) 00367 snprintf(buf, len, "%i", (int) ftmp); 00368 else if (type_of_result == HEX_RESULT) 00369 snprintf(buf, len, "%x", (unsigned int) ftmp); 00370 else if (type_of_result == CHAR_RESULT) 00371 snprintf(buf, len, "%c", (unsigned char) ftmp); 00372 } 00373 00374 return 0; 00375 }
static int unload_module | ( | void | ) | [static] |
Definition at line 508 of file func_math.c.
References ast_custom_function_unregister(), AST_TEST_UNREGISTER, decrement_function, increment_function, and math_function.
00509 { 00510 int res = 0; 00511 00512 res |= ast_custom_function_unregister(&math_function); 00513 res |= ast_custom_function_unregister(&increment_function); 00514 res |= ast_custom_function_unregister(&decrement_function); 00515 AST_TEST_UNREGISTER(test_MATH_function); 00516 00517 return res; 00518 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 532 of file func_math.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 532 of file func_math.c.
struct ast_custom_function decrement_function [static] |
Initial value:
{ .name = "DEC", .read = crement_function_read, }
Definition at line 453 of file func_math.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function increment_function [static] |
Initial value:
{ .name = "INC", .read = crement_function_read, }
Definition at line 448 of file func_math.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function math_function [static] |
Initial value:
{ .name = "MATH", .read = math }
Definition at line 443 of file func_math.c.
Referenced by load_module(), and unload_module().