Tue Aug 20 16:35:04 2013

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"

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

Referenced by array(), hash_read(), and hash_write().

#define HASH_PREFIX   "~HASH~%s~"

Definition at line 883 of file func_strings.c.

Referenced by exec_clearhash(), hashkeys_read(), and hashkeys_read2().


Function Documentation

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

Definition at line 1212 of file func_strings.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_timeval(), ast_localtime(), ast_log(), AST_STANDARD_APP_ARGS, ast_strftime(), ast_tvnow(), format, and LOG_WARNING.

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

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

Definition at line 1246 of file func_strings.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_mktime(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_strptime(), format, LOG_ERROR, and LOG_WARNING.

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

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

Definition at line 910 of file func_strings.c.

References AST_APP_ARG, ast_autoservice_stop(), ast_debug, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, HASH_FORMAT, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and S_OR.

Referenced by hash_write().

00912 {
00913    AST_DECLARE_APP_ARGS(arg1,
00914               AST_APP_ARG(var)[100];
00915    );
00916    AST_DECLARE_APP_ARGS(arg2,
00917               AST_APP_ARG(val)[100];
00918    );
00919    char *origvar = "", *value2, varname[256];
00920    int i, ishash = 0;
00921 
00922    if (!var) {
00923       return -1;
00924    }
00925    value2 = ast_strdupa(value);
00926 
00927    if (!strcmp(cmd, "HASH")) {
00928       const char *var2 = pbx_builtin_getvar_helper(chan, "~ODBCFIELDS~");
00929       origvar = var;
00930       if (var2)
00931          var = ast_strdupa(var2);
00932       else {
00933          if (chan)
00934             ast_autoservice_stop(chan);
00935          return -1;
00936       }
00937       ishash = 1;
00938    }
00939 
00940    /* The functions this will generally be used with are SORT and ODBC_*, which
00941     * both return comma-delimited lists.  However, if somebody uses literal lists,
00942     * their commas will be translated to vertical bars by the load, and I don't
00943     * want them to be surprised by the result.  Hence, we prefer commas as the
00944     * delimiter, but we'll fall back to vertical bars if commas aren't found.
00945     */
00946    ast_debug(1, "array (%s=%s)\n", var, S_OR(value2, ""));
00947    AST_STANDARD_APP_ARGS(arg1, var);
00948 
00949    AST_STANDARD_APP_ARGS(arg2, value2);
00950 
00951    for (i = 0; i < arg1.argc; i++) {
00952       ast_debug(1, "array set value (%s=%s)\n", arg1.var[i],
00953             S_OR(arg2.val[i], ""));
00954       if (i < arg2.argc) {
00955          if (ishash) {
00956             if (origvar[0] == '_') {
00957                if (origvar[1] == '_') {
00958                   snprintf(varname, sizeof(varname), "__" HASH_FORMAT, origvar + 2, arg1.var[i]);
00959                } else {
00960                   snprintf(varname, sizeof(varname), "_" HASH_FORMAT, origvar + 1, arg1.var[i]);
00961                }
00962             } else {
00963                snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
00964             }
00965 
00966             pbx_builtin_setvar_helper(chan, varname, arg2.val[i]);
00967          } else {
00968             pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
00969          }
00970       } else {
00971          /* We could unset the variable, by passing a NULL, but due to
00972           * pushvar semantics, that could create some undesired behavior. */
00973          if (ishash) {
00974             snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
00975             pbx_builtin_setvar_helper(chan, varname, "");
00976          } else {
00977             pbx_builtin_setvar_helper(chan, arg1.var[i], "");
00978          }
00979       }
00980    }
00981 
00982    return 0;
00983 }

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"String handling dialplan functions"   
)
AST_THREADSTORAGE ( tmp_buf   ) 
AST_THREADSTORAGE ( result_buf   ) 
static void clearvar_prefix ( struct ast_channel chan,
const char *  prefix 
) [static]

