Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
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.

Macros

#define beginning   (cmd[0] == 'S') /* SHIFT */
 
#define beginning   (cmd[0] == 'U') /* UNSHIFT */
 
#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)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_FIELDNUM)
 
 AST_TEST_DEFINE (test_REPLACE)
 
 AST_TEST_DEFINE (test_FILTER)
 
 AST_TEST_DEFINE (test_STRREPLACE)
 
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 const char * get_key (const struct ast_str *prefix, const struct ast_var_t *var)
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 const 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.

Macro Definition Documentation

◆ beginning [1/2]

#define beginning   (cmd[0] == 'S') /* SHIFT */

Referenced by shift_pop(), and unshift_push().

◆ beginning [2/2]

#define beginning   (cmd[0] == 'U') /* UNSHIFT */

◆ HASH_FORMAT

#define HASH_FORMAT   HASH_PREFIX "%s~"

Definition at line 991 of file func_strings.c.

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

◆ HASH_PREFIX

#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

◆ __init_result_buf()

static void __init_result_buf ( void  )
static

Definition at line 45 of file func_strings.c.

442 {

◆ __init_tmp_buf()

static void __init_tmp_buf ( void  )
static

Definition at line 46 of file func_strings.c.

442 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2032 of file func_strings.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2032 of file func_strings.c.

◆ acf_strftime()

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

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

1364 {
1366  AST_APP_ARG(epoch);
1367  AST_APP_ARG(timezone);
1369  );
1370  struct timeval when;
1371  struct ast_tm tm;
1372 
1373  buf[0] = '\0';
1374 
1376 
1377  ast_get_timeval(args.epoch, &when, ast_tvnow(), NULL);
1378  ast_localtime(&when, &tm, args.timezone);
1379 
1380  if (!args.format)
1381  args.format = "%c";
1382 
1383  if (ast_strftime(buf, buflen, args.format, &tm) <= 0)
1384  ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
1385 
1386  buf[buflen - 1] = '\0';
1387 
1388  return 0;
1389 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
const char * args
#define NULL
Definition: resample.c:96
int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed)
get values from config variables.
Definition: main/utils.c:2171
#define ast_log
Definition: astobj2.c:42
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
static snd_pcm_format_t format
Definition: chan_alsa.c:102
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ acf_strptime()

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

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

1398 {
1400  AST_APP_ARG(timestring);
1401  AST_APP_ARG(timezone);
1403  );
1404  struct ast_tm tm;
1405 
1406  buf[0] = '\0';
1407 
1408  if (!data) {
1410  "Asterisk function STRPTIME() requires an argument.\n");
1411  return -1;
1412  }
1413 
1414  AST_STANDARD_APP_ARGS(args, data);
1415 
1416  if (ast_strlen_zero(args.format)) {
1418  "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
1419  return -1;
1420  }
1421 
1422  if (!ast_strptime(args.timestring, args.format, &tm)) {
1423  ast_log(LOG_WARNING, "STRPTIME() found no time specified within the string\n");
1424  } else {
1425  struct timeval when;
1426  when = ast_mktime(&tm, args.timezone);
1427  snprintf(buf, buflen, "%d", (int) when.tv_sec);
1428  }
1429 
1430  return 0;
1431 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm. Also, unlike strptime(3), ast_strptime() initializes its memory prior to use.
Definition: localtime.c:2550
#define LOG_ERROR
Definition: logger.h:285
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2357
static snd_pcm_format_t format
Definition: chan_alsa.c:102
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ array()

