Sat Feb 11 06:35:45 2012

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 void __init_result_buf (void)
static void __init_tmp_buf (void)
static void __reg_module (void)
static void __unreg_module (void)
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)
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 strreplace (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static int unload_module (void)
static int unshift_push (struct ast_channel *chan, const char *cmd, char *data, const char *new_value)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "String handling dialplan functions" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static char * app_clearhash = "ClearHash"
static struct ast_custom_function array_function
static struct ast_module_infoast_module_info = &__mod_info
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_threadstorage result_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_result_buf , .custom_init = NULL , }
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 strreplace_function
static struct ast_threadstorage tmp_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_tmp_buf , .custom_init = NULL , }
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 991 of file func_strings.c.

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

#define HASH_PREFIX   "~HASH~%s~"

Definition at line 990 of file func_strings.c.

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


Function Documentation

static void __init_result_buf ( void   )  [static]

Definition at line 47 of file func_strings.c.

00065 : If ${example} contains <literal>ex-amp-le</literal>, then ${FIELDQTY(example,-)} returns 3.</para>

static void __init_tmp_buf ( void   )  [static]

Definition at line 48 of file func_strings.c.

00065 : If ${example} contains <literal>ex-amp-le</literal>, then ${FIELDQTY(example,-)} returns 3.</para>

static void __reg_module ( void   )  [static]

Definition at line 1895 of file func_strings.c.

static void __unreg_module ( void   )  [static]

Definition at line 1895 of file func_strings.c.

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

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

01320 {
01321    AST_DECLARE_APP_ARGS(args,
01322               AST_APP_ARG(epoch);
01323               AST_APP_ARG(timezone);
01324               AST_APP_ARG(format);
01325    );
01326    struct timeval when;
01327    struct ast_tm tm;
01328 
01329    buf[0] = '\0';
01330 
01331    AST_STANDARD_APP_ARGS(args, parse);
01332 
01333    ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL);
01334    ast_localtime(&when, &tm, args.timezone);
01335 
01336    if (!args.format)
01337       args.format = "%c";
01338 
01339    if (ast_strftime(buf, buflen, args.format, &tm) <= 0)
01340       ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
01341 
01342    buf[buflen - 1] = '\0';
01343 
01344    return 0;
01345 }

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

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

01354 {
01355    AST_DECLARE_APP_ARGS(args,
01356               AST_APP_ARG(timestring);
01357               AST_APP_ARG(timezone);
01358               AST_APP_ARG(format);
01359    );
01360    struct ast_tm tm;
01361 
01362    buf[0] = '\0';
01363 
01364    if (!data) {
01365       ast_log(LOG_ERROR,
01366             "Asterisk function STRPTIME() requires an argument.\n");
01367       return -1;
01368    }
01369 
01370    AST_STANDARD_APP_ARGS(args, data);
01371 
01372    if (ast_strlen_zero(args.format)) {
01373       ast_log(LOG_ERROR,
01374             "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
01375       return -1;
01376    }
01377 
01378    if (!ast_strptime(args.timestring, args.format, &tm)) {
01379       ast_log(LOG_WARNING, "STRPTIME() found no time specified within the string\n");
01380    } else {
01381       struct timeval when;
01382       when = ast_mktime(&tm, args.timezone);
01383       snprintf(buf, buflen, "%d", (int) when.tv_sec);
01384    }
01385 
01386    return 0;
01387 }

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

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

01019 {
01020    AST_DECLARE_APP_ARGS(arg1,
01021               AST_APP_ARG(var)[100];
01022    );
01023    AST_DECLARE_APP_ARGS(arg2,
01024               AST_APP_ARG(val)[100];
01025    );
01026    char *origvar = "", *value2, varname[256];
01027    int i, ishash = 0;
01028 
01029    value2 = ast_strdupa(value);
01030    if (!var || !value2)
01031       return -1;
01032 
01033    if (!strcmp(cmd, "HASH")) {
01034       const char *var2 = pbx_builtin_getvar_helper(chan, "~ODBCFIELDS~");
01035       origvar = var;
01036       if (var2)
01037          var = ast_strdupa(var2);
01038       else {
01039          if (chan)
01040             ast_autoservice_stop(chan);
01041          return -1;
01042       }
01043       ishash = 1;
01044    }
01045 
01046    /* The functions this will generally be used with are SORT and ODBC_*, which
01047     * both return comma-delimited lists.  However, if somebody uses literal lists,
01048     * their commas will be translated to vertical bars by the load, and I don't
01049     * want them to be surprised by the result.  Hence, we prefer commas as the
01050     * delimiter, but we'll fall back to vertical bars if commas aren't found.
01051     */
01052    ast_debug(1, "array (%s=%s)\n", var, S_OR(value2, ""));
01053    AST_STANDARD_APP_ARGS(arg1, var);
01054 
01055    AST_STANDARD_APP_ARGS(arg2, value2);
01056 
01057    for (i = 0; i < arg1.argc; i++) {
01058       ast_debug(1, "array set value (%s=%s)\n", arg1.var[i],
01059             S_OR(arg2.val[i], ""));
01060       if (i < arg2.argc) {
01061          if (ishash) {
01062             if (origvar[0] == '_') {
01063                if (origvar[1] == '_') {
01064                   snprintf(varname, sizeof(varname), "__" HASH_FORMAT, origvar + 2, arg1.var[i]);
01065                } else {
01066                   snprintf(varname, sizeof(varname), "_" HASH_FORMAT, origvar + 1, arg1.var[i]);
01067                }
01068             } else {
01069                snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
01070             }
01071 
01072             pbx_builtin_setvar_helper(chan, varname, arg2.val[i]);
01073          } else {
01074             pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
01075          }
01076       } else {
01077          /* We could unset the variable, by passing a NULL, but due to
01078           * pushvar semantics, that could create some undesired behavior. */
01079          if (ishash) {
01080             snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
01081             pbx_builtin_setvar_helper(chan, varname, "");
01082          } else {
01083             pbx_builtin_setvar_helper(chan, arg1.var[i], "");
01084          }
01085       }
01086    }
01087 
01088    return 0;
01089 }

static void clearvar_prefix ( struct ast_channel chan,
const char *  prefix 
) [static]

Definition at line 996 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(), ast_var_t::entries, len(), var, and ast_channel::varshead.

Referenced by exec_clearhash().

00997 {
00998    struct ast_var_t *var;
00999    int len = strlen(prefix);
01000    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->varshead, var, entries) {
01001       if (strncasecmp(prefix, ast_var_name(var), len) == 0) {
01002          AST_LIST_REMOVE_CURRENT(entries);
01003          ast_free(var);
01004       }
01005    }
01006    AST_LIST_TRAVERSE_SAFE_END
01007 }

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