Definition at line 889 of file func_strings.c.

References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_name(), len(), var, and ast_channel::varshead.

Referenced by exec_clearhash().

00890 {
00891    struct ast_var_t *var;
00892    int len = strlen(prefix);
00893    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->varshead, var, entries) {
00894       if (strncasecmp(prefix, ast_var_name(var), len) == 0) {
00895          AST_LIST_REMOVE_CURRENT(entries);
00896          ast_free(var);
00897       }
00898    }
00899    AST_LIST_TRAVERSE_SAFE_END
00900 }

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

Definition at line 1159 of file func_strings.c.

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

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

static int exec_clearhash ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 902 of file func_strings.c.

References clearvar_prefix(), HASH_PREFIX, and prefix.

Referenced by load_module().

00903 {
00904    char prefix[80];
00905    snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null");
00906    clearvar_prefix(chan, prefix);
00907    return 0;
00908 }

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

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

Definition at line 690 of file func_strings.c.

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), ast_opt_dont_warn, AST_STANDARD_RAW_ARGS, LOG_ERROR, and LOG_WARNING.

Referenced by __ast_data_add(), data_filter_destructor(), data_filter_generate(), data_result_generate(), manager_data_get(), realtime_ldap_base_ap(), set_egress_subscription(), update2_ldap(), and update_ldap().

00692 {
00693    AST_DECLARE_APP_ARGS(args,
00694               AST_APP_ARG(allowed);
00695               AST_APP_ARG(string);
00696    );
00697    char *outbuf = buf;
00698    unsigned char ac;
00699    char allowed[256] = "";
00700    size_t allowedlen = 0;
00701    int32_t bitfield[8] = { 0, }; /* 256 bits */
00702 
00703    AST_STANDARD_RAW_ARGS(args, parse);
00704 
00705    if (!args.string) {
00706       ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n");
00707       return -1;
00708    }
00709 
00710    if (args.allowed[0] == '"' && !ast_opt_dont_warn) {
00711       ast_log(LOG_WARNING, "FILTER allowed characters includes the quote (\") character.  This may not be what you want.\n");
00712    }
00713 
00714    /* Expand ranges */
00715    for (; *(args.allowed);) {
00716       char c1 = 0, c2 = 0;
00717       size_t consumed = 0;
00718 
00719       if (ast_get_encoded_char(args.allowed, &c1, &consumed))
00720          return -1;
00721       args.allowed += consumed;
00722 
00723       if (*(args.allowed) == '-') {
00724          if (ast_get_encoded_char(args.allowed + 1, &c2, &consumed))
00725             c2 = c1;
00726          args.allowed += consumed + 1;
00727 
00728          if ((unsigned char) c2 < (unsigned char) c1 && !ast_opt_dont_warn) {
00729             ast_log(LOG_WARNING, "Range wrapping in FILTER(%s,%s).  This may not be what you want.\n", parse, args.string);
00730          }
00731 
00732          /*!\note
00733           * Looks a little strange, until you realize that we can overflow
00734           * the size of a char.
00735           */
00736          for (ac = (unsigned char) c1; ac != (unsigned char) c2; ac++) {
00737             bitfield[ac / 32] |= 1 << (ac % 32);
00738          }
00739          bitfield[ac / 32] |= 1 << (ac % 32);
00740 
00741          ast_debug(4, "c1=%d, c2=%d\n", c1, c2);
00742       } else {
00743          ac = (unsigned char) c1;
00744          ast_debug(4, "c1=%d, consumed=%d, args.allowed=%s\n", c1, (int) consumed, args.allowed - consumed);
00745          bitfield[ac / 32] |= 1 << (ac % 32);
00746       }
00747    }
00748 
00749    for (ac = 1; ac != 0; ac++) {
00750       if (bitfield[ac / 32] & (1 << (ac % 32))) {
00751          allowed[allowedlen++] = ac;
00752       }
00753    }
00754 
00755    ast_debug(1, "Allowed: %s\n", allowed);
00756 
00757    for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
00758       if (strchr(allowed, *(args.string)))
00759          *outbuf++ = *(args.string);
00760    }
00761    *outbuf = '\0';
00762 
00763    return 0;
00764 }

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

