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, .support_level = AST_MODULE_SUPPORT_CORE, }
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 994 of file func_strings.c.

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

#define HASH_PREFIX   "~HASH~%s~"

Definition at line 993 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 2007 of file func_strings.c.

static void __unreg_module ( void   )  [static]

Definition at line 2007 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 1337 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, LOG_WARNING, and NULL.

01339 {
01340    AST_DECLARE_APP_ARGS(args,
01341               AST_APP_ARG(epoch);
01342               AST_APP_ARG(timezone);
01343               AST_APP_ARG(format);
01344    );
01345    struct timeval when;
01346    struct ast_tm tm;
01347 
01348    buf[0] = '\0';
01349 
01350    AST_STANDARD_APP_ARGS(args, parse);
01351 
01352    ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL);
01353    ast_localtime(&when, &tm, args.timezone);
01354 
01355    if (!args.format)
01356       args.format = "%c";
01357 
01358    if (ast_strftime(buf, buflen, args.format, &tm) <= 0)
01359       ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
01360 
01361    buf[buflen - 1] = '\0';
01362 
01363    return 0;
01364 }

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

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

01373 {
01374    AST_DECLARE_APP_ARGS(args,
01375               AST_APP_ARG(timestring);
01376               AST_APP_ARG(timezone);
01377               AST_APP_ARG(format);
01378    );
01379    struct ast_tm tm;
01380 
01381    buf[0] = '\0';
01382 
01383    if (!data) {
01384       ast_log(LOG_ERROR,
01385             "Asterisk function STRPTIME() requires an argument.\n");
01386       return -1;
01387    }
01388 
01389    AST_STANDARD_APP_ARGS(args, data);
01390 
01391    if (ast_strlen_zero(args.format)) {
01392       ast_log(LOG_ERROR,
01393             "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
01394       return -1;
01395    }
01396 
01397    if (!ast_strptime(args.timestring, args.format, &tm)) {
01398       ast_log(LOG_WARNING, "STRPTIME() found no time specified within the string\n");
01399    } else {
01400       struct timeval when;
01401       when = ast_mktime(&tm, args.timezone);
01402       snprintf(buf, buflen, "%d", (int) when.tv_sec);
01403    }
01404 
01405    return 0;
01406 }

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

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 1020 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 append_json(), device_to_json_cb(), devices_to_json(), hash_write(), json_array_from_list(), stasis_app_device_states_to_json(), and stasis_app_mailboxes_to_json().

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

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

Definition at line 999 of file func_strings.c.

References ast_channel_varshead(), ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_var_name(), ast_var_t::entries, len(), and var.

Referenced by exec_clearhash().

01000 {
01001    struct ast_var_t *var;
01002    int len = strlen(prefix);
01003    AST_LIST_TRAVERSE_SAFE_BEGIN(ast_channel_varshead(chan), var, entries) {
01004       if (strncmp(prefix, ast_var_name(var), len) == 0) {
01005          AST_LIST_REMOVE_CURRENT(entries);
01006          ast_free(var);
01007       }
01008    }
01009    AST_LIST_TRAVERSE_SAFE_END
01010 }

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

Definition at line 1284 of file func_strings.c.

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

01285 {
01286    char *bufptr = buf, *dataptr = data;
01287 
01288    if (len < 3) { /* at least two for quotes and one for binary zero */
01289       ast_log(LOG_ERROR, "Not enough buffer\n");
01290       return -1;
01291    }
01292 
01293    if (ast_strlen_zero(data)) {
01294       ast_copy_string(buf, "\"\"", len);
01295       return 0;
01296    }
01297 
01298    *bufptr++ = '"';
01299    for (; bufptr < buf + len - 3; dataptr++){
01300       if (*dataptr == '"') {
01301          *bufptr++ = '"';
01302          *bufptr++ = '"';
01303       } else if (*dataptr == '\0') {
01304          break;
01305       } else {
01306          *bufptr++ = *dataptr;
01307       }
01308    }
01309    *bufptr++ = '"';
01310    *bufptr='\0';
01311    return 0;
01312 }

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

Definition at line 1012 of file func_strings.c.

References clearvar_prefix(), HASH_PREFIX, and prefix.

Referenced by load_module().

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

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 712 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(), action_getconfig(), action_getconfigjson(), data_filter_destructor(), data_filter_generate(), data_result_generate(), kqueue_timer_ack(), manager_data_get(), realtime_ldap_base_ap(), update2_ldap(), and update_ldap().

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

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

Definition at line 1413 of file func_strings.c.

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

01415 {
01416    if (ast_strlen_zero(data)) {
01417       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
01418       return -1;
01419    }
01420 
01421    pbx_substitute_variables_helper(chan, data, buf, buflen - 1);
01422 
01423    return 0;
01424 }

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

Definition at line 1426 of file func_strings.c.

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

01428 {
01429    if (ast_strlen_zero(data)) {
01430       ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
01431       return -1;
01432    }
01433 
01434    ast_str_substitute_variables(buf, buflen, chan, data);
01435 
01436    return 0;
01437 }

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

Definition at line 566 of file func_strings.c.

References function_fieldnum_helper(), and NULL.

00568 {
00569    return function_fieldnum_helper(chan, cmd, parse, buf, NULL, len);
00570 }

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 505 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, NULL, result_buf, str, and strsep().

Referenced by function_fieldnum(), and function_fieldnum_str().

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

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

References function_fieldnum_helper(), and NULL.

00574 {
00575    return function_fieldnum_helper(chan, cmd, parse, NULL, buf, len);
00576 }

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

Definition at line 487 of file func_strings.c.

References function_fieldqty_helper(), and NULL.

00489 {
00490    return function_fieldqty_helper(chan, cmd, parse, buf, NULL, len);
00491 }

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

Referenced by function_fieldqty(), and function_fieldqty_str().

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

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

References function_fieldqty_helper(), and NULL.

00495 {
00496    return function_fieldqty_helper(chan, cmd, parse, NULL, buf, len);
00497 }

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

Definition at line 1177 of file func_strings.c.

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

01178 {
01179    char varname[256];
01180    const char *varvalue;
01181    AST_DECLARE_APP_ARGS(arg,
01182       AST_APP_ARG(hashname);
01183       AST_APP_ARG(hashkey);
01184    );
01185 
01186    AST_STANDARD_APP_ARGS(arg, data);
01187    if (arg.argc == 2) {
01188       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
01189       varvalue = pbx_builtin_getvar_helper(chan, varname);
01190       if (varvalue)
01191          ast_copy_string(buf, varvalue, len);
01192       else
01193          *buf = '\0';
01194    } else if (arg.argc == 1) {
01195       char colnames[4096];
01196       int i;
01197       AST_DECLARE_APP_ARGS(arg2,
01198          AST_APP_ARG(col)[100];
01199       );
01200 
01201       if (!chan) {
01202          ast_log(LOG_WARNING, "No channel and only 1 parameter was provided to %s function.\n", cmd);
01203          return -1;
01204       }
01205 
01206       /* Get column names, in no particular order */
01207       hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames));
01208       pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames);
01209 
01210       AST_STANDARD_APP_ARGS(arg2, colnames);
01211       *buf = '\0';
01212 
01213       /* Now get the corresponding column values, in exactly the same order */
01214       for (i = 0; i < arg2.argc; i++) {
01215          snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]);
01216          varvalue = pbx_builtin_getvar_helper(chan, varname);
01217          strncat(buf, varvalue, len - strlen(buf) - 1);
01218          strncat(buf, ",", len - strlen(buf) - 1);
01219       }
01220 
01221       /* Strip trailing comma */
01222       buf[strlen(buf) - 1] = '\0';
01223    }
01224 
01225    return 0;
01226 }

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

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