Definition at line 1265 of file func_strings.c.

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

01266 {
01267    char *bufptr = buf, *dataptr = data;
01268 
01269    if (len < 3) { /* at least two for quotes and one for binary zero */
01270       ast_log(LOG_ERROR, "Not enough buffer");
01271       return -1;
01272    }
01273 
01274    if (ast_strlen_zero(data)) {
01275       ast_copy_string(buf, "\"\"", len);
01276       return 0;
01277    }
01278 
01279    *bufptr++ = '"';
01280    for (; bufptr < buf + len - 3; dataptr++){
01281       if (*dataptr == '"') {
01282          *bufptr++ = '"';
01283          *bufptr++ = '"';
01284       } else if (*dataptr == '\0') {
01285          break;
01286       } else {
01287          *bufptr++ = *dataptr;
01288       }
01289    }
01290    *bufptr++ = '"';
01291    *bufptr='\0';
01292    return 0;
01293 }

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

Definition at line 1009 of file func_strings.c.

References clearvar_prefix(), HASH_PREFIX, and prefix.

Referenced by load_module().

01010 {
01011    char prefix[80];
01012    snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null");
01013    clearvar_prefix(chan, prefix);
01014    return 0;
01015 }

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 708 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(), action_filter(), data_filter_destructor(), data_filter_generate(), data_result_generate(), manager_data_get(), realtime_ldap_base_ap(), update2_ldap(), and update_ldap().

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

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

Definition at line 1394 of file func_strings.c.

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

01396 {
01397    if (ast_strlen_zero(data)) {
01398       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
01399       return -1;
01400    }
01401 
01402    pbx_substitute_variables_helper(chan, data, buf, buflen - 1);
01403 
01404    return 0;
01405 }

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

Definition at line 1407 of file func_strings.c.

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

01409 {
01410    if (ast_strlen_zero(data)) {
01411       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
01412       return -1;
01413    }
01414 
01415    ast_str_substitute_variables(buf, buflen, chan, data);
01416 
01417    return 0;
01418 }

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

Definition at line 562 of file func_strings.c.

References function_fieldnum_helper().

00564 {
00565    return function_fieldnum_helper(chan, cmd, parse, buf, NULL, len);
00566 }

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

References args, 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, str, and strsep().

Referenced by function_fieldnum(), and function_fieldnum_str().