static int array ( struct ast_channel chan,
const char *  cmd,
char *  var,
const char *  value 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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(), S_OR, and var.

Referenced by app_to_json(), 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().

1019 {
1020  AST_DECLARE_APP_ARGS(arg1,
1021  AST_APP_ARG(var)[100];
1022  );
1023  AST_DECLARE_APP_ARGS(arg2,
1024  AST_APP_ARG(val)[100];
1025  );
1026  char *origvar = "", *value2, varname[256];
1027  int i, ishash = 0;
1028 
1029  if (!var) {
1030  return -1;
1031  }
1032  value2 = ast_strdupa(value);
1033 
1034  if (!strcmp(cmd, "HASH")) {
1035  const char *var2 = pbx_builtin_getvar_helper(chan, "~ODBCFIELDS~");
1036  origvar = var;
1037  if (var2)
1038  var = ast_strdupa(var2);
1039  else {
1040  if (chan)
1041  ast_autoservice_stop(chan);
1042  return -1;
1043  }
1044  ishash = 1;
1045  }
1046 
1047  /* The functions this will generally be used with are SORT and ODBC_*, which
1048  * both return comma-delimited lists. However, if somebody uses literal lists,
1049  * their commas will be translated to vertical bars by the load, and I don't
1050  * want them to be surprised by the result. Hence, we prefer commas as the
1051  * delimiter, but we'll fall back to vertical bars if commas aren't found.
1052  */
1053  ast_debug(1, "array (%s=%s)\n", var, S_OR(value2, ""));
1054  AST_STANDARD_APP_ARGS(arg1, var);
1055 
1056  AST_STANDARD_APP_ARGS(arg2, value2);
1057 
1058  for (i = 0; i < arg1.argc; i++) {
1059  ast_debug(1, "array set value (%s=%s)\n", arg1.var[i],
1060  S_OR(arg2.val[i], ""));
1061  if (i < arg2.argc) {
1062  if (ishash) {
1063  if (origvar[0] == '_') {
1064  if (origvar[1] == '_') {
1065  snprintf(varname, sizeof(varname), "__" HASH_FORMAT, origvar + 2, arg1.var[i]);
1066  } else {
1067  snprintf(varname, sizeof(varname), "_" HASH_FORMAT, origvar + 1, arg1.var[i]);
1068  }
1069  } else {
1070  snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
1071  }
1072 
1073  pbx_builtin_setvar_helper(chan, varname, arg2.val[i]);
1074  } else {
1075  pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
1076  }
1077  } else {
1078  /* We could unset the variable, by passing a NULL, but due to
1079  * pushvar semantics, that could create some undesired behavior. */
1080  if (ishash) {
1081  snprintf(varname, sizeof(varname), HASH_FORMAT, origvar, arg1.var[i]);
1082  pbx_builtin_setvar_helper(chan, varname, "");
1083  } else {
1084  pbx_builtin_setvar_helper(chan, arg1.var[i], "");
1085  }
1086  }
1087  }
1088 
1089  return 0;
1090 }
Definition: ast_expr2.c:325
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define var
Definition: ast_expr2f.c:614
#define HASH_FORMAT
Definition: func_strings.c:991
int value
Definition: syslog.c:37
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 2032 of file func_strings.c.

◆ AST_TEST_DEFINE() [1/4]

AST_TEST_DEFINE ( test_FIELDNUM  )

Definition at line 1704 of file func_strings.c.

References ARRAY_LEN, ast_channel_release(), ast_channel_varshead(), ast_dummy_channel_alloc, ast_free, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_var_assign, ast_var_delete(), ast_var_t::entries, sip_to_pjsip::info(), ast_var_t::name, str, TEST_EXECUTE, TEST_INIT, and var.

1705 {
1706  int i, res = AST_TEST_PASS;
1707  struct ast_channel *chan;
1708  struct ast_str *str;
1709  char expression[256];
1710  struct {
1711  const char *fields;
1712  const char *delim;
1713  const char *field;
1714  const char *expected;
1715  } test_args[] = {
1716  {"abc,def,ghi,jkl", "\\,", "ghi", "3"},
1717  {"abc def ghi jkl", " ", "abc", "1"},
1718  {"abc/def/ghi/jkl", "\\\\x2f", "def", "2"},
1719  {"abc$def$ghi$jkl", "", "ghi", "0"},
1720  {"abc,def,ghi,jkl", "-", "", "0"},
1721  {"abc-def-ghi-jkl", "-", "mno", "0"}
1722  };
1723 
1724  switch (cmd) {
1725  case TEST_INIT:
1726  info->name = "func_FIELDNUM_test";
1727  info->category = "/funcs/func_strings/";
1728  info->summary = "Test FIELDNUM function";
1729  info->description = "Verify FIELDNUM behavior";
1730  return AST_TEST_NOT_RUN;
1731  case TEST_EXECUTE:
1732  break;
1733  }
1734 
1735  if (!(chan = ast_dummy_channel_alloc())) {
1736  ast_test_status_update(test, "Unable to allocate dummy channel\n");
1737  return AST_TEST_FAIL;
1738  }
1739 
1740  if (!(str = ast_str_create(16))) {
1741  ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
1742  ast_channel_release(chan);
1743  return AST_TEST_FAIL;
1744  }
1745 
1746  for (i = 0; i < ARRAY_LEN(test_args); i++) {
1747  struct ast_var_t *var = ast_var_assign("FIELDS", test_args[i].fields);
1748  if (!var) {
1749  ast_test_status_update(test, "Out of memory\n");
1750  res = AST_TEST_FAIL;
1751  break;
1752  }
1753 
1755 
1756  snprintf(expression, sizeof(expression), "${FIELDNUM(%s,%s,%s)}", var->name, test_args[i].delim, test_args[i].field);
1757  ast_str_substitute_variables(&str, 0, chan, expression);
1758 
1760  ast_var_delete(var);
1761 
1762  if (strcasecmp(ast_str_buffer(str), test_args[i].expected)) {
1763  ast_test_status_update(test, "Evaluation of '%s' returned '%s' instead of the expected value '%s'\n",
1764  expression, ast_str_buffer(str), test_args[i].expected);
1765  res = AST_TEST_FAIL;
1766  break;
1767  }
1768  }
1769 
1770  ast_free(str);
1771  ast_channel_release(chan);
1772 
1773  return res;
1774 }
Main Channel structure associated with a channel.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define var
Definition: ast_expr2f.c:614
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
const char * str
Definition: app_jack.c:147
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
char name[0]
Definition: chanvars.h:31
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2473
def info(msg)
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_free(a)
Definition: astmm.h:182
struct ast_var_t::@249 entries
#define ast_var_assign(name, value)
Definition: chanvars.h:40
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ AST_TEST_DEFINE() [2/4]

AST_TEST_DEFINE ( test_REPLACE  )

Definition at line 1776 of file func_strings.c.

References ARRAY_LEN, ast_channel_release(), ast_channel_varshead(), ast_dummy_channel_alloc, ast_free, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_var_assign, ast_var_delete(), ast_var_t::entries, sip_to_pjsip::info(), ast_var_t::name, str, TEST_EXECUTE, TEST_INIT, and var.

1777 {
1778  int i, res = AST_TEST_PASS;
1779  struct ast_channel *chan;
1780  struct ast_str *str;
1781  char expression[256];
1782  struct {
1783  const char *test_string;
1784  const char *find_chars;
1785  const char *replace_char;
1786  const char *expected;
1787  } test_args[] = {
1788  {"abc,def", "\\,", "-", "abc-def"},
1789  {"abc,abc", "bc", "a", "aaa,aaa"},
1790  {"abc,def", "x", "?", "abc,def"},
1791  {"abc,def", "\\,", "", "abcdef"}
1792  };
1793 
1794  switch (cmd) {
1795  case TEST_INIT:
1796  info->name = "func_REPLACE_test";
1797  info->category = "/funcs/func_strings/";
1798  info->summary = "Test REPLACE function";
1799  info->description = "Verify REPLACE behavior";
1800  return AST_TEST_NOT_RUN;
1801  case TEST_EXECUTE:
1802  break;
1803  }
1804 
1805  if (!(chan = ast_dummy_channel_alloc())) {
1806  ast_test_status_update(test, "Unable to allocate dummy channel\n");
1807  return AST_TEST_FAIL;
1808  }
1809 
1810  if (!(str = ast_str_create(16))) {
1811  ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
1812  ast_channel_release(chan);
1813  return AST_TEST_FAIL;
1814  }
1815 
1816  for (i = 0; i < ARRAY_LEN(test_args); i++) {
1817  struct ast_var_t *var = ast_var_assign("TEST_STRING", test_args[i].test_string);
1818  if (!var) {
1819  ast_test_status_update(test, "Out of memory\n");
1820  res = AST_TEST_FAIL;
1821  break;
1822  }
1823 
1825 
1826  snprintf(expression, sizeof(expression), "${REPLACE(%s,%s,%s)}", var->name, test_args[i].find_chars, test_args[i].replace_char);
1827  ast_str_substitute_variables(&str, 0, chan, expression);
1828 
1830  ast_var_delete(var);
1831 
1832  if (strcasecmp(ast_str_buffer(str), test_args[i].expected)) {
1833  ast_test_status_update(test, "Evaluation of '%s' returned '%s' instead of the expected value '%s'\n",
1834  expression, ast_str_buffer(str), test_args[i].expected);
1835  res = AST_TEST_FAIL;
1836  break;
1837  }
1838  }
1839 
1840  ast_free(str);
1841  ast_channel_release(chan);
1842 
1843  return res;
1844 }
Main Channel structure associated with a channel.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define var
Definition: ast_expr2f.c:614
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
const char * str
Definition: app_jack.c:147
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
char name[0]
Definition: chanvars.h:31
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2473
def info(msg)
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_free(a)
Definition: astmm.h:182
struct ast_var_t::@249 entries
#define ast_var_assign(name, value)
Definition: chanvars.h:40
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ AST_TEST_DEFINE() [3/4]

AST_TEST_DEFINE ( test_FILTER  )

Definition at line 1846 of file func_strings.c.

References AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, pbx_substitute_variables_helper(), TEST_EXECUTE, TEST_INIT, test_strings, and tmp().

1847 {
1848  int i, res = AST_TEST_PASS;
1849  const char *test_strings[][2] = {
1850  {"A-R", "DAHDI"},
1851  {"A\\-R", "A"},
1852  {"\\x41-R", "DAHDI"},
1853  {"0-9A-Ca-c", "0042133333A12212"},
1854  {"0-9a-cA-C_+\\-", "0042133333A12212"},
1855  {NULL, NULL},
1856  };
1857 
1858  switch (cmd) {
1859  case TEST_INIT:
1860  info->name = "func_FILTER_test";
1861  info->category = "/funcs/func_strings/";
1862  info->summary = "Test FILTER function";
1863  info->description = "Verify FILTER behavior";
1864  return AST_TEST_NOT_RUN;
1865  case TEST_EXECUTE:
1866  break;
1867  }
1868 
1869  for (i = 0; test_strings[i][0]; i++) {
1870  char tmp[256], tmp2[256] = "";
1871  snprintf(tmp, sizeof(tmp), "${FILTER(%s,0042133333&DAHDI/g1/2212)}", test_strings[i][0]);
1872  pbx_substitute_variables_helper(NULL, tmp, tmp2, sizeof(tmp2) - 1);
1873  if (strcmp(test_strings[i][1], tmp2)) {
1874  ast_test_status_update(test, "Format string '%s' substituted to '%s'. Expected '%s'.\n", test_strings[i][0], tmp2, test_strings[i][1]);
1875  res = AST_TEST_FAIL;
1876  }
1877  }
1878  return res;
1879 }
static int tmp()
Definition: bt_open.c:389
static char * test_strings[][2]
#define NULL
Definition: resample.c:96
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
def info(msg)
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211

◆ AST_TEST_DEFINE() [4/4]

AST_TEST_DEFINE ( test_STRREPLACE  )

Definition at line 1881 of file func_strings.c.

References ARRAY_LEN, ast_channel_release(), ast_channel_varshead(), ast_dummy_channel_alloc, ast_free, AST_LIST_INSERT_HEAD, ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_var_assign, ast_var_t::entries, sip_to_pjsip::info(), NULL, str, TEST_EXECUTE, TEST_INIT, test_strings, tmp(), and var.

1882 {
1883  int i, res = AST_TEST_PASS;
1884  struct ast_channel *chan; /* dummy channel */
1885  struct ast_str *str; /* fancy string for holding comparing value */
1886 
1887  const char *test_strings[][5] = {
1888  {"Weasels have eaten my telephone system", "have eaten my", "are eating our", "", "Weasels are eating our telephone system"}, /*Test normal conditions */
1889  {"Did you know twenty plus two is twenty-two?", "twenty", "thirty", NULL, "Did you know thirty plus two is thirty-two?"}, /* Test no third comma */
1890  {"foofoofoofoofoofoofoo", "foofoo", "bar", NULL, "barbarbarfoo"}, /* Found string within previous match */
1891  {"My pet dog once ate a dog who sat on a dog while eating a corndog.", "dog", "cat", "3", "My pet cat once ate a cat who sat on a cat while eating a corndog."},
1892  {"One and one and one is three", "and", "plus", "1", "One plus one and one is three"}, /* Test <max-replacements> = 1*/
1893  {"", "fhqwagads", "spelunker", NULL, ""}, /* Empty primary string */
1894  {"Part of this string is missing.", "missing", NULL, NULL, "Part of this string is ."}, /* Empty replace string */
1895  {"'Accidentally' left off a bunch of stuff.", NULL, NULL, NULL, ""}, /* Deliberate error test from too few args */
1896  {"This test will also error.", "", "", "", ""}, /* Deliberate error test from blank find string */
1897  {"This is an \"escape character\" test.", "\\\"escape character\\\"", "evil", NULL, "This is an evil test."}
1898  };
1899 
1900  switch (cmd) {
1901  case TEST_INIT:
1902  info->name = "func_STRREPLACE_test";
1903  info->category = "/funcs/func_strings/";
1904  info->summary = "Test STRREPLACE function";
1905  info->description = "Verify STRREPLACE behavior";
1906  return AST_TEST_NOT_RUN;
1907  case TEST_EXECUTE:
1908  break;
1909  }
1910 
1911  if (!(chan = ast_dummy_channel_alloc())) {
1912  ast_test_status_update(test, "Unable to allocate dummy channel\n");
1913  return AST_TEST_FAIL;
1914  }
1915 
1916  if (!(str = ast_str_create(64))) {
1917  ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
1918  ast_channel_release(chan);
1919  return AST_TEST_FAIL;
1920  }
1921 
1922  for (i = 0; i < ARRAY_LEN(test_strings); i++) {
1923  char tmp[512], tmp2[512] = "";
1924 
1925  struct ast_var_t *var = ast_var_assign("test_string", test_strings[i][0]);
1926  if (!var) {
1927  ast_test_status_update(test, "Unable to allocate variable\n");
1928  ast_free(str);
1929  ast_channel_release(chan);
1930  return AST_TEST_FAIL;
1931  }
1932 
1934 
1935  if (test_strings[i][3]) {
1936  snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s,%s,%s,%s)}", "test_string", test_strings[i][1], test_strings[i][2], test_strings[i][3]);
1937  } else if (test_strings[i][2]) {
1938  snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s,%s,%s)}", "test_string", test_strings[i][1], test_strings[i][2]);
1939  } else if (test_strings[i][1]) {
1940  snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s,%s)}", "test_string", test_strings[i][1]);
1941  } else {
1942  snprintf(tmp, sizeof(tmp), "${STRREPLACE(%s)}", "test_string");
1943  }
1944  ast_str_substitute_variables(&str, 0, chan, tmp);
1945  if (strcmp(test_strings[i][4], ast_str_buffer(str))) {
1946  ast_test_status_update(test, "Format string '%s' substituted to '%s'. Expected '%s'.\n", test_strings[i][0], tmp2, test_strings[i][4]);
1947  res = AST_TEST_FAIL;
1948  }
1949  }
1950 
1951  ast_free(str);
1952  ast_channel_release(chan);
1953 
1954  return res;
1955 }
Main Channel structure associated with a channel.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
#define var
Definition: ast_expr2f.c:614
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
static char * test_strings[][2]
const char * str
Definition: app_jack.c:147
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define NULL
Definition: resample.c:96
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
def info(msg)
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_free(a)
Definition: astmm.h:182
struct ast_var_t::@249 entries
#define ast_var_assign(name, value)
Definition: chanvars.h:40
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ clearvar_prefix()

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

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