01150 {
01151    char varname[256];
01152    AST_DECLARE_APP_ARGS(arg,
01153       AST_APP_ARG(hashname);
01154       AST_APP_ARG(hashkey);
01155    );
01156 
01157    if (!strchr(var, ',')) {
01158       /* Single argument version */
01159       return array(chan, "HASH", var, value);
01160    }
01161 
01162    AST_STANDARD_APP_ARGS(arg, var);
01163    if (arg.hashname[0] == '_') {
01164       if (arg.hashname[1] == '_') {
01165          snprintf(varname, sizeof(varname), "__" HASH_FORMAT, arg.hashname + 2, arg.hashkey);
01166       } else {
01167          snprintf(varname, sizeof(varname), "_" HASH_FORMAT, arg.hashname + 1, arg.hashkey);
01168       }
01169    } else {
01170       snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
01171    }
01172    pbx_builtin_setvar_helper(chan, varname, value);
01173 
01174    return 0;
01175 }

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

Definition at line 1095 of file func_strings.c.

References ast_channel_varshead(), AST_LIST_TRAVERSE, ast_log, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, LOG_WARNING, and prefix.

Referenced by hash_read().

01096 {
01097    struct ast_var_t *newvar;
01098    struct ast_str *prefix = ast_str_alloca(80);
01099 
01100    if (!chan) {
01101       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
01102       return -1;
01103    }
01104 
01105    ast_str_set(&prefix, -1, HASH_PREFIX, data);
01106    memset(buf, 0, len);
01107 
01108    AST_LIST_TRAVERSE(ast_channel_varshead(chan), newvar, entries) {
01109       if (strncmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) {
01110          /* Copy everything after the prefix */
01111          strncat(buf, ast_var_name(newvar) + ast_str_strlen(prefix), len - strlen(buf) - 1);
01112          /* Trim the trailing ~ */
01113          buf[strlen(buf) - 1] = ',';
01114       }
01115    }
01116    /* Trim the trailing comma */
01117    buf[strlen(buf) - 1] = '\0';
01118    return 0;
01119 }

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