00503 {
00504    char *varsubst, *field;
00505    struct ast_str *str = ast_str_thread_get(&result_buf, 16);
00506    int fieldindex = 0, res = 0;
00507    AST_DECLARE_APP_ARGS(args,
00508       AST_APP_ARG(varname);
00509       AST_APP_ARG(delim);
00510       AST_APP_ARG(field);
00511    );
00512    char delim[2] = "";
00513    size_t delim_used;
00514 
00515    if (!str) {
00516       return -1;
00517    }
00518 
00519    AST_STANDARD_APP_ARGS(args, parse);
00520 
00521    if (args.argc < 3) {
00522       ast_log(LOG_ERROR, "Usage: FIELDNUM(<listname>,<delimiter>,<fieldvalue>)\n");
00523       res = -1;
00524    } else {
00525       varsubst = alloca(strlen(args.varname) + 4);
00526       sprintf(varsubst, "${%s}", args.varname);
00527 
00528       ast_str_substitute_variables(&str, 0, chan, varsubst);
00529 
00530       if (ast_str_strlen(str) == 0 || ast_strlen_zero(args.delim)) {
00531          fieldindex = 0;
00532       } else if (ast_get_encoded_char(args.delim, delim, &delim_used) == -1) {
00533          res = -1;
00534       } else {
00535          char *varval = ast_str_buffer(str);
00536 
00537          while ((field = strsep(&varval, delim)) != NULL) {
00538             fieldindex++;
00539 
00540             if (!strcasecmp(field, args.field)) {
00541                break;
00542             }
00543          }
00544 
00545          if (!field) {
00546             fieldindex = 0;
00547          }
00548 
00549          res = 0;
00550       }
00551    }
00552 
00553    if (sbuf) {
00554       ast_str_set(sbuf, len, "%d", fieldindex);
00555    } else {
00556       snprintf(buf, len, "%d", fieldindex);
00557    }
00558 
00559    return res;
00560 }

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

References function_fieldnum_helper().

00570 {
00571    return function_fieldnum_helper(chan, cmd, parse, NULL, buf, len);
00572 }

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

Definition at line 483 of file func_strings.c.

References function_fieldqty_helper().

00485 {
00486    return function_fieldqty_helper(chan, cmd, parse, buf, NULL, len);
00487 }

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

References args, 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, str, and strsep().

Referenced by function_fieldqty(), and function_fieldqty_str().

00440 {
00441    char *varsubst;
00442    struct ast_str *str = ast_str_thread_get(&result_buf, 16);
00443    int fieldcount = 0;
00444    AST_DECLARE_APP_ARGS(args,
00445               AST_APP_ARG(varname);
00446               AST_APP_ARG(delim);
00447       );
00448    char delim[2] = "";
00449    size_t delim_used;
00450 
00451    if (!str) {
00452       return -1;
00453    }
00454 
00455    AST_STANDARD_APP_ARGS(args, parse);
00456    if (args.delim) {
00457       ast_get_encoded_char(args.delim, delim, &delim_used);
00458 
00459       varsubst = alloca(strlen(args.varname) + 4);
00460 
00461       sprintf(varsubst, "${%s}", args.varname);
00462       ast_str_substitute_variables(&str, 0, chan, varsubst);
00463       if (ast_str_strlen(str) == 0) {
00464          fieldcount = 0;
00465       } else {
00466          char *varval = ast_str_buffer(str);
00467          while (strsep(&varval, delim)) {
00468             fieldcount++;
00469          }
00470       }
00471    } else {
00472       fieldcount = 1;
00473    }
00474    if (sbuf) {
00475       ast_str_set(sbuf, len, "%d", fieldcount);
00476    } else {
00477       snprintf(buf, len, "%d", fieldcount);
00478    }
00479 
00480    return 0;
00481 }

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

References function_fieldqty_helper().

00491 {
00492    return function_fieldqty_helper(chan, cmd, parse, NULL, buf, len);
00493 }

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

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

01164 {
01165    char varname[256];
01166    const char *varvalue;
01167    AST_DECLARE_APP_ARGS(arg,
01168       AST_APP_ARG(hashname);
01169       AST_APP_ARG(hashkey);
01170    );
01171 
01172    AST_STANDARD_APP_ARGS(arg, data);
01173    if (arg.argc == 2) {
01174       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
01175       varvalue = pbx_builtin_getvar_helper(chan, varname);
01176       if (varvalue)
01177          ast_copy_string(buf, varvalue, len);
01178       else
01179          *buf = '\0';
01180    } else if (arg.argc == 1) {
01181       char colnames[4096];
01182       int i;
01183       AST_DECLARE_APP_ARGS(arg2,
01184          AST_APP_ARG(col)[100];
01185       );
01186 
01187       /* Get column names, in no particular order */
01188       hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames));
01189       pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames);
01190 
01191       AST_STANDARD_APP_ARGS(arg2, colnames);
01192       *buf = '\0';
01193 
01194       /* Now get the corresponding column values, in exactly the same order */
01195       for (i = 0; i < arg2.argc; i++) {
01196          snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]);
01197          varvalue = pbx_builtin_getvar_helper(chan, varname);
01198          strncat(buf, varvalue, len - strlen(buf) - 1);
01199          strncat(buf, ",", len - strlen(buf) - 1);
01200       }
01201 
01202       /* Strip trailing comma */
01203       buf[strlen(buf) - 1] = '\0';
01204    }
01205 
01206    return 0;
01207 }

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

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

