Thu Apr 3 08:21:59 2014

Asterisk developer's documentation


func_strings.c File Reference

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"
Include dependency graph for func_strings.c:

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

Detailed Description

String manipulation dialplan functions.

Author:
Tilghman Lesher
Anothony Minessale II

Definition in file func_strings.c.


Define Documentation

#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().


Function Documentation

static int acf_strftime ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
size_t  buflen 
) [static]

Definition at line 1215 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.

01217 {
01218    AST_DECLARE_APP_ARGS(args,
01219               AST_APP_ARG(epoch);
01220               AST_APP_ARG(timezone);
01221               AST_APP_ARG(format);
01222    );
01223    struct timeval when;
01224    struct ast_tm tm;
01225 
01226    buf[0] = '\0';
01227 
01228    AST_STANDARD_APP_ARGS(args, parse);
01229 
01230    ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL);
01231    ast_localtime(&when, &tm, args.timezone);
01232 
01233    if (!args.format)
01234       args.format = "%c";
01235 
01236    if (ast_strftime(buf, buflen, args.format, &tm) <= 0)
01237       ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
01238 
01239    buf[buflen - 1] = '\0';
01240 
01241    return 0;
01242 }

static int acf_strptime ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  buflen 
) [static]

Definition at line 1249 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.

01251 {
01252    AST_DECLARE_APP_ARGS(args,
01253               AST_APP_ARG(timestring);
01254               AST_APP_ARG(timezone);
01255               AST_APP_ARG(format);
01256    );
01257    struct ast_tm tm;
01258 
01259    buf[0] = '\0';
01260 
01261    if (!data) {
01262       ast_log(LOG_ERROR,
01263             "Asterisk function STRPTIME() requires an argument.\n");
01264       return -1;
01265    }
01266 
01267    AST_STANDARD_APP_ARGS(args, data);
01268 
01269    if (ast_strlen_zero(args.format)) {
01270       ast_log(LOG_ERROR,
01271             "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
01272       return -1;
01273    }
01274 
01275    if (!ast_strptime(args.timestring, args.format, &tm)) {
01276       ast_log(LOG_WARNING, "STRPTIME() found no time specified within the string\n");
01277    } else {
01278       struct timeval when;
01279       when = ast_mktime(&tm, args.timezone);
01280       snprintf(buf, buflen, "%d", (int) when.tv_sec);
01281    }
01282 
01283    return 0;
01284 }

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 1162 of file func_strings.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), and LOG_ERROR.

01163 {
01164    char *bufptr = buf, *dataptr = data;
01165 
01166    if (len < 3) { /* at least two for quotes and one for binary zero */
01167       ast_log(LOG_ERROR, "Not enough buffer\n");
01168       return -1;
01169    }
01170 
01171    if (ast_strlen_zero(data)) {
01172       ast_copy_string(buf, "\"\"", len);
01173       return 0;
01174    }
01175 
01176    *bufptr++ = '"';
01177    for (; bufptr < buf + len - 3; dataptr++){
01178       if (*dataptr == '"') {
01179          *bufptr++ = '"';
01180          *bufptr++ = '"';
01181       } else if (*dataptr == '\0') {
01182          break;
01183       } else {
01184          *bufptr++ = *dataptr;
01185       }
01186    }
01187    *bufptr++ = '"';
01188    *bufptr='\0';
01189    return 0;
01190 }

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]

Note:
Looks a little strange, until you realize that we can overflow the size of a char.

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 1291 of file func_strings.c.

References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_substitute_variables_helper().

01293 {
01294    if (ast_strlen_zero(data)) {
01295       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
01296       return -1;
01297    }
01298 
01299    pbx_substitute_variables_helper(chan, data, buf, buflen - 1);
01300 
01301    return 0;
01302 }

static int function_eval2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  buflen 
) [static]

Definition at line 1304 of file func_strings.c.

References ast_log(), ast_str_substitute_variables(), ast_strlen_zero(), and LOG_WARNING.