Definition at line 1121 of file func_strings.c.

References ast_channel_varshead(), AST_LIST_TRAVERSE, ast_log, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_var_name(), HASH_PREFIX, LOG_WARNING, prefix, and tmp().

01122 {
01123    struct ast_var_t *newvar;
01124    struct ast_str *prefix = ast_str_alloca(80);
01125    char *tmp;
01126 
01127    if (!chan) {
01128       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
01129       return -1;
01130    }
01131 
01132    ast_str_set(&prefix, -1, HASH_PREFIX, data);
01133 
01134    AST_LIST_TRAVERSE(ast_channel_varshead(chan), newvar, entries) {
01135       if (strncmp(ast_str_buffer(prefix), ast_var_name(newvar), ast_str_strlen(prefix)) == 0) {
01136          /* Copy everything after the prefix */
01137          ast_str_append(buf, len, "%s", ast_var_name(newvar) + ast_str_strlen(prefix));
01138          /* Trim the trailing ~ */
01139          tmp = ast_str_buffer(*buf);
01140          tmp[ast_str_strlen(*buf) - 1] = ',';
01141       }
01142    }
01143    /* Trim the trailing comma */
01144    tmp = ast_str_buffer(*buf);
01145    tmp[ast_str_strlen(*buf) - 1] = '\0';
01146    return 0;
01147 }

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

Definition at line 1445 of file func_strings.c.

01446 {
01447    char *bufptr, *dataptr;
01448 
01449    for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) {
01450       if (*dataptr == '\0') {
01451          *bufptr++ = '\0';
01452          break;
01453       } else if (*dataptr == '1') {
01454          *bufptr++ = '1';
01455       } else if (strchr("AaBbCc2", *dataptr)) {
01456          *bufptr++ = '2';
01457       } else if (strchr("DdEeFf3", *dataptr)) {
01458          *bufptr++ = '3';
01459       } else if (strchr("GgHhIi4", *dataptr)) {
01460          *bufptr++ = '4';
01461       } else if (strchr("JjKkLl5", *dataptr)) {
01462          *bufptr++ = '5';
01463       } else if (strchr("MmNnOo6", *dataptr)) {
01464          *bufptr++ = '6';
01465       } else if (strchr("PpQqRrSs7", *dataptr)) {
01466          *bufptr++ = '7';
01467       } else if (strchr("TtUuVv8", *dataptr)) {
01468          *bufptr++ = '8';
01469       } else if (strchr("WwXxYyZz9", *dataptr)) {
01470          *bufptr++ = '9';
01471       } else if (*dataptr == '0') {
01472          *bufptr++ = '0';
01473       }
01474    }
01475    buf[buflen - 1] = '\0';
01476 
01477    return 0;
01478 }

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

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 1319 of file func_strings.c.