01136 {
01137    char varname[256];
01138    AST_DECLARE_APP_ARGS(arg,
01139       AST_APP_ARG(hashname);
01140       AST_APP_ARG(hashkey);
01141    );
01142 
01143    if (!strchr(var, ',')) {
01144       /* Single argument version */
01145       return array(chan, "HASH", var, value);
01146    }
01147 
01148    AST_STANDARD_APP_ARGS(arg, var);
01149    if (arg.hashname[0] == '_') {
01150       if (arg.hashname[1] == '_') {
01151          snprintf(varname, sizeof(varname), "__" HASH_FORMAT, arg.hashname + 2, arg.hashkey);
01152       } else {
01153          snprintf(varname, sizeof(varname), "_" HASH_FORMAT, arg.hashname + 1, arg.hashkey);
01154       }
01155    } else {
01156       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
01157    }
01158    pbx_builtin_setvar_helper(chan, varname, value);
01159 
01160    return 0;
01161 }

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

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

01092 {
01093    struct ast_var_t *newvar;
01094    struct ast_str *prefix = ast_str_alloca(80);
01095 
01096    ast_str_set(&prefix, -1, HASH_PREFIX, data);
01097    memset(buf, 0, len);
01098 
01099    AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) {
01100       if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) {
01101          /* Copy everything after the prefix */
01102          strncat(buf, ast_var_name(newvar) + ast_str_strlen(prefix), len - strlen(buf) - 1);
01103          /* Trim the trailing ~ */
01104          buf[strlen(buf) - 1] = ',';
01105       }
01106    }
01107    /* Trim the trailing comma */
01108    buf[strlen(buf) - 1] = '\0';
01109    return 0;
01110 }

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

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

01113 {
01114    struct ast_var_t *newvar;
01115    struct ast_str *prefix = ast_str_alloca(80);
01116    char *tmp;
01117 
01118    ast_str_set(&prefix, -1, HASH_PREFIX, data);
01119 
01120    AST_LIST_TRAVERSE(&chan->varshead, newvar, entries) {
01121       if (strncasecmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) {
01122          /* Copy everything after the prefix */
01123          ast_str_append(buf, len, "%s", ast_var_name(newvar) + ast_str_strlen(prefix));
01124          /* Trim the trailing ~ */
01125          tmp = ast_str_buffer(*buf);
01126          tmp[ast_str_strlen(*buf) - 1] = ',';
01127       }
01128    }
01129    /* Trim the trailing comma */
01130    tmp = ast_str_buffer(*buf);
01131    tmp[ast_str_strlen(*buf) - 1] = '\0';
01132    return 0;
01133 }

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

Definition at line 1426 of file func_strings.c.

01427 {
01428    char *bufptr, *dataptr;
01429 
01430    for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) {
01431       if (*dataptr == '\0') {
01432          *bufptr++ = '\0';
01433          break;
01434       } else if (*dataptr == '1') {
01435          *bufptr++ = '1';
01436       } else if (strchr("AaBbCc2", *dataptr)) {
01437          *bufptr++ = '2';
01438       } else if (strchr("DdEeFf3", *dataptr)) {
01439          *bufptr++ = '3';
01440       } else if (strchr("GgHhIi4", *dataptr)) {
01441          *bufptr++ = '4';
01442       } else if (strchr("JjKkLl5", *dataptr)) {
01443          *bufptr++ = '5';
01444       } else if (strchr("MmNnOo6", *dataptr)) {
01445          *bufptr++ = '6';
01446       } else if (strchr("PpQqRrSs7", *dataptr)) {
01447          *bufptr++ = '7';
01448       } else if (strchr("TtUuVv8", *dataptr)) {
01449          *bufptr++ = '8';
01450       } else if (strchr("WwXxYyZz9", *dataptr)) {
01451          *bufptr++ = '9';
01452       } else if (*dataptr == '0') {
01453          *bufptr++ = '0';
01454       }
01455    }
01456    buf[buflen - 1] = '\0';
01457 
01458    return 0;
01459 }

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