Definition at line 1288 of file func_strings.c.

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

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

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

Definition at line 1301 of file func_strings.c.

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

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

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

Definition at line 544 of file func_strings.c.

References function_fieldnum_helper().

00546 {
00547    return function_fieldnum_helper(chan, cmd, parse, buf, NULL, len);
00548 }

static int function_fieldnum_helper ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
struct ast_str **  sbuf,
ssize_t  len 
) [static]

Definition at line 483 of file func_strings.c.

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), LOG_ERROR, result_buf, and str.

Referenced by function_fieldnum(), and function_fieldnum_str().

00485 {
00486    char *varsubst, *field;
00487    struct ast_str *str = ast_str_thread_get(&result_buf, 16);
00488    int fieldindex = 0, res = 0;
00489    AST_DECLARE_APP_ARGS(args,
00490       AST_APP_ARG(varname);
00491       AST_APP_ARG(delim);
00492       AST_APP_ARG(field);
00493    );
00494    char delim[2] = "";
00495    size_t delim_used;
00496 
00497    if (!str) {
00498       return -1;
00499    }
00500 
00501    AST_STANDARD_APP_ARGS(args, parse);
00502 
00503    if (args.argc < 3) {
00504       ast_log(LOG_ERROR, "Usage: FIELDNUM(<listname>,<delimiter>,<fieldvalue>)\n");
00505       res = -1;
00506    } else {
00507       varsubst = ast_alloca(strlen(args.varname) + 4);
00508       sprintf(varsubst, "${%s}", args.varname);
00509 
00510       ast_str_substitute_variables(&str, 0, chan, varsubst);
00511 
00512       if (ast_str_strlen(str) == 0 || ast_strlen_zero(args.delim)) {
00513          fieldindex = 0;
00514       } else if (ast_get_encoded_char(args.delim, delim, &delim_used) == -1) {
00515          res = -1;
00516       } else {
00517          char *varval = ast_str_buffer(str);
00518 
00519          while ((field = strsep(&varval, delim)) != NULL) {
00520             fieldindex++;
00521 
00522             if (!strcasecmp(field, args.field)) {
00523                break;
00524             }
00525          }
00526 
00527          if (!field) {
00528             fieldindex = 0;
00529          }
00530 
00531          res = 0;
00532       }
00533    }
00534 
00535    if (sbuf) {
00536       ast_str_set(sbuf, len, "%d", fieldindex);
00537    } else {
00538       snprintf(buf, len, "%d", fieldindex);
00539    }
00540 
00541    return res;
00542 }

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

Definition at line 550 of file func_strings.c.

References function_fieldnum_helper().

00552 {
00553    return function_fieldnum_helper(chan, cmd, parse, NULL, buf, len);
00554 }

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

Definition at line 465 of file func_strings.c.

References function_fieldqty_helper().

00467 {
00468    return function_fieldqty_helper(chan, cmd, parse, buf, NULL, len);
00469 }

static int function_fieldqty_helper ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
struct ast_str **  sbuf,
ssize_t  len 
) [static]

Definition at line 420 of file func_strings.c.

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), result_buf, and str.

Referenced by function_fieldqty(), and function_fieldqty_str().