01306 {
01307    if (ast_strlen_zero(data)) {
01308       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
01309       return -1;
01310    }
01311 
01312    ast_str_substitute_variables(buf, buflen, chan, data);
01313 
01314    return 0;
01315 }

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 1060 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().

01061 {
01062    char varname[256];
01063    const char *varvalue;
01064    AST_DECLARE_APP_ARGS(arg,
01065       AST_APP_ARG(hashname);
01066       AST_APP_ARG(hashkey);
01067    );
01068 
01069    AST_STANDARD_APP_ARGS(arg, data);
01070    if (arg.argc == 2) {
01071       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
01072       varvalue = pbx_builtin_getvar_helper(chan, varname);
01073       if (varvalue)
01074          ast_copy_string(buf, varvalue, len);
01075       else
01076          *buf = '\0';
01077    } else if (arg.argc == 1) {
01078       char colnames[4096];
01079       int i;
01080       AST_DECLARE_APP_ARGS(arg2,
01081          AST_APP_ARG(col)[100];
01082       );
01083 
01084       /* Get column names, in no particular order */
01085       hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames));
01086       pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames);
01087 
01088       AST_STANDARD_APP_ARGS(arg2, colnames);
01089       *buf = '\0';
01090 
01091       /* Now get the corresponding column values, in exactly the same order */
01092       for (i = 0; i < arg2.argc; i++) {
01093          snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]);
01094          varvalue = pbx_builtin_getvar_helper(chan, varname);
01095          strncat(buf, varvalue, len - strlen(buf) - 1);
01096          strncat(buf, ",", len - strlen(buf) - 1);
01097       }
01098 
01099       /* Strip trailing comma */
01100       buf[strlen(buf) - 1] = '\0';
01101    }
01102 
01103    return 0;
01104 }

static int hash_write ( struct ast_channel chan,
const char *  cmd,
char *  var,
const char *  value 
) [static]

Definition at line 1032 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().

01033 {
01034    char varname[256];
01035    AST_DECLARE_APP_ARGS(arg,
01036       AST_APP_ARG(hashname);
01037       AST_APP_ARG(hashkey);
01038    );
01039 
01040    if (!strchr(var, ',')) {
01041       /* Single argument version */
01042       return array(chan, "HASH", var, value);
01043    }
01044 
01045    AST_STANDARD_APP_ARGS(arg, var);
01046    if (arg.hashname[0] == '_') {
01047       if (arg.hashname[1] == '_') {
01048          snprintf(varname, sizeof(varname), "__" HASH_FORMAT, arg.hashname + 2, arg.hashkey);
01049       } else {
01050          snprintf(varname, sizeof(varname), "_" HASH_FORMAT, arg.hashname + 1, arg.hashkey);
01051       }
01052    } else {
01053       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
01054    }
01055    pbx_builtin_setvar_helper(chan, varname, value);
01056 
01057    return 0;
01058 }

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_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().

00989 {
00990    struct ast_var_t *newvar;
00991    struct ast_str *prefix = ast_str_alloca(80);
00992 
00993    ast_str_set(&prefix, -1, HASH_PREFIX, data);
00994    memset(buf, 0, len);
00995 
00996    AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) {
00997       if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) {
00998          /* Copy everything after the prefix */
00999          strncat(buf, ast_var_name(newvar) + ast_str_strlen(prefix), len - strlen(buf) - 1);
01000          /* Trim the trailing ~ */
01001          buf[strlen(buf) - 1] = ',';
01002       }
01003    }
01004    /* Trim the trailing comma */
01005    buf[strlen(buf) - 1] = '\0';
01006    return 0;
01007 }

static int hashkeys_read2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
) [static]

Definition at line 1009 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.

01010 {
01011    struct ast_var_t *newvar;
01012    struct ast_str *prefix = ast_str_alloca(80);
01013    char *tmp;
01014 
01015    ast_str_set(&prefix, -1, HASH_PREFIX, data);
01016 
01017    AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) {
01018       if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) {
01019          /* Copy everything after the prefix */
01020          ast_str_append(buf, len, "%s", ast_var_name(newvar) + ast_str_strlen(prefix));
01021          /* Trim the trailing ~ */
01022          tmp = ast_str_buffer(*buf);
01023          tmp[ast_str_strlen(*buf) - 1] = ',';
01024       }
01025    }
01026    /* Trim the trailing comma */
01027    tmp = ast_str_buffer(*buf);
01028    tmp[ast_str_strlen(*buf) - 1] = '\0';
01029    return 0;
01030 }