Definition at line 1300 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_process(), ast_dsp_silence_noise_with_energy(), ast_format_str_reduce(), ast_frdup(), ast_getformatname_multiple(), ast_getformatname_multiple_byid(), 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(), auth_exec(), authenticate(), build_device(), build_facility(), build_route(), callerid_generate(), cleaned_basedn(), clearvar_prefix(), cli_console_sendtext(), complete_agent_logoff_cmd(), 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(), complete_peer_helper(), complete_trans_path_choice(), conf_get_pin(), 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(), expr2_token_subst(), 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_devstate_change(), handle_commandmatchesarray(), handle_incoming(), handle_output(), handle_response(), handle_show_translation_path(), help1(), iax_parse_ies(), iax_str2flags(), load_file(), local_call(), lpc10tolin_framein(), lws2sws(), message_template_parse_emailbody(), method_match(), mgcp_ss(), mgcpsock_read(), misdn_read(), mktemp_internal(), monmp3thread(), mpeg4_encap(), newpvt(), ogg_vorbis_read(), parse_ie(), ParseBookmark(), pbx_substitute_variables_helper_full(), phoneprov_callback(), process_sdp(), readfile_exec(), receive_message(), red_t140_to_red(), reschedule_precache(), run_agi(), set(), sip_addheader(), sip_show_channel(), sip_show_history(), skinny_ss(), sms_messagetx(), socket_read(), static_callback(), strndup(), strnlen(), term_filter_escapes(), transfer_exec(), udptl_build_packet(), unistim_sp(), unquote(), and wav_write().

01301 {
01302    int length = 0;
01303 
01304    if (data)
01305       length = strlen(data);
01306 
01307    snprintf(buf, buflen, "%d", length);
01308 
01309    return 0;
01310 }

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

References args, 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, result_buf, and tmp_buf.

Referenced by listfilter_read(), and listfilter_read2().

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

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

Definition at line 692 of file func_strings.c.

References listfilter().

00693 {
00694    return listfilter(chan, cmd, parse, buf, NULL, len);
00695 }

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

Definition at line 697 of file func_strings.c.

References listfilter().

00698 {
00699    return listfilter(chan, cmd, parse, NULL, buf, len);
00700 }

static int load_module ( void   )  [static]

Definition at line 1859 of file func_strings.c.

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

01860 {
01861    int res = 0;
01862 
01863    AST_TEST_REGISTER(test_FIELDNUM);
01864    AST_TEST_REGISTER(test_FILTER);
01865    AST_TEST_REGISTER(test_STRREPLACE);
01866    res |= ast_custom_function_register(&fieldqty_function);
01867    res |= ast_custom_function_register(&fieldnum_function);
01868    res |= ast_custom_function_register(&filter_function);
01869    res |= ast_custom_function_register(&replace_function);
01870    res |= ast_custom_function_register(&strreplace_function);
01871    res |= ast_custom_function_register(&listfilter_function);
01872    res |= ast_custom_function_register(&regex_function);
01873    res |= ast_custom_function_register(&array_function);
01874    res |= ast_custom_function_register(&quote_function);
01875    res |= ast_custom_function_register(&csv_quote_function);
01876    res |= ast_custom_function_register(&len_function);
01877    res |= ast_custom_function_register(&strftime_function);
01878    res |= ast_custom_function_register(&strptime_function);
01879    res |= ast_custom_function_register(&eval_function);
01880    res |= ast_custom_function_register(&keypadhash_function);
01881    res |= ast_custom_function_register(&hashkeys_function);
01882    res |= ast_custom_function_register(&hash_function);
01883    res |= ast_register_application_xml(app_clearhash, exec_clearhash);
01884    res |= ast_custom_function_register(&toupper_function);
01885    res |= ast_custom_function_register(&tolower_function);
01886    res |= ast_custom_function_register(&shift_function);
01887    res |= ast_custom_function_register(&pop_function);
01888    res |= ast_custom_function_register(&push_function);
01889    res |= ast_custom_function_register(&unshift_function);
01890    res |= ast_custom_function_register(&passthru_function);
01891 
01892    return res;
01893 }

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

Definition at line 1640 of file func_strings.c.

References ast_str_set().

01641 {
01642    ast_str_set(buf, len, "%s", data);
01643    return 0;
01644 }

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

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

01227 {
01228    char *bufptr = buf, *dataptr = data;
01229 
01230    if (len < 3){ /* at least two for quotes and one for binary zero */
01231       ast_log(LOG_ERROR, "Not enough buffer");
01232       return -1;
01233    }
01234 
01235    if (ast_strlen_zero(data)) {
01236       ast_log(LOG_WARNING, "No argument specified!\n");
01237       ast_copy_string(buf, "\"\"", len);
01238       return 0;
01239    }
01240 
01241    *bufptr++ = '"';
01242    for (; bufptr < buf + len - 3; dataptr++) {
01243       if (*dataptr == '\\') {
01244          *bufptr++ = '\\';
01245          *bufptr++ = '\\';
01246       } else if (*dataptr == '"') {
01247          *bufptr++ = '\\';
01248          *bufptr++ = '"';
01249       } else if (*dataptr == '\0') {
01250          break;
01251       } else {
01252          *bufptr++ = *dataptr;
01253       }
01254    }
01255    *bufptr++ = '"';
01256    *bufptr = '\0';
01257    return 0;
01258 }

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

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

