String manipulation dialplan functions. More...
#include "asterisk.h"
#include <regex.h>
#include <ctype.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/localtime.h"
#include "asterisk/test.h"
Go to the source code of this file.
Defines | |
#define | beginning (cmd[0] == 'U') |
#define | beginning (cmd[0] == 'S') |
#define | HASH_FORMAT HASH_PREFIX "%s~" |
#define | HASH_PREFIX "~HASH~%s~" |
Functions | |
static int | acf_strftime (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t buflen) |
static int | acf_strptime (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen) |
static int | array (struct ast_channel *chan, const char *cmd, char *var, const char *value) |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"String handling dialplan functions") | |
AST_THREADSTORAGE (tmp_buf) | |
AST_THREADSTORAGE (result_buf) | |
static void | clearvar_prefix (struct ast_channel *chan, const char *prefix) |
static int | csv_quote (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | exec_clearhash (struct ast_channel *chan, const char *data) |
static int | filter (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len) |
static int | function_eval (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen) |
static int | function_eval2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen) |
static int | function_fieldnum (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len) |
static int | function_fieldnum_helper (struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len) |
static int | function_fieldnum_str (struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len) |
static int | function_fieldqty (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len) |
static int | function_fieldqty_helper (struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len) |
static int | function_fieldqty_str (struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len) |
static int | hash_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | hash_write (struct ast_channel *chan, const char *cmd, char *var, const char *value) |
static int | hashkeys_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | hashkeys_read2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len) |
static int | keypadhash (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen) |
static int | len (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen) |
static int | listfilter (struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **bufstr, ssize_t len) |
static int | listfilter_read (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len) |
static int | listfilter_read2 (struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len) |
static int | load_module (void) |
static int | passthru (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len) |
static int | quote (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | regex (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len) |
static int | replace (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len) |
static int | shift_pop (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len) |
static int | string_tolower (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen) |
static int | string_tolower2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen) |
static int | string_toupper (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen) |
static int | string_toupper2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen) |
static int | unload_module (void) |
static int | unshift_push (struct ast_channel *chan, const char *cmd, char *data, const char *new_value) |
Variables | |
static char * | app_clearhash = "ClearHash" |
static struct ast_custom_function | array_function |
static struct ast_custom_function | csv_quote_function |
static struct ast_custom_function | eval_function |
static struct ast_custom_function | fieldnum_function |
static struct ast_custom_function | fieldqty_function |
static struct ast_custom_function | filter_function |
static struct ast_custom_function | hash_function |
static struct ast_custom_function | hashkeys_function |
static struct ast_custom_function | keypadhash_function |
static struct ast_custom_function | len_function |
static struct ast_custom_function | listfilter_function |
static struct ast_custom_function | passthru_function |
static struct ast_custom_function | pop_function |
static struct ast_custom_function | push_function |
static struct ast_custom_function | quote_function |
static struct ast_custom_function | regex_function |
static struct ast_custom_function | replace_function |
static struct ast_custom_function | shift_function |
static struct ast_custom_function | strftime_function |
static struct ast_custom_function | strptime_function |
static struct ast_custom_function | tolower_function |
static struct ast_custom_function | toupper_function |
static struct ast_custom_function | unshift_function |
String manipulation dialplan functions.
Definition in file func_strings.c.
#define beginning (cmd[0] == 'U') |
#define beginning (cmd[0] == 'S') |
Referenced by shift_pop(), and unshift_push().
#define HASH_FORMAT HASH_PREFIX "%s~" |
Definition at line 884 of file func_strings.c.
Referenced by array(), hash_read(), and hash_write().
#define HASH_PREFIX "~HASH~%s~" |
Definition at line 883 of file func_strings.c.
Referenced by exec_clearhash(), hashkeys_read(), and hashkeys_read2().
static int acf_strftime | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1212 of file func_strings.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_timeval(), ast_localtime(), ast_log(), AST_STANDARD_APP_ARGS, ast_strftime(), ast_tvnow(), format, and LOG_WARNING.
01214 { 01215 AST_DECLARE_APP_ARGS(args, 01216 AST_APP_ARG(epoch); 01217 AST_APP_ARG(timezone); 01218 AST_APP_ARG(format); 01219 ); 01220 struct timeval when; 01221 struct ast_tm tm; 01222 01223 buf[0] = '\0'; 01224 01225 AST_STANDARD_APP_ARGS(args, parse); 01226 01227 ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL); 01228 ast_localtime(&when, &tm, args.timezone); 01229 01230 if (!args.format) 01231 args.format = "%c"; 01232 01233 if (ast_strftime(buf, buflen, args.format, &tm) <= 0) 01234 ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n"); 01235 01236 buf[buflen - 1] = '\0'; 01237 01238 return 0; 01239 }
static int acf_strptime | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1246 of file func_strings.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_mktime(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_strptime(), format, LOG_ERROR, and LOG_WARNING.
01248 { 01249 AST_DECLARE_APP_ARGS(args, 01250 AST_APP_ARG(timestring); 01251 AST_APP_ARG(timezone); 01252 AST_APP_ARG(format); 01253 ); 01254 struct ast_tm tm; 01255 01256 buf[0] = '\0'; 01257 01258 if (!data) { 01259 ast_log(LOG_ERROR, 01260 "Asterisk function STRPTIME() requires an argument.\n"); 01261 return -1; 01262 } 01263 01264 AST_STANDARD_APP_ARGS(args, data); 01265 01266 if (ast_strlen_zero(args.format)) { 01267 ast_log(LOG_ERROR, 01268 "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)"); 01269 return -1; 01270 } 01271 01272 if (!ast_strptime(args.timestring, args.format, &tm)) { 01273 ast_log(LOG_WARNING, "STRPTIME() found no time specified within the string\n"); 01274 } else { 01275 struct timeval when; 01276 when = ast_mktime(&tm, args.timezone); 01277 snprintf(buf, buflen, "%d", (int) when.tv_sec); 01278 } 01279 01280 return 0; 01281 }
static int array | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 910 of file func_strings.c.
References AST_APP_ARG, ast_autoservice_stop(), ast_debug, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, HASH_FORMAT, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and S_OR.
Referenced by hash_write().
00912 { 00913 AST_DECLARE_APP_ARGS(arg1, 00914 AST_APP_ARG(var)[100]; 00915 ); 00916 AST_DECLARE_APP_ARGS(arg2, 00917 AST_APP_ARG(val)[100]; 00918 ); 00919 char *origvar = "", *value2, varname[256]; 00920 int i, ishash = 0; 00921 00922 if (!var) { 00923 return -1; 00924 } 00925 value2 = ast_strdupa(value); 00926 00927 if (!strcmp(cmd, "HASH")) { 00928 const char *var2 = pbx_builtin_getvar_helper(chan, "~ODBCFIELDS~"); 00929 origvar = var; 00930 if (var2) 00931 var = ast_strdupa(var2); 00932 else { 00933 if (chan) 00934 ast_autoservice_stop(chan); 00935 return -1; 00936 } 00937 ishash = 1; 00938 } 00939 00940 /* The functions this will generally be used with are SORT and ODBC_*, which 00941 * both return comma-delimited lists. However, if somebody uses literal lists, 00942 * their commas will be translated to vertical bars by the load, and I don't 00943 * want them to be surprised by the result. Hence, we prefer commas as the 00944 * delimiter, but we'll fall back to vertical bars if commas aren't found. 00945 */ 00946 ast_debug(1, "array (%s=%s)\n", var, S_OR(value2, "")); 00947 AST_STANDARD_APP_ARGS(arg1, var); 00948 00949 AST_STANDARD_APP_ARGS(arg2, value2); 00950 00951 for (i = 0; i < arg1.argc; i++) { 00952 ast_debug(1, "array set value (%s=%s)\n", arg1.var[i], 00953 S_OR(arg2.val[i], "")); 00954 if (i < arg2.argc) { 00955 if (ishash) { 00956 if (origvar[0] == '_') { 00957 if (origvar[1] == '_') { 00958 snprintf(varname, sizeof(varname), "__" HASH_FORMAT, origvar + 2, arg1.var[i]); 00959 } else { 00960 snprintf(varname, sizeof(varname), "_" HASH_FORMAT, origvar + 1, arg1.var[i]); 00961 } 00962 } else { 00963 snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]); 00964 } 00965 00966 pbx_builtin_setvar_helper(chan, varname, arg2.val[i]); 00967 } else { 00968 pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]); 00969 } 00970 } else { 00971 /* We could unset the variable, by passing a NULL, but due to 00972 * pushvar semantics, that could create some undesired behavior. */ 00973 if (ishash) { 00974 snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]); 00975 pbx_builtin_setvar_helper(chan, varname, ""); 00976 } else { 00977 pbx_builtin_setvar_helper(chan, arg1.var[i], ""); 00978 } 00979 } 00980 } 00981 00982 return 0; 00983 }
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"String handling dialplan functions" | ||||
) |
AST_THREADSTORAGE | ( | tmp_buf | ) |
AST_THREADSTORAGE | ( | result_buf | ) |
static void clearvar_prefix | ( | struct ast_channel * | chan, | |
const char * | prefix | |||
) | [static] |
Definition at line 889 of file func_strings.c.
References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_name(), len(), var, and ast_channel::varshead.
Referenced by exec_clearhash().
00890 { 00891 struct ast_var_t *var; 00892 int len = strlen(prefix); 00893 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->varshead, var, entries) { 00894 if (strncasecmp(prefix, ast_var_name(var), len) == 0) { 00895 AST_LIST_REMOVE_CURRENT(entries); 00896 ast_free(var); 00897 } 00898 } 00899 AST_LIST_TRAVERSE_SAFE_END 00900 }
static int csv_quote | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1159 of file func_strings.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and LOG_ERROR.
01160 { 01161 char *bufptr = buf, *dataptr = data; 01162 01163 if (len < 3) { /* at least two for quotes and one for binary zero */ 01164 ast_log(LOG_ERROR, "Not enough buffer\n"); 01165 return -1; 01166 } 01167 01168 if (ast_strlen_zero(data)) { 01169 ast_copy_string(buf, "\"\"", len); 01170 return 0; 01171 } 01172 01173 *bufptr++ = '"'; 01174 for (; bufptr < buf + len - 3; dataptr++){ 01175 if (*dataptr == '"') { 01176 *bufptr++ = '"'; 01177 *bufptr++ = '"'; 01178 } else if (*dataptr == '\0') { 01179 break; 01180 } else { 01181 *bufptr++ = *dataptr; 01182 } 01183 } 01184 *bufptr++ = '"'; 01185 *bufptr='\0'; 01186 return 0; 01187 }
static int exec_clearhash | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 902 of file func_strings.c.
References clearvar_prefix(), HASH_PREFIX, and prefix.
Referenced by load_module().
00903 { 00904 char prefix[80]; 00905 snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null"); 00906 clearvar_prefix(chan, prefix); 00907 return 0; 00908 }
static int filter | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 690 of file func_strings.c.
References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), ast_opt_dont_warn, AST_STANDARD_RAW_ARGS, LOG_ERROR, and LOG_WARNING.
Referenced by __ast_data_add(), data_filter_destructor(), data_filter_generate(), data_result_generate(), manager_data_get(), realtime_ldap_base_ap(), set_egress_subscription(), update2_ldap(), and update_ldap().
00692 { 00693 AST_DECLARE_APP_ARGS(args, 00694 AST_APP_ARG(allowed); 00695 AST_APP_ARG(string); 00696 ); 00697 char *outbuf = buf; 00698 unsigned char ac; 00699 char allowed[256] = ""; 00700 size_t allowedlen = 0; 00701 int32_t bitfield[8] = { 0, }; /* 256 bits */ 00702 00703 AST_STANDARD_RAW_ARGS(args, parse); 00704 00705 if (!args.string) { 00706 ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n"); 00707 return -1; 00708 } 00709 00710 if (args.allowed[0] == '"' && !ast_opt_dont_warn) { 00711 ast_log(LOG_WARNING, "FILTER allowed characters includes the quote (\") character. This may not be what you want.\n"); 00712 } 00713 00714 /* Expand ranges */ 00715 for (; *(args.allowed);) { 00716 char c1 = 0, c2 = 0; 00717 size_t consumed = 0; 00718 00719 if (ast_get_encoded_char(args.allowed, &c1, &consumed)) 00720 return -1; 00721 args.allowed += consumed; 00722 00723 if (*(args.allowed) == '-') { 00724 if (ast_get_encoded_char(args.allowed + 1, &c2, &consumed)) 00725 c2 = c1; 00726 args.allowed += consumed + 1; 00727 00728 if ((unsigned char) c2 < (unsigned char) c1 && !ast_opt_dont_warn) { 00729 ast_log(LOG_WARNING, "Range wrapping in FILTER(%s,%s). This may not be what you want.\n", parse, args.string); 00730 } 00731 00732 /*!\note 00733 * Looks a little strange, until you realize that we can overflow 00734 * the size of a char. 00735 */ 00736 for (ac = (unsigned char) c1; ac != (unsigned char) c2; ac++) { 00737 bitfield[ac / 32] |= 1 << (ac % 32); 00738 } 00739 bitfield[ac / 32] |= 1 << (ac % 32); 00740 00741 ast_debug(4, "c1=%d, c2=%d\n", c1, c2); 00742 } else { 00743 ac = (unsigned char) c1; 00744 ast_debug(4, "c1=%d, consumed=%d, args.allowed=%s\n", c1, (int) consumed, args.allowed - consumed); 00745 bitfield[ac / 32] |= 1 << (ac % 32); 00746 } 00747 } 00748 00749 for (ac = 1; ac != 0; ac++) { 00750 if (bitfield[ac / 32] & (1 << (ac % 32))) { 00751 allowed[allowedlen++] = ac; 00752 } 00753 } 00754 00755 ast_debug(1, "Allowed: %s\n", allowed); 00756 00757 for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) { 00758 if (strchr(allowed, *(args.string))) 00759 *outbuf++ = *(args.string); 00760 } 00761 *outbuf = '\0'; 00762 00763 return 0; 00764 }
static int function_eval | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1288 of file func_strings.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_substitute_variables_helper().
01290 { 01291 if (ast_strlen_zero(data)) { 01292 ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n"); 01293 return -1; 01294 } 01295 01296 pbx_substitute_variables_helper(chan, data, buf, buflen - 1); 01297 01298 return 0; 01299 }
static int function_eval2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | buflen | |||
) | [static] |
Definition at line 1301 of file func_strings.c.
References ast_log(), ast_str_substitute_variables(), ast_strlen_zero(), and LOG_WARNING.
01303 { 01304 if (ast_strlen_zero(data)) { 01305 ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n"); 01306 return -1; 01307 } 01308 01309 ast_str_substitute_variables(buf, buflen, chan, data); 01310 01311 return 0; 01312 }
static int function_fieldnum | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 544 of file func_strings.c.
References function_fieldnum_helper().
00546 { 00547 return function_fieldnum_helper(chan, cmd, parse, buf, NULL, len); 00548 }
static int function_fieldnum_helper | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
struct ast_str ** | sbuf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 483 of file func_strings.c.
References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), LOG_ERROR, result_buf, and str.
Referenced by function_fieldnum(), and function_fieldnum_str().
00485 { 00486 char *varsubst, *field; 00487 struct ast_str *str = ast_str_thread_get(&result_buf, 16); 00488 int fieldindex = 0, res = 0; 00489 AST_DECLARE_APP_ARGS(args, 00490 AST_APP_ARG(varname); 00491 AST_APP_ARG(delim); 00492 AST_APP_ARG(field); 00493 ); 00494 char delim[2] = ""; 00495 size_t delim_used; 00496 00497 if (!str) { 00498 return -1; 00499 } 00500 00501 AST_STANDARD_APP_ARGS(args, parse); 00502 00503 if (args.argc < 3) { 00504 ast_log(LOG_ERROR, "Usage: FIELDNUM(<listname>,<delimiter>,<fieldvalue>)\n"); 00505 res = -1; 00506 } else { 00507 varsubst = ast_alloca(strlen(args.varname) + 4); 00508 sprintf(varsubst, "${%s}", args.varname); 00509 00510 ast_str_substitute_variables(&str, 0, chan, varsubst); 00511 00512 if (ast_str_strlen(str) == 0 || ast_strlen_zero(args.delim)) { 00513 fieldindex = 0; 00514 } else if (ast_get_encoded_char(args.delim, delim, &delim_used) == -1) { 00515 res = -1; 00516 } else { 00517 char *varval = ast_str_buffer(str); 00518 00519 while ((field = strsep(&varval, delim)) != NULL) { 00520 fieldindex++; 00521 00522 if (!strcasecmp(field, args.field)) { 00523 break; 00524 } 00525 } 00526 00527 if (!field) { 00528 fieldindex = 0; 00529 } 00530 00531 res = 0; 00532 } 00533 } 00534 00535 if (sbuf) { 00536 ast_str_set(sbuf, len, "%d", fieldindex); 00537 } else { 00538 snprintf(buf, len, "%d", fieldindex); 00539 } 00540 00541 return res; 00542 }
static int function_fieldnum_str | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 550 of file func_strings.c.
References function_fieldnum_helper().
00552 { 00553 return function_fieldnum_helper(chan, cmd, parse, NULL, buf, len); 00554 }
static int function_fieldqty | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 465 of file func_strings.c.
References function_fieldqty_helper().
00467 { 00468 return function_fieldqty_helper(chan, cmd, parse, buf, NULL, len); 00469 }
static int function_fieldqty_helper | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
struct ast_str ** | sbuf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 420 of file func_strings.c.
References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), result_buf, and str.
Referenced by function_fieldqty(), and function_fieldqty_str().
00422 { 00423 char *varsubst; 00424 struct ast_str *str = ast_str_thread_get(&result_buf, 16); 00425 int fieldcount = 0; 00426 AST_DECLARE_APP_ARGS(args, 00427 AST_APP_ARG(varname); 00428 AST_APP_ARG(delim); 00429 ); 00430 char delim[2] = ""; 00431 size_t delim_used; 00432 00433 if (!str) { 00434 return -1; 00435 } 00436 00437 AST_STANDARD_APP_ARGS(args, parse); 00438 if (args.delim) { 00439 ast_get_encoded_char(args.delim, delim, &delim_used); 00440 00441 varsubst = ast_alloca(strlen(args.varname) + 4); 00442 00443 sprintf(varsubst, "${%s}", args.varname); 00444 ast_str_substitute_variables(&str, 0, chan, varsubst); 00445 if (ast_str_strlen(str) == 0) { 00446 fieldcount = 0; 00447 } else { 00448 char *varval = ast_str_buffer(str); 00449 while (strsep(&varval, delim)) { 00450 fieldcount++; 00451 } 00452 } 00453 } else { 00454 fieldcount = 1; 00455 } 00456 if (sbuf) { 00457 ast_str_set(sbuf, len, "%d", fieldcount); 00458 } else { 00459 snprintf(buf, len, "%d", fieldcount); 00460 } 00461 00462 return 0; 00463 }
static int function_fieldqty_str | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 471 of file func_strings.c.
References function_fieldqty_helper().
00473 { 00474 return function_fieldqty_helper(chan, cmd, parse, NULL, buf, len); 00475 }
static int hash_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1057 of file func_strings.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, HASH_FORMAT, hashkeys_read(), pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().
01058 { 01059 char varname[256]; 01060 const char *varvalue; 01061 AST_DECLARE_APP_ARGS(arg, 01062 AST_APP_ARG(hashname); 01063 AST_APP_ARG(hashkey); 01064 ); 01065 01066 AST_STANDARD_APP_ARGS(arg, data); 01067 if (arg.argc == 2) { 01068 snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey); 01069 varvalue = pbx_builtin_getvar_helper(chan, varname); 01070 if (varvalue) 01071 ast_copy_string(buf, varvalue, len); 01072 else 01073 *buf = '\0'; 01074 } else if (arg.argc == 1) { 01075 char colnames[4096]; 01076 int i; 01077 AST_DECLARE_APP_ARGS(arg2, 01078 AST_APP_ARG(col)[100]; 01079 ); 01080 01081 /* Get column names, in no particular order */ 01082 hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames)); 01083 pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames); 01084 01085 AST_STANDARD_APP_ARGS(arg2, colnames); 01086 *buf = '\0'; 01087 01088 /* Now get the corresponding column values, in exactly the same order */ 01089 for (i = 0; i < arg2.argc; i++) { 01090 snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]); 01091 varvalue = pbx_builtin_getvar_helper(chan, varname); 01092 strncat(buf, varvalue, len - strlen(buf) - 1); 01093 strncat(buf, ",", len - strlen(buf) - 1); 01094 } 01095 01096 /* Strip trailing comma */ 01097 buf[strlen(buf) - 1] = '\0'; 01098 } 01099 01100 return 0; 01101 }
static int hash_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 1029 of file func_strings.c.
References array(), AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, HASH_FORMAT, and pbx_builtin_setvar_helper().
01030 { 01031 char varname[256]; 01032 AST_DECLARE_APP_ARGS(arg, 01033 AST_APP_ARG(hashname); 01034 AST_APP_ARG(hashkey); 01035 ); 01036 01037 if (!strchr(var, ',')) { 01038 /* Single argument version */ 01039 return array(chan, "HASH", var, value); 01040 } 01041 01042 AST_STANDARD_APP_ARGS(arg, var); 01043 if (arg.hashname[0] == '_') { 01044 if (arg.hashname[1] == '_') { 01045 snprintf(varname, sizeof(varname), "__" HASH_FORMAT, arg.hashname + 2, arg.hashkey); 01046 } else { 01047 snprintf(varname, sizeof(varname), "_" HASH_FORMAT, arg.hashname + 1, arg.hashkey); 01048 } 01049 } else { 01050 snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey); 01051 } 01052 pbx_builtin_setvar_helper(chan, varname, value); 01053 01054 return 0; 01055 }
static int hashkeys_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 985 of file func_strings.c.
References AST_LIST_TRAVERSE, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, prefix, and ast_channel::varshead.
Referenced by hash_read().
00986 { 00987 struct ast_var_t *newvar; 00988 struct ast_str *prefix = ast_str_alloca(80); 00989 00990 ast_str_set(&prefix, -1, HASH_PREFIX, data); 00991 memset(buf, 0, len); 00992 00993 AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) { 00994 if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) { 00995 /* Copy everything after the prefix */ 00996 strncat(buf, ast_var_name(newvar) + ast_str_strlen(prefix), len - strlen(buf) - 1); 00997 /* Trim the trailing ~ */ 00998 buf[strlen(buf) - 1] = ','; 00999 } 01000 } 01001 /* Trim the trailing comma */ 01002 buf[strlen(buf) - 1] = '\0'; 01003 return 0; 01004 }
static int hashkeys_read2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 1006 of file func_strings.c.
References AST_LIST_TRAVERSE, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, prefix, and ast_channel::varshead.
01007 { 01008 struct ast_var_t *newvar; 01009 struct ast_str *prefix = ast_str_alloca(80); 01010 char *tmp; 01011 01012 ast_str_set(&prefix, -1, HASH_PREFIX, data); 01013 01014 AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) { 01015 if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) { 01016 /* Copy everything after the prefix */ 01017 ast_str_append(buf, len, "%s", ast_var_name(newvar) + ast_str_strlen(prefix)); 01018 /* Trim the trailing ~ */ 01019 tmp = ast_str_buffer(*buf); 01020 tmp[ast_str_strlen(*buf) - 1] = ','; 01021 } 01022 } 01023 /* Trim the trailing comma */ 01024 tmp = ast_str_buffer(*buf); 01025 tmp[ast_str_strlen(*buf) - 1] = '\0'; 01026 return 0; 01027 }
static int keypadhash | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1320 of file func_strings.c.
01321 { 01322 char *bufptr, *dataptr; 01323 01324 for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) { 01325 if (*dataptr == '\0') { 01326 *bufptr++ = '\0'; 01327 break; 01328 } else if (*dataptr == '1') { 01329 *bufptr++ = '1'; 01330 } else if (strchr("AaBbCc2", *dataptr)) { 01331 *bufptr++ = '2'; 01332 } else if (strchr("DdEeFf3", *dataptr)) { 01333 *bufptr++ = '3'; 01334 } else if (strchr("GgHhIi4", *dataptr)) { 01335 *bufptr++ = '4'; 01336 } else if (strchr("JjKkLl5", *dataptr)) { 01337 *bufptr++ = '5'; 01338 } else if (strchr("MmNnOo6", *dataptr)) { 01339 *bufptr++ = '6'; 01340 } else if (strchr("PpQqRrSs7", *dataptr)) { 01341 *bufptr++ = '7'; 01342 } else if (strchr("TtUuVv8", *dataptr)) { 01343 *bufptr++ = '8'; 01344 } else if (strchr("WwXxYyZz9", *dataptr)) { 01345 *bufptr++ = '9'; 01346 } else if (*dataptr == '0') { 01347 *bufptr++ = '0'; 01348 } 01349 } 01350 buf[buflen - 1] = '\0'; 01351 01352 return 0; 01353 }
static int len | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1194 of file func_strings.c.
Referenced by __analog_ss_thread(), __ast_cli_register(), __ast_str_helper(), __get_header(), __rtp_recvfrom(), __rtp_sendto(), _parse(), add_sdp(), ael_token_subst(), aji_io_recv(), aji_recv(), aji_send_header(), aji_send_raw(), aji_start_sasl(), alsa_write(), analog_ss_thread(), aoc_parse_ie(), append_interface(), append_var_and_value_to_filter(), ast_agi_register_multiple(), ast_agi_unregister_multiple(), ast_app_group_set_channel(), ast_callerid_vmwi_generate(), ast_cdr_appenduserfield(), ast_cli_complete(), ast_codec_get_len(), ast_complete_source_filename(), ast_dsp_noise(), ast_dsp_process(), ast_dsp_silence(), ast_event_cb(), ast_format_str_reduce(), ast_frdup(), ast_getformatname_multiple(), ast_http_send(), ast_http_uri_link(), ast_mkdir(), ast_read_image(), ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_read(), ast_say_number_full_ka(), ast_smoother_read(), ast_str_buffer(), ast_str_substitute_variables_full(), ast_translate(), ast_udptl_write(), ast_xml_escape(), ast_xmldoc_printable(), auth_exec(), authenticate(), build_device(), build_facility(), build_route(), callerid_generate(), cleaned_basedn(), clearvar_prefix(), cli_console_sendtext(), complete_agent_logoff_cmd(), complete_confno(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_meetmecmd_list(), complete_meetmecmd_mute_kick(), complete_peer_helper(), complete_trans_path_choice(), complete_userno(), conf_play(), config_jitterbuffer(), cops_getmsg(), copy(), create_video_frame(), dahdi_sendtext(), dahdi_setoption(), devstate_write(), dialgroup_refreshdb(), dictate_exec(), do_pktccops(), dundi_encrypt(), dundi_parse_ies(), dundi_send(), enc_ie_facility(), evt_event_deliver_cb(), expr2_token_subst(), ext_cmp_exten_strlen(), ffmpeg_decode(), find_by_part(), get_body(), get_ip_and_port_from_sdp(), get_sdp(), get_sdp_iterate(), get_to_address(), gsm_write(), gsmtolin_framein(), h261_encap(), h263_encap(), h263_read(), h263_write(), h263p_encap(), h264_read(), h264_write(), handle_cli_core_show_translation(), handle_cli_devstate_change(), handle_commandmatchesarray(), handle_incoming(), handle_message(), handle_output(), handle_response(), handle_show_sysinfo(), help1(), iax_parse_ies(), iax_str2flags(), launch_monitor_thread(), listener(), load_file(), local_call(), lpc10tolin_framein(), lws2sws(), message_template_parse_emailbody(), method_match(), mgcp_ss(), mgcpsock_read(), misdn_read(), monmp3thread(), mpeg4_encap(), newpvt(), parse_ie(), ParseBookmark(), pbx_substitute_variables_helper_full(), phoneprov_callback(), process_sdp(), read_credentials(), readfile_exec(), red_t140_to_red(), reschedule_precache(), run_agi(), scan_thread(), schedule_delivery(), set(), set_egress_subscription(), sip_addheader(), sip_show_channel(), sip_show_history(), skinny_ss(), sms_messagetx(), socket_process_meta(), socket_read(), static_callback(), term_filter_escapes(), transfer_exec(), try_firmware(), udptl_build_packet(), unistim_sp(), unquote(), wav_write(), and xmldoc_get_syntax_fun().
static int listfilter | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
struct ast_str ** | bufstr, | |||
ssize_t | len | |||
) | [static] |
Definition at line 562 of file func_strings.c.
References args, ast_alloca, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_get_encoded_str(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_append_substr(), ast_str_buffer(), ast_str_make_space(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), first, LOG_ERROR, and result_buf.
Referenced by listfilter_read(), and listfilter_read2().
00563 { 00564 AST_DECLARE_APP_ARGS(args, 00565 AST_APP_ARG(listname); 00566 AST_APP_ARG(delimiter); 00567 AST_APP_ARG(fieldvalue); 00568 ); 00569 struct ast_str *orig_list = ast_str_thread_get(&tmp_buf, 16); 00570 const char *begin, *cur, *next; 00571 int dlen, flen, first = 1; 00572 struct ast_str *result, **result_ptr = &result; 00573 char *delim, *varsubst; 00574 00575 AST_STANDARD_APP_ARGS(args, parse); 00576 00577 if (buf) { 00578 if (!(result = ast_str_thread_get(&result_buf, 16))) { 00579 return -1; 00580 } 00581 } else { 00582 /* Place the result directly into the output buffer */ 00583 result_ptr = bufstr; 00584 } 00585 00586 if (args.argc < 3) { 00587 ast_log(LOG_ERROR, "Usage: LISTFILTER(<listname>,<delimiter>,<fieldvalue>)\n"); 00588 return -1; 00589 } 00590 00591 varsubst = ast_alloca(strlen(args.listname) + 4); 00592 sprintf(varsubst, "${%s}", args.listname); 00593 00594 /* If we don't lock the channel, the variable could disappear out from underneath us. */ 00595 if (chan) { 00596 ast_channel_lock(chan); 00597 } 00598 ast_str_substitute_variables(&orig_list, 0, chan, varsubst); 00599 if (!ast_str_strlen(orig_list)) { 00600 ast_log(LOG_ERROR, "List variable '%s' not found\n", args.listname); 00601 if (chan) { 00602 ast_channel_unlock(chan); 00603 } 00604 return -1; 00605 } 00606 00607 /* If the string isn't there, just copy out the string and be done with it. */ 00608 if (!strstr(ast_str_buffer(orig_list), args.fieldvalue)) { 00609 if (buf) { 00610 ast_copy_string(buf, ast_str_buffer(orig_list), len); 00611 } else { 00612 ast_str_set(result_ptr, len, "%s", ast_str_buffer(orig_list)); 00613 } 00614 if (chan) { 00615 ast_channel_unlock(chan); 00616 } 00617 return 0; 00618 } 00619 00620 dlen = strlen(args.delimiter); 00621 delim = ast_alloca(dlen + 1); 00622 ast_get_encoded_str(args.delimiter, delim, dlen + 1); 00623 00624 if ((dlen = strlen(delim)) == 0) { 00625 delim = ","; 00626 dlen = 1; 00627 } 00628 00629 flen = strlen(args.fieldvalue); 00630 00631 ast_str_reset(*result_ptr); 00632 /* Enough space for any result */ 00633 if (len > -1) { 00634 ast_str_make_space(result_ptr, len ? len : ast_str_strlen(orig_list) + 1); 00635 } 00636 00637 begin = ast_str_buffer(orig_list); 00638 next = strstr(begin, delim); 00639 00640 do { 00641 /* Find next boundary */ 00642 if (next) { 00643 cur = next; 00644 next = strstr(cur + dlen, delim); 00645 } else { 00646 cur = strchr(begin + dlen, '\0'); 00647 } 00648 00649 if (flen == cur - begin && !strncmp(begin, args.fieldvalue, flen)) { 00650 /* Skip field */ 00651 begin += flen + dlen; 00652 } else { 00653 /* Copy field to output */ 00654 if (!first) { 00655 ast_str_append(result_ptr, len, "%s", delim); 00656 } 00657 00658 ast_str_append_substr(result_ptr, len, begin, cur - begin); 00659 first = 0; 00660 begin = cur + dlen; 00661 } 00662 } while (*cur != '\0'); 00663 if (chan) { 00664 ast_channel_unlock(chan); 00665 } 00666 00667 if (buf) { 00668 ast_copy_string(buf, ast_str_buffer(result), len); 00669 } 00670 00671 return 0; 00672 }
static int listfilter_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 674 of file func_strings.c.
References listfilter().
00675 { 00676 return listfilter(chan, cmd, parse, buf, NULL, len); 00677 }
static int listfilter_read2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 679 of file func_strings.c.
References listfilter().
00680 { 00681 return listfilter(chan, cmd, parse, NULL, buf, len); 00682 }
static int load_module | ( | void | ) | [static] |
Definition at line 1682 of file func_strings.c.
References ast_custom_function_register, ast_register_application_xml, AST_TEST_REGISTER, and exec_clearhash().
01683 { 01684 int res = 0; 01685 01686 AST_TEST_REGISTER(test_FIELDNUM); 01687 AST_TEST_REGISTER(test_FILTER); 01688 res |= ast_custom_function_register(&fieldqty_function); 01689 res |= ast_custom_function_register(&fieldnum_function); 01690 res |= ast_custom_function_register(&filter_function); 01691 res |= ast_custom_function_register(&replace_function); 01692 res |= ast_custom_function_register(&listfilter_function); 01693 res |= ast_custom_function_register(®ex_function); 01694 res |= ast_custom_function_register(&array_function); 01695 res |= ast_custom_function_register("e_function); 01696 res |= ast_custom_function_register(&csv_quote_function); 01697 res |= ast_custom_function_register(&len_function); 01698 res |= ast_custom_function_register(&strftime_function); 01699 res |= ast_custom_function_register(&strptime_function); 01700 res |= ast_custom_function_register(&eval_function); 01701 res |= ast_custom_function_register(&keypadhash_function); 01702 res |= ast_custom_function_register(&hashkeys_function); 01703 res |= ast_custom_function_register(&hash_function); 01704 res |= ast_register_application_xml(app_clearhash, exec_clearhash); 01705 res |= ast_custom_function_register(&toupper_function); 01706 res |= ast_custom_function_register(&tolower_function); 01707 res |= ast_custom_function_register(&shift_function); 01708 res |= ast_custom_function_register(&pop_function); 01709 res |= ast_custom_function_register(&push_function); 01710 res |= ast_custom_function_register(&unshift_function); 01711 res |= ast_custom_function_register(&passthru_function); 01712 01713 return res; 01714 }
static int passthru | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 1534 of file func_strings.c.
References ast_str_set().
01535 { 01536 ast_str_set(buf, len, "%s", data); 01537 return 0; 01538 }
static int quote | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1120 of file func_strings.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_ERROR, and LOG_WARNING.
Referenced by __ast_app_separate_args(), and parse_options().
01121 { 01122 char *bufptr = buf, *dataptr = data; 01123 01124 if (len < 3){ /* at least two for quotes and one for binary zero */ 01125 ast_log(LOG_ERROR, "Not enough buffer\n"); 01126 return -1; 01127 } 01128 01129 if (ast_strlen_zero(data)) { 01130 ast_log(LOG_WARNING, "No argument specified!\n"); 01131 ast_copy_string(buf, "\"\"", len); 01132 return 0; 01133 } 01134 01135 *bufptr++ = '"'; 01136 for (; bufptr < buf + len - 3; dataptr++) { 01137 if (*dataptr == '\\') { 01138 *bufptr++ = '\\'; 01139 *bufptr++ = '\\'; 01140 } else if (*dataptr == '"') { 01141 *bufptr++ = '\\'; 01142 *bufptr++ = '"'; 01143 } else if (*dataptr == '\0') { 01144 break; 01145 } else { 01146 *bufptr++ = *dataptr; 01147 } 01148 } 01149 *bufptr++ = '"'; 01150 *bufptr = '\0'; 01151 return 0; 01152 }
static int regex | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 841 of file func_strings.c.
References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, LOG_ERROR, LOG_WARNING, and str.
00843 { 00844 AST_DECLARE_APP_ARGS(args, 00845 AST_APP_ARG(null); 00846 AST_APP_ARG(reg); 00847 AST_APP_ARG(str); 00848 ); 00849 int errcode; 00850 regex_t regexbuf; 00851 00852 buf[0] = '\0'; 00853 00854 AST_NONSTANDARD_APP_ARGS(args, parse, '"'); 00855 00856 if (args.argc != 3) { 00857 ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n"); 00858 return -1; 00859 } 00860 if ((*args.str == ' ') || (*args.str == '\t')) 00861 args.str++; 00862 00863 ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str); 00864 00865 if ((errcode = regcomp(®exbuf, args.reg, REG_EXTENDED | REG_NOSUB))) { 00866 regerror(errcode, ®exbuf, buf, len); 00867 ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf); 00868 return -1; 00869 } 00870 00871 strcpy(buf, regexec(®exbuf, args.str, 0, NULL, 0) ? "0" : "1"); 00872 00873 regfree(®exbuf); 00874 00875 return 0; 00876 }
static int replace | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 771 of file func_strings.c.
References args, ast_alloca, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_get_encoded_str(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), LOG_ERROR, result_buf, and str.
Referenced by process_text_line().
00772 { 00773 AST_DECLARE_APP_ARGS(args, 00774 AST_APP_ARG(varname); 00775 AST_APP_ARG(find); 00776 AST_APP_ARG(replace); 00777 ); 00778 char *strptr, *varsubst; 00779 struct ast_str *str = ast_str_thread_get(&result_buf, 16); 00780 char find[256]; /* Only 256 characters possible */ 00781 char replace[2] = ""; 00782 size_t unused; 00783 00784 AST_STANDARD_APP_ARGS(args, data); 00785 00786 if (!str) { 00787 return -1; 00788 } 00789 00790 if (args.argc < 2) { 00791 ast_log(LOG_ERROR, "Usage: %s(<varname>,<search-chars>[,<replace-char>])\n", cmd); 00792 return -1; 00793 } 00794 00795 /* Decode escapes */ 00796 ast_get_encoded_str(args.find, find, sizeof(find)); 00797 ast_get_encoded_char(args.replace, replace, &unused); 00798 00799 if (ast_strlen_zero(find) || ast_strlen_zero(args.varname)) { 00800 ast_log(LOG_ERROR, "The characters to search for and the variable name must not be empty.\n"); 00801 return -1; 00802 } 00803 00804 varsubst = ast_alloca(strlen(args.varname) + 4); 00805 sprintf(varsubst, "${%s}", args.varname); 00806 ast_str_substitute_variables(&str, 0, chan, varsubst); 00807 00808 if (!ast_str_strlen(str)) { 00809 /* Blank, nothing to replace */ 00810 return -1; 00811 } 00812 00813 ast_debug(3, "String to search: (%s)\n", ast_str_buffer(str)); 00814 ast_debug(3, "Characters to find: (%s)\n", find); 00815 ast_debug(3, "Character to replace with: (%s)\n", replace); 00816 00817 for (strptr = ast_str_buffer(str); *strptr; strptr++) { 00818 /* buf is already a mutable buffer, so we construct the result 00819 * directly there */ 00820 if (strchr(find, *strptr)) { 00821 if (ast_strlen_zero(replace)) { 00822 /* Remove character */ 00823 strcpy(strptr, strptr + 1); /* SAFE */ 00824 strptr--; 00825 } else { 00826 /* Replace character */ 00827 *strptr = *replace; 00828 } 00829 } 00830 } 00831 00832 ast_str_set(buf, len, "%s", ast_str_buffer(str)); 00833 return 0; 00834 }
static int shift_pop | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 1418 of file func_strings.c.
References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), beginning, LOG_WARNING, pbx_builtin_setvar_helper(), result_buf, and var.
01419 { 01420 #define beginning (cmd[0] == 'S') /* SHIFT */ 01421 char *after, delimiter[2] = ",", *varsubst; 01422 size_t unused; 01423 struct ast_str *before = ast_str_thread_get(&result_buf, 16); 01424 char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr); 01425 AST_DECLARE_APP_ARGS(args, 01426 AST_APP_ARG(var); 01427 AST_APP_ARG(delimiter); 01428 ); 01429 01430 if (!before) { 01431 return -1; 01432 } 01433 01434 AST_STANDARD_APP_ARGS(args, data); 01435 01436 if (ast_strlen_zero(args.var)) { 01437 ast_log(LOG_WARNING, "%s requires a variable name\n", cmd); 01438 return -1; 01439 } 01440 01441 varsubst = ast_alloca(strlen(args.var) + 4); 01442 sprintf(varsubst, "${%s}", args.var); 01443 ast_str_substitute_variables(&before, 0, chan, varsubst); 01444 01445 if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) { 01446 ast_get_encoded_char(args.delimiter, delimiter, &unused); 01447 } 01448 01449 if (!ast_str_strlen(before)) { 01450 /* Nothing to pop */ 01451 return -1; 01452 } 01453 01454 if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) { 01455 /* Only one entry in array */ 01456 ast_str_set(buf, len, "%s", ast_str_buffer(before)); 01457 pbx_builtin_setvar_helper(chan, args.var, ""); 01458 } else { 01459 *after++ = '\0'; 01460 ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after); 01461 pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before)); 01462 } 01463 01464 return 0; 01465 #undef beginning 01466 }
static int string_tolower | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1389 of file func_strings.c.
static int string_tolower2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | buflen | |||
) | [static] |
Definition at line 1398 of file func_strings.c.
References ast_str_buffer(), ast_str_make_space(), ast_str_size(), and ast_str_update().
01399 { 01400 char *bufptr, *dataptr = data; 01401 01402 if (buflen > -1) { 01403 ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1); 01404 } 01405 bufptr = ast_str_buffer(*buf); 01406 while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++))); 01407 ast_str_update(*buf); 01408 01409 return 0; 01410 }
static int string_toupper | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1360 of file func_strings.c.
static int string_toupper2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | buflen | |||
) | [static] |
Definition at line 1369 of file func_strings.c.
References ast_str_buffer(), ast_str_make_space(), ast_str_size(), and ast_str_update().
01370 { 01371 char *bufptr, *dataptr = data; 01372 01373 if (buflen > -1) { 01374 ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1); 01375 } 01376 bufptr = ast_str_buffer(*buf); 01377 while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++))); 01378 ast_str_update(*buf); 01379 01380 return 0; 01381 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1648 of file func_strings.c.
References ast_custom_function_unregister(), AST_TEST_UNREGISTER, and ast_unregister_application().
01649 { 01650 int res = 0; 01651 01652 AST_TEST_UNREGISTER(test_FIELDNUM); 01653 AST_TEST_UNREGISTER(test_FILTER); 01654 res |= ast_custom_function_unregister(&fieldqty_function); 01655 res |= ast_custom_function_unregister(&fieldnum_function); 01656 res |= ast_custom_function_unregister(&filter_function); 01657 res |= ast_custom_function_unregister(&replace_function); 01658 res |= ast_custom_function_unregister(&listfilter_function); 01659 res |= ast_custom_function_unregister(®ex_function); 01660 res |= ast_custom_function_unregister(&array_function); 01661 res |= ast_custom_function_unregister("e_function); 01662 res |= ast_custom_function_unregister(&csv_quote_function); 01663 res |= ast_custom_function_unregister(&len_function); 01664 res |= ast_custom_function_unregister(&strftime_function); 01665 res |= ast_custom_function_unregister(&strptime_function); 01666 res |= ast_custom_function_unregister(&eval_function); 01667 res |= ast_custom_function_unregister(&keypadhash_function); 01668 res |= ast_custom_function_unregister(&hashkeys_function); 01669 res |= ast_custom_function_unregister(&hash_function); 01670 res |= ast_unregister_application(app_clearhash); 01671 res |= ast_custom_function_unregister(&toupper_function); 01672 res |= ast_custom_function_unregister(&tolower_function); 01673 res |= ast_custom_function_unregister(&shift_function); 01674 res |= ast_custom_function_unregister(&pop_function); 01675 res |= ast_custom_function_unregister(&push_function); 01676 res |= ast_custom_function_unregister(&unshift_function); 01677 res |= ast_custom_function_unregister(&passthru_function); 01678 01679 return res; 01680 }
static int unshift_push | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | new_value | |||
) | [static] |
Definition at line 1478 of file func_strings.c.
References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), beginning, LOG_WARNING, pbx_builtin_setvar_helper(), result_buf, and var.
01479 { 01480 #define beginning (cmd[0] == 'U') /* UNSHIFT */ 01481 char delimiter[2] = ",", *varsubst; 01482 size_t unused; 01483 struct ast_str *buf, *previous_value; 01484 AST_DECLARE_APP_ARGS(args, 01485 AST_APP_ARG(var); 01486 AST_APP_ARG(delimiter); 01487 ); 01488 01489 if (!(buf = ast_str_thread_get(&result_buf, 16)) || 01490 !(previous_value = ast_str_thread_get(&tmp_buf, 16))) { 01491 return -1; 01492 } 01493 01494 AST_STANDARD_APP_ARGS(args, data); 01495 01496 if (ast_strlen_zero(args.var)) { 01497 ast_log(LOG_WARNING, "%s requires a variable name\n", cmd); 01498 return -1; 01499 } 01500 01501 if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) { 01502 ast_get_encoded_char(args.delimiter, delimiter, &unused); 01503 } 01504 01505 varsubst = ast_alloca(strlen(args.var) + 4); 01506 sprintf(varsubst, "${%s}", args.var); 01507 ast_str_substitute_variables(&previous_value, 0, chan, varsubst); 01508 01509 if (!ast_str_strlen(previous_value)) { 01510 ast_str_set(&buf, 0, "%s", new_value); 01511 } else { 01512 ast_str_set(&buf, 0, "%s%c%s", 01513 beginning ? new_value : ast_str_buffer(previous_value), 01514 delimiter[0], 01515 beginning ? ast_str_buffer(previous_value) : new_value); 01516 } 01517 01518 pbx_builtin_setvar_helper(chan, args.var, ast_str_buffer(buf)); 01519 01520 return 0; 01521 #undef beginning 01522 }
char* app_clearhash = "ClearHash" [static] |
Definition at line 886 of file func_strings.c.
struct ast_custom_function array_function [static] |
{ .name = "ARRAY", .write = array, }
Definition at line 1115 of file func_strings.c.
struct ast_custom_function csv_quote_function [static] |
{ .name = "CSV_QUOTE", .read = csv_quote, }
Definition at line 1189 of file func_strings.c.
struct ast_custom_function eval_function [static] |
{ .name = "EVAL", .read = function_eval, .read2 = function_eval2, }
Definition at line 1314 of file func_strings.c.
struct ast_custom_function fieldnum_function [static] |
{ .name = "FIELDNUM", .read = function_fieldnum, .read2 = function_fieldnum_str, }
Definition at line 556 of file func_strings.c.
struct ast_custom_function fieldqty_function [static] |
{ .name = "FIELDQTY", .read = function_fieldqty, .read2 = function_fieldqty_str, }
Definition at line 477 of file func_strings.c.
struct ast_custom_function filter_function [static] |
{ .name = "FILTER", .read = filter, }
Definition at line 766 of file func_strings.c.
struct ast_custom_function hash_function [static] |
{ .name = "HASH", .write = hash_write, .read = hash_read, }
Definition at line 1103 of file func_strings.c.
struct ast_custom_function hashkeys_function [static] |
{ .name = "HASHKEYS", .read = hashkeys_read, .read2 = hashkeys_read2, }
Definition at line 1109 of file func_strings.c.
struct ast_custom_function keypadhash_function [static] |
{ .name = "KEYPADHASH", .read = keypadhash, }
Definition at line 1355 of file func_strings.c.
struct ast_custom_function len_function [static] |
{ .name = "LEN", .read = len, .read_max = 12, }
Definition at line 1206 of file func_strings.c.
struct ast_custom_function listfilter_function [static] |
{ .name = "LISTFILTER", .read = listfilter_read, .read2 = listfilter_read2, }
Definition at line 684 of file func_strings.c.
struct ast_custom_function passthru_function [static] |
{ .name = "PASSTHRU", .read2 = passthru, }
Definition at line 1540 of file func_strings.c.
struct ast_custom_function pop_function [static] |
{ .name = "POP", .read2 = shift_pop, }
Definition at line 1473 of file func_strings.c.
struct ast_custom_function push_function [static] |
{ .name = "PUSH", .write = unshift_push, }
Definition at line 1524 of file func_strings.c.
struct ast_custom_function quote_function [static] |
{ .name = "QUOTE", .read = quote, }
Definition at line 1154 of file func_strings.c.
struct ast_custom_function regex_function [static] |
{ .name = "REGEX", .read = regex, }
Definition at line 878 of file func_strings.c.
struct ast_custom_function replace_function [static] |
{ .name = "REPLACE", .read2 = replace, }
Definition at line 836 of file func_strings.c.
struct ast_custom_function shift_function [static] |
{ .name = "SHIFT", .read2 = shift_pop, }
Definition at line 1468 of file func_strings.c.
struct ast_custom_function strftime_function [static] |
{ .name = "STRFTIME", .read = acf_strftime, }
Definition at line 1241 of file func_strings.c.
struct ast_custom_function strptime_function [static] |
{ .name = "STRPTIME", .read = acf_strptime, }
Definition at line 1283 of file func_strings.c.
struct ast_custom_function tolower_function [static] |
{ .name = "TOLOWER", .read = string_tolower, .read2 = string_tolower2, }
Definition at line 1412 of file func_strings.c.
struct ast_custom_function toupper_function [static] |
{ .name = "TOUPPER", .read = string_toupper, .read2 = string_toupper2, }
Definition at line 1383 of file func_strings.c.
struct ast_custom_function unshift_function [static] |
{ .name = "UNSHIFT", .write = unshift_push, }
Definition at line 1529 of file func_strings.c.