static int keypadhash ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  buflen 
) [static]

Definition at line 1323 of file func_strings.c.

01324 {
01325    char *bufptr, *dataptr;
01326 
01327    for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) {
01328       if (*dataptr == '\0') {
01329          *bufptr++ = '\0';
01330          break;
01331       } else if (*dataptr == '1') {
01332          *bufptr++ = '1';
01333       } else if (strchr("AaBbCc2", *dataptr)) {
01334          *bufptr++ = '2';
01335       } else if (strchr("DdEeFf3", *dataptr)) {
01336          *bufptr++ = '3';
01337       } else if (strchr("GgHhIi4", *dataptr)) {
01338          *bufptr++ = '4';
01339       } else if (strchr("JjKkLl5", *dataptr)) {
01340          *bufptr++ = '5';
01341       } else if (strchr("MmNnOo6", *dataptr)) {
01342          *bufptr++ = '6';
01343       } else if (strchr("PpQqRrSs7", *dataptr)) {
01344          *bufptr++ = '7';
01345       } else if (strchr("TtUuVv8", *dataptr)) {
01346          *bufptr++ = '8';
01347       } else if (strchr("WwXxYyZz9", *dataptr)) {
01348          *bufptr++ = '9';
01349       } else if (*dataptr == '0') {
01350          *bufptr++ = '0';
01351       }
01352    }
01353    buf[buflen - 1] = '\0';
01354 
01355    return 0;
01356 }

static int len ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  buflen 
) [static]

Definition at line 1197 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().

01198 {
01199    int length = 0;
01200 
01201    if (data)
01202       length = strlen(data);
01203 
01204    snprintf(buf, buflen, "%d", length);
01205 
01206    return 0;
01207 }

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 1762 of file func_strings.c.

References ast_custom_function_register, ast_register_application_xml, AST_TEST_REGISTER, and exec_clearhash().

01763 {
01764    int res = 0;
01765 
01766    AST_TEST_REGISTER(test_FIELDNUM);
01767    AST_TEST_REGISTER(test_REPLACE);
01768    AST_TEST_REGISTER(test_FILTER);
01769    res |= ast_custom_function_register(&fieldqty_function);
01770    res |= ast_custom_function_register(&fieldnum_function);
01771    res |= ast_custom_function_register(&filter_function);
01772    res |= ast_custom_function_register(&replace_function);
01773    res |= ast_custom_function_register(&listfilter_function);
01774    res |= ast_custom_function_register(&regex_function);
01775    res |= ast_custom_function_register(&array_function);
01776    res |= ast_custom_function_register(&quote_function);
01777    res |= ast_custom_function_register(&csv_quote_function);
01778    res |= ast_custom_function_register(&len_function);
01779    res |= ast_custom_function_register(&strftime_function);
01780    res |= ast_custom_function_register(&strptime_function);
01781    res |= ast_custom_function_register(&eval_function);
01782    res |= ast_custom_function_register(&keypadhash_function);
01783    res |= ast_custom_function_register(&hashkeys_function);
01784    res |= ast_custom_function_register(&hash_function);
01785    res |= ast_register_application_xml(app_clearhash, exec_clearhash);
01786    res |= ast_custom_function_register(&toupper_function);
01787    res |= ast_custom_function_register(&tolower_function);
01788    res |= ast_custom_function_register(&shift_function);
01789    res |= ast_custom_function_register(&pop_function);
01790    res |= ast_custom_function_register(&push_function);
01791    res |= ast_custom_function_register(&unshift_function);
01792    res |= ast_custom_function_register(&passthru_function);
01793 
01794    return res;
01795 }

static int passthru ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  len 
) [static]