00950 {
00951    AST_DECLARE_APP_ARGS(args,
00952               AST_APP_ARG(null);
00953               AST_APP_ARG(reg);
00954               AST_APP_ARG(str);
00955    );
00956    int errcode;
00957    regex_t regexbuf;
00958 
00959    buf[0] = '\0';
00960 
00961    AST_NONSTANDARD_APP_ARGS(args, parse, '"');
00962 
00963    if (args.argc != 3) {
00964       ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n");
00965       return -1;
00966    }
00967    if ((*args.str == ' ') || (*args.str == '\t'))
00968       args.str++;
00969 
00970    ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
00971 
00972    if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
00973       regerror(errcode, &regexbuf, buf, len);
00974       ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
00975       return -1;
00976    }
00977    
00978    strcpy(buf, regexec(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
00979 
00980    regfree(&regexbuf);
00981 
00982    return 0;
00983 }

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

Definition at line 789 of file func_strings.c.

References args, 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().

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

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

Definition at line 1524 of file func_strings.c.

References args, 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.

01525 {
01526 #define beginning (cmd[0] == 'S') /* SHIFT */
01527    char *after, delimiter[2] = ",", *varsubst;
01528    size_t unused;
01529    struct ast_str *before = ast_str_thread_get(&result_buf, 16);
01530    char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr);
01531    AST_DECLARE_APP_ARGS(args,
01532       AST_APP_ARG(var);
01533       AST_APP_ARG(delimiter);
01534    );
01535 
01536    if (!before) {
01537       return -1;
01538    }
01539 
01540    AST_STANDARD_APP_ARGS(args, data);
01541 
01542    if (ast_strlen_zero(args.var)) {
01543       ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
01544       return -1;
01545    }
01546 
01547    varsubst = alloca(strlen(args.var) + 4);
01548    sprintf(varsubst, "${%s}", args.var);
01549    ast_str_substitute_variables(&before, 0, chan, varsubst);
01550 
01551    if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
01552       ast_get_encoded_char(args.delimiter, delimiter, &unused);
01553    }
01554 
01555    if (!ast_str_strlen(before)) {
01556       /* Nothing to pop */
01557       return -1;
01558    }
01559 
01560    if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) {
01561       /* Only one entry in array */
01562       ast_str_set(buf, len, "%s", ast_str_buffer(before));
01563       pbx_builtin_setvar_helper(chan, args.var, "");
01564    } else {
01565       *after++ = '\0';
01566       ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after);
01567       pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before));
01568    }
01569 
01570    return 0;
01571 #undef beginning
01572 }

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

Definition at line 1495 of file func_strings.c.

01496 {
01497    char *bufptr = buf, *dataptr = data;
01498 
01499    while ((bufptr < buf + buflen - 1) && (*bufptr++ = tolower(*dataptr++)));
01500 
01501    return 0;
01502 }

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

Definition at line 1504 of file func_strings.c.

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

01505 {
01506    char *bufptr, *dataptr = data;
01507 
01508    if (buflen > -1) {
01509       ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
01510    }
01511    bufptr = ast_str_buffer(*buf);
01512    while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++)));
01513    ast_str_update(*buf);
01514 
01515    return 0;
01516 }

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

Definition at line 1466 of file func_strings.c.

01467 {
01468    char *bufptr = buf, *dataptr = data;
01469 
01470    while ((bufptr < buf + buflen - 1) && (*bufptr++ = toupper(*dataptr++)));
01471 
01472    return 0;
01473 }

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

Definition at line 1475 of file func_strings.c.

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

01476 {
01477    char *bufptr, *dataptr = data;
01478 
01479    if (buflen > -1) {
01480       ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
01481    }
01482    bufptr = ast_str_buffer(*buf);
01483    while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++)));
01484    ast_str_update(*buf);
01485 
01486    return 0;
01487 }

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

Definition at line 859 of file func_strings.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_substitute_variables(), ast_str_thread_get(), ast_strlen_zero(), LOG_ERROR, result_buf, and str.

