mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 04:30:28 +00:00
Add REPLACE & PASSTHRU functions, overhaul of func_strings, fix API docs for the ast_get_encoded_* functions.
* Add REPLACE function, which searches a given variable for a set of characters and replaces each with a given character. * Add PASSTHRU function, which passes a literal string back, like a NoOp for functions. Intent is to be able to specify a literal string to another function that takes a variable name as an argument. * Let the array manipulation functions work with dialplan functions, in addition to variables. This allows the array manipulation functions to modify ASTDB and ODBC backends, assuming the func_odbc configuration has both read and write functions. (closes issue #15223) Reported by: ajohnson Patches: 20091112__issue15223.diff.txt uploaded by tilghman (license 14) Tested by: lmadsen, tilghman git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@230994 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
9
CHANGES
9
CHANGES
@@ -146,8 +146,13 @@ Dialplan Functions
|
|||||||
mode=multirow. If rowlimit is set, then additional rows may be retrieved
|
mode=multirow. If rowlimit is set, then additional rows may be retrieved
|
||||||
from the same query by using the name of the function which retrieved the
|
from the same query by using the name of the function which retrieved the
|
||||||
first row as an argument to ODBC_FETCH().
|
first row as an argument to ODBC_FETCH().
|
||||||
* Added JABBER_RECEIVE, which permits receiving XMPP messages from the
|
* Added JABBER_RECEIVE, which permits receiving XMPP messages from the
|
||||||
dialplan. This function returns the content of the received message.
|
dialplan. This function returns the content of the received message.
|
||||||
|
* Added REPLACE, which searches a given variable name for a set of characters,
|
||||||
|
then either replaces them with a single character or deletes them.
|
||||||
|
* Added PASSTHRU, which literally passes the same argument back as its return
|
||||||
|
value. The intent is to be able to use a literal string argument to
|
||||||
|
functions that currently require a variable name as an argument.
|
||||||
|
|
||||||
Dialplan Variables
|
Dialplan Variables
|
||||||
------------------
|
------------------
|
||||||
|
@@ -40,6 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#include "asterisk/localtime.h"
|
#include "asterisk/localtime.h"
|
||||||
|
|
||||||
AST_THREADSTORAGE(result_buf);
|
AST_THREADSTORAGE(result_buf);
|
||||||
|
AST_THREADSTORAGE(tmp_buf);
|
||||||
|
|
||||||
/*** DOCUMENTATION
|
/*** DOCUMENTATION
|
||||||
<function name="FIELDQTY" language="en_US">
|
<function name="FIELDQTY" language="en_US">
|
||||||
@@ -91,6 +92,37 @@ AST_THREADSTORAGE(result_buf);
|
|||||||
<literal>\</literal></para></note>
|
<literal>\</literal></para></note>
|
||||||
</description>
|
</description>
|
||||||
</function>
|
</function>
|
||||||
|
<function name="REPLACE" language="en_US">
|
||||||
|
<synopsis>
|
||||||
|
Replace a set of characters in a given string with another character.
|
||||||
|
</synopsis>
|
||||||
|
<syntax>
|
||||||
|
<parameter name="varname" required="true" />
|
||||||
|
<parameter name="find-chars" required="true" />
|
||||||
|
<parameter name="replace-char" required="false" />
|
||||||
|
</syntax>
|
||||||
|
<description>
|
||||||
|
<para>Iterates through a string replacing all the <replaceable>find-chars</replaceable> with
|
||||||
|
<replaceable>replace-char</replaceable>. <replaceable>replace-char</replaceable> may be either
|
||||||
|
empty or contain one character. If empty, all <replaceable>find-chars</replaceable> will be
|
||||||
|
deleted from the output.</para>
|
||||||
|
<note><para>The replacement only occurs in the output. The original variable is not
|
||||||
|
altered.</para></note>
|
||||||
|
</description>
|
||||||
|
</function>
|
||||||
|
<function name="PASSTHRU" language="en_US">
|
||||||
|
<synopsis>
|
||||||
|
Pass the given argument back as a value.
|
||||||
|
</synopsis>
|
||||||
|
<syntax>
|
||||||
|
<parameter name="string" required="false" />
|
||||||
|
</syntax>
|
||||||
|
<description>
|
||||||
|
<para>Literally returns the given <replaceable>string</replaceable>. The intent is to permit
|
||||||
|
other dialplan functions which take a variable name as an argument to be able to take a literal
|
||||||
|
string, instead.</para>
|
||||||
|
</description>
|
||||||
|
</function>
|
||||||
<function name="REGEX" language="en_US">
|
<function name="REGEX" language="en_US">
|
||||||
<synopsis>
|
<synopsis>
|
||||||
Check string against a regular expression.
|
Check string against a regular expression.
|
||||||
@@ -363,7 +395,7 @@ static int function_fieldqty_helper(struct ast_channel *chan, const char *cmd,
|
|||||||
char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
|
char *parse, char *buf, struct ast_str **sbuf, ssize_t len)
|
||||||
{
|
{
|
||||||
char *varsubst;
|
char *varsubst;
|
||||||
struct ast_str *str = ast_str_create(16);
|
struct ast_str *str = ast_str_thread_get(&result_buf, 16);
|
||||||
int fieldcount = 0;
|
int fieldcount = 0;
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(varname);
|
AST_APP_ARG(varname);
|
||||||
@@ -401,7 +433,6 @@ static int function_fieldqty_helper(struct ast_channel *chan, const char *cmd,
|
|||||||
snprintf(buf, len, "%d", fieldcount);
|
snprintf(buf, len, "%d", fieldcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_free(str);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,16 +461,19 @@ static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, ch
|
|||||||
AST_APP_ARG(delimiter);
|
AST_APP_ARG(delimiter);
|
||||||
AST_APP_ARG(fieldvalue);
|
AST_APP_ARG(fieldvalue);
|
||||||
);
|
);
|
||||||
const char *orig_list, *ptr;
|
const char *ptr;
|
||||||
|
struct ast_str *orig_list = ast_str_thread_get(&tmp_buf, 16);
|
||||||
const char *begin, *cur, *next;
|
const char *begin, *cur, *next;
|
||||||
int dlen, flen, first = 1;
|
int dlen, flen, first = 1;
|
||||||
struct ast_str *result, **result_ptr = &result;
|
struct ast_str *result, **result_ptr = &result;
|
||||||
char *delim;
|
char *delim, *varsubst;
|
||||||
|
|
||||||
AST_STANDARD_APP_ARGS(args, parse);
|
AST_STANDARD_APP_ARGS(args, parse);
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
result = ast_str_thread_get(&result_buf, 16);
|
if (!(result = ast_str_thread_get(&result_buf, 16))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Place the result directly into the output buffer */
|
/* Place the result directly into the output buffer */
|
||||||
result_ptr = bufstr;
|
result_ptr = bufstr;
|
||||||
@@ -450,11 +484,15 @@ static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, ch
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
varsubst = alloca(strlen(args.listname) + 4);
|
||||||
|
sprintf(varsubst, "${%s}", args.listname);
|
||||||
|
|
||||||
/* If we don't lock the channel, the variable could disappear out from underneath us. */
|
/* If we don't lock the channel, the variable could disappear out from underneath us. */
|
||||||
if (chan) {
|
if (chan) {
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
}
|
}
|
||||||
if (!(orig_list = pbx_builtin_getvar_helper(chan, args.listname))) {
|
ast_str_substitute_variables(&orig_list, 0, chan, varsubst);
|
||||||
|
if (ast_str_strlen(orig_list)) {
|
||||||
ast_log(LOG_ERROR, "List variable '%s' not found\n", args.listname);
|
ast_log(LOG_ERROR, "List variable '%s' not found\n", args.listname);
|
||||||
if (chan) {
|
if (chan) {
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
@@ -463,11 +501,11 @@ static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If the string isn't there, just copy out the string and be done with it. */
|
/* If the string isn't there, just copy out the string and be done with it. */
|
||||||
if (!(ptr = strstr(orig_list, args.fieldvalue))) {
|
if (!(ptr = strstr(ast_str_buffer(orig_list), args.fieldvalue))) {
|
||||||
if (buf) {
|
if (buf) {
|
||||||
ast_copy_string(buf, orig_list, len);
|
ast_copy_string(buf, ast_str_buffer(orig_list), len);
|
||||||
} else {
|
} else {
|
||||||
ast_str_set(result_ptr, len, "%s", orig_list);
|
ast_str_set(result_ptr, len, "%s", ast_str_buffer(orig_list));
|
||||||
}
|
}
|
||||||
if (chan) {
|
if (chan) {
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
@@ -489,10 +527,10 @@ static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, ch
|
|||||||
ast_str_reset(result);
|
ast_str_reset(result);
|
||||||
/* Enough space for any result */
|
/* Enough space for any result */
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
ast_str_make_space(result_ptr, len ? len : strlen(orig_list) + 1);
|
ast_str_make_space(result_ptr, len ? len : ast_str_strlen(orig_list) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
begin = orig_list;
|
begin = ast_str_buffer(orig_list);
|
||||||
next = strstr(begin, delim);
|
next = strstr(begin, delim);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -609,6 +647,76 @@ static struct ast_custom_function filter_function = {
|
|||||||
.read = filter,
|
.read = filter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
|
||||||
|
{
|
||||||
|
AST_DECLARE_APP_ARGS(args,
|
||||||
|
AST_APP_ARG(varname);
|
||||||
|
AST_APP_ARG(find);
|
||||||
|
AST_APP_ARG(replace);
|
||||||
|
);
|
||||||
|
char *strptr, *varsubst;
|
||||||
|
struct ast_str *str = ast_str_thread_get(&result_buf, 16);
|
||||||
|
char find[256]; /* Only 256 characters possible */
|
||||||
|
char replace[2] = "";
|
||||||
|
size_t unused;
|
||||||
|
|
||||||
|
AST_STANDARD_APP_ARGS(args, data);
|
||||||
|
|
||||||
|
if (!str) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.argc < 2) {
|
||||||
|
ast_log(LOG_ERROR, "Usage: %s(<varname>,<search-chars>[,<replace-char>])\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode escapes */
|
||||||
|
ast_get_encoded_str(args.find, find, sizeof(find));
|
||||||
|
ast_get_encoded_char(args.replace, replace, &unused);
|
||||||
|
|
||||||
|
if (ast_strlen_zero(find) || ast_strlen_zero(args.varname)) {
|
||||||
|
ast_log(LOG_ERROR, "The characters to search for and the variable name must not be empty.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
varsubst = alloca(strlen(args.varname) + 4);
|
||||||
|
sprintf(varsubst, "${%s}", args.varname);
|
||||||
|
ast_str_substitute_variables(&str, 0, chan, varsubst);
|
||||||
|
|
||||||
|
if (!ast_str_strlen(str)) {
|
||||||
|
/* Blank, nothing to replace */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_debug(3, "String to search: (%s)\n", ast_str_buffer(str));
|
||||||
|
ast_debug(3, "Characters to find: (%s)\n", find);
|
||||||
|
ast_debug(3, "Character to replace with: (%s)\n", replace);
|
||||||
|
|
||||||
|
for (strptr = ast_str_buffer(str); *strptr; strptr++) {
|
||||||
|
/* buf is already a mutable buffer, so we construct the result
|
||||||
|
* directly there */
|
||||||
|
if (strchr(find, *strptr)) {
|
||||||
|
if (ast_strlen_zero(replace)) {
|
||||||
|
/* Remove character */
|
||||||
|
strcpy(strptr, strptr + 1); /* SAFE */
|
||||||
|
strptr--;
|
||||||
|
} else {
|
||||||
|
/* Replace character */
|
||||||
|
*strptr = *replace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_str_set(buf, len, "%s", ast_str_buffer(str));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ast_custom_function replace_function = {
|
||||||
|
.name = "REPLACE",
|
||||||
|
.read2 = replace,
|
||||||
|
};
|
||||||
|
|
||||||
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf,
|
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
@@ -1169,138 +1277,131 @@ static struct ast_custom_function tolower_function = {
|
|||||||
.read2 = string_tolower2,
|
.read2 = string_tolower2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int array_remove(struct ast_channel *chan, const char *cmd, char *var, char *buf, size_t len, int beginning)
|
static int shift_pop(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
|
||||||
{
|
{
|
||||||
const char *tmp;
|
#define beginning (cmd[0] == 'S') /* SHIFT */
|
||||||
char *after, *before;
|
char *after, delimiter[2] = ",", *varsubst;
|
||||||
char *(*search_func)(const char *s, int c) = beginning ? strchr : strrchr;
|
size_t unused;
|
||||||
|
struct ast_str *before = ast_str_thread_get(&result_buf, 16);
|
||||||
|
char *(*search_func)(const char *s, int c) = (beginning ? strchr : strrchr);
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(var);
|
AST_APP_ARG(var);
|
||||||
AST_APP_ARG(delimiter);
|
AST_APP_ARG(delimiter);
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!chan) {
|
if (!before) {
|
||||||
ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_STANDARD_APP_ARGS(args, var);
|
AST_STANDARD_APP_ARGS(args, data);
|
||||||
|
|
||||||
if (ast_strlen_zero(args.var)) {
|
if (ast_strlen_zero(args.var)) {
|
||||||
ast_log(LOG_WARNING, "%s requires a channel variable name\n", cmd);
|
ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.delimiter && strlen(args.delimiter) != 1) {
|
varsubst = alloca(strlen(args.var) + 4);
|
||||||
ast_log(LOG_WARNING, "%s delimeters should be a single character\n", cmd);
|
sprintf(varsubst, "${%s}", args.var);
|
||||||
|
ast_str_substitute_variables(&before, 0, chan, varsubst);
|
||||||
|
|
||||||
|
if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
|
||||||
|
ast_get_encoded_char(args.delimiter, delimiter, &unused);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ast_str_strlen(before)) {
|
||||||
|
/* Nothing to pop */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_channel_lock(chan);
|
if (!(after = search_func(ast_str_buffer(before), delimiter[0]))) {
|
||||||
if (ast_strlen_zero(tmp = pbx_builtin_getvar_helper(chan, args.var))) {
|
/* Only one entry in array */
|
||||||
ast_channel_unlock(chan);
|
ast_str_set(buf, len, "%s", ast_str_buffer(before));
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
before = ast_strdupa(tmp);
|
|
||||||
ast_channel_unlock(chan);
|
|
||||||
|
|
||||||
/* Only one entry in array */
|
|
||||||
if (!(after = search_func(before, S_OR(args.delimiter, ",")[0]))) {
|
|
||||||
ast_copy_string(buf, before, len);
|
|
||||||
pbx_builtin_setvar_helper(chan, args.var, "");
|
pbx_builtin_setvar_helper(chan, args.var, "");
|
||||||
} else {
|
} else {
|
||||||
*after++ = '\0';
|
*after++ = '\0';
|
||||||
ast_copy_string(buf, beginning ? before : after, len);
|
ast_str_set(buf, len, "%s", beginning ? ast_str_buffer(before) : after);
|
||||||
pbx_builtin_setvar_helper(chan, args.var, beginning ? after : before);
|
pbx_builtin_setvar_helper(chan, args.var, beginning ? after : ast_str_buffer(before));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#undef beginning
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shift(struct ast_channel *chan, const char *cmd, char *var, char *buf, size_t len)
|
|
||||||
{
|
|
||||||
return array_remove(chan, cmd, var, buf, len, 1);
|
|
||||||
}
|
|
||||||
static struct ast_custom_function shift_function = {
|
static struct ast_custom_function shift_function = {
|
||||||
.name = "SHIFT",
|
.name = "SHIFT",
|
||||||
.read = shift,
|
.read2 = shift_pop,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pop(struct ast_channel *chan, const char *cmd, char *var, char *buf, size_t len)
|
|
||||||
{
|
|
||||||
return array_remove(chan, cmd, var, buf, len, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ast_custom_function pop_function = {
|
static struct ast_custom_function pop_function = {
|
||||||
.name = "POP",
|
.name = "POP",
|
||||||
.read = pop,
|
.read2 = shift_pop,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int array_insert(struct ast_channel *chan, const char *cmd, char *var, const char *val, int beginning)
|
static int unshift_push(struct ast_channel *chan, const char *cmd, char *data, const char *new_value)
|
||||||
{
|
{
|
||||||
const char *tmp;
|
#define beginning (cmd[0] == 'U') /* UNSHIFT */
|
||||||
struct ast_str *buf;
|
char delimiter[2] = ",", *varsubst;
|
||||||
|
size_t unused;
|
||||||
|
struct ast_str *buf, *previous_value;
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(var);
|
AST_APP_ARG(var);
|
||||||
AST_APP_ARG(delimiter);
|
AST_APP_ARG(delimiter);
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!chan) {
|
if (!(buf = ast_str_thread_get(&result_buf, 16)) ||
|
||||||
ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
|
!(previous_value = ast_str_thread_get(&tmp_buf, 16))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_STANDARD_APP_ARGS(args, var);
|
AST_STANDARD_APP_ARGS(args, data);
|
||||||
|
|
||||||
if (ast_strlen_zero(args.var) || ast_strlen_zero(val)) {
|
if (ast_strlen_zero(args.var)) {
|
||||||
ast_log(LOG_WARNING, "%s requires a variable, and at least one value\n", cmd);
|
ast_log(LOG_WARNING, "%s requires a variable name\n", cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.delimiter && strlen(args.delimiter) != 1) {
|
if (args.argc > 1 && !ast_strlen_zero(args.delimiter)) {
|
||||||
ast_log(LOG_WARNING, "%s delimeters should be a single character\n", cmd);
|
ast_get_encoded_char(args.delimiter, delimiter, &unused);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buf = ast_str_create(32))) {
|
varsubst = alloca(strlen(args.var) + 4);
|
||||||
ast_log(LOG_ERROR, "Unable to allocate memory for buffer!\n");
|
sprintf(varsubst, "${%s}", args.var);
|
||||||
return -1;
|
ast_str_substitute_variables(&previous_value, 0, chan, varsubst);
|
||||||
}
|
|
||||||
|
|
||||||
ast_channel_lock(chan);
|
if (!ast_str_strlen(previous_value)) {
|
||||||
if (!(tmp = pbx_builtin_getvar_helper(chan, args.var))) {
|
ast_str_set(&buf, 0, "%s", new_value);
|
||||||
ast_str_set(&buf, 0, "%s", val);
|
|
||||||
} else {
|
} else {
|
||||||
ast_str_append(&buf, 0, "%s%s%s", beginning ? val : tmp, S_OR(args.delimiter, ","), beginning ? tmp : val);
|
ast_str_set(&buf, 0, "%s%c%s",
|
||||||
|
beginning ? new_value : ast_str_buffer(previous_value),
|
||||||
|
delimiter[0],
|
||||||
|
beginning ? ast_str_buffer(previous_value) : new_value);
|
||||||
}
|
}
|
||||||
ast_channel_unlock(chan);
|
|
||||||
|
|
||||||
pbx_builtin_setvar_helper(chan, args.var, ast_str_buffer(buf));
|
pbx_builtin_setvar_helper(chan, args.var, ast_str_buffer(buf));
|
||||||
ast_free(buf);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
#undef beginning
|
||||||
|
|
||||||
static int push(struct ast_channel *chan, const char *cmd, char *var, const char *val)
|
|
||||||
{
|
|
||||||
return array_insert(chan, cmd, var, val, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ast_custom_function push_function = {
|
static struct ast_custom_function push_function = {
|
||||||
.name = "PUSH",
|
.name = "PUSH",
|
||||||
.write = push,
|
.write = unshift_push,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int unshift(struct ast_channel *chan, const char *cmd, char *var, const char *val)
|
|
||||||
{
|
|
||||||
return array_insert(chan, cmd, var, val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ast_custom_function unshift_function = {
|
static struct ast_custom_function unshift_function = {
|
||||||
.name = "UNSHIFT",
|
.name = "UNSHIFT",
|
||||||
.write = unshift,
|
.write = unshift_push,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int passthru(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
|
||||||
|
{
|
||||||
|
ast_str_set(buf, len, "%s", data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ast_custom_function passthru_function = {
|
||||||
|
.name = "PASSTHRU",
|
||||||
|
.read2 = passthru,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int unload_module(void)
|
static int unload_module(void)
|
||||||
@@ -1309,6 +1410,7 @@ static int unload_module(void)
|
|||||||
|
|
||||||
res |= ast_custom_function_unregister(&fieldqty_function);
|
res |= ast_custom_function_unregister(&fieldqty_function);
|
||||||
res |= ast_custom_function_unregister(&filter_function);
|
res |= ast_custom_function_unregister(&filter_function);
|
||||||
|
res |= ast_custom_function_unregister(&replace_function);
|
||||||
res |= ast_custom_function_unregister(&listfilter_function);
|
res |= ast_custom_function_unregister(&listfilter_function);
|
||||||
res |= ast_custom_function_unregister(®ex_function);
|
res |= ast_custom_function_unregister(®ex_function);
|
||||||
res |= ast_custom_function_unregister(&array_function);
|
res |= ast_custom_function_unregister(&array_function);
|
||||||
@@ -1328,6 +1430,7 @@ static int unload_module(void)
|
|||||||
res |= ast_custom_function_unregister(&pop_function);
|
res |= ast_custom_function_unregister(&pop_function);
|
||||||
res |= ast_custom_function_unregister(&push_function);
|
res |= ast_custom_function_unregister(&push_function);
|
||||||
res |= ast_custom_function_unregister(&unshift_function);
|
res |= ast_custom_function_unregister(&unshift_function);
|
||||||
|
res |= ast_custom_function_unregister(&passthru_function);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1338,6 +1441,7 @@ static int load_module(void)
|
|||||||
|
|
||||||
res |= ast_custom_function_register(&fieldqty_function);
|
res |= ast_custom_function_register(&fieldqty_function);
|
||||||
res |= ast_custom_function_register(&filter_function);
|
res |= ast_custom_function_register(&filter_function);
|
||||||
|
res |= ast_custom_function_register(&replace_function);
|
||||||
res |= ast_custom_function_register(&listfilter_function);
|
res |= ast_custom_function_register(&listfilter_function);
|
||||||
res |= ast_custom_function_register(®ex_function);
|
res |= ast_custom_function_register(®ex_function);
|
||||||
res |= ast_custom_function_register(&array_function);
|
res |= ast_custom_function_register(&array_function);
|
||||||
@@ -1357,6 +1461,7 @@ static int load_module(void)
|
|||||||
res |= ast_custom_function_register(&pop_function);
|
res |= ast_custom_function_register(&pop_function);
|
||||||
res |= ast_custom_function_register(&push_function);
|
res |= ast_custom_function_register(&push_function);
|
||||||
res |= ast_custom_function_register(&unshift_function);
|
res |= ast_custom_function_register(&unshift_function);
|
||||||
|
res |= ast_custom_function_register(&passthru_function);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@@ -555,12 +555,21 @@ int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect,
|
|||||||
/*! \brief Allow to record message and have a review option */
|
/*! \brief Allow to record message and have a review option */
|
||||||
int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path);
|
int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path);
|
||||||
|
|
||||||
/*! \brief Decode an encoded control or extended ASCII character
|
/*!\brief Decode an encoded control or extended ASCII character
|
||||||
\return Returns a pointer to the result string
|
* \param[in] stream String to decode
|
||||||
*/
|
* \param[out] result Decoded character
|
||||||
|
* \param[out] consumed Number of characters used in stream to encode the character
|
||||||
|
* \retval -1 Stream is of zero length
|
||||||
|
* \retval 0 Success
|
||||||
|
*/
|
||||||
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed);
|
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed);
|
||||||
|
|
||||||
/*! \brief Decode a stream of encoded control or extended ASCII characters */
|
/*!\brief Decode a stream of encoded control or extended ASCII characters
|
||||||
|
* \param[in] stream Encoded string
|
||||||
|
* \param[out] result Decoded string
|
||||||
|
* \param[in] result_len Maximum size of the result buffer
|
||||||
|
* \return A pointer to the result string
|
||||||
|
*/
|
||||||
char *ast_get_encoded_str(const char *stream, char *result, size_t result_len);
|
char *ast_get_encoded_str(const char *stream, char *result, size_t result_len);
|
||||||
|
|
||||||
/*! \brief Decode a stream of encoded control or extended ASCII characters */
|
/*! \brief Decode a stream of encoded control or extended ASCII characters */
|
||||||
|
Reference in New Issue
Block a user