00422 {
00423    char *varsubst;
00424    struct ast_str *str = ast_str_thread_get(&result_buf, 16);
00425    int fieldcount = 0;
00426    AST_DECLARE_APP_ARGS(args,
00427               AST_APP_ARG(varname);
00428               AST_APP_ARG(delim);
00429       );
00430    char delim[2] = "";
00431    size_t delim_used;
00432 
00433    if (!str) {
00434       return -1;
00435    }
00436 
00437    AST_STANDARD_APP_ARGS(args, parse);
00438    if (args.delim) {
00439       ast_get_encoded_char(args.delim, delim, &delim_used);
00440 
00441       varsubst = ast_alloca(strlen(args.varname) + 4);
00442 
00443       sprintf(varsubst, "${%s}", args.varname);
00444       ast_str_substitute_variables(&str, 0, chan, varsubst);
00445       if (ast_str_strlen(str) == 0) {
00446          fieldcount = 0;
00447       } else {
00448          char *varval = ast_str_buffer(str);
00449          while (strsep(&varval, delim)) {
00450             fieldcount++;
00451          }
00452       }
00453    } else {
00454       fieldcount = 1;
00455    }
00456    if (sbuf) {
00457       ast_str_set(sbuf, len, "%d", fieldcount);
00458    } else {
00459       snprintf(buf, len, "%d", fieldcount);
00460    }
00461 
00462    return 0;
00463 }

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

Definition at line 471 of file func_strings.c.

References function_fieldqty_helper().

00473 {
00474    return function_fieldqty_helper(chan, cmd, parse, NULL, buf, len);
00475 }

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

Definition at line 1057 of file func_strings.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, HASH_FORMAT, hashkeys_read(), pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().

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

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

Definition at line 1029 of file func_strings.c.

References array(), AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, HASH_FORMAT, and pbx_builtin_setvar_helper().

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

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

Definition at line 985 of file func_strings.c.

References AST_LIST_TRAVERSE, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, prefix, and ast_channel::varshead.

Referenced by hash_read().

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

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

Definition at line 1006 of file func_strings.c.

References AST_LIST_TRAVERSE, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, prefix, and ast_channel::varshead.

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

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

Definition at line 1320 of file func_strings.c.

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

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

Definition at line 1194 of file func_strings.c.

Referenced by __analog_ss_thread(), __ast_cli_register(), __ast_str_helper(), __get_header(), __rtp_recvfrom(), __rtp_sendto(), _parse(), add_sdp(), ael_token_subst(), aji_io_recv(), aji_recv(), aji_send_header(), aji_send_raw(), aji_start_sasl(), alsa_write(), analog_ss_thread(), aoc_parse_ie(), append_interface(), append_var_and_value_to_filter(), ast_agi_register_multiple(), ast_agi_unregister_multiple(), ast_app_group_set_channel(), ast_callerid_vmwi_generate(), ast_cdr_appenduserfield(), ast_cli_complete(), ast_codec_get_len(), ast_complete_source_filename(), ast_dsp_noise(), ast_dsp_process(), ast_dsp_silence(), ast_event_cb(), ast_format_str_reduce(), ast_frdup(), ast_getformatname_multiple(), ast_http_send(), ast_http_uri_link(), ast_mkdir(), ast_read_image(), ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_read(), ast_say_number_full_ka(), ast_smoother_read(), ast_str_buffer(), ast_str_substitute_variables_full(), ast_translate(), ast_udptl_write(), ast_xml_escape(), ast_xmldoc_printable(), auth_exec(), authenticate(), build_device(), build_facility(), build_route(), callerid_generate(), cleaned_basedn(), clearvar_prefix(), cli_console_sendtext(), complete_agent_logoff_cmd(), complete_confno(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_meetmecmd_list(), complete_meetmecmd_mute_kick(), complete_peer_helper(), complete_trans_path_choice(), complete_userno(), conf_play(), config_jitterbuffer(), cops_getmsg(), copy(), create_video_frame(), dahdi_sendtext(), dahdi_setoption(), devstate_write(), dialgroup_refreshdb(), dictate_exec(), do_pktccops(), dundi_encrypt(), dundi_parse_ies(), dundi_send(), enc_ie_facility(), evt_event_deliver_cb(), expr2_token_subst(), ext_cmp_exten_strlen(), ffmpeg_decode(), find_by_part(), get_body(), get_ip_and_port_from_sdp(), get_sdp(), get_sdp_iterate(), get_to_address(), gsm_write(), gsmtolin_framein(), h261_encap(), h263_encap(), h263_read(), h263_write(), h263p_encap(), h264_read(), h264_write(), handle_cli_core_show_translation(), handle_cli_devstate_change(), handle_commandmatchesarray(), handle_incoming(), handle_message(), handle_output(), handle_response(), handle_show_sysinfo(), help1(), iax_parse_ies(), iax_str2flags(), launch_monitor_thread(), listener(), load_file(), local_call(), lpc10tolin_framein(), lws2sws(), message_template_parse_emailbody(), method_match(), mgcp_ss(), mgcpsock_read(), misdn_read(), monmp3thread(), mpeg4_encap(), newpvt(), parse_ie(), ParseBookmark(), pbx_substitute_variables_helper_full(), phoneprov_callback(), process_sdp(), read_credentials(), readfile_exec(), red_t140_to_red(), reschedule_precache(), run_agi(), scan_thread(), schedule_delivery(), set(), set_egress_subscription(), sip_addheader(), sip_show_channel(), sip_show_history(), skinny_ss(), sms_messagetx(), socket_process_meta(), socket_read(), static_callback(), term_filter_escapes(), transfer_exec(), try_firmware(), udptl_build_packet(), unistim_sp(), unquote(), wav_write(), and xmldoc_get_syntax_fun().

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

static int listfilter ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
struct ast_str **  bufstr,
ssize_t  len 
) [static]