00860 {
00861    char *varsubstr; /* substring for input var */
00862    char *start; /* Starting pos of substring search. */
00863    char *end; /* Ending pos of substring search. */
00864    int find_size; /* length of given find-string */
00865    unsigned max_matches; /* number of matches we find before terminating search */
00866    unsigned count; /* loop counter */
00867    struct ast_str *str = ast_str_thread_get(&result_buf, 16); /* Holds the data obtained from varname */
00868 
00869    AST_DECLARE_APP_ARGS(args,
00870       AST_APP_ARG(varname);
00871       AST_APP_ARG(find_string);
00872       AST_APP_ARG(replace_string);
00873       AST_APP_ARG(max_replacements);
00874       AST_APP_ARG(other);  /* Any remining unused arguments */
00875    );
00876 
00877    /* Guarantee output string is empty to start with. */
00878    ast_str_reset(*buf);
00879 
00880    if (!str) {
00881       /* We failed to allocate str, forget it.  We failed. */
00882       return -1;
00883    }
00884 
00885    /* Parse the arguments. */
00886    AST_STANDARD_APP_ARGS(args, data);
00887 
00888    if (args.argc < 2) {
00889       /* Didn't receive enough arguments to do anything */
00890       ast_log(LOG_ERROR,
00891          "Usage: %s(<varname>,<find-string>[,<replace-string>,[<max-replacements>]])\n",
00892          cmd);
00893       return -1;
00894    }
00895 
00896    /* No var name specified. Return failure, string is already empty. */
00897    if (ast_strlen_zero(args.varname)) {
00898       return -1;
00899    }
00900 
00901    /* Zero length find strings are a no-no. Kill the function if we run into one. */
00902    if (ast_strlen_zero(args.find_string)) {
00903       ast_log(LOG_ERROR, "No <find-string> specified\n");
00904       return -1;
00905    }
00906    find_size = strlen(args.find_string);
00907 
00908    /* set varsubstr to the matching variable */
00909    varsubstr = alloca(strlen(args.varname) + 4);
00910    sprintf(varsubstr, "${%s}", args.varname);
00911    ast_str_substitute_variables(&str, 0, chan, varsubstr);
00912 
00913    /* Determine how many replacements are allowed. */
00914    if (!args.max_replacements
00915       || (max_matches = atoi(args.max_replacements)) <= 0) {
00916       /* Unlimited replacements are allowed. */
00917       max_matches = -1;
00918    }
00919 
00920    /* Generate the search and replaced string. */
00921    start = ast_str_buffer(str);
00922    for (count = 0; count < max_matches; ++count) {
00923       end = strstr(start, args.find_string);
00924       if (!end) {
00925          /* Did not find a matching substring in the remainder. */
00926          break;
00927       }
00928 
00929       /* Replace the found substring. */
00930       *end = '\0';
00931       ast_str_append(buf, len, "%s", start);
00932       if (args.replace_string) {
00933          /* Append the replacement string */
00934          ast_str_append(buf, len, "%s", args.replace_string);
00935       }
00936       start = end + find_size;
00937    }
00938    ast_str_append(buf, len, "%s", start);
00939 
00940    return 0;
00941 }

static int unload_module ( void   )  [static]

Definition at line 1823 of file func_strings.c.

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

01824 {
01825    int res = 0;
01826 
01827    AST_TEST_UNREGISTER(test_FIELDNUM);
01828    AST_TEST_UNREGISTER(test_FILTER);
01829    AST_TEST_UNREGISTER(test_STRREPLACE);
01830    res |= ast_custom_function_unregister(&fieldqty_function);
01831    res |= ast_custom_function_unregister(&fieldnum_function);
01832    res |= ast_custom_function_unregister(&filter_function);
01833    res |= ast_custom_function_unregister(&replace_function);
01834    res |= ast_custom_function_unregister(&strreplace_function);
01835    res |= ast_custom_function_unregister(&listfilter_function);
01836    res |= ast_custom_function_unregister(&regex_function);
01837    res |= ast_custom_function_unregister(&array_function);
01838    res |= ast_custom_function_unregister(&quote_function);
01839    res |= ast_custom_function_unregister(&csv_quote_function);
01840    res |= ast_custom_function_unregister(&len_function);
01841    res |= ast_custom_function_unregister(&strftime_function);
01842    res |= ast_custom_function_unregister(&strptime_function);
01843    res |= ast_custom_function_unregister(&eval_function);
01844    res |= ast_custom_function_unregister(&keypadhash_function);
01845    res |= ast_custom_function_unregister(&hashkeys_function);
01846    res |= ast_custom_function_unregister(&hash_function);
01847    res |= ast_unregister_application(app_clearhash);
01848    res |= ast_custom_function_unregister(&toupper_function);
01849    res |= ast_custom_function_unregister(&tolower_function);
01850    res |= ast_custom_function_unregister(&shift_function);
01851    res |= ast_custom_function_unregister(&pop_function);
01852    res |= ast_custom_function_unregister(&push_function);
01853    res |= ast_custom_function_unregister(&unshift_function);
01854    res |= ast_custom_function_unregister(&passthru_function);
01855 
01856    return res;
01857 }

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

Definition at line 1584 of file func_strings.c.

References args, 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, tmp_buf, and var.