Definition at line 1537 of file func_strings.c.

References ast_str_set().

01538 {
01539    ast_str_set(buf, len, "%s", data);
01540    return 0;
01541 }

static int quote ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 1123 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().

01124 {
01125    char *bufptr = buf, *dataptr = data;
01126 
01127    if (len < 3){ /* at least two for quotes and one for binary zero */
01128       ast_log(LOG_ERROR, "Not enough buffer\n");
01129       return -1;
01130    }
01131 
01132    if (ast_strlen_zero(data)) {
01133       ast_log(LOG_WARNING, "No argument specified!\n");
01134       ast_copy_string(buf, "\"\"", len);
01135       return 0;
01136    }
01137 
01138    *bufptr++ = '"';
01139    for (; bufptr < buf + len - 3; dataptr++) {
01140       if (*dataptr == '\\') {
01141          *bufptr++ = '\\';
01142          *bufptr++ = '\\';
01143       } else if (*dataptr == '"') {
01144          *bufptr++ = '\\';
01145          *bufptr++ = '"';
01146       } else if (*dataptr == '\0') {
01147          break;
01148       } else {
01149          *bufptr++ = *dataptr;
01150       }
01151    }
01152    *bufptr++ = '"';
01153    *bufptr = '\0';
01154    return 0;
01155 }

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(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
00869       regerror(errcode, &regexbuf, 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(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
00875 
00876    regfree(&regexbuf);
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_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().

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    struct ast_str *str = ast_str_thread_get(&result_buf, 16);
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 1421 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.

01422 {
01423 #define beginning (cmd[0] == 'S') /* SHIFT */
01424    char *after, delimiter[2] = ",", *varsubst;
01425    size_t unused;
01426    struct ast_str *before = ast_str_thread_get(&result_buf, 16);
01427    char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr);
01428    AST_DECLARE_APP_ARGS(args,
01429       AST_APP_ARG(var);
01430       AST_APP_ARG(delimiter);
01431    );
01432 
01433    if (!before) {
01434       return -1;
01435    }
01436 
01437    AST_STANDARD_APP_ARGS(args, data);
01438 
01439    if (ast_strlen_zero(args.var)) {
01440       ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
01441       return -1;
01442    }
01443 
01444    varsubst = ast_alloca(strlen(args.var) + 4);
01445    sprintf(varsubst, "${%s}", args.var);
01446    ast_str_substitute_variables(&before, 0, chan, varsubst);
01447 
01448    if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
01449       ast_get_encoded_char(args.delimiter, delimiter, &unused);
01450    }
01451 
01452    if (!ast_str_strlen(before)) {
01453       /* Nothing to pop */
01454       return -1;
01455    }
01456 
01457    if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) {
01458       /* Only one entry in array */
01459       ast_str_set(buf, len, "%s", ast_str_buffer(before));
01460       pbx_builtin_setvar_helper(chan, args.var, "");
01461    } else {
01462       *after++ = '\0';
01463       ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after);
01464       pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before));
01465    }
01466 
01467    return 0;
01468 #undef beginning
01469 }

static int string_tolower ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  buflen 
) [static]

Definition at line 1392 of file func_strings.c.

01393 {
01394    char *bufptr = buf, *dataptr = data;
01395 
01396    while ((bufptr < buf + buflen - 1) && (*bufptr++ = tolower(*dataptr++)));
01397 
01398    return 0;
01399 }

static int string_tolower2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  buflen 
) [static]

Definition at line 1401 of file func_strings.c.

References ast_str_buffer(), ast_str_make_space(), ast_str_size(), and ast_str_update().

01402 {
01403    char *bufptr, *dataptr = data;
01404 
01405    if (buflen > -1) {
01406       ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
01407    }
01408    bufptr = ast_str_buffer(*buf);
01409    while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++)));
01410    ast_str_update(*buf);
01411 
01412    return 0;
01413 }

static int string_toupper ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  buflen 
) [static]

Definition at line 1363 of file func_strings.c.