997 {
998  struct ast_var_t *var;
999  int len = strlen(prefix);
1001  if (strncmp(prefix, ast_var_name(var), len) == 0) {
1003  ast_free(var);
1004  }
1005  }
1007 }
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
#define var
Definition: ast_expr2f.c:614
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
struct ast_var_t::@249 entries
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ csv_quote()

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

Definition at line 1309 of file func_strings.c.

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

1310 {
1311  char *bufptr = buf, *dataptr = data;
1312 
1313  if (len < 3) { /* at least two for quotes and one for binary zero */
1314  ast_log(LOG_ERROR, "Not enough buffer\n");
1315  return -1;
1316  }
1317 
1318  if (ast_strlen_zero(data)) {
1319  ast_copy_string(buf, "\"\"", len);
1320  return 0;
1321  }
1322 
1323  *bufptr++ = '"';
1324  for (; bufptr < buf + len - 3; dataptr++){
1325  if (*dataptr == '"') {
1326  *bufptr++ = '"';
1327  *bufptr++ = '"';
1328  } else if (*dataptr == '\0') {
1329  break;
1330  } else {
1331  *bufptr++ = *dataptr;
1332  }
1333  }
1334  *bufptr++ = '"';
1335  *bufptr='\0';
1336  return 0;
1337 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ exec_clearhash()

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

1010 {
1011  char prefix[80];
1012  snprintf(prefix, sizeof(prefix), HASH_PREFIX, data ? (char *)data : "null");
1013  clearvar_prefix(chan, prefix);
1014  return 0;
1015 }
static void clearvar_prefix(struct ast_channel *chan, const char *prefix)
Definition: func_strings.c:996
#define HASH_PREFIX
Definition: func_strings.c:990
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ filter()

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 709 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, buf, LOG_ERROR, and LOG_WARNING.

Referenced by action_filter(), action_getconfig(), action_getconfigjson(), create_lookup_filter(), kqueue_timer_ack(), process_text_line(), realtime_ldap_base_ap(), stasis_subscription_set_filter(), and update2_ldap().

711 {
713  AST_APP_ARG(allowed);
714  AST_APP_ARG(string);
715  );
716  char *outbuf = buf;
717  unsigned char ac;
718  char allowed[256] = "";
719  size_t allowedlen = 0;
720  int32_t bitfield[8] = { 0, }; /* 256 bits */
721 
723 
724  if (!args.string) {
725  ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n");
726  return -1;
727  }
728 
729  if (args.allowed[0] == '"' && !ast_opt_dont_warn) {
730  ast_log(LOG_WARNING, "FILTER allowed characters includes the quote (\") character. This may not be what you want.\n");
731  }
732 
733  /* Expand ranges */
734  for (; *(args.allowed);) {
735  char c1 = 0, c2 = 0;
736  size_t consumed = 0;
737 
738  if (ast_get_encoded_char(args.allowed, &c1, &consumed))
739  return -1;
740  args.allowed += consumed;
741 
742  if (*(args.allowed) == '-') {
743  if (ast_get_encoded_char(args.allowed + 1, &c2, &consumed))
744  c2 = c1;
745  args.allowed += consumed + 1;
746 
747  if ((unsigned char) c2 < (unsigned char) c1 && !ast_opt_dont_warn) {
748  ast_log(LOG_WARNING, "Range wrapping in FILTER(%s,%s). This may not be what you want.\n", parse, args.string);
749  }
750 
751  /*!\note
752  * Looks a little strange, until you realize that we can overflow
753  * the size of a char.
754  */
755  for (ac = (unsigned char) c1; ac != (unsigned char) c2; ac++) {
756  bitfield[ac / 32] |= 1 << (ac % 32);
757  }
758  bitfield[ac / 32] |= 1 << (ac % 32);
759 
760  ast_debug(4, "c1=%d, c2=%d\n", c1, c2);
761  } else {
762  ac = (unsigned char) c1;
763  ast_debug(4, "c1=%d, consumed=%d, args.allowed=%s\n", c1, (int) consumed, args.allowed - consumed);
764  bitfield[ac / 32] |= 1 << (ac % 32);
765  }
766  }
767 
768  for (ac = 1; ac != 0; ac++) {
769  if (bitfield[ac / 32] & (1 << (ac % 32))) {
770  allowed[allowedlen++] = ac;
771  }
772  }
773 
774  ast_debug(1, "Allowed: %s\n", allowed);
775 
776  for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
777  if (strchr(allowed, *(args.string)))
778  *outbuf++ = *(args.string);
779  }
780  *outbuf = '\0';
781 
782  return 0;
783 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define AST_STANDARD_RAW_ARGS(args, parse)
const char * args
#define ast_opt_dont_warn
Definition: options.h:125
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:2927
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
int int32_t
Definition: db.h:60
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ function_eval()

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

Definition at line 1438 of file func_strings.c.

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

