7ea7c22f84fccb267e53d0d30969f100dd4c6bd3
[asterisk/asterisk.git] / apps / app_math.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * simple maths application
5  * 
6  * Copyright (C) 2004, Andy Powell 
7  *
8  * Updated by Mark Spencer <markster@digium.com>
9  *
10  */
11
12 #include <asterisk/lock.h>
13 #include <asterisk/file.h>
14 #include <asterisk/logger.h>
15 #include <asterisk/channel.h>
16 #include <asterisk/channel_pvt.h>
17 #include <asterisk/pbx.h>
18 #include <asterisk/options.h>
19 #include <asterisk/config.h>
20 #include <asterisk/say.h>
21 #include <asterisk/module.h>
22 #include <asterisk/app.h>
23 #include <asterisk/manager.h>
24 #include <asterisk/localtime.h>
25 #include <asterisk/cli.h>
26 #include <asterisk/utils.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <sys/time.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <time.h>
37 #include <dirent.h>
38 #include <asterisk/module.h>
39 #include <asterisk/translate.h>
40 #include <ctype.h>
41 #include <sys/file.h>
42 #include "../astconf.h"
43
44 static char *tdesc = "Basic maths functions";
45
46 static char *app_math = "Math";
47
48 static char *math_synopsis = "Performs Mathematical Functions";
49
50 static char *math_descrip =
51 "Math(returnvar,<number1><op><number 2>\n\n"
52 "Perform floating point calculation on number 1 to number 2 and \n"
53 "store the result in returnvar.  Valid ops are: \n"
54 "    +,-,/,*,%,<,>,>=,<=,==\n"
55 "and behave as their C equivalents.  Always returns 0.\n";
56
57 #define ADDFUNCTION 0
58 #define DIVIDEFUNCTION 1
59 #define MULTIPLYFUNCTION 2
60 #define SUBTRACTFUNCTION 3
61 #define MODULUSFUNCTION 4
62
63 #define GTFUNCTION 5
64 #define LTFUNCTION 6
65 #define GTEFUNCTION 7
66 #define LTEFUNCTION 8
67 #define EQFUNCTION 9
68
69 STANDARD_LOCAL_USER;
70
71 LOCAL_USER_DECL;
72
73 static int math_exec(struct ast_channel *chan, void *data) 
74 {
75         float fnum1;
76         float fnum2;
77         float ftmp = 0;
78         char *op;
79         int iaction=-1;
80
81         /* dunno, big calulations :D */
82         char user_result[30];
83
84         char *s;
85         char *mvar, *mvalue1, *mvalue2=NULL;
86                 
87         struct localuser *u;
88
89         if (!data) {
90                 ast_log(LOG_WARNING, "No parameters passed. !\n");
91                 return -1;
92         }
93
94         LOCAL_USER_ADD(u);
95                 
96         s = ast_strdupa((void *) data);
97
98         mvar = strsep(&s, "|");
99         mvalue1 = strsep(&s, "|");
100         
101         if ((op = strchr(mvalue1, '+'))) {
102                 iaction = ADDFUNCTION;
103                 *op = '\0';
104         } else if ((op = strchr(mvalue1, '-'))) {
105                 iaction = SUBTRACTFUNCTION;
106                 *op = '\0';
107         } else if ((op = strchr(mvalue1, '*'))) {
108                 iaction = MULTIPLYFUNCTION;
109                 *op = '\0';
110         } else if ((op = strchr(mvalue1, '/'))) {
111                 iaction = DIVIDEFUNCTION;
112                 *op = '\0';
113         } else if ((op = strchr(mvalue1, '>'))) {
114                 iaction = GTFUNCTION;
115                 *op = '\0';
116                 if (*(op+1) == '=') {
117                         op++;
118                         *op = '\0';
119                         iaction = GTEFUNCTION;
120                 }
121         } else if ((op = strchr(mvalue1, '<'))) {
122                 iaction = LTFUNCTION;
123                 *op = '\0';
124                 if (*(op+1) == '=') {
125                         op++;
126                         *op = '\0';
127                         iaction = LTEFUNCTION;
128                 }
129         } else if ((op = strchr(mvalue1, '='))) {
130                 iaction = GTFUNCTION;
131                 *op = '\0';
132                 if (*(op+1) == '=') {
133                         op++;
134                         *op = '\0';
135                         iaction = EQFUNCTION;
136                 } else
137                         op = NULL;
138         } 
139         
140         if (op) 
141                 mvalue2 = op + 1;
142                 
143         if (!mvar || !mvalue1 || !mvalue2) {
144                 ast_log(LOG_WARNING, "Supply all the parameters - just this once, please\n");
145                 LOCAL_USER_REMOVE(u);
146                 return -1;
147         }
148
149         if (!strcmp(mvar,"")) {
150                 ast_log(LOG_WARNING, "No return variable set.\n");
151                 LOCAL_USER_REMOVE(u);
152                 return -1;
153         }
154
155         if (sscanf(mvalue1, "%f", &fnum1) != 1) {
156                 ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
157                 LOCAL_USER_REMOVE(u);
158                 return -1;
159         }
160
161         if (sscanf(mvalue2, "%f", &fnum2) != 1) {
162                 ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
163                 LOCAL_USER_REMOVE(u);
164                 return -1;
165         }
166
167         switch (iaction) {
168         case ADDFUNCTION :
169                 ftmp = fnum1 + fnum2;
170                 break;
171         case DIVIDEFUNCTION :
172                 if (fnum2 <=0)
173                         ftmp = 0; /* can't do a divide by 0 */
174                 else
175                         ftmp = (fnum1 / fnum2);
176                 break;
177         case MULTIPLYFUNCTION :
178                 ftmp = (fnum1 * fnum2);
179                 break;
180         case SUBTRACTFUNCTION :
181                 ftmp = (fnum2 - fnum1);
182                 break;
183         case MODULUSFUNCTION : {
184                 int inum1 = fnum1;
185                 int inum2 = fnum2;
186                         
187                 ftmp = (inum1 % inum2);
188                 
189                 break;
190                 }
191         case GTFUNCTION :
192                 if (fnum1 > fnum2)
193                         strncpy (user_result, "TRUE", sizeof (user_result) - 1);
194                 else
195                         strncpy (user_result, "FALSE", sizeof (user_result) - 1);
196                 break;
197         case LTFUNCTION :
198                 if (fnum1 < fnum2)
199                         strncpy (user_result, "TRUE", sizeof (user_result) - 1);
200                 else
201                         strncpy (user_result, "FALSE", sizeof (user_result) - 1);
202                 break;
203         case GTEFUNCTION :
204                 if (fnum1 >= fnum2)
205                         strncpy (user_result, "TRUE", sizeof (user_result) - 1);
206                 else
207                         strncpy (user_result, "FALSE", sizeof (user_result) - 1);
208                 break;
209         case LTEFUNCTION :
210                 if (fnum1 <= fnum2)
211                         strncpy (user_result, "TRUE", sizeof (user_result) - 1);
212                 else
213                         strncpy (user_result, "FALSE", sizeof (user_result) - 1);
214                 break;                                  
215         case EQFUNCTION :
216                 if (fnum1 == fnum2)
217                         strncpy (user_result, "TRUE", sizeof (user_result) - 1);
218                 else
219                         strncpy (user_result, "FALSE", sizeof (user_result) - 1);
220                 break;
221         default :
222                 ast_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction);
223                 LOCAL_USER_REMOVE(u);
224                 return -1;
225         }
226
227         if (iaction < GTFUNCTION || iaction > EQFUNCTION) 
228                 snprintf(user_result,sizeof(user_result),"%f",ftmp);
229                 
230         pbx_builtin_setvar_helper(chan, mvar, user_result);     
231         
232         LOCAL_USER_REMOVE(u);
233         return 0;
234 }
235
236 int unload_module(void)
237 {
238         int res;
239         STANDARD_HANGUP_LOCALUSERS;
240
241         res  = ast_unregister_application(app_math);
242         return res;
243 }
244
245 int load_module(void)
246 {
247         int res;
248         res = ast_register_application(app_math, math_exec, math_synopsis, math_descrip);
249         return res;
250 }
251
252 char *description(void)
253 {
254         return tdesc;
255 }
256
257 int usecount(void)
258 {
259         int res;
260         STANDARD_USECOUNT(res);
261         return res;
262 }
263
264 char *key()
265 {
266         return ASTERISK_GPL_KEY;
267 }
268
269 /* Fading everything to black and blue... */