01364 {
01365    char *bufptr = buf, *dataptr = data;
01366 
01367    while ((bufptr < buf + buflen - 1) && (*bufptr++ = toupper(*dataptr++)));
01368 
01369    return 0;
01370 }

static int string_toupper2 ( struct ast_channel chan,
const char *  cmd,
char *  data,
struct ast_str **  buf,
ssize_t  buflen 
) [static]

Definition at line 1372 of file func_strings.c.

References ast_str_buffer(), ast_str_make_space(), ast_str_size(), and ast_str_update().

01373 {
01374    char *bufptr, *dataptr = data;
01375 
01376    if (buflen > -1) {
01377       ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
01378    }
01379    bufptr = ast_str_buffer(*buf);
01380    while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++)));
01381    ast_str_update(*buf);
01382 
01383    return 0;
01384 }

static int unload_module ( void   )  [static]

Definition at line 1727 of file func_strings.c.

References ast_custom_function_unregister(), AST_TEST_UNREGISTER, and ast_unregister_application().

01728 {
01729    int res = 0;
01730 
01731    AST_TEST_UNREGISTER(test_FIELDNUM);
01732    AST_TEST_UNREGISTER(test_REPLACE);
01733    AST_TEST_UNREGISTER(test_FILTER);
01734    res |= ast_custom_function_unregister(&fieldqty_function);
01735    res |= ast_custom_function_unregister(&fieldnum_function);
01736    res |= ast_custom_function_unregister(&filter_function);
01737    res |= ast_custom_function_unregister(&replace_function);
01738    res |= ast_custom_function_unregister(&listfilter_function);
01739    res |= ast_custom_function_unregister(&regex_function);
01740    res |= ast_custom_function_unregister(&array_function);
01741    res |= ast_custom_function_unregister(&quote_function);
01742    res |= ast_custom_function_unregister(&csv_quote_function);
01743    res |= ast_custom_function_unregister(&len_function);
01744    res |= ast_custom_function_unregister(&strftime_function);
01745    res |= ast_custom_function_unregister(&strptime_function);
01746    res |= ast_custom_function_unregister(&eval_function);
01747    res |= ast_custom_function_unregister(&keypadhash_function);
01748    res |= ast_custom_function_unregister(&hashkeys_function);
01749    res |= ast_custom_function_unregister(&hash_function);
01750    res |= ast_unregister_application(app_clearhash);
01751    res |= ast_custom_function_unregister(&toupper_function);
01752    res |= ast_custom_function_unregister(&tolower_function);
01753    res |= ast_custom_function_unregister(&shift_function);
01754    res |= ast_custom_function_unregister(&pop_function);
01755    res |= ast_custom_function_unregister(&push_function);
01756    res |= ast_custom_function_unregister(&unshift_function);
01757    res |= ast_custom_function_unregister(&passthru_function);
01758 
01759    return res;
01760 }

static int unshift_push ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  new_value 
) [static]

Definition at line 1481 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.

01482 {
01483 #define beginning (cmd[0] == 'U') /* UNSHIFT */
01484    char delimiter[2] = ",", *varsubst;
01485    size_t unused;
01486    struct ast_str *buf, *previous_value;
01487    AST_DECLARE_APP_ARGS(args,
01488       AST_APP_ARG(var);
01489       AST_APP_ARG(delimiter);
01490    );
01491 
01492    if (!(buf = ast_str_thread_get(&result_buf, 16)) ||
01493       !(previous_value = ast_str_thread_get(&tmp_buf, 16))) {
01494       return -1;
01495    }
01496 
01497    AST_STANDARD_APP_ARGS(args, data);
01498 
01499    if (ast_strlen_zero(args.var)) {
01500       ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
01501       return -1;
01502    }
01503 
01504    if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
01505       ast_get_encoded_char(args.delimiter, delimiter, &unused);
01506    }
01507 
01508    varsubst = ast_alloca(strlen(args.var) + 4);
01509    sprintf(varsubst, "${%s}", args.var);
01510    ast_str_substitute_variables(&previous_value, 0, chan, varsubst);
01511 
01512    if (!ast_str_strlen(previous_value)) {
01513       ast_str_set(&buf, 0, "%s", new_value);
01514    } else {
01515       ast_str_set(&buf, 0, "%s%c%s",
01516          beginning ? new_value : ast_str_buffer(previous_value),
01517          delimiter[0],
01518          beginning ? ast_str_buffer(previous_value) : new_value);
01519    }
01520 
01521    pbx_builtin_setvar_helper(chan, args.var, ast_str_buffer(buf));
01522 
01523    return 0;
01524 #undef beginning
01525 }