1440 {
1441  if (ast_strlen_zero(data)) {
1442  ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
1443  return -1;
1444  }
1445 
1446  pbx_substitute_variables_helper(chan, data, buf, buflen - 1);
1447 
1448  return 0;
1449 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211

◆ function_eval2()

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

Definition at line 1451 of file func_strings.c.

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

1453 {
1454  if (ast_strlen_zero(data)) {
1455  ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
1456  return -1;
1457  }
1458 
1459  ast_str_substitute_variables(buf, buflen, chan, data);
1460 
1461  return 0;
1462 }
#define LOG_WARNING
Definition: logger.h:274
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42

◆ function_fieldnum()

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

Definition at line 564 of file func_strings.c.

References function_fieldnum_helper(), and NULL.

566 {
567  return function_fieldnum_helper(chan, cmd, parse, buf, NULL, len);
568 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static int function_fieldnum_helper(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
Definition: func_strings.c:503

◆ function_fieldnum_helper()

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

505 {
506  char *varsubst, *field;
507  struct ast_str *str = ast_str_thread_get(&result_buf, 16);
508  int fieldindex = 0, res = 0;
510  AST_APP_ARG(varname);
511  AST_APP_ARG(delim);
512  AST_APP_ARG(field);
513  );
514  char delim[2] = "";
515  size_t delim_used;
516 
517  if (!str) {
518  return -1;
519  }
520 
522 
523  if (args.argc < 3) {
524  ast_log(LOG_ERROR, "Usage: FIELDNUM(<listname>,<delimiter>,<fieldvalue>)\n");
525  res = -1;
526  } else {
527  varsubst = ast_alloca(strlen(args.varname) + 4);
528  sprintf(varsubst, "${%s}", args.varname);
529 
530  ast_str_substitute_variables(&str, 0, chan, varsubst);
531 
532  if (ast_str_strlen(str) == 0 || ast_strlen_zero(args.delim)) {
533  fieldindex = 0;
534  } else if (ast_get_encoded_char(args.delim, delim, &delim_used) == -1) {
535  res = -1;
536  } else {
537  char *varval = ast_str_buffer(str);
538 
539  while ((field = strsep(&varval, delim)) != NULL) {
540  fieldindex++;
541 
542  if (!strcasecmp(field, args.field)) {
543  break;
544  }
545  }
546 
547  if (!field) {
548  fieldindex = 0;
549  }
550 
551  res = 0;
552  }
553  }
554 
555  if (sbuf) {
556  ast_str_set(sbuf, len, "%d", fieldindex);
557  } else {
558  snprintf(buf, len, "%d", fieldindex);
559  }
560 
561  return res;
562 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
const char * str
Definition: app_jack.c:147
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:2927
static struct ast_threadstorage result_buf
Definition: func_strings.c:45
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
char * strsep(char **str, const char *delims)
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ function_fieldnum_str()

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

References function_fieldnum_helper(), and NULL.

572 {
573  return function_fieldnum_helper(chan, cmd, parse, NULL, buf, len);
574 }
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static int function_fieldnum_helper(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
Definition: func_strings.c:503

◆ function_fieldqty()

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

Definition at line 485 of file func_strings.c.

References function_fieldqty_helper(), and NULL.

487 {
488  return function_fieldqty_helper(chan, cmd, parse, buf, NULL, len);
489 }
static int function_fieldqty_helper(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
Definition: func_strings.c:440
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872

◆ function_fieldqty_helper()

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

442 {
443  char *varsubst;
444  struct ast_str *str = ast_str_thread_get(&result_buf, 16);
445  int fieldcount = 0;
447  AST_APP_ARG(varname);
448  AST_APP_ARG(delim);
449  );
450  char delim[2] = "";
451  size_t delim_used;
452 
453  if (!str) {
454  return -1;
455  }
456 
458  if (args.delim) {
459  ast_get_encoded_char(args.delim, delim, &delim_used);
460 
461  varsubst = ast_alloca(strlen(args.varname) + 4);
462 
463  sprintf(varsubst, "${%s}", args.varname);
464  ast_str_substitute_variables(&str, 0, chan, varsubst);
465  if (ast_str_strlen(str) == 0) {
466  fieldcount = 0;
467  } else {
468  char *varval = ast_str_buffer(str);
469  while (strsep(&varval, delim)) {
470  fieldcount++;
471  }
472  }
473  } else {
474  fieldcount = 1;
475  }
476  if (sbuf) {
477  ast_str_set(sbuf, len, "%d", fieldcount);
478  } else {
479  snprintf(buf, len, "%d", fieldcount);
480  }
481 
482  return 0;
483 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
const char * str
Definition: app_jack.c:147
const char * args
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:2927
static struct ast_threadstorage result_buf
Definition: func_strings.c:45
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
char * strsep(char **str, const char *delims)
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ function_fieldqty_str()

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

References function_fieldqty_helper(), and NULL.

493 {
494  return function_fieldqty_helper(chan, cmd, parse, NULL, buf, len);
495 }
static int function_fieldqty_helper(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
Definition: func_strings.c:440
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872

◆ get_key()

static const char* get_key ( const struct ast_str prefix,
const struct ast_var_t var 
)
static

Definition at line 1092 of file func_strings.c.

References ast_str_buffer(), ast_str_strlen(), ast_strlen_zero, ast_var_name(), and NULL.

Referenced by hashkeys_read(), and hashkeys_read2().

1093 {
1094  const char *prefix_name = ast_str_buffer(prefix);
1095  const char *var_name = ast_var_name(var);
1096  int prefix_len;
1097  int var_len;
1098 
1099  if (ast_strlen_zero(var_name)) {
1100  return NULL;
1101  }
1102 
1103  prefix_len = ast_str_strlen(prefix);
1104  var_len = strlen(var_name);
1105 
1106  /*
1107  * Make sure we only match on non-empty, hash function created keys. If valid
1108  * then return a pointer to the variable that's just after the prefix.
1109  */
1110  return var_len > (prefix_len + 1) && var_name[var_len - 1] == '~' &&
1111  strncmp(prefix_name, var_name, prefix_len) == 0 ? var_name + prefix_len : NULL;
1112 }
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688

◆ hash_read()

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

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

1203 {
1204  char varname[256];
1205  const char *varvalue;
1207  AST_APP_ARG(hashname);
1208  AST_APP_ARG(hashkey);
1209  );
1210 
1211  AST_STANDARD_APP_ARGS(arg, data);
1212  if (arg.argc == 2) {
1213  snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
1214  varvalue = pbx_builtin_getvar_helper(chan, varname);
1215  if (varvalue)
1216  ast_copy_string(buf, varvalue, len);
1217  else
1218  *buf = '\0';
1219  } else if (arg.argc == 1) {
1220  char colnames[4096];
1221  int i;
1222  AST_DECLARE_APP_ARGS(arg2,
1223  AST_APP_ARG(col)[100];
1224  );
1225 
1226  if (!chan) {
1227  ast_log(LOG_WARNING, "No channel and only 1 parameter was provided to %s function.\n", cmd);
1228  return -1;
1229  }
1230 
1231  /* Get column names, in no particular order */
1232  hashkeys_read(chan, "HASHKEYS", arg.hashname, colnames, sizeof(colnames));
1233  pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", colnames);
1234 
1235  AST_STANDARD_APP_ARGS(arg2, colnames);
1236  *buf = '\0';
1237 
1238  /* Now get the corresponding column values, in exactly the same order */
1239  for (i = 0; i < arg2.argc; i++) {
1240  snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg2.col[i]);
1241  varvalue = pbx_builtin_getvar_helper(chan, varname);
1242  strncat(buf, varvalue, len - strlen(buf) - 1);
1243  strncat(buf, ",", len - strlen(buf) - 1);
1244  }
1245 
1246  /* Strip trailing comma */
1247  buf[strlen(buf) - 1] = '\0';
1248  }
1249 
1250  return 0;
1251 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
#define HASH_FORMAT
Definition: func_strings.c:991
static int hashkeys_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ hash_write()

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

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

1175 {
1176  char varname[256];
1178  AST_APP_ARG(hashname);
1179  AST_APP_ARG(hashkey);
1180  );
1181 
1182  if (!strchr(var, ',')) {
1183  /* Single argument version */
1184  return array(chan, "HASH", var, value);
1185  }
1186 
1187  AST_STANDARD_APP_ARGS(arg, var);
1188  if (arg.hashname[0] == '_') {
1189  if (arg.hashname[1] == '_') {
1190  snprintf(varname, sizeof(varname), "__" HASH_FORMAT, arg.hashname + 2, arg.hashkey);
1191  } else {
1192  snprintf(varname, sizeof(varname), "_" HASH_FORMAT, arg.hashname + 1, arg.hashkey);
1193  }
1194  } else {
1195  snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
1196  }
1197  pbx_builtin_setvar_helper(chan, varname, value);
1198 
1199  return 0;
1200 }
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define var
Definition: ast_expr2f.c:614
#define HASH_FORMAT
Definition: func_strings.c:991
int value
Definition: syslog.c:37
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ hashkeys_read()

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

Definition at line 1114 of file func_strings.c.

References ast_channel_varshead(), AST_LIST_TRAVERSE, ast_log, ast_str_alloca, ast_str_set(), get_key(), HASH_PREFIX, LOG_WARNING, and prefix.

Referenced by hash_read().

1115 {
1116  struct ast_var_t *newvar;
1117  struct ast_str *prefix = ast_str_alloca(80);
1118  size_t buf_len;
1119 
1120  if (!chan) {
1121  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1122  return -1;
1123  }
1124 
1125  ast_str_set(&prefix, -1, HASH_PREFIX, data);
1126  memset(buf, 0, len);
1127 
1128  AST_LIST_TRAVERSE(ast_channel_varshead(chan), newvar, entries) {
1129  const char *key = get_key(prefix, newvar);
1130 
1131  if (key) {
1132  strncat(buf, key, len - strlen(buf) - 1);
1133  /* Replace the trailing ~ */
1134  buf[strlen(buf) - 1] = ',';
1135  }
1136  }
1137  /* Trim the trailing comma */
1138  buf_len = strlen(buf);
1139  if (buf_len) {
1140  buf[buf_len - 1] = '\0';
1141  }
1142  return 0;
1143 }
static const char * get_key(const struct ast_str *prefix, const struct ast_var_t *var)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ast_str_alloca(init_len)
Definition: strings.h:800
struct varshead * ast_channel_varshead(struct ast_channel *chan)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define HASH_PREFIX
Definition: func_strings.c:990
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ hashkeys_read2()

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

Definition at line 1145 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_str_truncate(), get_key(), HASH_PREFIX, LOG_WARNING, prefix, and tmp().

1146 {
1147  struct ast_var_t *newvar;
1148  struct ast_str *prefix = ast_str_alloca(80);
1149 
1150  if (!chan) {
1151  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1152  return -1;
1153  }
1154 
1155  ast_str_set(&prefix, -1, HASH_PREFIX, data);
1156 
1157  AST_LIST_TRAVERSE(ast_channel_varshead(chan), newvar, entries) {
1158  const char *key = get_key(prefix, newvar);
1159 
1160  if (key) {
1161  char *tmp;
1162 
1163  ast_str_append(buf, len, "%s", key);
1164  /* Replace the trailing ~ */
1165  tmp = ast_str_buffer(*buf);
1166  tmp[ast_str_strlen(*buf) - 1] = ',';
1167  }
1168  }
1169 
1170  ast_str_truncate(*buf, -1);
1171  return 0;
1172 }
static const char * get_key(const struct ast_str *prefix, const struct ast_var_t *var)
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
struct varshead * ast_channel_varshead(struct ast_channel *chan)
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define HASH_PREFIX
Definition: func_strings.c:990
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ keypadhash()

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

Definition at line 1470 of file func_strings.c.

1471 {
1472  char *bufptr, *dataptr;
1473 
1474  for (bufptr = buf, dataptr = data; bufptr < buf + buflen - 1; dataptr++) {
1475  if (*dataptr == '\0') {
1476  *bufptr++ = '\0';
1477  break;
1478  } else if (*dataptr == '1') {
1479  *bufptr++ = '1';
1480  } else if (strchr("AaBbCc2", *dataptr)) {
1481  *bufptr++ = '2';
1482  } else if (strchr("DdEeFf3", *dataptr)) {
1483  *bufptr++ = '3';
1484  } else if (strchr("GgHhIi4", *dataptr)) {
1485  *bufptr++ = '4';
1486  } else if (strchr("JjKkLl5", *dataptr)) {
1487  *bufptr++ = '5';
1488  } else if (strchr("MmNnOo6", *dataptr)) {
1489  *bufptr++ = '6';
1490  } else if (strchr("PpQqRrSs7", *dataptr)) {
1491  *bufptr++ = '7';
1492  } else if (strchr("TtUuVv8", *dataptr)) {
1493  *bufptr++ = '8';
1494  } else if (strchr("WwXxYyZz9", *dataptr)) {
1495  *bufptr++ = '9';
1496  } else if (*dataptr == '0') {
1497  *bufptr++ = '0';
1498  }
1499  }
1500  buf[buflen - 1] = '\0';
1501 
1502  return 0;
1503 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

◆ len()

static int len ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  buflen 
)
static
Examples:
/usr/src/asterisk-18.5.0/include/asterisk/strings.h, and /usr/src/asterisk-18.5.0/main/app.c.

Definition at line 1344 of file func_strings.c.

Referenced by __analog_ss_thread(), __ast_cli_register(), __ast_cli_register_multiple(), __ast_dsp_call_progress(), __ast_dsp_silence_noise(), __ast_frdup(), __big_return(), __bt_defcmp(), __bt_defpfx(), OrderedDict::__eq__(), __get_header(), OrderedDict::__init__(), __rec_fmap(), __rec_fpipe(), __rec_vpipe(), __rtp_recvfrom(), __rtp_sendto(), MultiOrderedDict::__setitem__(), __stub__ast_agi_unregister(), _parse(), AbsQuantW(), acf_escape(), action_command(), FaxPcap::add(), add_sdp(), adsi_careful_send(), ael_token_subst(), alsa_write(), amdf_pitch(), anaFilter(), analog_ss_thread(), anti_injection(), ao2_container_check(), aoc_parse_ie(), append_interface(), append_var_and_value_to_filter(), apply_outgoing(), ast_agi_register_multiple(), ast_agi_unregister_multiple(), ast_app_group_set_channel(), ast_app_options2str64(), ast_audiosocket_receive_frame(), ast_beep_start(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_channel_get_cc_agent_type(), ast_channel_get_device_name(), ast_cli_complete(), ast_cli_unregister_multiple(), ast_dns_test_write_string(), ast_dsp_process(), ast_dsp_silence_noise_with_energy(), ast_format_str_reduce(), ast_get_namedgroups(), ast_http_send(), ast_http_uri_link(), ast_iostream_gets(), ast_iostream_printf(), ast_join_delim(), ast_json_utf8_check_len(), ast_mkdir(), ast_msg_data_alloc(), ast_read_image(), ast_register_cleanup(), ast_rtcp_generate_report(), ast_rtcp_generate_sdes(), ast_rtp_interpret(), ast_say_number_full_ka(), ast_srtp_protect(), ast_srtp_unprotect(), ast_statsd_log_string(), ast_str_buffer(), ast_str_substitute_variables_full(), ast_tdd_gen_ecdisa(), AST_TEST_DEFINE(), ast_translate(), ast_websocket_write_string(), ast_xml_escape(), ast_xmldoc_printable(), auth_exec(), authenticate(), bucket_copy(), bucket_file_wizard_retrieve(), bucket_wizard_retrieve(), build_device(), build_facility(), build_ha(), build_regex(), build_route(), calc_energy(), category_set_sublevels(), CB_ADD_LEN(), cdr_read(), channel_do_masquerade(), chararray_handler_fn(), cleaned_basedn(), clearvar_prefix(), cli_complete(), cli_console_sendtext(), sip_to_pjsql::cli_options(), sip_to_pjsip::cli_options(), closefrom(), 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_cc_callback(), dahdi_chan_conf_default(), dahdi_sendtext(), dahdi_setoption(), dbl_list_expect_reverse(), dbm_open(), dcbias_(), devstate_write(), dialgroup_refreshdb(), dictate_exec(), do_pktccops(), do_tone(), dtmf_store_framehook(), dump_addr(), dump_ipaddr(), dump_prefs(), dump_raw(), dump_string(), dump_versioned_codec(), dundi_encrypt(), dundi_parse_ies(), dundi_send(), enc_ie_facility(), energy_(), eval_exten_read(), expand_gosub_args(), expr2_token_subst(), ext_cmp_exten_strlen(), fax_generator_generate(), fbuf_append(), fetch_response_reader(), ffmpeg_decode(), flip_buf_bits(), frame_set_var(), fsk_serial(), func_read_header(), g722_decode(), g722_encode(), PathSegment::get_child(), get_content_line(), get_name_from_resource(), get_sdp(), get_sdp_iterate(), 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_moh_unregister_class(), handle_cli_presencestate_change(), handle_commandmatchesarray(), handle_incoming(), handle_keypad_button_message(), handle_output(), handle_response(), handle_show_sysinfo(), handle_soft_key_event_message(), Model::has_properties(), Model::has_subtypes(), header_identify_match_check(), help1(), hepv3_create_capture_info(), hpInput(), hpOutput(), http_request_headers_get(), httpd_process_request(), iax_parse_ies(), iax_str2flags(), inner_product_single(), interpolate_product_single(), ip_identify_apply(), ivfilt_(), jb_debug_output(), json_utf8_check_full(), listener(), lpc10_decode(), lpc10tolin_framein(), lpfilt_(), lws2sws(), make_ari_stubs::main(), main(), refcounter::main(), spandspflow2pcap::main(), manager_login(), memcpy_decrypt(), memcpy_encrypt(), message_template_parse_emailbody(), method_match(), mgcp_postrequest(), mgcp_ss(), mgcpsock_read(), milliwatt_generate(), misdn_jb_empty(), misdn_jb_fill(), misdn_lib_tx2misdn_frm(), misdn_read(), misdn_tx_jitter(), monmp3thread(), mpeg4_encap(), my_dahdi_write(), newpvt(), PathSegment::num_children(), openssl_error_string(), parse_bookmark(), parse_ie(), refcounter::parse_line(), get_documentation::parse_manager_event_instance(), pbx_substitute_variables_helper_full(), phone_write_buf(), pjsip_acf_channel_read(), playtones_generator(), plc_fillin(), plc_rx(), pp_each_extension_helper(), presence_write(), reflocks::process_file(), refstats::process_file(), process_sdp(), read_credentials(), receive_message(), refer_blind_callback(), remove_header(), res_sdp_srtp_get_attr(), reschedule_precache(), resource_name_baselen(), rtp_instance_parse_extmap_extensions(), run_agi(), save_history(), scan_thread(), schedule_delivery(), sco_accept(), send_string(), set(), set_bridge_peer_vars_multiparty(), shared_write(), sip_addheader(), sip_route_process_header(), sip_show_channel(), sip_show_history(), sip_tcptls_write(), sms_messagetx(), socket_process_meta(), start_automixmonitor(), start_automonitor(), StateConstructW(), StateSearchW(), static_callback(), strnncpy(), syntFilter(), tdd_feed(), term_filter_escapes(), threadstorage_init(), tonepair_generator(), transfer_exec(), transmit_response_bysession(), try_firmware(), unistim_sp(), unquote(), OrderedDict::update(), uri_parse_and_default(), vm_allocate_dh(), wav_write(), ws_safe_read(), ws_send_msg(), xmldoc_get_syntax_fun(), xmldoc_setpostbr(), xmpp_client_authenticate_sasl(), xmpp_client_receive(), xmpp_client_send_raw_message(), and xmpp_io_recv().

1345 {
1346  int length = 0;
1347 
1348  if (data)
1349  length = strlen(data);
1350 
1351  snprintf(buf, buflen, "%d", length);
1352 
1353  return 0;
1354 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

◆ listfilter()

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

583 {
585  AST_APP_ARG(listname);
586  AST_APP_ARG(delimiter);
587  AST_APP_ARG(fieldvalue);
588  );
589  struct ast_str *orig_list = ast_str_thread_get(&tmp_buf, 16);
590  const char *begin, *cur, *next;
591  int dlen, flen, first = 1;
592  struct ast_str *result, **result_ptr = &result;
593  char *delim, *varsubst;
594 
596 
597  if (buf) {
598  if (!(result = ast_str_thread_get(&result_buf, 16))) {
599  return -1;
600  }
601  } else {
602  /* Place the result directly into the output buffer */
603  result_ptr = bufstr;
604  }
605 
606  if (args.argc < 3) {
607  ast_log(LOG_ERROR, "Usage: LISTFILTER(<listname>,<delimiter>,<fieldvalue>)\n");
608  return -1;
609  }
610 
611  varsubst = ast_alloca(strlen(args.listname) + 4);
612  sprintf(varsubst, "${%s}", args.listname);
613 
614  /* If we don't lock the channel, the variable could disappear out from underneath us. */
615  if (chan) {
616  ast_channel_lock(chan);
617  }
618  ast_str_substitute_variables(&orig_list, 0, chan, varsubst);
619  if (!ast_str_strlen(orig_list)) {
620  if (chan) {
621  ast_channel_unlock(chan);
622  }
623  return -1;
624  }
625 
626  /* If the string isn't there, just copy out the string and be done with it. */
627  if (!strstr(ast_str_buffer(orig_list), args.fieldvalue)) {
628  if (buf) {
629  ast_copy_string(buf, ast_str_buffer(orig_list), len);
630  } else {
631  ast_str_set(result_ptr, len, "%s", ast_str_buffer(orig_list));
632  }
633  if (chan) {
634  ast_channel_unlock(chan);
635  }
636  return 0;
637  }
638 
639  dlen = strlen(args.delimiter);
640  delim = ast_alloca(dlen + 1);
641  ast_get_encoded_str(args.delimiter, delim, dlen + 1);
642 
643  if ((dlen = strlen(delim)) == 0) {
644  delim = ",";
645  dlen = 1;
646  }
647 
648  flen = strlen(args.fieldvalue);
649 
650  ast_str_reset(*result_ptr);
651  /* Enough space for any result */
652  if (len > -1) {
653  ast_str_make_space(result_ptr, len ? len : ast_str_strlen(orig_list) + 1);
654  }
655 
656  begin = ast_str_buffer(orig_list);
657  next = strstr(begin, delim);
658 
659  do {
660  /* Find next boundary */
661  if (next) {
662  cur = next;
663  next = strstr(cur + dlen, delim);
664  } else {
665  cur = strchr(begin + dlen, '\0');
666  }
667 
668  if (flen == cur - begin && !strncmp(begin, args.fieldvalue, flen)) {
669  /* Skip field */
670  begin += flen + dlen;
671  } else {
672  /* Copy field to output */
673  if (!first) {
674  ast_str_append(result_ptr, len, "%s", delim);
675  }
676 
677  ast_str_append_substr(result_ptr, len, begin, cur - begin);
678  first = 0;
679  begin = cur + dlen;
680  }
681  } while (*cur != '\0');
682  if (chan) {
683  ast_channel_unlock(chan);
684  }
685 
686  if (buf) {
688  }
689 
690  return 0;
691 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3002
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * args
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
static struct ast_threadstorage tmp_buf
Definition: func_strings.c:46
char * ast_str_append_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string.
Definition: strings.h:1014
static struct ast_threadstorage result_buf
Definition: func_strings.c:45
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static PGresult * result
Definition: cel_pgsql.c:88
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ listfilter_read()

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

Definition at line 693 of file func_strings.c.

References listfilter(), and NULL.

694 {
695  return listfilter(chan, cmd, parse, buf, NULL, len);
696 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **bufstr, ssize_t len)
Definition: func_strings.c:582
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872

◆ listfilter_read2()

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

Definition at line 698 of file func_strings.c.

References listfilter(), and NULL.

699 {
700  return listfilter(chan, cmd, parse, NULL, buf, len);
701 }
#define NULL
Definition: resample.c:96
static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **bufstr, ssize_t len)
Definition: func_strings.c:582
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872

◆ load_module()

static int load_module ( void  )
static

Definition at line 1995 of file func_strings.c.

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

1996 {
1997  int res = 0;
1998 
1999  AST_TEST_REGISTER(test_FIELDNUM);
2000  AST_TEST_REGISTER(test_REPLACE);
2001  AST_TEST_REGISTER(test_FILTER);
2002  AST_TEST_REGISTER(test_STRREPLACE);
2028 
2029  return res;
2030 }
static struct ast_custom_function hashkeys_function
static struct ast_custom_function len_function
static struct ast_custom_function shift_function
static struct ast_custom_function strftime_function
static struct ast_custom_function passthru_function
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static struct ast_custom_function eval_function
static struct ast_custom_function fieldnum_function
Definition: func_strings.c:576
static struct ast_custom_function push_function
static struct ast_custom_function unshift_function
static struct ast_custom_function replace_function
Definition: func_strings.c:854
static struct ast_custom_function quote_function
static int exec_clearhash(struct ast_channel *chan, const char *data)
static struct ast_custom_function listfilter_function
Definition: func_strings.c:703
static char * app_clearhash
Definition: func_strings.c:993
static struct ast_custom_function toupper_function
static struct ast_custom_function csv_quote_function
static struct ast_custom_function filter_function
Definition: func_strings.c:785
static struct ast_custom_function regex_function
Definition: func_strings.c:985
static struct ast_custom_function array_function
static struct ast_custom_function fieldqty_function
Definition: func_strings.c:497
static struct ast_custom_function keypadhash_function
static struct ast_custom_function hash_function
static struct ast_custom_function pop_function
static struct ast_custom_function tolower_function
static struct ast_custom_function strptime_function
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
static struct ast_custom_function strreplace_function
Definition: func_strings.c:943
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ passthru()

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

Definition at line 1692 of file func_strings.c.

References ast_str_set().

1693 {
1694  ast_str_set(buf, len, "%s", data);
1695  return 0;
1696 }
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ quote()

static int quote ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

Definition at line 1270 of file func_strings.c.

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

Referenced by __ast_app_separate_args(), ast_app_separate_args(), parse_options(), and vm_allocate_dh().

1271 {
1272  char *bufptr = buf, *dataptr = data;
1273 
1274  if (len < 3){ /* at least two for quotes and one for binary zero */
1275  ast_log(LOG_ERROR, "Not enough buffer\n");
1276  return -1;
1277  }
1278 
1279  if (ast_strlen_zero(data)) {
1280  ast_log(LOG_WARNING, "No argument specified!\n");
1281  ast_copy_string(buf, "\"\"", len);
1282  return 0;
1283  }
1284 
1285  *bufptr++ = '"';
1286  for (; bufptr < buf + len - 3; dataptr++) {
1287  if (*dataptr == '\\') {
1288  *bufptr++ = '\\';
1289  *bufptr++ = '\\';
1290  } else if (*dataptr == '"') {
1291  *bufptr++ = '\\';
1292  *bufptr++ = '"';
1293  } else if (*dataptr == '\0') {
1294  break;
1295  } else {
1296  *bufptr++ = *dataptr;
1297  }
1298  }
1299  *bufptr++ = '"';
1300  *bufptr = '\0';
1301  return 0;
1302 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ regex()

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, NULL, and str.

Referenced by ast_sip_cli_traverse_objects(), ast_strings_match(), build_regex(), cli_list_subscriptions_inout(), cli_show_subscriptions_inout(), cli_show_tasks(), config_option_destroy(), and xmldoc_get_syntax_config_option().

950 {
952  AST_APP_ARG(null);
953  AST_APP_ARG(reg);
954  AST_APP_ARG(str);
955  );
956  int errcode;
957  regex_t regexbuf;
958 
959  buf[0] = '\0';
960 
962 
963  if (args.argc != 3) {
964  ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n");
965  return -1;
966  }
967  if ((*args.str == ' ') || (*args.str == '\t'))
968  args.str++;
969 
970  ast_debug(1, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
971 
972  if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
973  regerror(errcode, &regexbuf, buf, len);
974  ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
975  return -1;
976  }
977 
978  strcpy(buf, regexec(&regexbuf, args.str, 0, NULL, 0) ? "0" : "1");
979 
980  regfree(&regexbuf);
981 
982  return 0;
983 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * str
Definition: app_jack.c:147
const char * args
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ replace()

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

Definition at line 790 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 FaxPcap::add(), app_get_replace_channel_app(), app_set_replace_channel_app(), app_set_replace_channel_snapshot(), get_replace_channel_snapshot(), ResourceApi::load(), ApiDeclaration::load_file(), manager_dialplan_extension_add(), spandspflow2pcap::n2b(), get_documentation::parse_manager_event_instance(), pj_thread_register_check(), process_text_line(), replace_channel_destroy(), and astconfigparser::try_section().

791 {
793  AST_APP_ARG(varname);
794  AST_APP_ARG(find);
796  );
797  char *strptr, *varsubst;
798  RAII_VAR(struct ast_str *, str, ast_str_create(16), ast_free);
799  char find[256]; /* Only 256 characters possible */
800  char replace[2] = "";
801  size_t unused;
802 
804 
805  if (!str) {
806  return -1;
807  }
808 
809  if (args.argc < 2) {
810  ast_log(LOG_ERROR, "Usage: %s(<varname>,<search-chars>[,<replace-char>])\n", cmd);
811  return -1;
812  }
813 
814  /* Decode escapes */
815  ast_get_encoded_str(args.find, find, sizeof(find));
816  ast_get_encoded_char(args.replace, replace, &unused);
817 
818  if (ast_strlen_zero(find) || ast_strlen_zero(args.varname)) {
819  ast_log(LOG_ERROR, "The characters to search for and the variable name must not be empty.\n");
820  return -1;
821  }
822 
823  varsubst = ast_alloca(strlen(args.varname) + 4);
824  sprintf(varsubst, "${%s}", args.varname);
825  ast_str_substitute_variables(&str, 0, chan, varsubst);
826 
827  if (!ast_str_strlen(str)) {
828  /* Blank, nothing to replace */
829  return -1;
830  }
831 
832  ast_debug(3, "String to search: (%s)\n", ast_str_buffer(str));
833  ast_debug(3, "Characters to find: (%s)\n", find);
834  ast_debug(3, "Character to replace with: (%s)\n", replace);
835 
836  for (strptr = ast_str_buffer(str); *strptr; strptr++) {
837  /* buf is already a mutable buffer, so we construct the result
838  * directly there */
839  if (strchr(find, *strptr)) {
840  if (ast_strlen_zero(replace)) {
841  memmove(strptr, strptr + 1, strlen(strptr + 1) + 1);
842  strptr--;
843  } else {
844  /* Replace character */
845  *strptr = *replace;
846  }
847  }
848  }
849 
850  ast_str_set(buf, len, "%s", ast_str_buffer(str));
851  return 0;
852 }
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition: main/app.c:3002
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
const char * str
Definition: app_jack.c:147
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:2927
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:790
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define AST_APP_ARG(name)
Define an application argument.

◆ shift_pop()

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

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

1569 {
1570 #define beginning (cmd[0] == 'S') /* SHIFT */
1571  char *after, delimiter[2] = ",", *varsubst;
1572  size_t unused;
1573  struct ast_str *before = ast_str_thread_get(&result_buf, 16);
1574  char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr);
1576  AST_APP_ARG(var);
1577  AST_APP_ARG(delimiter);
1578  );
1579 
1580  if (!before) {
1581  return -1;
1582  }
1583 
1584  AST_STANDARD_APP_ARGS(args, data);
1585 
1586  if (ast_strlen_zero(args.var)) {
1587  ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
1588  return -1;
1589  }
1590 
1591  varsubst = ast_alloca(strlen(args.var) + 4);
1592  sprintf(varsubst, "${%s}", args.var);
1593  ast_str_substitute_variables(&before, 0, chan, varsubst);
1594 
1595  if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
1596  ast_get_encoded_char(args.delimiter, delimiter, &unused);
1597  }
1598 
1599  if (!ast_str_strlen(before)) {
1600  /* Nothing to pop */
1601  return -1;
1602  }
1603 
1604  if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) {
1605  /* Only one entry in array */
1606  ast_str_set(buf, len, "%s", ast_str_buffer(before));
1607  pbx_builtin_setvar_helper(chan, args.var, "");
1608  } else {
1609  *after++ = '\0';
1610  ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after);
1611  pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before));
1612  }
1613 
1614  return 0;
1615 #undef beginning
1616 }
#define beginning
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define var
Definition: ast_expr2f.c:614
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
static struct test_val c
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:2927
static struct ast_threadstorage result_buf
Definition: func_strings.c:45
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ string_tolower()

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

