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 887 of file func_strings.c.
Referenced by array(), hash_read(), and hash_write().
#define HASH_PREFIX "~HASH~%s~" |
Definition at line 886 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 1230 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.
01232 { 01233 AST_DECLARE_APP_ARGS(args, 01234 AST_APP_ARG(epoch); 01235 AST_APP_ARG(timezone); 01236 AST_APP_ARG(format); 01237 ); 01238 struct timeval when; 01239 struct ast_tm tm; 01240 01241 buf[0] = '\0'; 01242 01243 AST_STANDARD_APP_ARGS(args, parse); 01244 01245 ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL); 01246 ast_localtime(&when, &tm, args.timezone); 01247 01248 if (!args.format) 01249 args.format = "%c"; 01250 01251 if (ast_strftime(buf, buflen, args.format, &tm) <= 0) 01252 ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n"); 01253 01254 buf[buflen - 1] = '\0'; 01255 01256 return 0; 01257 }
static int acf_strptime | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1264 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.
01266 { 01267 AST_DECLARE_APP_ARGS(args, 01268 AST_APP_ARG(timestring); 01269 AST_APP_ARG(timezone); 01270 AST_APP_ARG(format); 01271 ); 01272 struct ast_tm tm; 01273 01274 buf[0] = '\0'; 01275 01276 if (!data) { 01277 ast_log(LOG_ERROR, 01278 "Asterisk function STRPTIME() requires an argument.\n"); 01279 return -1; 01280 } 01281 01282 AST_STANDARD_APP_ARGS(args, data); 01283 01284 if (ast_strlen_zero(args.format)) { 01285 ast_log(LOG_ERROR, 01286 "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)"); 01287 return -1; 01288 } 01289 01290 if (!ast_strptime(args.timestring, args.format, &tm)) { 01291 ast_log(LOG_WARNING, "STRPTIME() found no time specified within the string\n"); 01292 } else { 01293 struct timeval when; 01294 when = ast_mktime(&tm, args.timezone); 01295 snprintf(buf, buflen, "%d", (int) when.tv_sec); 01296 } 01297 01298 return 0; 01299 }
static int array | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 913 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().
00915 { 00916 AST_DECLARE_APP_ARGS(arg1, 00917 AST_APP_ARG(var)[100]; 00918 ); 00919 AST_DECLARE_APP_ARGS(arg2, 00920 AST_APP_ARG(val)[100]; 00921 ); 00922 char *origvar = "", *value2, varname[256]; 00923 int i, ishash = 0; 00924 00925 if (!var) { 00926 return -1; 00927 } 00928 value2 = ast_strdupa(value); 00929 00930 if (!strcmp(cmd, "HASH")) { 00931 const char *var2 = pbx_builtin_getvar_helper(chan, "~ODBCFIELDS~"); 00932 origvar = var; 00933 if (var2) 00934 var = ast_strdupa(var2); 00935 else { 00936 if (chan) 00937 ast_autoservice_stop(chan); 00938 return -1; 00939 } 00940 ishash = 1; 00941 } 00942 00943 /* The functions this will generally be used with are SORT and ODBC_*, which 00944 * both return comma-delimited lists. However, if somebody uses literal lists, 00945 * their commas will be translated to vertical bars by the load, and I don't 00946 * want them to be surprised by the result. Hence, we prefer commas as the 00947 * delimiter, but we'll fall back to vertical bars if commas aren't found. 00948 */ 00949 ast_debug(1, "array (%s=%s)\n", var, S_OR(value2, "")); 00950 AST_STANDARD_APP_ARGS(arg1, var); 00951 00952 AST_STANDARD_APP_ARGS(arg2, value2); 00953 00954 for (i = 0; i < arg1.argc; i++) { 00955 ast_debug(1, "array set value (%s=%s)\n", arg1.var[i], 00956 S_OR(arg2.val[i], "")); 00957 if (i < arg2.argc) { 00958 if (ishash) { 00959 if (origvar[0] == '_') { 00960 if (origvar[1] == '_') { 00961 snprintf(varname, sizeof(varname), "__" HASH_FORMAT, origvar + 2, arg1.var[i]); 00962 } else { 00963 snprintf(varname, sizeof(varname), "_" HASH_FORMAT, origvar + 1, arg1.var[i]); 00964 } 00965 } else { 00966 snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]); 00967 } 00968 00969 pbx_builtin_setvar_helper(chan, varname, arg2.val[i]); 00970 } else { 00971 pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]); 00972 } 00973 } else { 00974 /* We could unset the variable, by passing a NULL, but due to 00975 * pushvar semantics, that could create some undesired behavior. */ 00976 if (ishash) { 00977 snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]); 00978 pbx_builtin_setvar_helper(chan, varname, ""); 00979 } else { 00980 pbx_builtin_setvar_helper(chan, arg1.var[i], ""); 00981 } 00982 } 00983 } 00984 00985 return 0; 00986 }
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 892 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().
00893 { 00894 struct ast_var_t *var; 00895 int len = strlen(prefix); 00896 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->varshead, var, entries) { 00897 if (strncasecmp(prefix, ast_var_name(var), len) == 0) { 00898 AST_LIST_REMOVE_CURRENT(entries); 00899 ast_free(var); 00900 } 00901 } 00902 AST_LIST_TRAVERSE_SAFE_END 00903 }
static int csv_quote | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1177 of file func_strings.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and LOG_ERROR.
01178 { 01179 char *bufptr = buf, *dataptr = data; 01180 01181 if (len < 3) { /* at least two for quotes and one for binary zero */ 01182 ast_log(LOG_ERROR, "Not enough buffer\n"); 01183 return -1; 01184 } 01185 01186 if (ast_strlen_zero(data)) { 01187 ast_copy_string(buf, "\"\"", len); 01188 return 0; 01189 } 01190 01191 *bufptr++ = '"'; 01192 for (; bufptr < buf + len - 3; dataptr++){ 01193 if (*dataptr == '"') { 01194 *bufptr++ = '"'; 01195 *bufptr++ = '"'; 01196 } else if (*dataptr == '\0') { 01197 break; 01198 } else { 01199 *bufptr++ = *dataptr; 01200 } 01201 } 01202 *bufptr++ = '"'; 01203 *bufptr='\0'; 01204 return 0; 01205 }
static int exec_clearhash | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 905 of file func_strings.c.
References clearvar_prefix(), HASH_PREFIX, and prefix.
Referenced by load_module().
00906 { 00907 char prefix[80]; 00908 snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null"); 00909 clearvar_prefix(chan, prefix); 00910 return 0; 00911 }
static int filter | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 694 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().
00696 { 00697 AST_DECLARE_APP_ARGS(args, 00698 AST_APP_ARG(allowed); 00699 AST_APP_ARG(string); 00700 ); 00701 char *outbuf = buf; 00702 unsigned char ac; 00703 char allowed[256] = ""; 00704 size_t allowedlen = 0; 00705 int32_t bitfield[8] = { 0, }; /* 256 bits */ 00706 00707 AST_STANDARD_RAW_ARGS(args, parse); 00708 00709 if (!args.string) { 00710 ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n"); 00711 return -1; 00712 } 00713 00714 if (args.allowed[0] == '"' && !ast_opt_dont_warn) { 00715 ast_log(LOG_WARNING, "FILTER allowed characters includes the quote (\") character. This may not be what you want.\n"); 00716 } 00717 00718 /* Expand ranges */ 00719 for (; *(args.allowed);) { 00720 char c1 = 0, c2 = 0; 00721 size_t consumed = 0; 00722 00723 if (ast_get_encoded_char(args.allowed, &c1, &consumed)) 00724 return -1; 00725 args.allowed += consumed; 00726 00727 if (*(args.allowed) == '-') { 00728 if (ast_get_encoded_char(args.allowed + 1, &c2, &consumed)) 00729 c2 = c1; 00730 args.allowed += consumed + 1; 00731 00732 if ((unsigned char) c2 < (unsigned char) c1 && !ast_opt_dont_warn) { 00733 ast_log(LOG_WARNING, "Range wrapping in FILTER(%s,%s). This may not be what you want.\n", parse, args.string); 00734 } 00735 00736 /*!\note 00737 * Looks a little strange, until you realize that we can overflow 00738 * the size of a char. 00739 */ 00740 for (ac = (unsigned char) c1; ac != (unsigned char) c2; ac++) { 00741 bitfield[ac / 32] |= 1 << (ac % 32); 00742 } 00743 bitfield[ac / 32] |= 1 << (ac % 32); 00744 00745 ast_debug(4, "c1=%d, c2=%d\n", c1, c2); 00746 } else { 00747 ac = (unsigned char) c1; 00748 ast_debug(4, "c1=%d, consumed=%d, args.allowed=%s\n", c1, (int) consumed, args.allowed - consumed); 00749 bitfield[ac / 32] |= 1 << (ac % 32); 00750 } 00751 } 00752 00753 for (ac = 1; ac != 0; ac++) { 00754 if (bitfield[ac / 32] & (1 << (ac % 32))) { 00755 allowed[allowedlen++] = ac; 00756 } 00757 } 00758 00759 ast_debug(1, "Allowed: %s\n", allowed); 00760 00761 for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) { 00762 if (strchr(allowed, *(args.string))) 00763 *outbuf++ = *(args.string); 00764 } 00765 *outbuf = '\0'; 00766 00767 return 0; 00768 }
static int function_eval | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1306 of file func_strings.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_substitute_variables_helper().
01308 { 01309 if (ast_strlen_zero(data)) { 01310 ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n"); 01311 return -1; 01312 } 01313 01314 pbx_substitute_variables_helper(chan, data, buf, buflen - 1); 01315 01316 return 0; 01317 }
static int function_eval2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | buflen | |||
) | [static] |
Definition at line 1319 of file func_strings.c.
References ast_log(), ast_str_substitute_variables(), ast_strlen_zero(), and LOG_WARNING.
01321 { 01322 if (ast_strlen_zero(data)) { 01323 ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n"); 01324 return -1; 01325 } 01326 01327 ast_str_substitute_variables(buf, buflen, chan, data); 01328 01329 return 0; 01330 }
static int function_fieldnum | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 548 of file func_strings.c.
References function_fieldnum_helper().
00550 { 00551 return function_fieldnum_helper(chan, cmd, parse, buf, NULL, len); 00552 }
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 487 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().
00489 { 00490 char *varsubst, *field; 00491 struct ast_str *str = ast_str_thread_get(&result_buf, 16); 00492 int fieldindex = 0, res = 0; 00493 AST_DECLARE_APP_ARGS(args, 00494 AST_APP_ARG(varname); 00495 AST_APP_ARG(delim); 00496 AST_APP_ARG(field); 00497 ); 00498 char delim[2] = ""; 00499 size_t delim_used; 00500 00501 if (!str) { 00502 return -1; 00503 } 00504 00505 AST_STANDARD_APP_ARGS(args, parse); 00506 00507 if (args.argc < 3) { 00508 ast_log(LOG_ERROR, "Usage: FIELDNUM(<listname>,<delimiter>,<fieldvalue>)\n"); 00509 res = -1; 00510 } else { 00511 varsubst = ast_alloca(strlen(args.varname) + 4); 00512 sprintf(varsubst, "${%s}", args.varname); 00513 00514 ast_str_substitute_variables(&str, 0, chan, varsubst); 00515 00516 if (ast_str_strlen(str) == 0 || ast_strlen_zero(args.delim)) { 00517 fieldindex = 0; 00518 } else if (ast_get_encoded_char(args.delim, delim, &delim_used) == -1) { 00519 res = -1; 00520 } else { 00521 char *varval = ast_str_buffer(str); 00522 00523 while ((field = strsep(&varval, delim)) != NULL) { 00524 fieldindex++; 00525 00526 if (!strcasecmp(field, args.field)) { 00527 break; 00528 } 00529 } 00530 00531 if (!field) { 00532 fieldindex = 0; 00533 } 00534 00535 res = 0; 00536 } 00537 } 00538 00539 if (sbuf) { 00540 ast_str_set(sbuf, len, "%d", fieldindex); 00541 } else { 00542 snprintf(buf, len, "%d", fieldindex); 00543 } 00544 00545 return res; 00546 }
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 554 of file func_strings.c.
References function_fieldnum_helper().
00556 { 00557 return function_fieldnum_helper(chan, cmd, parse, NULL, buf, len); 00558 }
static int function_fieldqty | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 469 of file func_strings.c.
References function_fieldqty_helper().
00471 { 00472 return function_fieldqty_helper(chan, cmd, parse, buf, NULL, len); 00473 }
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 424 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().
00426 { 00427 char *varsubst; 00428 struct ast_str *str = ast_str_thread_get(&result_buf, 16); 00429 int fieldcount = 0; 00430 AST_DECLARE_APP_ARGS(args, 00431 AST_APP_ARG(varname); 00432 AST_APP_ARG(delim); 00433 ); 00434 char delim[2] = ""; 00435 size_t delim_used; 00436 00437 if (!str) { 00438 return -1; 00439 } 00440 00441 AST_STANDARD_APP_ARGS(args, parse); 00442 if (args.delim) { 00443 ast_get_encoded_char(args.delim, delim, &delim_used); 00444 00445 varsubst = ast_alloca(strlen(args.varname) + 4); 00446 00447 sprintf(varsubst, "${%s}", args.varname); 00448 ast_str_substitute_variables(&str, 0, chan, varsubst); 00449 if (ast_str_strlen(str) == 0) { 00450 fieldcount = 0; 00451 } else { 00452 char *varval = ast_str_buffer(str); 00453 while (strsep(&varval, delim)) { 00454 fieldcount++; 00455 } 00456 } 00457 } else { 00458 fieldcount = 1; 00459 } 00460 if (sbuf) { 00461 ast_str_set(sbuf, len, "%d", fieldcount); 00462 } else { 00463 snprintf(buf, len, "%d", fieldcount); 00464 } 00465 00466 return 0; 00467 }
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 475 of file func_strings.c.
References function_fieldqty_helper().
00477 { 00478 return function_fieldqty_helper(chan, cmd, parse, NULL, buf, len); 00479 }
static int hash_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1070 of file func_strings.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, HASH_FORMAT, hashkeys_read(), LOG_WARNING, pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().
01071 { 01072 char varname[256]; 01073 const char *varvalue; 01074 AST_DECLARE_APP_ARGS(arg, 01075 AST_APP_ARG(hashname); 01076 AST_APP_ARG(hashkey); 01077 ); 01078 01079 AST_STANDARD_APP_ARGS(arg, data); 01080 if (arg.argc == 2) { 01081 snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey); 01082 varvalue = pbx_builtin_getvar_helper(chan, varname); 01083 if (varvalue) 01084 ast_copy_string(buf, varvalue, len); 01085 else 01086 *buf = '\0'; 01087 } else if (arg.argc == 1) { 01088 char colnames[4096]; 01089 int i; 01090 AST_DECLARE_APP_ARGS(arg2, 01091 AST_APP_ARG(col)[100]; 01092 ); 01093 01094 if (!chan) { 01095 ast_log(LOG_WARNING, "No channel and only 1 parameter was provided to %s function.\n", cmd); 01096 return -1; 01097 } 01098 01099 /* Get column names, in no particular order */ 01100 hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames)); 01101 pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames); 01102 01103 AST_STANDARD_APP_ARGS(arg2, colnames); 01104 *buf = '\0'; 01105 01106 /* Now get the corresponding column values, in exactly the same order */ 01107 for (i = 0; i < arg2.argc; i++) { 01108 snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]); 01109 varvalue = pbx_builtin_getvar_helper(chan, varname); 01110 strncat(buf, varvalue, len - strlen(buf) - 1); 01111 strncat(buf, ",", len - strlen(buf) - 1); 01112 } 01113 01114 /* Strip trailing comma */ 01115 buf[strlen(buf) - 1] = '\0'; 01116 } 01117 01118 return 0; 01119 }
static int hash_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 1042 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().
01043 { 01044 char varname[256]; 01045 AST_DECLARE_APP_ARGS(arg, 01046 AST_APP_ARG(hashname); 01047 AST_APP_ARG(hashkey); 01048 ); 01049 01050 if (!strchr(var, ',')) { 01051 /* Single argument version */ 01052 return array(chan, "HASH", var, value); 01053 } 01054 01055 AST_STANDARD_APP_ARGS(arg, var); 01056 if (arg.hashname[0] == '_') { 01057 if (arg.hashname[1] == '_') { 01058 snprintf(varname, sizeof(varname), "__" HASH_FORMAT, arg.hashname + 2, arg.hashkey); 01059 } else { 01060 snprintf(varname, sizeof(varname), "_" HASH_FORMAT, arg.hashname + 1, arg.hashkey); 01061 } 01062 } else { 01063 snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey); 01064 } 01065 pbx_builtin_setvar_helper(chan, varname, value); 01066 01067 return 0; 01068 }
static int hashkeys_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 988 of file func_strings.c.
References AST_LIST_TRAVERSE, ast_log(), ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, LOG_WARNING, prefix, and ast_channel::varshead.
Referenced by hash_read().
00989 { 00990 struct ast_var_t *newvar; 00991 struct ast_str *prefix = ast_str_alloca(80); 00992 00993 if (!chan) { 00994 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 00995 return -1; 00996 } 00997 00998 ast_str_set(&prefix, -1, HASH_PREFIX, data); 00999 memset(buf, 0, len); 01000 01001 AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) { 01002 if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) { 01003 /* Copy everything after the prefix */ 01004 strncat(buf, ast_var_name(newvar) + ast_str_strlen(prefix), len - strlen(buf) - 1); 01005 /* Trim the trailing ~ */ 01006 buf[strlen(buf) - 1] = ','; 01007 } 01008 } 01009 /* Trim the trailing comma */ 01010 buf[strlen(buf) - 1] = '\0'; 01011 return 0; 01012 }
static int hashkeys_read2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 1014 of file func_strings.c.
References AST_LIST_TRAVERSE, ast_log(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, LOG_WARNING, prefix, and ast_channel::varshead.
01015 { 01016 struct ast_var_t *newvar; 01017 struct ast_str *prefix = ast_str_alloca(80); 01018 char *tmp; 01019 01020 if (!chan) { 01021 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 01022 return -1; 01023 } 01024 01025 ast_str_set(&prefix, -1, HASH_PREFIX, data); 01026 01027 AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) { 01028 if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) { 01029 /* Copy everything after the prefix */ 01030 ast_str_append(buf, len, "%s", ast_var_name(newvar) + ast_str_strlen(prefix)); 01031 /* Trim the trailing ~ */ 01032 tmp = ast_str_buffer(*buf); 01033 tmp[ast_str_strlen(*buf) - 1] = ','; 01034 } 01035 } 01036 /* Trim the trailing comma */ 01037 tmp = ast_str_buffer(*buf); 01038 tmp[ast_str_strlen(*buf) - 1] = '\0'; 01039 return 0; 01040 }
static int keypadhash | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1338 of file func_strings.c.
01339 { 01340 char *bufptr, *dataptr; 01341 01342 for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) { 01343 if (*dataptr == '\0') { 01344 *bufptr++ = '\0'; 01345 break; 01346 } else if (*dataptr == '1') { 01347 *bufptr++ = '1'; 01348 } else if (strchr("AaBbCc2", *dataptr)) { 01349 *bufptr++ = '2'; 01350 } else if (strchr("DdEeFf3", *dataptr)) { 01351 *bufptr++ = '3'; 01352 } else if (strchr("GgHhIi4", *dataptr)) { 01353 *bufptr++ = '4'; 01354 } else if (strchr("JjKkLl5", *dataptr)) { 01355 *bufptr++ = '5'; 01356 } else if (strchr("MmNnOo6", *dataptr)) { 01357 *bufptr++ = '6'; 01358 } else if (strchr("PpQqRrSs7", *dataptr)) { 01359 *bufptr++ = '7'; 01360 } else if (strchr("TtUuVv8", *dataptr)) { 01361 *bufptr++ = '8'; 01362 } else if (strchr("WwXxYyZz9", *dataptr)) { 01363 *bufptr++ = '9'; 01364 } else if (*dataptr == '0') { 01365 *bufptr++ = '0'; 01366 } 01367 } 01368 buf[buflen - 1] = '\0'; 01369 01370 return 0; 01371 }
static int len | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1212 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(), expand_gosub_args(), 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 566 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().
00567 { 00568 AST_DECLARE_APP_ARGS(args, 00569 AST_APP_ARG(listname); 00570 AST_APP_ARG(delimiter); 00571 AST_APP_ARG(fieldvalue); 00572 ); 00573 struct ast_str *orig_list = ast_str_thread_get(&tmp_buf, 16); 00574 const char *begin, *cur, *next; 00575 int dlen, flen, first = 1; 00576 struct ast_str *result, **result_ptr = &result; 00577 char *delim, *varsubst; 00578 00579 AST_STANDARD_APP_ARGS(args, parse); 00580 00581 if (buf) { 00582 if (!(result = ast_str_thread_get(&result_buf, 16))) { 00583 return -1; 00584 } 00585 } else { 00586 /* Place the result directly into the output buffer */ 00587 result_ptr = bufstr; 00588 } 00589 00590 if (args.argc < 3) { 00591 ast_log(LOG_ERROR, "Usage: LISTFILTER(<listname>,<delimiter>,<fieldvalue>)\n"); 00592 return -1; 00593 } 00594 00595 varsubst = ast_alloca(strlen(args.listname) + 4); 00596 sprintf(varsubst, "${%s}", args.listname); 00597 00598 /* If we don't lock the channel, the variable could disappear out from underneath us. */ 00599 if (chan) { 00600 ast_channel_lock(chan); 00601 } 00602 ast_str_substitute_variables(&orig_list, 0, chan, varsubst); 00603 if (!ast_str_strlen(orig_list)) { 00604 ast_log(LOG_ERROR, "List variable '%s' not found\n", args.listname); 00605 if (chan) { 00606 ast_channel_unlock(chan); 00607 } 00608 return -1; 00609 } 00610 00611 /* If the string isn't there, just copy out the string and be done with it. */ 00612 if (!strstr(ast_str_buffer(orig_list), args.fieldvalue)) { 00613 if (buf) { 00614 ast_copy_string(buf, ast_str_buffer(orig_list), len); 00615 } else { 00616 ast_str_set(result_ptr, len, "%s", ast_str_buffer(orig_list)); 00617 } 00618 if (chan) { 00619 ast_channel_unlock(chan); 00620 } 00621 return 0; 00622 } 00623 00624 dlen = strlen(args.delimiter); 00625 delim = ast_alloca(dlen + 1); 00626 ast_get_encoded_str(args.delimiter, delim, dlen + 1); 00627 00628 if ((dlen = strlen(delim)) == 0) { 00629 delim = ","; 00630 dlen = 1; 00631 } 00632 00633 flen = strlen(args.fieldvalue); 00634 00635 ast_str_reset(*result_ptr); 00636 /* Enough space for any result */ 00637 if (len > -1) { 00638 ast_str_make_space(result_ptr, len ? len : ast_str_strlen(orig_list) + 1); 00639 } 00640 00641 begin = ast_str_buffer(orig_list); 00642 next = strstr(begin, delim); 00643 00644 do { 00645 /* Find next boundary */ 00646 if (next) { 00647 cur = next; 00648 next = strstr(cur + dlen, delim); 00649 } else { 00650 cur = strchr(begin + dlen, '\0'); 00651 } 00652 00653 if (flen == cur - begin && !strncmp(begin, args.fieldvalue, flen)) { 00654 /* Skip field */ 00655 begin += flen + dlen; 00656 } else { 00657 /* Copy field to output */ 00658 if (!first) { 00659 ast_str_append(result_ptr, len, "%s", delim); 00660 } 00661 00662 ast_str_append_substr(result_ptr, len, begin, cur - begin); 00663 first = 0; 00664 begin = cur + dlen; 00665 } 00666 } while (*cur != '\0'); 00667 if (chan) { 00668 ast_channel_unlock(chan); 00669 } 00670 00671 if (buf) { 00672 ast_copy_string(buf, ast_str_buffer(result), len); 00673 } 00674 00675 return 0; 00676 }
static int listfilter_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 678 of file func_strings.c.
References listfilter().
00679 { 00680 return listfilter(chan, cmd, parse, buf, NULL, len); 00681 }
static int listfilter_read2 | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 683 of file func_strings.c.
References listfilter().
00684 { 00685 return listfilter(chan, cmd, parse, NULL, buf, len); 00686 }
static int load_module | ( | void | ) | [static] |
Definition at line 1785 of file func_strings.c.
References ast_custom_function_register, ast_register_application_xml, AST_TEST_REGISTER, and exec_clearhash().
01786 { 01787 int res = 0; 01788 01789 AST_TEST_REGISTER(test_FIELDNUM); 01790 AST_TEST_REGISTER(test_REPLACE); 01791 AST_TEST_REGISTER(test_FILTER); 01792 res |= ast_custom_function_register(&fieldqty_function); 01793 res |= ast_custom_function_register(&fieldnum_function); 01794 res |= ast_custom_function_register(&filter_function); 01795 res |= ast_custom_function_register(&replace_function); 01796 res |= ast_custom_function_register(&listfilter_function); 01797 res |= ast_custom_function_register(®ex_function); 01798 res |= ast_custom_function_register(&array_function); 01799 res |= ast_custom_function_register("e_function); 01800 res |= ast_custom_function_register(&csv_quote_function); 01801 res |= ast_custom_function_register(&len_function); 01802 res |= ast_custom_function_register(&strftime_function); 01803 res |= ast_custom_function_register(&strptime_function); 01804 res |= ast_custom_function_register(&eval_function); 01805 res |= ast_custom_function_register(&keypadhash_function); 01806 res |= ast_custom_function_register(&hashkeys_function); 01807 res |= ast_custom_function_register(&hash_function); 01808 res |= ast_register_application_xml(app_clearhash, exec_clearhash); 01809 res |= ast_custom_function_register(&toupper_function); 01810 res |= ast_custom_function_register(&tolower_function); 01811 res |= ast_custom_function_register(&shift_function); 01812 res |= ast_custom_function_register(&pop_function); 01813 res |= ast_custom_function_register(&push_function); 01814 res |= ast_custom_function_register(&unshift_function); 01815 res |= ast_custom_function_register(&passthru_function); 01816 01817 return res; 01818 }
static int passthru | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 1560 of file func_strings.c.
References ast_str_set().
01561 { 01562 ast_str_set(buf, len, "%s", data); 01563 return 0; 01564 }
static int quote | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1138 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().
01139 { 01140 char *bufptr = buf, *dataptr = data; 01141 01142 if (len < 3){ /* at least two for quotes and one for binary zero */ 01143 ast_log(LOG_ERROR, "Not enough buffer\n"); 01144 return -1; 01145 } 01146 01147 if (ast_strlen_zero(data)) { 01148 ast_log(LOG_WARNING, "No argument specified!\n"); 01149 ast_copy_string(buf, "\"\"", len); 01150 return 0; 01151 } 01152 01153 *bufptr++ = '"'; 01154 for (; bufptr < buf + len - 3; dataptr++) { 01155 if (*dataptr == '\\') { 01156 *bufptr++ = '\\'; 01157 *bufptr++ = '\\'; 01158 } else if (*dataptr == '"') { 01159 *bufptr++ = '\\'; 01160 *bufptr++ = '"'; 01161 } else if (*dataptr == '\0') { 01162 break; 01163 } else { 01164 *bufptr++ = *dataptr; 01165 } 01166 } 01167 *bufptr++ = '"'; 01168 *bufptr = '\0'; 01169 return 0; 01170 }
static int regex | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 844 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.
00846 { 00847 AST_DECLARE_APP_ARGS(args, 00848 AST_APP_ARG(null); 00849 AST_APP_ARG(reg); 00850 AST_APP_ARG(str); 00851 ); 00852 int errcode; 00853 regex_t regexbuf; 00854 00855 buf[0] = '\0'; 00856 00857 AST_NONSTANDARD_APP_ARGS(args, parse, '"'); 00858 00859 if (args.argc != 3) { 00860 ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n"); 00861 return -1; 00862 } 00863 if ((*args.str == ' ') || (*args.str == '\t')) 00864 args.str++; 00865 00866 ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str); 00867 00868 if ((errcode = regcomp(®exbuf, args.reg, REG_EXTENDED | REG_NOSUB))) { 00869 regerror(errcode, ®exbuf, buf, len); 00870 ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf); 00871 return -1; 00872 } 00873 00874 strcpy(buf, regexec(®exbuf, args.str, 0, NULL, 0) ? "0" : "1"); 00875 00876 regfree(®exbuf); 00877 00878 return 0; 00879 }
static int replace | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 775 of file func_strings.c.
References args, ast_alloca, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_get_encoded_char(), ast_get_encoded_str(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_strlen_zero(), LOG_ERROR, RAII_VAR, and str.
Referenced by process_text_line().
00776 { 00777 AST_DECLARE_APP_ARGS(args, 00778 AST_APP_ARG(varname); 00779 AST_APP_ARG(find); 00780 AST_APP_ARG(replace); 00781 ); 00782 char *strptr, *varsubst; 00783 RAII_VAR(struct ast_str *, str, ast_str_create(16), ast_free); 00784 char find[256]; /* Only 256 characters possible */ 00785 char replace[2] = ""; 00786 size_t unused; 00787 00788 AST_STANDARD_APP_ARGS(args, data); 00789 00790 if (!str) { 00791 return -1; 00792 } 00793 00794 if (args.argc < 2) { 00795 ast_log(LOG_ERROR, "Usage: %s(<varname>,<search-chars>[,<replace-char>])\n", cmd); 00796 return -1; 00797 } 00798 00799 /* Decode escapes */ 00800 ast_get_encoded_str(args.find, find, sizeof(find)); 00801 ast_get_encoded_char(args.replace, replace, &unused); 00802 00803 if (ast_strlen_zero(find) || ast_strlen_zero(args.varname)) { 00804 ast_log(LOG_ERROR, "The characters to search for and the variable name must not be empty.\n"); 00805 return -1; 00806 } 00807 00808 varsubst = ast_alloca(strlen(args.varname) + 4); 00809 sprintf(varsubst, "${%s}", args.varname); 00810 ast_str_substitute_variables(&str, 0, chan, varsubst); 00811 00812 if (!ast_str_strlen(str)) { 00813 /* Blank, nothing to replace */ 00814 return -1; 00815 } 00816 00817 ast_debug(3, "String to search: (%s)\n", ast_str_buffer(str)); 00818 ast_debug(3, "Characters to find: (%s)\n", find); 00819 ast_debug(3, "Character to replace with: (%s)\n", replace); 00820 00821 for (strptr = ast_str_buffer(str); *strptr; strptr++) { 00822 /* buf is already a mutable buffer, so we construct the result 00823 * directly there */ 00824 if (strchr(find, *strptr)) { 00825 if (ast_strlen_zero(replace)) { 00826 memmove(strptr, strptr + 1, strlen(strptr + 1) + 1); 00827 strptr--; 00828 } else { 00829 /* Replace character */ 00830 *strptr = *replace; 00831 } 00832 } 00833 } 00834 00835 ast_str_set(buf, len, "%s", ast_str_buffer(str)); 00836 return 0; 00837 }
static int shift_pop | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 1436 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.
01437 { 01438 #define beginning (cmd[0] == 'S') /* SHIFT */ 01439 char *after, delimiter[2] = ",", *varsubst; 01440 size_t unused; 01441 struct ast_str *before = ast_str_thread_get(&result_buf, 16); 01442 char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr); 01443 AST_DECLARE_APP_ARGS(args, 01444 AST_APP_ARG(var); 01445 AST_APP_ARG(delimiter); 01446 ); 01447 01448 if (!before) { 01449 return -1; 01450 } 01451 01452 AST_STANDARD_APP_ARGS(args, data); 01453 01454 if (ast_strlen_zero(args.var)) { 01455 ast_log(LOG_WARNING, "%s requires a variable name\n", cmd); 01456 return -1; 01457 } 01458 01459 varsubst = ast_alloca(strlen(args.var) + 4); 01460 sprintf(varsubst, "${%s}", args.var); 01461 ast_str_substitute_variables(&before, 0, chan, varsubst); 01462 01463 if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) { 01464 ast_get_encoded_char(args.delimiter, delimiter, &unused); 01465 } 01466 01467 if (!ast_str_strlen(before)) { 01468 /* Nothing to pop */ 01469 return -1; 01470 } 01471 01472 if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) { 01473 /* Only one entry in array */ 01474 ast_str_set(buf, len, "%s", ast_str_buffer(before)); 01475 pbx_builtin_setvar_helper(chan, args.var, ""); 01476 } else { 01477 *after++ = '\0'; 01478 ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after); 01479 pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before)); 01480 } 01481 01482 return 0; 01483 #undef beginning 01484 }
static int string_tolower | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1407 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 1416 of file func_strings.c.
References ast_str_buffer(), ast_str_make_space(), ast_str_size(), and ast_str_update().
01417 { 01418 char *bufptr, *dataptr = data; 01419 01420 if (buflen > -1) { 01421 ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1); 01422 } 01423 bufptr = ast_str_buffer(*buf); 01424 while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++))); 01425 ast_str_update(*buf); 01426 01427 return 0; 01428 }
static int string_toupper | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 1378 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 1387 of file func_strings.c.
References ast_str_buffer(), ast_str_make_space(), ast_str_size(), and ast_str_update().
01388 { 01389 char *bufptr, *dataptr = data; 01390 01391 if (buflen > -1) { 01392 ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1); 01393 } 01394 bufptr = ast_str_buffer(*buf); 01395 while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++))); 01396 ast_str_update(*buf); 01397 01398 return 0; 01399 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1750 of file func_strings.c.
References ast_custom_function_unregister(), AST_TEST_UNREGISTER, and ast_unregister_application().
01751 { 01752 int res = 0; 01753 01754 AST_TEST_UNREGISTER(test_FIELDNUM); 01755 AST_TEST_UNREGISTER(test_REPLACE); 01756 AST_TEST_UNREGISTER(test_FILTER); 01757 res |= ast_custom_function_unregister(&fieldqty_function); 01758 res |= ast_custom_function_unregister(&fieldnum_function); 01759 res |= ast_custom_function_unregister(&filter_function); 01760 res |= ast_custom_function_unregister(&replace_function); 01761 res |= ast_custom_function_unregister(&listfilter_function); 01762 res |= ast_custom_function_unregister(®ex_function); 01763 res |= ast_custom_function_unregister(&array_function); 01764 res |= ast_custom_function_unregister("e_function); 01765 res |= ast_custom_function_unregister(&csv_quote_function); 01766 res |= ast_custom_function_unregister(&len_function); 01767 res |= ast_custom_function_unregister(&strftime_function); 01768 res |= ast_custom_function_unregister(&strptime_function); 01769 res |= ast_custom_function_unregister(&eval_function); 01770 res |= ast_custom_function_unregister(&keypadhash_function); 01771 res |= ast_custom_function_unregister(&hashkeys_function); 01772 res |= ast_custom_function_unregister(&hash_function); 01773 res |= ast_unregister_application(app_clearhash); 01774 res |= ast_custom_function_unregister(&toupper_function); 01775 res |= ast_custom_function_unregister(&tolower_function); 01776 res |= ast_custom_function_unregister(&shift_function); 01777 res |= ast_custom_function_unregister(&pop_function); 01778 res |= ast_custom_function_unregister(&push_function); 01779 res |= ast_custom_function_unregister(&unshift_function); 01780 res |= ast_custom_function_unregister(&passthru_function); 01781 01782 return res; 01783 }
static int unshift_push | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | new_value | |||
) | [static] |
Definition at line 1496 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, MIN, pbx_builtin_setvar_helper(), result_buf, and var.
01497 { 01498 #define beginning (cmd[0] == 'U') /* UNSHIFT */ 01499 char delimiter[2] = ",", *varsubst; 01500 size_t unused; 01501 struct ast_str *buf, *previous_value; 01502 AST_DECLARE_APP_ARGS(args, 01503 AST_APP_ARG(var); 01504 AST_APP_ARG(delimiter); 01505 ); 01506 const char *stripped_var; 01507 01508 if (!(buf = ast_str_thread_get(&result_buf, 16)) || 01509 !(previous_value = ast_str_thread_get(&tmp_buf, 16))) { 01510 return -1; 01511 } 01512 01513 AST_STANDARD_APP_ARGS(args, data); 01514 01515 if (ast_strlen_zero(args.var)) { 01516 ast_log(LOG_WARNING, "%s requires a variable name\n", cmd); 01517 return -1; 01518 } 01519 01520 if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) { 01521 ast_get_encoded_char(args.delimiter, delimiter, &unused); 01522 } 01523 01524 /* UNSHIFT and PUSH act as ways of setting a variable, so we need to be 01525 * sure to skip leading underscores if they appear. However, we only want 01526 * to skip up to two since that is the maximum number that can be used to 01527 * indicate variable inheritance. Any further underscores are part of the 01528 * variable name. 01529 */ 01530 stripped_var = args.var + MIN(strspn(args.var, "_"), 2); 01531 varsubst = ast_alloca(strlen(stripped_var) + 4); 01532 sprintf(varsubst, "${%s}", stripped_var); 01533 ast_str_substitute_variables(&previous_value, 0, chan, varsubst); 01534 01535 if (!ast_str_strlen(previous_value)) { 01536 ast_str_set(&buf, 0, "%s", new_value); 01537 } else { 01538 ast_str_set(&buf, 0, "%s%c%s", 01539 beginning ? new_value : ast_str_buffer(previous_value), 01540 delimiter[0], 01541 beginning ? ast_str_buffer(previous_value) : new_value); 01542 } 01543 01544 pbx_builtin_setvar_helper(chan, args.var, ast_str_buffer(buf)); 01545 01546 return 0; 01547 #undef beginning 01548 }
char* app_clearhash = "ClearHash" [static] |
Definition at line 889 of file func_strings.c.
struct ast_custom_function array_function [static] |
{ .name = "ARRAY", .write = array, }
Definition at line 1133 of file func_strings.c.
struct ast_custom_function csv_quote_function [static] |
{ .name = "CSV_QUOTE", .read = csv_quote, }
Definition at line 1207 of file func_strings.c.
struct ast_custom_function eval_function [static] |
{ .name = "EVAL", .read = function_eval, .read2 = function_eval2, }
Definition at line 1332 of file func_strings.c.
struct ast_custom_function fieldnum_function [static] |
{ .name = "FIELDNUM", .read = function_fieldnum, .read2 = function_fieldnum_str, }
Definition at line 560 of file func_strings.c.
struct ast_custom_function fieldqty_function [static] |
{ .name = "FIELDQTY", .read = function_fieldqty, .read2 = function_fieldqty_str, }
Definition at line 481 of file func_strings.c.
struct ast_custom_function filter_function [static] |
{ .name = "FILTER", .read = filter, }
Definition at line 770 of file func_strings.c.
struct ast_custom_function hash_function [static] |
{ .name = "HASH", .write = hash_write, .read = hash_read, }
Definition at line 1121 of file func_strings.c.
struct ast_custom_function hashkeys_function [static] |
{ .name = "HASHKEYS", .read = hashkeys_read, .read2 = hashkeys_read2, }
Definition at line 1127 of file func_strings.c.
struct ast_custom_function keypadhash_function [static] |
{ .name = "KEYPADHASH", .read = keypadhash, }
Definition at line 1373 of file func_strings.c.
struct ast_custom_function len_function [static] |
{ .name = "LEN", .read = len, .read_max = 12, }
Definition at line 1224 of file func_strings.c.
struct ast_custom_function listfilter_function [static] |
{ .name = "LISTFILTER", .read = listfilter_read, .read2 = listfilter_read2, }
Definition at line 688 of file func_strings.c.
struct ast_custom_function passthru_function [static] |
{ .name = "PASSTHRU", .read2 = passthru, }
Definition at line 1566 of file func_strings.c.
struct ast_custom_function pop_function [static] |
{ .name = "POP", .read2 = shift_pop, }
Definition at line 1491 of file func_strings.c.
struct ast_custom_function push_function [static] |
{ .name = "PUSH", .write = unshift_push, }
Definition at line 1550 of file func_strings.c.
struct ast_custom_function quote_function [static] |
{ .name = "QUOTE", .read = quote, }
Definition at line 1172 of file func_strings.c.
struct ast_custom_function regex_function [static] |
{ .name = "REGEX", .read = regex, }
Definition at line 881 of file func_strings.c.
struct ast_custom_function replace_function [static] |
{ .name = "REPLACE", .read2 = replace, }
Definition at line 839 of file func_strings.c.
struct ast_custom_function shift_function [static] |
{ .name = "SHIFT", .read2 = shift_pop, }
Definition at line 1486 of file func_strings.c.
struct ast_custom_function strftime_function [static] |
{ .name = "STRFTIME", .read = acf_strftime, }
Definition at line 1259 of file func_strings.c.
struct ast_custom_function strptime_function [static] |
{ .name = "STRPTIME", .read = acf_strptime, }
Definition at line 1301 of file func_strings.c.
struct ast_custom_function tolower_function [static] |
{ .name = "TOLOWER", .read = string_tolower, .read2 = string_tolower2, }
Definition at line 1430 of file func_strings.c.
struct ast_custom_function toupper_function [static] |
{ .name = "TOUPPER", .read = string_toupper, .read2 = string_toupper2, }
Definition at line 1401 of file func_strings.c.
struct ast_custom_function unshift_function [static] |
{ .name = "UNSHIFT", .write = unshift_push, }
Definition at line 1555 of file func_strings.c.