Variable Documentation

char* app_clearhash = "ClearHash" [static]

Definition at line 889 of file func_strings.c.

Initial value:
 {
   .name = "ARRAY",
   .write = array,
}

Definition at line 1118 of file func_strings.c.

Initial value:
 {
   .name = "CSV_QUOTE",
   .read = csv_quote,
}

Definition at line 1192 of file func_strings.c.

Initial value:
 {
   .name = "EVAL",
   .read = function_eval,
   .read2 = function_eval2,
}

Definition at line 1317 of file func_strings.c.

Initial value:
 {
   .name = "FIELDNUM",
   .read = function_fieldnum,
   .read2 = function_fieldnum_str,
}

Definition at line 560 of file func_strings.c.

Initial value:
 {
   .name = "FIELDQTY",
   .read = function_fieldqty,
   .read2 = function_fieldqty_str,
}

Definition at line 481 of file func_strings.c.

Initial value:
 {
   .name = "FILTER",
   .read = filter,
}

Definition at line 770 of file func_strings.c.

Initial value:
 {
   .name = "HASH",
   .write = hash_write,
   .read = hash_read,
}

Definition at line 1106 of file func_strings.c.

Initial value:
 {
   .name = "HASHKEYS",
   .read = hashkeys_read,
   .read2 = hashkeys_read2,
}

Definition at line 1112 of file func_strings.c.

Initial value:
 {
   .name = "KEYPADHASH",
   .read = keypadhash,
}

Definition at line 1358 of file func_strings.c.

Initial value:
 {
   .name = "LEN",
   .read = len,
   .read_max = 12,
}

Definition at line 1209 of file func_strings.c.

Initial value:
 {
   .name = "LISTFILTER",
   .read = listfilter_read,
   .read2 = listfilter_read2,
}

Definition at line 688 of file func_strings.c.

Initial value:
 {
   .name = "PASSTHRU",
   .read2 = passthru,
}

Definition at line 1543 of file func_strings.c.

Initial value:
 {
   .name = "POP",
   .read2 = shift_pop,
}

Definition at line 1476 of file func_strings.c.

Initial value:
 {
   .name = "PUSH",
   .write = unshift_push,
}

Definition at line 1527 of file func_strings.c.

Initial value:
 {
   .name = "QUOTE",
   .read = quote,
}

Definition at line 1157 of file func_strings.c.

Initial value:
 {
   .name = "REGEX",
   .read = regex,
}

Definition at line 881 of file func_strings.c.

Initial value:
 {
   .name = "REPLACE",
   .read2 = replace,
}

Definition at line 839 of file func_strings.c.

Initial value:
 {
   .name = "SHIFT",
   .read2 = shift_pop,
}

Definition at line 1471 of file func_strings.c.

Initial value:
 {
   .name = "STRFTIME",
   .read = acf_strftime,
}

Definition at line 1244 of file func_strings.c.

Initial value:
 {
   .name = "STRPTIME",
   .read = acf_strptime,
}

Definition at line 1286 of file func_strings.c.

Initial value:
 {
   .name = "TOLOWER",
   .read = string_tolower,
   .read2 = string_tolower2,
}

Definition at line 1415 of file func_strings.c.

Initial value:
 {
   .name = "TOUPPER",
   .read = string_toupper,
   .read2 = string_toupper2,
}

Definition at line 1386 of file func_strings.c.

Initial value:
 {
   .name = "UNSHIFT",
   .write = unshift_push,
}

Definition at line 1532 of file func_strings.c.


Generated on 3 Apr 2014 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1