Definition at line 1539 of file func_strings.c.

References buf.

1540 {
1541  char *bufptr = buf, *dataptr = data;
1542 
1543  while ((bufptr < buf + buflen - 1) && (*bufptr++ = tolower(*dataptr++)));
1544 
1545  return 0;
1546 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

◆ string_tolower2()

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

Definition at line 1548 of file func_strings.c.

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

1549 {
1550  char *bufptr, *dataptr = data;
1551 
1552  if (buflen > -1) {
1553  ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
1554  }
1555  bufptr = ast_str_buffer(*buf);
1556  while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++)));
1557  ast_str_update(*buf);
1558 
1559  return 0;
1560 }
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:663

◆ string_toupper()

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

Definition at line 1510 of file func_strings.c.

References buf.

1511 {
1512  char *bufptr = buf, *dataptr = data;
1513 
1514  while ((bufptr < buf + buflen - 1) && (*bufptr++ = toupper(*dataptr++)));
1515 
1516  return 0;
1517 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

◆ string_toupper2()

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

Definition at line 1519 of file func_strings.c.

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

1520 {
1521  char *bufptr, *dataptr = data;
1522 
1523  if (buflen > -1) {
1524  ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
1525  }
1526  bufptr = ast_str_buffer(*buf);
1527  while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++)));
1528  ast_str_update(*buf);
1529 
1530  return 0;
1531 }
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:663