01585 {
01586 #define beginning (cmd[0] == 'U') /* UNSHIFT */
01587    char delimiter[2] = ",", *varsubst;
01588    size_t unused;
01589    struct ast_str *buf, *previous_value;
01590    AST_DECLARE_APP_ARGS(args,
01591       AST_APP_ARG(var);
01592       AST_APP_ARG(delimiter);
01593    );
01594 
01595    if (!(buf = ast_str_thread_get(&result_buf, 16)) ||
01596       !(previous_value = ast_str_thread_get(&tmp_buf, 16))) {
01597       return -1;
01598    }
01599 
01600    AST_STANDARD_APP_ARGS(args, data);
01601 
01602    if (ast_strlen_zero(args.var)) {
01603       ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
01604       return -1;
01605    }
01606 
01607    if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
01608       ast_get_encoded_char(args.delimiter, delimiter, &unused);
01609    }
01610 
01611    varsubst = alloca(strlen(args.var) + 4);
01612    sprintf(varsubst, "${%s}", args.var);
01613    ast_str_substitute_variables(&previous_value, 0, chan, varsubst);
01614 
01615    if (!ast_str_strlen(previous_value)) {
01616       ast_str_set(&buf, 0, "%s", new_value);
01617    } else {
01618       ast_str_set(&buf, 0, "%s%c%s",
01619          beginning ? new_value : ast_str_buffer(previous_value),
01620          delimiter[0],
01621          beginning ? ast_str_buffer(previous_value) : new_value);
01622    }
01623 
01624    pbx_builtin_setvar_helper(chan, args.var, ast_str_buffer(buf));
01625 
01626    return 0;
01627 #undef beginning
01628 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "String handling dialplan functions" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 1895 of file func_strings.c.

char* app_clearhash = "ClearHash" [static]

Definition at line 993 of file func_strings.c.

Initial value:

 {
   .name = "ARRAY",
   .write = array,
}

Definition at line 1221 of file func_strings.c.

Definition at line 1895 of file func_strings.c.

Initial value:

 {
   .name = "CSV_QUOTE",
   .read = csv_quote,
}

Definition at line 1295 of file func_strings.c.

Initial value:

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

Definition at line 1420 of file func_strings.c.

Initial value:

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

Definition at line 574 of file func_strings.c.

Initial value:

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

Definition at line 495 of file func_strings.c.

Initial value:

 {
   .name = "FILTER",
   .read = filter,
}

Definition at line 784 of file func_strings.c.

Initial value:

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

Definition at line 1209 of file func_strings.c.

Initial value:

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

Definition at line 1215 of file func_strings.c.

Initial value:

 {
   .name = "KEYPADHASH",
   .read = keypadhash,
}

Definition at line 1461 of file func_strings.c.

Initial value:

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

Definition at line 1312 of file func_strings.c.

Initial value:

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

Definition at line 702 of file func_strings.c.

Initial value:

 {
   .name = "PASSTHRU",
   .read2 = passthru,
}

Definition at line 1646 of file func_strings.c.

Initial value:

 {
   .name = "POP",
   .read2 = shift_pop,
}

Definition at line 1579 of file func_strings.c.

Initial value:

 {
   .name = "PUSH",
   .write = unshift_push,
}

Definition at line 1630 of file func_strings.c.

Initial value:

 {
   .name = "QUOTE",
   .read = quote,
}

Definition at line 1260 of file func_strings.c.

Initial value:

 {
   .name = "REGEX",
   .read = regex,
}

Definition at line 985 of file func_strings.c.

Initial value:

 {
   .name = "REPLACE",
   .read2 = replace,
}

Definition at line 854 of file func_strings.c.

struct ast_threadstorage result_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_result_buf , .custom_init = NULL , } [static]

Definition at line 47 of file func_strings.c.

Initial value:

 {
   .name = "SHIFT",
   .read2 = shift_pop,
}

Definition at line 1574 of file func_strings.c.

Initial value:

 {
   .name = "STRFTIME",
   .read = acf_strftime,
}

Definition at line 1347 of file func_strings.c.

Initial value:

 {
   .name = "STRPTIME",
   .read = acf_strptime,
}

Definition at line 1389 of file func_strings.c.

Initial value:

 {
   .name = "STRREPLACE",
   .read2 = strreplace,
}

Definition at line 943 of file func_strings.c.

struct ast_threadstorage tmp_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_tmp_buf , .custom_init = NULL , } [static]

Definition at line 48 of file func_strings.c.

Referenced by listfilter(), remote_bridge_loop(), and unshift_push().

Initial value:

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

Definition at line 1518 of file func_strings.c.

Initial value:

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

Definition at line 1489 of file func_strings.c.

Initial value:

 {
   .name = "UNSHIFT",
   .write = unshift_push,
}

Definition at line 1635 of file func_strings.c.


Generated on Sat Feb 11 06:35:45 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6