--- funcs/func_strings.c.orig 2010-09-21 17:04:16.000000000 +0200
+++ funcs/func_strings.c 2010-09-21 16:45:45.000000000 +0200
@@ -91,6 +91,25 @@
\
+
+
+ Replace occurrences of string in a variable with another string.
+
+
+
+
+
+
+
+
+ Iterates through a the string contained in the varname
+ replacing at most occurrences occurrences of
+ needle with replace-char.
+ If occurrences is not specified, it defaults to all.
+ The replacement only occurs in the output. The original variable is not
+ altered.
+
+
Check string against a regular expression.
@@ -505,6 +524,117 @@
.read = filter,
};
+/* Taken from https://issues.asterisk.org/file_download.php?file_id=24946&type=bug */
+static char *generic_strreplace(char const *haystack, char const *needle, char const *replacement, char *dst, size_t len, size_t occurrences)
+{
+ size_t haystack_len = strlen(haystack);
+ size_t needle_len = strlen(needle);
+ size_t replacement_len = strlen(replacement);
+ char const *needle_in_haystack;
+ char *orig_dst = dst;
+
+ if (len == 0)
+ return NULL;
+ len -= 1; /* leave room for NUL byte */
+
+ while (1) {
+ size_t n;
+ needle_in_haystack = strstr(haystack, needle);
+ /* not found? we shall copy the whole thing */
+ if (needle_in_haystack == NULL)
+ n = haystack_len;
+ else
+ n = needle_in_haystack - haystack;
+ /* not enough room? copy as much as we can and break */
+ if (n > len) {
+ memcpy(dst, haystack, len);
+ dst += len;
+ break;
+ }
+ /* at least enough room to copy up to needle */
+ memcpy(dst, haystack, n);
+ dst += n;
+ len -= n;
+ /* are we done? break */
+ if (needle_in_haystack == NULL) {
+ break;
+ }
+ /* not enough room for replacement? break */
+ if (len < replacement_len) {
+ break;
+ }
+ /* copy replacement and re-set haystack so we can continue */
+ memcpy(dst, replacement, replacement_len);
+ dst += replacement_len;
+ len -= replacement_len;
+ haystack += (n + needle_len);
+ haystack_len -= (n + needle_len);
+ /* is there a limit on the occurrences? copy rest and stop */
+ if (--occurrences == 0) {
+ size_t rest_len = len >= haystack_len ? haystack_len : len;
+ memcpy(dst, haystack, rest_len);
+ dst += rest_len;
+ break;
+ }
+ }
+
+ *dst = '\0';
+ return orig_dst;
+}
+
+static int strreplace(struct ast_channel *chan, const char *cmd, char *parse, char *buf,
+ size_t len)
+{
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(varname);
+ AST_APP_ARG(needle);
+ AST_APP_ARG(replacement);
+ AST_APP_ARG(occurrences);
+ );
+ char const *haystack;
+ char *needle, *replacement;
+ size_t occurrences = 0;
+ size_t tmp;
+
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ if (args.argc < 3) {
+ ast_log(LOG_ERROR, "Usage: %s(,,[,])\n", cmd);
+ return -1;
+ }
+
+ /* Decode escapes */
+ tmp = strlen(args.needle) + 1;
+ needle = alloca(tmp);
+ ast_get_encoded_str(args.needle, needle, tmp);
+ tmp = strlen(args.replacement) + 1;
+ replacement = alloca(tmp);
+ ast_get_encoded_str(args.replacement, replacement, tmp);
+
+ /* Fetch and check values */
+ if (ast_strlen_zero(args.varname) || ast_strlen_zero(needle)) {
+ ast_log(LOG_ERROR, "The string to search for and the variable name must not be empty.\n");
+ return -1;
+ }
+ haystack = pbx_builtin_getvar_helper(chan, args.varname);
+ if (haystack == NULL) {
+ ast_log(LOG_ERROR, "Variable %s not found.\n", args.varname);
+ return -1;
+ }
+ if (args.argc >= 4) { /* be forward compatible and allow 5+ args */
+ occurrences = (size_t)atoi(args.occurrences);
+ }
+
+ /* Do the actual work */
+ generic_strreplace(haystack, needle, replacement, buf, len, occurrences);
+ return 0;
+}
+
+static struct ast_custom_function strreplace_function = {
+ .name = "STRREPLACE",
+ .read = strreplace,
+};
+
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf,
size_t len)
{
@@ -1004,6 +1134,7 @@
res |= ast_custom_function_unregister(&fieldqty_function);
res |= ast_custom_function_unregister(&filter_function);
res |= ast_custom_function_unregister(&listfilter_function);
+ res |= ast_custom_function_unregister(&strreplace_function);
res |= ast_custom_function_unregister(®ex_function);
res |= ast_custom_function_unregister(&array_function);
res |= ast_custom_function_unregister("e_function);
@@ -1029,6 +1160,7 @@
res |= ast_custom_function_register(&fieldqty_function);
res |= ast_custom_function_register(&filter_function);
res |= ast_custom_function_register(&listfilter_function);
+ res |= ast_custom_function_register(&strreplace_function);
res |= ast_custom_function_register(®ex_function);
res |= ast_custom_function_register(&array_function);
res |= ast_custom_function_register("e_function);