◆ strreplace()

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

860 {
861  char *varsubstr; /* substring for input var */
862  char *start; /* Starting pos of substring search. */
863  char *end; /* Ending pos of substring search. */
864  int find_size; /* length of given find-string */
865  unsigned max_matches; /* number of matches we find before terminating search */
866  unsigned count; /* loop counter */
867  struct ast_str *str = ast_str_thread_get(&result_buf, 16); /* Holds the data obtained from varname */
868 
870  AST_APP_ARG(varname);
871  AST_APP_ARG(find_string);
872  AST_APP_ARG(replace_string);
873  AST_APP_ARG(max_replacements);
874  AST_APP_ARG(other); /* Any remining unused arguments */
875  );
876 
877  /* Guarantee output string is empty to start with. */
878  ast_str_reset(*buf);
879 
880  if (!str) {
881  /* We failed to allocate str, forget it. We failed. */
882  return -1;
883  }
884 
885  /* Parse the arguments. */
887 
888  if (args.argc < 2) {
889  /* Didn't receive enough arguments to do anything */
891  "Usage: %s(<varname>,<find-string>[,<replace-string>,[<max-replacements>]])\n",
892  cmd);
893  return -1;
894  }
895 
896  /* No var name specified. Return failure, string is already empty. */
897  if (ast_strlen_zero(args.varname)) {
898  return -1;
899  }
900 
901  /* Zero length find strings are a no-no. Kill the function if we run into one. */
902  if (ast_strlen_zero(args.find_string)) {
903  ast_log(LOG_ERROR, "No <find-string> specified\n");
904  return -1;
905  }
906  find_size = strlen(args.find_string);
907 
908  /* set varsubstr to the matching variable */
909  varsubstr = ast_alloca(strlen(args.varname) + 4);
910  sprintf(varsubstr, "${%s}", args.varname);
911  ast_str_substitute_variables(&str, 0, chan, varsubstr);
912 
913  /* Determine how many replacements are allowed. */
914  if (!args.max_replacements
915  || (max_matches = atoi(args.max_replacements)) <= 0) {
916  /* Unlimited replacements are allowed. */
917  max_matches = -1;
918  }
919 
920  /* Generate the search and replaced string. */
921  start = ast_str_buffer(str);
922  for (count = 0; count < max_matches; ++count) {
923  end = strstr(start, args.find_string);
924  if (!end) {
925  /* Did not find a matching substring in the remainder. */
926  break;
927  }
928 
929  /* Replace the found substring. */
930  *end = '\0';
931  ast_str_append(buf, len, "%s", start);
932  if (args.replace_string) {
933  /* Append the replacement string */
934  ast_str_append(buf, len, "%s", args.replace_string);
935  }
936  start = end + find_size;
937  }
938  ast_str_append(buf, len, "%s", start);
939 
940  return 0;
941 }
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * str
Definition: app_jack.c:147
const char * args
char * end
Definition: eagi_proxy.c:73
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static struct ast_threadstorage result_buf
Definition: func_strings.c:45
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1958 of file func_strings.c.

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