Definition at line 562 of file func_strings.c.

References args, ast_alloca, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_get_encoded_str(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_append_substr(), ast_str_buffer(), ast_str_make_space(), ast_str_reset(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), first, LOG_ERROR, and result_buf.

Referenced by listfilter_read(), and listfilter_read2().

00563 {
00564    AST_DECLARE_APP_ARGS(args,
00565       AST_APP_ARG(listname);
00566       AST_APP_ARG(delimiter);
00567       AST_APP_ARG(fieldvalue);
00568    );
00569    struct ast_str *orig_list = ast_str_thread_get(&tmp_buf, 16);
00570    const char *begin, *cur, *next;
00571    int dlen, flen, first = 1;
00572    struct ast_str *result, **result_ptr = &result;
00573    char *delim, *varsubst;
00574 
00575    AST_STANDARD_APP_ARGS(args, parse);
00576 
00577    if (buf) {
00578       if (!(result = ast_str_thread_get(&result_buf, 16))) {
00579          return -1;
00580       }
00581    } else {
00582       /* Place the result directly into the output buffer */
00583       result_ptr = bufstr;
00584    }
00585 
00586    if (args.argc < 3) {
00587       ast_log(LOG_ERROR, "Usage: LISTFILTER(<listname>,<delimiter>,<fieldvalue>)\n");
00588       return -1;
00589    }
00590 
00591    varsubst = ast_alloca(strlen(args.listname) + 4);
00592    sprintf(varsubst, "${%s}", args.listname);
00593 
00594    /* If we don't lock the channel, the variable could disappear out from underneath us. */
00595    if (chan) {
00596       ast_channel_lock(chan);
00597    }
00598    ast_str_substitute_variables(&orig_list, 0, chan, varsubst);
00599    if (!ast_str_strlen(orig_list)) {
00600       ast_log(LOG_ERROR, "List variable '%s' not found\n", args.listname);
00601       if (chan) {
00602          ast_channel_unlock(chan);
00603       }
00604       return -1;
00605    }
00606 
00607    /* If the string isn't there, just copy out the string and be done with it. */
00608    if (!strstr(ast_str_buffer(orig_list), args.fieldvalue)) {
00609       if (buf) {
00610          ast_copy_string(buf, ast_str_buffer(orig_list), len);
00611       } else {
00612          ast_str_set(result_ptr, len, "%s", ast_str_buffer(orig_list));
00613       }
00614       if (chan) {
00615          ast_channel_unlock(chan);
00616       }
00617       return 0;
00618    }
00619 
00620    dlen = strlen(args.delimiter);
00621    delim = ast_alloca(dlen + 1);
00622    ast_get_encoded_str(args.delimiter, delim, dlen + 1);
00623 
00624    if ((dlen = strlen(delim)) == 0) {
00625       delim = ",";
00626       dlen = 1;
00627    }
00628 
00629    flen = strlen(args.fieldvalue);
00630 
00631    ast_str_reset(*result_ptr);
00632    /* Enough space for any result */
00633    if (len > -1) {
00634       ast_str_make_space(result_ptr, len ? len : ast_str_strlen(orig_list) + 1);
00635    }
00636 
00637    begin = ast_str_buffer(orig_list);
00638    next = strstr(begin, delim);
00639 
00640    do {
00641       /* Find next boundary */
00642       if (next) {
00643          cur = next;
00644          next = strstr(cur + dlen, delim);
00645       } else {
00646          cur = strchr(begin + dlen, '\0');
00647       }
00648 
00649       if (flen == cur - begin && !strncmp(begin, args.fieldvalue, flen)) {
00650          /* Skip field */
00651          begin += flen + dlen;
00652       } else {
00653          /* Copy field to output */
00654          if (!first) {
00655             ast_str_append(result_ptr, len, "%s", delim);
00656          }
00657 
00658          ast_str_append_substr(result_ptr, len, begin, cur - begin);
00659          first = 0;
00660          begin = cur + dlen;
00661       }
00662    } while (*cur != '\0');
00663    if (chan) {
00664       ast_channel_unlock(chan);
00665    }
00666 
00667    if (buf) {
00668       ast_copy_string(buf, ast_str_buffer(result), len);
00669    }
00670 
00671    return 0;
00672 }

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

Definition at line 674 of file func_strings.c.

References listfilter().

00675 {
00676    return listfilter(chan, cmd, parse, buf, NULL, len);
00677 }

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

Definition at line 679 of file func_strings.c.

References listfilter().

00680 {
00681    return listfilter(chan, cmd, parse, NULL, buf, len);
00682 }

static int load_module ( void   )  [static]

Definition at line 1682 of file func_strings.c.

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

01683 {
01684    int res = 0;
01685 
01686    AST_TEST_REGISTER(test_FIELDNUM);
01687    AST_TEST_REGISTER(test_FILTER);
01688    res |= ast_custom_function_register(&fieldqty_function);
01689    res |= ast_custom_function_register(&fieldnum_function);
01690    res |= ast_custom_function_register(&filter_function);
01691    res |= ast_custom_function_register(&replace_function);
01692    res |= ast_custom_function_register(&listfilter_function);
01693    res |= ast_custom_function_register(&regex_function);
01694    res |= ast_custom_function_register(&array_function);
01695    res |= ast_custom_function_register(&quote_function);
01696    res |= ast_custom_function_register(&csv_quote_function);
01697    res |= ast_custom_function_register(&len_function);
01698    res |= ast_custom_function_register(&strftime_function);
01699    res |= ast_custom_function_register(&strptime_function);
01700    res |= ast_custom_function_register(&eval_function);
01701    res |= ast_custom_function_register(&keypadhash_function);
01702    res |= ast_custom_function_register(&hashkeys_function);
01703    res |= ast_custom_function_register(&hash_function);
01704    res |= ast_register_application_xml(app_clearhash, exec_clearhash);
01705    res |= ast_custom_function_register(&toupper_function);
01706    res |= ast_custom_function_register(&tolower_function);
01707    res |= ast_custom_function_register(&shift_function);
01708    res |= ast_custom_function_register(&pop_function);
01709    res |= ast_custom_function_register(&push_function);
01710    res |= ast_custom_function_register(&unshift_function);
01711    res |= ast_custom_function_register(&passthru_function);
01712 
01713    return res;
01714 }

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

Definition at line 1534 of file func_strings.c.

References ast_str_set().

01535 {
01536    ast_str_set(buf, len, "%s", data);
01537    return 0;
01538 }

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

Definition at line 1120 of file func_strings.c.

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

Referenced by __ast_app_separate_args(), and parse_options().

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

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

Definition at line 841 of file func_strings.c.

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, LOG_ERROR, LOG_WARNING, and str.

00843 {
00844    AST_DECLARE_APP_ARGS(args,
00845               AST_APP_ARG(null);
00846               AST_APP_ARG(reg);
00847               AST_APP_ARG(str);
00848    );
00849    int errcode;
00850    regex_t regexbuf;
00851 
00852    buf[0] = '\0';
00853 
00854    AST_NONSTANDARD_APP_ARGS(args, parse, '"');
00855 
00856    if (args.argc != 3) {
00857       ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n");
00858       return -1;
00859    }
00860    if ((*args.str == ' ') || (*args.str == '\t'))
00861       args.str++;
00862 
00863    ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
00864 
00865    if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
00866       regerror(errcode, &regexbuf, buf, len);
00867       ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
00868       return -1;
00869    }
00870    
00871    strcpy(buf, regexec(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
00872 
00873    regfree(&regexbuf);
00874 
00875    return 0;
00876 }

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

Definition at line 771 of file func_strings.c.

References args, ast_alloca, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_get_encoded_str(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), LOG_ERROR, result_buf, and str.

Referenced by process_text_line().

00772 {
00773    AST_DECLARE_APP_ARGS(args,
00774       AST_APP_ARG(varname);
00775       AST_APP_ARG(find);
00776       AST_APP_ARG(replace);
00777    );
00778    char *strptr, *varsubst;
00779    struct ast_str *str = ast_str_thread_get(&result_buf, 16);
00780    char find[256]; /* Only 256 characters possible */
00781    char replace[2] = "";
00782    size_t unused;
00783 
00784    AST_STANDARD_APP_ARGS(args, data);
00785 
00786    if (!str) {
00787       return -1;
00788    }
00789 
00790    if (args.argc < 2) {
00791       ast_log(LOG_ERROR, "Usage: %s(<varname>,<search-chars>[,<replace-char>])\n", cmd);
00792       return -1;
00793    }
00794 
00795    /* Decode escapes */
00796    ast_get_encoded_str(args.find, find, sizeof(find));
00797    ast_get_encoded_char(args.replace, replace, &unused);
00798 
00799    if (ast_strlen_zero(find) || ast_strlen_zero(args.varname)) {
00800       ast_log(LOG_ERROR, "The characters to search for and the variable name must not be empty.\n");
00801       return -1;
00802    }
00803 
00804    varsubst = ast_alloca(strlen(args.varname) + 4);
00805    sprintf(varsubst, "${%s}", args.varname);
00806    ast_str_substitute_variables(&str, 0, chan, varsubst);
00807 
00808    if (!ast_str_strlen(str)) {
00809       /* Blank, nothing to replace */
00810       return -1;
00811    }
00812 
00813    ast_debug(3, "String to search: (%s)\n", ast_str_buffer(str));
00814    ast_debug(3, "Characters to find: (%s)\n", find);
00815    ast_debug(3, "Character to replace with: (%s)\n", replace);
00816 
00817    for (strptr = ast_str_buffer(str); *strptr; strptr++) {
00818       /* buf is already a mutable buffer, so we construct the result
00819        * directly there */
00820       if (strchr(find, *strptr)) {
00821          if (ast_strlen_zero(replace)) {
00822             /* Remove character */
00823             strcpy(strptr, strptr + 1); /* SAFE */
00824             strptr--;
00825          } else {
00826             /* Replace character */
00827             *strptr = *replace;
00828          }
00829       }
00830    }
00831 
00832    ast_str_set(buf, len, "%s", ast_str_buffer(str));
00833    return 0;
00834 }

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

Definition at line 1418 of file func_strings.c.

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), beginning, LOG_WARNING, pbx_builtin_setvar_helper(), result_buf, and var.

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

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

Definition at line 1389 of file func_strings.c.

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

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

Definition at line 1398 of file func_strings.c.

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

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

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

Definition at line 1360 of file func_strings.c.

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

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

Definition at line 1369 of file func_strings.c.

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

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

static int unload_module ( void   )  [static]

Definition at line 1648 of file func_strings.c.

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

01649 {
01650    int res = 0;
01651 
01652    AST_TEST_UNREGISTER(test_FIELDNUM);
01653    AST_TEST_UNREGISTER(test_FILTER);
01654    res |= ast_custom_function_unregister(&fieldqty_function);
01655    res |= ast_custom_function_unregister(&fieldnum_function);
01656    res |= ast_custom_function_unregister(&filter_function);
01657    res |= ast_custom_function_unregister(&replace_function);
01658    res |= ast_custom_function_unregister(&listfilter_function);
01659    res |= ast_custom_function_unregister(&regex_function);
01660    res |= ast_custom_function_unregister(&array_function);
01661    res |= ast_custom_function_unregister(&quote_function);
01662    res |= ast_custom_function_unregister(&csv_quote_function);
01663    res |= ast_custom_function_unregister(&len_function);
01664    res |= ast_custom_function_unregister(&strftime_function);
01665    res |= ast_custom_function_unregister(&strptime_function);
01666    res |= ast_custom_function_unregister(&eval_function);
01667    res |= ast_custom_function_unregister(&keypadhash_function);
01668    res |= ast_custom_function_unregister(&hashkeys_function);
01669    res |= ast_custom_function_unregister(&hash_function);
01670    res |= ast_unregister_application(app_clearhash);
01671    res |= ast_custom_function_unregister(&toupper_function);
01672    res |= ast_custom_function_unregister(&tolower_function);
01673    res |= ast_custom_function_unregister(&shift_function);
01674    res |= ast_custom_function_unregister(&pop_function);
01675    res |= ast_custom_function_unregister(&push_function);
01676    res |= ast_custom_function_unregister(&unshift_function);
01677    res |= ast_custom_function_unregister(&passthru_function);
01678 
01679    return res;
01680 }

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

Definition at line 1478 of file func_strings.c.

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), beginning, LOG_WARNING, pbx_builtin_setvar_helper(), result_buf, and var.

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


