Mon Mar 20 08:20:06 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

app_math.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2004 - 2005, Andy Powell 
00005  *
00006  * Updated by Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief A simple math application
00022  * 
00023  * \ingroup applications
00024  */
00025 
00026 #include <stdlib.h>
00027 #include <errno.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032 #include <sys/time.h>
00033 #include <sys/stat.h>
00034 #include <sys/types.h>
00035 #include <time.h>
00036 #include <dirent.h>
00037 #include <ctype.h>
00038 #include <sys/file.h>
00039 
00040 #include "asterisk.h"
00041 
00042 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00043 
00044 #include "asterisk/lock.h"
00045 #include "asterisk/file.h"
00046 #include "asterisk/logger.h"
00047 #include "asterisk/channel.h"
00048 #include "asterisk/pbx.h"
00049 #include "asterisk/options.h"
00050 #include "asterisk/config.h"
00051 #include "asterisk/say.h"
00052 #include "asterisk/module.h"
00053 #include "asterisk/app.h"
00054 #include "asterisk/manager.h"
00055 #include "asterisk/localtime.h"
00056 #include "asterisk/cli.h"
00057 #include "asterisk/utils.h"
00058 #include "asterisk/module.h"
00059 #include "asterisk/translate.h"
00060 
00061 static char *tdesc = "Basic Math Functions";
00062 
00063 static char *app_math = "Math";
00064 
00065 static char *math_synopsis = "Performs Mathematical Functions";
00066 
00067 static char *math_descrip =
00068 "Math(returnvar,<number1><op><number 2>\n\n"
00069 "Perform floating point calculation on number 1 to number 2 and \n"
00070 "store the result in returnvar.  Valid ops are: \n"
00071 "    +,-,/,*,%,<,>,>=,<=,==\n"
00072 "and behave as their C equivalents.\n";
00073 
00074 #define ADDFUNCTION 0
00075 #define DIVIDEFUNCTION 1
00076 #define MULTIPLYFUNCTION 2
00077 #define SUBTRACTFUNCTION 3
00078 #define MODULUSFUNCTION 4
00079 
00080 #define GTFUNCTION 5
00081 #define LTFUNCTION 6
00082 #define GTEFUNCTION 7
00083 #define LTEFUNCTION 8
00084 #define EQFUNCTION 9
00085 
00086 STANDARD_LOCAL_USER;
00087 
00088 LOCAL_USER_DECL;
00089 
00090 static int math_exec(struct ast_channel *chan, void *data) 
00091 {
00092    float fnum1;
00093    float fnum2;
00094    float ftmp = 0;
00095    char *op;
00096    int iaction=-1;
00097    static int deprecation_warning = 0;
00098 
00099    /* dunno, big calulations :D */
00100    char user_result[30];
00101 
00102    char *s;
00103    char *mvar, *mvalue1, *mvalue2=NULL;
00104       
00105    struct localuser *u;
00106 
00107    if (!deprecation_warning) {
00108       ast_log(LOG_WARNING, "Math() is deprecated, please use Set(var=${MATH(...)} instead.\n");
00109       deprecation_warning = 1;
00110    }
00111 
00112    if (ast_strlen_zero(data)) {
00113       ast_log(LOG_WARNING, "No parameters passed. !\n");
00114       return -1;
00115    }
00116 
00117    LOCAL_USER_ADD(u);
00118 
00119    s = ast_strdupa(data);
00120    if (!s) {
00121       ast_log(LOG_ERROR, "Out of memory\n");
00122       LOCAL_USER_REMOVE(u);
00123       return -1;
00124    }
00125 
00126    mvar = strsep(&s, "|");
00127    mvalue1 = strsep(&s, "|");
00128    
00129    if ((op = strchr(mvalue1, '+'))) {
00130       iaction = ADDFUNCTION;
00131       *op = '\0';
00132    } else if ((op = strchr(mvalue1, '-'))) {
00133       iaction = SUBTRACTFUNCTION;
00134       *op = '\0';
00135    } else if ((op = strchr(mvalue1, '*'))) {
00136       iaction = MULTIPLYFUNCTION;
00137       *op = '\0';
00138    } else if ((op = strchr(mvalue1, '/'))) {
00139       iaction = DIVIDEFUNCTION;
00140       *op = '\0';
00141    } else if ((op = strchr(mvalue1, '>'))) {
00142       iaction = GTFUNCTION;
00143       *op = '\0';
00144       if (*(op+1) == '=') {
00145          op++;
00146          *op = '\0';
00147          iaction = GTEFUNCTION;
00148       }
00149    } else if ((op = strchr(mvalue1, '<'))) {
00150       iaction = LTFUNCTION;
00151       *op = '\0';
00152       if (*(op+1) == '=') {
00153          op++;
00154          *op = '\0';
00155          iaction = LTEFUNCTION;
00156       }
00157    } else if ((op = strchr(mvalue1, '='))) {
00158       iaction = GTFUNCTION;
00159       *op = '\0';
00160       if (*(op+1) == '=') {
00161          op++;
00162          *op = '\0';
00163          iaction = EQFUNCTION;
00164       } else
00165          op = NULL;
00166    } 
00167    
00168    if (op) 
00169       mvalue2 = op + 1;
00170       
00171    if (!mvar || !mvalue1 || !mvalue2) {
00172       ast_log(LOG_WARNING, "Supply all the parameters - just this once, please\n");
00173       LOCAL_USER_REMOVE(u);
00174       return -1;
00175    }
00176 
00177    if (!strcmp(mvar,"")) {
00178       ast_log(LOG_WARNING, "No return variable set.\n");
00179       LOCAL_USER_REMOVE(u);
00180       return -1;
00181    }
00182 
00183    if (sscanf(mvalue1, "%f", &fnum1) != 1) {
00184       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
00185       LOCAL_USER_REMOVE(u);
00186       return -1;
00187    }
00188 
00189    if (sscanf(mvalue2, "%f", &fnum2) != 1) {
00190       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
00191       LOCAL_USER_REMOVE(u);
00192       return -1;
00193    }
00194 
00195    switch (iaction) {
00196    case ADDFUNCTION :
00197       ftmp = fnum1 + fnum2;
00198       break;
00199    case DIVIDEFUNCTION :
00200       if (fnum2 <=0)
00201          ftmp = 0; /* can't do a divide by 0 */
00202       else
00203          ftmp = (fnum1 / fnum2);
00204       break;
00205    case MULTIPLYFUNCTION :
00206       ftmp = (fnum1 * fnum2);
00207       break;
00208    case SUBTRACTFUNCTION :
00209       ftmp = (fnum1 - fnum2);
00210       break;
00211    case MODULUSFUNCTION : {
00212       int inum1 = fnum1;
00213       int inum2 = fnum2;
00214          
00215       ftmp = (inum1 % inum2);
00216       
00217       break;
00218       }
00219    case GTFUNCTION :
00220       if (fnum1 > fnum2)
00221          strcpy(user_result, "TRUE");
00222       else
00223          strcpy(user_result, "FALSE");
00224       break;
00225    case LTFUNCTION :
00226       if (fnum1 < fnum2)
00227          strcpy(user_result, "TRUE");
00228       else
00229          strcpy(user_result, "FALSE");
00230       break;
00231    case GTEFUNCTION :
00232       if (fnum1 >= fnum2)
00233          strcpy(user_result, "TRUE");
00234       else
00235          strcpy(user_result, "FALSE");
00236       break;
00237    case LTEFUNCTION :
00238       if (fnum1 <= fnum2)
00239          strcpy(user_result, "TRUE");
00240       else
00241          strcpy(user_result, "FALSE");
00242       break;               
00243    case EQFUNCTION :
00244       if (fnum1 == fnum2)
00245          strcpy(user_result, "TRUE");
00246       else
00247          strcpy(user_result, "FALSE");
00248       break;
00249    default :
00250       ast_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction);
00251       LOCAL_USER_REMOVE(u);
00252       return -1;
00253    }
00254 
00255    if (iaction < GTFUNCTION || iaction > EQFUNCTION) 
00256       snprintf(user_result,sizeof(user_result),"%f",ftmp);
00257       
00258    pbx_builtin_setvar_helper(chan, mvar, user_result);   
00259    
00260    LOCAL_USER_REMOVE(u);
00261    return 0;
00262 }
00263 
00264 int unload_module(void)
00265 {
00266    int res;
00267    
00268    res = ast_unregister_application(app_math);
00269 
00270    STANDARD_HANGUP_LOCALUSERS;
00271 
00272    return res;
00273 }
00274 
00275 int load_module(void)
00276 {
00277    return ast_register_application(app_math, math_exec, math_synopsis, math_descrip);
00278 }
00279 
00280 char *description(void)
00281 {
00282    return tdesc;
00283 }
00284 
00285 int usecount(void)
00286 {
00287    int res;
00288    STANDARD_USECOUNT(res);
00289    return res;
00290 }
00291 
00292 char *key()
00293 {
00294    return ASTERISK_GPL_KEY;
00295 }
00296 
00297 /* Fading everything to black and blue... */

Generated on Mon Mar 20 08:20:06 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1