1959 {
1960  int res = 0;
1961 
1962  AST_TEST_UNREGISTER(test_FIELDNUM);
1963  AST_TEST_UNREGISTER(test_REPLACE);
1964  AST_TEST_UNREGISTER(test_FILTER);
1965  AST_TEST_UNREGISTER(test_STRREPLACE);
1991 
1992  return res;
1993 }
static struct ast_custom_function hashkeys_function
static struct ast_custom_function len_function
static struct ast_custom_function shift_function
static struct ast_custom_function strftime_function
static struct ast_custom_function passthru_function
static struct ast_custom_function eval_function
static struct ast_custom_function fieldnum_function
Definition: func_strings.c:576
static struct ast_custom_function push_function
static struct ast_custom_function unshift_function
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static struct ast_custom_function replace_function
Definition: func_strings.c:854
static struct ast_custom_function quote_function
static struct ast_custom_function listfilter_function
Definition: func_strings.c:703
static char * app_clearhash
Definition: func_strings.c:993
static struct ast_custom_function toupper_function
static struct ast_custom_function csv_quote_function
static struct ast_custom_function filter_function
Definition: func_strings.c:785
static struct ast_custom_function regex_function
Definition: func_strings.c:985
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static struct ast_custom_function array_function
static struct ast_custom_function fieldqty_function
Definition: func_strings.c:497
static struct ast_custom_function keypadhash_function
static struct ast_custom_function hash_function
static struct ast_custom_function pop_function
static struct ast_custom_function tolower_function
static struct ast_custom_function strptime_function
static struct ast_custom_function strreplace_function
Definition: func_strings.c:943