Referenced by __analog_ss_thread(), __ast_cli_register(), __ast_str_helper(), __big_return(), __bt_defcmp(), __bt_defpfx(), __get_header(), __rec_fmap(), __rec_fpipe(), __rec_vpipe(), __rtp_recvfrom(), __rtp_sendto(), _history_expand_command(), _parse(), _rl_compat_sub(), add_sdp(), ael_token_subst(), 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_beep_start(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_callerid_vmwi_generate(), ast_cli_complete(), ast_complete_source_filename(), ast_dsp_process(), ast_dsp_silence_noise_with_energy(), ast_format_str_reduce(), ast_frdup(), ast_get_namedgroups(), ast_http_send(), ast_http_uri_link(), ast_mkdir(), ast_read_image(), ast_rtcp_write_report(), ast_rtp_read(), ast_rtp_write(), ast_say_number_full_ka(), ast_smoother_read(), ast_statsd_log_full(), ast_str_substitute_variables_full(), AST_TEST_DEFINE(), ast_translate(), ast_udptl_write(), ast_xml_escape(), auth_exec(), authenticate(), bucket_copy(), bucket_file_wizard_retrieve(), bucket_wizard_retrieve(), build_device(), build_facility(), build_regex(), build_route(), c_gets(), callerid_generate(), channel_do_masquerade(), chararray_handler_fn(), cleaned_basedn(), clearvar_prefix(), cli_console_sendtext(), complete(), complete_confno(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_context(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_meetmecmd_list(), complete_meetmecmd_mute_kick(), complete_peer_helper(), complete_userno(), conf_get_pin(), conf_play(), config_jitterbuffer(), cops_getmsg(), copy(), create_video_frame(), dahdi_sendtext(), dahdi_setoption(), dbl_list_expect_reverse(), dbm_open(), devstate_write(), dialgroup_refreshdb(), dictate_exec(), do_pktccops(), dundi_encrypt(), dundi_parse_ies(), dundi_send(), el_insertstr(), el_source(), enc_ie_facility(), expand_gosub_args(), expr2_token_subst(), ext_cmp_exten_strlen(), ffmpeg_decode(), filename_completion_function(), frame_set_var(), get_content_line(), 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_cli_mobile_search(), handle_cli_presencestate_change(), handle_commandmatchesarray(), handle_incoming(), handle_keypad_button_message(), handle_output(), handle_response(), handle_soft_key_event_message(), help1(), history_def_add(), history_expand(), history_next_string(), history_prev_string(), history_save(), history_tokenize(), iax_parse_ies(), iax_str2flags(), load_file(), logger_strip_verbose_magic(), lpc10_decode(), lpc10tolin_framein(), lws2sws(), main(), manager_login(), message_template_parse_emailbody(), method_match(), mgcp_ss(), mgcpsock_read(), misdn_read(), mktemp_internal(), monmp3thread(), mpeg4_encap(), newpvt(), parse_bookmark(), parse_ie(), pbx_substitute_variables_helper_full(), phoneprov_callback(), presence_write(), process_sdp(), receive_message(), red_t140_to_red(), refer_blind_callback(), remove_header(), reschedule_precache(), rl_complete_internal(), run_agi(), sco_accept(), set(), set_bridge_peer_vars_multiparty(), shared_write(), sip_addheader(), sip_route_process_header(), sip_show_channel(), sip_show_history(), sms_messagetx(), socket_read(), start_automixmonitor(), start_automonitor(), static_callback(), strndup(), strnlen(), term_filter_escapes(), tilde_expand(), transfer_exec(), transmit_response_bysession(), try_firmware(), tty_stty(), udptl_build_packet(), unistim_sp(), unquote(), uri_parse_and_default(), wav_write(), xmpp_client_authenticate_sasl(), xmpp_client_receive(), xmpp_client_send_raw_message(), and xmpp_io_recv().

01320 {
01321    int length = 0;
01322 
01323    if (data)
01324       length = strlen(data);
01325 
01326    snprintf(buf, buflen, "%d", length);
01327 
01328    return 0;
01329 }

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 584 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, result, result_buf, and tmp_buf.

Referenced by listfilter_read(), and listfilter_read2().

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

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

Definition at line 696 of file func_strings.c.

References listfilter(), and NULL.

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

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

Definition at line 701 of file func_strings.c.

References listfilter(), and NULL.

00702 {
00703    return listfilter(chan, cmd, parse, NULL, buf, len);
00704 }

static int load_module ( void   )  [static]

Definition at line 1970 of file func_strings.c.

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

01971 {
01972    int res = 0;
01973 
01974    AST_TEST_REGISTER(test_FIELDNUM);
01975    AST_TEST_REGISTER(test_REPLACE);
01976    AST_TEST_REGISTER(test_FILTER);
01977    AST_TEST_REGISTER(test_STRREPLACE);
01978    res |= ast_custom_function_register(&fieldqty_function);
01979    res |= ast_custom_function_register(&fieldnum_function);
01980    res |= ast_custom_function_register(&filter_function);
01981    res |= ast_custom_function_register(&replace_function);
01982    res |= ast_custom_function_register(&strreplace_function);
01983    res |= ast_custom_function_register(&listfilter_function);
01984    res |= ast_custom_function_register(&regex_function);
01985    res |= ast_custom_function_register(&array_function);
01986    res |= ast_custom_function_register(&quote_function);
01987    res |= ast_custom_function_register(&csv_quote_function);
01988    res |= ast_custom_function_register(&len_function);
01989    res |= ast_custom_function_register(&strftime_function);
01990    res |= ast_custom_function_register(&strptime_function);
01991    res |= ast_custom_function_register(&eval_function);
01992    res |= ast_custom_function_register(&keypadhash_function);
01993    res |= ast_custom_function_register(&hashkeys_function);
01994    res |= ast_custom_function_register(&hash_function);
01995    res |= ast_register_application_xml(app_clearhash, exec_clearhash);
01996    res |= ast_custom_function_register(&toupper_function);
01997    res |= ast_custom_function_register(&tolower_function);
01998    res |= ast_custom_function_register(&shift_function);
01999    res |= ast_custom_function_register(&pop_function);
02000    res |= ast_custom_function_register(&push_function);
02001    res |= ast_custom_function_register(&unshift_function);
02002    res |= ast_custom_function_register(&passthru_function);
02003 
02004    return res;
02005 }

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

Definition at line 1667 of file func_strings.c.

References ast_str_set().

01668 {
01669    ast_str_set(buf, len, "%s", data);
01670    return 0;
01671 }

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

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 1245 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(), ast_app_separate_args(), and parse_options().

01246 {
01247    char *bufptr = buf, *dataptr = data;
01248 
01249    if (len < 3){ /* at least two for quotes and one for binary zero */
01250       ast_log(LOG_ERROR, "Not enough buffer\n");
01251       return -1;
01252    }
01253 
01254    if (ast_strlen_zero(data)) {
01255       ast_log(LOG_WARNING, "No argument specified!\n");
01256       ast_copy_string(buf, "\"\"", len);
01257       return 0;
01258    }
01259 
01260    *bufptr++ = '"';
01261    for (; bufptr < buf + len - 3; dataptr++) {
01262       if (*dataptr == '\\') {
01263          *bufptr++ = '\\';
01264          *bufptr++ = '\\';
01265       } else if (*dataptr == '"') {
01266          *bufptr++ = '\\';
01267          *bufptr++ = '"';
01268       } else if (*dataptr == '\0') {
01269          break;
01270       } else {
01271          *bufptr++ = *dataptr;
01272       }
01273    }
01274    *bufptr++ = '"';
01275    *bufptr = '\0';
01276    return 0;
01277 }

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

Definition at line 951 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, NULL, and str.

Referenced by ast_sip_location_retrieve_aor_contacts(), and build_regex().

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

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

Definition at line 793 of file func_strings.c.

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

Referenced by app_get_replace_channel_app(), app_set_replace_channel_app(), app_set_replace_channel_snapshot(), get_replace_channel_snapshot(), manager_dialplan_extension_add(), process_text_line(), and replace_channel_destroy().

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

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

Definition at line 1543 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, c, LOG_WARNING, pbx_builtin_setvar_helper(), result_buf, and var.

01544 {
01545 #define beginning (cmd[0] == 'S') /* SHIFT */
01546    char *after, delimiter[2] = ",", *varsubst;
01547    size_t unused;
01548    struct ast_str *before = ast_str_thread_get(&result_buf, 16);
01549    char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr);
01550    AST_DECLARE_APP_ARGS(args,
01551       AST_APP_ARG(var);
01552       AST_APP_ARG(delimiter);
01553    );
01554 
01555    if (!before) {
01556       return -1;
01557    }
01558 
01559    AST_STANDARD_APP_ARGS(args, data);
01560 
01561    if (ast_strlen_zero(args.var)) {
01562       ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
01563       return -1;
01564    }
01565 
01566    varsubst = ast_alloca(strlen(args.var) + 4);
01567    sprintf(varsubst, "${%s}", args.var);
01568    ast_str_substitute_variables(&before, 0, chan, varsubst);
01569 
01570    if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
01571       ast_get_encoded_char(args.delimiter, delimiter, &unused);
01572    }
01573 
01574    if (!ast_str_strlen(before)) {
01575       /* Nothing to pop */
01576       return -1;
01577    }
01578 
01579    if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) {
01580       /* Only one entry in array */
01581       ast_str_set(buf, len, "%s", ast_str_buffer(before));
01582       pbx_builtin_setvar_helper(chan, args.var, "");
01583    } else {
01584       *after++ = '\0';
01585       ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after);
01586       pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before));
01587    }
01588 
01589    return 0;
01590 #undef beginning
01591 }

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

