handle whitepace around expression
[asterisk/asterisk.git] / funcs / func_logic.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Conditional logic dialplan functions
5  * 
6  * Copyright (C) 2005, Digium, Inc.
7  * Portions Copyright (C) 2005, Anthony Minessale II
8  *
9  * This program is free software, distributed under the terms of
10  * the GNU General Public License
11  */
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/types.h>
16
17 #include "asterisk.h"
18
19 /* ASTERISK_FILE_VERSION(__FILE__, "$Revision$") */
20
21 #include "asterisk/channel.h"
22 #include "asterisk/pbx.h"
23 #include "asterisk/logger.h"
24 #include "asterisk/utils.h"
25 #include "asterisk/app.h"
26 #include "asterisk/config.h"            /* for ast_true */
27
28 static char *builtin_function_isnull(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
29 {
30         return data && *data ? "0" : "1";
31 }
32
33 static char *builtin_function_exists(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
34 {
35         return data && *data ? "1" : "0";
36 }
37
38 static char *builtin_function_iftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
39 {
40         struct ast_timing timing;
41         char *ret;
42         char *expr;
43         char *iftrue;
44         char *iffalse;
45
46         if (!(data = ast_strdupa(data))) {
47                 ast_log(LOG_WARNING, "Memory Error!\n");
48                 return NULL;
49         }
50
51         data = ast_strip_quoted(data, "\"", "\"");
52         expr = strsep(&data, "?");
53         iftrue = strsep(&data, ":");
54         iffalse = data;
55
56         if (!expr || ast_strlen_zero(expr) || !(iftrue || iffalse)) {
57                 ast_log(LOG_WARNING, "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
58                 return NULL;
59         }
60
61         if (!ast_build_timing(&timing, expr)) {
62                 ast_log(LOG_WARNING, "Invalid Time Spec.\n");
63                 return NULL;
64         }
65
66         if (iftrue)
67                 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
68         if (iffalse)
69                 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
70
71         if ((ret = ast_check_timing(&timing) ? iftrue : iffalse)) {
72                 ast_copy_string(buf, ret, len);
73                 ret = buf;
74         } 
75         
76         return ret;
77 }
78
79 static char *builtin_function_if(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
80 {
81         char *ret;
82         char *expr;
83         char *iftrue;
84         char *iffalse;
85
86         if (!(data = ast_strdupa(data))) {
87                 ast_log(LOG_WARNING, "Memory Error!\n");
88                 return NULL;
89         }
90
91         data = ast_strip_quoted(data, "\"", "\"");
92         expr = strsep(&data, "?");
93         iftrue = strsep(&data, ":");
94         iffalse = data;
95
96         if (!expr || ast_strlen_zero(expr) || !(iftrue || iffalse)) {
97                 ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>])\n");
98                 return NULL;
99         }
100
101         expr = ast_strip(expr);
102         if (iftrue)
103                 iftrue = ast_strip_quoted(iftrue, "\"", "\"");
104         if (iffalse)
105                 iffalse = ast_strip_quoted(iffalse, "\"", "\"");
106
107         if ((ret = ast_true(expr) ? iftrue : iffalse)) {
108                 ast_copy_string(buf, ret, len);
109                 ret = buf;
110         } 
111         
112         return ret;
113 }
114
115 static char *builtin_function_set(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
116 {
117         char *varname;
118         char *val;
119
120         if (!(data = ast_strdupa(data))) {
121                 ast_log(LOG_WARNING, "Memory Error!\n");
122                 return NULL;
123         }
124
125         varname = strsep(&data, "=");
126         val = data;
127
128         if (!varname || ast_strlen_zero(varname) || !val) {
129                 ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
130                 return NULL;
131         }
132
133         varname = ast_strip(varname);
134         val = ast_strip(val);
135         pbx_builtin_setvar_helper(chan, varname, val);
136         ast_copy_string(buf, val, len);
137
138         return buf;
139 }
140
141 #ifndef BUILTIN_FUNC
142 static
143 #endif
144 struct ast_custom_function isnull_function = {
145         .name = "ISNULL",
146         .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
147         .syntax = "ISNULL(<data>)",
148         .read = builtin_function_isnull,
149 };
150
151 #ifndef BUILTIN_FUNC
152 static
153 #endif
154 struct ast_custom_function set_function = {
155         .name = "SET",
156         .synopsis = "SET assigns a value to a channel variable",
157         .syntax = "SET(<varname>=[<value>])",
158         .read = builtin_function_set,
159 };
160
161 #ifndef BUILTIN_FUNC
162 static
163 #endif
164 struct ast_custom_function exists_function = {
165         .name = "EXISTS",
166         .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
167         .syntax = "EXISTS(<data>)",
168         .read = builtin_function_exists,
169 };
170
171 #ifndef BUILTIN_FUNC
172 static
173 #endif
174 struct ast_custom_function if_function = {
175         .name = "IF",
176         .synopsis = "Conditional: Returns the data following '?' if true else the data following ':'",
177         .syntax = "IF(<expr>?[<true>][:<false>])",
178         .read = builtin_function_if,
179 };
180
181
182 #ifndef BUILTIN_FUNC
183 static
184 #endif
185 struct ast_custom_function if_time_function = {
186         .name = "IFTIME",
187         .synopsis = "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
188         .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
189         .read = builtin_function_iftime,
190 };