◆ unshift_push()

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

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

1629 {
1630 #define beginning (cmd[0] == 'U') /* UNSHIFT */
1631  char delimiter[2] = ",", *varsubst;
1632  size_t unused;
1633  struct ast_str *buf, *previous_value;
1635  AST_APP_ARG(var);
1636  AST_APP_ARG(delimiter);
1637  );
1638  const char *stripped_var;
1639 
1640  if (!(buf = ast_str_thread_get(&result_buf, 16)) ||
1641  !(previous_value = ast_str_thread_get(&tmp_buf, 16))) {
1642  return -1;
1643  }
1644 
1645  AST_STANDARD_APP_ARGS(args, data);
1646 
1647  if (ast_strlen_zero(args.var)) {
1648  ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
1649  return -1;
1650  }
1651 
1652  if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
1653  ast_get_encoded_char(args.delimiter, delimiter, &unused);
1654  }
1655 
1656  /* UNSHIFT and PUSH act as ways of setting a variable, so we need to be
1657  * sure to skip leading underscores if they appear. However, we only want
1658  * to skip up to two since that is the maximum number that can be used to
1659  * indicate variable inheritance. Any further underscores are part of the
1660  * variable name.
1661  */
1662  stripped_var = args.var + MIN(strspn(args.var, "_"), 2);
1663  varsubst = ast_alloca(strlen(stripped_var) + 4);
1664  sprintf(varsubst, "${%s}", stripped_var);
1665  ast_str_substitute_variables(&previous_value, 0, chan, varsubst);
1666 
1667  if (!ast_str_strlen(previous_value)) {
1668  ast_str_set(&buf, 0, "%s", new_value);
1669  } else {
1670  ast_str_set(&buf, 0, "%s%c%s",
1671  beginning ? new_value : ast_str_buffer(previous_value),
1672  delimiter[0],
1673  beginning ? ast_str_buffer(previous_value) : new_value);
1674  }
1675 
1677 
1678  return 0;
1679 #undef beginning
1680 }
#define beginning
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define var
Definition: ast_expr2f.c:614
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define MIN(a, b)
Definition: utils.h:226
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
static struct ast_threadstorage tmp_buf
Definition: func_strings.c:46
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:2927
static struct ast_threadstorage result_buf
Definition: func_strings.c:45
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 2032 of file func_strings.c.

◆ app_clearhash

char* app_clearhash = "ClearHash"
static

Definition at line 993 of file func_strings.c.

Referenced by load_module(), and unload_module().

◆ array_function

struct ast_custom_function array_function
static
Initial value:
= {
.name = "ARRAY",
.write = array,
}
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)

Definition at line 1265 of file func_strings.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2032 of file func_strings.c.

◆ csv_quote_function

struct ast_custom_function csv_quote_function
static
Initial value:
= {
.name = "CSV_QUOTE",
.read = csv_quote,
}
static int csv_quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1339 of file func_strings.c.

◆ eval_function

struct ast_custom_function eval_function
static
Initial value:
= {
.name = "EVAL",
.read = function_eval,
.read2 = function_eval2,
}
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)

Definition at line 1464 of file func_strings.c.

◆ fieldnum_function

struct ast_custom_function fieldnum_function
static
Initial value:
= {
.name = "FIELDNUM",
}
static int function_fieldnum(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:564
static int function_fieldnum_str(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:570

Definition at line 576 of file func_strings.c.

◆ fieldqty_function

struct ast_custom_function fieldqty_function
static
Initial value:
= {
.name = "FIELDQTY",
}
static int function_fieldqty(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:485
static int function_fieldqty_str(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:491

Definition at line 497 of file func_strings.c.

◆ filter_function

struct ast_custom_function filter_function
static
Initial value:
= {
.name = "FILTER",
.read = filter,
}
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709

Definition at line 785 of file func_strings.c.

◆ hash_function

struct ast_custom_function hash_function
static
Initial value:
= {
.name = "HASH",
.write = hash_write,
.read = hash_read,
}
static int hash_write(struct ast_channel *chan, const char *cmd, char *var, const char *value)
static int hash_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1253 of file func_strings.c.

◆ hashkeys_function

struct ast_custom_function hashkeys_function
static
Initial value:
= {
.name = "HASHKEYS",
.read = hashkeys_read,
.read2 = hashkeys_read2,
}
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)

Definition at line 1259 of file func_strings.c.

◆ keypadhash_function

struct ast_custom_function keypadhash_function
static
Initial value:
= {
.name = "KEYPADHASH",
.read = keypadhash,
}
static int keypadhash(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 1505 of file func_strings.c.

◆ len_function

struct ast_custom_function len_function
static
Initial value:
= {
.name = "LEN",
.read = len,
.read_max = 12,
}
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 1356 of file func_strings.c.

◆ listfilter_function

struct ast_custom_function listfilter_function
static
Initial value:
= {
.name = "LISTFILTER",
.read = listfilter_read,
.read2 = listfilter_read2,
}
static int listfilter_read(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:693
static int listfilter_read2(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:698

Definition at line 703 of file func_strings.c.

◆ passthru_function

struct ast_custom_function passthru_function
static
Initial value:
= {
.name = "PASSTHRU",
.read2 = passthru,
}
static int passthru(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1698 of file func_strings.c.

◆ pop_function

struct ast_custom_function pop_function
static
Initial value:
= {
.name = "POP",
.read2 = shift_pop,
}
static int shift_pop(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1623 of file func_strings.c.

◆ push_function

struct ast_custom_function push_function
static
Initial value:
= {
.name = "PUSH",
.write = unshift_push,
}
static int unshift_push(struct ast_channel *chan, const char *cmd, char *data, const char *new_value)

Definition at line 1682 of file func_strings.c.

◆ quote_function

struct ast_custom_function quote_function
static
Initial value:
= {
.name = "QUOTE",
.read = quote,
}
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1304 of file func_strings.c.

◆ regex_function

struct ast_custom_function regex_function
static
Initial value:
= {
.name = "REGEX",
.read = regex,
}
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:948

Definition at line 985 of file func_strings.c.

◆ replace_function

struct ast_custom_function replace_function
static
Initial value:
= {
.name = "REPLACE",
.read2 = replace,
}
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:790

Definition at line 854 of file func_strings.c.

◆ result_buf

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

◆ shift_function

struct ast_custom_function shift_function
static
Initial value:
= {
.name = "SHIFT",
.read2 = shift_pop,
}
static int shift_pop(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)

Definition at line 1618 of file func_strings.c.

◆ strftime_function

struct ast_custom_function strftime_function
static
Initial value:
= {
.name = "STRFTIME",
.read = acf_strftime,
}
static int acf_strftime(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t buflen)

Definition at line 1391 of file func_strings.c.

◆ strptime_function

struct ast_custom_function strptime_function
static
Initial value:
= {
.name = "STRPTIME",
.read = acf_strptime,
}
static int acf_strptime(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 1433 of file func_strings.c.

◆ strreplace_function

struct ast_custom_function strreplace_function
static
Initial value:
= {
.name = "STRREPLACE",
.read2 = strreplace,
}
static int strreplace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:859

Definition at line 943 of file func_strings.c.

◆ tmp_buf

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

Definition at line 46 of file func_strings.c.

Referenced by listfilter(), and unshift_push().

◆ tolower_function

struct ast_custom_function tolower_function
static
Initial value:
= {
.name = "TOLOWER",
.read = string_tolower,
.read2 = string_tolower2,
}
static int string_tolower2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t buflen)
static int string_tolower(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

Definition at line 1562 of file func_strings.c.

◆ toupper_function

struct ast_custom_function toupper_function
static
Initial value:
= {
.name = "TOUPPER",
.read = string_toupper,
.read2 = string_toupper2,
}
static int string_toupper2(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)

Definition at line 1533 of file func_strings.c.

◆ unshift_function

struct ast_custom_function unshift_function
static
Initial value:
= {
.name = "UNSHIFT",
.write = unshift_push,
}
static int unshift_push(struct ast_channel *chan, const char *cmd, char *data, const char *new_value)

Definition at line 1687 of file func_strings.c.