Definition at line 1514 of file func_strings.c.

01515 {
01516    char *bufptr = buf, *dataptr = data;
01517 
01518    while ((bufptr < buf + buflen - 1) && (*bufptr++ = tolower(*dataptr++)));
01519 
01520    return 0;
01521 }

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

Definition at line 1523 of file func_strings.c.

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

01524 {
01525    char *bufptr, *dataptr = data;
01526 
01527    if (buflen > -1) {
01528       ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
01529    }
01530    bufptr = ast_str_buffer(*buf);
01531    while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++)));
01532    ast_str_update(*buf);
01533 
01534    return 0;
01535 }

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

Definition at line 1485 of file func_strings.c.

01486 {
01487    char *bufptr = buf, *dataptr = data;
01488 
01489    while ((bufptr < buf + buflen - 1) && (*bufptr++ = toupper(*dataptr++)));
01490 
01491    return 0;
01492 }

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

Definition at line 1494 of file func_strings.c.

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

01495 {
01496    char *bufptr, *dataptr = data;
01497 
01498    if (buflen > -1) {
01499       ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
01500    }
01501    bufptr = ast_str_buffer(*buf);
01502    while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++)));
01503    ast_str_update(*buf);
01504 
01505    return 0;
01506 }

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

Definition at line 862 of file func_strings.c.