Variable Documentation

char* app_clearhash = "ClearHash" [static]

Definition at line 886 of file func_strings.c.

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

Definition at line 1115 of file func_strings.c.

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

Definition at line 1189 of file func_strings.c.

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

Definition at line 1314 of file func_strings.c.

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

Definition at line 556 of file func_strings.c.

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

Definition at line 477 of file func_strings.c.

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

Definition at line 766 of file func_strings.c.

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

Definition at line 1103 of file func_strings.c.

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

Definition at line 1109 of file func_strings.c.

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

Definition at line 1355 of file func_strings.c.

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

Definition at line 1206 of file func_strings.c.

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

Definition at line 684 of file func_strings.c.

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

Definition at line 1540 of file func_strings.c.

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

Definition at line 1473 of file func_strings.c.

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

Definition at line 1524 of file func_strings.c.

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

Definition at line 1154 of file func_strings.c.

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

Definition at line 878 of file func_strings.c.

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

Definition at line 836 of file func_strings.c.

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

Definition at line 1468 of file func_strings.c.

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

Definition at line 1241 of file func_strings.c.

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

Definition at line 1283 of file func_strings.c.

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

Definition at line 1412 of file func_strings.c.

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

Definition at line 1383 of file func_strings.c.

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

Definition at line 1529 of file func_strings.c.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1