References args, ast_alloca, 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, end, LOG_ERROR, result_buf, and str.

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

static int unload_module ( void   )  [static]

Definition at line 1933 of file func_strings.c.

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

01934 {
01935    int res = 0;
01936 
01937    AST_TEST_UNREGISTER(test_FIELDNUM);
01938    AST_TEST_UNREGISTER(test_REPLACE);
01939    AST_TEST_UNREGISTER(test_FILTER);
01940    AST_TEST_UNREGISTER(test_STRREPLACE);
01941    res |= ast_custom_function_unregister(&fieldqty_function);
01942    res |= ast_custom_function_unregister(&fieldnum_function);
01943    res |= ast_custom_function_unregister(&filter_function);
01944    res |= ast_custom_function_unregister(&replace_function);
01945    res |= ast_custom_function_unregister(&strreplace_function);
01946    res |= ast_custom_function_unregister(&listfilter_function);
01947    res |= ast_custom_function_unregister(&regex_function);
01948    res |= ast_custom_function_unregister(&array_function);
01949    res |= ast_custom_function_unregister(&quote_function);
01950    res |= ast_custom_function_unregister(&csv_quote_function);
01951    res |= ast_custom_function_unregister(&len_function);
01952    res |= ast_custom_function_unregister(&strftime_function);
01953    res |= ast_custom_function_unregister(&strptime_function);
01954    res |= ast_custom_function_unregister(&eval_function);
01955    res |= ast_custom_function_unregister(&keypadhash_function);
01956    res |= ast_custom_function_unregister(&hashkeys_function);
01957    res |= ast_custom_function_unregister(&hash_function);
01958    res |= ast_unregister_application(app_clearhash);
01959    res |= ast_custom_function_unregister(&toupper_function);
01960    res |= ast_custom_function_unregister(&tolower_function);
01961    res |= ast_custom_function_unregister(&shift_function);
01962    res |= ast_custom_function_unregister(&pop_function);
01963    res |= ast_custom_function_unregister(&push_function);
01964    res |= ast_custom_function_unregister(&unshift_function);
01965    res |= ast_custom_function_unregister(&passthru_function);
01966 
01967    return res;
01968 }

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

Definition at line 1603 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, buf, LOG_WARNING, MIN, pbx_builtin_setvar_helper(), result_buf, tmp_buf, and var.

01604 {
01605 #define beginning (cmd[0] == 'U') /* UNSHIFT */
01606    char delimiter[2] = ",", *varsubst;
01607    size_t unused;
01608    struct ast_str *buf, *previous_value;
01609    AST_DECLARE_APP_ARGS(args,
01610       AST_APP_ARG(var);
01611       AST_APP_ARG(delimiter);
01612    );
01613    const char *stripped_var;
01614 
01615    if (!(buf = ast_str_thread_get(&result_buf, 16)) ||
01616       !(previous_value = ast_str_thread_get(&tmp_buf, 16))) {
01617       return -1;
01618    }
01619 
01620    AST_STANDARD_APP_ARGS(args, data);
01621 
01622    if (ast_strlen_zero(args.var)) {
01623       ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
01624       return -1;
01625    }
01626 
01627    if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
01628       ast_get_encoded_char(args.delimiter, delimiter, &unused);
01629    }
01630 
01631    /* UNSHIFT and PUSH act as ways of setting a variable, so we need to be
01632     * sure to skip leading underscores if they appear. However, we only want
01633     * to skip up to two since that is the maximum number that can be used to
01634     * indicate variable inheritance. Any further underscores are part of the
01635     * variable name.
01636     */
01637    stripped_var = args.var + MIN(strspn(args.var, "_"), 2);
01638    varsubst = ast_alloca(strlen(stripped_var) + 4);
01639    sprintf(varsubst, "${%s}", stripped_var);
01640    ast_str_substitute_variables(&previous_value, 0, chan, varsubst);
01641 
01642    if (!ast_str_strlen(previous_value)) {
01643       ast_str_set(&buf, 0, "%s", new_value);
01644    } else {
01645       ast_str_set(&buf, 0, "%s%c%s",
01646          beginning ? new_value : ast_str_buffer(previous_value),
01647          delimiter[0],
01648          beginning ? ast_str_buffer(previous_value) : new_value);
01649    }
01650 
01651    pbx_builtin_setvar_helper(chan, args.var, ast_str_buffer(buf));
01652 
01653    return 0;
01654 #undef beginning
01655 }


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, .support_level = AST_MODULE_SUPPORT_CORE, } [static]

Definition at line 2007 of file func_strings.c.

char* app_clearhash = "ClearHash" [static]

Definition at line 996 of file func_strings.c.

Initial value:

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

Definition at line 1240 of file func_strings.c.

Definition at line 2007 of file func_strings.c.

Initial value:

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

Definition at line 1314 of file func_strings.c.

Initial value:

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

Definition at line 1439 of file func_strings.c.

Initial value:

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

Definition at line 578 of file func_strings.c.

Initial value:

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

Definition at line 499 of file func_strings.c.

Initial value:

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

Definition at line 788 of file func_strings.c.

Initial value:

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

Definition at line 1228 of file func_strings.c.

Initial value:

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

Definition at line 1234 of file func_strings.c.

Initial value:

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

Definition at line 1480 of file func_strings.c.

Initial value:

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

Definition at line 1331 of file func_strings.c.

Initial value:

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

Definition at line 706 of file func_strings.c.

Initial value:

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

Definition at line 1673 of file func_strings.c.

Initial value:

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

Definition at line 1598 of file func_strings.c.

Initial value:

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

Definition at line 1657 of file func_strings.c.

Initial value:

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

Definition at line 1279 of file func_strings.c.

Initial value:

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

Definition at line 988 of file func_strings.c.

Initial value:

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

Definition at line 857 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 1593 of file func_strings.c.

Initial value:

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

Definition at line 1366 of file func_strings.c.

Initial value:

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

Definition at line 1408 of file func_strings.c.

Initial value:

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

Definition at line 946 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(), and unshift_push().

Initial value:

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

Definition at line 1537 of file func_strings.c.

Initial value:

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

Definition at line 1508 of file func_strings.c.

Initial value:

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

Definition at line 1662 of file func_strings.c.


Generated on Thu Apr 16 06:31:26 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6